From patchwork Fri May 6 10:53:12 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 9031831 Return-Path: X-Original-To: patchwork-linux-media@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 70F13BF440 for ; Fri, 6 May 2016 10:57:11 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 9F82B2037F for ; Fri, 6 May 2016 10:57:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C0CD02037C for ; Fri, 6 May 2016 10:57:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758106AbcEFK4q (ORCPT ); Fri, 6 May 2016 06:56:46 -0400 Received: from mga14.intel.com ([192.55.52.115]:19796 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758049AbcEFK4k (ORCPT ); Fri, 6 May 2016 06:56:40 -0400 Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga103.fm.intel.com with ESMTP; 06 May 2016 03:56:37 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.24,586,1455004800"; d="scan'208";a="947527806" Received: from paasikivi.fi.intel.com ([10.237.72.42]) by orsmga001.jf.intel.com with ESMTP; 06 May 2016 03:56:35 -0700 Received: from nauris.fi.intel.com (nauris.localdomain [192.168.240.2]) by paasikivi.fi.intel.com (Postfix) with ESMTP id BFCBF20902; Fri, 6 May 2016 13:56:34 +0300 (EEST) Received: by nauris.fi.intel.com (Postfix, from userid 1000) id EB4FD201D3; Fri, 6 May 2016 13:53:35 +0300 (EEST) From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, hverkuil@xs4all.nl, mchehab@osg.samsung.com Subject: [RFC 03/22] media: Prevent queueing queued requests Date: Fri, 6 May 2016 13:53:12 +0300 Message-Id: <1462532011-15527-4-git-send-email-sakari.ailus@linux.intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1462532011-15527-1-git-send-email-sakari.ailus@linux.intel.com> References: <1462532011-15527-1-git-send-email-sakari.ailus@linux.intel.com> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Spam-Status: No, score=-9.0 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Verify that the request state is IDLE before queueing it. Also mark requests queued when they're queued, and return the request to IDLE if queueing it failed. Signed-off-by: Sakari Ailus --- drivers/media/media-device.c | 43 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 4fc1eb1..481e8e4 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -158,6 +158,37 @@ static void media_device_request_delete(struct media_device *mdev, media_device_request_put(req); } +static int media_device_request_queue_apply( + struct media_device *mdev, struct media_device_request *req, + int (*fn)(struct media_device *mdev, + struct media_device_request *req)) +{ + unsigned long flags; + int rval = 0; + + if (!fn) + return -ENOSYS; + + spin_lock_irqsave(&mdev->req_lock, flags); + if (req->state != MEDIA_DEVICE_REQUEST_STATE_IDLE) + rval = -EINVAL; + else + req->state = MEDIA_DEVICE_REQUEST_STATE_QUEUED; + spin_unlock_irqrestore(&mdev->req_lock, flags); + + if (rval) + return rval; + + rval = fn(mdev, req); + if (rval) { + spin_lock_irqsave(&mdev->req_lock, flags); + req->state = MEDIA_DEVICE_REQUEST_STATE_IDLE; + spin_unlock_irqrestore(&mdev->req_lock, flags); + } + + return rval; +} + static long media_device_request_cmd(struct media_device *mdev, struct file *filp, struct media_request_cmd *cmd) @@ -186,17 +217,13 @@ static long media_device_request_cmd(struct media_device *mdev, break; case MEDIA_REQ_CMD_APPLY: - if (!mdev->ops->req_apply) - return -ENOSYS; - - ret = mdev->ops->req_apply(mdev, req); + ret = media_device_request_queue_apply(mdev, req, + mdev->ops->req_apply); break; case MEDIA_REQ_CMD_QUEUE: - if (!mdev->ops->req_queue) - return -ENOSYS; - - ret = mdev->ops->req_queue(mdev, req); + ret = media_device_request_queue_apply(mdev, req, + mdev->ops->req_queue); break; default: