2 * $Id: names.c,v 1.6 1998/07/17 08:57:16 mj Exp $
4 * Linux PCI Utilities -- Device ID to Name Translation
6 * Copyright (c) 1997, 1998 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
8 * Can be freely distributed and used under the terms of the GNU GPL.
22 char *pci_ids = ETC_PCI_IDS;
24 static byte *name_list;
25 static int name_list_loaded;
28 struct nl_entry *next;
38 #define NL_SUBSYSTEM_VENDOR 4
39 #define NL_SUBSYSTEM_DEVICE 5
41 #define HASH_SIZE 1024
43 static struct nl_entry *nl_hash[HASH_SIZE];
45 static inline unsigned int nl_calc_hash(int cat, int id1, int id2)
49 h = id1 ^ id2 ^ (cat << 5);
51 return h & (HASH_SIZE-1);
54 static struct nl_entry *nl_lookup(int cat, int id1, int id2)
56 unsigned int h = nl_calc_hash(cat, id1, id2);
57 struct nl_entry *n = nl_hash[h];
59 while (n && (n->id1 != id1 || n->id2 != id2 || n->cat != cat))
64 static int nl_add(int cat, int id1, int id2, byte *text)
66 unsigned int h = nl_calc_hash(cat, id1, id2);
67 struct nl_entry *n = nl_hash[h];
69 while (n && (n->id1 != id1 || n->id2 != id2 || n->cat != cat))
73 n = xmalloc(sizeof(struct nl_entry));
84 err_name_list(char *msg)
86 fprintf(stderr, "%s: %s: %m\n", pci_ids, msg);
96 unsigned int id1=0, id2=0;
97 int cat, last_cat = -1;
103 while (*p && *p != '\n')
108 while (*p && *p != '\n')
121 while (r > q && r[-1] == ' ')
128 if (q[0] == 'C' && q[1] == ' ')
130 if (strlen(q+2) < 3 ||
132 sscanf(q+2, "%x", &id1) != 1)
134 cat = last_cat = NL_CLASS;
136 else if (q[0] == 'S' && q[1] == ' ')
138 if (strlen(q+2) < 5 ||
140 sscanf(q+2, "%x", &id1) != 1)
142 cat = last_cat = NL_SUBSYSTEM_VENDOR;
149 sscanf(q, "%x", &id1) != 1)
151 cat = last_cat = NL_VENDOR;
157 if (sscanf(q, "%x", &id2) != 1)
161 if (last_cat == NL_CLASS)
171 if (nl_add(cat, id1, id2, q))
173 fprintf(stderr, "%s, line %d: duplicate entry\n", pci_ids, lino);
180 fprintf(stderr, "%s, line %d: parse error\n", pci_ids, lino);
190 fd = open(pci_ids, O_RDONLY);
193 show_numeric_ids = 1;
196 if (fstat(fd, &st) < 0)
197 err_name_list("stat");
198 name_list = xmalloc(st.st_size + 1);
199 if (read(fd, name_list, st.st_size) != st.st_size)
200 err_name_list("read");
201 name_list[st.st_size] = 0;
204 name_list_loaded = 1;
208 do_lookup_vendor(int cat, word i)
210 static char vendbuf[6];
212 if (!show_numeric_ids && !name_list_loaded)
214 if (!show_numeric_ids)
218 e = nl_lookup(cat, i, 0);
222 sprintf(vendbuf, "%04x", i);
227 do_lookup_device(int cat, word v, word i)
229 static char devbuf[6];
231 if (!show_numeric_ids && !name_list_loaded)
233 if (!show_numeric_ids)
237 e = nl_lookup(cat, v, i);
241 sprintf(devbuf, "%04x", i);
246 do_lookup_device_full(int cat, word v, word i)
248 static char fullbuf[256];
250 if (!show_numeric_ids && !name_list_loaded)
252 if (!show_numeric_ids)
254 struct nl_entry *e, *e2;
256 e = nl_lookup(cat, v, 0);
257 e2 = nl_lookup(cat+1, v, i);
259 sprintf(fullbuf, "Unknown device %04x:%04x", v, i);
261 sprintf(fullbuf, "%s: Unknown device %04x", e->name, i);
263 sprintf(fullbuf, "%s %s", e->name, e2->name);
266 sprintf(fullbuf, "%04x:%04x", v, i);
271 lookup_vendor(word i)
273 return do_lookup_vendor(NL_VENDOR, i);
277 lookup_subsys_vendor(word i)
279 return do_lookup_vendor(NL_SUBSYSTEM_VENDOR, i);
283 lookup_device(word i, word v)
285 return do_lookup_device(NL_DEVICE, v, i);
289 lookup_subsys_device(word v, word i)
291 return do_lookup_device(NL_SUBSYSTEM_DEVICE, v, i);
295 lookup_device_full(word v, word i)
297 return do_lookup_device_full(NL_VENDOR, v, i);
301 lookup_subsys_device_full(word v, word i)
303 return do_lookup_device_full(NL_SUBSYSTEM_VENDOR, v, i);
309 static char classbuf[80];
311 if (!show_numeric_ids && !name_list_loaded)
313 if (!show_numeric_ids)
317 e = nl_lookup(NL_SUBCLASS, c >> 8, c & 0xff);
320 e = nl_lookup(NL_CLASS, c, 0);
322 sprintf(classbuf, "%s [%04x]", e->name, c);
324 sprintf(classbuf, "Unknown class [%04x]", c);
327 sprintf(classbuf, "Class %04x", c);