17227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna/*
27227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna * gh.c
37227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna *
47227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna * DSP-BIOS Bridge driver support functions for TI OMAP processors.
57227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna *
67227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna * Copyright (C) 2005-2006 Texas Instruments, Inc.
77227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna *
87227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna * This package is free software; you can redistribute it and/or modify
97227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna * it under the terms of the GNU General Public License version 2 as
107227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna * published by the Free Software Foundation.
117227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna *
127227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
137227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
147227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
157227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna */
167227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna
172094f12d440c5a9fae032932266fa4a44135194cNishanth Menon#include <linux/types.h>
187227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna
197227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna#include <dspbridge/host_os.h>
207227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna#include <dspbridge/gh.h>
217227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna
227227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Lunastruct element {
237227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	struct element *next;
247227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	u8 data[1];
257227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna};
267227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna
277227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Lunastruct gh_t_hash_tab {
287227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	u16 max_bucket;
297227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	u16 val_size;
307227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	struct element **buckets;
317227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	 u16(*hash) (void *, u16);
327227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	 bool(*match) (void *, void *);
337227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	void (*delete) (void *);
347227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna};
357227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna
367227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Lunastatic void noop(void *p);
377227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna
387227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna/*
397227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna *  ======== gh_create ========
407227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna */
417227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna
427227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Lunastruct gh_t_hash_tab *gh_create(u16 max_bucket, u16 val_size,
437227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna				u16(*hash) (void *, u16), bool(*match) (void *,
447227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna									void *),
457227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna				void (*delete) (void *))
467227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna{
477227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	struct gh_t_hash_tab *hash_tab;
487227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	u16 i;
4931de278078aeb869467cbde0877d7f1027ab844cIonut Nicu	hash_tab = kzalloc(sizeof(struct gh_t_hash_tab), GFP_KERNEL);
507227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	if (hash_tab == NULL)
517227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna		return NULL;
527227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	hash_tab->max_bucket = max_bucket;
537227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	hash_tab->val_size = val_size;
547227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	hash_tab->hash = hash;
557227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	hash_tab->match = match;
567227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	hash_tab->delete = delete == NULL ? noop : delete;
577227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna
588c670f4d157bcaba0001455ace554572b9b417efThomas Meyer	hash_tab->buckets =
5931de278078aeb869467cbde0877d7f1027ab844cIonut Nicu	    kzalloc(sizeof(struct element *) * max_bucket, GFP_KERNEL);
607227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	if (hash_tab->buckets == NULL) {
617227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna		gh_delete(hash_tab);
627227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna		return NULL;
637227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	}
647227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna
657227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	for (i = 0; i < max_bucket; i++)
667227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna		hash_tab->buckets[i] = NULL;
677227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna
687227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	return hash_tab;
697227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna}
707227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna
717227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna/*
727227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna *  ======== gh_delete ========
737227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna */
747227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Lunavoid gh_delete(struct gh_t_hash_tab *hash_tab)
757227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna{
767227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	struct element *elem, *next;
777227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	u16 i;
787227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna
797227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	if (hash_tab != NULL) {
807227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna		if (hash_tab->buckets != NULL) {
817227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna			for (i = 0; i < hash_tab->max_bucket; i++) {
827227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna				for (elem = hash_tab->buckets[i]; elem != NULL;
837227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna				     elem = next) {
847227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna					next = elem->next;
857227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna					(*hash_tab->delete) (elem->data);
8631de278078aeb869467cbde0877d7f1027ab844cIonut Nicu					kfree(elem);
877227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna				}
887227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna			}
897227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna
9031de278078aeb869467cbde0877d7f1027ab844cIonut Nicu			kfree(hash_tab->buckets);
917227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna		}
927227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna
9331de278078aeb869467cbde0877d7f1027ab844cIonut Nicu		kfree(hash_tab);
947227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	}
957227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna}
967227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna
977227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna/*
987227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna *  ======== gh_find ========
997227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna */
1007227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna
1017227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Lunavoid *gh_find(struct gh_t_hash_tab *hash_tab, void *key)
1027227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna{
1037227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	struct element *elem;
1047227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna
1057227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	elem = hash_tab->buckets[(*hash_tab->hash) (key, hash_tab->max_bucket)];
1067227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna
1077227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	for (; elem; elem = elem->next) {
1087227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna		if ((*hash_tab->match) (key, elem->data))
1097227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna			return elem->data;
1107227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	}
1117227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna
1127227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	return NULL;
1137227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna}
1147227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna
1157227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna/*
1167227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna *  ======== gh_insert ========
1177227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna */
1187227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna
1197227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Lunavoid *gh_insert(struct gh_t_hash_tab *hash_tab, void *key, void *value)
1207227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna{
1217227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	struct element *elem;
1227227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	u16 i;
1237227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	char *src, *dst;
1247227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna
12531de278078aeb869467cbde0877d7f1027ab844cIonut Nicu	elem = kzalloc(sizeof(struct element) - 1 + hash_tab->val_size,
12631de278078aeb869467cbde0877d7f1027ab844cIonut Nicu			GFP_KERNEL);
1277227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	if (elem != NULL) {
1287227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna
1297227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna		dst = (char *)elem->data;
1307227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna		src = (char *)value;
1317227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna		for (i = 0; i < hash_tab->val_size; i++)
1327227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna			*dst++ = *src++;
1337227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna
1347227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna		i = (*hash_tab->hash) (key, hash_tab->max_bucket);
1357227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna		elem->next = hash_tab->buckets[i];
1367227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna		hash_tab->buckets[i] = elem;
1377227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna
1387227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna		return elem->data;
1397227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	}
1407227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna
1417227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	return NULL;
1427227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna}
1437227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna
1447227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna/*
1457227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna *  ======== noop ========
1467227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna */
1477227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna/* ARGSUSED */
1487227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Lunastatic void noop(void *p)
1497227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna{
1507227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	p = p;			/* stifle compiler warning */
1517227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna}
1527227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna
1534f551c8f6b89902a83328fbf50585ec7ee03ed5aFelipe Contreras#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
1547227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna/**
1557227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna * gh_iterate() - This function goes through all the elements in the hash table
1567227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna *		looking for the dsp symbols.
1577227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna * @hash_tab:	Hash table
1587227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna * @callback:	pointer to callback function
1597227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna * @user_data:	User data, contains the find_symbol_context pointer
1607227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna *
1617227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna */
1627227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Lunavoid gh_iterate(struct gh_t_hash_tab *hash_tab,
1637227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna		void (*callback)(void *, void *), void *user_data)
1647227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna{
1657227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	struct element *elem;
1667227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	u32 i;
1677227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna
1687227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna	if (hash_tab && hash_tab->buckets)
1697227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna		for (i = 0; i < hash_tab->max_bucket; i++) {
1707227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna			elem = hash_tab->buckets[i];
1717227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna			while (elem) {
1727227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna				callback(&elem->data, user_data);
1737227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna				elem = elem->next;
1747227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna			}
1757227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna		}
1767227b671f7dd2f0d0c7cc700b184f0cdf5d6ee65Omar Ramirez Luna}
1774f551c8f6b89902a83328fbf50585ec7ee03ed5aFelipe Contreras#endif
178