/*
 *
 *  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-context.h"
#include "pvrusb2-io.h"
#include "pvrusb2-ioread.h"
#include "pvrusb2-hdw.h"
#include "pvrusb2-debug.h"
#include <linux/wait.h>
#include <linux/kthread.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/slab.h>

static struct pvr2_context *pvr2_context_exist_first;
static struct pvr2_context *pvr2_context_exist_last;
static struct pvr2_context *pvr2_context_notify_first;
static struct pvr2_context *pvr2_context_notify_last;
static DEFINE_MUTEX(pvr2_context_mutex);
static DECLARE_WAIT_QUEUE_HEAD(pvr2_context_sync_data);
static DECLARE_WAIT_QUEUE_HEAD(pvr2_context_cleanup_data);
static int pvr2_context_cleanup_flag;
static int pvr2_context_cleaned_flag;
static struct task_struct *pvr2_context_thread_ptr;


static void pvr2_context_set_notify(struct pvr2_context *mp, int fl)
{
	int signal_flag = 0;
	mutex_lock(&pvr2_context_mutex);
	if (fl) {
		if (!mp->notify_flag) {
			signal_flag = (pvr2_context_notify_first == NULL);
			mp->notify_prev = pvr2_context_notify_last;
			mp->notify_next = NULL;
			pvr2_context_notify_last = mp;
			if (mp->notify_prev) {
				mp->notify_prev->notify_next = mp;
			} else {
				pvr2_context_notify_first = mp;
			}
			mp->notify_flag = !0;
		}
	} else {
		if (mp->notify_flag) {
			mp->notify_flag = 0;
			if (mp->notify_next) {
				mp->notify_next->notify_prev = mp->notify_prev;
			} else {
				pvr2_context_notify_last = mp->notify_prev;
			}
			if (mp->notify_prev) {
				mp->notify_prev->notify_next = mp->notify_next;
			} else {
				pvr2_context_notify_first = mp->notify_next;
			}
		}
	}
	mutex_unlock(&pvr2_context_mutex);
	if (signal_flag) wake_up(&pvr2_context_sync_data);
}


static void pvr2_context_destroy(struct pvr2_context *mp)
{
	pvr2_trace(PVR2_TRACE_CTXT,"pvr2_context %p (destroy)",mp);
	pvr2_hdw_destroy(mp->hdw);
	pvr2_context_set_notify(mp, 0);
	mutex_lock(&pvr2_context_mutex);
	if (mp->exist_next) {
		mp->exist_next->exist_prev = mp->exist_prev;
	} else {
		pvr2_context_exist_last = mp->exist_prev;
	}
	if (mp->exist_prev) {
		mp->exist_prev->exist_next = mp->exist_next;
	} else {
		pvr2_context_exist_first = mp->exist_next;
	}
	if (!pvr2_context_exist_first) {
		/* Trigger wakeup on control thread in case it is waiting
		   for an exit condition. */
		wake_up(&pvr2_context_sync_data);
	}
	mutex_unlock(&pvr2_context_mutex);
	kfree(mp);
}


static void pvr2_context_notify(struct pvr2_context *mp)
{
	pvr2_context_set_notify(mp,!0);
}


static void pvr2_context_check(struct pvr2_context *mp)
{
	struct pvr2_channel *ch1, *ch2;
	pvr2_trace(PVR2_TRACE_CTXT,
		   "pvr2_context %p (notify)", mp);
	if (!mp->initialized_flag && !mp->disconnect_flag) {
		mp->initialized_flag = !0;
		pvr2_trace(PVR2_TRACE_CTXT,
			   "pvr2_context %p (initialize)", mp);
		/* Finish hardware initialization */
		if (pvr2_hdw_initialize(mp->hdw,
					(void (*)(void *))pvr2_context_notify,
					mp)) {
			mp->video_stream.stream =
				pvr2_hdw_get_video_stream(mp->hdw);
			/* Trigger interface initialization.  By doing this
			   here initialization runs in our own safe and
			   cozy thread context. */
			if (mp->setup_func) mp->setup_func(mp);
		} else {
			pvr2_trace(PVR2_TRACE_CTXT,
				   "pvr2_context %p (thread skipping setup)",
				   mp);
			/* Even though initialization did not succeed,
			   we're still going to continue anyway.  We need
			   to do this in order to await the expected
			   disconnect (which we will detect in the normal
			   course of operation). */
		}
	}

	for (ch1 = mp->mc_first; ch1; ch1 = ch2) {
		ch2 = ch1->mc_next;
		if (ch1->check_func) ch1->check_func(ch1);
	}

	if (mp->disconnect_flag && !mp->mc_first) {
		/* Go away... */
		pvr2_context_destroy(mp);
		return;
	}
}


