/*
 * OSS compatible sequencer driver
 *
 * seq_oss_readq.c - MIDI input queue
 *
 * Copyright (C) 1998,99 Takashi Iwai <tiwai@suse.de>
 *
 * 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, 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 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 "seq_oss_readq.h"
#include "seq_oss_event.h"
#include <sound/seq_oss_legacy.h>
#include "../seq_lock.h"
#include <linux/wait.h>
#include <linux/slab.h>

/*
 * constants
 */
//#define SNDRV_SEQ_OSS_MAX_TIMEOUT	(unsigned long)(-1)
#define SNDRV_SEQ_OSS_MAX_TIMEOUT	(HZ * 3600)


/*
 * prototypes
 */


/*
 * create a read queue
 */
struct seq_oss_readq *
snd_seq_oss_readq_new(struct seq_oss_devinfo *dp, int maxlen)
{
	struct seq_oss_readq *q;

	if ((q = kzalloc(sizeof(*q), GFP_KERNEL)) == NULL) {
		pr_err("ALSA: seq_oss: can't malloc read queue\n");
		return NULL;
	}

	if ((q->q = kcalloc(maxlen, sizeof(union evrec), GFP_KERNEL)) == NULL) {
		pr_err("ALSA: seq_oss: can't malloc read queue buffer\n");
		kfree(q);
		return NULL;
	}

	q->maxlen = maxlen;
	q->qlen = 0;
	q->head = q->tail = 0;
	init_waitqueue_head(&q->midi_sleep);
	spin_lock_init(&q->lock);
	q->pre_event_timeout = SNDRV_SEQ_OSS_MAX_TIMEOUT;
	q->input_time = (unsigned long)-1;

	return q;
}

/*
 * delete the read queue
 */
void
snd_seq_oss_readq_delete(struct seq_oss_readq *q)
{
	if (q) {
		kfree(q->q);
		kfree(q);
	}
}

/*
 * reset the read queue
 */
void
snd_seq_oss_readq_clear(struct seq_oss_readq *q)
{
	if (q->qlen) {
		q->qlen = 0;
		q->head = q->tail = 0;
	}
	/* if someone sleeping, wake'em up */
	if (waitqueue_active(&q->midi_sleep))
		wake_up(&q->midi_sleep);
	q->input_time = (unsigned long)-1;
}

/*
 * put a midi byte
 */
int
snd_seq_oss_readq_puts(struct seq_oss_readq *q, int dev, unsigned char *data, int len)
{
	union evrec rec;
	int result;

	memset(&rec, 0, sizeof(rec));
	rec.c[0] = SEQ_MIDIPUTC;
	rec.c[2] = dev;

	while (len-- > 0) {
		rec.c[1] = *data++;
		result = snd_seq_oss_readq_put_event(q, &rec);
		if (result < 0)
			return result;
	}
	return 0;
}

/*
 * copy an event to input queue:
 * return zero if enqueued
 */
int
snd_seq_oss_readq_put_event(struct seq_oss_readq *q, union evrec *ev)
{
	unsigned long flags;

	spin_lock_irqsave(&q->lock, flags);
	if (q->qlen >= q->maxlen - 1) {
		spin_unlock_irqrestore(&q->lock, flags);
		return -ENOMEM;
	}

	memcpy(&q->q[q->tail], ev, sizeof(*ev));
	q->tail = (q->tail + 1) % q->maxlen;
	q->qlen++;

	/* wake up sleeper */
	if (waitqueue_active(&q->midi_sleep))
		wake_up(&q->midi_sleep);

	spin_unlock_irqrestore(&q->lock, flags);

	return 0;
}


/*
 * pop queue
 * caller must hold lock
 */
int
snd_seq_oss_readq_pick(struct seq_oss_readq *q, union evrec *rec)
{
	if (q->qlen == 0)
		return -EAGAIN;
	memcpy(rec, &q->q[q->head], sizeof(*rec));
	return 0;
}

/*
 * sleep until ready
 */
void
snd_seq_oss_readq_wait(struct seq_oss_readq *q)
{
	wait_event_interruptible_timeout(q->midi_sleep,
					 (q->qlen > 0 || q->head == q->tail),
					 q->pre_event_timeout);
}

/*
 * drain one record
 * caller must hold lock
 */
void
snd_seq_oss_readq_free(struct seq_oss_readq *q)
{
	if (q->qlen > 0) {
		q->head = (q->head + 1) % q->maxlen;
		q->qlen--;
	}
}

/*
 * polling/select:
 * return non-zero if readq is not empty.
 */
unsigned int
snd_seq_oss_readq_poll(struct seq_oss_readq *q, struct file *file, poll_table *wait)
{
	poll_wait(file, &q->midi_sleep, wait);
	return q->qlen;
}

/*
 * put a timestamp
 */
int
snd_seq_oss_readq_put_timestamp(struct seq_oss_readq *q, unsigned long curt, int seq_mode)
{
	if (curt != q->input_time) {
		union evrec rec;
		memset(&rec, 0, sizeof(rec));
		switch (seq_mode) {
		case SNDRV_SEQ_OSS_MODE_SYNTH:
			rec.echo = (curt << 8) | SEQ_WAIT;
			snd_seq_oss_readq_put_event(q, &rec);
			break;
		case SNDRV_SEQ_OSS_MODE_MUSIC:
			rec.t.code = EV_TIMING;
			rec.t.cmd = TMR_WAIT_ABS;
			rec.t.time = curt;
			snd_seq_oss_readq_put_event(q, &rec);
			break;
		}
		q->input_time = curt;
	}
	return 0;
}


#ifdef CONFIG_PROC_FS
/*
 * proc interface
 */
void
snd_seq_oss_readq_info_read(struct seq_oss_readq *q, struct snd_info_buffer *buf)
{
	snd_iprintf(buf, "  read queue [%s] length = %d : tick = %ld\n",
		    (waitqueue_active(&q->midi_sleep) ? "sleeping":"running"),
		    q->qlen, q->input_time);
}
#endif /* CONFIG_PROC_FS */
