static ssize_t smsdvb_stats_read(struct file *file, char __user *user_buf,
				      size_t nbytes, loff_t *ppos)
{
	int rc = 0, len;
	struct smsdvb_debugfs *debug_data = file->private_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;
}
Exemple #2
0
static __poll_t smsdvb_stats_poll(struct file *file, poll_table *wait)
{
	struct smsdvb_debugfs *debug_data = file->private_data;
	int rc;

	kref_get(&debug_data->refcount);

	poll_wait(file, &debug_data->stats_queue, wait);

	rc = smsdvb_stats_wait_read(debug_data);
	kref_put(&debug_data->refcount, smsdvb_debugfs_data_release);

	return rc > 0 ? EPOLLIN | EPOLLRDNORM : 0;
}