Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 09092787 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab
Browse files

[media] saa6588: add support for non-blocking mode



saa6588 always blocked while waiting for data, even if the filehandle
was in non-blocking mode.

Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <m.chehab@samsung.com>
parent a101b947
Loading
Loading
Loading
Loading
+25 −20
Original line number Diff line number Diff line
@@ -150,14 +150,14 @@ static inline struct saa6588 *to_saa6588(struct v4l2_subdev *sd)

/* ---------------------------------------------------------------------- */

static int block_to_user_buf(struct saa6588 *s, unsigned char __user *user_buf)
static bool block_from_buf(struct saa6588 *s, unsigned char *buf)
{
	int i;

	if (s->rd_index == s->wr_index) {
		if (debug > 2)
			dprintk(PREFIX "Read: buffer empty.\n");
		return 0;
		return false;
	}

	if (debug > 2) {
@@ -166,8 +166,7 @@ static int block_to_user_buf(struct saa6588 *s, unsigned char __user *user_buf)
			dprintk("0x%02x ", s->buffer[i]);
	}

	if (copy_to_user(user_buf, &s->buffer[s->rd_index], 3))
		return -EFAULT;
	memcpy(buf, &s->buffer[s->rd_index], 3);

	s->rd_index += 3;
	if (s->rd_index >= s->buf_size)
@@ -177,22 +176,22 @@ static int block_to_user_buf(struct saa6588 *s, unsigned char __user *user_buf)
	if (debug > 2)
		dprintk("%d blocks total.\n", s->block_count);

	return 1;
	return true;
}

static void read_from_buf(struct saa6588 *s, struct saa6588_command *a)
{
	unsigned long flags;

	unsigned char __user *buf_ptr = a->buffer;
	unsigned int i;
	unsigned char buf[3];
	unsigned long flags;
	unsigned int rd_blocks;
	unsigned int i;

	a->result = 0;
	if (!a->buffer)
		return;

	while (!s->data_available_for_read) {
	while (!a->nonblocking && !s->data_available_for_read) {
		int ret = wait_event_interruptible(s->read_queue,
					     s->data_available_for_read);
		if (ret == -ERESTARTSYS) {
@@ -201,24 +200,31 @@ static void read_from_buf(struct saa6588 *s, struct saa6588_command *a)
		}
	}

	spin_lock_irqsave(&s->lock, flags);
	rd_blocks = a->block_count;
	spin_lock_irqsave(&s->lock, flags);
	if (rd_blocks > s->block_count)
		rd_blocks = s->block_count;

	if (!rd_blocks) {
	spin_unlock_irqrestore(&s->lock, flags);

	if (!rd_blocks)
		return;
	}

	for (i = 0; i < rd_blocks; i++) {
		if (block_to_user_buf(s, buf_ptr)) {
			buf_ptr += 3;
			a->result++;
		} else
		bool got_block;

		spin_lock_irqsave(&s->lock, flags);
		got_block = block_from_buf(s, buf);
		spin_unlock_irqrestore(&s->lock, flags);
		if (!got_block)
			break;
		if (copy_to_user(buf_ptr, buf, 3)) {
			a->result = -EFAULT;
			return;
		}
		buf_ptr += 3;
		a->result += 3;
	}
	a->result *= 3;
	spin_lock_irqsave(&s->lock, flags);
	s->data_available_for_read = (s->block_count > 0);
	spin_unlock_irqrestore(&s->lock, flags);
}
@@ -408,9 +414,8 @@ static long saa6588_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
		/* --- poll() for /dev/radio --- */
	case SAA6588_CMD_POLL:
		a->result = 0;
		if (s->data_available_for_read) {
		if (s->data_available_for_read)
			a->result |= POLLIN | POLLRDNORM;
		}
		poll_wait(a->instance, &s->read_queue, a->event_list);
		break;

+3 −1
Original line number Diff line number Diff line
@@ -3266,7 +3266,9 @@ static ssize_t radio_read(struct file *file, char __user *data,
	struct bttv_fh *fh = file->private_data;
	struct bttv *btv = fh->btv;
	struct saa6588_command cmd;

	cmd.block_count = count / 3;
	cmd.nonblocking = file->f_flags & O_NONBLOCK;
	cmd.buffer = data;
	cmd.instance = file;
	cmd.result = -ENODEV;
+1 −0
Original line number Diff line number Diff line
@@ -1285,6 +1285,7 @@ static ssize_t radio_read(struct file *file, char __user *data,
	struct saa6588_command cmd;

	cmd.block_count = count/3;
	cmd.nonblocking = file->f_flags & O_NONBLOCK;
	cmd.buffer = data;
	cmd.instance = file;
	cmd.result = -ENODEV;
+1 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@

struct saa6588_command {
	unsigned int  block_count;
	bool          nonblocking;
	int           result;
	unsigned char __user *buffer;
	struct file   *instance;