xref: /netbsd/sys/dev/pci/pci_verbose.c (revision 6550d01e)
1 /*	$NetBSD: pci_verbose.c,v 1.7 2010/07/25 14:14:25 pgoyette Exp $	*/
2 
3 /*
4  * Copyright (c) 1997 Zubin D. Dittia.  All rights reserved.
5  * Copyright (c) 1995, 1996, 1998, 2000
6  *	Christopher G. Demetriou.  All rights reserved.
7  * Copyright (c) 1994 Charles M. Hannum.  All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *	This product includes software developed by Charles M. Hannum.
20  * 4. The name of the author may not be used to endorse or promote products
21  *    derived from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 /*
36  * PCI autoconfiguration support functions.
37  *
38  * Note: This file is also built into a userland library (libpci).
39  * Pay attention to this when you make modifications.
40  */
41 
42 #include <sys/cdefs.h>
43 __KERNEL_RCSID(0, "$NetBSD: pci_verbose.c,v 1.7 2010/07/25 14:14:25 pgoyette Exp $");
44 
45 #include <sys/param.h>
46 
47 #ifdef _KERNEL
48 #include <sys/module.h>
49 #else
50 #include <pci.h>
51 #endif
52 
53 #include <dev/pci/pcireg.h>
54 #include <dev/pci/pcidevs.h>
55 #ifdef _KERNEL
56 #include <dev/pci/pci_verbose.h>
57 #endif
58 
59 /*
60  * Descriptions of of known vendors and devices ("products").
61  */
62 
63 #include <dev/pci/pcidevs_data.h>
64 
65 #ifndef _KERNEL
66 #include <string.h>
67 #endif
68 
69 #ifdef _KERNEL
70 static int pciverbose_modcmd(modcmd_t, void *);
71 
72 MODULE(MODULE_CLASS_MISC, pciverbose, NULL);
73 
74 static int
75 pciverbose_modcmd(modcmd_t cmd, void *arg)
76 {
77 	static const char *(*saved_findvendor)(pcireg_t);
78 	static const char *(*saved_findproduct)(pcireg_t);
79 	static const char *saved_unmatched;
80 
81 	switch (cmd) {
82 	case MODULE_CMD_INIT:
83 		saved_findvendor = pci_findvendor;
84 		saved_findproduct = pci_findproduct;
85 		saved_unmatched = pci_unmatched;
86 		pci_findvendor = pci_findvendor_real;
87 		pci_findproduct = pci_findproduct_real;
88 		pci_unmatched = "unmatched ";
89 		pciverbose_loaded = 1;
90 		return 0;
91 	case MODULE_CMD_FINI:
92 		pci_findvendor = saved_findvendor;
93 		pci_findproduct = saved_findproduct;
94 		pci_unmatched = saved_unmatched;
95 		pciverbose_loaded = 0;
96 		return 0;
97 	default:
98 		return ENOTTY;
99 	}
100 }
101 #endif /* KERNEL */
102 
103 static const char *
104 pci_untokenstring(const uint16_t *token, char *buf, size_t len)
105 {
106 	char *cp = buf;
107 
108 	buf[0] = '\0';
109 	for (; *token != 0; token++) {
110 		cp = buf + strlcat(buf, pci_words + *token, len - 2);
111 		cp[0] = ' ';
112 		cp[1] = '\0';
113 	}
114 	*cp = '\0';
115 	return cp != buf ? buf : NULL;
116 }
117 
118 const char *
119 pci_findvendor_real(pcireg_t id_reg)
120 {
121 	static char buf[256];
122 	pci_vendor_id_t vendor = PCI_VENDOR(id_reg);
123 	size_t n;
124 
125 	for (n = 0; n < __arraycount(pci_vendors); n++) {
126 		if (pci_vendors[n] == vendor)
127 			return pci_untokenstring(&pci_vendors[n+1], buf,
128 			    sizeof(buf));
129 
130 		/* Skip Tokens */
131 		n++;
132 		while (pci_vendors[n] != 0 && n < __arraycount(pci_vendors))
133 			n++;
134 	}
135 	return (NULL);
136 }
137 
138 const char *
139 pci_findproduct_real(pcireg_t id_reg)
140 {
141 	static char buf[256];
142 	pci_vendor_id_t vendor = PCI_VENDOR(id_reg);
143 	pci_product_id_t product = PCI_PRODUCT(id_reg);
144 	size_t n;
145 
146 	for (n = 0; n < __arraycount(pci_products); n++) {
147 		if (pci_products[n] == vendor && pci_products[n+1] == product)
148 			return pci_untokenstring(&pci_products[n+2], buf,
149 			    sizeof(buf));
150 
151 		/* Skip Tokens */
152 		n += 2;
153 		while (pci_products[n] != 0 && n < __arraycount(pci_products))
154 			n++;
155 	}
156 	return (NULL);
157 }
158 
159