Annotation of embedaddon/pciutils/lib/names-hash.c, revision 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>