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