/*
 *
 *
 *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License
 *
 *  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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#include "pvrusb2-ioread.h"
#include "pvrusb2-debug.h"
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/mutex.h>
#include <asm/uaccess.h>

#define BUFFER_COUNT 32
#define BUFFER_SIZE PAGE_ALIGN(0x4000)

struct pvr2_ioread {
	struct pvr2_stream *stream;
	char *buffer_storage[BUFFER_COUNT];
	char *sync_key_ptr;
	unsigned int sync_key_len;
	unsigned int sync_buf_offs;
	unsigned int sync_state;
	unsigned int sync_trashed_count;
	int enabled;         // Streaming is on
	int spigot_open;     // OK to pass data to client
	int stream_running;  // Passing data to client now

	/* State relevant to current buffer being read */
	struct pvr2_buffer *c_buf;
	char *c_data_ptr;
	unsigned int c_data_len;
	unsigned int c_data_offs;
	struct mutex mutex;
};

static int pvr2_ioread_init(struct pvr2_ioread *cp)
{
	unsigned int idx;

	cp->stream = NULL;
	mutex_init(&cp->mutex);

	for (idx = 0; idx < BUFFER_COUNT; idx++) {
		cp->buffer_storage[idx] = kmalloc(BUFFER_SIZE,GFP_KERNEL);
		if (!(cp->buffer_storage[idx])) break;
	}

	if (idx < BUFFER_COUNT) {
		// An allocation appears to have failed
		for (idx = 0; idx < BUFFER_COUNT; idx++) {
			if (!(cp->buffer_storage[idx])) continue;
			kfree(cp->buffer_storage[idx]);
		}
		return -ENOMEM;
	}
	return 0;
}

static void pvr2_ioread_done(struct pvr2_ioread *cp)
{
	unsigned int idx;

	pvr2_ioread_setup(cp,NULL);
	for (idx = 0; idx < BUFFER_COUNT; idx++) {
		if (!(cp->buffer_storage[idx])) continue;
		kfree(cp->buffer_storage[idx]);
	}
}

struct pvr2_ioread *pvr2_ioread_create(void)
{
	struct pvr2_ioread *cp;
	cp = kzalloc(sizeof(*cp),GFP_KERNEL);
	if (!cp) return NULL;
	pvr2_trace(PVR2_TRACE_STRUCT,"pvr2_ioread_create id=%p",cp);
	if (pvr2_ioread_init(cp) < 0) {
		kfree(cp);
		return NULL;
	}
	return cp;
}

void pvr2_ioread_destroy(struct pvr2_ioread *cp)
{
	if (!cp) return;
	pvr2_ioread_done(cp);
	pvr2_trace(PVR2_TRACE_STRUCT,"pvr2_ioread_destroy id=%p",cp);
	if (cp->sync_key_ptr) {
		kfree(cp->sync_key_ptr);
		cp->sync_key_ptr = NULL;
	}
	kfree(cp);
}

void pvr2_ioread_set_sync_key(struct pvr2_ioread *cp,
			      const char *sync_key_ptr,
			      unsigned int sync_key_len)
{
	if (!cp) return;

	if (!sync_key_ptr) sync_key_len = 0;
	if ((sync_key_len == cp->sync_key_len) &&
	    ((!sync_key_len) ||
	     (!memcmp(sync_key_ptr,cp->sync_key_ptr,sync_key_len)))) return;

	if (sync_key_len != cp->sync_key_len) {
		if (cp->sync_key_ptr) {
			kfree(cp->sync_key_ptr);
			cp->sync_key_ptr = NULL;
		}
		cp->sync_key_len = 0;
		if (sync_key_len) {
			cp->sync_key_ptr = kmalloc(sync_key_len,GFP_KERNEL);
			if (cp->sync_key_ptr) {
				cp->sync_key_len = sync_key_len;
			}
		}
	}
	if (!cp->sync_key_len) return;
	memcpy(cp->sync_key_ptr,sync_key_ptr,cp->sync_key_len);
}

