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