dmaengine: idxd: add command status to idxd sysfs attribute
authorDave Jiang <dave.jiang@intel.com>
Fri, 28 Aug 2020 22:13:55 +0000 (15:13 -0700)
committerVinod Koul <vkoul@kernel.org>
Thu, 3 Sep 2020 07:10:12 +0000 (12:40 +0530)
Export admin command status to sysfs attribute in order to allow user to
retrieve configuration error. Allows user tooling to retrieve the command
error and provide more user friendly error messages.

Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Link: https://lore.kernel.org/r/159865278770.29455.8026892329182750127.stgit@djiang5-desk3.ch.intel.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Documentation/ABI/stable/sysfs-driver-dma-idxd
drivers/dma/idxd/device.c
drivers/dma/idxd/idxd.h
drivers/dma/idxd/sysfs.c

index a2bc4af..b441838 100644 (file)
@@ -116,6 +116,12 @@ Description:    The maximum number of bandwidth tokens that may be in use at
                one time by operations that access low bandwidth memory in the
                device.
 
+What:          /sys/bus/dsa/devices/dsa<m>/cmd_status
+Date:          Aug 28, 2020
+KernelVersion: 5.10.0
+Contact:       dmaengine@vger.kernel.org
+Description:   The last executed device administrative command's status/error.
+
 What:           /sys/bus/dsa/devices/wq<m>.<n>/group_id
 Date:           Oct 25, 2019
 KernelVersion:  5.6.0
index 00dab14..22f6c87 100644 (file)
@@ -368,6 +368,7 @@ static void idxd_cmd_exec(struct idxd_device *idxd, int cmd_code, u32 operand,
        dev_dbg(&idxd->pdev->dev, "%s: sending cmd: %#x op: %#x\n",
                __func__, cmd_code, operand);
 
+       idxd->cmd_status = 0;
        __set_bit(IDXD_FLAG_CMD_RUNNING, &idxd->flags);
        idxd->cmd_done = &done;
        iowrite32(cmd.bits, idxd->reg_base + IDXD_CMD_OFFSET);
@@ -379,8 +380,11 @@ static void idxd_cmd_exec(struct idxd_device *idxd, int cmd_code, u32 operand,
        spin_unlock_irqrestore(&idxd->dev_lock, flags);
        wait_for_completion(&done);
        spin_lock_irqsave(&idxd->dev_lock, flags);
-       if (status)
+       if (status) {
                *status = ioread32(idxd->reg_base + IDXD_CMDSTS_OFFSET);
+               idxd->cmd_status = *status & GENMASK(7, 0);
+       }
+
        __clear_bit(IDXD_FLAG_CMD_RUNNING, &idxd->flags);
        /* Wake up other pending commands */
        wake_up(&idxd->cmd_waitq);
index e8bec6e..c64df19 100644 (file)
@@ -156,6 +156,7 @@ struct idxd_device {
        unsigned long flags;
        int id;
        int major;
+       u8 cmd_status;
 
        struct pci_dev *pdev;
        void __iomem *reg_base;
index e6284cb..07a5db0 100644 (file)
@@ -1402,6 +1402,15 @@ static ssize_t cdev_major_show(struct device *dev,
 }
 static DEVICE_ATTR_RO(cdev_major);
 
+static ssize_t cmd_status_show(struct device *dev,
+                              struct device_attribute *attr, char *buf)
+{
+       struct idxd_device *idxd = container_of(dev, struct idxd_device, conf_dev);
+
+       return sprintf(buf, "%#x\n", idxd->cmd_status);
+}
+static DEVICE_ATTR_RO(cmd_status);
+
 static struct attribute *idxd_device_attributes[] = {
        &dev_attr_version.attr,
        &dev_attr_max_groups.attr,
@@ -1420,6 +1429,7 @@ static struct attribute *idxd_device_attributes[] = {
        &dev_attr_max_tokens.attr,
        &dev_attr_token_limit.attr,
        &dev_attr_cdev_major.attr,
+       &dev_attr_cmd_status.attr,
        NULL,
 };