From patchwork Tue Mar 19 16:49:27 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mauro Carvalho Chehab X-Patchwork-Id: 2302941 Return-Path: X-Original-To: patchwork-linux-media@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id CC6A5DFB79 for ; Tue, 19 Mar 2013 17:01:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932918Ab3CSRBr (ORCPT ); Tue, 19 Mar 2013 13:01:47 -0400 Received: from mx1.redhat.com ([209.132.183.28]:22576 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932483Ab3CSRBq (ORCPT ); Tue, 19 Mar 2013 13:01:46 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r2JH1huS001074 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 19 Mar 2013 13:01:44 -0400 Received: from pedra (vpn1-6-11.gru2.redhat.com [10.97.6.11]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r2JGntAU016745 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 19 Mar 2013 12:49:58 -0400 Received: from v4l by pedra with local (Exim 4.80.1) (envelope-from ) id 1UHzjR-0005oC-Qw; Tue, 19 Mar 2013 13:49:49 -0300 From: Mauro Carvalho Chehab Cc: Doron Cohen , Mauro Carvalho Chehab , Linux Media Mailing List Subject: [PATCH 38/46] [media] siano: add support for .poll on debugfs Date: Tue, 19 Mar 2013 13:49:27 -0300 Message-Id: <1363711775-2120-39-git-send-email-mchehab@redhat.com> In-Reply-To: <1363711775-2120-1-git-send-email-mchehab@redhat.com> References: <1363711775-2120-1-git-send-email-mchehab@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 To: unlisted-recipients:; (no To-header on input) Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Implement poll() method for debugfs and be sure that the debug_data won't be freed on ir or on read(). With this change, poll() will return POLLIN if either data was filled or if data was read. That allows read() to return 0 to indicate EOF in the latter case. As poll() is now provided, fix support for non-block mode. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/siano/smsdvb-debugfs.c | 77 ++++++++++++++++++++++------- 1 file changed, 59 insertions(+), 18 deletions(-) diff --git a/drivers/media/common/siano/smsdvb-debugfs.c b/drivers/media/common/siano/smsdvb-debugfs.c index 59c7323..0219be3 100644 --- a/drivers/media/common/siano/smsdvb-debugfs.c +++ b/drivers/media/common/siano/smsdvb-debugfs.c @@ -352,6 +352,14 @@ static int smsdvb_stats_open(struct inode *inode, struct file *file) return 0; } +static void smsdvb_debugfs_data_release(struct kref *ref) +{ + struct smsdvb_debugfs *debug_data; + + debug_data = container_of(ref, struct smsdvb_debugfs, refcount); + kfree(debug_data); +} + static int smsdvb_stats_wait_read(struct smsdvb_debugfs *debug_data) { int rc = 1; @@ -368,33 +376,65 @@ exit: return rc; } -static ssize_t smsdvb_stats_read(struct file *file, char __user *user_buf, - size_t nbytes, loff_t *ppos) +static unsigned int smsdvb_stats_poll(struct file *file, poll_table *wait) { - int rc = 0; struct smsdvb_debugfs *debug_data = file->private_data; + int rc; - rc = wait_event_interruptible(debug_data->stats_queue, - smsdvb_stats_wait_read(debug_data)); - if (rc < 0) - return rc; + kref_get(&debug_data->refcount); - rc = simple_read_from_buffer(user_buf, nbytes, ppos, - debug_data->stats_data, - debug_data->stats_count); - spin_lock(&debug_data->lock); - debug_data->stats_was_read = true; - spin_unlock(&debug_data->lock); + poll_wait(file, &debug_data->stats_queue, wait); + + rc = smsdvb_stats_wait_read(debug_data); + if (rc > 0) + rc = POLLIN | POLLRDNORM; + + kref_put(&debug_data->refcount, smsdvb_debugfs_data_release); return rc; } -static void smsdvb_debugfs_data_release(struct kref *ref) +static ssize_t smsdvb_stats_read(struct file *file, char __user *user_buf, + size_t nbytes, loff_t *ppos) { - struct smsdvb_debugfs *debug_data; + int rc = 0, len; + struct smsdvb_debugfs *debug_data = file->private_data; - debug_data = container_of(ref, struct smsdvb_debugfs, refcount); - kfree(debug_data); + kref_get(&debug_data->refcount); + + if (file->f_flags & O_NONBLOCK) { + rc = smsdvb_stats_wait_read(debug_data); + if (!rc) { + rc = -EWOULDBLOCK; + goto ret; + } + } else { + rc = wait_event_interruptible(debug_data->stats_queue, + smsdvb_stats_wait_read(debug_data)); + if (rc < 0) + goto ret; + } + + if (debug_data->stats_was_read) { + rc = 0; /* EOF */ + goto ret; + } + + len = debug_data->stats_count - *ppos; + if (len >= 0) + rc = simple_read_from_buffer(user_buf, nbytes, ppos, + debug_data->stats_data, len); + else + rc = 0; + + if (*ppos >= debug_data->stats_count) { + spin_lock(&debug_data->lock); + debug_data->stats_was_read = true; + spin_unlock(&debug_data->lock); + } +ret: + kref_put(&debug_data->refcount, smsdvb_debugfs_data_release); + return rc; } static int smsdvb_stats_release(struct inode *inode, struct file *file) @@ -402,7 +442,7 @@ static int smsdvb_stats_release(struct inode *inode, struct file *file) struct smsdvb_debugfs *debug_data = file->private_data; spin_lock(&debug_data->lock); - debug_data->stats_was_read = true; + debug_data->stats_was_read = true; /* return EOF to read() */ spin_unlock(&debug_data->lock); wake_up_interruptible_sync(&debug_data->stats_queue); @@ -414,6 +454,7 @@ static int smsdvb_stats_release(struct inode *inode, struct file *file) static const struct file_operations debugfs_stats_ops = { .open = smsdvb_stats_open, + .poll = smsdvb_stats_poll, .read = smsdvb_stats_read, .release = smsdvb_stats_release, .llseek = generic_file_llseek,