xref: /OK3568_Linux_fs/kernel/tools/include/linux/err.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun #ifndef __TOOLS_LINUX_ERR_H
3*4882a593Smuzhiyun #define __TOOLS_LINUX_ERR_H
4*4882a593Smuzhiyun 
5*4882a593Smuzhiyun #include <linux/compiler.h>
6*4882a593Smuzhiyun #include <linux/types.h>
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #include <asm/errno.h>
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun /*
11*4882a593Smuzhiyun  * Original kernel header comment:
12*4882a593Smuzhiyun  *
13*4882a593Smuzhiyun  * Kernel pointers have redundant information, so we can use a
14*4882a593Smuzhiyun  * scheme where we can return either an error code or a normal
15*4882a593Smuzhiyun  * pointer with the same return value.
16*4882a593Smuzhiyun  *
17*4882a593Smuzhiyun  * This should be a per-architecture thing, to allow different
18*4882a593Smuzhiyun  * error and pointer decisions.
19*4882a593Smuzhiyun  *
20*4882a593Smuzhiyun  * Userspace note:
21*4882a593Smuzhiyun  * The same principle works for userspace, because 'error' pointers
22*4882a593Smuzhiyun  * fall down to the unused hole far from user space, as described
23*4882a593Smuzhiyun  * in Documentation/x86/x86_64/mm.rst for x86_64 arch:
24*4882a593Smuzhiyun  *
25*4882a593Smuzhiyun  * 0000000000000000 - 00007fffffffffff (=47 bits) user space, different per mm hole caused by [48:63] sign extension
26*4882a593Smuzhiyun  * ffffffffffe00000 - ffffffffffffffff (=2 MB) unused hole
27*4882a593Smuzhiyun  *
28*4882a593Smuzhiyun  * It should be the same case for other architectures, because
29*4882a593Smuzhiyun  * this code is used in generic kernel code.
30*4882a593Smuzhiyun  */
31*4882a593Smuzhiyun #define MAX_ERRNO	4095
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun #define IS_ERR_VALUE(x) unlikely((x) >= (unsigned long)-MAX_ERRNO)
34*4882a593Smuzhiyun 
ERR_PTR(long error_)35*4882a593Smuzhiyun static inline void * __must_check ERR_PTR(long error_)
36*4882a593Smuzhiyun {
37*4882a593Smuzhiyun 	return (void *) error_;
38*4882a593Smuzhiyun }
39*4882a593Smuzhiyun 
PTR_ERR(__force const void * ptr)40*4882a593Smuzhiyun static inline long __must_check PTR_ERR(__force const void *ptr)
41*4882a593Smuzhiyun {
42*4882a593Smuzhiyun 	return (long) ptr;
43*4882a593Smuzhiyun }
44*4882a593Smuzhiyun 
IS_ERR(__force const void * ptr)45*4882a593Smuzhiyun static inline bool __must_check IS_ERR(__force const void *ptr)
46*4882a593Smuzhiyun {
47*4882a593Smuzhiyun 	return IS_ERR_VALUE((unsigned long)ptr);
48*4882a593Smuzhiyun }
49*4882a593Smuzhiyun 
IS_ERR_OR_NULL(__force const void * ptr)50*4882a593Smuzhiyun static inline bool __must_check IS_ERR_OR_NULL(__force const void *ptr)
51*4882a593Smuzhiyun {
52*4882a593Smuzhiyun 	return unlikely(!ptr) || IS_ERR_VALUE((unsigned long)ptr);
53*4882a593Smuzhiyun }
54*4882a593Smuzhiyun 
PTR_ERR_OR_ZERO(__force const void * ptr)55*4882a593Smuzhiyun static inline int __must_check PTR_ERR_OR_ZERO(__force const void *ptr)
56*4882a593Smuzhiyun {
57*4882a593Smuzhiyun 	if (IS_ERR(ptr))
58*4882a593Smuzhiyun 		return PTR_ERR(ptr);
59*4882a593Smuzhiyun 	else
60*4882a593Smuzhiyun 		return 0;
61*4882a593Smuzhiyun }
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun /**
64*4882a593Smuzhiyun  * ERR_CAST - Explicitly cast an error-valued pointer to another pointer type
65*4882a593Smuzhiyun  * @ptr: The pointer to cast.
66*4882a593Smuzhiyun  *
67*4882a593Smuzhiyun  * Explicitly cast an error-valued pointer to another pointer type in such a
68*4882a593Smuzhiyun  * way as to make it clear that's what's going on.
69*4882a593Smuzhiyun  */
ERR_CAST(__force const void * ptr)70*4882a593Smuzhiyun static inline void * __must_check ERR_CAST(__force const void *ptr)
71*4882a593Smuzhiyun {
72*4882a593Smuzhiyun 	/* cast away the const */
73*4882a593Smuzhiyun 	return (void *) ptr;
74*4882a593Smuzhiyun }
75*4882a593Smuzhiyun #endif /* _LINUX_ERR_H */
76