1*2912Sartem /***************************************************************************
2*2912Sartem * CVSID: $Id$
3*2912Sartem *
4*2912Sartem * ids.c : Lookup names from hardware identifiers
5*2912Sartem *
6*2912Sartem * Copyright (C) 2004 David Zeuthen, <david@fubar.dk>
7*2912Sartem *
8*2912Sartem * Licensed under the Academic Free License version 2.1
9*2912Sartem *
10*2912Sartem * This program is free software; you can redistribute it and/or modify
11*2912Sartem * it under the terms of the GNU General Public License as published by
12*2912Sartem * the Free Software Foundation; either version 2 of the License, or
13*2912Sartem * (at your option) any later version.
14*2912Sartem *
15*2912Sartem * This program is distributed in the hope that it will be useful,
16*2912Sartem * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*2912Sartem * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18*2912Sartem * GNU General Public License for more details.
19*2912Sartem *
20*2912Sartem * You should have received a copy of the GNU General Public License
21*2912Sartem * along with this program; if not, write to the Free Software
22*2912Sartem * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23*2912Sartem *
24*2912Sartem **************************************************************************/
25*2912Sartem
26*2912Sartem #ifdef HAVE_CONFIG_H
27*2912Sartem # include <config.h>
28*2912Sartem #endif
29*2912Sartem
30*2912Sartem #include <ctype.h>
31*2912Sartem #include <stdint.h>
32*2912Sartem #include <string.h>
33*2912Sartem #include <unistd.h>
34*2912Sartem
35*2912Sartem #include <dbus/dbus.h>
36*2912Sartem #include <dbus/dbus-glib.h>
37*2912Sartem
38*2912Sartem #include "logger.h"
39*2912Sartem
40*2912Sartem #include "ids.h"
41*2912Sartem
42*2912Sartem /** Pointer to where the pci.ids file is loaded */
43*2912Sartem static char *pci_ids = NULL;
44*2912Sartem
45*2912Sartem /** Length of data store at at pci_ids */
46*2912Sartem static unsigned int pci_ids_len;
47*2912Sartem
48*2912Sartem /** Iterator position into pci_ids */
49*2912Sartem static unsigned int pci_ids_iter_pos;
50*2912Sartem
51*2912Sartem /** Initialize the pci.ids line iterator to the beginning of the file */
52*2912Sartem static void
pci_ids_line_iter_init()53*2912Sartem pci_ids_line_iter_init ()
54*2912Sartem {
55*2912Sartem pci_ids_iter_pos = 0;
56*2912Sartem }
57*2912Sartem
58*2912Sartem /** Maximum length of lines in pci.ids */
59*2912Sartem #define PCI_IDS_MAX_LINE_LEN 512
60*2912Sartem
61*2912Sartem /** Get the next line from pci.ids
62*2912Sartem *
63*2912Sartem * @param line_len Pointer to where number of bytes in line will
64*2912Sartem * be stored
65*2912Sartem * @return Pointer to the line; only valid until the
66*2912Sartem * next invocation of this function
67*2912Sartem */
68*2912Sartem static char *
pci_ids_line_iter_get_line(unsigned int * line_len)69*2912Sartem pci_ids_line_iter_get_line (unsigned int *line_len)
70*2912Sartem {
71*2912Sartem unsigned int i;
72*2912Sartem static char line[PCI_IDS_MAX_LINE_LEN];
73*2912Sartem
74*2912Sartem for (i = 0;
75*2912Sartem pci_ids_iter_pos < pci_ids_len &&
76*2912Sartem i < PCI_IDS_MAX_LINE_LEN - 1 &&
77*2912Sartem pci_ids[pci_ids_iter_pos] != '\n'; i++, pci_ids_iter_pos++) {
78*2912Sartem line[i] = pci_ids[pci_ids_iter_pos];
79*2912Sartem }
80*2912Sartem
81*2912Sartem line[i] = '\0';
82*2912Sartem if (line_len != NULL)
83*2912Sartem *line_len = i;
84*2912Sartem
85*2912Sartem pci_ids_iter_pos++;
86*2912Sartem
87*2912Sartem return line;
88*2912Sartem }
89*2912Sartem
90*2912Sartem /** See if there are more lines to process in pci.ids
91*2912Sartem *
92*2912Sartem * @return #TRUE iff there are more lines to process
93*2912Sartem */
94*2912Sartem static dbus_bool_t
pci_ids_line_iter_has_more()95*2912Sartem pci_ids_line_iter_has_more ()
96*2912Sartem {
97*2912Sartem return pci_ids_iter_pos < pci_ids_len;
98*2912Sartem }
99*2912Sartem
100*2912Sartem
101*2912Sartem /** Find the names for a PCI device.
102*2912Sartem *
103*2912Sartem * The pointers returned are only valid until the next invocation of this
104*2912Sartem * function.
105*2912Sartem *
106*2912Sartem * @param vendor_id PCI vendor id or 0 if unknown
107*2912Sartem * @param product_id PCI product id or 0 if unknown
108*2912Sartem * @param subsys_vendor_id PCI subsystem vendor id or 0 if unknown
109*2912Sartem * @param subsys_product_id PCI subsystem product id or 0 if unknown
110*2912Sartem * @param vendor_name Set to pointer of result or NULL
111*2912Sartem * @param product_name Set to pointer of result or NULL
112*2912Sartem * @param subsys_vendor_name Set to pointer of result or NULL
113*2912Sartem * @param subsys_product_name Set to pointer of result or NULL
114*2912Sartem */
115*2912Sartem void
ids_find_pci(int vendor_id,int product_id,int subsys_vendor_id,int subsys_product_id,char ** vendor_name,char ** product_name,char ** subsys_vendor_name,char ** subsys_product_name)116*2912Sartem ids_find_pci (int vendor_id, int product_id,
117*2912Sartem int subsys_vendor_id, int subsys_product_id,
118*2912Sartem char **vendor_name, char **product_name,
119*2912Sartem char **subsys_vendor_name, char **subsys_product_name)
120*2912Sartem {
121*2912Sartem char *line;
122*2912Sartem unsigned int i;
123*2912Sartem unsigned int line_len;
124*2912Sartem unsigned int num_tabs;
125*2912Sartem char rep_vi[8];
126*2912Sartem char rep_pi[8];
127*2912Sartem char rep_svi[8];
128*2912Sartem char rep_spi[8];
129*2912Sartem dbus_bool_t vendor_matched = FALSE;
130*2912Sartem dbus_bool_t product_matched = FALSE;
131*2912Sartem static char store_vn[PCI_IDS_MAX_LINE_LEN];
132*2912Sartem static char store_pn[PCI_IDS_MAX_LINE_LEN];
133*2912Sartem static char store_svn[PCI_IDS_MAX_LINE_LEN];
134*2912Sartem static char store_spn[PCI_IDS_MAX_LINE_LEN];
135*2912Sartem
136*2912Sartem snprintf (rep_vi, 8, "%04x", vendor_id);
137*2912Sartem snprintf (rep_pi, 8, "%04x", product_id);
138*2912Sartem snprintf (rep_svi, 8, "%04x", subsys_vendor_id);
139*2912Sartem snprintf (rep_spi, 8, "%04x", subsys_product_id);
140*2912Sartem
141*2912Sartem *vendor_name = NULL;
142*2912Sartem *product_name = NULL;
143*2912Sartem *subsys_vendor_name = NULL;
144*2912Sartem *subsys_product_name = NULL;
145*2912Sartem
146*2912Sartem for (pci_ids_line_iter_init (); pci_ids_line_iter_has_more ();) {
147*2912Sartem line = pci_ids_line_iter_get_line (&line_len);
148*2912Sartem
149*2912Sartem /* skip lines with no content */
150*2912Sartem if (line_len < 4)
151*2912Sartem continue;
152*2912Sartem
153*2912Sartem /* skip comments */
154*2912Sartem if (line[0] == '#')
155*2912Sartem continue;
156*2912Sartem
157*2912Sartem /* count number of tabs */
158*2912Sartem num_tabs = 0;
159*2912Sartem for (i = 0; i < line_len; i++) {
160*2912Sartem if (line[i] != '\t')
161*2912Sartem break;
162*2912Sartem num_tabs++;
163*2912Sartem }
164*2912Sartem
165*2912Sartem switch (num_tabs) {
166*2912Sartem case 0:
167*2912Sartem /* vendor names */
168*2912Sartem vendor_matched = FALSE;
169*2912Sartem
170*2912Sartem /* first check subsys_vendor_id, if haven't done
171*2912Sartem * already */
172*2912Sartem if (*subsys_vendor_name == NULL
173*2912Sartem && subsys_vendor_id != 0) {
174*2912Sartem if ((*((dbus_uint32_t *) line)) ==
175*2912Sartem (*((dbus_uint32_t *) rep_svi))) {
176*2912Sartem /* found it */
177*2912Sartem for (i = 4; i < line_len; i++) {
178*2912Sartem if (!isspace (line[i]))
179*2912Sartem break;
180*2912Sartem }
181*2912Sartem strncpy (store_svn, line + i,
182*2912Sartem PCI_IDS_MAX_LINE_LEN);
183*2912Sartem *subsys_vendor_name = store_svn;
184*2912Sartem }
185*2912Sartem }
186*2912Sartem
187*2912Sartem /* check vendor_id */
188*2912Sartem if (vendor_id != 0) {
189*2912Sartem if (memcmp (line, rep_vi, 4) == 0) {
190*2912Sartem /* found it */
191*2912Sartem vendor_matched = TRUE;
192*2912Sartem
193*2912Sartem for (i = 4; i < line_len; i++) {
194*2912Sartem if (!isspace (line[i]))
195*2912Sartem break;
196*2912Sartem }
197*2912Sartem strncpy (store_vn, line + i,
198*2912Sartem PCI_IDS_MAX_LINE_LEN);
199*2912Sartem *vendor_name = store_vn;
200*2912Sartem }
201*2912Sartem }
202*2912Sartem
203*2912Sartem break;
204*2912Sartem
205*2912Sartem case 1:
206*2912Sartem product_matched = FALSE;
207*2912Sartem
208*2912Sartem /* product names */
209*2912Sartem if (!vendor_matched)
210*2912Sartem continue;
211*2912Sartem
212*2912Sartem /* check product_id */
213*2912Sartem if (product_id != 0) {
214*2912Sartem if (memcmp (line + 1, rep_pi, 4) == 0) {
215*2912Sartem /* found it */
216*2912Sartem
217*2912Sartem product_matched = TRUE;
218*2912Sartem
219*2912Sartem for (i = 5; i < line_len; i++) {
220*2912Sartem if (!isspace (line[i]))
221*2912Sartem break;
222*2912Sartem }
223*2912Sartem strncpy (store_pn, line + i,
224*2912Sartem PCI_IDS_MAX_LINE_LEN);
225*2912Sartem *product_name = store_pn;
226*2912Sartem }
227*2912Sartem }
228*2912Sartem break;
229*2912Sartem
230*2912Sartem case 2:
231*2912Sartem /* subsystem_vendor subsystem_product */
232*2912Sartem if (!vendor_matched || !product_matched)
233*2912Sartem continue;
234*2912Sartem
235*2912Sartem /* check product_id */
236*2912Sartem if (subsys_vendor_id != 0
237*2912Sartem && subsys_product_id != 0) {
238*2912Sartem if (memcmp (line + 2, rep_svi, 4) == 0
239*2912Sartem && memcmp (line + 7, rep_spi,
240*2912Sartem 4) == 0) {
241*2912Sartem /* found it */
242*2912Sartem for (i = 11; i < line_len; i++) {
243*2912Sartem if (!isspace (line[i]))
244*2912Sartem break;
245*2912Sartem }
246*2912Sartem strncpy (store_spn, line + i,
247*2912Sartem PCI_IDS_MAX_LINE_LEN);
248*2912Sartem *subsys_product_name = store_spn;
249*2912Sartem }
250*2912Sartem }
251*2912Sartem
252*2912Sartem break;
253*2912Sartem
254*2912Sartem default:
255*2912Sartem break;
256*2912Sartem }
257*2912Sartem
258*2912Sartem }
259*2912Sartem }
260*2912Sartem
261*2912Sartem /** Free resources used by to store the PCI database
262*2912Sartem *
263*2912Sartem * @param #FALSE if the PCI database wasn't loaded
264*2912Sartem */
265*2912Sartem static dbus_bool_t
pci_ids_free()266*2912Sartem pci_ids_free ()
267*2912Sartem {
268*2912Sartem if (pci_ids != NULL) {
269*2912Sartem free (pci_ids);
270*2912Sartem pci_ids = NULL;
271*2912Sartem return TRUE;
272*2912Sartem }
273*2912Sartem return FALSE;
274*2912Sartem }
275*2912Sartem
276*2912Sartem /** Load the PCI database used for mapping vendor, product, subsys_vendor
277*2912Sartem * and subsys_product numbers into names.
278*2912Sartem *
279*2912Sartem * @param path Path of the pci.ids file, e.g.
280*2912Sartem * /usr/share/hwdata/pci.ids
281*2912Sartem * @return #TRUE if the file was succesfully loaded
282*2912Sartem */
283*2912Sartem static dbus_bool_t
pci_ids_load(const char * path)284*2912Sartem pci_ids_load (const char *path)
285*2912Sartem {
286*2912Sartem FILE *fp;
287*2912Sartem unsigned int num_read;
288*2912Sartem
289*2912Sartem fp = fopen (path, "r");
290*2912Sartem if (fp == NULL) {
291*2912Sartem HAL_ERROR (("couldn't open PCI database at %s,", path));
292*2912Sartem return FALSE;
293*2912Sartem }
294*2912Sartem
295*2912Sartem fseek (fp, 0, SEEK_END);
296*2912Sartem pci_ids_len = ftell (fp);
297*2912Sartem fseek (fp, 0, SEEK_SET);
298*2912Sartem
299*2912Sartem pci_ids = malloc (pci_ids_len);
300*2912Sartem if (pci_ids == NULL) {
301*2912Sartem DIE (("Couldn't allocate %d bytes for PCI database file\n",
302*2912Sartem pci_ids_len));
303*2912Sartem }
304*2912Sartem
305*2912Sartem num_read = fread (pci_ids, sizeof (char), pci_ids_len, fp);
306*2912Sartem if (pci_ids_len != num_read) {
307*2912Sartem HAL_ERROR (("Error loading PCI database file"));
308*2912Sartem pci_ids_free();
309*2912Sartem fclose(fp);
310*2912Sartem return FALSE;
311*2912Sartem }
312*2912Sartem
313*2912Sartem fclose(fp);
314*2912Sartem return TRUE;
315*2912Sartem }
316*2912Sartem
317*2912Sartem /*==========================================================================*/
318*2912Sartem
319*2912Sartem /** Pointer to where the usb.ids file is loaded */
320*2912Sartem static char *usb_ids = NULL;
321*2912Sartem
322*2912Sartem /** Length of data store at at usb_ids */
323*2912Sartem static unsigned int usb_ids_len;
324*2912Sartem
325*2912Sartem /** Iterator position into usb_ids */
326*2912Sartem static unsigned int usb_ids_iter_pos;
327*2912Sartem
328*2912Sartem /** Initialize the usb.ids line iterator to the beginning of the file */
329*2912Sartem static void
usb_ids_line_iter_init()330*2912Sartem usb_ids_line_iter_init ()
331*2912Sartem {
332*2912Sartem usb_ids_iter_pos = 0;
333*2912Sartem }
334*2912Sartem
335*2912Sartem /** Maximum length of lines in usb.ids */
336*2912Sartem #define USB_IDS_MAX_LINE_LEN 512
337*2912Sartem
338*2912Sartem /** Get the next line from usb.ids
339*2912Sartem *
340*2912Sartem * @param line_len Pointer to where number of bytes in line will
341*2912Sartem * be stored
342*2912Sartem * @return Pointer to the line; only valid until the
343*2912Sartem * next invocation of this function
344*2912Sartem */
345*2912Sartem static char *
usb_ids_line_iter_get_line(unsigned int * line_len)346*2912Sartem usb_ids_line_iter_get_line (unsigned int *line_len)
347*2912Sartem {
348*2912Sartem unsigned int i;
349*2912Sartem static char line[USB_IDS_MAX_LINE_LEN];
350*2912Sartem
351*2912Sartem for (i = 0;
352*2912Sartem usb_ids_iter_pos < usb_ids_len &&
353*2912Sartem i < USB_IDS_MAX_LINE_LEN - 1 &&
354*2912Sartem usb_ids[usb_ids_iter_pos] != '\n'; i++, usb_ids_iter_pos++) {
355*2912Sartem line[i] = usb_ids[usb_ids_iter_pos];
356*2912Sartem }
357*2912Sartem
358*2912Sartem line[i] = '\0';
359*2912Sartem if (line_len != NULL)
360*2912Sartem *line_len = i;
361*2912Sartem
362*2912Sartem usb_ids_iter_pos++;
363*2912Sartem
364*2912Sartem return line;
365*2912Sartem }
366*2912Sartem
367*2912Sartem /** See if there are more lines to process in usb.ids
368*2912Sartem *
369*2912Sartem * @return #TRUE iff there are more lines to process
370*2912Sartem */
371*2912Sartem static dbus_bool_t
usb_ids_line_iter_has_more()372*2912Sartem usb_ids_line_iter_has_more ()
373*2912Sartem {
374*2912Sartem return usb_ids_iter_pos < usb_ids_len;
375*2912Sartem }
376*2912Sartem
377*2912Sartem /** Find the names for a USB device.
378*2912Sartem *
379*2912Sartem * The pointers returned are only valid until the next invocation of this
380*2912Sartem * function.
381*2912Sartem *
382*2912Sartem * @param vendor_id USB vendor id or 0 if unknown
383*2912Sartem * @param product_id USB product id or 0 if unknown
384*2912Sartem * @param vendor_name Set to pointer of result or NULL
385*2912Sartem * @param product_name Set to pointer of result or NULL
386*2912Sartem */
387*2912Sartem void
ids_find_usb(int vendor_id,int product_id,char ** vendor_name,char ** product_name)388*2912Sartem ids_find_usb (int vendor_id, int product_id,
389*2912Sartem char **vendor_name, char **product_name)
390*2912Sartem {
391*2912Sartem char *line;
392*2912Sartem unsigned int i;
393*2912Sartem unsigned int line_len;
394*2912Sartem unsigned int num_tabs;
395*2912Sartem char rep_vi[8];
396*2912Sartem char rep_pi[8];
397*2912Sartem static char store_vn[USB_IDS_MAX_LINE_LEN];
398*2912Sartem static char store_pn[USB_IDS_MAX_LINE_LEN];
399*2912Sartem dbus_bool_t vendor_matched = FALSE;
400*2912Sartem
401*2912Sartem snprintf (rep_vi, 8, "%04x", vendor_id);
402*2912Sartem snprintf (rep_pi, 8, "%04x", product_id);
403*2912Sartem
404*2912Sartem *vendor_name = NULL;
405*2912Sartem *product_name = NULL;
406*2912Sartem
407*2912Sartem for (usb_ids_line_iter_init (); usb_ids_line_iter_has_more ();) {
408*2912Sartem line = usb_ids_line_iter_get_line (&line_len);
409*2912Sartem
410*2912Sartem /* skip lines with no content */
411*2912Sartem if (line_len < 4)
412*2912Sartem continue;
413*2912Sartem
414*2912Sartem /* skip comments */
415*2912Sartem if (line[0] == '#')
416*2912Sartem continue;
417*2912Sartem
418*2912Sartem /* count number of tabs */
419*2912Sartem num_tabs = 0;
420*2912Sartem for (i = 0; i < line_len; i++) {
421*2912Sartem if (line[i] != '\t')
422*2912Sartem break;
423*2912Sartem num_tabs++;
424*2912Sartem }
425*2912Sartem
426*2912Sartem switch (num_tabs) {
427*2912Sartem case 0:
428*2912Sartem /* vendor names */
429*2912Sartem vendor_matched = FALSE;
430*2912Sartem
431*2912Sartem /* check vendor_id */
432*2912Sartem if (vendor_id != 0) {
433*2912Sartem if (memcmp (line, rep_vi, 4) == 0) {
434*2912Sartem /* found it */
435*2912Sartem vendor_matched = TRUE;
436*2912Sartem
437*2912Sartem for (i = 4; i < line_len; i++) {
438*2912Sartem if (!isspace (line[i]))
439*2912Sartem break;
440*2912Sartem }
441*2912Sartem strncpy (store_vn, line + i,
442*2912Sartem USB_IDS_MAX_LINE_LEN);
443*2912Sartem *vendor_name = store_vn;
444*2912Sartem }
445*2912Sartem }
446*2912Sartem break;
447*2912Sartem
448*2912Sartem case 1:
449*2912Sartem /* product names */
450*2912Sartem if (!vendor_matched)
451*2912Sartem continue;
452*2912Sartem
453*2912Sartem /* check product_id */
454*2912Sartem if (product_id != 0) {
455*2912Sartem if (memcmp (line + 1, rep_pi, 4) == 0) {
456*2912Sartem /* found it */
457*2912Sartem for (i = 5; i < line_len; i++) {
458*2912Sartem if (!isspace (line[i]))
459*2912Sartem break;
460*2912Sartem }
461*2912Sartem strncpy (store_pn, line + i,
462*2912Sartem USB_IDS_MAX_LINE_LEN);
463*2912Sartem *product_name = store_pn;
464*2912Sartem
465*2912Sartem /* no need to continue the search */
466*2912Sartem return;
467*2912Sartem }
468*2912Sartem }
469*2912Sartem break;
470*2912Sartem
471*2912Sartem default:
472*2912Sartem break;
473*2912Sartem }
474*2912Sartem
475*2912Sartem }
476*2912Sartem }
477*2912Sartem
478*2912Sartem /** Free resources used by to store the USB database
479*2912Sartem *
480*2912Sartem * @param #FALSE if the USB database wasn't loaded
481*2912Sartem */
482*2912Sartem static dbus_bool_t
usb_ids_free()483*2912Sartem usb_ids_free ()
484*2912Sartem {
485*2912Sartem if (usb_ids != NULL) {
486*2912Sartem free (usb_ids);
487*2912Sartem usb_ids = NULL;
488*2912Sartem return TRUE;
489*2912Sartem }
490*2912Sartem return FALSE;
491*2912Sartem }
492*2912Sartem
493*2912Sartem /** Load the USB database used for mapping vendor, product, subsys_vendor
494*2912Sartem * and subsys_product numbers into names.
495*2912Sartem *
496*2912Sartem * @param path Path of the usb.ids file, e.g.
497*2912Sartem * /usr/share/hwdata/usb.ids
498*2912Sartem * @return #TRUE if the file was succesfully loaded
499*2912Sartem */
500*2912Sartem static dbus_bool_t
usb_ids_load(const char * path)501*2912Sartem usb_ids_load (const char *path)
502*2912Sartem {
503*2912Sartem FILE *fp;
504*2912Sartem unsigned int num_read;
505*2912Sartem
506*2912Sartem fp = fopen (path, "r");
507*2912Sartem if (fp == NULL) {
508*2912Sartem printf ("couldn't open USB database at %s,", path);
509*2912Sartem return FALSE;
510*2912Sartem }
511*2912Sartem
512*2912Sartem fseek (fp, 0, SEEK_END);
513*2912Sartem usb_ids_len = ftell (fp);
514*2912Sartem fseek (fp, 0, SEEK_SET);
515*2912Sartem
516*2912Sartem usb_ids = malloc (usb_ids_len);
517*2912Sartem if (usb_ids == NULL) {
518*2912Sartem printf
519*2912Sartem ("Couldn't allocate %d bytes for USB database file\n",
520*2912Sartem usb_ids_len);
521*2912Sartem fclose(fp);
522*2912Sartem return FALSE;
523*2912Sartem }
524*2912Sartem
525*2912Sartem num_read = fread (usb_ids, sizeof (char), usb_ids_len, fp);
526*2912Sartem if (usb_ids_len != num_read) {
527*2912Sartem printf ("Error loading USB database file\n");
528*2912Sartem usb_ids_free ();
529*2912Sartem fclose(fp);
530*2912Sartem return FALSE;
531*2912Sartem }
532*2912Sartem
533*2912Sartem fclose(fp);
534*2912Sartem return TRUE;
535*2912Sartem }
536*2912Sartem
537*2912Sartem
538*2912Sartem void
ids_init(void)539*2912Sartem ids_init (void)
540*2912Sartem {
541*2912Sartem /* Load /usr/share/hwdata/pci.ids */
542*2912Sartem pci_ids_load (HWDATA_DIR "/pci.ids");
543*2912Sartem
544*2912Sartem /* Load /usr/share/hwdata/usb.ids */
545*2912Sartem usb_ids_load (HWDATA_DIR "/usb.ids");
546*2912Sartem }
547*2912Sartem
548*2912Sartem
549*2912Sartem /* This, somewhat incomplete, list is from this sources:
550*2912Sartem * http://www.plasma-online.de/english/identify/serial/pnp_id_pnp.html
551*2912Sartem * http://www-pc.uni-regensburg.de/hardware/TECHNIK/PCI_PNP/pnpid.txt
552*2912Sartem *
553*2912Sartem * Keep this sorted!
554*2912Sartem */
555*2912Sartem struct pnp_id {
556*2912Sartem char *id;
557*2912Sartem char *desc;
558*2912Sartem } static pnp_ids_list[] = {
559*2912Sartem /* Crystal Semiconductor devices */
560*2912Sartem {"CSC0000", "Crystal Semiconductor CS423x sound -- SB/WSS/OPL3 emulation"},
561*2912Sartem {"CSC0001", "Crystal Semiconductor CS423x sound -- joystick"},
562*2912Sartem {"CSC0003", "Crystal Semiconductor CS423x sound -- MPU401"},
563*2912Sartem {"CSC0010", "Crystal Semiconductor CS423x sound -- control"},
564*2912Sartem /* IBM devices */
565*2912Sartem {"IBM0071", "IBM infrared communications device"},
566*2912Sartem {"IBM3760", "IBM DSP"},
567*2912Sartem {"IBM3780", "IBM pointing device"},
568*2912Sartem /* FinePoint devices */
569*2912Sartem {"FPI2004", "FinePoint Innovations Tablet"},
570*2912Sartem /* Fujitsu (Siemens Computers) devices */
571*2912Sartem {"FUJ02E5", "Wacom Serial Pen HID Tablet"},
572*2912Sartem {"FUJ02E6", "Fujitsu Serial TouchScreen"},
573*2912Sartem /* interrupt controllers */
574*2912Sartem {"PNP0000", "AT Interrupt Controller"},
575*2912Sartem {"PNP0001", "EISA Interrupt Controller"},
576*2912Sartem {"PNP0002", "MCA Interrupt Controller"},
577*2912Sartem {"PNP0003", "APIC"},
578*2912Sartem {"PNP0004", "Cyrix SLiC MP interrupt controller"},
579*2912Sartem /* timers */
580*2912Sartem {"PNP0100", "AT Timer"},
581*2912Sartem {"PNP0101", "EISA Timer"},
582*2912Sartem {"PNP0102", "MCA Timer"},
583*2912Sartem /* DMA controllers */
584*2912Sartem {"PNP0200", "AT DMA Controller"},
585*2912Sartem {"PNP0201", "EISA DMA Controller"},
586*2912Sartem {"PNP0202", "MCA DMA Controller"},
587*2912Sartem /* keyboards */
588*2912Sartem {"PNP0300", "IBM PC/XT keyboard controller (83-key)"},
589*2912Sartem {"PNP0301", "IBM PC/AT keyboard controller (86-key)"},
590*2912Sartem {"PNP0302", "IBM PC/XT keyboard controller (84-key)"},
591*2912Sartem {"PNP0303", "IBM Enhanced (101/102-key, PS/2 mouse support)"},
592*2912Sartem {"PNP0304", "Olivetti Keyboard (83-key)"},
593*2912Sartem {"PNP0305", "Olivetti Keyboard (102-key)"},
594*2912Sartem {"PNP0306", "Olivetti Keyboard (86-key)"},
595*2912Sartem {"PNP0307", "Microsoft Windows(R) Keyboard"},
596*2912Sartem {"PNP0308", "General Input Device Emulation Interface (GIDEI) legacy"},
597*2912Sartem {"PNP0309", "Olivetti Keyboard (A101/102 key)"},
598*2912Sartem {"PNP030A", "AT&T 302 keyboard"},
599*2912Sartem {"PNP030B", "Reserved by Microsoft"},
600*2912Sartem {"PNP0320", "Japanese 101-key keyboard"},
601*2912Sartem {"PNP0321", "Japanese AX keyboard"},
602*2912Sartem {"PNP0322", "Japanese 106-key keyboard A01"},
603*2912Sartem {"PNP0323", "Japanese 106-key keyboard 002/003"},
604*2912Sartem {"PNP0324", "Japanese 106-key keyboard 001"},
605*2912Sartem {"PNP0325", "Japanese Toshiba Desktop keyboard"},
606*2912Sartem {"PNP0326", "Japanese Toshiba Laptop keyboard"},
607*2912Sartem {"PNP0327", "Japanese Toshiba Notebook keyboard"},
608*2912Sartem {"PNP0340", "Korean 84-key keyboard"},
609*2912Sartem {"PNP0341", "Korean 86-key keyboard"},
610*2912Sartem {"PNP0342", "Korean Enhanced keyboard"},
611*2912Sartem {"PNP0343", "Korean Enhanced keyboard 101b"},
612*2912Sartem {"PNP0343", "Korean Enhanced keyboard 101c"},
613*2912Sartem {"PNP0344", "Korean Enhanced keyboard 103"},
614*2912Sartem /* parallel ports */
615*2912Sartem {"PNP0400", "Standard LPT printer port"},
616*2912Sartem {"PNP0401", "ECP printer port"},
617*2912Sartem /* serial ports */
618*2912Sartem {"PNP0500", "Standard PC COM port"},
619*2912Sartem {"PNP0501", "16550A-compatible COM port"},
620*2912Sartem {"PNP0502", "Multiport serial device (non-intelligent 16550)"},
621*2912Sartem {"PNP0510", "Generic IRDA-compatible device"},
622*2912Sartem {"PNP0511", "Generic IRDA-compatible device"},
623*2912Sartem /* IDE controller */
624*2912Sartem {"PNP0600", "Generic ESDI/IDE/ATA compatible hard disk controller"},
625*2912Sartem {"PNP0601", "Plus Hardcard II"},
626*2912Sartem {"PNP0602", "Plus Hardcard IIXL/EZ"},
627*2912Sartem {"PNP0603", "Generic IDE supporting Microsoft Device Bay Specification"},
628*2912Sartem {"PNP0604", "PC standard floppy disk controller"},
629*2912Sartem {"PNP0605", "HP Omnibook floppy disk controller"},
630*2912Sartem {"PNP0680", "Bus Master E-IDE controller"},
631*2912Sartem {"PNP0700", "PC standard floppy disk controller"},
632*2912Sartem {"PNP0701", "Standard floppy controller supporting MS Device Bay Spec"},
633*2912Sartem /* system devices */
634*2912Sartem {"PNP0800", "AT-style speaker sound"},
635*2912Sartem /* obsolete devices */
636*2912Sartem {"PNP0802", "Microsoft Sound System compatible device (obsolete, use PNPB0xx instead)"},
637*2912Sartem /* display adapters / graphic cards */
638*2912Sartem {"PNP0900", "VGA Compatible"},
639*2912Sartem {"PNP0901", "Video Seven VRAM/VRAM II/1024i"},
640*2912Sartem {"PNP0902", "IBM 8514/A Compatible"},
641*2912Sartem {"PNP0903", "Trident VGA"},
642*2912Sartem {"PNP0904", "Cirrus Logic Laptop VGA"},
643*2912Sartem {"PNP0905", "Cirrus Logic VGA"},
644*2912Sartem {"PNP0906", "Tseng Labs ET4000"},
645*2912Sartem {"PNP0907", "Western Digital VGA"},
646*2912Sartem {"PNP0908", "Western Digital Laptop VGA"},
647*2912Sartem {"PNP0909", "S3 Inc. 911/924"},
648*2912Sartem {"PNP090A", "ATI Ultra Pro/Plus (Mach 32)"},
649*2912Sartem {"PNP090B", "ATI Ultra (Mach 8)"},
650*2912Sartem {"PNP090C", "IBM XGA Compatible"},
651*2912Sartem {"PNP090D", "ATI VGA Wonder"},
652*2912Sartem {"PNP090E", "Weitek P9000 Graphics Adapter"},
653*2912Sartem {"PNP090F", "Oak Technology VGA"},
654*2912Sartem {"PNP0910", "Compaq QVision"},
655*2912Sartem {"PNP0911", "IBM XGA/2"},
656*2912Sartem {"PNP0912", "Tseng Labs ET4000 W32/W32i/W32p"},
657*2912Sartem {"PNP0913", "S3 Inc. 801/928/964"},
658*2912Sartem {"PNP0914", "Cirrus Logic 5429/5434 (memory mapped)"},
659*2912Sartem {"PNP0915", "Compaq Advanced VGA (AVGA)"},
660*2912Sartem {"PNP0916", "ATI Ultra Pro Turbo (Mach64)"},
661*2912Sartem {"PNP0917", "Reserved by Microsoft"},
662*2912Sartem {"PNP0918", "Matrox MGA"},
663*2912Sartem {"PNP0919", "Compaq QVision 2000"},
664*2912Sartem {"PNP091A", "Tseng Labs W128"},
665*2912Sartem {"PNP0930", "Chips & Technologies Super VGA"},
666*2912Sartem {"PNP0931", "Chips & Technologies Accelerator"},
667*2912Sartem {"PNP0940", "NCR 77c22e Super VGA"},
668*2912Sartem {"PNP0941", "NCR 77c32blt"},
669*2912Sartem {"PNP09FF", "Plug and Play Monitors (VESA DDC)"},
670*2912Sartem /* peripheral buses */
671*2912Sartem {"PNP0A00", "ISA Bus"},
672*2912Sartem {"PNP0A01", "EISA Bus"},
673*2912Sartem {"PNP0A02", "MCA Bus"},
674*2912Sartem {"PNP0A03", "PCI Bus"},
675*2912Sartem {"PNP0A04", "VESA/VL Bus"},
676*2912Sartem {"PNP0A05", "Generic ACPI Bus"},
677*2912Sartem {"PNP0A06", "Generic ACPI Extended-IO Bus (EIO bus)"},
678*2912Sartem /* system devices */
679*2912Sartem {"PNP0B00", "AT Real-Time Clock"},
680*2912Sartem {"PNP0C00", "Plug and Play BIOS (only created by the root enumerator)"},
681*2912Sartem {"PNP0C01", "System Board"},
682*2912Sartem {"PNP0C02", "General ID for reserving resources required by PnP motherboard registers. (Not device specific.)"},
683*2912Sartem {"PNP0C03", "Plug and Play BIOS Event Notification Interrupt"},
684*2912Sartem {"PNP0C04", "Math Coprocessor"},
685*2912Sartem {"PNP0C05", "APM BIOS (Version independent)"},
686*2912Sartem {"PNP0C06", "Reserved for identification of early Plug and Play BIOS implementation"},
687*2912Sartem {"PNP0C07", "Reserved for identification of early Plug and Play BIOS implementation"},
688*2912Sartem {"PNP0C08", "ACPI system board hardware"},
689*2912Sartem {"PNP0C09", "ACPI Embedded Controller"},
690*2912Sartem {"PNP0C0A", "ACPI Control Method Battery"},
691*2912Sartem {"PNP0C0B", "ACPI Fan"},
692*2912Sartem {"PNP0C0C", "ACPI power button device"},
693*2912Sartem {"PNP0C0D", "ACPI lid device"},
694*2912Sartem {"PNP0C0E", "ACPI sleep button device"},
695*2912Sartem {"PNP0C0F", "PCI interrupt link device"},
696*2912Sartem {"PNP0C10", "ACPI system indicator device"},
697*2912Sartem {"PNP0C11", "ACPI thermal zone"},
698*2912Sartem {"PNP0C12", "Device Bay Controller"},
699*2912Sartem {"PNP0C13", "Plug and Play BIOS (used when ACPI mode cannot be used)"},
700*2912Sartem {"PNP0CF0", "Compaq LTE Lite Support"},
701*2912Sartem {"PNP0CF1", "Compaq LTE Elite Support"},
702*2912Sartem /* PCMCIA controllers */
703*2912Sartem {"PNP0E00", "Intel 82365-Compatible PCMCIA Controller"},
704*2912Sartem {"PNP0E01", "Cirrus Logic CL-PD6720 PCMCIA Controller"},
705*2912Sartem {"PNP0E02", "VLSI VL82C146 PCMCIA Controller"},
706*2912Sartem {"PNP0E03", "Intel 82365-compatible CardBus controller"},
707*2912Sartem /* mice */
708*2912Sartem {"PNP0F00", "Microsoft Bus Mouse"},
709*2912Sartem {"PNP0F01", "Microsoft Serial Mouse"},
710*2912Sartem {"PNP0F02", "Microsoft InPort Mouse"},
711*2912Sartem {"PNP0F03", "Microsoft PS/2-style Mouse"},
712*2912Sartem {"PNP0F04", "Mouse Systems Mouse"},
713*2912Sartem {"PNP0F05", "Mouse Systems 3-Button Mouse (COM2)"},
714*2912Sartem {"PNP0F06", "Genius Mouse (COM1)"},
715*2912Sartem {"PNP0F07", "Genius Mouse (COM2)"},
716*2912Sartem {"PNP0F08", "Logitech Serial Mouse"},
717*2912Sartem {"PNP0F09", "Microsoft BallPoint Serial Mouse"},
718*2912Sartem {"PNP0F0A", "Microsoft Plug and Play Mouse"},
719*2912Sartem {"PNP0F0B", "Microsoft Plug and Play BallPoint Mouse"},
720*2912Sartem {"PNP0F0C", "Microsoft-compatible Serial Mouse"},
721*2912Sartem {"PNP0F0D", "Microsoft-compatible InPort-compatible Mouse"},
722*2912Sartem {"PNP0F0E", "Microsoft-compatible PS/2-style Mouse"},
723*2912Sartem {"PNP0F0F", "Microsoft-compatible Serial BallPoint-compatible Mouse"},
724*2912Sartem {"PNP0F10", "Texas Instruments QuickPort Mouse"},
725*2912Sartem {"PNP0F11", "Microsoft-compatible Bus Mouse"},
726*2912Sartem {"PNP0F12", "Logitech PS/2-style Mouse"},
727*2912Sartem {"PNP0F13", "PS/2 Port for PS/2-style Mice"},
728*2912Sartem {"PNP0F14", "Microsoft Kids Mouse"},
729*2912Sartem {"PNP0F15", "Logitech bus mouse"},
730*2912Sartem {"PNP0F16", "Logitech SWIFT device"},
731*2912Sartem {"PNP0F17", "Logitech-compatible serial mouse"},
732*2912Sartem {"PNP0F18", "Logitech-compatible bus mouse"},
733*2912Sartem {"PNP0F19", "Logitech-compatible PS/2-style Mouse"},
734*2912Sartem {"PNP0F1A", "Logitech-compatible SWIFT Device"},
735*2912Sartem {"PNP0F1B", "HP Omnibook Mouse"},
736*2912Sartem {"PNP0F1C", "Compaq LTE Trackball PS/2-style Mouse"},
737*2912Sartem {"PNP0F1D", "Compaq LTE Trackball Serial Mouse"},
738*2912Sartem {"PNP0F1E", "Microsoft Kids Trackball Mouse"},
739*2912Sartem {"PNP0F1F", "Reserved by Microsoft Input Device Group"},
740*2912Sartem {"PNP0F20", "Reserved by Microsoft Input Device Group"},
741*2912Sartem {"PNP0F21", "Reserved by Microsoft Input Device Group"},
742*2912Sartem {"PNP0F22", "Reserved by Microsoft Input Device Group"},
743*2912Sartem {"PNP0F23", "Reserved by Microsoft Input Device Group"},
744*2912Sartem {"PNP0FFF", "Reserved by Microsoft Systems"},
745*2912Sartem {"PNP0XXX", "Unknown System Device"},
746*2912Sartem /* network cards */
747*2912Sartem {"PNP8000", "Network Adapter"},
748*2912Sartem {"PNP8001", "Novell/Anthem NE3200"},
749*2912Sartem {"PNP8004", "Compaq NE3200"},
750*2912Sartem {"PNP8006", "Intel EtherExpress/32"},
751*2912Sartem {"PNP8008", "HP EtherTwist EISA LAN Adapter/32 (HP27248A)"},
752*2912Sartem {"PNP8065", "Ungermann-Bass NIUps or NIUps/EOTP"},
753*2912Sartem {"PNP8072", "DEC (DE211) EtherWorks MC/TP"},
754*2912Sartem {"PNP8073", "DEC (DE212) EtherWorks MC/TP_BNC"},
755*2912Sartem {"PNP8074", "HP MC LAN Adapter/16 TP (PC27246)"},
756*2912Sartem {"PNP8078", "DCA 10 Mb MCA"},
757*2912Sartem {"PNP807F", "Racal NI9210"},
758*2912Sartem {"PNP8081", "Pure Data Ethernet"},
759*2912Sartem {"PNP8096", "Thomas-Conrad TC4046"},
760*2912Sartem {"PNP80C9", "IBM Token Ring"},
761*2912Sartem {"PNP80CA", "IBM Token Ring II"},
762*2912Sartem {"PNP80CB", "IBM Token Ring II/Short"},
763*2912Sartem {"PNP80CC", "IBM Token Ring 4/16Mbs"},
764*2912Sartem {"PNP80D3", "Novell/Anthem NE1000"},
765*2912Sartem {"PNP80D4", "Novell/Anthem NE2000"},
766*2912Sartem {"PNP80D5", "NE1000 Compatible"},
767*2912Sartem {"PNP80D6", "NE2000 Compatible"},
768*2912Sartem {"PNP80D7", "Novell/Anthem NE1500T"},
769*2912Sartem {"PNP80D8", "Novell/Anthem NE2100"},
770*2912Sartem {"PNP80D9", "NE2000 Plus"},
771*2912Sartem {"PNP80DD", "SMC ARCNETPC"},
772*2912Sartem {"PNP80DE", "SMC ARCNET PC100, PC200"},
773*2912Sartem {"PNP80DF", "SMC ARCNET PC110, PC210, PC250"},
774*2912Sartem {"PNP80E0", "SMC ARCNET PC130/E"},
775*2912Sartem {"PNP80E1", "SMC ARCNET PC120, PC220, PC260"},
776*2912Sartem {"PNP80E2", "SMC ARCNET PC270/E"},
777*2912Sartem {"PNP80E5", "SMC ARCNET PC600W, PC650W"},
778*2912Sartem {"PNP80E7", "DEC DEPCA"},
779*2912Sartem {"PNP80E8", "DEC (DE100) EtherWorks LC"},
780*2912Sartem {"PNP80E9", "DEC (DE200) EtherWorks Turbo"},
781*2912Sartem {"PNP80EA", "DEC (DE101) EtherWorks LC/TP"},
782*2912Sartem {"PNP80EB", "DEC (DE201) EtherWorks Turbo/TP"},
783*2912Sartem {"PNP80EC", "DEC (DE202) EtherWorks Turbo/TP_BNC"},
784*2912Sartem {"PNP80ED", "DEC (DE102) EtherWorks LC/TP_BNC"},
785*2912Sartem {"PNP80EE", "DEC EE101 (Built-In)"},
786*2912Sartem {"PNP80EF", "DEC PC 433 WS (Built-In)"},
787*2912Sartem {"PNP80F1", "3Com EtherLink Plus"},
788*2912Sartem {"PNP80F3", "3Com EtherLink II or IITP (8 or 16-bit)"},
789*2912Sartem {"PNP80F4", "3Com TokenLink"},
790*2912Sartem {"PNP80F6", "3Com EtherLink 16"},
791*2912Sartem {"PNP80F7", "3Com EtherLink III"},
792*2912Sartem {"PNP80F8", "3Com Generic Etherlink Plug and Play Device"},
793*2912Sartem {"PNP80FB", "Thomas Conrad TC6045"},
794*2912Sartem {"PNP80FC", "Thomas Conrad TC6042"},
795*2912Sartem {"PNP80FD", "Thomas Conrad TC6142"},
796*2912Sartem {"PNP80FE", "Thomas Conrad TC6145"},
797*2912Sartem {"PNP80FF", "Thomas Conrad TC6242"},
798*2912Sartem {"PNP8100", "Thomas Conrad TC6245"},
799*2912Sartem {"PNP8101", "Thomas-Conrad TC4045"},
800*2912Sartem {"PNP8104", "Thomas-Conrad TC4035"},
801*2912Sartem {"PNP8105", "DCA 10 MB"},
802*2912Sartem {"PNP8106", "DCA 10 MB Fiber Optic"},
803*2912Sartem {"PNP8107", "DCA 10 MB Twisted Pair"},
804*2912Sartem {"PNP8113", "Racal NI6510"},
805*2912Sartem {"PNP8114", "Racal NI5210/8 or NI5210/16"},
806*2912Sartem {"PNP8119", "Ungermann-Bass pcNIU"},
807*2912Sartem {"PNP811A", "Ungermann-Bass pcNIU/ex 128K"},
808*2912Sartem {"PNP811B", "Ungermann-Bass pcNIU/ex 512K"},
809*2912Sartem {"PNP811C", "Ungermann-Bass NIUpc"},
810*2912Sartem {"PNP811D", "Ungermann-Bass NIUpc/3270"},
811*2912Sartem {"PNP8120", "Ungermann-Bass NIUpc/EOTP"},
812*2912Sartem {"PNP8123", "SMC StarCard PLUS (WD/8003S)"},
813*2912Sartem {"PNP8124", "SMC StarCard PLUS With On Board Hub (WD/8003SH)"},
814*2912Sartem {"PNP8125", "SMC EtherCard PLUS (WD/8003E)"},
815*2912Sartem {"PNP8126", "SMC EtherCard PLUS With Boot ROM Socket (WD/8003EBT)"},
816*2912Sartem {"PNP8127", "SMC EtherCard PLUS With Boot ROM Socket (WD/8003EB)"},
817*2912Sartem {"PNP8128", "SMC EtherCard PLUS TP (WD/8003WT)"},
818*2912Sartem {"PNP812A", "SMC EtherCard PLUS 16 With Boot ROM Socket (WD/8013EBT)"},
819*2912Sartem {"PNP812D", "Intel EtherExpress 16 or 16TP"},
820*2912Sartem {"PNP812F", "Intel TokenExpress 16/4"},
821*2912Sartem {"PNP8130", "Intel TokenExpress MCA 16/4"},
822*2912Sartem {"PNP8132", "Intel EtherExpress 16 (MCA)"},
823*2912Sartem {"PNP8133", "Compaq Ethernet 16E"},
824*2912Sartem {"PNP8137", "Artisoft AE-1"},
825*2912Sartem {"PNP8138", "Artisoft AE-2 or AE-3"},
826*2912Sartem {"PNP8141", "Amplicard AC 210/XT"},
827*2912Sartem {"PNP8142", "Amplicard AC 210/AT"},
828*2912Sartem {"PNP814B", "Everex SpeedLink /PC16 (EV2027)"},
829*2912Sartem {"PNP8155", "HP PC LAN Adapter/8 TP (HP27245)"},
830*2912Sartem {"PNP8156", "HP PC LAN Adapter/16 TP (HP27247A)"},
831*2912Sartem {"PNP8157", "HP PC LAN Adapter/8 TL (HP27250)"},
832*2912Sartem {"PNP8158", "HP PC LAN Adapter/16 TP Plus (HP27247B)"},
833*2912Sartem {"PNP8159", "HP PC LAN Adapter/16 TL Plus (HP27252)"},
834*2912Sartem {"PNP815F", "National Semiconductor Ethernode *16AT"},
835*2912Sartem {"PNP8160", "National Semiconductor AT/LANTIC EtherNODE 16-AT3"},
836*2912Sartem {"PNP8169", "NCR StarCard"},
837*2912Sartem {"PNP816A", "NCR Token-Ring 4 Mbs ISA"},
838*2912Sartem {"PNP816B", "NCR WaveLAN AT"},
839*2912Sartem {"PNP816C", "NCR WaveLan MC"},
840*2912Sartem {"PNP816D", "NCR Token-Ring 16/4 Mbs ISA"},
841*2912Sartem {"PNP8191", "Olicom 16/4 Token-Ring Adapter"},
842*2912Sartem {"PNP81A5", "Research Machines Ethernet"},
843*2912Sartem {"PNP81B9", "ToshibaLAN (internal)"},
844*2912Sartem {"PNP81C3", "SMC EtherCard PLUS Elite (WD/8003EP)"},
845*2912Sartem {"PNP81C4", "SMC EtherCard PLUS 10T (WD/8003W)"},
846*2912Sartem {"PNP81C5", "SMC EtherCard PLUS Elite 16 (WD/8013EP)"},
847*2912Sartem {"PNP81C6", "SMC EtherCard PLUS Elite 16T (WD/8013W)"},
848*2912Sartem {"PNP81C7", "SMC EtherCard PLUS Elite 16 Combo (WD/8013EW or 8013EWC)"},
849*2912Sartem {"PNP81C8", "SMC EtherElite Ultra 16"},
850*2912Sartem {"PNP81C9", "SMC TigerCard (8216L, 8216LC, 8216LT)"},
851*2912Sartem {"PNP81CA", "SMC EtherEZ (8416)"},
852*2912Sartem {"PNP81D7", "Madge Smart 16/4 PC Ringnode"},
853*2912Sartem {"PNP81D8", "Madge Smart 16/4 Ringnode ISA"},
854*2912Sartem {"PNP81E4", "Pure Data PDI9025-32 (Token Ring)"},
855*2912Sartem {"PNP81E6", "Pure Data PDI508+ (ArcNet)"},
856*2912Sartem {"PNP81E7", "Pure Data PDI516+ (ArcNet)"},
857*2912Sartem {"PNP81EB", "Proteon Token Ring (P1390)"},
858*2912Sartem {"PNP81EC", "Proteon Token Ring (P1392)"},
859*2912Sartem {"PNP81ED", "Proteon Token Ring ISA (P1340)"},
860*2912Sartem {"PNP81EE", "Proteon Token Ring ISA (P1342)"},
861*2912Sartem {"PNP81EF", "Proteon Token Ring ISA (P1346)"},
862*2912Sartem {"PNP81F0", "Proteon Token Ring ISA (P1347)"},
863*2912Sartem {"PNP81FF", "Cabletron E2000 Series DNI"},
864*2912Sartem {"PNP8200", "Cabletron E2100 Series DNI"},
865*2912Sartem {"PNP8201", "Cabletron T2015 4/16 Mbit/s DNI"},
866*2912Sartem {"PNP8209", "Zenith Data Systems Z-Note"},
867*2912Sartem {"PNP820A", "Zenith Data Systems NE2000-Compatible"},
868*2912Sartem {"PNP8213", "Xircom Pocket Ethernet II"},
869*2912Sartem {"PNP8214", "Xircom Pocket Ethernet I"},
870*2912Sartem {"PNP8215", "Xircom Pocket Ethernet III Adapter"},
871*2912Sartem {"PNP821D", "RadiSys EXM-10"},
872*2912Sartem {"PNP8227", "SMC 3000 Series"},
873*2912Sartem {"PNP8228", "SMC 91C2 controller"},
874*2912Sartem {"PNP8231", "AMD AM2100/AM1500T"},
875*2912Sartem {"PNP824F", "RCE 10Base-T (16 bit)"},
876*2912Sartem {"PNP8250", "RCE 10Base-T (8 bit)"},
877*2912Sartem {"PNP8263", "Tulip NCC-16"},
878*2912Sartem {"PNP8277", "Exos 105"},
879*2912Sartem {"PNP828A", "Intel '595 based Ethernet"},
880*2912Sartem {"PNP828B", "TI2000-style Token Ring"},
881*2912Sartem {"PNP828C", "AMD PCNet Family cards"},
882*2912Sartem {"PNP828D", "AMD PCNet32 (VL version)"},
883*2912Sartem {"PNP8294", "IrDA Infrared NDIS driver (Microsoft-supplied)"},
884*2912Sartem {"PNP82BD", "IBM PCMCIA-NIC"},
885*2912Sartem {"PNP82C0", "Eagle Technology NE200T"},
886*2912Sartem {"PNP82C2", "Xircom CE10"},
887*2912Sartem {"PNP82C3", "Xircom CEM2"},
888*2912Sartem {"PNP82C4", "Xircom CE2"},
889*2912Sartem {"PNP8321", "DEC Ethernet (All Types)"},
890*2912Sartem {"PNP8323", "SMC EtherCard (All Types except 8013/A)"},
891*2912Sartem {"PNP8324", "ARCNET Compatible"},
892*2912Sartem {"PNP8325", "SMC TokenCard PLUS (8115T)"},
893*2912Sartem {"PNP8326", "Thomas Conrad (All Arcnet Types)"},
894*2912Sartem {"PNP8327", "IBM Token Ring (All Types)"},
895*2912Sartem {"PNP8328", "Ungermann-Bass NIU"},
896*2912Sartem {"PNP8329", "Proteon ProNET-4/16 ISA Token Ring (P1392+,P1392,1390)"},
897*2912Sartem {"PNP8385", "Remote Network Access [RNA] Driver"},
898*2912Sartem {"PNP8387", "Remote Network Access [RNA] PPP Driver"},
899*2912Sartem {"PNP8388", "Reserved for Microsoft Networking components"},
900*2912Sartem {"PNP8389", "Peer IrLAN infrared driver (Microsoft-supplied)"},
901*2912Sartem {"PNP8390", "Generic network adapter"},
902*2912Sartem {"PNP8XXX", "Unknown Network Adapter"},
903*2912Sartem /* modems */
904*2912Sartem {"PNP9000", "Modem"},
905*2912Sartem /* CD controller */
906*2912Sartem {"PNPA000", "Adaptec 154x compatible SCSI controller"},
907*2912Sartem {"PNPA001", "Adaptec 174x compatible SCSI controller"},
908*2912Sartem {"PNPA002", "Future Domain 16-700 compatible controller"},
909*2912Sartem {"PNPA003", "Mitsumi CD-ROM adapter (Panasonic spec., used on SBPro/SB16)"},
910*2912Sartem {"PNPA01B", "Trantor 128 SCSI Controller"},
911*2912Sartem {"PNPA01D", "Trantor T160 SCSI Controller"},
912*2912Sartem {"PNPA01E", "Trantor T338 Parallel SCSI controller"},
913*2912Sartem {"PNPA01F", "Trantor T348 Parallel SCSI controller"},
914*2912Sartem {"PNPA020", "Trantor Media Vision SCSI controller"},
915*2912Sartem {"PNPA022", "Always IN-2000 SCSI controller"},
916*2912Sartem {"PNPA02B", "Sony proprietary CD-ROM controller"},
917*2912Sartem {"PNPA02D", "Trantor T13b 8-bit SCSI controller"},
918*2912Sartem {"PNPA02F", "Trantor T358 Parallel SCSI controller"},
919*2912Sartem {"PNPA030", "Mitsumi LU-005 Single Speed CD-ROM controller + drive"},
920*2912Sartem {"PNPA031", "Mitsumi FX-001 Single Speed CD-ROM controller + drive"},
921*2912Sartem {"PNPA032", "Mitsumi FX-001 Double Speed CD-ROM controller + drive"},
922*2912Sartem {"PNPAXXX", "Unknown SCSI, Proprietary CD Adapter"},
923*2912Sartem /* multimedia devices */
924*2912Sartem {"PNPB000", "Creative Labs Sound Blaster 1.5 (or compatible sound device)"},
925*2912Sartem {"PNPB001", "Creative Labs Sound Blaster 2.0 (or compatible sound device)"},
926*2912Sartem {"PNPB002", "Creative Labs Sound Blaster Pro (or compatible sound device)"},
927*2912Sartem {"PNPB003", "Creative Labs Sound Blaster 16 (or compatible sound device)"},
928*2912Sartem {"PNPB004", "MediaVision Thunderboard (or compatible sound device)"},
929*2912Sartem {"PNPB005", "Adlib-compatible FM synthesizer device"},
930*2912Sartem {"PNPB006", "MPU401 compatible"},
931*2912Sartem {"PNPB007", "Microsoft Windows Sound System-compatible sound device"},
932*2912Sartem {"PNPB008", "Compaq Business Audio"},
933*2912Sartem {"PNPB009", "Plug and Play Microsoft Windows Sound System Device"},
934*2912Sartem {"PNPB00A", "MediaVision Pro Audio Spectrum (Trantor SCSI enabled, Thunder Chip Disabled)"},
935*2912Sartem {"PNPB00B", "MediaVision Pro Audio 3D"},
936*2912Sartem {"PNPB00C", "MusicQuest MQX-32M"},
937*2912Sartem {"PNPB00D", "MediaVision Pro Audio Spectrum Basic (No Trantor SCSI, Thunder Chip Enabled)"},
938*2912Sartem {"PNPB00E", "MediaVision Pro Audio Spectrum (Trantor SCSI enabled, Thunder Chip Disabled)"},
939*2912Sartem {"PNPB00F", "MediaVision Jazz-16 chipset (OEM Versions)"},
940*2912Sartem {"PNPB010", "Orchid Videola - Auravision VxP500 chipset"},
941*2912Sartem {"PNPB018", "MediaVision Pro Audio Spectrum 8-bit"},
942*2912Sartem {"PNPB019", "MediaVision Pro Audio Spectrum Basic (No Trantor SCSI, Thunder Chip Enabled)"},
943*2912Sartem {"PNPB020", "Yamaha OPL3-compatible FM synthesizer device"},
944*2912Sartem {"PNPB02F", "Joystick/Game port"},
945*2912Sartem {"PNPB077", "OAK Mozart Sound System"},
946*2912Sartem {"PNPB078", "OAK Mozart Sound System MPU-401"},
947*2912Sartem {"PNPBXXX", "Unknown Multimedia Device"},
948*2912Sartem /* modems */
949*2912Sartem {"PNPC000", "Compaq 14400 Modem (TBD)"},
950*2912Sartem {"PNPC001", "Compaq 2400/9600 Modem (TBD)"},
951*2912Sartem {"PNPCXXX", "Unknown Modem"},
952*2912Sartem /* some other network cards */
953*2912Sartem {"PNPD300", "SK-NET TR4/16+ Token-Ring"},
954*2912Sartem {"PNPE000", "SK-NET G16, G16/TP Ethernet"},
955*2912Sartem {"PNPF000", "SK-NET FDDI-FI FDDI LAN"},
956*2912Sartem /* Toshiba devices */
957*2912Sartem {"TOS6200", "Toshiba Notebook Extra HCI driver"},
958*2912Sartem {"TOS6202", "Toshiba Notebook Extra HCI driver"},
959*2912Sartem {"TOS6207", "Toshiba Notebook Extra HCI driver"},
960*2912Sartem {"TOS7400", "Toshiba AcuPoint"},
961*2912Sartem /* Wacom devices */
962*2912Sartem {"WACf004", "Wacom Serial Tablet PC Pen Tablet/Digitizer"},
963*2912Sartem {"WACf005", "Wacom Serial Tablet PC Pen Tablet/Digitizer"},
964*2912Sartem {"WACf006", "Wacom Serial Tablet PC Pen Tablet/Digitizer"}
965*2912Sartem };
966*2912Sartem
967*2912Sartem static int
ids_comp_pnp(const void * id1,const void * id2)968*2912Sartem ids_comp_pnp(const void *id1, const void *id2) {
969*2912Sartem struct pnp_id *pnp_id1 = (struct pnp_id *) id1;
970*2912Sartem struct pnp_id *pnp_id2 = (struct pnp_id *) id2;
971*2912Sartem return strcasecmp(pnp_id1->id, pnp_id2->id);
972*2912Sartem }
973*2912Sartem
974*2912Sartem void
ids_find_pnp(const char * pnp_id,char ** pnp_description)975*2912Sartem ids_find_pnp (const char *pnp_id, char **pnp_description)
976*2912Sartem {
977*2912Sartem static gboolean sorted = FALSE;
978*2912Sartem struct pnp_id search, *res;
979*2912Sartem
980*2912Sartem if (!sorted) {
981*2912Sartem /* sort the list, to be sure that all is in correc order */
982*2912Sartem qsort(pnp_ids_list, sizeof(pnp_ids_list)/sizeof(pnp_ids_list[0]),
983*2912Sartem sizeof(struct pnp_id), ids_comp_pnp);
984*2912Sartem sorted = TRUE;
985*2912Sartem }
986*2912Sartem
987*2912Sartem search.id = (char *) pnp_id;
988*2912Sartem res = bsearch(&search, pnp_ids_list, sizeof(pnp_ids_list)/sizeof(pnp_ids_list[0]),
989*2912Sartem sizeof(struct pnp_id), ids_comp_pnp);
990*2912Sartem
991*2912Sartem if (res != NULL)
992*2912Sartem *pnp_description = res->desc;
993*2912Sartem else
994*2912Sartem *pnp_description = NULL;
995*2912Sartem return;
996*2912Sartem }
997