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