Generic Error Codes¶
The ioctl can’t be handled because the device is in state where it can’t perform it. This could happen for example in case where device is sleeping and ioctl is performed to query statistics. It is also returned when the ioctl would need to wait for an event, but the device was opened in non-blocking mode.
The file descriptor is not a valid.
The ioctl can’t be handled because the device is busy. This is typically return while device is streaming, and an ioctl tried to change something that would affect the stream, or would require the usage of a hardware resource that was already allocated. The ioctl must not be retried without performing another action to fix the problem first (typically: stop the stream before retrying).
There was a failure while copying data from/to userspace, probably caused by an invalid pointer reference.
One or more of the ioctl parameters are invalid or out of the allowed range. This is a widely used error code. See the individual ioctl requests for specific causes.
Device not found or was removed.
There’s not enough memory to handle the desired operation.
The ioctl is not supported by the driver, actually meaning that the required functionality is not available, or the file descriptor is not for a media device.
On USB devices, the stream ioctl’s can return this error, meaning that this request would overcommit the usb bandwidth reserved for periodic transfers (up to 80% of the USB bandwidth).
Permission denied. Can be returned if the device needs write permission, or some special capabilities is needed (e. g. root)
I/O error. Typically used when there are problems communicating with a hardware device. This could indicate broken or flaky hardware. It’s a ‘Something is wrong, I give up!’ type of error.
No device corresponding to this device special file exists.
- This list is not exhaustive; ioctls may return other error codes. Since errors may have side effects such as a driver reset, applications should abort on unexpected errors, or otherwise assume that the device is in a bad state.
- Request-specific error codes are listed in the individual requests descriptions.
Linux kernel error codes and error pointers
In the Linux kernel, the maximum error code value is MAX_ERRNO, the error code is negative, and negative numbers are stored in the form of complement. The complement range of Arm32-bit system error code is 0xFFFFF000 — 0xFFFFFFFF. The complement range of Arm64 system error code is 0xFFFFFFFFFFFFF000- 0xFFFFFFFFFFFFFFFF.
The virtual address range of the Linux kernel of the Arm32-bit system is 0xC0000000 — 0xFFFFFFFF. The last page (with a page size of 4KB) is the reserved address, that is, the 0xFFFFF000 — 0xFFFFFFFF address range is the reserved address. If the kernel address is greater than 0xFFFFF000, it is an illegal address. Virtual address range of Linux kernel of Arm64 bit system: 0xffffff000000000000000000 — 0xffffffffffffff, 16 high is all 1. The last page (the page size is 4KB) is the reserved address, that is, the address range 0xFFFFFFFFFFFFF000 — 0xffffffffffffffffffffffff is the reserved address. If the kernel address is greater than 0xfffffffffff000, it is an illegal address.
IS_ERR_VALUE can judge whether the incoming value is an error code. Generally, it is rarely used directly. Pay attention to IS_ERR_VALUE cannot judge null pointer.
[include/linux/err.h] #define MAX_ERRNO 4095 #define IS_ERR_VALUE(x) unlikely((unsigned long)(void *)(x) >= (unsigned long)-MAX_ERRNO)
2.ERR_PTR
ERR_PTR converts the incoming error code into a pointer. The return value of some functions is a pointer, but a negative error code needs to be returned to indicate the cause of the error. Err can be used_ The PTR macro converts a negative error code into a pointer return. Is available for calling function_ Err determines whether the pointer is an error code. If it is an error code, PTR can be used_ The err macro converts the pointer to an error code.
[include/linux/err.h] static inline void * __must_check ERR_PTR(long error)
Here is ERR_PTR,IS_ERR,PTR_ Use case of err. ERR_PTR converts — ENOMEM error code to pointer return. IS_ERR determines whether the pointer is an error code, PTR_ERR converts the pin to an error code.
[drivers/input/touchscreen/ads7846.c] static const struct ads7846_platform_data *ads7846_probe_dt(struct device *dev) < . pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) return ERR_PTR(-ENOMEM); // Convert error code to pointer . >static int ads7846_probe(struct spi_device *spi) < . pdata = ads7846_probe_dt(&spi->dev); if (IS_ERR(pdata)) < // Determine whether the pointer is an error code err = PTR_ERR(pdata); // Convert pointer to error code goto err_free_mem; >. >
3.IS_ERR
IS_ERR determines whether the incoming pointer is an error code, and is is is called internally_ ERR_ Value macro, see section 1.2 for examples.
[include/linux/err.h] static inline bool __must_check IS_ERR(__force const void *ptr)
4.IS_ERR_OR_NULL
IS_ERR_OR_NULL determines whether the passed in pointer is a null pointer or an error code. In is_ ERR_ Based on the value macro, the judgment of null pointer is added.
[include/linux/err.h] static inline bool __must_check IS_ERR_OR_NULL(__force const void *ptr)
Likely and unlikely internally encapsulate the built-in functions of GCC__ builtin_expect, which is used to tell the compiler branch jump information. Like indicates that the result is likely to be true and unlikely indicates that the result is likely to be false. After obtaining this information, the compiler will make corresponding optimization to reduce the performance loss caused by jump__ builtin_ The first parameter of expect is the value to be judged, the second parameter represents the expected result, and 1 is true. 0 is false.
[include/linux/compiler.h] # define likely(x) __ builtin_ Expect (. (x), 1) / / most likely true # define unlikely(x) __ builtin_ Expect (. (x), 0) / / most likely false
5.ERR_CAST
ERR_CAST converts the pointer type of error code conversion to void * type. It is often used in situations where the pointer type of error code conversion is inconsistent with the pointer type returned by the function. Avoid compiler alarms.
[include/linux/err.h] static inline void *__must_check ERR_CAST(__force const void *ptr) < return (void *) ptr; /* cast away the const */ >
Here is ERR_CAST use case.
[include/linux/pinctrl/consumer.h] static inline struct pinctrl * __must_check devm_pinctrl_get_select( struct device *dev, const char *name) < struct pinctrl_state *s; // The type of s is different from the return value type . s = pinctrl_lookup_state(p, name); if (IS_ERR(s)) < // Determine whether the returned is an error code devm_pinctrl_put(p); return ERR_CAST(s); // Convert pointer to void * type and return >. > [drivers/pinctrl/core.c] struct pinctrl_state *pinctrl_lookup_state(struct pinctrl *p, const char *name) < struct pinctrl_state *state; state = find_state(p, name); if (!state) < . state = ERR_PTR(-ENODEV); // Convert error code to pointer return >return state; >
6.PTR_ERR_OR_ZERO
PTR_ERR_OR_ZERO determines whether the incoming pointer is an error code. If so, the pointer is converted into an error code and returned. If not, 0 is returned.
[include/linux/err.h] static inline int __must_check PTR_ERR_OR_ZERO(__force const void *ptr)
Posted by xiaoqiangemail at Nov 13, 2021 — 12:16 PM Tag: Linux kernel
Hot Categories
Hot Tags
- Java × 8678
- Python × 3398
- Algorithm × 2157
- Linux × 2069
- Javascript × 1932
- data structure × 1524
- Spring × 1497
- C++ × 1439
- MySQL × 1163
- Database × 1138
- Front-end × 1057
- Design Pattern × 1024