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

Commit f3ba3f6a authored by Gilad Broner's avatar Gilad Broner
Browse files

media: dvb: Use fill count for dvb_ringbuffer



For circular buffer, to distinguish between a full buffer and
an empty buffer, dvb_ringbuffer implementation reserved one
slot to always be unused (so read and write offset can
only be equal when buffer is empty).
This is not suitable for working with circular buffers
managed by hardware like TSPP2, as it causes the HW offsets
and dvb_ringbuffer offset to be out-of-sync.

Change-Id: I09749021d6d03c0f1319b358651350aa4b8dab70
Signed-off-by: default avatarGilad Broner <gbroner@codeaurora.org>
parent 48e8b938
Loading
Loading
Loading
Loading
+19 −17
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@
 * Copyright (C) 2003 Oliver Endriss
 * Copyright (C) 2004 Andrew de Quincey
 *
 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
 * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
 *
 * based on code originally found in av7110.c & dvb_ci.c:
 * Copyright (C) 1999-2003 Ralph  Metzler
@@ -49,6 +49,7 @@ void dvb_ringbuffer_init(struct dvb_ringbuffer *rbuf, void *data, size_t len)
	rbuf->data=data;
	rbuf->size=len;
	rbuf->error=0;
	atomic_set(&rbuf->fill, 0);

	init_waitqueue_head(&rbuf->queue);

@@ -57,33 +58,23 @@ void dvb_ringbuffer_init(struct dvb_ringbuffer *rbuf, void *data, size_t len)



int dvb_ringbuffer_empty(struct dvb_ringbuffer *rbuf)
int dvb_ringbuffer_empty(const struct dvb_ringbuffer *rbuf)
{
	return (rbuf->pread==rbuf->pwrite);
	return (atomic_read(&rbuf->fill) == 0);
}



ssize_t dvb_ringbuffer_free(struct dvb_ringbuffer *rbuf)
ssize_t dvb_ringbuffer_free(const struct dvb_ringbuffer *rbuf)
{
	ssize_t free;

	free = rbuf->pread - rbuf->pwrite;
	if (free <= 0)
		free += rbuf->size;
	return free-1;
	return rbuf->size - atomic_read(&rbuf->fill);
}



ssize_t dvb_ringbuffer_avail(struct dvb_ringbuffer *rbuf)
ssize_t dvb_ringbuffer_avail(const struct dvb_ringbuffer *rbuf)
{
	ssize_t avail;

	avail = rbuf->pwrite - rbuf->pread;
	if (avail < 0)
		avail += rbuf->size;
	return avail;
	return atomic_read(&rbuf->fill);
}


@@ -92,6 +83,7 @@ void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf)
{
	rbuf->pread = rbuf->pwrite;
	rbuf->error = 0;
	atomic_set(&rbuf->fill, 0);
}
EXPORT_SYMBOL(dvb_ringbuffer_flush);

@@ -99,7 +91,9 @@ void dvb_ringbuffer_reset(struct dvb_ringbuffer *rbuf)
{
	rbuf->pread = rbuf->pwrite = 0;
	rbuf->error = 0;
	atomic_set(&rbuf->fill, 0);
}
EXPORT_SYMBOL(dvb_ringbuffer_reset);

void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf)
{
@@ -124,11 +118,13 @@ ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf, u8 __user *buf, si
		buf += split;
		todo -= split;
		rbuf->pread = 0;
		atomic_sub(split, &rbuf->fill);
	}
	if (copy_to_user(buf, rbuf->data+rbuf->pread, todo))
		return -EFAULT;

	rbuf->pread = (rbuf->pread + todo) % rbuf->size;
	atomic_sub(todo, &rbuf->fill);

	return len;
}
@@ -144,10 +140,12 @@ void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len)
		buf += split;
		todo -= split;
		rbuf->pread = 0;
		atomic_sub(split, &rbuf->fill);
	}
	memcpy(buf, rbuf->data+rbuf->pread, todo);

	rbuf->pread = (rbuf->pread + todo) % rbuf->size;
	atomic_sub(todo, &rbuf->fill);
}