static int pvr2_context_shutok(void)
{
	return pvr2_context_cleanup_flag && (pvr2_context_exist_first == NULL);
}


static int pvr2_context_thread_func(void *foo)
{
	struct pvr2_context *mp;

	pvr2_trace(PVR2_TRACE_CTXT,"pvr2_context thread start");

	do {
		while ((mp = pvr2_context_notify_first) != NULL) {
			pvr2_context_set_notify(mp, 0);
			pvr2_context_check(mp);
		}
		wait_event_interruptible(
			pvr2_context_sync_data,
			((pvr2_context_notify_first != NULL) ||
			 pvr2_context_shutok()));
	} while (!pvr2_context_shutok());

	pvr2_context_cleaned_flag = !0;
	wake_up(&pvr2_context_cleanup_data);

	pvr2_trace(PVR2_TRACE_CTXT,"pvr2_context thread cleaned up");

	wait_event_interruptible(
		pvr2_context_sync_data,
		kthread_should_stop());

	pvr2_trace(PVR2_TRACE_CTXT,"pvr2_context thread end");

	return 0;
}


int pvr2_context_global_init(void)
{
	pvr2_context_thread_ptr = kthread_run(pvr2_context_thread_func,
					      NULL,
					      "pvrusb2-context");
	return (pvr2_context_thread_ptr ? 0 : -ENOMEM);
}


void pvr2_context_global_done(void)
{
	pvr2_context_cleanup_flag = !0;
	wake_up(&pvr2_context_sync_data);
	wait_event_interruptible(
		pvr2_context_cleanup_data,
		pvr2_context_cleaned_flag);
	kthread_stop(pvr2_context_thread_ptr);
}


struct pvr2_context *pvr2_context_create(
	struct usb_interface *intf,
	const struct usb_device_id *devid,
	void (*setup_func)(struct pvr2_context *))
{
	struct pvr2_context *mp = NULL;
	mp = kzalloc(sizeof(*mp),GFP_KERNEL);
	if (!mp) goto done;
	pvr2_trace(PVR2_TRACE_CTXT,"pvr2_context %p (create)",mp);
	mp->setup_func = setup_func;
	mutex_init(&mp->mutex);
	mutex_lock(&pvr2_context_mutex);
	mp->exist_prev = pvr2_context_exist_last;
	mp->exist_next = NULL;
	pvr2_context_exist_last = mp;
	if (mp->exist_prev) {
		mp->exist_prev->exist_next = mp;
	} else {
		pvr2_context_exist_first = mp;
	}
	mutex_unlock(&pvr2_context_mutex);
	mp->hdw = pvr2_hdw_create(intf,devid);
	if (!mp->hdw) {
		pvr2_context_destroy(mp);
		mp = NULL;
		goto done;
	}
	pvr2_context_set_notify(mp, !0);
 done:
	return mp;
}


static void pvr2_context_reset_input_limits(struct pvr2_context *mp)
{
	unsigned int tmsk,mmsk;
	struct pvr2_channel *cp;
	struct pvr2_hdw *hdw = mp->hdw;
	mmsk = pvr2_hdw_get_input_available(hdw);
	tmsk = mmsk;
	for (cp = mp->mc_first; cp; cp = cp->mc_next) {
		if (!cp->input_mask) continue;
		tmsk &= cp->input_mask;
	}
	pvr2_hdw_set_input_allowed(hdw,mmsk,tmsk);
	pvr2_hdw_commit_ctl(hdw);
}


static void pvr2_context_enter(struct pvr2_context *mp)
{
	mutex_lock(&mp->mutex);
}


static void pvr2_context_exit(struct pvr2_context *mp)
{
	int destroy_flag = 0;
	if (!(mp->mc_first || !mp->disconnect_flag)) {
		destroy_flag = !0;
	}
	mutex_unlock(&mp->mutex);
	if (destroy_flag) pvr2_context_notify(mp);
}


