xref: /freebsd/sys/sys/exterrvar.h (revision 295f10230903d54c700518467c4ea4492f5c4faa)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2025 The FreeBSD Foundation
5  * All rights reserved.
6  *
7  * This software were developed by Konstantin Belousov <kib@FreeBSD.org>
8  * under sponsorship from the FreeBSD Foundation.
9  */
10 
11 #ifndef _SYS_EXTERRVAR_H_
12 #define	_SYS_EXTERRVAR_H_
13 
14 #include <sys/_exterr.h>
15 #include <sys/_uexterror.h>
16 #include <sys/exterr_cat.h>
17 #ifdef EXTERR_CATEGORY_DYNAMIC
18 #include <sys/linker_set.h>
19 #endif
20 
21 #define	UEXTERROR_MAXLEN	256
22 
23 #define	UEXTERROR_VER		0x10010002
24 
25 #define	EXTERRCTL_ENABLE	1
26 #define	EXTERRCTL_DISABLE	2
27 #define	EXTERRCTL_UD		3
28 
29 #define	EXTERRCTLF_FORCE	0x00000001
30 
31 #ifdef _KERNEL
32 
33 struct exterr_cat {
34 	unsigned int	cat;
35 	const char	*file;
36 };
37 
38 struct thread;
39 
40 #ifdef EXTERR_CATEGORY_DYNAMIC
41 #ifdef EXTERR_STRINGS
42 static struct exterr_cat __dynamic_cat = { .file = EXTERR_CATEGORY_DYNAMIC };
43 DATA_WSET(exterr_cats, __dynamic_cat);
44 #define	EXTERR_CATEGORY	(__dynamic_cat.cat | EXTERR_CAT_SRC_KERN_DYNAMIC)
45 #else
46 #define	EXTERR_CATEGORY	EXTERR_CAT_NONE
47 #endif
48 #endif
49 
50 #ifndef EXTERR_CATEGORY
51 #error "Specify error category before including sys/exterrvar.h"
52 #endif
53 
54 #ifdef	EXTERR_STRINGS
55 #define	SET_ERROR_MSG(mmsg)	(mmsg)
56 #else
57 #define	SET_ERROR_MSG(mmsg)	NULL
58 #endif
59 
60 #define	_SET_ERROR2_KE(kep, eerror, mmsg, pp1, pp2)	({		\
61 	(kep)->error = (eerror);					\
62 	(kep)->cat = EXTERR_CATEGORY;					\
63 	(kep)->msg = SET_ERROR_MSG(mmsg);				\
64 	(kep)->p1 = (pp1);						\
65 	(kep)->p2 = (pp2);						\
66 	(kep)->src_line = __LINE__;					\
67 	(kep)->error;							\
68 })
69 #define	_SET_ERROR0_KE(kep, eerror, mmsg)				\
70 	_SET_ERROR2_KE(kep, eerror, mmsg, 0, 0)
71 #define	_SET_ERROR1_KE(kep, eerror, mmsg, pp1)				\
72 	_SET_ERROR2_KE(kep, eerror, mmsg, pp1, 0)
73 
74 #define	_EXTERROR_MACRO_KE(kep, eerror, mmsg, _1, _2, NAME, ...)	\
75 	NAME
76 #define	EXTERROR_KE(...)						\
77 	_EXTERROR_MACRO_KE(__VA_ARGS__, _SET_ERROR2_KE, _SET_ERROR1_KE,	\
78 	    _SET_ERROR0_KE)(__VA_ARGS__)
79 
80 #define	_SET_ERROR2(eerror, mmsg, pp1, pp2)				\
81 	exterr_set(eerror, EXTERR_CATEGORY, SET_ERROR_MSG(mmsg),	\
82 	    (uint64ptr_t)(pp1), (uint64ptr_t)(pp2), __LINE__)
83 #define	_SET_ERROR0(eerror, mmsg)	_SET_ERROR2(eerror, mmsg, 0, 0)
84 #define	_SET_ERROR1(eerror, mmsg, pp1)	_SET_ERROR2(eerror, mmsg, pp1, 0)
85 
86 #define	_EXTERROR_MACRO(eerror, mmsg, _1, _2, NAME, ...)		\
87 	NAME
88 #define	EXTERROR(...)							\
89 	_EXTERROR_MACRO(__VA_ARGS__, _SET_ERROR2, _SET_ERROR1,		\
90 	    _SET_ERROR0)(__VA_ARGS__)
91 
92 void exterr_clear(struct kexterr *ke);
93 void exterr_db_print(struct kexterr *ke);
94 int exterr_set_from(const struct kexterr *ke);
95 int exterr_set(int eerror, int category, const char *mmsg, uint64ptr_t pp1,
96     uint64ptr_t pp2, int line);
97 int exterr_to_ue(struct thread *td, struct uexterror *ue);
98 void ktrexterr(struct thread *td);
99 void exterr_cat_register_module(struct exterr_cat **start,
100     struct exterr_cat **stop);
101 void exterr_cat_unregister_module(struct exterr_cat **start,
102     struct exterr_cat **stop);
103 
104 #else	/* !_KERNEL */
105 
106 #include <sys/types.h>
107 
108 __BEGIN_DECLS
109 int exterrctl(u_int op, u_int flags, void *ptr);
110 __END_DECLS
111 
112 #endif	/* _KERNEL */
113 
114 #endif
115