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