staging: tidspbridge: remove std.h
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / staging / tidspbridge / gen / gh.c
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
25 struct element {
26         struct element *next;
27         u8 data[1];
28 };
29
30 struct 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
39 static void noop(void *p);
40 static s32 cur_init;
41 static void myfree(void *ptr, s32 size);
42
43 /*
44  *  ======== gh_create ========
45  */
46
47 struct 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  */
80 void 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
110 void gh_exit(void)
111 {
112         if (cur_init-- == 1)
113                 gs_exit();
114
115 }
116
117 /*
118  *  ======== gh_find ========
119  */
120
121 void *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
139 void gh_init(void)
140 {
141         if (cur_init++ == 0)
142                 gs_init();
143 }
144
145 /*
146  *  ======== gh_insert ========
147  */
148
149 void *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 */
178 static void noop(void *p)
179 {
180         p = p;                  /* stifle compiler warning */
181 }
182
183 /*
184  *  ======== myfree ========
185  */
186 static 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  */
200 void 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