/*
 * gh.c
 *
 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
 *
 * Copyright (C) 2005-2006 Texas Instruments, Inc.
 *
 * This package is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include <linux/types.h>

#include <dspbridge/host_os.h>
#include <dspbridge/gh.h>

struct element {
	struct element *next;
	u8 data[1];
};

struct gh_t_hash_tab {
	u16 max_bucket;
	u16 val_size;
	struct element **buckets;
	 u16(*hash) (void *, u16);
	 bool(*match) (void *, void *);
	void (*delete) (void *);
};

static void noop(void *p);

/*
 *  ======== gh_create ========
 */

struct gh_t_hash_tab *gh_create(u16 max_bucket, u16 val_size,
				u16(*hash) (void *, u16), bool(*match) (void *,
									void *),
				void (*delete) (void *))
{
	struct gh_t_hash_tab *hash_tab;
	u16 i;
	hash_tab = kzalloc(sizeof(struct gh_t_hash_tab), GFP_KERNEL);
	if (hash_tab == NULL)
		return NULL;
	hash_tab->max_bucket = max_bucket;
	hash_tab->val_size = val_size;
	hash_tab->hash = hash;
	hash_tab->match = match;
	hash_tab->delete = delete == NULL ? noop : delete;

	hash_tab->buckets =
	    kzalloc(sizeof(struct element *) * max_bucket, GFP_KERNEL);
	if (hash_tab->buckets == NULL) {
		gh_delete(hash_tab);
		return NULL;
	}

	for (i = 0; i < max_bucket; i++)
		hash_tab->buckets[i] = NULL;

	return hash_tab;
}

/*
 *  ======== gh_delete ========
 */
void gh_delete(struct gh_t_hash_tab *hash_tab)
{
	struct element *elem, *next;
	u16 i;

	if (hash_tab != NULL) {
		if (hash_tab->buckets != NULL) {
			for (i = 0; i < hash_tab->max_bucket; i++) {
				for (elem = hash_tab->buckets[i]; elem != NULL;
				     elem = next) {
					next = elem->next;
					(*hash_tab->delete) (elem->data);
					kfree(elem);
				}
			}

			kfree(hash_tab->buckets);
		}

		kfree(hash_tab);
	}
}

/*
 *  ======== gh_exit ========
 */

void gh_exit(void)
{
	/* Do nothing */
}

/*
 *  ======== gh_find ========
 */

void *gh_find(struct gh_t_hash_tab *hash_tab, void *key)
{
	struct element *elem;

	elem = hash_tab->buckets[(*hash_tab->hash) (key, hash_tab->max_bucket)];

	for (; elem; elem = elem->next) {
		if ((*hash_tab->match) (key, elem->data))
			return elem->data;
	}

	return NULL;
}

/*
 *  ======== gh_init ========
 */

void gh_init(void)
{
	/* Do nothing */
}

/*
 *  ======== gh_insert ========
 */

void *gh_insert(struct gh_t_hash_tab *hash_tab, void *key, void *value)
{
	struct element *elem;
	u16 i;
	char *src, *dst;

	elem = kzalloc(sizeof(struct element) - 1 + hash_tab->val_size,
			GFP_KERNEL);
	if (elem != NULL) {

		dst = (char *)elem->data;
		src = (char *)value;
		for (i = 0; i < hash_tab->val_size; i++)
			*dst++ = *src++;

		i = (*hash_tab->hash) (key, hash_tab->max_bucket);
		elem->next = hash_tab->buckets[i];
		hash_tab->buckets[i] = elem;

		return elem->data;
	}

	return NULL;
}

/*
 *  ======== noop ========
 */
/* ARGSUSED */
static void noop(void *p)
{
	p = p;			/* stifle compiler warning */
}

#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
/**
 * gh_iterate() - This function goes through all the elements in the hash table
 *		looking for the dsp symbols.
 * @hash_tab:	Hash table
 * @callback:	pointer to callback function
 * @user_data:	User data, contains the find_symbol_context pointer
 *
 */
void gh_iterate(struct gh_t_hash_tab *hash_tab,
		void (*callback)(void *, void *), void *user_data)
{
	struct element *elem;
	u32 i;

	if (hash_tab && hash_tab->buckets)
		for (i = 0; i < hash_tab->max_bucket; i++) {
			elem = hash_tab->buckets[i];
			while (elem) {
				callback(&elem->data, user_data);
				elem = elem->next;
			}
		}
}
#endif