@@ -163,9 +161,11 @@ ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, size_t
		buf += split;
		todo -= split;
		rbuf->pwrite = 0;
		atomic_add(split, &rbuf->fill);
	}
	memcpy(rbuf->data+rbuf->pwrite, buf, todo);
	rbuf->pwrite = (rbuf->pwrite + todo) % rbuf->size;
	atomic_add(todo, &rbuf->fill);

	return len;
}
@@ -187,6 +187,7 @@ ssize_t dvb_ringbuffer_write_user(struct dvb_ringbuffer *rbuf,
		buf += split;
		todo -= split;
		rbuf->pwrite = 0;
		atomic_add(split, &rbuf->fill);
	}

	if (copy_from_user(rbuf->data + rbuf->pwrite, buf, todo)) {
@@ -195,6 +196,7 @@ ssize_t dvb_ringbuffer_write_user(struct dvb_ringbuffer *rbuf,
	}

	rbuf->pwrite = (rbuf->pwrite + todo) % rbuf->size;
	atomic_add(todo, &rbuf->fill);

	return len;
}
+16 −12
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@
 * Copyright (C) 2003 Oliver Endriss
 * Copyright (C) 2004 Andrew de Quincey
 *
 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
 * Copyright (c) 2012,2014, The Linux Foundation. All rights reserved.
 *
 * based on code originally found in av7110.c & dvb_ci.c:
 * Copyright (C) 1999-2003 Ralph Metzler & Marcus Metzler
@@ -37,6 +37,7 @@ struct dvb_ringbuffer {
	ssize_t		size;
	ssize_t		pread;
	ssize_t		pwrite;
	atomic_t	fill;
	int		error;

	wait_queue_head_t queue;
@@ -79,13 +80,13 @@ struct dvb_ringbuffer {
extern void dvb_ringbuffer_init(struct dvb_ringbuffer *rbuf, void *data, size_t len);

/* test whether buffer is empty */
extern int dvb_ringbuffer_empty(struct dvb_ringbuffer *rbuf);
extern int dvb_ringbuffer_empty(const struct dvb_ringbuffer *rbuf);

/* return the number of free bytes in the buffer */
extern ssize_t dvb_ringbuffer_free(struct dvb_ringbuffer *rbuf);
extern ssize_t dvb_ringbuffer_free(const struct dvb_ringbuffer *rbuf);

/* return the number of bytes waiting in the buffer */
extern ssize_t dvb_ringbuffer_avail(struct dvb_ringbuffer *rbuf);
extern ssize_t dvb_ringbuffer_avail(const struct dvb_ringbuffer *rbuf);


/*
@@ -109,11 +110,13 @@ extern void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf);

/* advance read ptr by <num> bytes */
#define DVB_RINGBUFFER_SKIP(rbuf,num)	\
			(rbuf)->pread=((rbuf)->pread+(num))%(rbuf)->size
	{ (rbuf)->pread = ((rbuf)->pread+(num))%(rbuf)->size;	\
	atomic_sub((num), &(rbuf)->fill); }

/* advance write ptr by <num> bytes */
#define DVB_RINGBUFFER_PUSH(rbuf, num)	\
			((rbuf)->pwrite = (((rbuf)->pwrite+(num))%(rbuf)->size))
	{ ((rbuf)->pwrite = (((rbuf)->pwrite+(num))%(rbuf)->size));	\
	atomic_add((num), &(rbuf)->fill); }

/*
** read <len> bytes from ring buffer into <buf>
@@ -131,7 +134,8 @@ extern void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf,
/* write single byte to ring buffer */
#define DVB_RINGBUFFER_WRITE_BYTE(rbuf,byte)	\
			{ (rbuf)->data[(rbuf)->pwrite]=(byte); \
			(rbuf)->pwrite=((rbuf)->pwrite+1)%(rbuf)->size; }
			(rbuf)->pwrite = ((rbuf)->pwrite+1)%(rbuf)->size; \
			atomic_inc(&(rbuf)->fill); }
/*
** write <len> bytes to ring buffer
** <usermem> specifies whether <buf> resides in user space
+2 −5
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@
 *                  & Ralph  Metzler <ralph@convergence.de>
 *                    for convergence integrated media GmbH
 *
 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
 * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
@@ -183,10 +183,7 @@ struct dmx_buffer_status {
	/* fullness of buffer in bytes */
	unsigned int fullness;

	/*
	 * How many bytes are free
	 * It's the same as: size-fullness-1
	 */
	/* How many bytes are free */
	unsigned int free_bytes;

	/* read pointer offset in bytes */