Re: [PATCH v3 1/7] ata: libata-sata: Factor out NCQ Priority configuration helpers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 02/03/2024 20:16, Igor Pylypiv wrote:
Export libata NCQ Priority configuration helpers to be reused
for libsas managed SATA devices.

Signed-off-by: Igor Pylypiv <ipylypiv@xxxxxxxxxx>

This looks ok. Some small code comments below, though.

---
  drivers/ata/libata-sata.c | 139 +++++++++++++++++++++++++++-----------
  include/linux/libata.h    |   4 ++
  2 files changed, 103 insertions(+), 40 deletions(-)

diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c
index 0fb1934875f2..a8d5e36d5211 100644
--- a/drivers/ata/libata-sata.c
+++ b/drivers/ata/libata-sata.c
@@ -848,29 +848,73 @@ DEVICE_ATTR(link_power_management_policy, S_IRUGO | S_IWUSR,
  	    ata_scsi_lpm_show, ata_scsi_lpm_store);
  EXPORT_SYMBOL_GPL(dev_attr_link_power_management_policy);
+/**
+ *	ata_ncq_prio_supported - Check if device supports NCQ Priority
+ *	@ap: ATA port of the target device
+ *	@sdev: SCSI device
+ *
+ *	Helper to check if device supports NCQ Priority feature,
+ *	usable with both libsas and libata.
+ */
+int ata_ncq_prio_supported(struct ata_port *ap, struct scsi_device *sdev)
+{
+	struct ata_device *dev;
+	unsigned long flags;
+	int rc;
+
+	spin_lock_irqsave(ap->lock, flags);
+	dev = ata_scsi_find_dev(ap, sdev);
+	if (!dev)
+		rc = -ENODEV;
+	else
+		rc = !!(dev->flags & ATA_DFLAG_NCQ_PRIO);
+	spin_unlock_irqrestore(ap->lock, flags);
+	return rc;
+}

I'm not the biggest fan of functions which effectively return both a boolean and an error code.

I like this patten more:

int ata_ncq_prio_supported(struct ata_port *ap, struct scsi_device *sdev, bool *supported)
{
	...
	if (rc)
		return rc;
	*supported = true/false.
	return 0;
}

No big deal, though.

+EXPORT_SYMBOL_GPL(ata_ncq_prio_supported);
+
  static ssize_t ata_ncq_prio_supported_show(struct device *device,
  					   struct device_attribute *attr,
  					   char *buf)
  {
  	struct scsi_device *sdev = to_scsi_device(device);
  	struct ata_port *ap = ata_shost_to_port(sdev->host);
+	int rc;
+
+	rc = ata_ncq_prio_supported(ap, sdev);
+	if (rc < 0)
+		return rc;
+
+	return sysfs_emit(buf, "%d\n", rc);
+}
+
+DEVICE_ATTR(ncq_prio_supported, S_IRUGO, ata_ncq_prio_supported_show, NULL);
+EXPORT_SYMBOL_GPL(dev_attr_ncq_prio_supported);
+
+/**
+ *	ata_ncq_prio_enabled - Check if NCQ Priority is enabled
+ *	@ap: ATA port of the target device
+ *	@sdev: SCSI device
+ *
+ *	Helper to check if NCQ Priority feature is enabled,
+ *	usable with both libsas and libata.

It's usable by anything which uses libata, really. For the moment that is libsas and libata.

+ */
+int ata_ncq_prio_enabled(struct ata_port *ap, struct scsi_device *sdev)
+{
  	struct ata_device *dev;
-	bool ncq_prio_supported;
-	int rc = 0;
+	unsigned long flags;
+	int rc;
- spin_lock_irq(ap->lock);
+	spin_lock_irqsave(ap->lock, flags);
  	dev = ata_scsi_find_dev(ap, sdev);
  	if (!dev)
  		rc = -ENODEV;
  	else
-		ncq_prio_supported = dev->flags & ATA_DFLAG_NCQ_PRIO;
-	spin_unlock_irq(ap->lock);
-
-	return rc ? rc : sysfs_emit(buf, "%u\n", ncq_prio_supported);
+		rc = !!(dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLED);
+	spin_unlock_irqrestore(ap->lock, flags);
+	return rc;
  }
-
-DEVICE_ATTR(ncq_prio_supported, S_IRUGO, ata_ncq_prio_supported_show, NULL);
-EXPORT_SYMBOL_GPL(dev_attr_ncq_prio_supported);
+EXPORT_SYMBOL_GPL(ata_ncq_prio_enabled);
static ssize_t ata_ncq_prio_enable_show(struct device *device,
  					struct device_attribute *attr,
@@ -878,50 +922,45 @@ static ssize_t ata_ncq_prio_enable_show(struct device *device,
  {
  	struct scsi_device *sdev = to_scsi_device(device);
  	struct ata_port *ap = ata_shost_to_port(sdev->host);
-	struct ata_device *dev;
-	bool ncq_prio_enable;
-	int rc = 0;
+	int rc;
- spin_lock_irq(ap->lock);
-	dev = ata_scsi_find_dev(ap, sdev);
-	if (!dev)
-		rc = -ENODEV;
-	else
-		ncq_prio_enable = dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLED;
-	spin_unlock_irq(ap->lock);
+	rc = ata_ncq_prio_enabled(ap, sdev);
+	if (rc < 0)
+		return rc;
- return rc ? rc : sysfs_emit(buf, "%u\n", ncq_prio_enable);
+	return sysfs_emit(buf, "%d\n", rc);
  }
-static ssize_t ata_ncq_prio_enable_store(struct device *device,
-					 struct device_attribute *attr,
-					 const char *buf, size_t len)
+/**
+ *	ata_ncq_prio_enable - Enable/disable NCQ Priority
+ *	@ap: ATA port of the target device
+ *	@sdev: SCSI device
+ *	@enable: true - enable NCQ Priority, false - disable NCQ Priority
+ *
+ *	Helper to enable/disable NCQ Priority feature, usable with both
+ *	libsas and libata.
+ */
+int ata_ncq_prio_enable(struct ata_port *ap, struct scsi_device *sdev,
+			bool enable)
  {
-	struct scsi_device *sdev = to_scsi_device(device);
-	struct ata_port *ap;
  	struct ata_device *dev;
-	long int input;
+	unsigned long flags;
  	int rc = 0;
- rc = kstrtol(buf, 10, &input);
-	if (rc)
-		return rc;
-	if ((input < 0) || (input > 1))
-		return -EINVAL;
+	spin_lock_irqsave(ap->lock, flags);
- ap = ata_shost_to_port(sdev->host);
  	dev = ata_scsi_find_dev(ap, sdev);
-	if (unlikely(!dev))
-		return  -ENODEV;
-
-	spin_lock_irq(ap->lock);
+	if (unlikely(!dev)) {

no need for unlikely() - this is not fathpath

+		rc = -ENODEV;
+		goto unlock;
+	}
if (!(dev->flags & ATA_DFLAG_NCQ_PRIO)) {
  		rc = -EINVAL;
  		goto unlock;





[Index of Archives]     [Linux Filesystems]     [Linux SCSI]     [Linux RAID]     [Git]     [Kernel Newbies]     [Linux Newbie]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Samba]     [Device Mapper]

  Powered by Linux