diff options
-rw-r--r-- | drivers/ata/libata-core.c | 77 | ||||
-rw-r--r-- | drivers/ata/libata-sff.c | 4 | ||||
-rw-r--r-- | include/linux/libata.h | 1 |
3 files changed, 49 insertions, 33 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 3f6771e63230..49cffb6094a3 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -1494,6 +1494,7 @@ static int ata_hpa_resize(struct ata_device *dev) | |||
1494 | { | 1494 | { |
1495 | struct ata_eh_context *ehc = &dev->link->eh_context; | 1495 | struct ata_eh_context *ehc = &dev->link->eh_context; |
1496 | int print_info = ehc->i.flags & ATA_EHI_PRINTINFO; | 1496 | int print_info = ehc->i.flags & ATA_EHI_PRINTINFO; |
1497 | bool unlock_hpa = ata_ignore_hpa || dev->flags & ATA_DFLAG_UNLOCK_HPA; | ||
1497 | u64 sectors = ata_id_n_sectors(dev->id); | 1498 | u64 sectors = ata_id_n_sectors(dev->id); |
1498 | u64 native_sectors; | 1499 | u64 native_sectors; |
1499 | int rc; | 1500 | int rc; |
@@ -1510,7 +1511,7 @@ static int ata_hpa_resize(struct ata_device *dev) | |||
1510 | /* If device aborted the command or HPA isn't going to | 1511 | /* If device aborted the command or HPA isn't going to |
1511 | * be unlocked, skip HPA resizing. | 1512 | * be unlocked, skip HPA resizing. |
1512 | */ | 1513 | */ |
1513 | if (rc == -EACCES || !ata_ignore_hpa) { | 1514 | if (rc == -EACCES || !unlock_hpa) { |
1514 | ata_dev_printk(dev, KERN_WARNING, "HPA support seems " | 1515 | ata_dev_printk(dev, KERN_WARNING, "HPA support seems " |
1515 | "broken, skipping HPA handling\n"); | 1516 | "broken, skipping HPA handling\n"); |
1516 | dev->horkage |= ATA_HORKAGE_BROKEN_HPA; | 1517 | dev->horkage |= ATA_HORKAGE_BROKEN_HPA; |
@@ -1525,7 +1526,7 @@ static int ata_hpa_resize(struct ata_device *dev) | |||
1525 | dev->n_native_sectors = native_sectors; | 1526 | dev->n_native_sectors = native_sectors; |
1526 | 1527 | ||
1527 | /* nothing to do? */ | 1528 | /* nothing to do? */ |
1528 | if (native_sectors <= sectors || !ata_ignore_hpa) { | 1529 | if (native_sectors <= sectors || !unlock_hpa) { |
1529 | if (!print_info || native_sectors == sectors) | 1530 | if (!print_info || native_sectors == sectors) |
1530 | return 0; | 1531 | return 0; |
1531 | 1532 | ||
@@ -4186,36 +4187,51 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class, | |||
4186 | goto fail; | 4187 | goto fail; |
4187 | 4188 | ||
4188 | /* verify n_sectors hasn't changed */ | 4189 | /* verify n_sectors hasn't changed */ |
4189 | if (dev->class == ATA_DEV_ATA && n_sectors && | 4190 | if (dev->class != ATA_DEV_ATA || !n_sectors || |
4190 | dev->n_sectors != n_sectors) { | 4191 | dev->n_sectors == n_sectors) |
4191 | ata_dev_printk(dev, KERN_WARNING, "n_sectors mismatch " | 4192 | return 0; |
4192 | "%llu != %llu\n", | 4193 | |
4193 | (unsigned long long)n_sectors, | 4194 | /* n_sectors has changed */ |
4194 | (unsigned long long)dev->n_sectors); | 4195 | ata_dev_printk(dev, KERN_WARNING, "n_sectors mismatch %llu != %llu\n", |
4195 | /* | 4196 | (unsigned long long)n_sectors, |
4196 | * Something could have caused HPA to be unlocked | 4197 | (unsigned long long)dev->n_sectors); |
4197 | * involuntarily. If n_native_sectors hasn't changed | 4198 | |
4198 | * and the new size matches it, keep the device. | 4199 | /* |
4199 | */ | 4200 | * Something could have caused HPA to be unlocked |
4200 | if (dev->n_native_sectors == n_native_sectors && | 4201 | * involuntarily. If n_native_sectors hasn't changed and the |
4201 | dev->n_sectors > n_sectors && | 4202 | * new size matches it, keep the device. |
4202 | dev->n_sectors == n_native_sectors) { | 4203 | */ |
4203 | ata_dev_printk(dev, KERN_WARNING, | 4204 | if (dev->n_native_sectors == n_native_sectors && |
4204 | "new n_sectors matches native, probably " | 4205 | dev->n_sectors > n_sectors && dev->n_sectors == n_native_sectors) { |
4205 | "late HPA unlock, continuing\n"); | 4206 | ata_dev_printk(dev, KERN_WARNING, |
4206 | /* keep using the old n_sectors */ | 4207 | "new n_sectors matches native, probably " |
4207 | dev->n_sectors = n_sectors; | 4208 | "late HPA unlock, continuing\n"); |
4208 | } else { | 4209 | /* keep using the old n_sectors */ |
4209 | /* restore original n_[native]_sectors and fail */ | 4210 | dev->n_sectors = n_sectors; |
4210 | dev->n_native_sectors = n_native_sectors; | 4211 | return 0; |
4211 | dev->n_sectors = n_sectors; | ||
4212 | rc = -ENODEV; | ||
4213 | goto fail; | ||
4214 | } | ||
4215 | } | 4212 | } |
4216 | 4213 | ||
4217 | return 0; | 4214 | /* |
4215 | * Some BIOSes boot w/o HPA but resume w/ HPA locked. Try | ||
4216 | * unlocking HPA in those cases. | ||
4217 | * | ||
4218 | * https://bugzilla.kernel.org/show_bug.cgi?id=15396 | ||
4219 | */ | ||
4220 | if (dev->n_native_sectors == n_native_sectors && | ||
4221 | dev->n_sectors < n_sectors && n_sectors == n_native_sectors && | ||
4222 | !(dev->horkage & ATA_HORKAGE_BROKEN_HPA)) { | ||
4223 | ata_dev_printk(dev, KERN_WARNING, | ||
4224 | "old n_sectors matches native, probably " | ||
4225 | "late HPA lock, will try to unlock HPA\n"); | ||
4226 | /* try unlocking HPA */ | ||
4227 | dev->flags |= ATA_DFLAG_UNLOCK_HPA; | ||
4228 | rc = -EIO; | ||
4229 | } else | ||
4230 | rc = -ENODEV; | ||
4218 | 4231 | ||
4232 | /* restore original n_[native_]sectors and fail */ | ||
4233 | dev->n_native_sectors = n_native_sectors; | ||
4234 | dev->n_sectors = n_sectors; | ||
4219 | fail: | 4235 | fail: |
4220 | ata_dev_printk(dev, KERN_ERR, "revalidation failed (errno=%d)\n", rc); | 4236 | ata_dev_printk(dev, KERN_ERR, "revalidation failed (errno=%d)\n", rc); |
4221 | return rc; | 4237 | return rc; |
@@ -4354,6 +4370,9 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { | |||
4354 | { "HTS541080G9SA00", "MB4OC60D", ATA_HORKAGE_NONCQ, }, | 4370 | { "HTS541080G9SA00", "MB4OC60D", ATA_HORKAGE_NONCQ, }, |
4355 | { "HTS541010G9SA00", "MBZOC60D", ATA_HORKAGE_NONCQ, }, | 4371 | { "HTS541010G9SA00", "MBZOC60D", ATA_HORKAGE_NONCQ, }, |
4356 | 4372 | ||
4373 | /* https://bugzilla.kernel.org/show_bug.cgi?id=15573 */ | ||
4374 | { "C300-CTFDDAC128MAG", "0001", ATA_HORKAGE_NONCQ, }, | ||
4375 | |||
4357 | /* devices which puke on READ_NATIVE_MAX */ | 4376 | /* devices which puke on READ_NATIVE_MAX */ |
4358 | { "HDS724040KLSA80", "KFAOA20N", ATA_HORKAGE_BROKEN_HPA, }, | 4377 | { "HDS724040KLSA80", "KFAOA20N", ATA_HORKAGE_BROKEN_HPA, }, |
4359 | { "WDC WD3200JD-00KLB0", "WD-WCAMR1130137", ATA_HORKAGE_BROKEN_HPA }, | 4378 | { "WDC WD3200JD-00KLB0", "WD-WCAMR1130137", ATA_HORKAGE_BROKEN_HPA }, |
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 6411e0c7b9fe..e3877b6843c9 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
@@ -1816,10 +1816,6 @@ retry: | |||
1816 | !ap->ops->sff_irq_check(ap)) | 1816 | !ap->ops->sff_irq_check(ap)) |
1817 | continue; | 1817 | continue; |
1818 | 1818 | ||
1819 | if (printk_ratelimit()) | ||
1820 | ata_port_printk(ap, KERN_INFO, | ||
1821 | "clearing spurious IRQ\n"); | ||
1822 | |||
1823 | if (idle & (1 << i)) { | 1819 | if (idle & (1 << i)) { |
1824 | ap->ops->sff_check_status(ap); | 1820 | ap->ops->sff_check_status(ap); |
1825 | ap->ops->sff_irq_clear(ap); | 1821 | ap->ops->sff_irq_clear(ap); |
diff --git a/include/linux/libata.h b/include/linux/libata.h index f8ea71e6d0e2..b2f2003b92e5 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -146,6 +146,7 @@ enum { | |||
146 | ATA_DFLAG_SLEEPING = (1 << 15), /* device is sleeping */ | 146 | ATA_DFLAG_SLEEPING = (1 << 15), /* device is sleeping */ |
147 | ATA_DFLAG_DUBIOUS_XFER = (1 << 16), /* data transfer not verified */ | 147 | ATA_DFLAG_DUBIOUS_XFER = (1 << 16), /* data transfer not verified */ |
148 | ATA_DFLAG_NO_UNLOAD = (1 << 17), /* device doesn't support unload */ | 148 | ATA_DFLAG_NO_UNLOAD = (1 << 17), /* device doesn't support unload */ |
149 | ATA_DFLAG_UNLOCK_HPA = (1 << 18), /* unlock HPA */ | ||
149 | ATA_DFLAG_INIT_MASK = (1 << 24) - 1, | 150 | ATA_DFLAG_INIT_MASK = (1 << 24) - 1, |
150 | 151 | ||
151 | ATA_DFLAG_DETACH = (1 << 24), | 152 | ATA_DFLAG_DETACH = (1 << 24), |