linux/drivers/staging/tidspbridge/gen/gh.c
<<
>>
Prefs
   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
  22struct element {
  23        struct element *next;
  24        u8 data[1];
  25};
  26
  27struct 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
  36static void noop(void *p);
  37
  38/*
  39 *  ======== gh_create ========
  40 */
  41
  42struct 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 = (struct element **)
  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 */
  74void 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_exit ========
  99 */
 100
 101void gh_exit(void)
 102{
 103        /* Do nothing */
 104}
 105
 106/*
 107 *  ======== gh_find ========
 108 */
 109
 110void *gh_find(struct gh_t_hash_tab *hash_tab, void *key)
 111{
 112        struct element *elem;
 113
 114        elem = hash_tab->buckets[(*hash_tab->hash) (key, hash_tab->max_bucket)];
 115
 116        for (; elem; elem = elem->next) {
 117                if ((*hash_tab->match) (key, elem->data))
 118                        return elem->data;
 119        }
 120
 121        return NULL;
 122}
 123
 124/*
 125 *  ======== gh_init ========
 126 */
 127
 128void gh_init(void)
 129{
 130        /* Do nothing */
 131}
 132
 133/*
 134 *  ======== gh_insert ========
 135 */
 136
 137void *gh_insert(struct gh_t_hash_tab *hash_tab, void *key, void *value)
 138{
 139        struct element *elem;
 140        u16 i;
 141        char *src, *dst;
 142
 143        elem = kzalloc(sizeof(struct element) - 1 + hash_tab->val_size,
 144                        GFP_KERNEL);
 145        if (elem != NULL) {
 146
 147                dst = (char *)elem->data;
 148                src = (char *)value;
 149                for (i = 0; i < hash_tab->val_size; i++)
 150                        *dst++ = *src++;
 151
 152                i = (*hash_tab->hash) (key, hash_tab->max_bucket);
 153                elem->next = hash_tab->buckets[i];
 154                hash_tab->buckets[i] = elem;
 155
 156                return elem->data;
 157        }
 158
 159        return NULL;
 160}
 161
 162/*
 163 *  ======== noop ========
 164 */
 165/* ARGSUSED */
 166static void noop(void *p)
 167{
 168        p = p;                  /* stifle compiler warning */
 169}
 170
 171#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
 172/**
 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
 178 *
 179 */
 180void gh_iterate(struct gh_t_hash_tab *hash_tab,
 181                void (*callback)(void *, void *), void *user_data)
 182{
 183        struct element *elem;
 184        u32 i;
 185
 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;
 192                        }
 193                }
 194}
 195#endif
 196