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.ai...@linux.intel.com>
---
 drivers/media/media-device.c | 49 ++++++++++++++++++++++++++++++++++++++++++++
 include/media/media-device.h |  3 +++
 2 files changed, 52 insertions(+)

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
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to