/*
 * 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_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_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
