/*
 *
 * dvb_ringbuffer.c: ring buffer implementation for the dvb driver
 *
 * Copyright (C) 2003 Oliver Endriss
 * Copyright (C) 2004 Andrew de Quincey
 *
 * based on code originally found in av7110.c & dvb_ci.c:
 * Copyright (C) 1999-2003 Ralph  Metzler
 *                       & Marcus Metzler for convergence integrated media GmbH
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 */



#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/uaccess.h>

#include <media/dvb_ringbuffer.h>

#define PKT_READY 0
#define PKT_DISPOSED 1


void dvb_ringbuffer_init(struct dvb_ringbuffer *rbuf, void *data, size_t len)
{
	rbuf->pread=rbuf->pwrite=0;
	rbuf->data=data;
	rbuf->size=len;
	rbuf->error=0;

	init_waitqueue_head(&rbuf->queue);

	spin_lock_init(&(rbuf->lock));
}



int dvb_ringbuffer_empty(struct dvb_ringbuffer *rbuf)
{
	/* smp_load_acquire() to load write pointer on reader side
	 * this pairs with smp_store_release() in dvb_ringbuffer_write(),
	 * dvb_ringbuffer_write_user(), or dvb_ringbuffer_reset()
	 *
	 * for memory barriers also see Documentation/core-api/circular-buffers.rst
	 */
	return (rbuf->pread == smp_load_acquire(&rbuf->pwrite));
}



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

	/* READ_ONCE() to load read pointer on writer side
	 * this pairs with smp_store_release() in dvb_ringbuffer_read(),
	 * dvb_ringbuffer_read_user(), dvb_ringbuffer_flush(),
	 * or dvb_ringbuffer_reset()
	 */
	free = READ_ONCE(rbuf->pread) - rbuf->pwrite;
	if (free <= 0)
		free += rbuf->size;
	return free-1;
}



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

	/* smp_load_acquire() to load write pointer on reader side
	 * this pairs with smp_store_release() in dvb_ringbuffer_write(),
	 * dvb_ringbuffer_write_user(), or dvb_ringbuffer_reset()
	 */
	avail = smp_load_acquire(&rbuf->pwrite) - rbuf->pread;
	if (avail < 0)
		avail += rbuf->size;
	return avail;
}



void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf)
{
	/* dvb_ringbuffer_flush() counts as read operation
	 * smp_load_acquire() to load write pointer
	 * smp_store_release() to update read pointer, this ensures that the
	 * correct pointer is visible for subsequent dvb_ringbuffer_free()
	 * calls on other cpu cores
	 */
	smp_store_release(&rbuf->pread, smp_load_acquire(&rbuf->pwrite));
	rbuf->error = 0;
}
EXPORT_SYMBOL(dvb_ringbuffer_flush);

void dvb_ringbuffer_reset(struct dvb_ringbuffer *rbuf)
{
	/* dvb_ringbuffer_reset() counts as read and write operation
	 * smp_store_release() to update read pointer
	 */
	smp_store_release(&rbuf->pread, 0);
	/* smp_store_release() to update write pointer */
	smp_store_release(&rbuf->pwrite, 0);
	rbuf->error = 0;
}

void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf)
{
	unsigned long flags;

	spin_lock_irqsave(&rbuf->lock, flags);
	dvb_ringbuffer_flush(rbuf);
	spin_unlock_irqrestore(&rbuf->lock, flags);

	wake_up(&rbuf->queue);
}

ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf, u8 __user *buf, size_t len)
{
	size_t todo = len;
	size_t split;

	split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0;
	if (split > 0) {
		if (copy_to_user(buf, rbuf->data+rbuf->pread, split))
			return -EFAULT;
		buf += split;
		todo -= split;
		/* smp_store_release() for read pointer update to ensure
		 * that buf is not overwritten until read is complete,
		 * this pairs with READ_ONCE() in dvb_ringbuffer_free()
		 */
		smp_store_release(&rbuf->pread, 0);
	}
	if (copy_to_user(buf, rbuf->data+rbuf->pread, todo))
		return -EFAULT;

	/* smp_store_release() to update read pointer, see above */
	smp_store_release(&rbuf->pread, (rbuf->pread + todo) % rbuf->size);

	return len;
}

