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 =
  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_find ========
  99 */
 100
 101void *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
 119void *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 */
 148static 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 */
 162void 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
 178