Annotation of sys/dev/pci/pci_subr.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: pci_subr.c,v 1.21 2007/02/21 13:08:22 dlg Exp $ */
2: /* $NetBSD: pci_subr.c,v 1.19 1996/10/13 01:38:29 christos Exp $ */
3:
4: /*
5: * Copyright (c) 1995, 1996 Christopher G. Demetriou. All rights reserved.
6: * Copyright (c) 1994 Charles Hannum. All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. All advertising materials mentioning features or use of this software
17: * must display the following acknowledgement:
18: * This product includes software developed by Charles Hannum.
19: * 4. The name of the author may not be used to endorse or promote products
20: * derived from this software without specific prior written permission.
21: *
22: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32: */
33:
34: /*
35: * PCI autoconfiguration support functions.
36: */
37:
38: #include <sys/param.h>
39: #include <sys/systm.h>
40: #include <sys/device.h>
41:
42: #include <dev/pci/pcireg.h>
43: #include <dev/pci/pcivar.h>
44: #ifdef PCIVERBOSE
45: #include <dev/pci/pcidevs.h>
46: #include <dev/pci/pcidevs_data.h>
47: #endif
48:
49: /*
50: * Descriptions of known PCI classes and subclasses.
51: *
52: * Subclasses are described in the same way as classes, but have a
53: * NULL subclass pointer.
54: */
55: struct pci_class {
56: const char *name;
57: int val; /* as wide as pci_{,sub}class_t */
58: const struct pci_class *subclasses;
59: };
60:
61: const struct pci_class pci_subclass_prehistoric[] = {
62: { "miscellaneous", PCI_SUBCLASS_PREHISTORIC_MISC, },
63: { "VGA", PCI_SUBCLASS_PREHISTORIC_VGA, },
64: { 0 }
65: };
66:
67: const struct pci_class pci_subclass_mass_storage[] = {
68: { "SCSI", PCI_SUBCLASS_MASS_STORAGE_SCSI, },
69: { "IDE", PCI_SUBCLASS_MASS_STORAGE_IDE, },
70: { "floppy", PCI_SUBCLASS_MASS_STORAGE_FLOPPY, },
71: { "IPI", PCI_SUBCLASS_MASS_STORAGE_IPI, },
72: { "RAID", PCI_SUBCLASS_MASS_STORAGE_RAID, },
73: { "ATA", PCI_SUBCLASS_MASS_STORAGE_ATA, },
74: { "SATA", PCI_SUBCLASS_MASS_STORAGE_SATA, },
75: { "SAS", PCI_SUBCLASS_MASS_STORAGE_SAS, },
76: { "miscellaneous", PCI_SUBCLASS_MASS_STORAGE_MISC, },
77: { 0 },
78: };
79:
80: const struct pci_class pci_subclass_network[] = {
81: { "ethernet", PCI_SUBCLASS_NETWORK_ETHERNET, },
82: { "token ring", PCI_SUBCLASS_NETWORK_TOKENRING, },
83: { "FDDI", PCI_SUBCLASS_NETWORK_FDDI, },
84: { "ATM", PCI_SUBCLASS_NETWORK_ATM, },
85: { "ISDN", PCI_SUBCLASS_NETWORK_ISDN, },
86: { "WorldFip", PCI_SUBCLASS_NETWORK_WORLDFIP, },
87: { "PCMIG Multi Computing", PCI_SUBCLASS_NETWORK_PCIMGMULTICOMP, },
88: { "miscellaneous", PCI_SUBCLASS_NETWORK_MISC, },
89: { 0 },
90: };
91:
92: const struct pci_class pci_subclass_display[] = {
93: { "VGA", PCI_SUBCLASS_DISPLAY_VGA, },
94: { "XGA", PCI_SUBCLASS_DISPLAY_XGA, },
95: { "3D", PCI_SUBCLASS_DISPLAY_3D, },
96: { "miscellaneous", PCI_SUBCLASS_DISPLAY_MISC, },
97: { 0 },
98: };
99:
100: const struct pci_class pci_subclass_multimedia[] = {
101: { "video", PCI_SUBCLASS_MULTIMEDIA_VIDEO, },
102: { "audio", PCI_SUBCLASS_MULTIMEDIA_AUDIO, },
103: { "telephony", PCI_SUBCLASS_MULTIMEDIA_TELEPHONY, },
104: { "hdaudio", PCI_SUBCLASS_MULTIMEDIA_HDAUDIO, },
105: { "miscellaneous", PCI_SUBCLASS_MULTIMEDIA_MISC, },
106: { 0 },
107: };
108:
109: const struct pci_class pci_subclass_memory[] = {
110: { "RAM", PCI_SUBCLASS_MEMORY_RAM, },
111: { "flash", PCI_SUBCLASS_MEMORY_FLASH, },
112: { "miscellaneous", PCI_SUBCLASS_MEMORY_MISC, },
113: { 0 },
114: };
115:
116: const struct pci_class pci_subclass_bridge[] = {
117: { "host", PCI_SUBCLASS_BRIDGE_HOST, },
118: { "ISA", PCI_SUBCLASS_BRIDGE_ISA, },
119: { "EISA", PCI_SUBCLASS_BRIDGE_EISA, },
120: { "MicroChannel", PCI_SUBCLASS_BRIDGE_MC, },
121: { "PCI", PCI_SUBCLASS_BRIDGE_PCI, },
122: { "PCMCIA", PCI_SUBCLASS_BRIDGE_PCMCIA, },
123: { "NuBus", PCI_SUBCLASS_BRIDGE_NUBUS, },
124: { "CardBus", PCI_SUBCLASS_BRIDGE_CARDBUS, },
125: { "RACEway", PCI_SUBCLASS_BRIDGE_RACEWAY, },
126: { "Semi-transparent PCI", PCI_SUBCLASS_BRIDGE_STPCI, },
127: { "InfiniBand", PCI_SUBCLASS_BRIDGE_INFINIBAND, },
128: { "miscellaneous", PCI_SUBCLASS_BRIDGE_MISC, },
129: { 0 },
130: };
131:
132: const struct pci_class pci_subclass_communications[] = {
133: { "serial", PCI_SUBCLASS_COMMUNICATIONS_SERIAL, },
134: { "parallel", PCI_SUBCLASS_COMMUNICATIONS_PARALLEL, },
135: { "multi-port serial", PCI_SUBCLASS_COMMUNICATIONS_MPSERIAL, },
136: { "modem", PCI_SUBCLASS_COMMUNICATIONS_MODEM, },
137: { "GPIB", PCI_SUBCLASS_COMMUNICATIONS_GPIB, },
138: { "smartcard", PCI_SUBCLASS_COMMUNICATIONS_SMARTCARD, },
139: { "miscellaneous", PCI_SUBCLASS_COMMUNICATIONS_MISC, },
140: { 0 },
141: };
142:
143: const struct pci_class pci_subclass_system[] = {
144: { "interrupt", PCI_SUBCLASS_SYSTEM_PIC, },
145: { "8237 DMA", PCI_SUBCLASS_SYSTEM_DMA, },
146: { "8254 timer", PCI_SUBCLASS_SYSTEM_TIMER, },
147: { "RTC", PCI_SUBCLASS_SYSTEM_RTC, },
148: { "PCI Hot-Plug", PCI_SUBCLASS_SYSTEM_PCIHOTPLUG, },
149: { "SD Host Controller", PCI_SUBCLASS_SYSTEM_SDHC, },
150: { "miscellaneous", PCI_SUBCLASS_SYSTEM_MISC, },
151: { 0 },
152: };
153:
154: const struct pci_class pci_subclass_input[] = {
155: { "keyboard", PCI_SUBCLASS_INPUT_KEYBOARD, },
156: { "digitizer", PCI_SUBCLASS_INPUT_DIGITIZER, },
157: { "mouse", PCI_SUBCLASS_INPUT_MOUSE, },
158: { "scanner", PCI_SUBCLASS_INPUT_SCANNER, },
159: { "game port", PCI_SUBCLASS_INPUT_GAMEPORT, },
160: { "miscellaneous", PCI_SUBCLASS_INPUT_MISC, },
161: { 0 },
162: };
163:
164: const struct pci_class pci_subclass_dock[] = {
165: { "generic", PCI_SUBCLASS_DOCK_GENERIC, },
166: { "miscellaneous", PCI_SUBCLASS_DOCK_MISC, },
167: { 0 },
168: };
169:
170: const struct pci_class pci_subclass_processor[] = {
171: { "386", PCI_SUBCLASS_PROCESSOR_386, },
172: { "486", PCI_SUBCLASS_PROCESSOR_486, },
173: { "Pentium", PCI_SUBCLASS_PROCESSOR_PENTIUM, },
174: { "Alpha", PCI_SUBCLASS_PROCESSOR_ALPHA, },
175: { "PowerPC", PCI_SUBCLASS_PROCESSOR_POWERPC, },
176: { "MIPS", PCI_SUBCLASS_PROCESSOR_MIPS, },
177: { "Co-processor", PCI_SUBCLASS_PROCESSOR_COPROC, },
178: { 0 },
179: };
180:
181: const struct pci_class pci_subclass_serialbus[] = {
182: { "Firewire", PCI_SUBCLASS_SERIALBUS_FIREWIRE, },
183: { "ACCESS.bus", PCI_SUBCLASS_SERIALBUS_ACCESS, },
184: { "SSA", PCI_SUBCLASS_SERIALBUS_SSA, },
185: { "USB", PCI_SUBCLASS_SERIALBUS_USB, },
186: /* XXX Fiber Channel/_FIBRECHANNEL */
187: { "Fiber Channel", PCI_SUBCLASS_SERIALBUS_FIBER, },
188: { "SMBus", PCI_SUBCLASS_SERIALBUS_SMBUS, },
189: { "InfiniBand", PCI_SUBCLASS_SERIALBUS_INFINIBAND, },
190: { "IPMI", PCI_SUBCLASS_SERIALBUS_IPMI, },
191: { "SERCOS", PCI_SUBCLASS_SERIALBUS_SERCOS, },
192: { "CANbus", PCI_SUBCLASS_SERIALBUS_CANBUS, },
193: { 0 },
194: };
195:
196: const struct pci_class pci_subclass_wireless[] = {
197: { "IrDA", PCI_SUBCLASS_WIRELESS_IRDA, },
198: { "Consumer IR", PCI_SUBCLASS_WIRELESS_CONSUMERIR, },
199: { "RF", PCI_SUBCLASS_WIRELESS_RF, },
200: { "bluetooth", PCI_SUBCLASS_WIRELESS_BLUETOOTH, },
201: { "broadband", PCI_SUBCLASS_WIRELESS_BROADBAND, },
202: { "802.11a (5 GHz)", PCI_SUBCLASS_WIRELESS_802_11A, },
203: { "802.11b (2.4 GHz)", PCI_SUBCLASS_WIRELESS_802_11B, },
204: { "miscellaneous", PCI_SUBCLASS_WIRELESS_MISC, },
205: { 0 },
206: };
207:
208: const struct pci_class pci_subclass_i2o[] = {
209: { "standard", PCI_SUBCLASS_I2O_STANDARD, },
210: { 0 },
211: };
212:
213: const struct pci_class pci_subclass_satcom[] = {
214: { "TV", PCI_SUBCLASS_SATCOM_TV, },
215: { "audio", PCI_SUBCLASS_SATCOM_AUDIO, },
216: { "voice", PCI_SUBCLASS_SATCOM_VOICE, },
217: { "data", PCI_SUBCLASS_SATCOM_DATA, },
218: { 0 },
219: };
220:
221: const struct pci_class pci_subclass_crypto[] = {
222: { "network/computing", PCI_SUBCLASS_CRYPTO_NETCOMP, },
223: { "entertainment", PCI_SUBCLASS_CRYPTO_ENTERTAINMENT, },
224: { "miscellaneous", PCI_SUBCLASS_CRYPTO_MISC, },
225: { 0 },
226: };
227:
228: const struct pci_class pci_subclass_dasp[] = {
229: { "DPIO", PCI_SUBCLASS_DASP_DPIO, },
230: { "Time and Frequency", PCI_SUBCLASS_DASP_TIMEFREQ, },
231: { "synchronization", PCI_SUBCLASS_DASP_SYNC, },
232: { "management", PCI_SUBCLASS_DASP_MGMT, },
233: { "miscellaneous", PCI_SUBCLASS_DASP_MISC, },
234: { 0 },
235: };
236:
237: const struct pci_class pci_class[] = {
238: { "prehistoric", PCI_CLASS_PREHISTORIC,
239: pci_subclass_prehistoric, },
240: { "mass storage", PCI_CLASS_MASS_STORAGE,
241: pci_subclass_mass_storage, },
242: { "network", PCI_CLASS_NETWORK,
243: pci_subclass_network, },
244: { "display", PCI_CLASS_DISPLAY,
245: pci_subclass_display, },
246: { "multimedia", PCI_CLASS_MULTIMEDIA,
247: pci_subclass_multimedia, },
248: { "memory", PCI_CLASS_MEMORY,
249: pci_subclass_memory, },
250: { "bridge", PCI_CLASS_BRIDGE,
251: pci_subclass_bridge, },
252: { "communications", PCI_CLASS_COMMUNICATIONS,
253: pci_subclass_communications, },
254: { "system", PCI_CLASS_SYSTEM,
255: pci_subclass_system, },
256: { "input", PCI_CLASS_INPUT,
257: pci_subclass_input, },
258: { "dock", PCI_CLASS_DOCK,
259: pci_subclass_dock, },
260: { "processor", PCI_CLASS_PROCESSOR,
261: pci_subclass_processor, },
262: { "serial bus", PCI_CLASS_SERIALBUS,
263: pci_subclass_serialbus, },
264: { "wireless", PCI_CLASS_WIRELESS,
265: pci_subclass_wireless, },
266: { "I2O", PCI_CLASS_I2O,
267: pci_subclass_i2o, },
268: { "satellite comm", PCI_CLASS_SATCOM,
269: pci_subclass_satcom, },
270: { "crypto", PCI_CLASS_CRYPTO,
271: pci_subclass_crypto, },
272: { "DASP", PCI_CLASS_DASP,
273: pci_subclass_dasp, },
274: { "undefined", PCI_CLASS_UNDEFINED,
275: 0, },
276: { 0 },
277: };
278:
279: const char *
280: pci_findvendor(pcireg_t id_reg)
281: {
282: #ifdef PCIVERBOSE
283: pci_vendor_id_t vendor = PCI_VENDOR(id_reg);
284: const struct pci_known_vendor *kdp;
285:
286: kdp = pci_known_vendors;
287: while (kdp->vendorname != NULL) { /* all have vendor name */
288: if (kdp->vendor == vendor)
289: break;
290: kdp++;
291: }
292: return (kdp->vendorname);
293: #else
294: return (NULL);
295: #endif
296: }
297:
298: const char *
299: pci_findproduct(pcireg_t id_reg)
300: {
301: #ifdef PCIVERBOSE
302: pci_vendor_id_t vendor = PCI_VENDOR(id_reg);
303: pci_product_id_t product = PCI_PRODUCT(id_reg);
304: const struct pci_known_product *pkp;
305:
306: pkp = pci_known_products;
307: while (pkp->productname != NULL) { /* all have product name */
308: if (pkp->vendor == vendor && pkp->product == product)
309: break;
310: pkp++;
311: }
312: return (pkp->productname);
313: #else
314: return NULL;
315: #endif
316: }
317:
318: void
319: pci_devinfo(pcireg_t id_reg, pcireg_t class_reg, int showclass, char *cp,
320: size_t cp_max)
321: {
322: pci_vendor_id_t vendor;
323: pci_product_id_t product;
324: pci_class_t class;
325: pci_subclass_t subclass;
326: pci_interface_t interface;
327: pci_revision_t revision;
328: const char *vendor_namep = NULL, *product_namep = NULL;
329: const struct pci_class *classp, *subclassp;
330: size_t cp_len = 0;
331: #ifdef PCIVERBOSE
332: const char *unmatched = "unknown ";
333: #else
334: const char *unmatched = "";
335: #endif
336:
337: vendor = PCI_VENDOR(id_reg);
338: product = PCI_PRODUCT(id_reg);
339:
340: class = PCI_CLASS(class_reg);
341: subclass = PCI_SUBCLASS(class_reg);
342: interface = PCI_INTERFACE(class_reg);
343: revision = PCI_REVISION(class_reg);
344:
345: #ifdef PCIVERBOSE
346: vendor_namep = pci_findvendor(id_reg);
347: if (vendor_namep != NULL)
348: product_namep = pci_findproduct(id_reg);
349: #endif /* PCIVERBOSE */
350:
351: classp = pci_class;
352: while (classp->name != NULL) {
353: if (class == classp->val)
354: break;
355: classp++;
356: }
357:
358: subclassp = (classp->name != NULL) ? classp->subclasses : NULL;
359: while (subclassp && subclassp->name != NULL) {
360: if (subclass == subclassp->val)
361: break;
362: subclassp++;
363: }
364:
365: if (vendor_namep == NULL)
366: snprintf(cp, cp_max, "%svendor 0x%04x product 0x%04x",
367: unmatched, vendor, product);
368: else if (product_namep != NULL)
369: snprintf(cp, cp_max, "\"%s %s\"", vendor_namep, product_namep);
370: else
371: snprintf(cp, cp_max, "vendor \"%s\", unknown product 0x%04x",
372: vendor_namep, product);
373: if (showclass && product_namep == NULL) {
374: strlcat(cp, " (", cp_max);
375: cp_len = strlen(cp);
376: if (classp->name == NULL)
377: snprintf(cp + cp_len, cp_max - cp_len,
378: "unknown class 0x%02x, subclass 0x%02x",
379: class, subclass);
380: else if (subclassp == NULL || subclassp->name == NULL)
381: snprintf(cp + cp_len, cp_max - cp_len,
382: "class %s unknown subclass 0x%02x", classp->name,
383: subclass);
384: else
385: snprintf(cp + cp_len, cp_max - cp_len,
386: "class %s subclass %s", classp->name,
387: subclassp->name);
388: #if 0 /* not very useful */
389: cp_len = strlen(cp);
390: snprintf(cp + cp_len, cp_max - cp_len,
391: ", interface 0x%02x", interface);
392: #endif
393: cp_len = strlen(cp);
394: snprintf(cp + cp_len, cp_max - cp_len,
395: ", rev 0x%02x)", revision);
396: } else {
397: cp_len = strlen(cp);
398: snprintf(cp + cp_len, cp_max - cp_len, " rev 0x%02x",
399: revision);
400: }
401: }
CVSweb