libata: Expose TRIM capability in sysfs
authorMartin K. Petersen <martin.petersen@oracle.com>
Tue, 5 May 2015 01:54:19 +0000 (21:54 -0400)
committerTejun Heo <tj@kernel.org>
Tue, 5 May 2015 13:30:18 +0000 (09:30 -0400)
Create a sysfs "trim" attribute for each ata_device that displays
whether DSM TRIM is "unsupported", "unqueued", "forced_unqueued"
(blacklisted) or "queued".

Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Tejun Heo <tj@kernel.org>
Documentation/ABI/testing/sysfs-ata
drivers/ata/libata-transport.c

index 0a932155cbbafc6eb87387125dc417f72707a767..9231daef3813e3b2bed71413bafdc75d432475cd 100644 (file)
@@ -90,6 +90,17 @@ gscr
        130:    SATA_PMP_GSCR_SII_GPIO
        Only valid if the device is a PM.
 
+trim
+
+       Shows the DSM TRIM mode currently used by the device. Valid
+       values are:
+       unsupported:            Drive does not support DSM TRIM
+       unqueued:               Drive supports unqueued DSM TRIM only
+       queued:                 Drive supports queued DSM TRIM
+       forced_unqueued:        Drive's unqueued DSM support is known to be
+                               buggy and only unqueued TRIM commands
+                               are sent
+
 spdn_cnt
 
        Number of time libata decided to lower the speed of link due to errors.
index 3227b7c8a05f88bf040dfefd61b4382583d1368a..d6c37bcd416d17145f291136b6e5f2a7192ee404 100644 (file)
@@ -560,6 +560,27 @@ show_ata_dev_gscr(struct device *dev,
 
 static DEVICE_ATTR(gscr, S_IRUGO, show_ata_dev_gscr, NULL);
 
+static ssize_t
+show_ata_dev_trim(struct device *dev,
+                 struct device_attribute *attr, char *buf)
+{
+       struct ata_device *ata_dev = transport_class_to_dev(dev);
+       unsigned char *mode;
+
+       if (!ata_id_has_trim(ata_dev->id))
+               mode = "unsupported";
+       else if (ata_dev->horkage & ATA_HORKAGE_NO_NCQ_TRIM)
+                       mode = "forced_unqueued";
+       else if (ata_fpdma_dsm_supported(ata_dev))
+               mode = "queued";
+       else
+               mode = "unqueued";
+
+       return snprintf(buf, 20, "%s\n", mode);
+}
+
+static DEVICE_ATTR(trim, S_IRUGO, show_ata_dev_trim, NULL);
+
 static DECLARE_TRANSPORT_CLASS(ata_dev_class,
                               "ata_device", NULL, NULL, NULL);
 
@@ -733,6 +754,7 @@ struct scsi_transport_template *ata_attach_transport(void)
        SETUP_DEV_ATTRIBUTE(ering);
        SETUP_DEV_ATTRIBUTE(id);
        SETUP_DEV_ATTRIBUTE(gscr);
+       SETUP_DEV_ATTRIBUTE(trim);
        BUG_ON(count > ATA_DEV_ATTRS);
        i->dev_attrs[count] = NULL;