void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len)
{
	size_t todo = len;
	size_t split;

	split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0;
	if (split > 0) {
		memcpy(buf, rbuf->data+rbuf->pread, split);
		buf += split;
		todo -= split;
		/* smp_store_release() for read pointer update to ensure
		 * that buf is not overwritten until read is complete,
		 * this pairs with READ_ONCE() in dvb_ringbuffer_free()
		 */
		smp_store_release(&rbuf->pread, 0);
	}
	memcpy(buf, rbuf->data+rbuf->pread, todo);

	/* smp_store_release() to update read pointer, see above */
	smp_store_release(&rbuf->pread, (rbuf->pread + todo) % rbuf->size);
}


ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, size_t len)
{
	size_t todo = len;
	size_t split;

	split = (rbuf->pwrite + len > rbuf->size) ? rbuf->size - rbuf->pwrite : 0;

	if (split > 0) {
		memcpy(rbuf->data+rbuf->pwrite, buf, split);
		buf += split;
		todo -= split;
		/* smp_store_release() for write pointer update to ensure that
		 * written data is visible on other cpu cores before the pointer
		 * update, this pairs with smp_load_acquire() in
		 * dvb_ringbuffer_empty() or dvb_ringbuffer_avail()
		 */
		smp_store_release(&rbuf->pwrite, 0);
	}
	memcpy(rbuf->data+rbuf->pwrite, buf, todo);
	/* smp_store_release() for write pointer update, see above */
	smp_store_release(&rbuf->pwrite, (rbuf->pwrite + todo) % rbuf->size);

	return len;
}

ssize_t dvb_ringbuffer_write_user(struct dvb_ringbuffer *rbuf,
				  const u8 __user *buf, size_t len)
{
	int status;
	size_t todo = len;
	size_t split;

	split = (rbuf->pwrite + len > rbuf->size) ? rbuf->size - rbuf->pwrite : 0;

	if (split > 0) {
		status = copy_from_user(rbuf->data+rbuf->pwrite, buf, split);
		if (status)
			return len - todo;
		buf += split;
		todo -= split;
		/* smp_store_release() for write pointer update to ensure that
		 * written data is visible on other cpu cores before the pointer
		 * update, this pairs with smp_load_acquire() in
		 * dvb_ringbuffer_empty() or dvb_ringbuffer_avail()
		 */
		smp_store_release(&rbuf->pwrite, 0);
	}
	status = copy_from_user(rbuf->data+rbuf->pwrite, buf, todo);
	if (status)
		return len - todo;
	/* smp_store_release() for write pointer update, see above */
	smp_store_release(&rbuf->pwrite, (rbuf->pwrite + todo) % rbuf->size);

	return len;
}

ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, size_t len)
{
	int status;
	ssize_t oldpwrite = rbuf->pwrite;

	DVB_RINGBUFFER_WRITE_BYTE(rbuf, len >> 8);
	DVB_RINGBUFFER_WRITE_BYTE(rbuf, len & 0xff);
	DVB_RINGBUFFER_WRITE_BYTE(rbuf, PKT_READY);
	status = dvb_ringbuffer_write(rbuf, buf, len);

	if (status < 0) rbuf->pwrite = oldpwrite;
	return status;
}

