Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ab195c58 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* '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
parents cb4361c1 445d211b
Loading
Loading
Loading
Loading
+48 −29
Original line number Diff line number Diff line
@@ -1494,6 +1494,7 @@ static int ata_hpa_resize(struct ata_device *dev)
{
	struct ata_eh_context *ehc = &dev->link->eh_context;
	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 native_sectors;
	int rc;
@@ -1510,7 +1511,7 @@ static int ata_hpa_resize(struct ata_device *dev)
		/* If device aborted the command or HPA isn't going to
		 * 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 "
				       "broken, skipping HPA handling\n");
			dev->horkage |= ATA_HORKAGE_BROKEN_HPA;
@@ -1525,7 +1526,7 @@ static int ata_hpa_resize(struct ata_device *dev)
	dev->n_native_sectors = native_sectors;

	/* nothing to do? */
	if (native_sectors <= sectors || !ata_ignore_hpa) {
	if (native_sectors <= sectors || !unlock_hpa) {
		if (!print_info || native_sectors == sectors)
			return 0;

@@ -4186,36 +4187,51 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class,
		goto fail;

	/* verify n_sectors hasn't changed */
	if (dev->class == ATA_DEV_ATA && n_sectors &&
	    dev->n_sectors != n_sectors) {
		ata_dev_printk(dev, KERN_WARNING, "n_sectors mismatch "
			       "%llu != %llu\n",
	if (dev->class != ATA_DEV_ATA || !n_sectors ||
	    dev->n_sectors == n_sectors)
		return 0;

	/* n_sectors has changed */
	ata_dev_printk(dev, KERN_WARNING, "n_sectors mismatch %llu != %llu\n",
		       (unsigned long long)n_sectors,
		       (unsigned long long)dev->n_sectors);

	/*
	 * Something could have caused HPA to be unlocked
		 * involuntarily.  If n_native_sectors hasn't changed
		 * and the new size matches it, keep the device.
	 * involuntarily.  If n_native_sectors hasn't changed and the
	 * new size matches it, keep the device.
	 */
	if (dev->n_native_sectors == n_native_sectors &&
		    dev->n_sectors > n_sectors &&
		    dev->n_sectors == n_native_sectors) {
	    dev->n_sectors > n_sectors && dev->n_sectors == n_native_sectors) {
		ata_dev_printk(dev, KERN_WARNING,
			       "new n_sectors matches native, probably "
			       "late HPA unlock, continuing\n");
		/* keep using the old n_sectors */
		dev->n_sectors = n_sectors;
		} else {
			/* restore original n_[native]_sectors and fail */
			dev->n_native_sectors = n_native_sectors;
			dev->n_sectors = n_sectors;
			rc = -ENODEV;
			goto fail;
		}
		return 0;
	}

	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:
	ata_dev_printk(dev, KERN_ERR, "revalidation failed (errno=%d)\n", rc);
	return rc;
@@ -4354,6 +4370,9 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
	{ "HTS541080G9SA00",    "MB4OC60D",     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 */
	{ "HDS724040KLSA80",	"KFAOA20N",	ATA_HORKAGE_BROKEN_HPA, },
	{ "WDC WD3200JD-00KLB0", "WD-WCAMR1130137", ATA_HORKAGE_BROKEN_HPA },
+0 −4
Original line number Diff line number Diff line
@@ -1816,10 +1816,6 @@ irqreturn_t ata_sff_interrupt(int irq, void *dev_instance)
			    !ap->ops->sff_irq_check(ap))
				continue;

			if (printk_ratelimit())
				ata_port_printk(ap, KERN_INFO,
						"clearing spurious IRQ\n");

			if (idle & (1 << i)) {
				ap->ops->sff_check_status(ap);
				ap->ops->sff_irq_clear(ap);
+1 −0
Original line number Diff line number Diff line
@@ -146,6 +146,7 @@ enum {
	ATA_DFLAG_SLEEPING	= (1 << 15), /* device is sleeping */
	ATA_DFLAG_DUBIOUS_XFER	= (1 << 16), /* data transfer not verified */
	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_DETACH	= (1 << 24),