Skip to the content.

I2C/SMBUS Fault Codes

这是 I2C/SMBus 堆栈中使用故障代码的最重要约定的摘要。

1. A “Fault” is not always an “Error”

并非所有故障报告都意味着错误; “页面错误”应该是一个熟悉的例子。 软件通常会在发生瞬时故障后重试幂等操作。 在某些情况下可能有更合适的恢复方案,例如重新初始化(也可能是重置)。 这样恢复后,由故障报告触发,就没有错误了。

以类似的方式,有时“故障”代码只是报告一个操作的一个定义结果……它并不表明有任何问题,只是结果不在“黄金路径”上。

简而言之,您的 I2C 驱动程序代码可能需要知道这些代码才能正确响应。 其他代码可能需要依赖您的代码报告正确的故障代码,以便它能够(反过来)正确运行。

2. I2C and SMBus fault codes

大多数调用都会以负数的形式返回这些值,零或某个正数表示无故障返回。 尽管大多数 Linux 系统使用 <asm-generic/errno*.h> 编号,但与这些符号关联的具体编号因体系结构而异。

请注意,此处的描述并不详尽。 还有可能返回其他代码,以及应返回这些代码的其他情况。 但是,驱动程序不应在这些情况下返回其他代码(除非硬件不提供唯一的故障报告)。

此外,适配器探测方法返回的代码遵循特定于其主机总线(例如 PCI 或平台总线)的规则。

EAFNOSUPPORT

 当请求使用 10 位地址时,由不支持 10 位地址的 I2C 适配器返回。

EAGAIN

 当 I2C 适配器在主机传输模式下失去仲裁时返回:其他主机同时传输不同的数据。

 当某些任务已在使用该 I2C 总线执行其他操作时,尝试在原子上下文中调用 I2C 操作时也会返回。

EBADMSG

 当收到无效的数据包错误代码字节时,由 SMBus 逻辑返回。 该代码是覆盖事务中所有字节的 CRC,并在终止 STOP 之前发送。 仅在读取事务时报告此错误; SMBus 从机可能有办法报告主机写入时的 PEC 不匹配情况。 请注意,即使正在使用 PEC,您也不应该依赖它们作为检测不正确数据传输的唯一方法。

EBUSY

 当总线繁忙时间超过允许的时间时,由 SMBus 适配器返回。 这通常表明某些设备(可能是 SMBus 适配器)需要某些故障恢复(例如重置),或者尝试重置但失败。

EINVAL

 这个相当模糊的错误意味着在启动任何 I/O 操作之前已检测到无效参数。 尽可能使用更具体的故障代码。

EIO

 这个相当模糊的错误意味着执行 I/O 操作时出现了问题。 尽可能使用更具体的故障代码。

ENODEV

 由驱动程序probe()方法返回。 这比 ENXIO 更具体一些,这意味着问题不在于地址,而在于在那里找到的设备。 驱动程序探针可以验证设备返回正确的响应,并根据需要返回该响应。 (驱动程序核心将警告除 ENXIO 和 ENODEV 之外的探针故障。)

ENOMEM

 由任何在需要时无法分配内存的组件返回。

ENXIO

 由 I2C 适配器返回,指示传输的地址阶段未获得 ACK。 虽然这可能只是意味着 I2C 设备暂时没有响应,但通常意味着该地址没有任何监听。

 由驱动程序probe()方法返回,表明它们没有找到可以绑定的设备。 (也可以使用 ENODEV。)

EOPNOTSUPP

 当适配器被要求执行它不支持或不能支持的操作时,由适配器返回。

 例如,当要求不支持 SMBus 块传输的适配器执行传输时,将返回此信息。 在这种情况下,发出该请求的驱动程序应该在发出块传输请求之前验证功能是否受支持。

 同样,如果 I2C 适配器无法执行所有合法的 I2C 消息,则当被要求执行它无法执行的事务时,它应该返回此消息。 (这些限制在适配器的功能掩码中看不到,因为假设如果适配器支持 I2C,则它支持所有 I2C。)

EPROTO

 当从机不符合相关 I2C 或 SMBus(或芯片特定)协议规范时返回。 一种情况是 SMBus 块数据响应(来自 SMBus 从设备)的长度超出 1-32 字节范围。

ESHUTDOWN

 当使用已挂起的适配器请求传输时返回。

ETIMEDOUT

 当操作花费太多时间并在完成之前中止时,驱动程序会返回此信息。

 当操作花费的时间超过 SMBus 规范允许的时间时,SMBus 适配器可能会返回它; 例如,当从设备将时钟拉得太长时。 I2C 没有此类超时,但 I2C 适配器施加一些任意限制(比 SMBus 长得多!)也是正常的。