Commit eebb4159 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'libata-5.15-2021-09-05' of git://git.kernel.dk/linux-block

Pull libata fixes from Jens Axboe:
 "Fixes for queued trim on certain Samsung SSDs, in conjunction with
  certain ATI controllers"

* tag 'libata-5.15-2021-09-05' of git://git.kernel.dk/linux-block:
  libata: Add ATA_HORKAGE_NO_NCQ_ON_ATI for Samsung 860 and 870 SSD.
  libata: add ATA_HORKAGE_NO_NCQ_TRIM for Samsung 860 and 870 SSDs
parents 60f8fbaa 7a8526a5
Loading
Loading
Loading
Loading
+34 −0
Original line number Diff line number Diff line
@@ -2186,6 +2186,25 @@ static void ata_dev_config_ncq_prio(struct ata_device *dev)
	dev->flags &= ~ATA_DFLAG_NCQ_PRIO;
}

static bool ata_dev_check_adapter(struct ata_device *dev,
				  unsigned short vendor_id)
{
	struct pci_dev *pcidev = NULL;
	struct device *parent_dev = NULL;

	for (parent_dev = dev->tdev.parent; parent_dev != NULL;
	     parent_dev = parent_dev->parent) {
		if (dev_is_pci(parent_dev)) {
			pcidev = to_pci_dev(parent_dev);
			if (pcidev->vendor == vendor_id)
				return true;
			break;
		}
	}

	return false;
}

static int ata_dev_config_ncq(struct ata_device *dev,
			       char *desc, size_t desc_sz)
{
@@ -2204,6 +2223,13 @@ static int ata_dev_config_ncq(struct ata_device *dev,
		snprintf(desc, desc_sz, "NCQ (not used)");
		return 0;
	}

	if (dev->horkage & ATA_HORKAGE_NO_NCQ_ON_ATI &&
	    ata_dev_check_adapter(dev, PCI_VENDOR_ID_ATI)) {
		snprintf(desc, desc_sz, "NCQ (not used)");
		return 0;
	}

	if (ap->flags & ATA_FLAG_NCQ) {
		hdepth = min(ap->scsi_host->can_queue, ATA_MAX_QUEUE);
		dev->flags |= ATA_DFLAG_NCQ;
@@ -3970,6 +3996,12 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
						ATA_HORKAGE_ZERO_AFTER_TRIM, },
	{ "Samsung SSD 850*",		NULL,	ATA_HORKAGE_NO_NCQ_TRIM |
						ATA_HORKAGE_ZERO_AFTER_TRIM, },
	{ "Samsung SSD 860*",		NULL,	ATA_HORKAGE_NO_NCQ_TRIM |
						ATA_HORKAGE_ZERO_AFTER_TRIM |
						ATA_HORKAGE_NO_NCQ_ON_ATI, },
	{ "Samsung SSD 870*",		NULL,	ATA_HORKAGE_NO_NCQ_TRIM |
						ATA_HORKAGE_ZERO_AFTER_TRIM |
						ATA_HORKAGE_NO_NCQ_ON_ATI, },
	{ "FCCT*M500*",			NULL,	ATA_HORKAGE_NO_NCQ_TRIM |
						ATA_HORKAGE_ZERO_AFTER_TRIM, },

@@ -6124,6 +6156,8 @@ static int __init ata_parse_force_one(char **cur,
		{ "ncq",	.horkage_off	= ATA_HORKAGE_NONCQ },
		{ "noncqtrim",	.horkage_on	= ATA_HORKAGE_NO_NCQ_TRIM },
		{ "ncqtrim",	.horkage_off	= ATA_HORKAGE_NO_NCQ_TRIM },
		{ "noncqati",	.horkage_on	= ATA_HORKAGE_NO_NCQ_ON_ATI },
		{ "ncqati",	.horkage_off	= ATA_HORKAGE_NO_NCQ_ON_ATI },
		{ "dump_id",	.horkage_on	= ATA_HORKAGE_DUMP_ID },
		{ "pio0",	.xfer_mask	= 1 << (ATA_SHIFT_PIO + 0) },
		{ "pio1",	.xfer_mask	= 1 << (ATA_SHIFT_PIO + 1) },
+1 −0
Original line number Diff line number Diff line
@@ -426,6 +426,7 @@ enum {
	ATA_HORKAGE_NOTRIM	= (1 << 24),	/* don't use TRIM */
	ATA_HORKAGE_MAX_SEC_1024 = (1 << 25),	/* Limit max sects to 1024 */
	ATA_HORKAGE_MAX_TRIM_128M = (1 << 26),	/* Limit max trim size to 128M */
	ATA_HORKAGE_NO_NCQ_ON_ATI = (1 << 27),	/* Disable NCQ on ATI chipset */

	 /* DMA mask for user DMA control: User visible values; DO NOT
	    renumber */