]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/staging/tidspbridge/gen/gh.c
25eaef782aaa1b46e530b1f5b363784d7b407f43
[karo-tx-linux.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 #include <dspbridge/gh.h>
21
22 struct element {
23         struct element *next;
24         u8 data[1];
25 };
26
27 struct gh_t_hash_tab {
28         u16 max_bucket;
29         u16 val_size;
30         struct element **buckets;
31          u16(*hash) (void *, u16);
32          bool(*match) (void *, void *);
33         void (*delete) (void *);
34 };
35
36 static void noop(void *p);
37
38 /*
39  *  ======== gh_create ========
40  */
41
42 struct gh_t_hash_tab *gh_create(u16 max_bucket, u16 val_size,
43                                 u16(*hash) (void *, u16), bool(*match) (void *,
44                                                                         void *),
45                                 void (*delete) (void *))
46 {
47         struct gh_t_hash_tab *hash_tab;
48         u16 i;
49         hash_tab = kzalloc(sizeof(struct gh_t_hash_tab), GFP_KERNEL);
50         if (hash_tab == NULL)
51                 return NULL;
52         hash_tab->max_bucket = max_bucket;
53         hash_tab->val_size = val_size;
54         hash_tab->hash = hash;
55         hash_tab->match = match;
56         hash_tab->delete = delete == NULL ? noop : delete;
57
58         hash_tab->buckets =
59             kzalloc(sizeof(struct element *) * max_bucket, GFP_KERNEL);
60         if (hash_tab->buckets == NULL) {
61                 gh_delete(hash_tab);
62                 return NULL;
63         }
64
65         for (i = 0; i < max_bucket; i++)
66                 hash_tab->buckets[i] = NULL;
67
68         return hash_tab;
69 }
70
71 /*
72  *  ======== gh_delete ========
73  */
74 void gh_delete(struct gh_t_hash_tab *hash_tab)
75 {
76         struct element *elem, *next;
77         u16 i;
78
79         if (hash_tab != NULL) {
80                 if (hash_tab->buckets != NULL) {
81                         for (i = 0; i < hash_tab->max_bucket; i++) {
82                                 for (elem = hash_tab->buckets[i]; elem != NULL;
83                                      elem = next) {
84                                         next = elem->next;
85                                         (*hash_tab->delete) (elem->data);
86                                         kfree(elem);
87                                 }
88                         }
89
90                         kfree(hash_tab->buckets);
91                 }
92
93                 kfree(hash_tab);
94         }
95 }
96
97 /*
98  *  ======== gh_find ========
99  */
100
101 void *gh_find(struct gh_t_hash_tab *hash_tab, void *key)
102 {
103         struct element *elem;
104
105         elem = hash_tab->buckets[(*hash_tab->hash) (key, hash_tab->max_bucket)];
106
107         for (; elem; elem = elem->next) {
108                 if ((*hash_tab->match) (key, elem->data))
109                         return elem->data;
110         }
111
112         return NULL;
113 }
114
115 /*
116  *  ======== gh_insert ========
117  */
118
119 void *gh_insert(struct gh_t_hash_tab *hash_tab, void *key, void *value)
120 {
121         struct element *elem;
122         u16 i;
123         char *src, *dst;
124
125         elem = kzalloc(sizeof(struct element) - 1 + hash_tab->val_size,
126                         GFP_KERNEL);
127         if (elem != NULL) {
128
129                 dst = (char *)elem->data;
130                 src = (char *)value;
131                 for (i = 0; i < hash_tab->val_size; i++)
132                         *dst++ = *src++;
133
134                 i = (*hash_tab->hash) (key, hash_tab->max_bucket);
135                 elem->next = hash_tab->buckets[i];
136                 hash_tab->buckets[i] = elem;
137
138                 return elem->data;
139         }
140
141         return NULL;
142 }
143
144 /*
145  *  ======== noop ========
146  */
147 /* ARGSUSED */
148 static void noop(void *p)
149 {
150         p = p;                  /* stifle compiler warning */
151 }
152
153 #ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
154 /**
155  * gh_iterate() - This function goes through all the elements in the hash table
156  *              looking for the dsp symbols.
157  * @hash_tab:   Hash table
158  * @callback:   pointer to callback function
159  * @user_data:  User data, contains the find_symbol_context pointer
160  *
161  */
162 void gh_iterate(struct gh_t_hash_tab *hash_tab,
163                 void (*callback)(void *, void *), void *user_data)
164 {
165         struct element *elem;
166         u32 i;
167
168         if (hash_tab && hash_tab->buckets)
169                 for (i = 0; i < hash_tab->max_bucket; i++) {
170                         elem = hash_tab->buckets[i];
171                         while (elem) {
172                                 callback(&elem->data, user_data);
173                                 elem = elem->next;
174                         }
175                 }
176 }
177 #endif