1 /* $Id: residual.c,v 1.1 2002/05/02 14:36:43 nonaka Exp $ */ 2 3 /*- 4 * Copyright (c) 2002 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by NONAKA Kimihiro. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 #include <sys/param.h> 40 #include <sys/systm.h> 41 42 #include <machine/residual.h> 43 #include <machine/pnp.h> 44 45 int dump_residual_data = 1; 46 47 static void make_pnp_device_tree(void *); 48 static void bustype_subr(DEVICE_ID *); 49 50 #define NELEMS(array) ((size_t)(sizeof(array)/sizeof(array[0]))) 51 52 static char *FirmwareSupplier[] = { 53 "IBMFirmware", 54 "MotoFirmware", 55 "FirmWorks", 56 "Bull", 57 }; 58 59 static char *FirmwareSupports[] = { 60 "Conventional", 61 "OpenFirmware", 62 "Diagnostics", 63 "LowDebug", 64 "Multiboot", 65 "LowClient", 66 "Hex41", 67 "FAT", 68 "ISO9660", 69 "SCSI_InitiatorID_Override", 70 "Tape_Boot", 71 "FW_Boot_Path", 72 }; 73 74 static char *EndianSwitchMethod[] = { 75 "Unknown", 76 "UsePort92", 77 "UsePCIConfigA8", 78 "UseFF001030", 79 }; 80 81 static char *SpreadIOMethod[] = { 82 "UsePort850", 83 }; 84 85 static char *CacheAttrib[] = { 86 "None", 87 "Split cache", 88 "Combined cache", 89 }; 90 91 static char *Usage[] = { 92 "FirmwareStack", 93 "FirmwareHeap", 94 "FirmwareCode", 95 "BootImage", 96 "Free", 97 "Unpopulated", 98 "ISAAddr", 99 "PCIConfig", 100 "PCIAddr", 101 "SystemRegs", 102 "SystemIO", 103 "IOMemory", 104 "UnPopSystemROM", 105 "SystemROM", 106 "ResumeBlock", 107 "Other", 108 }; 109 110 static char *BusId[] = { 111 "ISA", 112 "EISA", 113 "PCI", 114 "PCMCIA", 115 "ISAPNP", 116 "MCA", 117 "MX", 118 "PROCESSOR", 119 "VME", 120 }; 121 122 static char *Flags[] = { 123 "Output", 124 "Input", 125 "ConsoleOut", 126 "ConsoleIn", 127 "Removable", 128 "ReadOnly", 129 "PowerManaged", 130 "Disableable", 131 "Configurable", 132 "Boot", 133 "Dock", 134 "Static", 135 "Failed", 136 "Integrated", 137 "Enabled", 138 }; 139 140 static char hextochr[] = "0123456789ABCDEF"; 141 142 void 143 print_residual_device_info(void) 144 { 145 VPD *vpd; 146 PPC_CPU *ppc_cpu; 147 MEM_MAP *mem_map; 148 PPC_MEM *ppc_mem; 149 PPC_DEVICE *ppc_dev; 150 char *str; 151 unsigned long l; 152 unsigned short s; 153 unsigned long nmseg; 154 unsigned long nmem; 155 unsigned long ndev; 156 unsigned long page_size; 157 int ncpu; 158 int first; 159 int i, j; 160 unsigned char p[4]; 161 162 if (!dump_residual_data) 163 return; 164 165 if (be32toh(res->ResidualLength) == 0) 166 return; 167 168 printf("ResidualLength = %ld\n", be32toh(res->ResidualLength)); 169 printf("Version = %d\n", res->Version); 170 printf("Revision = %d\n", res->Revision); 171 printf("EC = %d\n", be16toh(res->EC)); 172 173 /* 174 * VPD 175 */ 176 vpd = &res->VitalProductData; 177 printf("\nVPD\n"); 178 printf("\tPrintableModel = %-32s\n", vpd->PrintableModel); 179 printf("\tSerial = %-16s\n", vpd->Serial); 180 181 l = be32toh(vpd->FirmwareSupplier); 182 printf("\tFirmwareSupplier = %s\n", 183 (l >= NELEMS(FirmwareSupplier)) ? "Unknown" : FirmwareSupplier[l]); 184 l = be32toh(vpd->FirmwareSupports); 185 printf("\tFirmwareSupports = 0x%08lx\n", l); 186 for (first = 1, i = 0; i < sizeof(unsigned long) * 8; i++) { 187 if ((l & (1UL << i)) != 0) { 188 printf("\t\t: %s\n", i >= NELEMS(FirmwareSupports) 189 ? "Unknown" : FirmwareSupports[i]); 190 first = 0; 191 } 192 } 193 if (first) 194 printf("\t\t: None\n"); 195 196 printf("\tNvramSize = %ld\n", be32toh(vpd->NvramSize)); 197 printf("\tNumSIMMSlots = %ld\n", be32toh(vpd->NumSIMMSlots)); 198 s = be16toh(vpd->EndianSwitchMethod); 199 printf("\tEndianSwitchMethod = %s\n", 200 (s >= NELEMS(EndianSwitchMethod)) 201 ? "Unknown" : EndianSwitchMethod[s]); 202 s = be16toh(vpd->SpreadIOMethod); 203 printf("\tSpreadIOMethod = %s\n", 204 (s >= NELEMS(SpreadIOMethod)) ? "Unknown" : SpreadIOMethod[s]); 205 printf("\tSmpIar = %ld\n", be32toh(vpd->SmpIar)); 206 printf("\tRAMErrLogOffset = %ld\n", be32toh(vpd->RAMErrLogOffset)); 207 printf("\tProcessorHz = %ld\n", be32toh(vpd->ProcessorHz)); 208 printf("\tProcessorBusHz = %ld\n", be32toh(vpd->ProcessorBusHz)); 209 printf("\tTimeBaseDivisor = %ld\n", be32toh(vpd->TimeBaseDivisor)); 210 printf("\tWordWidth = %ld\n", be32toh(vpd->WordWidth)); 211 page_size = be32toh(vpd->PageSize); 212 printf("\tPageSize = %ld\n", page_size); 213 printf("\tCoherenceBlockSize = %ld\n",be32toh(vpd->CoherenceBlockSize)); 214 printf("\tGranuleSize = %ld\n", be32toh(vpd->GranuleSize)); 215 216 printf("\tL1 Cache variables\n"); 217 printf("\t\tCacheSize = %ld\n", be32toh(vpd->CacheSize)); 218 l = be32toh(vpd->CacheAttrib); 219 printf("\t\tCacheAttrib = %s\n", 220 (s >= NELEMS(CacheAttrib)) ? "Unknown" : CacheAttrib[s]); 221 printf("\t\tCacheAssoc = %ld\n", be32toh(vpd->CacheAssoc)); 222 printf("\t\tCacheLineSize = %ld\n", be32toh(vpd->CacheLineSize)); 223 224 /* 225 * PPC_CPU 226 */ 227 printf("\n"); 228 printf("MaxNumCpus = %d\n", be16toh(res->MaxNumCpus)); 229 ncpu = be16toh(res->ActualNumCpus); 230 printf("ActualNumCpus = %d\n", ncpu); 231 ppc_cpu = res->Cpus; 232 for (i = 0; i < ((ncpu > MAX_CPUS) ? MAX_CPUS : ncpu); i++) { 233 printf("%d:\n", i); 234 printf("\tCpuType = %08lx\n", be32toh(ppc_cpu[i].CpuType)); 235 printf("\tCpuNumber = %d\n", ppc_cpu[i].CpuNumber); 236 switch (ppc_cpu[i].CpuState) { 237 case CPU_GOOD: 238 str = "CPU is present, and active"; 239 break; 240 case CPU_GOOD_FW: 241 str = "CPU is present, and in firmware"; 242 break; 243 case CPU_OFF: 244 str = "CPU is present, but inactive"; 245 break; 246 case CPU_FAILED: 247 str = "CPU is present, but failed POST"; 248 break; 249 case CPU_NOT_PRESENT: 250 str = "CPU not present"; 251 break; 252 default: 253 str = "Unknown state"; 254 break; 255 } 256 printf("\tCpuState: %s (%d)\n", str, ppc_cpu[i].CpuState); 257 } 258 259 printf("\n"); 260 printf("TotalMemory = %ld (0x%08lx)\n", 261 be32toh(res->TotalMemory) ,be32toh(res->TotalMemory)); 262 printf("GoodMemory = %ld (0x%08lx)\n", 263 be32toh(res->GoodMemory), be32toh(res->GoodMemory)); 264 265 /* 266 * MEM_MAP 267 */ 268 printf("\n"); 269 nmseg = be32toh(res->ActualNumMemSegs); 270 printf("ActualNumMemSegs = %ld\n", nmseg); 271 mem_map = res->Segs; 272 for (i = 0; i < ((nmseg > MAX_MEM_SEGS) ? MAX_MEM_SEGS : nmseg); i++) { 273 unsigned long pc; 274 275 printf("%d:\n", i); 276 l = be32toh(mem_map[i].Usage); 277 printf("\tUsage = "); 278 for (first = 1, j = 0; j < sizeof(unsigned long) * 8; j++) { 279 if ((l & (1UL << j)) != 0) { 280 printf("%s%s", first ? "" : ", ", 281 j >= NELEMS(Usage) ? "Unknown" : Usage[j]); 282 first = 0; 283 } 284 } 285 printf(" (0x%08lx)\n", l); 286 printf("\tBasePage = 0x%05lx000\n", 287 be32toh(mem_map[i].BasePage)); 288 pc = be32toh(mem_map[i].PageCount); 289 printf("\tPageCount = 0x%08lx (%ld page%s)\n", 290 page_size * pc, pc, pc == 1 ? "" : "s"); 291 } 292 293 /* 294 * PPC_MEM 295 */ 296 printf("\n"); 297 nmem = be32toh(res->ActualNumMemories); 298 printf("ActualNumMemories = %ld\n", nmem); 299 ppc_mem = res->Memories; 300 for (i = 0; i < ((nmem > MAX_MEMS) ? MAX_MEMS : nmem); i++) { 301 printf("%d:\n", i); 302 printf("\tSIMMSize = %ld MB\n", be32toh(ppc_mem[i].SIMMSize)); 303 } 304 305 /* 306 * PPC_DEVICE 307 */ 308 printf("\n"); 309 ndev = be32toh(res->ActualNumDevices); 310 printf("ActualNumDevices = %ld\n", ndev); 311 ppc_dev = res->Devices; 312 for (i = 0; i < ((ndev > MAX_DEVICES) ? MAX_DEVICES : ndev); i++) { 313 DEVICE_ID *id = &ppc_dev[i].DeviceId; 314 BUS_ACCESS *bus = &ppc_dev[i].BusAccess; 315 316 printf("\n%d:\n", i); 317 318 printf("\tDEVICE_ID\n"); 319 l = be32toh(id->BusId); 320 printf("\t\tBusId = "); 321 for (j = 0; j < sizeof(unsigned long) * 8; j++) { 322 if ((l & (1UL << j)) != 0) { 323 printf("%s", 324 j >= NELEMS(BusId) ? "Unknown" : BusId[j]); 325 break; 326 } 327 } 328 printf("\n"); 329 l = be32toh(id->DevId); 330 p[0] = (l >> 24) & 0xff; 331 p[1] = (l >> 16) & 0xff; 332 p[2] = (l >> 8) & 0xff; 333 p[3] = l & 0xff; 334 printf("\t\tDevId = 0x%08lx (%c%c%c%c%c%c%c)\n", l, 335 ((p[0] >> 2) & 0x1f) + 'A' - 1, 336 (((p[0] & 0x03) << 3) | ((p[1] >> 5) & 0x07)) + 'A' - 1, 337 (p[1] & 0x1f) + 'A' - 1, 338 hextochr[(p[2] >> 4) & 0xf], hextochr[p[2] & 0xf], 339 hextochr[(p[3] >> 4) & 0xf], hextochr[p[3] & 0xf]); 340 printf("\t\tSerialNum = 0x%08lx\n", be32toh(id->SerialNum)); 341 l = be32toh(id->Flags); 342 printf("\t\tFlags = 0x%08lx\n", l); 343 for (first = 1, j = 0; j < sizeof(unsigned long) * 8; j++) { 344 if ((l & (1UL << j)) != 0) { 345 printf("\t\t\t: %s\n", 346 j >= NELEMS(Flags) ? "Unknown" : Flags[j]); 347 first = 0; 348 } 349 } 350 if (first) 351 printf("\t\t\t: None\n"); 352 353 bustype_subr(id); 354 355 printf("\tBUS_ACCESS\n"); 356 printf("\t\tinfo0 = %d\n", bus->PnPAccess.CSN); 357 printf("\t\tinfo1 = %d\n", bus->PnPAccess.LogicalDevNumber); 358 359 l = be32toh(ppc_dev[i].AllocatedOffset); 360 printf("\tAllocatedOffset = 0x%08lx\n", l); 361 make_pnp_device_tree(res->DevicePnPHeap + l); 362 363 l = be32toh(ppc_dev[i].PossibleOffset); 364 printf("\tPossibleOffset = 0x%08lx\n", l); 365 make_pnp_device_tree(res->DevicePnPHeap + l); 366 367 l = be32toh(ppc_dev[i].CompatibleOffset); 368 printf("\tCompatibleOffset = 0x%08lx\n", l); 369 make_pnp_device_tree(res->DevicePnPHeap + l); 370 } 371 } 372 373 enum { 374 TAG_SMALL = 0, 375 TAG_LARGE 376 }; 377 378 /*-- 379 * pnp device 380 */ 381 static int pnp_small_pkt(void *); 382 static int pnp_large_pkt(void *); 383 384 static void 385 make_pnp_device_tree(void *v) 386 { 387 unsigned char *p = v; 388 int size; 389 390 if (p == NULL) 391 return; 392 393 for (; p[0] != END_TAG; p += size) { 394 if (tag_type(p[0]) == TAG_SMALL) 395 size = pnp_small_pkt(p); 396 else 397 size = pnp_large_pkt(p); 398 } 399 } 400 401 static int 402 pnp_small_pkt(void *v) 403 { 404 int tag = *(unsigned char *)v; 405 int item, size; 406 int i, j; 407 int first; 408 409 item = tag_small_item_name(tag); 410 size = tag_small_count(tag) + 1 /* tag */; 411 412 switch (item) { 413 case CompatibleDevice: { 414 struct _S3_Pack *p = v; 415 unsigned char *q = p->CompatId; 416 417 printf("\t\tCompatibleDevice = %c%c%c%c%c%c%c\n", 418 ((q[0] >> 2) & 0x1f) + 'A' - 1, 419 (((q[0] & 0x03) << 3) | ((q[1] >> 5) & 0x07)) + 'A' - 1, 420 (q[1] & 0x1f) + 'A' - 1, 421 hextochr[(q[2] >> 4) & 0xf], hextochr[q[2] & 0xf], 422 hextochr[(q[3] >> 4) & 0xf], hextochr[q[3] & 0xf]); 423 } 424 break; 425 426 case IRQFormat: { 427 struct _S4_Pack *p = v; 428 429 printf("\t\tIRQ: "); 430 for (first = 1, j = 0; j < 2; j++) { 431 for (i = 0; i < 8; i++) { 432 if (p->IRQMask[j] & (1 << i)) { 433 printf("%s%d", 434 first ? "" : ", ", j * 8 + i); 435 first = 0; 436 } 437 } 438 } 439 if (first) 440 printf("None "); 441 442 if (size == 3) { 443 static char *IRQInfo[] = { 444 "high true edge sensitive", 445 "low true edge sensitive", 446 "high true level sensitive", 447 "low true level sensitive", 448 }; 449 450 if (p->IRQInfo & 0xf0) 451 goto IRQout; 452 453 for (first = 1, i = 0; i < NELEMS(IRQInfo); i++) { 454 if (p->IRQInfo & (1 << i)) { 455 printf("%s%s", first ? " (" : ", ", 456 IRQInfo[i]); 457 first = 0; 458 } 459 } 460 if (!first) 461 printf(")"); 462 } 463 IRQout: 464 printf("\n"); 465 } 466 break; 467 468 case DMAFormat: { 469 struct _S5_Pack *p = v; 470 471 printf("\t\tDMA: "); 472 for (first = 1, i = 0; i < 8; i++) { 473 if (p->DMAMask & (1 << i)) { 474 printf("%s%d", first ? "" : ", ", i); 475 first = 0; 476 } 477 } 478 printf("%s", first ? "None" : ""); 479 480 printf("\n"); 481 } 482 break; 483 484 case StartDepFunc: 485 case EndDepFunc: 486 break; 487 488 case IOPort: { 489 struct _S8_Pack *p = v; 490 unsigned short mask; 491 unsigned short iomin, iomax; 492 int align, len; 493 494 mask = p->IOInfo & ISAAddr16bit ? 0xffff : 0x03ff; 495 iomin = (p->RangeMin[0] | (p->RangeMin[1] << 8)) & mask; 496 iomax = (p->RangeMax[0] | (p->RangeMax[1] << 8)) & mask; 497 align = p->IOAlign; 498 len = p->IONum; 499 500 if (len != 1) { 501 if (iomin == iomax) 502 printf("\t\tIOPort: 0x%x-0x%x", 503 iomin, iomin + len-1); 504 else 505 printf("\t\tIOPort: min 0x%x-0x%x," 506 " max 0x%x-0x%x (%d byte%s align)", 507 iomin, iomin + len-1, 508 iomax, iomax + len-1, 509 align, align != 1 ? "s" : ""); 510 } else { 511 if (iomin == iomax) 512 printf("\t\tIOPort: 0x%x", iomin); 513 else 514 printf("\t\tIOPort: min 0x%x, max 0x%x" 515 " (%d byte%s align)", 516 iomin, iomax, 517 align, align != 1 ? "s" : ""); 518 } 519 printf("\n"); 520 } 521 break; 522 523 case FixedIOPort: { 524 struct _S9_Pack *p = v; 525 unsigned short ioport; 526 int len; 527 528 ioport = (p->Range[0] | (p->Range[1] << 8)) & 0x3ff; 529 len = p->IONum; 530 531 if (len != 1) 532 printf("\t\tFixedIOPort: 0x%x-0x%x", 533 ioport, ioport + len - 1); 534 else 535 printf("\t\tFixedIOPort: 0x%x", ioport); 536 printf("\n"); 537 } 538 break; 539 540 case SmallVendorItem: { 541 unsigned char *p = v; 542 543 printf("\t\tSmallVendorItem: "); 544 switch (p[1]) { 545 case 1: 546 printf("%c%c%c", 547 ((p[2] >> 2) & 0x1f) + 'A' - 1, 548 (((p[2] & 3) << 3) | ((p[3] >> 5) & 7)) + 'A' - 1, 549 (p[3] & 0x1f) + 'A' - 1); 550 break; 551 552 default: 553 break; 554 } 555 556 printf("\n"); 557 for (i = 0; i < size - 1; i++) { 558 if ((i % 16) == 0) 559 printf("\t\t\t"); 560 printf("%02x ", p[i + 1]); 561 if ((i % 16) == 15) 562 printf("\n"); 563 } 564 if ((i % 16) != 0) 565 printf("\n"); 566 } 567 break; 568 569 default: { 570 unsigned char *p = v; 571 572 printf("small\n"); 573 printf("item = %d\n", item); 574 printf("size = %d\n", size); 575 576 for (i = 1; i < size; i++) 577 printf("%02x ", p[i]); 578 printf("\n"); 579 } 580 break; 581 } 582 583 return size; 584 } 585 586 static int 587 pnp_large_pkt(void *v) 588 { 589 int tag = *(unsigned char *)v; 590 unsigned char *q = v; 591 int item, size; 592 int i; 593 594 item = tag_large_item_name(tag); 595 size = (q[1] | (q[2] << 8)) + 3 /* tag + length */; 596 597 switch (item) { 598 case LargeVendorItem: { 599 unsigned char *p = v; 600 601 printf("\t\tLargeVendorItem:\n"); 602 for (i = 0; i < size - 3; i++) { 603 if ((i % 16) == 0) 604 printf("\t\t\t"); 605 printf("%02x ", p[i + 3]); 606 if ((i % 16) == 15) 607 printf("\n"); 608 } 609 if ((i % 16) != 0) 610 printf("\n"); 611 } 612 break; 613 614 default: { 615 unsigned char *p = v; 616 617 printf("large\n"); 618 printf("item = %d\n", item); 619 printf("size = %d\n", size); 620 621 for (i = 3; i < size; i++) 622 printf("%02x ", p[i]); 623 printf("\n"); 624 } 625 break; 626 } 627 628 return size; 629 } 630 631 /*-- 632 * bus type 633 */ 634 static void mass_subr(DEVICE_ID *); 635 static void nic_subr(DEVICE_ID *); 636 static void display_subr(DEVICE_ID *); 637 static void mm_subr(DEVICE_ID *); 638 static void mem_subr(DEVICE_ID *); 639 static void bridge_subr(DEVICE_ID *); 640 static void comm_subr(DEVICE_ID *); 641 static void sys_subr(DEVICE_ID *); 642 static void input_subr(DEVICE_ID *); 643 static void service_subr(DEVICE_ID *); 644 645 static void 646 bustype_subr(DEVICE_ID *id) 647 { 648 static struct bustype { 649 char *str; 650 void (*func)(DEVICE_ID *); 651 } BaseType[] = { 652 { "Reserved" , NULL }, 653 { "MassStorageDevice" , mass_subr }, 654 { "NetworkInterfaceController" , nic_subr }, 655 { "DisplayController" , display_subr }, 656 { "MultimediaController" , mm_subr }, 657 { "MemoryController" , mem_subr }, 658 { "BridgeController" , bridge_subr }, 659 { "CommunicationsDevice" , comm_subr }, 660 { "SystemPeripheral" , sys_subr }, 661 { "InputDevice" , input_subr }, 662 { "ServiceProcessor" , service_subr }, 663 }; 664 int type; 665 666 type = (id->BaseType >= NELEMS(BaseType)) ? 0 : id->BaseType; 667 668 printf("\t\tBaseType = %s (%d)\n", BaseType[type].str, id->BaseType); 669 if (BaseType[type].func != NULL) 670 (*BaseType[type].func)(id); 671 } 672 673 static void 674 mass_subr(DEVICE_ID *id) 675 { 676 static char *IDEController_tabel[] = { 677 "GeneralIDE", 678 "ATACompatible", 679 }; 680 static char *FloppyController_table[] = { 681 "GeneralFloppy", 682 "Compatible765", 683 "NS398_Floppy", 684 "NS26E_Floppy", 685 "NS15C_Floppy", 686 "NS2E_Floppy", 687 "CHRP_Floppy", 688 }; 689 char *p, *q = NULL; 690 691 switch (id->SubType) { 692 case SCSIController: 693 p = "SCSIController"; 694 q = "GeneralSCSI"; 695 break; 696 case IDEController: 697 p = "IDEController"; 698 q = id->Interface >= NELEMS(IDEController_tabel) 699 ? NULL : IDEController_tabel[id->Interface]; 700 break; 701 case FloppyController: 702 p = "FloppyController"; 703 q = id->Interface >= NELEMS(FloppyController_table) 704 ? NULL : FloppyController_table[id->Interface]; 705 break; 706 case IPIController: 707 p = "IPIController"; 708 q = "GeneralIPI"; 709 break; 710 case OtherMassStorageController: 711 p = "OtherMassStorageController"; 712 break; 713 default: 714 p = "UnknownStorageController"; 715 break; 716 } 717 718 printf("\t\tSubType = %s (%d)\n", p, id->SubType); 719 printf("\t\tInterface = %s (%d)\n", q ? q : "None", id->Interface); 720 } 721 722 static void 723 nic_subr(DEVICE_ID *id) 724 { 725 char *p, *q = NULL; 726 727 switch (id->SubType) { 728 case EthernetController: 729 p = "EthernetController"; 730 q = "GeneralEther"; 731 break; 732 case TokenRingController: 733 p = "TokenRingController"; 734 q = "GeneralToken"; 735 break; 736 case FDDIController: 737 p = "FDDIController"; 738 q = "GeneralFDDI"; 739 break; 740 case OtherNetworkController: 741 p = "OtherNetworkController"; 742 break; 743 default: 744 p = "UnknownNetworkController"; 745 break; 746 } 747 748 printf("\t\tSubType = %s (%d)\n", p, id->SubType); 749 printf("\t\tInterface = %s (%d)\n", q ? q : "None", id->Interface); 750 } 751 752 static void 753 display_subr(DEVICE_ID *id) 754 { 755 char *p, *q = NULL; 756 757 switch (id->SubType) { 758 case VGAController: 759 p = "VGAController"; 760 q = "GeneralVGA"; 761 break; 762 case SVGAController: 763 p = "SVGAController"; 764 q = "GeneralSVGA"; 765 break; 766 case XGAController: 767 p = "XGAController"; 768 q = "GeneralXGA"; 769 break; 770 case OtherDisplayController: 771 p = "OtherDisplayController"; 772 break; 773 default: 774 p = "UnknownDisplayController"; 775 break; 776 } 777 778 printf("\t\tSubType = %s (%d)\n", p, id->SubType); 779 printf("\t\tInterface = %s (%d)\n", q ? q : "None", id->Interface); 780 } 781 782 static void 783 mm_subr(DEVICE_ID *id) 784 { 785 static char *AudioController_table[] = { 786 "GeneralAudio", 787 "CS4232Audio", 788 }; 789 char *p, *q = NULL; 790 791 switch (id->SubType) { 792 case VideoController: 793 p = "VideoController"; 794 q = "GeneralVideo"; 795 break; 796 case AudioController: 797 p = "AudioController"; 798 q = id->Interface >= NELEMS(AudioController_table) 799 ? NULL : AudioController_table[id->Interface]; 800 break; 801 case OtherMultimediaController: 802 p = "OtherMultimediaController"; 803 break; 804 default: 805 p = "UnknownMultimediaController"; 806 break; 807 } 808 809 printf("\t\tSubType = %s (%d)\n", p, id->SubType); 810 printf("\t\tInterface = %s (%d)\n", q ? q : "None", id->Interface); 811 } 812 813 static void 814 mem_subr(DEVICE_ID *id) 815 { 816 char *p, *q = NULL; 817 818 switch (id->SubType) { 819 case RAM: 820 p = "RAM"; 821 q = "GeneralRAM"; 822 break; 823 case FLASH: 824 p = "FLASH"; 825 q = "GeneralFLASH"; 826 break; 827 case OtherMemoryDevice: 828 p = "OtherMemoryDevice"; 829 break; 830 default: 831 p = "UnknownMemoryDevice"; 832 break; 833 } 834 835 printf("\t\tSubType = %s (%d)\n", p, id->SubType); 836 printf("\t\tInterface = %s (%d)\n", q ? q : "None", id->Interface); 837 } 838 839 static void 840 bridge_subr(DEVICE_ID *id) 841 { 842 static char *PCIBridge_table[] = { 843 "GeneralPCIBridge", 844 "PCIBridgeIndirect", 845 "PCIBridgeRS6K", 846 }; 847 char *p, *q = NULL; 848 849 switch (id->SubType) { 850 case HostProcessorBridge: 851 p = "HostProcessorBridge"; 852 q = "GeneralHostBridge"; 853 break; 854 case ISABridge: 855 p = "ISABridge"; 856 q = "GeneralISABridge"; 857 break; 858 case EISABridge: 859 p = "EISABridge"; 860 q = "GeneralEISABridge"; 861 break; 862 case MicroChannelBridge: 863 p = "MicroChannelBridge"; 864 q = "GeneralMCABridge"; 865 break; 866 case PCIBridge: 867 p = "PCIBridge"; 868 q = id->Interface >= NELEMS(PCIBridge_table) 869 ? NULL : PCIBridge_table[id->Interface]; 870 break; 871 case PCMCIABridge: 872 p = "PCMCIABridge"; 873 q = "GeneralPCMCIABridge"; 874 break; 875 case VMEBridge: 876 p = "VMEBridge"; 877 q = "GeneralVMEBridge"; 878 break; 879 case OtherBridgeDevice: 880 p = "OtherBridgeDevice"; 881 break; 882 default: 883 p = "UnknownBridgeDevice"; 884 break; 885 } 886 887 printf("\t\tSubType = %s (%d)\n", p, id->SubType); 888 printf("\t\tInterface = %s (%d)\n", q ? q : "None", id->Interface); 889 } 890 891 static void 892 comm_subr(DEVICE_ID *id) 893 { 894 static char *RS232Device_table[] = { 895 "GeneralRS232", 896 "COMx", 897 "Compatible16450", 898 "Compatible16550", 899 "NS398SerPort", 900 "NS26ESerPort", 901 "NS15CSerPort", 902 "NS2ESerPort", 903 }; 904 static char *ATCompatibleParallelPort_table[] = { 905 "GeneralParPort", 906 "LPTx", 907 "NS398ParPort", 908 "NS26EParPort", 909 "NS15CParPort", 910 "NS2EParPort", 911 }; 912 char *p, *q = NULL; 913 914 switch (id->SubType) { 915 case RS232Device: 916 p = "RS232Device"; 917 q = id->Interface >= NELEMS(RS232Device_table) 918 ? NULL : RS232Device_table[id->Interface]; 919 break; 920 case ATCompatibleParallelPort: 921 p = "ATCompatibleParallelPort"; 922 q = id->Interface >= NELEMS(ATCompatibleParallelPort_table) 923 ? NULL : ATCompatibleParallelPort_table[id->Interface]; 924 break; 925 case OtherCommunicationsDevice: 926 p = "OtherCommunicationsDevice"; 927 break; 928 default: 929 p = "UnknownCommunicationsDevice"; 930 break; 931 } 932 933 printf("\t\tSubType = %s (%d)\n", p, id->SubType); 934 printf("\t\tInterface = %s (%d)\n", q ? q : "None", id->Interface); 935 } 936 937 static void 938 sys_subr(DEVICE_ID *id) 939 { 940 static char *PIC_table[] = { 941 "GeneralPIC", 942 "ISA_PIC", 943 "EISA_PIC", 944 "MPIC", 945 "RS6K_PIC", 946 }; 947 static char *DMAController_table[] = { 948 "GeneralDMA", 949 "ISA_DMA", 950 "EISA_DMA", 951 }; 952 static char *SystemTimer_table[] = { 953 "GeneralTimer", 954 "ISA_Timer", 955 "EISA_Timer", 956 }; 957 static char *RealTimeClock_table[] = { 958 "GeneralRTC", 959 "ISA_RTC", 960 }; 961 static char *L2Cache_table[] = { 962 "None", 963 "StoreThruOnly", 964 "StoreInEnabled", 965 "RS6KL2Cache", 966 }; 967 static char *NVRAM_table[] = { 968 "IndirectNVRAM", 969 "DirectNVRAM", 970 "IndirectNVRAM24", 971 }; 972 static char *PowerManagement_table[] = { 973 "GeneralPowerManagement", 974 "EPOWPowerManagement", 975 "PowerControl", 976 }; 977 static char *GraphicAssist_table[] = { 978 "Unknown", 979 "TransferData", 980 "IGMC32", 981 "IGMC64", 982 }; 983 static char *OperatorPanel_table[] = { 984 "GeneralOPPanel", 985 "HarddiskLight", 986 "CDROMLight", 987 "PowerLight", 988 "KeyLock", 989 "ANDisplay", 990 "SystemStatusLED", 991 "CHRP_SystemStatusLED", 992 }; 993 char *p, *q = NULL; 994 995 switch (id->SubType) { 996 case ProgrammableInterruptController: 997 p = "ProgrammableInterruptController"; 998 q = id->Interface >= NELEMS(PIC_table) 999 ? NULL : PIC_table[id->Interface]; 1000 break; 1001 case DMAController: 1002 p = "DMAController"; 1003 q = id->Interface >= NELEMS(DMAController_table) 1004 ? NULL : DMAController_table[id->Interface]; 1005 break; 1006 case SystemTimer: 1007 p = "SystemTimer"; 1008 q = id->Interface >= NELEMS(SystemTimer_table) 1009 ? NULL : SystemTimer_table[id->Interface]; 1010 break; 1011 case RealTimeClock: 1012 p = "RealTimeClock"; 1013 q = id->Interface >= NELEMS(RealTimeClock_table) 1014 ? NULL : RealTimeClock_table[id->Interface]; 1015 break; 1016 case L2Cache: 1017 p = "L2Cache"; 1018 q = id->Interface >= NELEMS(L2Cache_table) 1019 ? NULL : L2Cache_table[id->Interface]; 1020 break; 1021 case NVRAM: 1022 p = "NVRAM"; 1023 q = id->Interface >= NELEMS(NVRAM_table) 1024 ? NULL : NVRAM_table[id->Interface]; 1025 break; 1026 case PowerManagement: 1027 p = "PowerManagement"; 1028 q = id->Interface >= NELEMS(PowerManagement_table) 1029 ? NULL : PowerManagement_table[id->Interface]; 1030 break; 1031 case CMOS: 1032 p = "CMOS"; 1033 q = "GeneralCMOS"; 1034 break; 1035 case OperatorPanel: 1036 p = "OperatorPanel"; 1037 q = id->Interface >= NELEMS(OperatorPanel_table) 1038 ? NULL : OperatorPanel_table[id->Interface]; 1039 break; 1040 case ServiceProcessorClass1: 1041 p = "ServiceProcessorClass1"; 1042 q = "GeneralServiceProcessor"; 1043 break; 1044 case ServiceProcessorClass2: 1045 p = "ServiceProcessorClass2"; 1046 q = "GeneralServiceProcessor"; 1047 break; 1048 case ServiceProcessorClass3: 1049 p = "ServiceProcessorClass3"; 1050 q = "GeneralServiceProcessor"; 1051 break; 1052 case GraphicAssist: 1053 p = "GraphicAssist"; 1054 q = id->Interface >= NELEMS(GraphicAssist_table) 1055 ? NULL : GraphicAssist_table[id->Interface]; 1056 break; 1057 case SystemPlanar: 1058 p = "SystemPlanar"; 1059 q = "GeneralSystemPlanar"; 1060 break; 1061 case OtherSystemPeripheral: 1062 p = "OtherSystemPeripheral"; 1063 break; 1064 default: 1065 p = "UnknownSystemPeripheral"; 1066 break; 1067 } 1068 1069 printf("\t\tSubType = %s (%d)\n", p, id->SubType); 1070 printf("\t\tInterface = %s (%d)\n", q ? q : "None", id->Interface); 1071 } 1072 1073 static void 1074 input_subr(DEVICE_ID *id) 1075 { 1076 char *p, *q = NULL; 1077 1078 switch (id->SubType) { 1079 case KeyboardController: 1080 p = "KeyboardController"; 1081 break; 1082 case Digitizer: 1083 p = "Digitizer"; 1084 break; 1085 case MouseController: 1086 p = "MouseController"; 1087 break; 1088 case TabletController: 1089 p = "TabletController"; 1090 break; 1091 case OtherInputController: 1092 p = "OtherInputController"; 1093 break; 1094 default: 1095 p = "UnknownInputController"; 1096 break; 1097 } 1098 1099 printf("\t\tSubType = %s (%d)\n", p, id->SubType); 1100 printf("\t\tInterface = %s (%d)\n", q ? q : "None", id->Interface); 1101 } 1102 1103 static void 1104 service_subr(DEVICE_ID *id) 1105 { 1106 char *p, *q = NULL; 1107 1108 switch (id->SubType) { 1109 case GeneralMemoryController: 1110 p = "GeneralMemoryController"; 1111 break; 1112 default: 1113 p = "UnknownMemoryController"; 1114 break; 1115 } 1116 1117 printf("\t\tSubType = %s (%d)\n", p, id->SubType); 1118 printf("\t\tInterface = %s (%d)\n", q ? q : "None", id->Interface); 1119 } 1120