Annotation of embedaddon/pciutils/lib/names-hash.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  *     The PCI Library -- ID to Name Hash
                      3:  *
                      4:  *     Copyright (c) 1997--2008 Martin Mares <mj@ucw.cz>
                      5:  *
                      6:  *     Can be freely distributed and used under the terms of the GNU GPL.
                      7:  */
                      8: 
                      9: #include <string.h>
                     10: 
                     11: #include "internal.h"
                     12: #include "names.h"
                     13: 
                     14: struct id_bucket {
                     15:   struct id_bucket *next;
                     16:   unsigned int full;
                     17: };
                     18: 
                     19: #ifdef __GNUC__
                     20: #define BUCKET_ALIGNMENT __alignof__(struct id_bucket)
                     21: #else
                     22: union id_align {
                     23:   struct id_bucket *next;
                     24:   unsigned int full;
                     25: };
                     26: #define BUCKET_ALIGNMENT sizeof(union id_align)
                     27: #endif
                     28: #define BUCKET_ALIGN(n) ((n)+BUCKET_ALIGNMENT-(n)%BUCKET_ALIGNMENT)
                     29: 
                     30: static void *id_alloc(struct pci_access *a, unsigned int size)
                     31: {
                     32:   struct id_bucket *buck = a->current_id_bucket;
                     33:   unsigned int pos;
                     34: 
                     35:   if (!a->id_hash)
                     36:     {
                     37:       a->id_hash = pci_malloc(a, sizeof(struct id_entry *) * HASH_SIZE);
                     38:       memset(a->id_hash, 0, sizeof(struct id_entry *) * HASH_SIZE);
                     39:     }
                     40: 
                     41:   if (!buck || buck->full + size > BUCKET_SIZE)
                     42:     {
                     43:       buck = pci_malloc(a, BUCKET_SIZE);
                     44:       buck->next = a->current_id_bucket;
                     45:       a->current_id_bucket = buck;
                     46:       buck->full = BUCKET_ALIGN(sizeof(struct id_bucket));
                     47:     }
                     48:   pos = buck->full;
                     49:   buck->full = BUCKET_ALIGN(buck->full + size);
                     50:   return (byte *)buck + pos;
                     51: }
                     52: 
                     53: static inline unsigned int id_hash(int cat, u32 id12, u32 id34)
                     54: {
                     55:   unsigned int h;
                     56: 
                     57:   h = id12 ^ (id34 << 3) ^ (cat << 5);
                     58:   return h % HASH_SIZE;
                     59: }
                     60: 
                     61: int
                     62: pci_id_insert(struct pci_access *a, int cat, int id1, int id2, int id3, int id4, char *text, enum id_entry_src src)
                     63: {
                     64:   u32 id12 = id_pair(id1, id2);
                     65:   u32 id34 = id_pair(id3, id4);
                     66:   unsigned int h = id_hash(cat, id12, id34);
                     67:   struct id_entry *n = a->id_hash ? a->id_hash[h] : NULL;
                     68:   int len = strlen(text);
                     69: 
                     70:   while (n && (n->id12 != id12 || n->id34 != id34 || n->cat != cat))
                     71:     n = n->next;
                     72:   if (n)
                     73:     return 1;
                     74:   n = id_alloc(a, sizeof(struct id_entry) + len);
                     75:   n->id12 = id12;
                     76:   n->id34 = id34;
                     77:   n->cat = cat;
                     78:   n->src = src;
                     79:   memcpy(n->name, text, len+1);
                     80:   n->next = a->id_hash[h];
                     81:   a->id_hash[h] = n;
                     82:   return 0;
                     83: }
                     84: 
                     85: char
                     86: *pci_id_lookup(struct pci_access *a, int flags, int cat, int id1, int id2, int id3, int id4)
                     87: {
                     88:   struct id_entry *n, *best;
                     89:   u32 id12 = id_pair(id1, id2);
                     90:   u32 id34 = id_pair(id3, id4);
                     91: 
                     92:   if (a->id_hash)
                     93:     {
                     94:       n = a->id_hash[id_hash(cat, id12, id34)];
                     95:       best = NULL;
                     96:       for (; n; n=n->next)
                     97:         {
                     98:          if (n->id12 != id12 || n->id34 != id34 || n->cat != cat)
                     99:            continue;
                    100:          if (n->src == SRC_LOCAL && (flags & PCI_LOOKUP_SKIP_LOCAL))
                    101:            continue;
                    102:          if (n->src == SRC_NET && !(flags & PCI_LOOKUP_NETWORK))
                    103:            continue;
                    104:          if (n->src == SRC_CACHE && !(flags & PCI_LOOKUP_CACHE))
                    105:            continue;
                    106:          if (!best || best->src < n->src)
                    107:            best = n;
                    108:        }
                    109:       if (best)
                    110:        return best->name;
                    111:     }
                    112:   return NULL;
                    113: }
                    114: 
                    115: void
                    116: pci_id_hash_free(struct pci_access *a)
                    117: {
                    118:   pci_mfree(a->id_hash);
                    119:   a->id_hash = NULL;
                    120:   while (a->current_id_bucket)
                    121:     {
                    122:       struct id_bucket *buck = a->current_id_bucket;
                    123:       a->current_id_bucket = buck->next;
                    124:       pci_mfree(buck);
                    125:     }
                    126: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>