xref: /netbsd-src/sys/dev/dev_verbose.h (revision 74007e33ee94f1e0c4c6a9d698d39ab4de9f04cc)
1 /*	$NetBSD: dev_verbose.h,v 1.8 2021/06/29 21:03:36 pgoyette Exp $ */
2 
3 /*
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24 
25 #ifndef _DEV_DEV_VERBOSE_H_
26 #define	_DEV_DEV_VERBOSE_H_
27 
28 #ifdef _KERNEL
29 #include <sys/module_hook.h>
30 #endif
31 
32 const char *dev_findvendor(char *, size_t, const char *, size_t,
33 	const uint32_t *, size_t, uint32_t, const char *);
34 const char *dev_findproduct(char *, size_t, const char *, size_t,
35 	const uint32_t *, size_t, uint32_t, uint32_t, const char *);
36 
37 #define DEV_VERBOSE_COMMON_DEFINE(tag)					\
38 static const char *							\
39 tag ## _findvendor_real(char *buf, size_t len, uint32_t vendor)		\
40 {									\
41 	return dev_findvendor(buf, len, tag ## _words,			\
42 	    __arraycount(tag ## _words), tag ## _vendors,		\
43 	    __arraycount(tag ## _vendors), vendor, tag ## _id1_format);	\
44 }									\
45 									\
46 static const char *							\
47 tag ## _findproduct_real(char *buf, size_t len, uint32_t vendor,	\
48     uint32_t product)							\
49 {									\
50 	return dev_findproduct(buf, len, tag ## _words,			\
51 	    __arraycount(tag ## _words), tag ## _products,		\
52 	    __arraycount(tag ## _products), vendor, product,		\
53 	    tag ## _id2_format);					\
54 }									\
55 
56 #ifdef _KERNEL
57 
58 #define DEV_VERBOSE_KERNEL_DECLARE(tag)					\
59 MODULE_HOOK(tag ## _findvendor_hook, const char *,			\
60 	(char *, size_t, uint32_t));					\
61 MODULE_HOOK(tag ## _findproduct_hook, const char *,			\
62 	(char *, size_t, uint32_t, uint32_t));				\
63 extern int tag ## verbose_loaded;
64 
65 #define DEV_VERBOSE_MODULE_DEFINE(tag, deps)				\
66 DEV_VERBOSE_COMMON_DEFINE(tag)						\
67 DEV_VERBOSE_KERNEL_DECLARE(tag)						\
68 									\
69 static int								\
70 tag ## verbose_modcmd(modcmd_t cmd, void *arg)				\
71 {									\
72 									\
73 	switch (cmd) {							\
74 	case MODULE_CMD_INIT:						\
75 		MODULE_HOOK_SET(tag ## _findvendor_hook,		\
76 			tag ## _findvendor_real);			\
77 		MODULE_HOOK_SET(tag ## _findproduct_hook,		\
78 			tag ## _findproduct_real);			\
79 		tag ## verbose_loaded = 1;				\
80 		return 0;						\
81 	case MODULE_CMD_FINI:						\
82 		tag ## verbose_loaded = 0;				\
83 		MODULE_HOOK_UNSET(tag ## _findproduct_hook);		\
84 		MODULE_HOOK_UNSET(tag ## _findvendor_hook);		\
85 		return 0;						\
86 	default:							\
87 		return ENOTTY;						\
88 	}								\
89 }									\
90 MODULE(MODULE_CLASS_DRIVER, tag ## verbose, deps)
91 
92 #endif /* KERNEL */
93 
94 #define DEV_VERBOSE_DECLARE(tag)					\
95 extern const char * tag ## _findvendor(char *, size_t, uint32_t);	\
96 extern const char * tag ## _findproduct(char *, size_t, uint32_t, uint32_t)
97 
98 #if defined(_KERNEL)
99 
100 #define DEV_VERBOSE_DEFINE(tag)						\
101 DEV_VERBOSE_KERNEL_DECLARE(tag)						\
102 struct tag ## _findvendor_hook_t tag ## _findvendor_hook;		\
103 struct tag ## _findproduct_hook_t tag ## _findproduct_hook;		\
104 int tag ## verbose_loaded = 0;						\
105 									\
106 static void								\
107 tag ## _load_verbose(void)						\
108 {									\
109 									\
110 	if (tag ## verbose_loaded == 0)					\
111 		module_autoload(# tag "verbose", MODULE_CLASS_DRIVER);	\
112 }									\
113 									\
114 const char *								\
115 tag ## _findvendor(char *buf, size_t len, uint32_t vendor)		\
116 {									\
117 	const char *retval = NULL;					\
118 									\
119 	tag ## _load_verbose();						\
120 	MODULE_HOOK_CALL(tag ## _findvendor_hook, (buf, len, vendor),	\
121 		(snprintf(buf, len, tag ## _id1_format, vendor), NULL),	\
122 		retval);						\
123 	return retval;							\
124 }									\
125 									\
126 const char *								\
127 tag ## _findproduct(char *buf, size_t len, uint32_t vendor,		\
128     uint32_t product)							\
129 {									\
130 	const char *retval = NULL;					\
131 									\
132 	tag ## _load_verbose();						\
133 	MODULE_HOOK_CALL(tag ## _findproduct_hook,			\
134 		(buf, len, vendor, product),				\
135 		(snprintf(buf, len, tag ## _id2_format, product), NULL), \
136 		retval);						\
137 	return retval;							\
138 }									\
139 
140 #else	/* _KERNEL */
141 
142 #define DEV_VERBOSE_DEFINE(tag)						\
143 DEV_VERBOSE_COMMON_DEFINE(tag)						\
144 const char *tag ## _findvendor(char *buf, size_t len, uint32_t vendor)	\
145 {									\
146 									\
147 	return tag ## _findvendor_real(buf, len, vendor);		\
148 }									\
149 									\
150 const char *tag ## _findproduct(char *buf, size_t len, uint32_t vendor,	\
151 		uint32_t product)					\
152 {									\
153 									\
154 	return tag ## _findproduct_real(buf, len, vendor, product);	\
155 }
156 
157 #endif /* _KERNEL */
158 
159 #endif /* _DEV_DEV_VERBOSE_H_ */
160