diff mbox

[RFC,v2,05/21] media: Add media_device_request_complete() to mark requests complete

Message ID 1464108451-28142-6-git-send-email-sakari.ailus@linux.intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Sakari Ailus May 24, 2016, 4:47 p.m. UTC
Once the request has been queued and later on completed, a driver will
mark the request complete by calling media_device_request_complete().

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 drivers/media/media-device.c | 49 ++++++++++++++++++++++++++++++++++++++++++++
 include/media/media-device.h |  3 +++
 2 files changed, 52 insertions(+)
diff mbox

Patch

diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index a89d046..16fcc20 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -42,6 +42,7 @@  static char *__request_state[] = {
 	"IDLE",
 	"QUEUED",
 	"DELETED",
+	"COMPLETED",
 };
 
 #define request_state(i)			\
@@ -203,6 +204,54 @@  static int media_device_request_delete(struct media_device *mdev,
 	return 0;
 }
 
+void media_device_request_complete(struct media_device *mdev,
+				   struct media_device_request *req)
+{
+	struct file *filp;
+	unsigned long flags;
+
+	spin_lock_irqsave(&mdev->req_lock, flags);
+
+	if (req->state == MEDIA_DEVICE_REQUEST_STATE_IDLE) {
+		dev_dbg(mdev->dev,
+			"request: not completing an idle request %u\n",
+			req->id);
+		spin_unlock_irqrestore(&mdev->req_lock, flags);
+		return;
+	}
+
+	if (WARN_ON(req->state != MEDIA_DEVICE_REQUEST_STATE_QUEUED)) {
+		dev_dbg(mdev->dev, "request: can't delete %u, state %s\n",
+			req->id, request_state(req->state));
+		spin_unlock_irqrestore(&mdev->req_lock, flags);
+		return;
+	}
+
+	req->state = MEDIA_DEVICE_REQUEST_STATE_COMPLETE;
+	filp = req->filp;
+	if (filp) {
+		/*
+		 * If the file handle is still around we remove if
+		 * from the lists here. Otherwise it has been removed
+		 * when the file handle closed.
+		 */
+		list_del(&req->list);
+		list_del(&req->fh_list);
+		req->filp = NULL;
+	}
+
+	spin_unlock_irqrestore(&mdev->req_lock, flags);
+
+	/*
+	 * The driver holds a reference to a request if the filp
+	 * pointer is non-NULL: the file handle associated to the
+	 * request may have been released by now, i.e. filp is NULL.
+	 */
+	if (filp)
+		media_device_request_put(req);
+}
+EXPORT_SYMBOL_GPL(media_device_request_complete);
+
 static int media_device_request_queue_apply(
 	struct media_device *mdev, struct media_device_request *req,
 	int (*fn)(struct media_device *mdev,
diff --git a/include/media/media-device.h b/include/media/media-device.h
index df4afeb..acb7181 100644
--- a/include/media/media-device.h
+++ b/include/media/media-device.h
@@ -269,6 +269,7 @@  enum media_device_request_state {
 	MEDIA_DEVICE_REQUEST_STATE_IDLE,
 	MEDIA_DEVICE_REQUEST_STATE_QUEUED,
 	MEDIA_DEVICE_REQUEST_STATE_DELETED,
+	MEDIA_DEVICE_REQUEST_STATE_COMPLETE,
 };
 
 /**
@@ -765,5 +766,7 @@  struct media_device_request *
 media_device_request_find(struct media_device *mdev, u16 reqid);
 void media_device_request_get(struct media_device_request *req);
 void media_device_request_put(struct media_device_request *req);
+void media_device_request_complete(struct media_device *mdev,
+				   struct media_device_request *req);
 
 #endif