linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Russ Weight <russell.h.weight@intel.com>
To: sudeep.holla@arm.com, cristian.marussi@arm.com, ardb@kernel.org,
	bjorn.andersson@linaro.org, gregkh@linuxfoundation.org,
	linux-kernel@vger.kernel.org
Cc: trix@redhat.com, lgoncalv@redhat.com, yilun.xu@intel.com,
	hao.wu@intel.com, matthew.gerlach@intel.com,
	Russ Weight <russell.h.weight@intel.com>
Subject: [RFC PATCH 4/5] firmware: upload: Add status ioctl
Date: Wed, 10 Nov 2021 17:13:44 -0800	[thread overview]
Message-ID: <20211111011345.25049-5-russell.h.weight@intel.com> (raw)
In-Reply-To: <20211111011345.25049-1-russell.h.weight@intel.com>

Extend the Firmware Upload framework to include a FW_UPLOAD_STATUS IOCTL
that can be used to monitor the progress of an ongoing firmware upload.
The status returned includes how much data remains to be transferred, the
progress of the firmware upload, and error information in the case of a
failure.

Signed-off-by: Russ Weight <russell.h.weight@intel.com>
---
 .../driver-api/firmware/firmware-upload.rst   |  6 ++
 drivers/firmware/firmware-upload.c            | 56 +++++++++++++++----
 include/linux/firmware/firmware-upload.h      |  1 +
 include/uapi/linux/firmware-upload.h          | 17 ++++++
 4 files changed, 70 insertions(+), 10 deletions(-)

diff --git a/Documentation/driver-api/firmware/firmware-upload.rst b/Documentation/driver-api/firmware/firmware-upload.rst
index 0165c18a62be..bf079d648b5c 100644
--- a/Documentation/driver-api/firmware/firmware-upload.rst
+++ b/Documentation/driver-api/firmware/firmware-upload.rst
@@ -38,3 +38,9 @@ to a kernel worker thread. This is an exclusive operation; an attempt to
 start concurrent firmware uploads for the same device will fail with EBUSY.
 An eventfd file descriptor parameter is also passed to this IOCTL. It will
 be signalled at the completion of the firmware upload.
+
+FW_UPLOAD_STATUS:
+
+Collect status for an on-going firmware upload. The status returned includes
+how much data remains to be transferred, the progress of the upload, and
+error information in the case of a failure.
diff --git a/drivers/firmware/firmware-upload.c b/drivers/firmware/firmware-upload.c
index f8ddacc72b1d..507cd0f3740e 100644
--- a/drivers/firmware/firmware-upload.c
+++ b/drivers/firmware/firmware-upload.c
@@ -22,6 +22,21 @@ static dev_t fw_upload_devt;
 
 #define to_fw_upload(d) container_of(d, struct fw_upload, dev)
 
+static void fw_upload_update_progress(struct fw_upload *fwl, u32 new_progress)
+{
+	mutex_lock(&fwl->lock);
+	fwl->progress = new_progress;
+	mutex_unlock(&fwl->lock);
+}
+
+static void fw_upload_set_error(struct fw_upload *fwl, u32 err_code)
+{
+	mutex_lock(&fwl->lock);
+	fwl->err_progress = fwl->progress;
+	fwl->err_code = err_code;
+	mutex_unlock(&fwl->lock);
+}
+
 static void fw_upload_prog_complete(struct fw_upload *fwl)
 {
 	mutex_lock(&fwl->lock);
@@ -38,24 +53,24 @@ static void fw_upload_do_load(struct work_struct *work)
 	fwl = container_of(work, struct fw_upload, work);
 
 	if (fwl->driver_unload) {
-		fwl->err_code = FW_UPLOAD_ERR_CANCELED;
+		fw_upload_set_error(fwl, FW_UPLOAD_ERR_CANCELED);
 		goto idle_exit;
 	}
 
 	get_device(&fwl->dev);
 	if (!try_module_get(fwl->dev.parent->driver->owner)) {
-		fwl->err_code = FW_UPLOAD_ERR_BUSY;
+		fw_upload_set_error(fwl, FW_UPLOAD_ERR_BUSY);
 		goto putdev_exit;
 	}
 
-	fwl->progress = FW_UPLOAD_PROG_PREPARING;
+	fw_upload_update_progress(fwl, FW_UPLOAD_PROG_PREPARING);
 	ret = fwl->ops->prepare(fwl, fwl->data, fwl->remaining_size);
 	if (ret) {
-		fwl->err_code = ret;
+		fw_upload_set_error(fwl, ret);
 		goto modput_exit;
 	}
 
-	fwl->progress = FW_UPLOAD_PROG_WRITING;
+	fw_upload_update_progress(fwl, FW_UPLOAD_PROG_WRITING);
 	while (fwl->remaining_size) {
 		ret = fwl->ops->write(fwl, fwl->data, offset,
 					fwl->remaining_size);
@@ -65,7 +80,7 @@ static void fw_upload_do_load(struct work_struct *work)
 					 "write-op wrote zero data\n");
 				ret = -FW_UPLOAD_ERR_RW_ERROR;
 			}
-			fwl->err_code = -ret;
+			fw_upload_set_error(fwl, -ret);
 			goto done;
 		}
 
@@ -73,10 +88,10 @@ static void fw_upload_do_load(struct work_struct *work)
 		offset += ret;
 	}
 
