IS_ERR_OR_NULL
时间: 2023-08-30 14:10:08 浏览: 57
IS_ERR_OR_NULL是一个宏定义,用于判断一个指针是否为NULL或者是一个错误码。在Linux内核中,错误码通常被定义为一个负整数,而指针则被认为是非负整数。因此,IS_ERR_OR_NULL宏的实现如下:
```
#define IS_ERR_OR_NULL(ptr) (!ptr || IS_ERR(ptr))
```
其中,IS_ERR宏用于判断一个指针是否是一个错误码,其实现如下:
```
#define IS_ERR_VALUE(x) unlikely((x) >= (unsigned long)-MAX_ERRNO)
#define IS_ERR_PTR(x) unlikely(IS_ERR_VALUE((unsigned long)x)))
#define IS_ERR(x) unlikely((x) == NULL || IS_ERR_PTR(x))
```
在这里,unlikely是一个编译器指令,用于提示编译器,这个分支的执行概率比其它分支要低,以便优化代码的执行效率。因此,IS_ERR_OR_NULL宏的意义是,如果指针为空,则返回真;否则,如果指针是一个错误码,则返回真;否则,返回假。
相关问题
device->dbuf_q = is_init_dbuf_q(); if (IS_ERR_OR_NULL(device->dbuf_q)) { merr("is_resource_get is fail", device); goto p_err; } ret = is_devicemgr_open(device->devicemgr, (void *)device, IS_DEVICE_ISCHAIN); if (ret) { err("is_devicemgr_open is fail(%d)", ret); goto p_err; } device->pii = pablo_interface_irta_get(device->instance); if (device->pii) pablo_interface_irta_open(device->pii, device); /* for mediaserver force close */ ret = is_resource_get(device->resourcemgr, RESOURCE_TYPE_ISCHAIN); if (ret) { merr("is_resource_get is fail", device); goto p_err; }
这段代码是一个初始化函数,其中包含了一些设备的初始化操作,具体解释如下:
1. 首先,该函数会调用 is_init_dbuf_q() 函数初始化一个双缓冲队列,并将其赋值给设备结构体的 dbuf_q 成员变量。
2. 然后,该函数会检查 dbuf_q 是否初始化成功,如果出错或者返回值为 NULL,则会输出一个错误信息并跳转到 p_err 标签处。
3. 接着,该函数会调用 is_devicemgr_open() 函数打开设备管理器,并将设备结构体的指针和 IS_DEVICE_ISCHAIN 标志作为参数传递进去。
4. 如果 is_devicemgr_open() 函数返回值不为 0,则会输出一个错误信息并跳转到 p_err 标签处。
5. 接下来,该函数会调用 pablo_interface_irta_get() 函数获取一个 IR interface 的实例,并将其赋值给设备结构体的 pii 成员变量。
6. 如果 pii 不为 NULL,则会调用 pablo_interface_irta_open() 函数打开
解释一下这段代码int drm_of_find_panel_or_bridge(const struct device_node *np, int port, int endpoint, struct drm_panel **panel, struct drm_bridge **bridge) { int ret = -EPROBE_DEFER; struct device_node *remote; if (!panel && !bridge) return -EINVAL; if (panel) *panel = NULL; /* * of_graph_get_remote_node() produces a noisy error message if port * node isn't found and the absence of the port is a legit case here, * so at first we silently check whether graph presents in the * device-tree node. */ if (!of_graph_is_present(np)) return -ENODEV; remote = of_graph_get_remote_node(np, port, endpoint); if (!remote) return -ENODEV; if (panel) { *panel = of_drm_find_panel(remote); if (!IS_ERR(*panel)) ret = 0; else *panel = NULL; } /* No panel found yet, check for a bridge next. */ if (bridge) { if (ret) { *bridge = of_drm_find_bridge(remote); if (*bridge) ret = 0; } else { *bridge = NULL; } } of_node_put(remote); return ret; }
这段代码是 Linux 内核 DRM 子系统中的函数 `drm_of_find_panel_or_bridge` 的实现代码,该函数用于查找设备树节点下的面板或桥接器。
该函数的参数 `np` 是一个指向设备树节点的指针,`port` 和 `endpoint` 是设备树节点的端口和端点号,`panel` 和 `bridge` 分别是指向 drm_panel 和 drm_bridge 结构体指针的指针。函数返回一个整数值,表示查找结果。
在函数实现中,首先判断传入的参数 `panel` 和 `bridge` 是否都为空指针,如果是则返回 -EINVAL。接着,使用 `of_graph_is_present` 函数判断设备树节点中是否存在 graph 节点,如果不存在则返回 -ENODEV。然后,调用 `of_graph_get_remote_node` 函数获取指定端口和端点号的远程节点,如果获取失败则返回 -ENODEV。
接着,如果 `panel` 不为空,则调用 `of_drm_find_panel` 函数查找面板节点并将结果存入 `panel` 指针中,如果查找成功则将返回值 `ret` 设为 0,否则将 `panel` 指针设为 NULL。如果 `panel` 为空,则不查找面板节点。
如果没有找到面板节点,则继续查找桥接器节点。如果 `bridge` 不为空,则先判断 `ret` 的值,如果不为 0,则调用 `of_drm_find_bridge` 函数查找桥接器节点并将结果存入 `bridge` 指针中,如果查找成功则将返回值 `ret` 设为 0,否则将 `bridge` 指针设为 NULL。如果 `bridge` 为空,则不查找桥接器节点。
最后,使用 `of_node_put` 函数释放获取到的远程节点,最终返回查找结果。