diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-04-06 11:36:31 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-04-06 11:36:31 -0400 |
| commit | ab195c58b864802c15e494f06ae109413e12d50b (patch) | |
| tree | 7b86a6c2a673323b0a90cae227f9fc023eb5b3ff | |
| parent | cb4361c1dc29cd870f664c004b1817106fbce0fa (diff) | |
| parent | 445d211b0da4e9a6e6d576edff85085c2aaf53df (diff) | |
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
| -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), |