-	fwl->progress = FW_UPLOAD_PROG_PROGRAMMING;
+	fw_upload_update_progress(fwl, FW_UPLOAD_PROG_PROGRAMMING);
 	ret = fwl->ops->poll_complete(fwl);
 	if (ret)
-		fwl->err_code = ret;
+		fw_upload_set_error(fwl, ret);
 
 done:
 	if (fwl->ops->cleanup)
@@ -150,20 +165,41 @@ static int fw_upload_ioctl_write(struct fw_upload *fwl, unsigned long arg)
 	return ret;
 }
 
+static int fw_upload_ioctl_status(struct fw_upload *fwl, unsigned long arg)
+{
+	struct fw_upload_status status;
+
+	memset(&status, 0, sizeof(status));
+	status.progress = fwl->progress;
+	status.remaining_size = fwl->remaining_size;
+	status.err_progress = fwl->err_progress;
+	status.err_code = fwl->err_code;
+
+	if (copy_to_user((void __user *)arg, &status, sizeof(status)))
+		return -EFAULT;
+
+	return 0;
+}
+
 static long fw_upload_ioctl(struct file *filp, unsigned int cmd,
 			    unsigned long arg)
 {
 	struct fw_upload *fwl = filp->private_data;
 	int ret = -ENOTTY;
 
+	mutex_lock(&fwl->lock);
+
 	switch (cmd) {
 	case FW_UPLOAD_WRITE:
-		mutex_lock(&fwl->lock);
 		ret = fw_upload_ioctl_write(fwl, arg);
-		mutex_unlock(&fwl->lock);
+		break;
+	case FW_UPLOAD_STATUS:
+		ret = fw_upload_ioctl_status(fwl, arg);
 		break;
 	}
 
+	mutex_unlock(&fwl->lock);
+
 	return ret;
 }
 
diff --git a/include/linux/firmware/firmware-upload.h b/include/linux/firmware/firmware-upload.h
index c96473fb1e6c..63c6c65e7489 100644
--- a/include/linux/firmware/firmware-upload.h
+++ b/include/linux/firmware/firmware-upload.h
@@ -49,6 +49,7 @@ struct fw_upload {
 	const u8 *data;			/* pointer to update data */
 	u32 remaining_size;		/* size remaining to transfer */
 	u32 progress;
+	u32 err_progress;		/* progress at time of error */
 	u32 err_code;			/* upload error code */
 	bool driver_unload;
 	struct eventfd_ctx *finished;
diff --git a/include/uapi/linux/firmware-upload.h b/include/uapi/linux/firmware-upload.h
index 5ac9079e1bf7..b8d96ee3f646 100644
--- a/include/uapi/linux/firmware-upload.h
+++ b/include/uapi/linux/firmware-upload.h
@@ -51,4 +51,21 @@ struct fw_upload_write {
 
 #define FW_UPLOAD_WRITE	_IOW(FW_UPLOAD_MAGIC, 0, struct fw_upload_write)
 
+/**
+ * FW_UPLOAD_STATUS - _IOR(FW_UPLOAD_MAGIC, 1, struct fw_upload_status)
+ *
+ * Request status information for an ongoing update.
+ *
+ * Return: 0 on success, -errno on failure.
+ */
+struct fw_upload_status {
+	/* Output */
+	__u32 remaining_size;	/* size remaining to transfer */
+	__u32 progress;		/* current progress of firmware upload */
+	__u32 err_progress;	/* progress at time of error */
+	__u32 err_code;		/* error code */
+};
+
+#define FW_UPLOAD_STATUS	_IOR(FW_UPLOAD_MAGIC, 1, struct fw_upload_status)
+
 #endif /* _UAPI_LINUX_FW_UPLOAD_H */
-- 
2.25.1


  parent reply	other threads:[~2021-11-11  1:14 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-11  1:13 [RFC PATCH 0/5] Firmware Upload Framework Russ Weight
2021-11-11  1:13 ` [RFC PATCH 1/5] firmware: Create firmware upload framework Russ Weight
2021-11-17 15:15   ` Greg KH
2021-11-17 18:00     ` Russ Weight
2021-11-17 18:18       ` Greg KH
2021-11-17 18:47         ` Russ Weight
2021-11-17 18:54           ` Greg KH
2021-11-17 20:02             ` Russ Weight
2021-11-11  1:13 ` [RFC PATCH 2/5] firmware: upload: Enable firmware uploads Russ Weight
2021-11-17 19:29   ` Bjorn Andersson
2021-11-11  1:13 ` [RFC PATCH 3/5] firmware: upload: Signal eventfd when complete Russ Weight
2021-11-11  1:13 ` Russ Weight [this message]
2021-11-11  1:13 ` [RFC PATCH 5/5] firmware: upload: Enable cancel of firmware upload Russ Weight
2021-11-15 13:57 ` [RFC PATCH 0/5] Firmware Upload Framework Tom Rix
2021-11-17 19:20   ` Bjorn Andersson
2021-12-09 15:15     ` Tom Rix
2021-12-09 15:34       ` Greg KH
2021-12-09 18:55         ` Tom Rix

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211111011345.25049-5-russell.h.weight@intel.com \
    --to=russell.h.weight@intel.com \
    --cc=ardb@kernel.org \
    --cc=bjorn.andersson@linaro.org \
    --cc=cristian.marussi@arm.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=hao.wu@intel.com \
    --cc=lgoncalv@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=matthew.gerlach@intel.com \
    --cc=sudeep.holla@arm.com \
    --cc=trix@redhat.com \
    --cc=yilun.xu@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).