xref: /openbsd/usr.sbin/pcidump/pcidump.c (revision 4cfece93)
1 /*	$OpenBSD: pcidump.c,v 1.57 2020/06/22 05:54:26 dlg Exp $	*/
2 
3 /*
4  * Copyright (c) 2006, 2007 David Gwynne <loki@animata.net>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/types.h>
20 #include <sys/ioctl.h>
21 #include <sys/pciio.h>
22 
23 #include <stdio.h>	/* need NULL for dev/pci/ headers */
24 
25 #include <dev/pci/pcireg.h>
26 #include <dev/pci/pcidevs.h>
27 #include <dev/pci/pcidevs_data.h>
28 
29 #include <err.h>
30 #include <errno.h>
31 #include <fcntl.h>
32 #include <paths.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <unistd.h>
36 #include <limits.h>
37 #include <vis.h>
38 
39 #define PCIDEV	"/dev/pci"
40 
41 #ifndef nitems
42 #define nitems(_a)	(sizeof((_a)) / sizeof((_a)[0]))
43 #endif
44 
45 __dead void usage(void);
46 void scanpcidomain(void);
47 int probe(int, int, int);
48 void dump(int, int, int);
49 void hexdump(int, int, int, int);
50 const char *str2busdevfunc(const char *, int *, int *, int *);
51 int pci_nfuncs(int, int);
52 int pci_read(int, int, int, u_int32_t, u_int32_t *);
53 int pci_readmask(int, int, int, u_int32_t, u_int32_t *);
54 void dump_bars(int, int, int, int);
55 void dump_caplist(int, int, int, u_int8_t);
56 void dump_vpd(int, int, int);
57 void dump_pci_powerstate(int, int, int, uint8_t);
58 void dump_pcie_linkspeed(int, int, int, uint8_t);
59 void dump_pcie_devserial(int, int, int, uint16_t);
60 void dump_msi(int, int, int, uint8_t);
61 void dump_msix(int, int, int, uint8_t);
62 void print_pcie_ls(uint8_t);
63 int dump_rom(int, int, int);
64 int dump_vga_bios(void);
65 
66 static const char *
67 	pci_class_name(pci_class_t);
68 static const char *
69 	pci_subclass_name(pci_class_t, pci_subclass_t);
70 
71 void	dump_type0(int bus, int dev, int func);
72 void	dump_type1(int bus, int dev, int func);
73 void	dump_type2(int bus, int dev, int func);
74 
75 __dead void
76 usage(void)
77 {
78 	extern char *__progname;
79 
80 	fprintf(stderr,
81 	    "usage: %s [-v] [-x | -xx | -xxx] [-d pcidev] [bus:dev:func]\n"
82 	    "       %s -r file [-d pcidev] bus:dev:func\n",
83 	    __progname, __progname);
84 	exit(1);
85 }
86 
87 int pcifd;
88 int romfd;
89 int verbose = 0;
90 int hex = 0;
91 int size = 64;
92 
93 const char *pci_capnames[] = {
94 	"Reserved",
95 	"Power Management",
96 	"AGP",
97 	"Vital Product Data (VPD)",
98 	"Slot Identification",
99 	"Message Signalled Interrupts (MSI)",
100 	"CompactPCI Hot Swap",
101 	"PCI-X",
102 	"AMD LDT/HT",
103 	"Vendor Specific",
104 	"Debug Port",
105 	"CompactPCI Central Resource Control",
106 	"PCI Hot-Plug",
107 	"PCI-PCI",
108 	"AGP8",
109 	"Secure",
110 	"PCI Express",
111 	"Extended Message Signalled Interrupts (MSI-X)",
112 	"SATA",
113 	"PCI Advanced Features"
114 };
115 
116 const char *pci_enhanced_capnames[] = {
117 	"Unknown",
118 	"Advanced Error Reporting",
119 	"Virtual Channel Capability",
120 	"Device Serial Number",
121 	"Power Budgeting",
122 	"Root Complex Link Declaration",
123 	"Root Complex Internal Link Control",
124 	"Root Complex Event Collector",
125 	"Multi-Function VC Capability",
126 	"Virtual Channel Capability",
127 	"Root Complex/Root Bridge",
128 	"Vendor-Specific",
129 	"Config Access",
130 	"Access Control Services",
131 	"Alternate Routing ID",
132 	"Address Translation Services",
133 	"Single Root I/O Virtualization",
134 	"Multi Root I/O Virtualization",
135 	"Multicast",
136 	"Page Request Interface",
137 	"Reserved for AMD",
138 	"Resizable BAR",
139 	"Dynamic Power Allocation",
140 	"TPH Requester",
141 	"Latency Tolerance Reporting",
142 	"Secondary PCIe Capability",
143 	"Protocol Multiplexing",
144 	"Process Address Space ID",
145 	"LN Requester",
146 	"Downstream Port Containment",
147 	"L1 PM",
148 	"Precision Time Measurement",
149 };
150 
151 int
152 main(int argc, char *argv[])
153 {
154 	int nfuncs;
155 	int bus, dev, func;
156 	char pcidev[PATH_MAX] = PCIDEV;
157 	char *romfile = NULL;
158 	const char *errstr;
159 	int c, error = 0, dumpall = 1, domid = 0;
160 
161 	while ((c = getopt(argc, argv, "d:r:vx")) != -1) {
162 		switch (c) {
163 		case 'd':
164 			strlcpy(pcidev, optarg, sizeof(pcidev));
165 			dumpall = 0;
166 			break;
167 		case 'r':
168 			romfile = optarg;
169 			dumpall = 0;
170 			break;
171 		case 'v':
172 			verbose = 1;
173 			break;
174 		case 'x':
175 			hex++;
176 			break;
177 		default:
178 			usage();
179 		}
180 	}
181 	argc -= optind;
182 	argv += optind;
183 
184 	if (argc > 1 || (romfile && argc != 1))
185 		usage();
186 
187 	if (romfile) {
188 		romfd = open(romfile, O_WRONLY|O_CREAT|O_TRUNC, 0777);
189 		if (romfd == -1)
190 			err(1, "%s", romfile);
191 	}
192 
193 	if (unveil("/dev", "r") == -1)
194 		err(1, "unveil");
195 	if (unveil(NULL, NULL) == -1)
196 		err(1, "unveil");
197 
198 	if (hex > 1)
199 		size = 256;
200 	if (hex > 2)
201 		size = 4096;
202 
203 	if (argc == 1)
204 		dumpall = 0;
205 
206 	if (dumpall == 0) {
207 		pcifd = open(pcidev, O_RDONLY, 0777);
208 		if (pcifd == -1)
209 			err(1, "%s", pcidev);
210 	} else {
211 		for (;;) {
212 			snprintf(pcidev, 16, "/dev/pci%d", domid++);
213 			pcifd = open(pcidev, O_RDONLY, 0777);
214 			if (pcifd == -1) {
215 				if (errno == ENXIO || errno == ENOENT) {
216 					return 0;
217 				} else {
218 					err(1, "%s", pcidev);
219 				}
220 			}
221 			printf("Domain %s:\n", pcidev);
222 			scanpcidomain();
223 			close(pcifd);
224 		}
225 	}
226 
227 	if (argc == 1) {
228 		errstr = str2busdevfunc(argv[0], &bus, &dev, &func);
229 		if (errstr != NULL)
230 			errx(1, "\"%s\": %s", argv[0], errstr);
231 
232 		nfuncs = pci_nfuncs(bus, dev);
233 		if (nfuncs == -1 || func > nfuncs)
234 			error = ENXIO;
235 		else if (romfile)
236 			error = dump_rom(bus, dev, func);
237 		else
238 			error = probe(bus, dev, func);
239 
240 		if (error != 0)
241 			errc(1, error, "\"%s\"", argv[0]);
242 	} else {
243 		printf("Domain %s:\n", pcidev);
244 		scanpcidomain();
245 	}
246 
247 	return (0);
248 }
249 
250 void
251 scanpcidomain(void)
252 {
253 	int nfuncs;
254 	int bus, dev, func;
255 
256 	for (bus = 0; bus < 256; bus++) {
257 		for (dev = 0; dev < 32; dev++) {
258 			nfuncs = pci_nfuncs(bus, dev);
259 			for (func = 0; func < nfuncs; func++) {
260 				probe(bus, dev, func);
261 			}
262 		}
263 	}
264 }
265 
266 const char *
267 str2busdevfunc(const char *string, int *bus, int *dev, int *func)
268 {
269 	const char *errstr;
270 	char b[80], *d, *f;
271 
272 	strlcpy(b, string, sizeof(b));
273 
274 	d = strchr(b, ':');
275 	if (d == NULL)
276 		return("device not specified");
277 	*d++ = '\0';
278 
279 	f = strchr(d, ':');
280 	if (f == NULL)
281 		return("function not specified");
282 	*f++ = '\0';
283 
284 	*bus = strtonum(b, 0, 255, &errstr);
285 	if (errstr != NULL)
286 		return (errstr);
287 	*dev = strtonum(d, 0, 31, &errstr);
288 	if (errstr != NULL)
289 		return (errstr);
290 	*func = strtonum(f, 0, 7, &errstr);
291 	if (errstr != NULL)
292 		return (errstr);
293 
294 	return (NULL);
295 }
296 
297 int
298 probe(int bus, int dev, int func)
299 {
300 	u_int32_t id_reg;
301 	const struct pci_known_vendor *pkv;
302 	const struct pci_known_product *pkp;
303 	const char *vendor = NULL, *product = NULL;
304 
305 	if (pci_read(bus, dev, func, PCI_ID_REG, &id_reg) != 0)
306 		return (errno);
307 
308 	if (PCI_VENDOR(id_reg) == PCI_VENDOR_INVALID ||
309 	    PCI_VENDOR(id_reg) == 0)
310 		return (ENXIO);
311 
312 	for (pkv = pci_known_vendors; pkv->vendorname != NULL; pkv++) {
313 		if (pkv->vendor == PCI_VENDOR(id_reg)) {
314 			vendor = pkv->vendorname;
315 			break;
316 		}
317 	}
318 
319 	if (vendor != NULL) {
320 		for (pkp = pci_known_products; pkp->productname != NULL; pkp++)
321 		if (pkp->vendor == PCI_VENDOR(id_reg) &&
322 		    pkp->product == PCI_PRODUCT(id_reg)) {
323 			product = pkp->productname;
324 			break;
325 		}
326 	}
327 
328 	printf(" %d:%d:%d: %s %s\n", bus, dev, func,
329 	    (vendor == NULL) ? "unknown" : vendor,
330 	    (product == NULL) ? "unknown" : product);
331 
332 	if (verbose)
333 		dump(bus, dev, func);
334 	if (hex > 0)
335 		hexdump(bus, dev, func, size);
336 
337 	return (0);
338 }
339 
340 int
341 print_bytes(const uint8_t *buf, size_t len)
342 {
343 	char dst[8];
344 	size_t i;
345 
346 	for (i = 0; i < len; i++) {
347 		vis(dst, buf[i], VIS_TAB|VIS_NL, 0);
348 		printf("%s", dst);
349 	}
350 	printf("\n");
351 
352 	return (0);
353 }
354 
355 int
356 print_vpd(const uint8_t *buf, size_t len)
357 {
358 	const struct pci_vpd *vpd;
359 	char key0[8];
360 	char key1[8];
361 	size_t vlen, i;
362 
363 	while (len > 0) {
364 		if (len < sizeof(*vpd))
365 			return (1);
366 
367 		vpd = (const struct pci_vpd *)buf;
368 		vis(key0, vpd->vpd_key0, VIS_TAB|VIS_NL, 0);
369 		vis(key1, vpd->vpd_key1, VIS_TAB|VIS_NL, 0);
370 		vlen = vpd->vpd_len;
371 
372 		printf("\t\t    %s%s: ", key0, key1);
373 
374 		buf += sizeof(*vpd);
375 		len -= sizeof(*vpd);
376 
377 		if (len < vlen)
378 			return (1);
379 		print_bytes(buf, vlen);
380 
381 		buf += vlen;
382 		len -= vlen;
383 	}
384 
385 	return (0);
386 }
387 
388 void
389 dump_vpd(int bus, int dev, int func)
390 {
391 	struct pci_vpd_req io;
392 	uint32_t data[64]; /* XXX this can be up to 32k of data */
393 	uint8_t *buf = (uint8_t *)data;
394 	size_t len = sizeof(data);
395 	size_t i;
396 
397 	bzero(&io, sizeof(io));
398 	io.pv_sel.pc_bus = bus;
399 	io.pv_sel.pc_dev = dev;
400 	io.pv_sel.pc_func = func;
401 	io.pv_offset = 0;
402 	io.pv_count = nitems(data);
403 	io.pv_data = data;
404 
405 	if (ioctl(pcifd, PCIOCGETVPD, &io) == -1)
406 		warn("PCIOCGETVPD");
407 
408 	do {
409 		uint8_t vpd = *buf;
410 		uint8_t type;
411 		size_t hlen, vlen;
412 		int (*print)(const uint8_t *, size_t) = print_bytes;
413 
414 		if (PCI_VPDRES_ISLARGE(vpd)) {
415 			struct pci_vpd_largeres *res;
416 			type = PCI_VPDRES_LARGE_NAME(vpd);
417 
418 			switch (type) {
419 			case PCI_VPDRES_TYPE_IDENTIFIER_STRING:
420 				printf("\t\tProduct Name: ");
421 				break;
422 			case PCI_VPDRES_TYPE_VPD:
423 				print = print_vpd;
424 				break;
425 			default:
426 				printf("%02x: ", type);
427 				break;
428 			}
429 
430 			if (len < sizeof(*res))
431 				goto trunc;
432 			res = (struct pci_vpd_largeres *)buf;
433 
434 			hlen = sizeof(*res);
435 			vlen = ((size_t)res->vpdres_len_msb << 8) |
436 			    (size_t)res->vpdres_len_lsb;
437 		} else { /* small */
438 			type = PCI_VPDRES_SMALL_NAME(vpd);
439 			if (type == PCI_VPDRES_TYPE_END_TAG)
440 				break;
441 
442 			printf("\t\t");
443 			switch (type) {
444 			case PCI_VPDRES_TYPE_COMPATIBLE_DEVICE_ID:
445 			case PCI_VPDRES_TYPE_VENDOR_DEFINED:
446 			default:
447 				printf("%02x", type);
448 				break;
449 			}
450 
451 			hlen = sizeof(vpd);
452 			vlen = PCI_VPDRES_SMALL_LENGTH(vpd);
453 		}
454 		buf += hlen;
455 		len -= hlen;
456 
457 		if (len < vlen)
458 			goto trunc;
459 		(*print)(buf, vlen);
460 
461 		buf += vlen;
462 		len -= vlen;
463 	} while (len > 0);
464 
465 	return;
466 trunc:
467 	/* i have spent too much time in tcpdump - dlg */
468 	printf("[|vpd]\n");
469 }
470 
471 void
472 dump_pci_powerstate(int bus, int dev, int func, uint8_t ptr)
473 {
474 	u_int32_t pmcsr;
475 
476 	if (pci_read(bus, dev, func, ptr + PCI_PMCSR, &pmcsr) != 0)
477 		return;
478 
479 	printf("\t\tState: D%d", pmcsr & PCI_PMCSR_STATE_MASK);
480 	if (pmcsr & PCI_PMCSR_PME_EN)
481 		printf(" PME# enabled");
482 	if (pmcsr & PCI_PMCSR_PME_STATUS)
483 		printf(" PME# asserted");
484 	printf("\n");
485 }
486 
487 void
488 print_pcie_ls(uint8_t speed)
489 {
490 	if (speed & 4)
491 		printf("8.0");
492 	else if (speed & 2)
493 		printf("5.0");
494 	else if (speed & 1)
495 		printf("2.5");
496 	else
497 		printf("unknown (%d)", speed);
498 }
499 
500 void
501 dump_pcie_linkspeed(int bus, int dev, int func, uint8_t ptr)
502 {
503 	u_int32_t lcap, sreg, lcap2 = 0, xcap;
504 	u_int8_t cwidth, cspeed, swidth, sspeed;
505 
506 	if (pci_read(bus, dev, func, ptr + PCI_PCIE_XCAP, &xcap) != 0)
507 		return;
508 
509 	if (PCI_PCIE_XCAP_VER(xcap) >= 2) {
510 		if (pci_read(bus, dev, func, ptr + PCI_PCIE_LCAP2, &lcap2) != 0)
511 			lcap2 = 0;
512 		else
513 			cspeed = (lcap2 & 0x0e) >> 1;
514 	}
515 
516 	if (pci_read(bus, dev, func, ptr + PCI_PCIE_LCAP, &lcap) != 0)
517 		return;
518 	if (lcap2 == 0)
519 		cspeed = lcap & 0x0f;
520 
521 	if (pci_read(bus, dev, func, ptr + PCI_PCIE_LCSR, &sreg) != 0)
522 		return;
523 	sreg = sreg >> 16;
524 
525 	cwidth = (lcap >> 4) & 0x3f;
526 	if (cwidth == 0)
527 		return;
528 
529 	swidth = (sreg >> 4) & 0x3f;
530 	sspeed = sreg & 0x0f;
531 
532 	printf("\t\tLink Speed: ");
533 	print_pcie_ls(sspeed);
534 	printf(" / ");
535 	print_pcie_ls(cspeed);
536 	printf(" GT/s, ");
537 
538 	printf("Link Width: x%d / x%d\n", swidth, cwidth);
539 }
540 
541 void
542 dump_pcie_devserial(int bus, int dev, int func, u_int16_t ptr)
543 {
544 	uint32_t lower, upper;
545 	uint64_t serial;
546 
547 	if ((pci_read(bus, dev, func, ptr + 8, &upper) != 0) ||
548 	    (pci_read(bus, dev, func, ptr + 4, &lower) != 0))
549 		return;
550 
551 	serial = ((uint64_t)upper << 32) | (uint64_t)lower;
552 
553 	printf("\t\tSerial Number: %016llx\n", serial);
554 }
555 
556 void
557 dump_msi(int bus, int dev, int func, u_int8_t ptr)
558 {
559 	u_int32_t reg;
560 
561 	if (pci_read(bus, dev, func, ptr, &reg) != 0)
562 		return;
563 
564 	printf("\t\tEnabled: %s\n", reg & PCI_MSI_MC_MSIE ? "yes" : "no");
565 }
566 
567 void
568 dump_msix(int bus, int dev, int func, u_int8_t ptr)
569 {
570 	u_int32_t reg;
571 	u_int32_t table;
572 
573 	if ((pci_read(bus, dev, func, ptr, &reg) != 0) ||
574 	    (pci_read(bus, dev, func, ptr + PCI_MSIX_TABLE, &table) != 0))
575 		return;
576 
577 	printf("\t\tEnabled: %s; table size %d (BAR %d:%d)\n",
578 	    reg & PCI_MSIX_MC_MSIXE ? "yes" : "no",
579 	    PCI_MSIX_MC_TBLSZ(reg) + 1,
580 	    (table & PCI_MSIX_TABLE_BIR),
581 	    (table & PCI_MSIX_TABLE_OFF));
582 }
583 
584 void
585 dump_pcie_enhanced_caplist(int bus, int dev, int func)
586 {
587 	u_int32_t reg;
588 	u_int32_t capidx;
589 	u_int16_t ptr;
590 	u_int16_t ecap;
591 
592 	ptr = PCI_PCIE_ECAP;
593 
594 	do {
595 		if (pci_read(bus, dev, func, ptr, &reg) != 0)
596 			return;
597 
598 		if (PCI_PCIE_ECAP_ID(reg) == 0xffff &&
599 		    PCI_PCIE_ECAP_NEXT(reg) == PCI_PCIE_ECAP_LAST)
600 			return;
601 
602 		ecap = PCI_PCIE_ECAP_ID(reg);
603 		if (ecap >= nitems(pci_enhanced_capnames))
604 			capidx = 0;
605 		else
606 			capidx = ecap;
607 
608 		printf("\t0x%04x: Enhanced Capability 0x%02x: ", ptr, ecap);
609 		printf("%s\n", pci_enhanced_capnames[capidx]);
610 
611 		switch (ecap) {
612 		case 0x03:
613 			dump_pcie_devserial(bus, dev, func, ptr);
614 			break;
615 		}
616 
617 		ptr = PCI_PCIE_ECAP_NEXT(reg);
618 
619 	} while (ptr != PCI_PCIE_ECAP_LAST);
620 }
621 
622 void
623 dump_caplist(int bus, int dev, int func, u_int8_t ptr)
624 {
625 	u_int32_t reg;
626 	u_int8_t cap;
627 
628 	if (pci_read(bus, dev, func, PCI_COMMAND_STATUS_REG, &reg) != 0)
629 		return;
630 	if (!(reg & PCI_STATUS_CAPLIST_SUPPORT))
631 		return;
632 
633 	if (pci_read(bus, dev, func, ptr, &reg) != 0)
634 		return;
635 	ptr = PCI_CAPLIST_PTR(reg);
636 	while (ptr != 0) {
637 		if (pci_read(bus, dev, func, ptr, &reg) != 0)
638 			return;
639 		cap = PCI_CAPLIST_CAP(reg);
640 		printf("\t0x%04x: Capability 0x%02x: ", ptr, cap);
641 		if (cap >= nitems(pci_capnames))
642 			cap = 0;
643 		printf("%s\n", pci_capnames[cap]);
644 		switch (cap) {
645 		case PCI_CAP_PWRMGMT:
646 			dump_pci_powerstate(bus, dev, func, ptr);
647 			break;
648 		case PCI_CAP_VPD:
649 			dump_vpd(bus, dev, func);
650 			break;
651 		case PCI_CAP_PCIEXPRESS:
652 			dump_pcie_linkspeed(bus, dev, func, ptr);
653 			dump_pcie_enhanced_caplist(bus, dev, func);
654 			break;
655 		case PCI_CAP_MSI:
656 			dump_msi(bus, dev,func, ptr);
657 			break;
658 		case PCI_CAP_MSIX:
659 			dump_msix(bus, dev, func, ptr);
660 			break;
661 		}
662 		ptr = PCI_CAPLIST_NEXT(reg);
663 	}
664 }
665 
666 void
667 dump_bars(int bus, int dev, int func, int end)
668 {
669 	const char *memtype;
670 	u_int64_t mem;
671 	u_int64_t mask;
672 	u_int32_t reg, reg1;
673 	int bar;
674 
675 	for (bar = PCI_MAPREG_START; bar < end; bar += 0x4) {
676 		if (pci_read(bus, dev, func, bar, &reg) != 0 ||
677 		    pci_readmask(bus, dev, func, bar, &reg1) != 0)
678 			warn("unable to read PCI_MAPREG 0x%02x", bar);
679 
680 		printf("\t0x%04x: BAR ", bar);
681 
682 		if (reg == 0 && reg1 == 0) {
683 			printf("empty (%08x)\n", reg);
684 			continue;
685 		}
686 
687 		switch (PCI_MAPREG_TYPE(reg)) {
688 		case PCI_MAPREG_TYPE_MEM:
689 			printf("mem ");
690 			if (PCI_MAPREG_MEM_PREFETCHABLE(reg))
691 				printf("prefetchable ");
692 
693 			memtype = "32bit 1m";
694 			switch (PCI_MAPREG_MEM_TYPE(reg)) {
695 			case PCI_MAPREG_MEM_TYPE_32BIT:
696 				memtype = "32bit";
697 			case PCI_MAPREG_MEM_TYPE_32BIT_1M:
698 				printf("%s ", memtype);
699 
700 				printf("addr: 0x%08x/0x%08x\n",
701 				    PCI_MAPREG_MEM_ADDR(reg),
702 				    PCI_MAPREG_MEM_SIZE(reg1));
703 
704 				break;
705 			case PCI_MAPREG_MEM_TYPE_64BIT:
706 				mem = reg;
707 				mask = reg1;
708 				bar += 0x04;
709 				if (pci_read(bus, dev, func, bar, &reg) != 0 ||
710 				    pci_readmask(bus, dev, func, bar, &reg1) != 0)
711 					warn("unable to read 0x%02x", bar);
712 
713 				mem |= (u_int64_t)reg << 32;
714 				mask |= (u_int64_t)reg1 << 32;
715 
716 				printf("64bit addr: 0x%016llx/0x%08llx\n",
717 				    PCI_MAPREG_MEM64_ADDR(mem),
718 				    PCI_MAPREG_MEM64_SIZE(mask));
719 
720 				break;
721 			}
722 			break;
723 
724 		case PCI_MAPREG_TYPE_IO:
725 			printf("io addr: 0x%08x/0x%04x\n",
726 			    PCI_MAPREG_IO_ADDR(reg),
727 			    PCI_MAPREG_IO_SIZE(reg1));
728 			break;
729 		}
730 	}
731 }
732 
733 void
734 dump_type0(int bus, int dev, int func)
735 {
736 	u_int32_t reg;
737 
738 	dump_bars(bus, dev, func, PCI_MAPREG_END);
739 
740 	if (pci_read(bus, dev, func, PCI_CARDBUS_CIS_REG, &reg) != 0)
741 		warn("unable to read PCI_CARDBUS_CIS_REG");
742 	printf("\t0x%04x: Cardbus CIS: %08x\n", PCI_CARDBUS_CIS_REG, reg);
743 
744 	if (pci_read(bus, dev, func, PCI_SUBSYS_ID_REG, &reg) != 0)
745 		warn("unable to read PCI_SUBSYS_ID_REG");
746 	printf("\t0x%04x: Subsystem Vendor ID: %04x Product ID: %04x\n",
747 	    PCI_SUBSYS_ID_REG, PCI_VENDOR(reg), PCI_PRODUCT(reg));
748 
749 	if (pci_read(bus, dev, func, PCI_ROM_REG, &reg) != 0)
750 		warn("unable to read PCI_ROM_REG");
751 	printf("\t0x%04x: Expansion ROM Base Address: %08x\n",
752 	    PCI_ROM_REG, reg);
753 
754 	if (pci_read(bus, dev, func, 0x38, &reg) != 0)
755 		warn("unable to read 0x38 (reserved)");
756 	printf("\t0x%04x: %08x\n", 0x38, reg);
757 
758 	if (pci_read(bus, dev, func, PCI_INTERRUPT_REG, &reg) != 0)
759 		warn("unable to read PCI_INTERRUPT_REG");
760 	printf("\t0x%04x: Interrupt Pin: %02x Line: %02x Min Gnt: %02x"
761 	    " Max Lat: %02x\n", PCI_INTERRUPT_REG, PCI_INTERRUPT_PIN(reg),
762 	    PCI_INTERRUPT_LINE(reg), PCI_MIN_GNT(reg), PCI_MAX_LAT(reg));
763 }
764 
765 void
766 dump_type1(int bus, int dev, int func)
767 {
768 	u_int32_t reg;
769 
770 	dump_bars(bus, dev, func, PCI_MAPREG_PPB_END);
771 
772 	if (pci_read(bus, dev, func, PCI_PRIBUS_1, &reg) != 0)
773 		warn("unable to read PCI_PRIBUS_1");
774 	printf("\t0x%04x: Primary Bus: %d, Secondary Bus: %d, "
775 	    "Subordinate Bus: %d,\n\t\tSecondary Latency Timer: %02x\n",
776 	    PCI_PRIBUS_1, (reg >> 0) & 0xff, (reg >> 8) & 0xff,
777 	    (reg >> 16) & 0xff, (reg >> 24) & 0xff);
778 
779 	if (pci_read(bus, dev, func, PCI_IOBASEL_1, &reg) != 0)
780 		warn("unable to read PCI_IOBASEL_1");
781 	printf("\t0x%04x: I/O Base: %02x, I/O Limit: %02x, "
782 	    "Secondary Status: %04x\n", PCI_IOBASEL_1, (reg >> 0 ) & 0xff,
783 	    (reg >> 8) & 0xff, (reg >> 16) & 0xffff);
784 
785 	if (pci_read(bus, dev, func, PCI_MEMBASE_1, &reg) != 0)
786 		warn("unable to read PCI_MEMBASE_1");
787 	printf("\t0x%04x: Memory Base: %04x, Memory Limit: %04x\n",
788 	    PCI_MEMBASE_1, (reg >> 0) & 0xffff, (reg >> 16) & 0xffff);
789 
790 	if (pci_read(bus, dev, func, PCI_PMBASEL_1, &reg) != 0)
791 		warn("unable to read PCI_PMBASEL_1");
792 	printf("\t0x%04x: Prefetch Memory Base: %04x, "
793 	    "Prefetch Memory Limit: %04x\n", PCI_PMBASEL_1,
794 	    (reg >> 0) & 0xffff, (reg >> 16) & 0xffff);
795 
796 #undef PCI_PMBASEH_1
797 #define PCI_PMBASEH_1	0x28
798 	if (pci_read(bus, dev, func, PCI_PMBASEH_1, &reg) != 0)
799 		warn("unable to read PCI_PMBASEH_1");
800 	printf("\t0x%04x: Prefetch Memory Base Upper 32 Bits: %08x\n",
801 	    PCI_PMBASEH_1, reg);
802 
803 #undef PCI_PMLIMITH_1
804 #define PCI_PMLIMITH_1	0x2c
805 	if (pci_read(bus, dev, func, PCI_PMLIMITH_1, &reg) != 0)
806 		warn("unable to read PCI_PMLIMITH_1");
807 	printf("\t0x%04x: Prefetch Memory Limit Upper 32 Bits: %08x\n",
808 	    PCI_PMLIMITH_1, reg);
809 
810 #undef PCI_IOBASEH_1
811 #define PCI_IOBASEH_1	0x30
812 	if (pci_read(bus, dev, func, PCI_IOBASEH_1, &reg) != 0)
813 		warn("unable to read PCI_IOBASEH_1");
814 	printf("\t0x%04x: I/O Base Upper 16 Bits: %04x, "
815 	    "I/O Limit Upper 16 Bits: %04x\n", PCI_IOBASEH_1,
816 	    (reg >> 0) & 0xffff, (reg >> 16) & 0xffff);
817 
818 #define PCI_PPB_ROM_REG		0x38
819 	if (pci_read(bus, dev, func, PCI_PPB_ROM_REG, &reg) != 0)
820 		warn("unable to read PCI_PPB_ROM_REG");
821 	printf("\t0x%04x: Expansion ROM Base Address: %08x\n",
822 	    PCI_PPB_ROM_REG, reg);
823 
824 	if (pci_read(bus, dev, func, PCI_INTERRUPT_REG, &reg) != 0)
825 		warn("unable to read PCI_INTERRUPT_REG");
826 	printf("\t0x%04x: Interrupt Pin: %02x, Line: %02x, "
827 	    "Bridge Control: %04x\n",
828 	    PCI_INTERRUPT_REG, PCI_INTERRUPT_PIN(reg),
829 	    PCI_INTERRUPT_LINE(reg), reg >> 16);
830 }
831 
832 void
833 dump_type2(int bus, int dev, int func)
834 {
835 	u_int32_t reg;
836 
837 	if (pci_read(bus, dev, func, PCI_MAPREG_START, &reg) != 0)
838 		warn("unable to read PCI_MAPREG\n");
839 	printf("\t0x%04x: Cardbus Control Registers Base Address: %08x\n",
840 	    PCI_MAPREG_START, reg);
841 
842 	if (pci_read(bus, dev, func, PCI_PRIBUS_2, &reg) != 0)
843 		warn("unable to read PCI_PRIBUS_2");
844 	printf("\t0x%04x: Primary Bus: %d Cardbus Bus: %d "
845 	    "Subordinate Bus: %d \n\t        Cardbus Latency Timer: %02x\n",
846 	    PCI_PRIBUS_2, (reg >> 0) & 0xff, (reg >> 8) & 0xff,
847 	    (reg >> 16) & 0xff, (reg >> 24) & 0xff);
848 
849 	if (pci_read(bus, dev, func, PCI_MEMBASE0_2, &reg) != 0)
850 		warn("unable to read PCI_MEMBASE0_2\n");
851 	printf("\t0x%04x: Memory Base 0: %08x\n", PCI_MEMBASE0_2, reg);
852 
853 	if (pci_read(bus, dev, func, PCI_MEMLIMIT0_2, &reg) != 0)
854 		warn("unable to read PCI_MEMLIMIT0_2\n");
855 	printf("\t0x%04x: Memory Limit 0: %08x\n", PCI_MEMLIMIT0_2, reg);
856 
857 	if (pci_read(bus, dev, func, PCI_MEMBASE1_2, &reg) != 0)
858 		warn("unable to read PCI_MEMBASE1_2\n");
859 	printf("\t0x%04x: Memory Base 1: %08x\n", PCI_MEMBASE1_2, reg);
860 
861 	if (pci_read(bus, dev, func, PCI_MEMLIMIT1_2, &reg) != 0)
862 		warn("unable to read PCI_MEMLIMIT1_2\n");
863 	printf("\t0x%04x: Memory Limit 1: %08x\n", PCI_MEMLIMIT1_2, reg);
864 
865 	if (pci_read(bus, dev, func, PCI_IOBASE0_2, &reg) != 0)
866 		warn("unable to read PCI_IOBASE0_2\n");
867 	printf("\t0x%04x: I/O Base 0: %08x\n", PCI_IOBASE0_2, reg);
868 
869 	if (pci_read(bus, dev, func, PCI_IOLIMIT0_2, &reg) != 0)
870 		warn("unable to read PCI_IOLIMIT0_2\n");
871 	printf("\t0x%04x: I/O Limit 0: %08x\n", PCI_IOLIMIT0_2, reg);
872 
873 	if (pci_read(bus, dev, func, PCI_IOBASE1_2, &reg) != 0)
874 		warn("unable to read PCI_IOBASE1_2\n");
875 	printf("\t0x%04x: I/O Base 1: %08x\n", PCI_IOBASE1_2, reg);
876 
877 	if (pci_read(bus, dev, func, PCI_IOLIMIT1_2, &reg) != 0)
878 		warn("unable to read PCI_IOLIMIT1_2\n");
879 	printf("\t0x%04x: I/O Limit 1: %08x\n", PCI_IOLIMIT1_2, reg);
880 
881 	if (pci_read(bus, dev, func, PCI_INTERRUPT_REG, &reg) != 0)
882 		warn("unable to read PCI_INTERRUPT_REG");
883 	printf("\t0x%04x: Interrupt Pin: %02x Line: %02x "
884 	    "Bridge Control: %04x\n",
885 	    PCI_INTERRUPT_REG, PCI_INTERRUPT_PIN(reg),
886 	    PCI_INTERRUPT_LINE(reg), reg >> 16);
887 
888 	if (pci_read(bus, dev, func, PCI_SUBVEND_2, &reg) != 0)
889 		warn("unable to read PCI_SUBVEND_2");
890 	printf("\t0x%04x: Subsystem Vendor ID: %04x Product ID: %04x\n",
891 	    PCI_SUBVEND_2, PCI_VENDOR(reg), PCI_PRODUCT(reg));
892 
893 	if (pci_read(bus, dev, func, PCI_PCCARDIF_2, &reg) != 0)
894 		warn("unable to read PCI_PCCARDIF_2\n");
895 	printf("\t0x%04x: 16-bit Legacy Mode Base Address: %08x\n",
896 	    PCI_PCCARDIF_2, reg);
897 }
898 
899 void
900 dump(int bus, int dev, int func)
901 {
902 	u_int32_t reg;
903 	u_int8_t capptr = PCI_CAPLISTPTR_REG;
904 	pci_class_t class;
905 	pci_subclass_t subclass;
906 
907 	if (pci_read(bus, dev, func, PCI_ID_REG, &reg) != 0)
908 		warn("unable to read PCI_ID_REG");
909 	printf("\t0x%04x: Vendor ID: %04x, Product ID: %04x\n", PCI_ID_REG,
910 	    PCI_VENDOR(reg), PCI_PRODUCT(reg));
911 
912 	if (pci_read(bus, dev, func, PCI_COMMAND_STATUS_REG, &reg) != 0)
913 		warn("unable to read PCI_COMMAND_STATUS_REG");
914 	printf("\t0x%04x: Command: %04x, Status: %04x\n",
915 	    PCI_COMMAND_STATUS_REG, reg & 0xffff, (reg  >> 16) & 0xffff);
916 
917 	if (pci_read(bus, dev, func, PCI_CLASS_REG, &reg) != 0)
918 		warn("unable to read PCI_CLASS_REG");
919 	class = PCI_CLASS(reg);
920 	subclass = PCI_SUBCLASS(reg);
921 	printf("\t0x%04x:\tClass: %02x %s,", PCI_CLASS_REG, class,
922 	    pci_class_name(class));
923 	printf(" Subclass: %02x %s,", subclass,
924 	    pci_subclass_name(class, subclass));
925 	printf("\n\t\tInterface: %02x, Revision: %02x\n",
926 	    PCI_INTERFACE(reg), PCI_REVISION(reg));
927 
928 	if (pci_read(bus, dev, func, PCI_BHLC_REG, &reg) != 0)
929 		warn("unable to read PCI_BHLC_REG");
930 	printf("\t0x%04x: BIST: %02x, Header Type: %02x, "
931 	    "Latency Timer: %02x,\n\t\tCache Line Size: %02x\n", PCI_BHLC_REG,
932 	    PCI_BIST(reg), PCI_HDRTYPE(reg),
933 	    PCI_LATTIMER(reg), PCI_CACHELINE(reg));
934 
935 	switch (PCI_HDRTYPE_TYPE(reg)) {
936 	case 2:
937 		dump_type2(bus, dev, func);
938 		capptr = PCI_CARDBUS_CAPLISTPTR_REG;
939 		break;
940 	case 1:
941 		dump_type1(bus, dev, func);
942 		break;
943 	case 0:
944 		dump_type0(bus, dev, func);
945 		break;
946 	default:
947 		break;
948 	}
949 	dump_caplist(bus, dev, func, capptr);
950 }
951 
952 void
953 hexdump(int bus, int dev, int func, int size)
954 {
955 	u_int32_t reg;
956 	int i;
957 
958 	for (i = 0; i < size; i += 4) {
959 		if (pci_read(bus, dev, func, i, &reg) != 0) {
960 			if (errno == EINVAL)
961 				return;
962 			warn("unable to read 0x%02x", i);
963 		}
964 
965 		if ((i % 16) == 0)
966 			printf("\t0x%04x:", i);
967 		printf(" %08x", reg);
968 
969 		if ((i % 16) == 12)
970 			printf("\n");
971 	}
972 }
973 
974 int
975 pci_nfuncs(int bus, int dev)
976 {
977 	u_int32_t hdr;
978 
979 	if (pci_read(bus, dev, 0, PCI_BHLC_REG, &hdr) != 0)
980 		return (-1);
981 
982 	return (PCI_HDRTYPE_MULTIFN(hdr) ? 8 : 1);
983 }
984 
985 int
986 pci_read(int bus, int dev, int func, u_int32_t reg, u_int32_t *val)
987 {
988 	struct pci_io io;
989 	int rv;
990 
991 	bzero(&io, sizeof(io));
992 	io.pi_sel.pc_bus = bus;
993 	io.pi_sel.pc_dev = dev;
994 	io.pi_sel.pc_func = func;
995 	io.pi_reg = reg;
996 	io.pi_width = 4;
997 
998 	rv = ioctl(pcifd, PCIOCREAD, &io);
999 	if (rv != 0)
1000 		return (rv);
1001 
1002 	*val = io.pi_data;
1003 
1004 	return (0);
1005 }
1006 
1007 int
1008 pci_readmask(int bus, int dev, int func, u_int32_t reg, u_int32_t *val)
1009 {
1010 	struct pci_io io;
1011 	int rv;
1012 
1013 	bzero(&io, sizeof(io));
1014 	io.pi_sel.pc_bus = bus;
1015 	io.pi_sel.pc_dev = dev;
1016 	io.pi_sel.pc_func = func;
1017 	io.pi_reg = reg;
1018 	io.pi_width = 4;
1019 
1020 	rv = ioctl(pcifd, PCIOCREADMASK, &io);
1021 	if (rv != 0)
1022 		return (rv);
1023 
1024 	*val = io.pi_data;
1025 
1026 	return (0);
1027 }
1028 
1029 int
1030 dump_rom(int bus, int dev, int func)
1031 {
1032 	struct pci_rom rom;
1033 	u_int32_t cr, addr;
1034 
1035 	if (pci_read(bus, dev, func, PCI_ROM_REG, &addr) != 0 ||
1036 	    pci_read(bus, dev, func, PCI_CLASS_REG, &cr) != 0)
1037 		return (errno);
1038 
1039 	if (addr == 0 && PCI_CLASS(cr) == PCI_CLASS_DISPLAY &&
1040 	    PCI_SUBCLASS(cr) == PCI_SUBCLASS_DISPLAY_VGA)
1041 		return dump_vga_bios();
1042 
1043 	bzero(&rom, sizeof(rom));
1044 	rom.pr_sel.pc_bus = bus;
1045 	rom.pr_sel.pc_dev = dev;
1046 	rom.pr_sel.pc_func = func;
1047 	if (ioctl(pcifd, PCIOCGETROMLEN, &rom) == -1)
1048 		return (errno);
1049 
1050 	rom.pr_rom = malloc(rom.pr_romlen);
1051 	if (rom.pr_rom == NULL)
1052 		return (ENOMEM);
1053 
1054 	if (ioctl(pcifd, PCIOCGETROM, &rom) == -1)
1055 		return (errno);
1056 
1057 	if (write(romfd, rom.pr_rom, rom.pr_romlen) == -1)
1058 		return (errno);
1059 
1060 	return (0);
1061 }
1062 
1063 #define VGA_BIOS_ADDR	0xc0000
1064 #define VGA_BIOS_LEN	0x10000
1065 
1066 int
1067 dump_vga_bios(void)
1068 {
1069 #if defined(__amd64__) || defined(__i386__)
1070 	void *bios;
1071 	int fd;
1072 
1073 	fd = open(_PATH_MEM, O_RDONLY, 0777);
1074 	if (fd == -1)
1075 		err(1, "%s", _PATH_MEM);
1076 
1077 	bios = malloc(VGA_BIOS_LEN);
1078 	if (bios == NULL)
1079 		return (ENOMEM);
1080 
1081 	if (pread(fd, bios, VGA_BIOS_LEN, VGA_BIOS_ADDR) == -1)
1082 		err(1, "%s", _PATH_MEM);
1083 
1084 	if (write(romfd, bios, VGA_BIOS_LEN) == -1) {
1085 		free(bios);
1086 		return (errno);
1087 	}
1088 
1089 	free(bios);
1090 
1091 	return (0);
1092 #else
1093 	return (ENODEV);
1094 #endif
1095 }
1096 
1097 struct pci_subclass {
1098 	pci_subclass_t	 subclass;
1099 	const char	*name;
1100 };
1101 
1102 struct pci_class {
1103 	pci_class_t	 class;
1104 	const char	*name;
1105 	const struct pci_subclass
1106 			*subclass;
1107 	size_t		 nsubclass;
1108 };
1109 
1110 static const struct pci_subclass pci_subclass_prehistoric[] = {
1111 	{ PCI_SUBCLASS_PREHISTORIC_MISC,	"Miscellaneous"	},
1112 	{ PCI_SUBCLASS_PREHISTORIC_VGA,		"VGA"		},
1113 };
1114 
1115 static const struct pci_subclass pci_subclass_mass_storage[] = {
1116 	{ PCI_SUBCLASS_MASS_STORAGE_SCSI,	"SCSI"		},
1117 	{ PCI_SUBCLASS_MASS_STORAGE_IDE,	"IDE"		},
1118 	{ PCI_SUBCLASS_MASS_STORAGE_FLOPPY,	"Floppy"	},
1119 	{ PCI_SUBCLASS_MASS_STORAGE_IPI,	"IPI"		},
1120 	{ PCI_SUBCLASS_MASS_STORAGE_RAID,	"RAID"		},
1121 	{ PCI_SUBCLASS_MASS_STORAGE_ATA,	"ATA"		},
1122 	{ PCI_SUBCLASS_MASS_STORAGE_SATA,	"SATA"		},
1123 	{ PCI_SUBCLASS_MASS_STORAGE_SAS,	"SAS"		},
1124 	{ PCI_SUBCLASS_MASS_STORAGE_UFS,	"UFS"		},
1125 	{ PCI_SUBCLASS_MASS_STORAGE_NVM,	"NVM"		},
1126 	{ PCI_SUBCLASS_MASS_STORAGE_MISC,	"Miscellaneous"	},
1127 };
1128 
1129 static const struct pci_subclass pci_subclass_network[] = {
1130 	{ PCI_SUBCLASS_NETWORK_ETHERNET,	"Ethernet"	},
1131 	{ PCI_SUBCLASS_NETWORK_TOKENRING,	"Token Ring"	},
1132 	{ PCI_SUBCLASS_NETWORK_FDDI,		"FDDI"		},
1133 	{ PCI_SUBCLASS_NETWORK_ATM,		"ATM"		},
1134 	{ PCI_SUBCLASS_NETWORK_ISDN,		"ISDN"		},
1135 	{ PCI_SUBCLASS_NETWORK_WORLDFIP,	"WorldFip"	},
1136 	{ PCI_SUBCLASS_NETWORK_PCIMGMULTICOMP,	"PCMIG Multi Computing"	},
1137 	{ PCI_SUBCLASS_NETWORK_INFINIBAND,	"InfiniBand"	},
1138 	{ PCI_SUBCLASS_NETWORK_MISC,		"Miscellaneous"	},
1139 };
1140 
1141 static const struct pci_subclass pci_subclass_display[] = {
1142 	{ PCI_SUBCLASS_DISPLAY_VGA,		"VGA"		},
1143 	{ PCI_SUBCLASS_DISPLAY_XGA,		"XGA"		},
1144 	{ PCI_SUBCLASS_DISPLAY_3D,		"3D"		},
1145 	{ PCI_SUBCLASS_DISPLAY_MISC,		"Miscellaneous"	},
1146 };
1147 
1148 static const struct pci_subclass pci_subclass_memory[] = {
1149 	{ PCI_SUBCLASS_MEMORY_RAM,		"RAM"		},
1150 	{ PCI_SUBCLASS_MEMORY_FLASH,		"Flash"		},
1151 	{ PCI_SUBCLASS_MEMORY_MISC,		"Miscellaneous" },
1152 };
1153 
1154 static const struct pci_subclass pci_subclass_bridge[] = {
1155 	{ PCI_SUBCLASS_BRIDGE_HOST,		"Host"		},
1156 	{ PCI_SUBCLASS_BRIDGE_ISA,		"ISA"		},
1157 	{ PCI_SUBCLASS_BRIDGE_EISA,		"EISA"		},
1158 	{ PCI_SUBCLASS_BRIDGE_MC,		"MicroChannel"	},
1159 	{ PCI_SUBCLASS_BRIDGE_PCI,		"PCI"		},
1160 	{ PCI_SUBCLASS_BRIDGE_PCMCIA,		"PCMCIA"	},
1161 	{ PCI_SUBCLASS_BRIDGE_NUBUS,		"NuBus"		},
1162 	{ PCI_SUBCLASS_BRIDGE_RACEWAY,		"RACEway"	},
1163 	{ PCI_SUBCLASS_BRIDGE_STPCI,		"Semi-transparent PCI" },
1164 	{ PCI_SUBCLASS_BRIDGE_INFINIBAND,	"InfiniBand"	},
1165 	{ PCI_SUBCLASS_BRIDGE_MISC,		"Miscellaneous"	},
1166 	{ PCI_SUBCLASS_BRIDGE_AS,		"advanced switching" },
1167 };
1168 
1169 static const struct pci_subclass pci_subclass_communications[] = {
1170 	{ PCI_SUBCLASS_COMMUNICATIONS_SERIAL,	"Serial"	},
1171 	{ PCI_SUBCLASS_COMMUNICATIONS_PARALLEL,	"Parallel"	},
1172 	{ PCI_SUBCLASS_COMMUNICATIONS_MPSERIAL,	"Multi-port Serial" },
1173 	{ PCI_SUBCLASS_COMMUNICATIONS_MODEM,	"Modem"		},
1174 	{ PCI_SUBCLASS_COMMUNICATIONS_GPIB,	"GPIB"		},
1175 	{ PCI_SUBCLASS_COMMUNICATIONS_SMARTCARD,
1176 						"Smartcard"	},
1177 	{ PCI_SUBCLASS_COMMUNICATIONS_MISC,	"Miscellaneous" },
1178 };
1179 
1180 static const struct pci_subclass pci_subclass_system[] = {
1181 	{ PCI_SUBCLASS_SYSTEM_PIC,		"Interrupt"	},
1182 	{ PCI_SUBCLASS_SYSTEM_DMA,		"8237 DMA"	},
1183 	{ PCI_SUBCLASS_SYSTEM_TIMER,		"8254 Timer"	},
1184 	{ PCI_SUBCLASS_SYSTEM_RTC,		"RTC"		},
1185 	{ PCI_SUBCLASS_SYSTEM_SDHC,		"SDHC"		},
1186 	{ PCI_SUBCLASS_SYSTEM_IOMMU,		"IOMMU"		},
1187 	{ PCI_SUBCLASS_SYSTEM_ROOTCOMPEVENT,	"Root Complex Event" },
1188 	{ PCI_SUBCLASS_SYSTEM_MISC,		"Miscellaneous" },
1189 };
1190 
1191 static const struct pci_subclass pci_subclass_input[] = {
1192 	{ PCI_SUBCLASS_INPUT_KEYBOARD,		"Keyboard"	},
1193 	{ PCI_SUBCLASS_INPUT_DIGITIZER,		"Digitizer"	},
1194 	{ PCI_SUBCLASS_INPUT_MOUSE,		"Mouse"		},
1195 	{ PCI_SUBCLASS_INPUT_SCANNER,		"Scanner"	},
1196 	{ PCI_SUBCLASS_INPUT_GAMEPORT,		"Game Port"	},
1197 	{ PCI_SUBCLASS_INPUT_MISC,		"Miscellaneous"	},
1198 };
1199 
1200 static const struct pci_subclass pci_subclass_dock[] = {
1201 	{ PCI_SUBCLASS_DOCK_GENERIC,		"Generic"	},
1202 	{ PCI_SUBCLASS_DOCK_MISC,		"Miscellaneous"	},
1203 };
1204 
1205 static const struct pci_subclass pci_subclass_processor[] = {
1206 	{ PCI_SUBCLASS_PROCESSOR_386,		"386"		},
1207 	{ PCI_SUBCLASS_PROCESSOR_486,		"486"		},
1208 	{ PCI_SUBCLASS_PROCESSOR_PENTIUM,	"Pentium"	},
1209 	{ PCI_SUBCLASS_PROCESSOR_ALPHA,		"Alpha"		},
1210 	{ PCI_SUBCLASS_PROCESSOR_POWERPC,	"PowerPC"	},
1211 	{ PCI_SUBCLASS_PROCESSOR_MIPS,		"MIPS"		},
1212 	{ PCI_SUBCLASS_PROCESSOR_COPROC,	"Co-Processor"	},
1213 };
1214 
1215 static const struct pci_subclass pci_subclass_serialbus[] = {
1216 	{ PCI_SUBCLASS_SERIALBUS_FIREWIRE,	"FireWire"	},
1217 	{ PCI_SUBCLASS_SERIALBUS_ACCESS,	"ACCESS.bus"	},
1218 	{ PCI_SUBCLASS_SERIALBUS_SSA,		"SSA"		},
1219 	{ PCI_SUBCLASS_SERIALBUS_USB,		"USB"		},
1220 	{ PCI_SUBCLASS_SERIALBUS_FIBER,		"Fiber Channel"	},
1221 	{ PCI_SUBCLASS_SERIALBUS_SMBUS,		"SMBus"		},
1222 	{ PCI_SUBCLASS_SERIALBUS_INFINIBAND,	"InfiniBand"	},
1223 	{ PCI_SUBCLASS_SERIALBUS_IPMI,		"IPMI"		},
1224 	{ PCI_SUBCLASS_SERIALBUS_SERCOS,	"SERCOS"	},
1225 	{ PCI_SUBCLASS_SERIALBUS_CANBUS,	"CANbus"	},
1226 };
1227 
1228 static const struct pci_subclass pci_subclass_wireless[] = {
1229 	{ PCI_SUBCLASS_WIRELESS_IRDA,		"IrDA"		},
1230 	{ PCI_SUBCLASS_WIRELESS_CONSUMERIR,	"Consumer IR"	},
1231 	{ PCI_SUBCLASS_WIRELESS_RF,		"RF"		},
1232 	{ PCI_SUBCLASS_WIRELESS_BLUETOOTH,	"Bluetooth"	},
1233 	{ PCI_SUBCLASS_WIRELESS_BROADBAND,	"Broadband"	},
1234 	{ PCI_SUBCLASS_WIRELESS_802_11A,	"802.11a"	},
1235 	{ PCI_SUBCLASS_WIRELESS_802_11B,	"802.11b"	},
1236 	{ PCI_SUBCLASS_WIRELESS_MISC,		"Miscellaneous"	},
1237 };
1238 
1239 static const struct pci_subclass pci_subclass_i2o[] = {
1240 	{ PCI_SUBCLASS_I2O_STANDARD,		"Standard"	},
1241 };
1242 
1243 static const struct pci_subclass pci_subclass_satcom[] = {
1244 	{ PCI_SUBCLASS_SATCOM_TV,		"TV"		},
1245 	{ PCI_SUBCLASS_SATCOM_AUDIO,		"Audio"		},
1246 	{ PCI_SUBCLASS_SATCOM_VOICE,		"Voice"		},
1247 	{ PCI_SUBCLASS_SATCOM_DATA,		"Data"		},
1248 };
1249 
1250 static const struct pci_subclass pci_subclass_crypto[] = {
1251 	{ PCI_SUBCLASS_CRYPTO_NETCOMP,		"Network/Computing" },
1252 	{ PCI_SUBCLASS_CRYPTO_ENTERTAINMENT,	"Entertainment"	},
1253 	{ PCI_SUBCLASS_CRYPTO_MISC,		"Miscellaneous"	},
1254 };
1255 
1256 static const struct pci_subclass pci_subclass_dasp[] = {
1257 	{ PCI_SUBCLASS_DASP_DPIO,		"DPIO"		},
1258 	{ PCI_SUBCLASS_DASP_TIMEFREQ,		"Time and Frequency" },
1259 	{ PCI_SUBCLASS_DASP_SYNC,		"Synchronization" },
1260 	{ PCI_SUBCLASS_DASP_MGMT,		"Management"	},
1261 	{ PCI_SUBCLASS_DASP_MISC,		"Miscellaneous"	},
1262 };
1263 
1264 #define CLASS(_c, _n, _s) { \
1265 	.class = _c, \
1266 	.name = _n, \
1267 	.subclass = _s, \
1268 	.nsubclass = nitems(_s), \
1269 }
1270 
1271 static const struct pci_class pci_classes[] = {
1272 	CLASS(PCI_CLASS_PREHISTORIC,	"Prehistoric",
1273 	    pci_subclass_prehistoric),
1274 	CLASS(PCI_CLASS_MASS_STORAGE,	"Mass Storage",
1275 	    pci_subclass_mass_storage),
1276 	CLASS(PCI_CLASS_NETWORK,	"Network",
1277 	    pci_subclass_network),
1278 	CLASS(PCI_CLASS_DISPLAY,	"Display",
1279 	    pci_subclass_display),
1280 	CLASS(PCI_CLASS_MEMORY,		"Memory",
1281 	    pci_subclass_memory),
1282 	CLASS(PCI_CLASS_BRIDGE,		"Bridge",
1283 	    pci_subclass_bridge),
1284 	CLASS(PCI_CLASS_COMMUNICATIONS,	"Communications",
1285 	    pci_subclass_communications),
1286 	CLASS(PCI_CLASS_SYSTEM,		"System",
1287 	    pci_subclass_system),
1288 	CLASS(PCI_CLASS_INPUT,		"Input",
1289 	    pci_subclass_input),
1290 	CLASS(PCI_CLASS_DOCK,		"Dock",
1291 	    pci_subclass_dock),
1292 	CLASS(PCI_CLASS_PROCESSOR,	"Processor",
1293 	    pci_subclass_processor),
1294 	CLASS(PCI_CLASS_SERIALBUS,	"Serial Bus",
1295 	    pci_subclass_serialbus),
1296 	CLASS(PCI_CLASS_WIRELESS,	"Wireless",
1297 	    pci_subclass_wireless),
1298 	CLASS(PCI_CLASS_I2O,		"I2O",
1299 	    pci_subclass_i2o),
1300 	CLASS(PCI_CLASS_SATCOM,		"Satellite Comm",
1301 	    pci_subclass_satcom),
1302 	CLASS(PCI_CLASS_CRYPTO,		"Crypto",
1303 	    pci_subclass_crypto),
1304 	CLASS(PCI_CLASS_DASP,		"DASP",
1305 	    pci_subclass_dasp),
1306 };
1307 
1308 static const struct pci_class *
1309 pci_class(pci_class_t class)
1310 {
1311 	const struct pci_class *pc;
1312 	size_t i;
1313 
1314 	for (i = 0; i < nitems(pci_classes); i++) {
1315 		pc = &pci_classes[i];
1316 		if (pc->class == class)
1317 			return (pc);
1318 	}
1319 
1320 	return (NULL);
1321 }
1322 
1323 static const struct pci_subclass *
1324 pci_subclass(const struct pci_class *pc, pci_subclass_t subclass)
1325 {
1326 	const struct pci_subclass *ps;
1327 	size_t i;
1328 
1329 	for (i = 0; i < pc->nsubclass; i++) {
1330 		ps = &pc->subclass[i];
1331 		if (ps->subclass == subclass)
1332 			return (ps);
1333 	}
1334 
1335 	return (NULL);
1336 }
1337 
1338 static const char *
1339 pci_class_name(pci_class_t class)
1340 {
1341 	const struct pci_class *pc;
1342 
1343 	pc = pci_class(class);
1344 	if (pc == NULL)
1345 		return ("(unknown)");
1346 
1347 	return (pc->name);
1348 }
1349 
1350 
1351 static const char *
1352 pci_subclass_name(pci_class_t class, pci_subclass_t subclass)
1353 {
1354 	const struct pci_class *pc;
1355 	const struct pci_subclass *ps;
1356 
1357 	pc = pci_class(class);
1358 	if (pc == NULL)
1359 		return ("(unknown)");
1360 
1361 	ps = pci_subclass(pc, subclass);
1362 	if (ps == NULL)
1363 		return ("(unknown)");
1364 
1365 	return (ps->name);
1366 }
1367