提交 ab195c58 编写于 作者: L Linus Torvalds

Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev

* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev:
  libata: unlock HPA if device shrunk
  libata: disable NCQ on Crucial C300 SSD
  libata: don't whine on spurious IRQ
...@@ -1494,6 +1494,7 @@ static int ata_hpa_resize(struct ata_device *dev) ...@@ -1494,6 +1494,7 @@ static int ata_hpa_resize(struct ata_device *dev)
{ {
struct ata_eh_context *ehc = &dev->link->eh_context; struct ata_eh_context *ehc = &dev->link->eh_context;
int print_info = ehc->i.flags & ATA_EHI_PRINTINFO; int print_info = ehc->i.flags & ATA_EHI_PRINTINFO;
bool unlock_hpa = ata_ignore_hpa || dev->flags & ATA_DFLAG_UNLOCK_HPA;
u64 sectors = ata_id_n_sectors(dev->id); u64 sectors = ata_id_n_sectors(dev->id);
u64 native_sectors; u64 native_sectors;
int rc; int rc;
...@@ -1510,7 +1511,7 @@ static int ata_hpa_resize(struct ata_device *dev) ...@@ -1510,7 +1511,7 @@ static int ata_hpa_resize(struct ata_device *dev)
/* If device aborted the command or HPA isn't going to /* If device aborted the command or HPA isn't going to
* be unlocked, skip HPA resizing. * be unlocked, skip HPA resizing.
*/ */
if (rc == -EACCES || !ata_ignore_hpa) { if (rc == -EACCES || !unlock_hpa) {
ata_dev_printk(dev, KERN_WARNING, "HPA support seems " ata_dev_printk(dev, KERN_WARNING, "HPA support seems "
"broken, skipping HPA handling\n"); "broken, skipping HPA handling\n");
dev->horkage |= ATA_HORKAGE_BROKEN_HPA; dev->horkage |= ATA_HORKAGE_BROKEN_HPA;
...@@ -1525,7 +1526,7 @@ static int ata_hpa_resize(struct ata_device *dev) ...@@ -1525,7 +1526,7 @@ static int ata_hpa_resize(struct ata_device *dev)
dev->n_native_sectors = native_sectors; dev->n_native_sectors = native_sectors;
/* nothing to do? */ /* nothing to do? */
if (native_sectors <= sectors || !ata_ignore_hpa) { if (native_sectors <= sectors || !unlock_hpa) {
if (!print_info || native_sectors == sectors) if (!print_info || native_sectors == sectors)
return 0; return 0;
...@@ -4186,36 +4187,51 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class, ...@@ -4186,36 +4187,51 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class,
goto fail; goto fail;
/* verify n_sectors hasn't changed */ /* verify n_sectors hasn't changed */
if (dev->class == ATA_DEV_ATA && n_sectors && if (dev->class != ATA_DEV_ATA || !n_sectors ||
dev->n_sectors != n_sectors) { dev->n_sectors == n_sectors)
ata_dev_printk(dev, KERN_WARNING, "n_sectors mismatch " return 0;
"%llu != %llu\n",
(unsigned long long)n_sectors, /* n_sectors has changed */
(unsigned long long)dev->n_sectors); ata_dev_printk(dev, KERN_WARNING, "n_sectors mismatch %llu != %llu\n",
/* (unsigned long long)n_sectors,
* Something could have caused HPA to be unlocked (unsigned long long)dev->n_sectors);
* involuntarily. If n_native_sectors hasn't changed
* and the new size matches it, keep the device. /*
*/ * Something could have caused HPA to be unlocked
if (dev->n_native_sectors == n_native_sectors && * involuntarily. If n_native_sectors hasn't changed and the
dev->n_sectors > n_sectors && * new size matches it, keep the device.
dev->n_sectors == n_native_sectors) { */
ata_dev_printk(dev, KERN_WARNING, if (dev->n_native_sectors == n_native_sectors &&
"new n_sectors matches native, probably " dev->n_sectors > n_sectors && dev->n_sectors == n_native_sectors) {
"late HPA unlock, continuing\n"); ata_dev_printk(dev, KERN_WARNING,
/* keep using the old n_sectors */ "new n_sectors matches native, probably "
dev->n_sectors = n_sectors; "late HPA unlock, continuing\n");
} else { /* keep using the old n_sectors */
/* restore original n_[native]_sectors and fail */ dev->n_sectors = n_sectors;
dev->n_native_sectors = n_native_sectors; return 0;
dev->n_sectors = n_sectors;
rc = -ENODEV;
goto fail;
}
} }
return 0; /*
* Some BIOSes boot w/o HPA but resume w/ HPA locked. Try
* unlocking HPA in those cases.
*
* https://bugzilla.kernel.org/show_bug.cgi?id=15396
*/
if (dev->n_native_sectors == n_native_sectors &&
dev->n_sectors < n_sectors && n_sectors == n_native_sectors &&
!(dev->horkage & ATA_HORKAGE_BROKEN_HPA)) {
ata_dev_printk(dev, KERN_WARNING,
"old n_sectors matches native, probably "
"late HPA lock, will try to unlock HPA\n");
/* try unlocking HPA */
dev->flags |= ATA_DFLAG_UNLOCK_HPA;
rc = -EIO;
} else
rc = -ENODEV;
/* restore original n_[native_]sectors and fail */
dev->n_native_sectors = n_native_sectors;
dev->n_sectors = n_sectors;
fail: fail:
ata_dev_printk(dev, KERN_ERR, "revalidation failed (errno=%d)\n", rc); ata_dev_printk(dev, KERN_ERR, "revalidation failed (errno=%d)\n", rc);
return rc; return rc;
...@@ -4354,6 +4370,9 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { ...@@ -4354,6 +4370,9 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
{ "HTS541080G9SA00", "MB4OC60D", ATA_HORKAGE_NONCQ, }, { "HTS541080G9SA00", "MB4OC60D", ATA_HORKAGE_NONCQ, },
{ "HTS541010G9SA00", "MBZOC60D", ATA_HORKAGE_NONCQ, }, { "HTS541010G9SA00", "MBZOC60D", ATA_HORKAGE_NONCQ, },
/* https://bugzilla.kernel.org/show_bug.cgi?id=15573 */
{ "C300-CTFDDAC128MAG", "0001", ATA_HORKAGE_NONCQ, },
/* devices which puke on READ_NATIVE_MAX */ /* devices which puke on READ_NATIVE_MAX */
{ "HDS724040KLSA80", "KFAOA20N", ATA_HORKAGE_BROKEN_HPA, }, { "HDS724040KLSA80", "KFAOA20N", ATA_HORKAGE_BROKEN_HPA, },
{ "WDC WD3200JD-00KLB0", "WD-WCAMR1130137", ATA_HORKAGE_BROKEN_HPA }, { "WDC WD3200JD-00KLB0", "WD-WCAMR1130137", ATA_HORKAGE_BROKEN_HPA },
......
...@@ -1816,10 +1816,6 @@ irqreturn_t ata_sff_interrupt(int irq, void *dev_instance) ...@@ -1816,10 +1816,6 @@ irqreturn_t ata_sff_interrupt(int irq, void *dev_instance)
!ap->ops->sff_irq_check(ap)) !ap->ops->sff_irq_check(ap))
continue; continue;
if (printk_ratelimit())
ata_port_printk(ap, KERN_INFO,
"clearing spurious IRQ\n");
if (idle & (1 << i)) { if (idle & (1 << i)) {
ap->ops->sff_check_status(ap); ap->ops->sff_check_status(ap);
ap->ops->sff_irq_clear(ap); ap->ops->sff_irq_clear(ap);
......
...@@ -146,6 +146,7 @@ enum { ...@@ -146,6 +146,7 @@ enum {
ATA_DFLAG_SLEEPING = (1 << 15), /* device is sleeping */ ATA_DFLAG_SLEEPING = (1 << 15), /* device is sleeping */
ATA_DFLAG_DUBIOUS_XFER = (1 << 16), /* data transfer not verified */ ATA_DFLAG_DUBIOUS_XFER = (1 << 16), /* data transfer not verified */
ATA_DFLAG_NO_UNLOAD = (1 << 17), /* device doesn't support unload */ ATA_DFLAG_NO_UNLOAD = (1 << 17), /* device doesn't support unload */
ATA_DFLAG_UNLOCK_HPA = (1 << 18), /* unlock HPA */
ATA_DFLAG_INIT_MASK = (1 << 24) - 1, ATA_DFLAG_INIT_MASK = (1 << 24) - 1,
ATA_DFLAG_DETACH = (1 << 24), ATA_DFLAG_DETACH = (1 << 24),
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册