]> mj.ucw.cz Git - pciutils.git/blob - names.c
Beginning of the history.
[pciutils.git] / names.c
1 /*
2  *      $Id: names.c,v 1.1 1997/12/23 10:29:18 mj Exp $
3  *
4  *      Linux PCI Utilities -- Device ID to Name Translation
5  *
6  *      Copyright (c) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
7  *
8  *      Can be freely distributed and used under the terms of the GNU GPL.
9  */
10
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <fcntl.h>
15 #include <unistd.h>
16 #include <sys/stat.h>
17 #include <linux/pci.h>
18
19 #include "pciutils.h"
20
21 int show_numeric_ids;
22
23 static byte *name_list;
24 static int name_list_loaded;
25
26 struct nl_entry {
27   struct nl_entry *next;
28   int id1, id2;
29   byte *name;
30 };
31
32 #define ID1_VENDOR -1
33 #define ID1_CLASS -2
34 #define ID1_SUBCLASS -3
35 #define ID1_ERROR -4
36
37 #define HASH_SIZE 1024
38
39 static struct nl_entry *nl_hash[HASH_SIZE];
40
41 static inline unsigned int nl_calc_hash(int id1, int id2)
42 {
43   unsigned int h;
44
45   h = id1 ^ id2;
46   h ^= (h >> 6);
47   return h & (HASH_SIZE-1);
48 }
49
50 static struct nl_entry *nl_lookup(int id1, int id2)
51 {
52   unsigned int h = nl_calc_hash(id1, id2);
53   struct nl_entry *n = nl_hash[h];
54
55   while (n && (n->id1 != id1 || n->id2 != id2))
56     n = n->next;
57   return n;
58 }
59
60 static int nl_add(int id1, int id2, byte *text)
61 {
62   unsigned int h = nl_calc_hash(id1, id2);
63   struct nl_entry *n = nl_hash[h];
64
65   while (n && (n->id1 != id1 || n->id2 != id2))
66     n = n->next;
67   if (n)
68     return 1;
69   n = xmalloc(sizeof(struct nl_entry));
70   n->id1 = id1;
71   n->id2 = id2;
72   n->name = text;
73   n->next = nl_hash[h];
74   nl_hash[h] = n;
75   return 0;
76 }
77
78 static void
79 err_name_list(char *msg)
80 {
81   fprintf(stderr, ETC_PCI_IDS ": %s: %m\n", msg);
82   exit(1);
83 }
84
85 static void
86 parse_name_list(void)
87 {
88   byte *p = name_list;
89   byte *q, *r, *s;
90   int lino = 0;
91   int id1 = ID1_ERROR;
92   int id2 = 0;
93   int i, j;
94
95   while (*p)
96     {
97       lino++;
98       q = p;
99       while (*p && *p != '\n')
100         {
101           if (*p == '#')
102             {
103               *p++ = 0;
104               while (*p && *p != '\n')
105                 p++;
106               break;
107             }
108           if (*p == '\t')
109             *p = ' ';
110           p++;
111         }
112       if (*p == '\n')
113         *p++ = 0;
114       if (!*q)
115         continue;
116       r = p;
117       while (r > q && r[-1] == ' ')
118         *--r = 0;
119       r = q;
120       while (*q == ' ')
121         q++;
122       if (strlen(q) < 5 || q[4] != ' ')
123         goto parserr;
124       if (r == q)
125         {
126           if (q[0] == 'C' && q[1] == ' ')
127             {
128               if (sscanf(q+2, "%x", &j) != 1)
129                 goto parserr;
130               i = ID1_CLASS;
131             }
132           else
133             {
134               if (sscanf(q, "%x", &j) != 1)
135                 goto parserr;
136               i = ID1_VENDOR;
137             }
138           id1 = i;
139           id2 = j;
140         }
141       else
142         {
143           if (sscanf(q, "%x", &j) != 1)
144             goto parserr;
145           if (id1 == ID1_ERROR)
146             goto parserr;
147           if (id1 == ID1_CLASS)
148             {
149               i = ID1_SUBCLASS;
150               j |= (id2 << 8);
151             }
152           else
153             i = id2;
154         }
155       q += 4;
156       while (*q == ' ')
157         q++;
158       if (!*q)
159         goto parserr;
160       if (nl_add(i, j, q))
161         {
162           fprintf(stderr, ETC_PCI_IDS ", line %d: duplicate entry\n", lino);
163           exit(1);
164         }
165     }
166   return;
167
168 parserr:
169   fprintf(stderr, ETC_PCI_IDS ", line %d: parse error\n", lino);
170   exit(1);
171 }
172
173 static void
174 load_name_list(void)
175 {
176   int fd;
177   struct stat st;
178
179   fd = open(ETC_PCI_IDS, O_RDONLY);
180   if (fd < 0)
181     {
182       show_numeric_ids = 1;
183       return;
184     }
185   if (fstat(fd, &st) < 0)
186     err_name_list("stat");
187   name_list = xmalloc(st.st_size + 1);
188   if (read(fd, name_list, st.st_size) != st.st_size)
189     err_name_list("read");
190   name_list[st.st_size] = 0;
191   parse_name_list();
192   close(fd);
193   name_list_loaded = 1;
194 }
195
196 char *
197 lookup_vendor(word i)
198 {
199   static char vendbuf[6];
200
201   if (!show_numeric_ids)
202     {
203       struct nl_entry *e;
204
205       if (!name_list_loaded)
206         load_name_list();
207       e = nl_lookup(ID1_VENDOR, i);
208       if (e)
209         return e->name;
210     }
211   sprintf(vendbuf, "%04x", i);
212   return vendbuf;
213 }
214
215 char *
216 lookup_device(word v, word i)
217 {
218   static char devbuf[6];
219
220   if (!show_numeric_ids)
221     {
222       struct nl_entry *e;
223
224       if (!name_list_loaded)
225         load_name_list();
226       e = nl_lookup(v, i);
227       if (e)
228         return e->name;
229     }
230   sprintf(devbuf, "%04x", i);
231   return devbuf;
232 }
233
234 char *
235 lookup_device_full(word v, word i)
236 {
237   static char fullbuf[256];
238
239   if (!show_numeric_ids)
240     {
241       struct nl_entry *e, *e2;
242
243       if (!name_list_loaded)
244         load_name_list();
245       e = nl_lookup(ID1_VENDOR, v);
246       e2 = nl_lookup(v, i);
247       if (!e)
248         sprintf(fullbuf, "Unknown device %04x:%04x", v, i);
249       else if (!e2)
250         sprintf(fullbuf, "%s: Unknown device %04x", e->name, i);
251       else
252         sprintf(fullbuf, "%s %s", e->name, e2->name);
253     }
254   else
255     sprintf(fullbuf, "%04x:%04x", v, i);
256   return fullbuf;
257 }
258
259 char *
260 lookup_class(word c)
261 {
262   static char classbuf[80];
263
264   if (!show_numeric_ids)
265     {
266       struct nl_entry *e;
267
268       if (!name_list_loaded)
269         load_name_list();
270       e = nl_lookup(ID1_SUBCLASS, c);
271       if (e)
272         return e->name;
273       e = nl_lookup(ID1_CLASS, c);
274       if (e)
275         sprintf(classbuf, "%s [%04x]", e->name, c);
276       else
277         sprintf(classbuf, "Unknown class [%04x]", c);
278     }
279   else
280     sprintf(classbuf, "Class %04x", c);
281   return classbuf;
282 }