Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
gh.c
Go to the documentation of this file.
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 {
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 
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 
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