void pvr2_context_disconnect(struct pvr2_context *mp)
{
	pvr2_hdw_disconnect(mp->hdw);
	mp->disconnect_flag = !0;
	pvr2_context_notify(mp);
}


void pvr2_channel_init(struct pvr2_channel *cp,struct pvr2_context *mp)
{
	pvr2_context_enter(mp);
	cp->hdw = mp->hdw;
	cp->mc_head = mp;
	cp->mc_next = NULL;
	cp->mc_prev = mp->mc_last;
	if (mp->mc_last) {
		mp->mc_last->mc_next = cp;
	} else {
		mp->mc_first = cp;
	}
	mp->mc_last = cp;
	pvr2_context_exit(mp);
}


static void pvr2_channel_disclaim_stream(struct pvr2_channel *cp)
{
	if (!cp->stream) return;
	pvr2_stream_kill(cp->stream->stream);
	cp->stream->user = NULL;
	cp->stream = NULL;
}


void pvr2_channel_done(struct pvr2_channel *cp)
{
	struct pvr2_context *mp = cp->mc_head;
	pvr2_context_enter(mp);
	cp->input_mask = 0;
	pvr2_channel_disclaim_stream(cp);
	pvr2_context_reset_input_limits(mp);
	if (cp->mc_next) {
		cp->mc_next->mc_prev = cp->mc_prev;
	} else {
		mp->mc_last = cp->mc_prev;
	}
	if (cp->mc_prev) {
		cp->mc_prev->mc_next = cp->mc_next;
	} else {
		mp->mc_first = cp->mc_next;
	}
	cp->hdw = NULL;
	pvr2_context_exit(mp);
}


int pvr2_channel_limit_inputs(struct pvr2_channel *cp,unsigned int cmsk)
{
	unsigned int tmsk,mmsk;
	int ret = 0;
	struct pvr2_channel *p2;
	struct pvr2_hdw *hdw = cp->hdw;

	mmsk = pvr2_hdw_get_input_available(hdw);
	cmsk &= mmsk;
	if (cmsk == cp->input_mask) {
		/* No change; nothing to do */
		return 0;
	}

	pvr2_context_enter(cp->mc_head);
	do {
		if (!cmsk) {
			cp->input_mask = 0;
			pvr2_context_reset_input_limits(cp->mc_head);
			break;
		}
		tmsk = mmsk;
		for (p2 = cp->mc_head->mc_first; p2; p2 = p2->mc_next) {
			if (p2 == cp) continue;
			if (!p2->input_mask) continue;
			tmsk &= p2->input_mask;
		}
		if (!(tmsk & cmsk)) {
			ret = -EPERM;
			break;
		}
		tmsk &= cmsk;
		if ((ret = pvr2_hdw_set_input_allowed(hdw,mmsk,tmsk)) != 0) {
			/* Internal failure changing allowed list; probably
			   should not happen, but react if it does. */
			break;
		}
		cp->input_mask = cmsk;
		pvr2_hdw_commit_ctl(hdw);
	} while (0);
	pvr2_context_exit(cp->mc_head);
	return ret;
}


unsigned int pvr2_channel_get_limited_inputs(struct pvr2_channel *cp)
{
	return cp->input_mask;
}


int pvr2_channel_claim_stream(struct pvr2_channel *cp,
			      struct pvr2_context_stream *sp)
{
	int code = 0;
	pvr2_context_enter(cp->mc_head); do {
		if (sp == cp->stream) break;
		if (sp && sp->user) {
			code = -EBUSY;
			break;
		}
		pvr2_channel_disclaim_stream(cp);
		if (!sp) break;
		sp->user = cp;
		cp->stream = sp;
	} while (0);
	pvr2_context_exit(cp->mc_head);
	return code;
}


// This is the marker for the real beginning of a legitimate mpeg2 stream.
static char stream_sync_key[] = {
	0x00, 0x00, 0x01, 0xba,
};

struct pvr2_ioread *pvr2_channel_create_mpeg_stream(
	struct pvr2_context_stream *sp)
{
	struct pvr2_ioread *cp;
	cp = pvr2_ioread_create();
	if (!cp) return NULL;
	pvr2_ioread_setup(cp,sp->stream);
	pvr2_ioread_set_sync_key(cp,stream_sync_key,sizeof(stream_sync_key));
	return cp;
}
