/*
 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
 * All Rights Reserved.
 *
 * 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.
 *
 * This program is distributed in the hope that it would 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 the Free Software Foundation,
 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
#include <xfs.h>

static kmem_zone_t *ktrace_hdr_zone;
static kmem_zone_t *ktrace_ent_zone;
static int          ktrace_zentries;

void
ktrace_init(int zentries)
{
	ktrace_zentries = zentries;

	ktrace_hdr_zone = kmem_zone_init(sizeof(ktrace_t),
					"ktrace_hdr");
	ASSERT(ktrace_hdr_zone);

	ktrace_ent_zone = kmem_zone_init(ktrace_zentries
					* sizeof(ktrace_entry_t),
					"ktrace_ent");
	ASSERT(ktrace_ent_zone);
}

void
ktrace_uninit(void)
{
	kmem_zone_destroy(ktrace_hdr_zone);
	kmem_zone_destroy(ktrace_ent_zone);
}

/*
 * ktrace_alloc()
 *
 * Allocate a ktrace header and enough buffering for the given
 * number of entries.
 */
ktrace_t *
ktrace_alloc(int nentries, unsigned int __nocast sleep)
{
	ktrace_t        *ktp;
	ktrace_entry_t  *ktep;

	ktp = (ktrace_t*)kmem_zone_alloc(ktrace_hdr_zone, sleep);

	if (ktp == (ktrace_t*)NULL) {
		/*
		 * KM_SLEEP callers don't expect failure.
		 */
		if (sleep & KM_SLEEP)
			panic("ktrace_alloc: NULL memory on KM_SLEEP request!");

		return NULL;
	}

	/*
	 * Special treatment for buffers with the ktrace_zentries entries
	 */
	if (nentries == ktrace_zentries) {
		ktep = (ktrace_entry_t*)kmem_zone_zalloc(ktrace_ent_zone,
							    sleep);
	} else {
		ktep = (ktrace_entry_t*)kmem_zalloc((nentries * sizeof(*ktep)),
							    sleep);
	}

	if (ktep == NULL) {
		/*
		 * KM_SLEEP callers don't expect failure.
		 */
		if (sleep & KM_SLEEP)
			panic("ktrace_alloc: NULL memory on KM_SLEEP request!");

		kmem_free(ktp, sizeof(*ktp));

		return NULL;
	}

	spinlock_init(&(ktp->kt_lock), "kt_lock");

	ktp->kt_entries  = ktep;
	ktp->kt_nentries = nentries;
	ktp->kt_index    = 0;
	ktp->kt_rollover = 0;
	return ktp;
}


/*
 * ktrace_free()
 *
 * Free up the ktrace header and buffer.  It is up to the caller
 * to ensure that no-one is referencing it.
 */
void
ktrace_free(ktrace_t *ktp)
{
	int     entries_size;

	if (ktp == (ktrace_t *)NULL)
		return;

	spinlock_destroy(&ktp->kt_lock);

	/*
	 * Special treatment for the Vnode trace buffer.
	 */
	if (ktp->kt_nentries == ktrace_zentries) {
		kmem_zone_free(ktrace_ent_zone, ktp->kt_entries);
	} else {
		entries_size = (int)(ktp->kt_nentries * sizeof(ktrace_entry_t));

		kmem_free(ktp->kt_entries, entries_size);
	}

	kmem_zone_free(ktrace_hdr_zone, ktp);
}


/*
 * Enter the given values into the "next" entry in the trace buffer.
 * kt_index is always the index of the next entry to be filled.
 */
