Avoid beyond bounds copy while caching ACL
[zen-stable.git] / drivers / staging / tidspbridge / gen / gh.c
blob60aa7b063c91a60c03f1ddc3eafed714a5e40772
1 /*
2 * gh.c
4 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
6 * Copyright (C) 2005-2006 Texas Instruments, Inc.
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.
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.
17 #include <linux/types.h>
19 #include <dspbridge/host_os.h>
20 #include <dspbridge/gh.h>
22 struct element {
23 struct element *next;
24 u8 data[1];
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 *);
36 static void noop(void *p);
39 * ======== gh_create ========
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 *))
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;
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;
65 for (i = 0; i < max_bucket; i++)
66 hash_tab->buckets[i] = NULL;
68 return hash_tab;
72 * ======== gh_delete ========
74 void gh_delete(struct gh_t_hash_tab *hash_tab)
76 struct element *elem, *next;
77 u16 i;
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);
90 kfree(hash_tab->buckets);
93 kfree(hash_tab);
98 * ======== gh_exit ========
101 void gh_exit(void)
103 /* Do nothing */
107 * ======== gh_find ========
110 void *gh_find(struct gh_t_hash_tab *hash_tab, void *key)
112 struct element *elem;
114 elem = hash_tab->buckets[(*hash_tab->hash) (key, hash_tab->max_bucket)];
116 for (; elem; elem = elem->next) {
117 if ((*hash_tab->match) (key, elem->data))
118 return elem->data;
121 return NULL;
125 * ======== gh_init ========
128 void gh_init(void)
130 /* Do nothing */
134 * ======== gh_insert ========
137 void *gh_insert(struct gh_t_hash_tab *hash_tab, void *key, void *value)
139 struct element *elem;
140 u16 i;
141 char *src, *dst;
143 elem = kzalloc(sizeof(struct element) - 1 + hash_tab->val_size,
144 GFP_KERNEL);
145 if (elem != NULL) {
147 dst = (char *)elem->data;
148 src = (char *)value;
149 for (i = 0; i < hash_tab->val_size; i++)
150 *dst++ = *src++;
152 i = (*hash_tab->hash) (key, hash_tab->max_bucket);
153 elem->next = hash_tab->buckets[i];
154 hash_tab->buckets[i] = elem;
156 return elem->data;
159 return NULL;
163 * ======== noop ========
165 /* ARGSUSED */
166 static void noop(void *p)
168 p = p; /* stifle compiler warning */
171 #ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
173 * gh_iterate() - This function goes through all the elements in the hash table
174 * looking for the dsp symbols.
175 * @hash_tab: Hash table
176 * @callback: pointer to callback function
177 * @user_data: User data, contains the find_symbol_context pointer
180 void gh_iterate(struct gh_t_hash_tab *hash_tab,
181 void (*callback)(void *, void *), void *user_data)
183 struct element *elem;
184 u32 i;
186 if (hash_tab && hash_tab->buckets)
187 for (i = 0; i < hash_tab->max_bucket; i++) {
188 elem = hash_tab->buckets[i];
189 while (elem) {
190 callback(&elem->data, user_data);
191 elem = elem->next;
195 #endif