]>
git.ipfire.org Git - thirdparty/pciutils.git/blob - lib/names-hash.c
2 * The PCI Library -- ID to Name Hash
4 * Copyright (c) 1997--2008 Martin Mares <mj@ucw.cz>
6 * Can be freely distributed and used under the terms of the GNU GPL.
15 struct id_bucket
*next
;
20 #define BUCKET_ALIGNMENT __alignof__(struct id_bucket)
23 struct id_bucket
*next
;
26 #define BUCKET_ALIGNMENT sizeof(union id_align)
28 #define BUCKET_ALIGN(n) ((n)+BUCKET_ALIGNMENT-(n)%BUCKET_ALIGNMENT)
30 static void *id_alloc(struct pci_access
*a
, unsigned int size
)
32 struct id_bucket
*buck
= a
->current_id_bucket
;
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
);
41 if (!buck
|| buck
->full
+ size
> BUCKET_SIZE
)
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
));
49 buck
->full
= BUCKET_ALIGN(buck
->full
+ size
);
50 return (byte
*)buck
+ pos
;
53 static inline unsigned int id_hash(int cat
, u32 id12
, u32 id34
)
57 h
= id12
^ (id34
<< 3) ^ (cat
<< 5);
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
)
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
);
70 while (n
&& (n
->id12
!= id12
|| n
->id34
!= id34
|| n
->cat
!= cat
))
74 n
= id_alloc(a
, sizeof(struct id_entry
) + len
);
79 memcpy(n
->name
, text
, len
+1);
80 n
->next
= a
->id_hash
[h
];
86 *pci_id_lookup(struct pci_access
*a
, int flags
, int cat
, int id1
, int id2
, int id3
, int id4
)
88 struct id_entry
*n
, *best
;
89 u32 id12
= id_pair(id1
, id2
);
90 u32 id34
= id_pair(id3
, id4
);
94 n
= a
->id_hash
[id_hash(cat
, id12
, id34
)];
98 if (n
->id12
!= id12
|| n
->id34
!= id34
|| n
->cat
!= cat
)
100 if (n
->src
== SRC_LOCAL
&& (flags
& PCI_LOOKUP_SKIP_LOCAL
))
102 if (n
->src
== SRC_NET
&& !(flags
& PCI_LOOKUP_NETWORK
))
104 if (n
->src
== SRC_CACHE
&& !(flags
& PCI_LOOKUP_CACHE
))
106 if (n
->src
== SRC_HWDB
&& (flags
& (PCI_LOOKUP_SKIP_LOCAL
| PCI_LOOKUP_NO_HWDB
)))
108 if (!best
|| best
->src
< n
->src
)
118 pci_id_hash_free(struct pci_access
*a
)
120 pci_mfree(a
->id_hash
);
122 while (a
->current_id_bucket
)
124 struct id_bucket
*buck
= a
->current_id_bucket
;
125 a
->current_id_bucket
= buck
->next
;