xref: /haiku/src/add-ons/kernel/bus_managers/pci/pci_info.cpp (revision d3d8b26997fac34a84981e6d2b649521de2cc45a)
1 /*
2 ** Copyright 2003-2006, Marcus Overhagen. All rights reserved.
3 ** Distributed under the terms of the MIT License.
4 */
5 
6 
7 #include <KernelExport.h>
8 #define __HAIKU_PCI_BUS_MANAGER_TESTING 1
9 #include <PCI.h>
10 #include <string.h>
11 #include "pci_info.h"
12 #include "pci_priv.h"
13 #include "pci.h"
14 
15 #define PCI_VERBOSE	1
16 #define USE_PCI_HEADER 1
17 
18 #if USE_PCI_HEADER
19 #	include "pcihdr.h"
20 #endif
21 
22 
23 void get_vendor_info(uint16 vendorID, const char **venShort, const char **venFull);
24 void get_device_info(uint16 vendorID, uint16 deviceID, const char **devShort, const char **devFull);
25 const char *get_class_info(uint8 class_base, uint8 class_sub, uint8 class_api);
26 const char *get_capability_name(uint8 cap_id);
27 
28 
29 static void
30 print_pci2pci_bridge_info(const pci_info *info, bool verbose)
31 {
32 	TRACE(("PCI:   subsystem_id %04x, subsystem_vendor_id %04x\n",
33 			info->u.h1.subsystem_id, info->u.h1.subsystem_vendor_id));
34 	TRACE(("PCI:   primary_bus %02x, secondary_bus %02x, subordinate_bus %02x, secondary_latency %02x\n",
35 			info->u.h1.primary_bus, info->u.h1.secondary_bus, info->u.h1.subordinate_bus, info->u.h1.secondary_latency));
36 	TRACE(("PCI:   io_base_upper_16  %04x, io_base  %02x\n",
37 			info->u.h1.io_base_upper16, info->u.h1.io_base));
38 	TRACE(("PCI:   io_limit_upper_16 %04x, io_limit %02x\n",
39 			info->u.h1.io_limit_upper16, info->u.h1.io_limit));
40 	TRACE(("PCI:   memory_base %04x, memory_limit %04x\n",
41 			info->u.h1.memory_base, info->u.h1.memory_limit));
42 	TRACE(("PCI:   prefetchable_memory_base_upper32  %08lx, prefetchable_memory_base  %04x\n",
43 		info->u.h1.prefetchable_memory_base_upper32, info->u.h1.prefetchable_memory_base));
44 	TRACE(("PCI:   prefetchable_memory_limit_upper32 %08lx, prefetchable_memory_limit %04x\n",
45 		info->u.h1.prefetchable_memory_limit_upper32, info->u.h1.prefetchable_memory_limit));
46 	TRACE(("PCI:   bridge_control %02x, secondary_status %04x\n",
47 			info->u.h1.bridge_control, info->u.h1.secondary_status));
48 	TRACE(("PCI:   interrupt_line %02x, interrupt_pin %02x\n",
49 			info->u.h1.interrupt_line, info->u.h1.interrupt_pin));
50 	TRACE(("PCI:   ROM base host %08lx, pci %08lx, size ??\n",
51 			info->u.h1.rom_base, info->u.h1.rom_base_pci));
52 	for (int i = 0; i < 2; i++)
53 		TRACE(("PCI:   base reg %d: host %08lx, pci %08lx, size %08lx, flags %02x\n",
54 			i, info->u.h1.base_registers[i], info->u.h1.base_registers_pci[i],
55 			info->u.h1.base_register_sizes[i], info->u.h1.base_register_flags[i]));
56 }
57 
58 
59 static void
60 print_pci2cardbus_bridge_info(const pci_info *info, bool verbose)
61 {
62 	TRACE(("PCI:   subsystem_id %04x, subsystem_vendor_id %04x\n",
63 			info->u.h2.subsystem_id, info->u.h2.subsystem_vendor_id));
64 	TRACE(("PCI:   primary_bus %02x, secondary_bus %02x, subordinate_bus %02x, secondary_latency %02x\n",
65 			info->u.h2.primary_bus, info->u.h2.secondary_bus, info->u.h2.subordinate_bus, info->u.h2.secondary_latency));
66 	TRACE(("PCI:   bridge_control %02x, secondary_status %04x\n",
67 			info->u.h2.bridge_control, info->u.h2.secondary_status));
68 	TRACE(("PCI:   memory_base_upper32  %08lx, memory_base  %08lx\n",
69 		info->u.h2.memory_base_upper32, info->u.h2.memory_base));
70 	TRACE(("PCI:   memory_limit_upper32 %08lx, memory_limit %08lx\n",
71 		info->u.h2.memory_limit_upper32, info->u.h2.memory_limit));
72 	TRACE(("PCI:   io_base_upper32  %08lx, io_base  %08lx\n",
73 		info->u.h2.io_base_upper32, info->u.h2.io_base));
74 	TRACE(("PCI:   io_limit_upper32 %08lx, io_limit %08lx\n",
75 		info->u.h2.io_limit_upper32, info->u.h2.io_limit));
76 }
77 
78 
79 static void
80 print_generic_info(const pci_info *info, bool verbose)
81 {
82 	TRACE(("PCI:   ROM base host %08lx, pci %08lx, size %08lx\n",
83 			info->u.h0.rom_base, info->u.h0.rom_base_pci, info->u.h0.rom_size));
84 	TRACE(("PCI:   cardbus_CIS %08lx, subsystem_id %04x, subsystem_vendor_id %04x\n",
85 			info->u.h0.cardbus_cis, info->u.h0.subsystem_id, info->u.h0.subsystem_vendor_id));
86 	TRACE(("PCI:   interrupt_line %02x, interrupt_pin %02x, min_grant %02x, max_latency %02x\n",
87 			info->u.h0.interrupt_line, info->u.h0.interrupt_pin, info->u.h0.min_grant, info->u.h0.max_latency));
88 	for (int i = 0; i < 6; i++)
89 		TRACE(("PCI:   base reg %d: host %08lx, pci %08lx, size %08lx, flags %02x\n",
90 			i, info->u.h0.base_registers[i], info->u.h0.base_registers_pci[i],
91 			info->u.h0.base_register_sizes[i], info->u.h0.base_register_flags[i]));
92 }
93 
94 
95 static void
96 print_capabilities(const pci_info *info)
97 {
98 	uint16	status;
99 	uint8	cap_ptr;
100 	uint8	cap_id;
101 	int		i;
102 
103 	TRACE(("PCI:   Capabilities: "));
104 
105 	status = pci_read_config(info->bus, info->device, info->function, PCI_status, 2);
106 	if (!(status & PCI_status_capabilities)) {
107 		TRACE(("(not supported)\n"));
108 		return;
109 	}
110 
111 	switch (info->header_type & PCI_header_type_mask) {
112 		case PCI_header_type_generic:
113 		case PCI_header_type_PCI_to_PCI_bridge:
114 			cap_ptr = pci_read_config(info->bus, info->device, info->function, PCI_capabilities_ptr, 1);
115 			break;
116 		case PCI_header_type_cardbus:
117 			cap_ptr = pci_read_config(info->bus, info->device, info->function, PCI_capabilities_ptr_2, 1);
118 			break;
119 		default:
120 			TRACE(("(unknown header type)\n"));
121 			return;
122 	}
123 
124 	cap_ptr &= ~3;
125 	if (!cap_ptr) {
126 		TRACE(("(empty list)\n"));
127 		return;
128 	}
129 
130 	for (i = 0; i < 48; i++) {
131 		const char *name;
132 		cap_id  = pci_read_config(info->bus, info->device, info->function, cap_ptr, 1);
133 		cap_ptr = pci_read_config(info->bus, info->device, info->function, cap_ptr + 1, 1);
134 		cap_ptr &= ~3;
135 		if (i) {
136 			TRACE((", "));
137 		}
138 		name = get_capability_name(cap_id);
139 		if (name) {
140 			TRACE(("%s", name));
141 		} else {
142 			TRACE(("0x%02x", cap_id));
143 		}
144 		if (!cap_ptr)
145 			break;
146 	}
147 	TRACE(("\n"));
148 }
149 
150 
151 static void
152 print_info_basic(const pci_info *info, bool verbose)
153 {
154 	TRACE(("PCI: [dom %d, bus %2d] bus %3d, device %2d, function %2d: vendor %04x, device %04x, revision %02x\n",
155 	// XXX this works only as long as PCI manager virtual bus mapping isn't changed:
156 			(info->bus >> 5) /* domain */, (info->bus & 0x1f) /* bus */,
157 			info->bus, info->device, info->function, info->vendor_id, info->device_id, info->revision));
158 	TRACE(("PCI:   class_base %02x, class_function %02x, class_api %02x\n",
159 			info->class_base, info->class_sub, info->class_api));
160 
161 	if (verbose) {
162 #if USE_PCI_HEADER
163 		const char *venShort;
164 		const char *venFull;
165 		get_vendor_info(info->vendor_id, &venShort, &venFull);
166 		if (!venShort && !venFull) {
167 			TRACE(("PCI:   vendor %04x: Unknown\n", info->vendor_id));
168 		} else if (venShort && venFull) {
169 			TRACE(("PCI:   vendor %04x: %s - %s\n", info->vendor_id, venShort, venFull));
170 		} else {
171 			TRACE(("PCI:   vendor %04x: %s\n", info->vendor_id, venShort ? venShort : venFull));
172 		}
173 		const char *devShort;
174 		const char *devFull;
175 		get_device_info(info->vendor_id, info->device_id, &devShort, &devFull);
176 		if (!devShort && !devFull) {
177 			TRACE(("PCI:   device %04x: Unknown\n", info->device_id));
178 		} else if (devShort && devFull) {
179 			TRACE(("PCI:   device %04x: %s - %s\n", info->device_id, devShort, devFull));
180 		} else {
181 			TRACE(("PCI:   device %04x: %s\n", info->device_id, devShort ? devShort : devFull));
182 		}
183 #endif
184 		TRACE(("PCI:   info: %s\n", get_class_info(info->class_base, info->class_sub, info->class_api)));
185 	}
186 	TRACE(("PCI:   line_size %02x, latency %02x, header_type %02x, BIST %02x\n",
187 			info->line_size, info->latency, info->header_type, info->bist));
188 
189 	switch (info->header_type & PCI_header_type_mask) {
190 		case PCI_header_type_generic:
191 			print_generic_info(info, verbose);
192 			break;
193 		case PCI_header_type_PCI_to_PCI_bridge:
194 			print_pci2pci_bridge_info(info, verbose);
195 			break;
196 		case PCI_header_type_cardbus:
197 			print_pci2cardbus_bridge_info(info, verbose);
198 			break;
199 		default:
200 			TRACE(("PCI:   unknown header type\n"));
201 	}
202 
203 	print_capabilities(info);
204 }
205 
206 
207 void
208 pci_print_info()
209 {
210 	pci_info info;
211 	for (long index = 0; B_OK == pci_get_nth_pci_info(index, &info); index++) {
212 		print_info_basic(&info, PCI_VERBOSE);
213 	}
214 }
215 
216 
217 const char *
218 get_class_info(uint8 class_base, uint8 class_sub, uint8 class_api)
219 {
220 	switch (class_base) {
221 		case PCI_early:
222 			switch (class_sub) {
223 				case PCI_early_not_vga:
224 					return "Not VGA-compatible pre-2.0 PCI specification device";
225 				case PCI_early_vga:
226 					return "VGA-compatible pre-2.0 PCI specification device";
227 				default:
228 					return "Unknown pre-2.0 PCI specification device";
229 			}
230 
231 		case PCI_mass_storage:
232 			switch (class_sub) {
233 				case PCI_scsi:
234 					return "SCSI mass storage controller";
235 				case PCI_ide:
236 					return "IDE mass storage controller";
237 				case PCI_floppy:
238 					return "Floppy disk controller";
239 				case PCI_ipi:
240 					return "IPI mass storage controller";
241 				case PCI_raid:
242 					return "RAID mass storage controller";
243 				case PCI_mass_storage_other:
244 					return "Other mass storage controller";
245 				default:
246 					return "Unknown mass storage controller";
247 			}
248 
249 		case PCI_network:
250 			switch (class_sub) {
251 				case PCI_ethernet:
252 					return "Ethernet network controller";
253 				case PCI_token_ring:
254 					return "Token ring network controller";
255 				case PCI_fddi:
256 					return "FDDI network controller";
257 				case PCI_atm:
258 					return "ATM network controller";
259 				case PCI_isdn:
260 					return "ISDN network controller";
261 				case PCI_network_other:
262 					return "Other network controller";
263 				default:
264 					return "Unknown network controller";
265 			}
266 
267 		case PCI_display:
268 			switch (class_sub) {
269 				case PCI_vga:
270 					switch (class_api) {
271 						case 0x00:
272 							return "VGA-compatible display controller";
273 						case 0x01:
274 							return "8514-compatible display controller";
275 						default:
276 							return "Unknown VGA display controller";
277 					}
278 				case PCI_xga:
279 					return "XGA display controller";
280 				case PCI_3d:
281 					return "3D display controller";
282 				case PCI_display_other:
283 					return "Other display controller";
284 				default:
285 					return "Unknown display controller";
286 			}
287 
288 		case PCI_multimedia:
289 			switch (class_sub) {
290 				case PCI_video:
291 					return "Video multimedia device";
292 				case PCI_audio:
293 					return "Audio multimedia device";
294 				case PCI_telephony:
295 					return "Computer telephony multimedia device";
296 				case PCI_multimedia_other:
297 					return "Other multimedia device";
298 				default:
299 					return "Unknown multimedia device";
300 			}
301 
302 		case PCI_memory:
303 			switch (class_sub) {
304 				case PCI_ram:
305 					return "RAM memory controller";
306 				case PCI_flash:
307 					return "Flash memory controller";
308 				case PCI_memory_other:
309 					return "Other memory controller";
310 				default:
311 					return "Unknown memory controller";
312 			}
313 
314 		case PCI_bridge:
315 			switch (class_sub) {
316 				case PCI_host:
317 					return "Host/PCI bridge device";
318 				case PCI_isa:
319 					return "PCI/ISA bridge device";
320 				case PCI_eisa:
321 					return "PCI/EISA bridge device";
322 				case PCI_microchannel:
323 					return "PCI/Micro Channel bridge device";
324 				case PCI_pci:
325 					switch (class_api) {
326 						case 0x00:
327 							return "PCI/PCI bridge device";
328 						case 0x01:
329 							return "Transparent PCI/PCI bridge device";
330 						default:
331 							return "Unknown PCI/PCI bridge device";
332 					}
333 				case PCI_pcmcia:
334 					return "PCI/PCMCIA bridge device";
335 				case PCI_nubus:
336 					return "PCI/NuBus bridge device";
337 				case PCI_cardbus:
338 					return "PCI/CardBus bridge device";
339 				case PCI_raceway:
340 					if (class_api & 1)
341 						return "PCI/RACEway bridge device, end-point mode";
342 					else
343 						return "PCI/RACEway bridge device, transparent mode";
344 				case PCI_bridge_other:
345 					return "Other bridge device";
346 				default:
347 					return "Unknown bridge device";
348 			}
349 
350 		case PCI_simple_communications:
351 			switch (class_sub) {
352 				case PCI_serial:
353 					switch (class_api) {
354 						case PCI_serial_xt:
355 							return "Generic XT-compatible serial communications controller";
356 						case PCI_serial_16450:
357 							return "16450-compatible serial communications controller";
358 						case PCI_serial_16550:
359 							return "16550-compatible serial communications controller";
360 						case 0x03:
361 							return "16650-compatible serial communications controller";
362 						case 0x04:
363 							return "16750-compatible serial communications controller";
364 						case 0x05:
365 							return "16850-compatible serial communications controller";
366 						case 0x06:
367 							return "16950-compatible serial communications controller";
368 						default:
369 							return "Unknown serial communications controller";
370 					}
371 				case PCI_parallel:
372 					switch (class_api) {
373 						case PCI_parallel_simple:
374 							return "Simple parallel port communications controller";
375 						case PCI_parallel_bidirectional:
376 							return "Bi-directional parallel port communications controller";
377 						case PCI_parallel_ecp:
378 							return "ECP 1.x compliant parallel port communications controller";
379 						case 0x03:
380 							return "IEEE 1284 parallel communications controller";
381 						case 0xfe:
382 							return "IEEE 1284 parallel communications target device";
383 						default:
384 							return "Unknown parallel communications controller";
385 					}
386 				case PCI_multiport_serial:
387 					return "Multiport serial communications controller";
388 				case PCI_modem:
389 					switch (class_api) {
390 						case 0x00:
391 							return "Generic modem";
392 						case 0x01:
393 							return "Hayes-compatible modem, 16450-compatible interface";
394 						case 0x02:
395 							return "Hayes-compatible modem, 16550-compatible interface";
396 						case 0x03:
397 							return "Hayes-compatible modem, 16650-compatible interface";
398 						case 0x04:
399 							return "Hayes-compatible modem, 16750-compatible interface";
400 						default:
401 							return "Unknown modem communications controller";
402 					}
403 				case PCI_simple_communications_other:
404 					return "Other simple communications controller";
405 				default:
406 					return "Unknown simple communications controller";
407 			}
408 
409 		case PCI_base_peripheral:
410 			switch (class_sub) {
411 				case PCI_pic:
412 					switch (class_api) {
413 						case PCI_pic_8259:
414 							return "Generic 8259 programmable interrupt controller (PIC)";
415 						case PCI_pic_isa:
416 							return "ISA programmable interrupt controller (PIC)";
417 						case PCI_pic_eisa:
418 							return "EISA programmable interrupt controller (PIC)";
419 						case 0x10:
420 							return "IO advanced programmable interrupt controller (APIC)";
421 						case 0x20:
422 							return "IO(x) advanced programmable interrupt controller (APIC)";
423 						default:
424 							return "Unknown programmable interrupt controller (PIC)";
425 					}
426 				case PCI_dma:
427 					switch (class_api) {
428 						case PCI_dma_8237:
429 							return "Generic 8237 DMA controller";
430 						case PCI_dma_isa:
431 							return "ISA DMA controller";
432 						case PCI_dma_eisa:
433 							return "EISA DMA controller";
434 						default:
435 							return "Unknown DMA controller";
436 					}
437 				case PCI_timer:
438 					switch (class_api) {
439 						case PCI_timer_8254:
440 							return "Generic 8254 timer";
441 						case PCI_timer_isa:
442 							return "ISA system timers";
443 						case PCI_timer_eisa:
444 							return "EISA system timers";
445 						default:
446 							return "Unknown timer";
447 					}
448 				case PCI_rtc:
449 					switch (class_api) {
450 						case PCI_rtc_generic:
451 							return "Generic real time clock (RTC) controller";
452 						case PCI_rtc_isa:
453 							return "ISA real time clock (RTC) controller";
454 						default:
455 							return "Unknown real time clock (RTC) controller";
456 					}
457 				case PCI_generic_hot_plug:
458 					return "Generic PCI Hot-Plug controller";
459 				case PCI_system_peripheral_other:
460 					return "Other base system peripheral";
461 				default:
462 					return "Unknown base system peripheral";
463 			}
464 
465 		case PCI_input:
466 			switch (class_sub) {
467 				case PCI_keyboard:
468 					return "Keyboard controller";
469 				case PCI_pen:
470 					return "Digitizer (pen) input device";
471 				case PCI_mouse:
472 					return "Mouse controller";
473 				case PCI_scanner:
474 					return "Scanner controller";
475 				case PCI_gameport:
476 					switch (class_api) {
477 						case 0x00:
478 							return "Generic gameport controller";
479 						case 0x10:
480 							return "Gameport controller";
481 						default:
482 							return "Unknown gameport controller";
483 					}
484 				case PCI_input_other:
485 					return "Other input controller";
486 				default:
487 					return "Unknown input controller";
488 			}
489 
490 		case PCI_docking_station:
491 			switch (class_sub) {
492 				case PCI_docking_generic:
493 					return "Generic docking station";
494 				case 0x80:
495 					return "Other type of docking station";
496 				default:
497 					return "Unknown docking station";
498 			}
499 
500 		case PCI_processor:
501 			switch (class_sub) {
502 				case PCI_386:
503 					return "386 processor";
504 				case PCI_486:
505 					return "486 processor";
506 				case PCI_pentium:
507 					return "Pentium processor";
508 				case PCI_alpha:
509 					return "Alpha processor";
510 				case PCI_PowerPC:
511 					return "PowerPC processor";
512 				case PCI_mips:
513 					return "MIPS processor";
514 				case PCI_coprocessor:
515 					return "Co-processor";
516 				default:
517 					return "Unknown processor";
518 			}
519 
520 		case PCI_serial_bus:
521 			switch (class_sub) {
522 				case PCI_firewire:
523 					switch (class_api) {
524 						case 0x00:
525 							return "Firewire (IEEE 1394) serial bus controller";
526 						case 0x10:
527 							return "Firewire (IEEE 1394) OpenHCI serial bus controller";
528 						default:
529 							return "Unknown Firewire (IEEE 1394) serial bus controller";
530 					}
531 				case PCI_access:
532 					return "ACCESS serial bus controller";
533 				case PCI_ssa:
534 					return "Serial Storage Architecture (SSA) controller";
535 				case PCI_usb:
536 					switch (class_api) {
537 						case PCI_usb_uhci:
538 							return "USB UHCI controller";
539 						case PCI_usb_ohci:
540 							return "USB OHCI controller";
541 						case 0x80:
542 							return "Other USB controller";
543 						case 0xfe:
544 							return "USB device";
545 						default:
546 							return "Unknown USB serial bus controller";
547 					}
548 				case PCI_fibre_channel:
549 					return "Fibre Channel serial bus controller";
550 				case 0x05:
551 					return "System Management Bus (SMBus) controller";
552 				default:
553 					return "Unknown serial bus controller";
554 			}
555 
556 		case PCI_wireless:
557 			switch (class_sub) {
558 				case 0x00:
559 					return "iRDA compatible wireless controller";
560 				case 0x01:
561 					return "Consumer IR wireless controller";
562 				case 0x10:
563 					return "RF wireless controller";
564 				case 0x80:
565 					return "Other wireless controller";
566 				default:
567 					return "Unknown wireless controller";
568 			}
569 
570 		case PCI_intelligent_io:
571 			switch (class_sub) {
572 				case 0x00:
573 					return "Intelligent IO controller";
574 				default:
575 					return "Unknown intelligent IO controller";
576 			}
577 
578 		case PCI_satellite_communications:
579 			switch (class_sub) {
580 				case 0x01:
581 					return "TV satellite communications controller";
582 				case 0x02:
583 					return "Audio satellite communications controller";
584 				case 0x03:
585 					return "Voice satellite communications controller";
586 				case 0x04:
587 					return "Data satellite communications controller";
588 				default:
589 					return "Unknown satellite communications controller";
590 			}
591 
592 		case PCI_encryption_decryption:
593 			switch (class_sub) {
594 				case 0x00:
595 					return "Network and computing encryption/decryption controller";
596 				case 0x10:
597 					return "Entertainment encryption/decryption controller";
598 				case 0x80:
599 					return "Other encryption/decryption controller";
600 				default:
601 					return "Unknown encryption/decryption controller";
602 			}
603 
604 		case PCI_data_acquisition:
605 			switch (class_sub) {
606 				case 0x00:
607 					return "DPIO modules (data acquisition and signal processing controller)";
608 				case 0x80:
609 					return "Other data acquisition and signal processing controller";
610 				default:
611 					return "Unknown data acquisition and signal processing controller";
612 			}
613 
614 		case PCI_undefined:
615 			return "Does not fit any defined class";
616 
617 		default:
618 			return "Unknown device class base";
619 	}
620 }
621 
622 
623 const char *
624 get_capability_name(uint8 cap_id)
625 {
626 	switch (cap_id) {
627 		case PCI_cap_id_reserved:
628 			return "reserved";
629 		case PCI_cap_id_pm:
630 			return "PM";
631 		case PCI_cap_id_agp:
632 			return "AGP";
633 		case PCI_cap_id_vpd:
634 			return "VPD";
635 		case PCI_cap_id_slotid:
636 			return "SlotID";
637 		case PCI_cap_id_msi:
638 			return "MSI";
639 		case PCI_cap_id_chswp:
640 			return "chswp";
641 		case PCI_cap_id_pcix:
642 			return "PCI-X";
643 		case PCI_cap_id_ldt:
644 			return "ldt";
645 		case PCI_cap_id_vendspec:
646 			return "vendspec";
647 		case PCI_cap_id_debugport:
648 			return "DebugPort";
649 		case PCI_cap_id_cpci_rsrcctl:
650 			return "cpci_rsrcctl";
651 		case PCI_cap_id_hotplug:
652 			return "HotPlug";
653 		default:
654 			return NULL;
655 	}
656 }
657 
658 
659 #if USE_PCI_HEADER
660 void
661 get_vendor_info(uint16 vendorID, const char **venShort, const char **venFull)
662 {
663 	for (int i = 0; i < (int)PCI_VENTABLE_LEN; i++) {
664 		if (PciVenTable[i].VenId == vendorID) {
665 			if (PciVenTable[i].VenShort && PciVenTable[i].VenFull
666 				&& 0 == strcmp(PciVenTable[i].VenShort, PciVenTable[i].VenFull)) {
667 				*venShort = PciVenTable[i].VenShort[0] ? PciVenTable[i].VenShort : NULL;
668 				*venFull = NULL;
669 			} else {
670 				*venShort = PciVenTable[i].VenShort && PciVenTable[i].VenShort[0] ? PciVenTable[i].VenShort : NULL;
671 				*venFull = PciVenTable[i].VenFull && PciVenTable[i].VenFull[0] ? PciVenTable[i].VenFull : NULL;
672 			}
673 			return;
674 		}
675 	}
676 	*venShort = NULL;
677 	*venFull = NULL;
678 }
679 
680 
681 void
682 get_device_info(uint16 vendorID, uint16 deviceID, const char **devShort, const char **devFull)
683 {
684 	for (int i = 0; i < (int)PCI_DEVTABLE_LEN; i++) {
685 		if (PciDevTable[i].VenId == vendorID && PciDevTable[i].DevId == deviceID ) {
686 			*devShort = PciDevTable[i].Chip && PciDevTable[i].Chip[0] ? PciDevTable[i].Chip : NULL;
687 			*devFull = PciDevTable[i].ChipDesc && PciDevTable[i].ChipDesc[0] ? PciDevTable[i].ChipDesc : NULL;
688 			return;
689 		}
690 	}
691 	*devShort = NULL;
692 	*devFull = NULL;
693 }
694 #endif	/* USE_PCI_HEADER */
695