• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/staging/tidspbridge/gen/
1/*
2 * gh.c
3 *
4 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
5 *
6 * Copyright (C) 2005-2006 Texas Instruments, Inc.
7 *
8 * This package is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
13 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
14 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
15 */
16
17#include <linux/types.h>
18
19#include <dspbridge/host_os.h>
20
21#include <dspbridge/gs.h>
22
23#include <dspbridge/gh.h>
24
25struct element {
26	struct element *next;
27	u8 data[1];
28};
29
30struct gh_t_hash_tab {
31	u16 max_bucket;
32	u16 val_size;
33	struct element **buckets;
34	 u16(*hash) (void *, u16);
35	 bool(*match) (void *, void *);
36	void (*delete) (void *);
37};
38
39static void noop(void *p);
40static s32 cur_init;
41static void myfree(void *ptr, s32 size);
42
43/*
44 *  ======== gh_create ========
45 */
46
47struct gh_t_hash_tab *gh_create(u16 max_bucket, u16 val_size,
48				u16(*hash) (void *, u16), bool(*match) (void *,
49									void *),
50				void (*delete) (void *))
51{
52	struct gh_t_hash_tab *hash_tab;
53	u16 i;
54	hash_tab =
55	    (struct gh_t_hash_tab *)gs_alloc(sizeof(struct gh_t_hash_tab));
56	if (hash_tab == NULL)
57		return NULL;
58	hash_tab->max_bucket = max_bucket;
59	hash_tab->val_size = val_size;
60	hash_tab->hash = hash;
61	hash_tab->match = match;
62	hash_tab->delete = delete == NULL ? noop : delete;
63
64	hash_tab->buckets = (struct element **)
65	    gs_alloc(sizeof(struct element *) * max_bucket);
66	if (hash_tab->buckets == NULL) {
67		gh_delete(hash_tab);
68		return NULL;
69	}
70
71	for (i = 0; i < max_bucket; i++)
72		hash_tab->buckets[i] = NULL;
73
74	return hash_tab;
75}
76
77/*
78 *  ======== gh_delete ========
79 */
80void gh_delete(struct gh_t_hash_tab *hash_tab)
81{
82	struct element *elem, *next;
83	u16 i;
84
85	if (hash_tab != NULL) {
86		if (hash_tab->buckets != NULL) {
87			for (i = 0; i < hash_tab->max_bucket; i++) {
88				for (elem = hash_tab->buckets[i]; elem != NULL;
89				     elem = next) {
90					next = elem->next;
91					(*hash_tab->delete) (elem->data);
92					myfree(elem,
93					       sizeof(struct element) - 1 +
94					       hash_tab->val_size);
95				}
96			}
97
98			myfree(hash_tab->buckets, sizeof(struct element *)
99			       * hash_tab->max_bucket);
100		}
101
102		myfree(hash_tab, sizeof(struct gh_t_hash_tab));
103	}
104}
105
106/*
107 *  ======== gh_exit ========
108 */
109
110void gh_exit(void)
111{
112	if (cur_init-- == 1)
113		gs_exit();
114
115}
116
117/*
118 *  ======== gh_find ========
119 */
120
121void *gh_find(struct gh_t_hash_tab *hash_tab, void *key)
122{
123	struct element *elem;
124
125	elem = hash_tab->buckets[(*hash_tab->hash) (key, hash_tab->max_bucket)];
126
127	for (; elem; elem = elem->next) {
128		if ((*hash_tab->match) (key, elem->data))
129			return elem->data;
130	}
131
132	return NULL;
133}
134
135/*
136 *  ======== gh_init ========
137 */
138
139void gh_init(void)
140{
141	if (cur_init++ == 0)
142		gs_init();
143}
144
145/*
146 *  ======== gh_insert ========
147 */
148
149void *gh_insert(struct gh_t_hash_tab *hash_tab, void *key, void *value)
150{
151	struct element *elem;
152	u16 i;
153	char *src, *dst;
154
155	elem = (struct element *)gs_alloc(sizeof(struct element) - 1 +
156					  hash_tab->val_size);
157	if (elem != NULL) {
158
159		dst = (char *)elem->data;
160		src = (char *)value;
161		for (i = 0; i < hash_tab->val_size; i++)
162			*dst++ = *src++;
163
164		i = (*hash_tab->hash) (key, hash_tab->max_bucket);
165		elem->next = hash_tab->buckets[i];
166		hash_tab->buckets[i] = elem;
167
168		return elem->data;
169	}
170
171	return NULL;
172}
173
174/*
175 *  ======== noop ========
176 */
177/* ARGSUSED */
178static void noop(void *p)
179{
180	p = p;			/* stifle compiler warning */
181}
182
183/*
184 *  ======== myfree ========
185 */
186static void myfree(void *ptr, s32 size)
187{
188	gs_free(ptr);
189}
190
191#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
192/**
193 * gh_iterate() - This function goes through all the elements in the hash table
194 *		looking for the dsp symbols.
195 * @hash_tab:	Hash table
196 * @callback:	pointer to callback function
197 * @user_data:	User data, contains the find_symbol_context pointer
198 *
199 */
200void gh_iterate(struct gh_t_hash_tab *hash_tab,
201		void (*callback)(void *, void *), void *user_data)
202{
203	struct element *elem;
204	u32 i;
205
206	if (hash_tab && hash_tab->buckets)
207		for (i = 0; i < hash_tab->max_bucket; i++) {
208			elem = hash_tab->buckets[i];
209			while (elem) {
210				callback(&elem->data, user_data);
211				elem = elem->next;
212			}
213		}
214}
215#endif
216