]>
git.ipfire.org Git - thirdparty/pciutils.git/blob - lib/names.c
2 * $Id: names.c,v 1.6 2000/04/29 12:56:23 mj Exp $
4 * The PCI Library -- ID to Name Translation
6 * Copyright (c) 1997--2000 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
8 * Can be freely distributed and used under the terms of the GNU GPL.
22 struct nl_entry
*next
;
23 word id1
, id2
, id3
, id4
;
30 #define NL_SUBSYSTEM 2
35 #define HASH_SIZE 1024
37 static inline unsigned int nl_calc_hash(int cat
, int id1
, int id2
, int id3
, int id4
)
41 h
= id1
^ id2
^ id3
^ id4
^ (cat
<< 5);
43 return h
& (HASH_SIZE
-1);
46 static struct nl_entry
*nl_lookup(struct pci_access
*a
, int num
, int cat
, int id1
, int id2
, int id3
, int id4
)
53 h
= nl_calc_hash(cat
, id1
, id2
, id3
, id4
);
55 while (n
&& (n
->id1
!= id1
|| n
->id2
!= id2
|| n
->id3
!= id3
|| n
->id4
!= id4
|| n
->cat
!= cat
))
60 static int nl_add(struct pci_access
*a
, int cat
, int id1
, int id2
, int id3
, int id4
, byte
*text
)
62 unsigned int h
= nl_calc_hash(cat
, id1
, id2
, id3
, id4
);
63 struct nl_entry
*n
= a
->nl_hash
[h
];
65 while (n
&& (n
->id1
!= id1
|| n
->id2
!= id2
|| n
->id3
!= id3
|| n
->id4
!= id4
|| n
->cat
!= cat
))
69 n
= pci_malloc(a
, sizeof(struct nl_entry
));
76 n
->next
= a
->nl_hash
[h
];
82 err_name_list(struct pci_access
*a
, char *msg
)
84 a
->error("%s: %s: %s\n", a
->id_file_name
, msg
, strerror(errno
));
88 parse_name_list(struct pci_access
*a
)
93 unsigned int id1
=0, id2
=0, id3
=0, id4
=0;
100 while (*p
&& *p
!= '\n')
105 while (*p
&& *p
!= '\n')
116 while (r
> q
&& r
[-1] == ' ')
123 if (q
[0] == 'C' && q
[1] == ' ')
125 if (strlen(q
+2) < 3 ||
127 sscanf(q
+2, "%x", &id1
) != 1)
135 sscanf(q
, "%x", &id1
) != 1)
148 if (sscanf(q
, "%x", &id2
) != 1 || q
[4] != ' ')
157 if (sscanf(q
, "%x", &id2
) != 1 || q
[2] != ' ')
171 if (sscanf(q
, "%x%x", &id3
, &id4
) != 2 || q
[9] != ' ')
179 if (sscanf(q
, "%x", &id3
) != 1 || q
[2] != ' ')
194 if (nl_add(a
, cat
, id1
, id2
, id3
, id4
, q
))
195 a
->error("%s, line %d: duplicate entry", a
->id_file_name
, lino
);
200 a
->error("%s, line %d: parse error", a
->id_file_name
, lino
);
204 load_name_list(struct pci_access
*a
)
209 fd
= open(a
->id_file_name
, O_RDONLY
);
215 if (fstat(fd
, &st
) < 0)
216 err_name_list(a
, "stat");
217 a
->nl_list
= pci_malloc(a
, st
.st_size
+ 1);
218 if (read(fd
, a
->nl_list
, st
.st_size
) != st
.st_size
)
219 err_name_list(a
, "read");
220 a
->nl_list
[st
.st_size
] = 0;
221 a
->nl_hash
= pci_malloc(a
, sizeof(struct nl_entry
*) * HASH_SIZE
);
222 bzero(a
->nl_hash
, sizeof(struct nl_entry
*) * HASH_SIZE
);
228 pci_free_name_list(struct pci_access
*a
)
230 pci_mfree(a
->nl_list
);
232 pci_mfree(a
->nl_hash
);
237 pci_lookup_name(struct pci_access
*a
, char *buf
, int size
, int flags
, u32 arg1
, u32 arg2
, u32 arg3
, u32 arg4
)
239 int num
= a
->numeric_ids
;
243 if (flags
& PCI_LOOKUP_NUMERIC
)
245 flags
&= PCI_LOOKUP_NUMERIC
;
248 if (!a
->nl_hash
&& !num
)
251 num
= a
->numeric_ids
;
255 case PCI_LOOKUP_VENDOR
:
256 if (n
= nl_lookup(a
, num
, NL_VENDOR
, arg1
, 0, 0, 0))
259 res
= snprintf(buf
, size
, "%04x", arg1
);
261 case PCI_LOOKUP_DEVICE
:
262 if (n
= nl_lookup(a
, num
, NL_DEVICE
, arg1
, arg2
, 0, 0))
265 res
= snprintf(buf
, size
, "%04x", arg2
);
267 case PCI_LOOKUP_VENDOR
| PCI_LOOKUP_DEVICE
:
270 struct nl_entry
*e
, *e2
;
271 e
= nl_lookup(a
, 0, NL_VENDOR
, arg1
, 0, 0, 0);
272 e2
= nl_lookup(a
, 0, NL_DEVICE
, arg1
, arg2
, 0, 0);
274 res
= snprintf(buf
, size
, "Unknown device %04x:%04x", arg1
, arg2
);
276 res
= snprintf(buf
, size
, "%s: Unknown device %04x", e
->name
, arg2
);
278 res
= snprintf(buf
, size
, "%s %s", e
->name
, e2
->name
);
281 res
= snprintf(buf
, size
, "%04x:%04x", arg1
, arg2
);
283 case PCI_LOOKUP_VENDOR
| PCI_LOOKUP_SUBSYSTEM
:
284 if (n
= nl_lookup(a
, num
, NL_VENDOR
, arg3
, 0, 0, 0))
287 res
= snprintf(buf
, size
, "%04x", arg1
);
289 case PCI_LOOKUP_DEVICE
| PCI_LOOKUP_SUBSYSTEM
:
290 if (n
= nl_lookup(a
, num
, NL_SUBSYSTEM
, arg1
, arg2
, arg3
, arg4
))
292 else if (arg1
== arg3
&& arg2
== arg4
&& (n
= nl_lookup(a
, num
, NL_DEVICE
, arg1
, arg2
, 0, 0)))
295 res
= snprintf(buf
, size
, "%04x", arg2
);
297 case PCI_LOOKUP_VENDOR
| PCI_LOOKUP_DEVICE
| PCI_LOOKUP_SUBSYSTEM
:
300 struct nl_entry
*e
, *e2
;
301 e
= nl_lookup(a
, 0, NL_VENDOR
, arg3
, 0, 0, 0);
302 e2
= nl_lookup(a
, 0, NL_SUBSYSTEM
, arg1
, arg2
, arg3
, arg4
);
303 if (!e2
&& arg1
== arg3
&& arg2
== arg4
)
304 /* Cheat for vendors blindly setting subsystem ID same as device ID */
305 e2
= nl_lookup(a
, 0, NL_DEVICE
, arg1
, arg2
, 0, 0);
307 res
= snprintf(buf
, size
, "Unknown device %04x:%04x", arg3
, arg4
);
309 res
= snprintf(buf
, size
, "%s: Unknown device %04x", e
->name
, arg4
);
311 res
= snprintf(buf
, size
, "%s %s", e
->name
, e2
->name
);
314 res
= snprintf(buf
, size
, "%04x:%04x", arg3
, arg4
);
316 case PCI_LOOKUP_CLASS
:
317 if (n
= nl_lookup(a
, num
, NL_SUBCLASS
, arg1
>> 8, arg1
& 0xff, 0, 0))
319 else if (n
= nl_lookup(a
, num
, NL_CLASS
, arg1
, 0, 0, 0))
320 res
= snprintf(buf
, size
, "%s [%04x]", n
->name
, arg1
);
322 res
= snprintf(buf
, size
, "Class %04x", arg1
);
324 case PCI_LOOKUP_PROGIF
:
325 if (n
= nl_lookup(a
, num
, NL_PROGIF
, arg1
>> 8, arg1
& 0xff, arg2
, 0))
329 /* IDE controllers have complex prog-if semantics */
332 res
= snprintf(buf
, size
, "%s%s%s%s%s",
333 (arg2
& 0x80) ? "Master " : "",
334 (arg2
& 0x08) ? "SecP " : "",
335 (arg2
& 0x04) ? "SecO " : "",
336 (arg2
& 0x02) ? "PriP " : "",
337 (arg2
& 0x01) ? "PriO " : "");
344 return "<pci_lookup_name: invalid request>";
346 return (res
== size
) ? "<too-large>" : buf
;