ssize_t dvb_ringbuffer_pkt_read_user(struct dvb_ringbuffer *rbuf, size_t idx,
				int offset, u8 __user *buf, size_t len)
{
	size_t todo;
	size_t split;
	size_t pktlen;

	pktlen = rbuf->data[idx] << 8;
	pktlen |= rbuf->data[(idx + 1) % rbuf->size];
	if (offset > pktlen) return -EINVAL;
	if ((offset + len) > pktlen) len = pktlen - offset;

	idx = (idx + DVB_RINGBUFFER_PKTHDRSIZE + offset) % rbuf->size;
	todo = len;
	split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0;
	if (split > 0) {
		if (copy_to_user(buf, rbuf->data+idx, split))
			return -EFAULT;
		buf += split;
		todo -= split;
		idx = 0;
	}
	if (copy_to_user(buf, rbuf->data+idx, todo))
		return -EFAULT;

	return len;
}

ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx,
				int offset, u8* buf, size_t len)
{
	size_t todo;
	size_t split;
	size_t pktlen;

	pktlen = rbuf->data[idx] << 8;
	pktlen |= rbuf->data[(idx + 1) % rbuf->size];
	if (offset > pktlen) return -EINVAL;
	if ((offset + len) > pktlen) len = pktlen - offset;

	idx = (idx + DVB_RINGBUFFER_PKTHDRSIZE + offset) % rbuf->size;
	todo = len;
	split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0;
	if (split > 0) {
		memcpy(buf, rbuf->data+idx, split);
		buf += split;
		todo -= split;
		idx = 0;
	}
	memcpy(buf, rbuf->data+idx, todo);
	return len;
}

void dvb_ringbuffer_pkt_dispose(struct dvb_ringbuffer *rbuf, size_t idx)
{
	size_t pktlen;

	rbuf->data[(idx + 2) % rbuf->size] = PKT_DISPOSED;

	// clean up disposed packets
	while(dvb_ringbuffer_avail(rbuf) > DVB_RINGBUFFER_PKTHDRSIZE) {
		if (DVB_RINGBUFFER_PEEK(rbuf, 2) == PKT_DISPOSED) {
			pktlen = DVB_RINGBUFFER_PEEK(rbuf, 0) << 8;
			pktlen |= DVB_RINGBUFFER_PEEK(rbuf, 1);
			DVB_RINGBUFFER_SKIP(rbuf, pktlen + DVB_RINGBUFFER_PKTHDRSIZE);
		} else {
			// first packet is not disposed, so we stop cleaning now
			break;
		}
	}
}

ssize_t dvb_ringbuffer_pkt_next(struct dvb_ringbuffer *rbuf, size_t idx, size_t* pktlen)
{
	int consumed;
	int curpktlen;
	int curpktstatus;

	if (idx == -1) {
	       idx = rbuf->pread;
	} else {
		curpktlen = rbuf->data[idx] << 8;
		curpktlen |= rbuf->data[(idx + 1) % rbuf->size];
		idx = (idx + curpktlen + DVB_RINGBUFFER_PKTHDRSIZE) % rbuf->size;
	}

	consumed = (idx - rbuf->pread) % rbuf->size;

	while((dvb_ringbuffer_avail(rbuf) - consumed) > DVB_RINGBUFFER_PKTHDRSIZE) {

		curpktlen = rbuf->data[idx] << 8;
		curpktlen |= rbuf->data[(idx + 1) % rbuf->size];
		curpktstatus = rbuf->data[(idx + 2) % rbuf->size];

		if (curpktstatus == PKT_READY) {
			*pktlen = curpktlen;
			return idx;
		}

		consumed += curpktlen + DVB_RINGBUFFER_PKTHDRSIZE;
		idx = (idx + curpktlen + DVB_RINGBUFFER_PKTHDRSIZE) % rbuf->size;
	}

	// no packets available
	return -1;
}



EXPORT_SYMBOL(dvb_ringbuffer_init);
EXPORT_SYMBOL(dvb_ringbuffer_empty);
EXPORT_SYMBOL(dvb_ringbuffer_free);
EXPORT_SYMBOL(dvb_ringbuffer_avail);
EXPORT_SYMBOL(dvb_ringbuffer_flush_spinlock_wakeup);
EXPORT_SYMBOL(dvb_ringbuffer_read_user);
EXPORT_SYMBOL(dvb_ringbuffer_read);
EXPORT_SYMBOL(dvb_ringbuffer_write);
EXPORT_SYMBOL(dvb_ringbuffer_write_user);