static void pvr2_ioread_stop(struct pvr2_ioread *cp)
{
	if (!(cp->enabled)) return;
	pvr2_trace(PVR2_TRACE_START_STOP,
		   "/*---TRACE_READ---*/ pvr2_ioread_stop id=%p",cp);
	pvr2_stream_kill(cp->stream);
	cp->c_buf = NULL;
	cp->c_data_ptr = NULL;
	cp->c_data_len = 0;
	cp->c_data_offs = 0;
	cp->enabled = 0;
	cp->stream_running = 0;
	cp->spigot_open = 0;
	if (cp->sync_state) {
		pvr2_trace(PVR2_TRACE_DATA_FLOW,
			   "/*---TRACE_READ---*/ sync_state <== 0");
		cp->sync_state = 0;
	}
}

static int pvr2_ioread_start(struct pvr2_ioread *cp)
{
	int stat;
	struct pvr2_buffer *bp;
	if (cp->enabled) return 0;
	if (!(cp->stream)) return 0;
	pvr2_trace(PVR2_TRACE_START_STOP,
		   "/*---TRACE_READ---*/ pvr2_ioread_start id=%p",cp);
	while ((bp = pvr2_stream_get_idle_buffer(cp->stream)) != NULL) {
		stat = pvr2_buffer_queue(bp);
		if (stat < 0) {
			pvr2_trace(PVR2_TRACE_DATA_FLOW,
				   "/*---TRACE_READ---*/"
				   " pvr2_ioread_start id=%p"
				   " error=%d",
				   cp,stat);
			pvr2_ioread_stop(cp);
			return stat;
		}
	}
	cp->enabled = !0;
	cp->c_buf = NULL;
	cp->c_data_ptr = NULL;
	cp->c_data_len = 0;
	cp->c_data_offs = 0;
	cp->stream_running = 0;
	if (cp->sync_key_len) {
		pvr2_trace(PVR2_TRACE_DATA_FLOW,
			   "/*---TRACE_READ---*/ sync_state <== 1");
		cp->sync_state = 1;
		cp->sync_trashed_count = 0;
		cp->sync_buf_offs = 0;
	}
	cp->spigot_open = 0;
	return 0;
}

struct pvr2_stream *pvr2_ioread_get_stream(struct pvr2_ioread *cp)
{
	return cp->stream;
}

int pvr2_ioread_setup(struct pvr2_ioread *cp,struct pvr2_stream *sp)
{
	int ret;
	unsigned int idx;
	struct pvr2_buffer *bp;

	mutex_lock(&cp->mutex); do {
		if (cp->stream) {
			pvr2_trace(PVR2_TRACE_START_STOP,
				   "/*---TRACE_READ---*/"
				   " pvr2_ioread_setup (tear-down) id=%p",cp);
			pvr2_ioread_stop(cp);
			pvr2_stream_kill(cp->stream);
			if (pvr2_stream_get_buffer_count(cp->stream)) {
				pvr2_stream_set_buffer_count(cp->stream,0);
			}
			cp->stream = NULL;
		}
		if (sp) {
			pvr2_trace(PVR2_TRACE_START_STOP,
				   "/*---TRACE_READ---*/"
				   " pvr2_ioread_setup (setup) id=%p",cp);
			pvr2_stream_kill(sp);
			ret = pvr2_stream_set_buffer_count(sp,BUFFER_COUNT);
			if (ret < 0) {
				mutex_unlock(&cp->mutex);
				return ret;
			}
			for (idx = 0; idx < BUFFER_COUNT; idx++) {
				bp = pvr2_stream_get_buffer(sp,idx);
				pvr2_buffer_set_buffer(bp,
						       cp->buffer_storage[idx],
						       BUFFER_SIZE);
			}
			cp->stream = sp;
		}
	} while (0); mutex_unlock(&cp->mutex);

	return 0;
}

int pvr2_ioread_set_enabled(struct pvr2_ioread *cp,int fl)
{
	int ret = 0;
	if ((!fl) == (!(cp->enabled))) return ret;

	mutex_lock(&cp->mutex); do {
		if (fl) {
			ret = pvr2_ioread_start(cp);
		} else {
			pvr2_ioread_stop(cp);
		}
	} while (0); mutex_unlock(&cp->mutex);
	return ret;
}

