Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 366620
b: refs/heads/master
c: 6a28bd9
h: refs/heads/master
v: v3
  • Loading branch information
Mauro Carvalho Chehab committed Mar 21, 2013
1 parent 3004880 commit 813405b
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 19 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 773adad14135999380a4652b4ba01c5694827870
refs/heads/master: 6a28bd94f4d068b6de65517e52f52b6840603d0a
77 changes: 59 additions & 18 deletions trunk/drivers/media/common/siano/smsdvb-debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -368,41 +376,73 @@ static int smsdvb_stats_wait_read(struct smsdvb_debugfs *debug_data)
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)
{
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);

Expand All @@ -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,
Expand Down

0 comments on commit 813405b

Please sign in to comment.