队列模型 - 📘 一、Figure 94(续)——通用命令状态码定义(SCT = 0h) (第109页)
NVME2.0协议解读 1 min read

队列模型 - 📘 一、Figure 94(续)——通用命令状态码定义(SCT = 0h) (第109页)

Blog Author

我们继续深入讲解 NVM Express® Base Specification, revision 2.0b 第 98 页,本页继续列出 通用命令状态码(Generic Command Status) 的具体值和含义。

本页重点围绕: - SGL(Scatter-Gather List)使用错误 - PRP(Physical Region Page)偏移问题 - 控制器内存使用 - 权限控制拒绝 - Keep Alive 超时 等典型错误场景的反馈机制。


📘 一、Figure 94(续)——通用命令状态码定义(SCT = 0h)

✅ 状态码清单(0Dh19h

代码 名称 描述
0Dh Invalid SGL Segment Descriptor 无效的 SGL 段描述符,可能出现如下情况:
① Last Segment 包含 Segment 或另一个 Last Segment;
② Last Segment 长度非法(0h 或 1h,或非 16 的倍数);
③ 地址未 Qword 对齐。
0Eh Invalid Number of SGL Descriptors SGL 的数量不符合规范。比如 Segment Descriptor 不是段中最后一个描述符,或命令胶囊中的 SGL 排布非法。
0Fh Data SGL Length Invalid 数据类型 SGL 长度非法:
① 太短;
② 太长,超出控制器支持范围(参见 Identify Controller 中 SGL Support 字段)。
10h Metadata SGL Length Invalid 元数据类型 SGL 长度非法。
11h SGL Descriptor Type Invalid SGL 描述符类型或其类型-子类型组合为控制器不支持的值。
12h Invalid Use of Controller Memory Buffer 控制器内存缓冲区(Controller Memory Buffer)的使用不被支持。参考 §8.3。
13h PRP Offset Invalid PRP 条目的偏移字段非法:
① 第一项后出现非零偏移;
② 偏移不是 dword 对齐(低两位应为 00b)。
14h Atomic Write Unit Exceeded 原子写单元大小被超出。参考适用的 I/O Command Set 说明(如 NVM 或 ZNS)。
该状态码是 I/O Command Set Specific。
15h Operation Denied 操作被拒绝,原因可能为缺乏访问权限(例如未通过认证机制,如 TCG)。对于读写类命令,更推荐使用 Access Denied 状态码。
16h SGL Offset Invalid SGL 描述符中的偏移字段非法。常见于 NVMe-oF 数据胶囊(Capsule)中。
17h Reserved 保留状态码,当前未使用。
18h Host Identifier Inconsistent Format NVM 子系统发现有控制器在使用不同格式的 Host Identifier(64-bit 和 128-bit 同时存在)。
19h Keep Alive Timer Expired 控制器未收到主机的 Keep Alive 命令,计时器超时。

🧩 二、重点状态码深入解析

1️⃣ 0DhInvalid SGL Segment Descriptor

此错误码在使用复杂的 SGL 结构(如 Segment、Last Segment)时出现频率较高。常见场景包括: - Segment 指向的段内部格式不对; - Segment 长度非法(如不为 16 的整数倍); - 描述符地址未 Qword 对齐(即低三位不为 000b)。

📌 可通过调试 SGL 结构或对齐方式排查。


2️⃣ 0Fh / 10hSGL 长度非法

  • 控制器对 数据 / 元数据 SGL 的长度 有限制。
  • 如果长度过短或大于 Identify Controller 中允许的传输大小,将触发该错误。
  • 检查 SGL Descriptor 中的 Length 字段是否与传输期望值一致。

3️⃣ 12hInvalid Use of Controller Memory Buffer

出现此错误说明主机尝试访问控制器内部缓冲区(CMB)时违反了规定。

常见原因: - 控制器未开启 CMB 支持,但主机试图访问; - 主机对缓冲区偏移或长度设置错误。


4️⃣ 13hPRP Offset Invalid

此错误多见于 PRP 的第二个条目中:

错误原因 说明
非首个 PRP 条目存在 offset 仅首个 PRP 条目可带 offset(偏移值)
offset 非 dword 对齐 例如 offset = 3,低两位 11b,应为 00b

5️⃣ 14hAtomic Write Unit Exceeded

该状态码适用于对存储介质要求“原子写入”的命令集,如: - NVM - ZNS(Zone Namespace)

控制器定义的 AUL(Atomic Write Unit Limit)不能被越界。典型场景如: - 跨越两个原子单元的写操作; - 写入未对齐。


6️⃣ 15hOperation Denied

操作被控制器拒绝,原因: - 当前命令需要权限控制; - 主机未进行认证(如未通过 TCG 安全认证协议); - 命令违反了访问控制策略。


7️⃣ 19hKeep Alive Timer Expired

  • 控制器在设定的超时时间内 未收到主机 Keep Alive 消息
  • 会导致会话断开或控制器进入非活跃状态;
  • NVMe over Fabrics 中尤为常见,主机需周期性发送 Keep Alive。

🧠 总结与核心要点

状态码 代表错误 检查建议
0Dh ~ 11h SGL 类型/结构/长度错误 检查 SGL 描述符是否格式合法、对齐、长度合理
12h 控制器内存缓冲区使用错误 检查是否启用了 CMB,访问是否合规
13h PRP 偏移对齐错误 仅 PRP1 可设置 offset,且必须 dword 对齐
14h 原子写超限 保证写入命令不越界原子单元
15h 权限不足 检查是否正确认证,或访问权限设置
18h Host ID 不一致 保证所有控制器使用相同格式(64-bit 或 128-bit)
19h Keep Alive 超时 主机需定时发送 Keep Alive 命令以维持连接状态

如果你希望我继续:

  • ✅ 继续分析 1Ah 及后续的通用状态码(Figure 94 的剩余部分)
  • ✅ 讲解 I/O Command Specific 状态码(SCT = 1h / 2h)
  • ✅ 展示使用示例:如何根据 SCT + SC 分析日志中命令失败的根因

请告诉我你最关心哪一部分内容?我可以逐步带你深入理解和应用这些状态反馈机制。