static int pvr2_ioread_get_buffer(struct pvr2_ioread *cp)
{
	int stat;

	while (cp->c_data_len <= cp->c_data_offs) {
		if (cp->c_buf) {
			// Flush out current buffer first.
			stat = pvr2_buffer_queue(cp->c_buf);
			if (stat < 0) {
				// Streaming error...
				pvr2_trace(PVR2_TRACE_DATA_FLOW,
					   "/*---TRACE_READ---*/"
					   " pvr2_ioread_read id=%p"
					   " queue_error=%d",
					   cp,stat);
				pvr2_ioread_stop(cp);
				return 0;
			}
			cp->c_buf = NULL;
			cp->c_data_ptr = NULL;
			cp->c_data_len = 0;
			cp->c_data_offs = 0;
		}
		// Now get a freshly filled buffer.
		cp->c_buf = pvr2_stream_get_ready_buffer(cp->stream);
		if (!cp->c_buf) break; // Nothing ready; done.
		cp->c_data_len = pvr2_buffer_get_count(cp->c_buf);
		if (!cp->c_data_len) {
			// Nothing transferred.  Was there an error?
			stat = pvr2_buffer_get_status(cp->c_buf);
			if (stat < 0) {
				// Streaming error...
				pvr2_trace(PVR2_TRACE_DATA_FLOW,
					   "/*---TRACE_READ---*/"
					   " pvr2_ioread_read id=%p"
					   " buffer_error=%d",
					   cp,stat);
				pvr2_ioread_stop(cp);
				// Give up.
				return 0;
			}
			// Start over...
			continue;
		}
		cp->c_data_offs = 0;
		cp->c_data_ptr = cp->buffer_storage[
			pvr2_buffer_get_id(cp->c_buf)];
	}
	return !0;
}

static void pvr2_ioread_filter(struct pvr2_ioread *cp)
{
	unsigned int idx;
	if (!cp->enabled) return;
	if (cp->sync_state != 1) return;

	// Search the stream for our synchronization key.  This is made
	// complicated by the fact that in order to be honest with
	// ourselves here we must search across buffer boundaries...
	mutex_lock(&cp->mutex); while (1) {
		// Ensure we have a buffer
		if (!pvr2_ioread_get_buffer(cp)) break;
		if (!cp->c_data_len) break;

		// Now walk the buffer contents until we match the key or
		// run out of buffer data.
		for (idx = cp->c_data_offs; idx < cp->c_data_len; idx++) {
			if (cp->sync_buf_offs >= cp->sync_key_len) break;
			if (cp->c_data_ptr[idx] ==
			    cp->sync_key_ptr[cp->sync_buf_offs]) {
				// Found the next key byte
				(cp->sync_buf_offs)++;
			} else {
				// Whoops, mismatched.  Start key over...
				cp->sync_buf_offs = 0;
			}
		}

		// Consume what we've walked through
		cp->c_data_offs += idx;
		cp->sync_trashed_count += idx;

		// If we've found the key, then update state and get out.
		if (cp->sync_buf_offs >= cp->sync_key_len) {
			cp->sync_trashed_count -= cp->sync_key_len;
			pvr2_trace(PVR2_TRACE_DATA_FLOW,
				   "/*---TRACE_READ---*/"
				   " sync_state <== 2 (skipped %u bytes)",
				   cp->sync_trashed_count);
			cp->sync_state = 2;
			cp->sync_buf_offs = 0;
			break;
		}

		if (cp->c_data_offs < cp->c_data_len) {
			// Sanity check - should NEVER get here
			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
				   "ERROR: pvr2_ioread filter sync problem"
				   " len=%u offs=%u",
				   cp->c_data_len,cp->c_data_offs);
			// Get out so we don't get stuck in an infinite
			// loop.
			break;
		}

		continue; // (for clarity)
	} mutex_unlock(&cp->mutex);
}

