|
@@ -4206,10 +4206,33 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
|
|
|
{ "PIONEER DVD-RW DVR-216D", NULL, ATA_HORKAGE_NOSETXFER },
|
|
|
|
|
|
/* devices that don't properly handle queued TRIM commands */
|
|
|
- { "Micron_M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, },
|
|
|
- { "Crucial_CT???M500SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, },
|
|
|
- { "Micron_M550*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, },
|
|
|
- { "Crucial_CT*M550SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, },
|
|
|
+ { "Micron_M[56]*", NULL, ATA_HORKAGE_NO_NCQ_TRIM |
|
|
|
+ ATA_HORKAGE_ZERO_AFTER_TRIM, },
|
|
|
+ { "Crucial_CT*SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * As defined, the DRAT (Deterministic Read After Trim) and RZAT
|
|
|
+ * (Return Zero After Trim) flags in the ATA Command Set are
|
|
|
+ * unreliable in the sense that they only define what happens if
|
|
|
+ * the device successfully executed the DSM TRIM command. TRIM
|
|
|
+ * is only advisory, however, and the device is free to silently
|
|
|
+ * ignore all or parts of the request.
|
|
|
+ *
|
|
|
+ * Whitelist drives that are known to reliably return zeroes
|
|
|
+ * after TRIM.
|
|
|
+ */
|
|
|
+
|
|
|
+ /*
|
|
|
+ * The intel 510 drive has buggy DRAT/RZAT. Explicitly exclude
|
|
|
+ * that model before whitelisting all other intel SSDs.
|
|
|
+ */
|
|
|
+ { "INTEL*SSDSC2MH*", NULL, 0, },
|
|
|
+
|
|
|
+ { "INTEL*SSD*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM, },
|
|
|
+ { "SSD*INTEL*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM, },
|
|
|
+ { "Samsung*SSD*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM, },
|
|
|
+ { "SAMSUNG*SSD*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM, },
|
|
|
+ { "ST[1248][0248]0[FH]*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM, },
|
|
|
|
|
|
/*
|
|
|
* Some WD SATA-I drives spin up and down erratically when the link
|
|
@@ -4721,7 +4744,10 @@ static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
|
|
|
return NULL;
|
|
|
|
|
|
for (i = 0, tag = ap->last_tag + 1; i < max_queue; i++, tag++) {
|
|
|
- tag = tag < max_queue ? tag : 0;
|
|
|
+ if (ap->flags & ATA_FLAG_LOWTAG)
|
|
|
+ tag = i;
|
|
|
+ else
|
|
|
+ tag = tag < max_queue ? tag : 0;
|
|
|
|
|
|
/* the last tag is reserved for internal command. */
|
|
|
if (tag == ATA_TAG_INTERNAL)
|