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