void
ktrace_enter(
	ktrace_t        *ktp,
	void            *val0,
	void            *val1,
	void            *val2,
	void            *val3,
	void            *val4,
	void            *val5,
	void            *val6,
	void            *val7,
	void            *val8,
	void            *val9,
	void            *val10,
	void            *val11,
	void            *val12,
	void            *val13,
	void            *val14,
	void            *val15)
{
	static DEFINE_SPINLOCK(wrap_lock);
	unsigned long	flags;
	int             index;
	ktrace_entry_t  *ktep;

	ASSERT(ktp != NULL);

	/*
	 * Grab an entry by pushing the index up to the next one.
	 */
	spin_lock_irqsave(&wrap_lock, flags);
	index = ktp->kt_index;
	if (++ktp->kt_index == ktp->kt_nentries)
		ktp->kt_index = 0;
	spin_unlock_irqrestore(&wrap_lock, flags);

	if (!ktp->kt_rollover && index == ktp->kt_nentries - 1)
		ktp->kt_rollover = 1;

	ASSERT((index >= 0) && (index < ktp->kt_nentries));

	ktep = &(ktp->kt_entries[index]);

	ktep->val[0]  = val0;
	ktep->val[1]  = val1;
	ktep->val[2]  = val2;
	ktep->val[3]  = val3;
	ktep->val[4]  = val4;
	ktep->val[5]  = val5;
	ktep->val[6]  = val6;
	ktep->val[7]  = val7;
	ktep->val[8]  = val8;
	ktep->val[9]  = val9;
	ktep->val[10] = val10;
	ktep->val[11] = val11;
	ktep->val[12] = val12;
	ktep->val[13] = val13;
	ktep->val[14] = val14;
	ktep->val[15] = val15;
}

/*
 * Return the number of entries in the trace buffer.
 */
int
ktrace_nentries(
	ktrace_t        *ktp)
{
	if (ktp == NULL) {
		return 0;
	}

	return (ktp->kt_rollover ? ktp->kt_nentries : ktp->kt_index);
}

/*
 * ktrace_first()
 *
 * This is used to find the start of the trace buffer.
 * In conjunction with ktrace_next() it can be used to
 * iterate through the entire trace buffer.  This code does
 * not do any locking because it is assumed that it is called
 * from the debugger.
 *
 * The caller must pass in a pointer to a ktrace_snap
 * structure in which we will keep some state used to
 * iterate through the buffer.  This state must not touched
 * by any code outside of this module.
 */
ktrace_entry_t *
ktrace_first(ktrace_t   *ktp, ktrace_snap_t     *ktsp)
{
	ktrace_entry_t  *ktep;
	int             index;
	int             nentries;

	if (ktp->kt_rollover)
		index = ktp->kt_index;
	else
		index = 0;

	ktsp->ks_start = index;
	ktep = &(ktp->kt_entries[index]);

	nentries = ktrace_nentries(ktp);
	index++;
	if (index < nentries) {
		ktsp->ks_index = index;
	} else {
		ktsp->ks_index = 0;
		if (index > nentries)
			ktep = NULL;
	}
	return ktep;
}

/*
 * ktrace_next()
 *
 * This is used to iterate through the entries of the given
 * trace buffer.  The caller must pass in the ktrace_snap_t
 * structure initialized by ktrace_first().  The return value
 * will be either a pointer to the next ktrace_entry or NULL
 * if all of the entries have been traversed.
 */
ktrace_entry_t *
ktrace_next(
	ktrace_t        *ktp,
	ktrace_snap_t   *ktsp)
{
	int             index;
	ktrace_entry_t  *ktep;

	index = ktsp->ks_index;
	if (index == ktsp->ks_start) {
		ktep = NULL;
	} else {
		ktep = &ktp->kt_entries[index];
	}

	index++;
	if (index == ktrace_nentries(ktp)) {
		ktsp->ks_index = 0;
	} else {
		ktsp->ks_index = index;
	}

	return ktep;
}

/*
 * ktrace_skip()
 *
 * Skip the next "count" entries and return the entry after that.
 * Return NULL if this causes us to iterate past the beginning again.
 */
ktrace_entry_t *
ktrace_skip(
	ktrace_t        *ktp,
	int             count,
	ktrace_snap_t   *ktsp)
{
	int             index;
	int             new_index;
	ktrace_entry_t  *ktep;
	int             nentries = ktrace_nentries(ktp);

	index = ktsp->ks_index;
	new_index = index + count;
	while (new_index >= nentries) {
		new_index -= nentries;
	}
	if (index == ktsp->ks_start) {
		/*
		 * We've iterated around to the start, so we're done.
		 */
		ktep = NULL;
	} else if ((new_index < index) && (index < ktsp->ks_index)) {
		/*
		 * We've skipped past the start again, so we're done.
		 */
		ktep = NULL;
		ktsp->ks_index = ktsp->ks_start;
	} else {
		ktep = &(ktp->kt_entries[new_index]);
		new_index++;
		if (new_index == nentries) {
			ktsp->ks_index = 0;
		} else {
			ktsp->ks_index = new_index;
		}
	}
	return ktep;
}