int pvr2_ioread_avail(struct pvr2_ioread *cp)
{
	int ret;
	if (!(cp->enabled)) {
		// Stream is not enabled; so this is an I/O error
		return -EIO;
	}

	if (cp->sync_state == 1) {
		pvr2_ioread_filter(cp);
		if (cp->sync_state == 1) return -EAGAIN;
	}

	ret = 0;
	if (cp->stream_running) {
		if (!pvr2_stream_get_ready_count(cp->stream)) {
			// No data available at all right now.
			ret = -EAGAIN;
		}
	} else {
		if (pvr2_stream_get_ready_count(cp->stream) < BUFFER_COUNT/2) {
			// Haven't buffered up enough yet; try again later
			ret = -EAGAIN;
		}
	}

	if ((!(cp->spigot_open)) != (!(ret == 0))) {
		cp->spigot_open = (ret == 0);
		pvr2_trace(PVR2_TRACE_DATA_FLOW,
			   "/*---TRACE_READ---*/ data is %s",
			   cp->spigot_open ? "available" : "pending");
	}

	return ret;
}

int pvr2_ioread_read(struct pvr2_ioread *cp,void __user *buf,unsigned int cnt)
{
	unsigned int copied_cnt;
	unsigned int bcnt;
	const char *src;
	int stat;
	int ret = 0;
	unsigned int req_cnt = cnt;

	if (!cnt) {
		pvr2_trace(PVR2_TRACE_TRAP,
			   "/*---TRACE_READ---*/ pvr2_ioread_read id=%p"
			   " ZERO Request? Returning zero.",cp);
		return 0;
	}

	stat = pvr2_ioread_avail(cp);
	if (stat < 0) return stat;

	cp->stream_running = !0;

	mutex_lock(&cp->mutex); do {

		// Suck data out of the buffers and copy to the user
		copied_cnt = 0;
		if (!buf) cnt = 0;
		while (1) {
			if (!pvr2_ioread_get_buffer(cp)) {
				ret = -EIO;
				break;
			}

			if (!cnt) break;

			if (cp->sync_state == 2) {
				// We're repeating the sync key data into
				// the stream.
				src = cp->sync_key_ptr + cp->sync_buf_offs;
				bcnt = cp->sync_key_len - cp->sync_buf_offs;
			} else {
				// Normal buffer copy
				src = cp->c_data_ptr + cp->c_data_offs;
				bcnt = cp->c_data_len - cp->c_data_offs;
			}

			if (!bcnt) break;

			// Don't run past user's buffer
			if (bcnt > cnt) bcnt = cnt;

			if (copy_to_user(buf,src,bcnt)) {
				// User supplied a bad pointer?
				// Give up - this *will* cause data
				// to be lost.
				ret = -EFAULT;
				break;
			}
			cnt -= bcnt;
			buf += bcnt;
			copied_cnt += bcnt;

			if (cp->sync_state == 2) {
				// Update offset inside sync key that we're
				// repeating back out.
				cp->sync_buf_offs += bcnt;
				if (cp->sync_buf_offs >= cp->sync_key_len) {
					// Consumed entire key; switch mode
					// to normal.
					pvr2_trace(PVR2_TRACE_DATA_FLOW,
						   "/*---TRACE_READ---*/"
						   " sync_state <== 0");
					cp->sync_state = 0;
				}
			} else {
				// Update buffer offset.
				cp->c_data_offs += bcnt;
			}
		}

	} while (0); mutex_unlock(&cp->mutex);

	if (!ret) {
		if (copied_cnt) {
			// If anything was copied, return that count
			ret = copied_cnt;
		} else {
			// Nothing copied; suggest to caller that another
			// attempt should be tried again later
			ret = -EAGAIN;
		}
	}

	pvr2_trace(PVR2_TRACE_DATA_FLOW,
		   "/*---TRACE_READ---*/ pvr2_ioread_read"
		   " id=%p request=%d result=%d",
		   cp,req_cnt,ret);
	return ret;
}


/*
  Stuff for Emacs to see, in order to encourage consistent editing style:
  *** Local Variables: ***
  *** mode: c ***
  *** fill-column: 75 ***
  *** tab-width: 8 ***
  *** c-basic-offset: 8 ***
  *** End: ***
  */
