4.6 Completion Queue Entry Completion Queue中的一个Entry至少是16个字节。图26表述了这16个字节的数据结构Dword0的内容在每种不同命令中可能不一样。如果一个命令使用了Dword0,则这个Dword0的定义包含在了命令的定义里面。如果命令没有使用Dword0。那么这一字段被保留。Dword1时保留的。Dword2在图27中定义了,Dword3在图28中定义。将来可能新增的IO命令会使用另外一种Completion Queue Entry的格式和大小。 如果一个Completion Queue Entry经过了多次写入操作,则Phase Tag位应该在最后一次写入Completion Queue Entry时被更新。 图26:Completion Queue Entry Layout-Admin and NVM Command Set
| | DW0 | Command Specific | DW1 | Reserved | DW2 | SQ Identifier | SQ Head Pointer | DW3 | Status Field | P | Command Identifier | | | | |
图27:Completion Queue Entry : DW2
Bit | Description | 31:16 | SQ Identifier(SQID):此字段代表了相关联的SQ。当有超过1个SQ和此CQ相关联时,此字段决定了CQ中的命令是与哪一个SQ相对应。 | 15:00 | SQ Head Pointer(SQHD):代表了在SQID字段中指出的SQ Head指针值。这被用来代表Host中哪一个SQ Entries已经被完成而且此Entry可以被再次使用。 |
图28:Completion Queue Entry : DW3
Bit | Description | 31:17 | Status Field(SF):代表了命令被完成的状态,参见4.6.1 | 16 | PhaseTag(P):这一位是当前Completion Queue Entry是否是最新的Entry.所有Completion Queue Entries的Phase Tag的值在CC.EN被设置为1之前都应该被设置为0。当Controller将Entry放入Completion Queue中时,Controller应该将Phase Tag翻转以便让Host识别出这是一个新加入的Entry。需要明确的是,在CC.EN为1之后第一次CQ Entries被发送进Queue时,他们的Phase Tag都应该被设置为1,当Controller使用过整个Queue并绕回了Queue的顶部时,第二次将CQ Entries发送进Queue应该将Phase Tag全部设置为0,Phase Tag的值每次进入Completion Queue时都应被翻转。 | 15:00 | Command Identifier(CID):本字段代表了被完成命令的ID。这个ID是Host分配给Submission Queue中的命令ID。这一部分和SQID组合的话可以得到一个独一无二的命令ID。同一时刻被请求的最大数量是64K。 |
4.6.1 Status Field Definition Status Field字段定义了Completion Queue Entry中的命令完成状态,图29定义了其结构。 Status Field为0代表了命令成功完成,没有严重的或者不严重的错误情况。 如果命令由于多种原因没有成功完成,那么在Status Code字段应该由厂商添加状态码。 图29:Completion Queue Entry : Status Field
Bit | Description | 31 | Do Not Retry(DNR):如果设置为1,则表示在此NVM subsystem中如果任何一个Controller对一个命令进行了重新申请,那么重新申请来的命令将会是一个失败状态。如果此位设置为0,表示如果重新申请,则这个命令可能是成功的。 如果一个命令由于time Limited Error Recover被Abort掉了(5.21.1.5),那么这一部分应被清0.如果SCT和SC字段被清0了,那么这一位也应被清0。 | 30 | More(M):如果设置为1,这个命令的更多状态信息作为Error Information的一部分在使用Get Log Page命令的时候被返回。如果清0了,对于这个命令没有更多的状态信息。参见5.14.1.1。 | 29:28 | Reserved | 27:25 | Status Code Type(SCT):代表了Completion Queue Entry的Status Code Type,这个Type是由Controller返回的。 | 24:17 | Status Code(SC):代表了这条命令的任何状态或者错误信息的状态码。 |
4.6.1.1 Status Code Type(SCT) 图30是Status Code Type的值和描述。 图30:Status Code-Status Code Type Values
Value | Description | 0h | Generic Command Status: Indicates that the command specified by the Command and Submission Queue identifiers in the completion queue entry has completed. These status values are generic across all command types, and include such conditions as success, opcode not supported, and invalid field. | 1h | Command Specific Status: Indicates a status value that is specific to a particular command opcode. These values may indicate additional processing is required. Status values such as invalid firmware image or exceeded maximum number of queues is reported with this type. | 2h | Media and Data Integrity Errors: Any media specific errors that occur in the NVM or data integrity type errors shall be of this type. | 3h – 6h | Reserved | 7h | Vendor Specific |
4.6.1.2 Status Code(SC) Completion Queue Entry中的Status Code(SC)里包含了很多Completion命令的完成状态细节。 每一个Status Code值都包含在以下三种范围内。 00h-7Fh:用于Admin命令或者多重命令。 80h-BFh:用于IO命令。 C0h-FFh:厂商自定义Status Code。 除非另有说明,Controller返回Status Code时,应该上面的状态中选择. 4.6.1.2.1 Generic Command Status Definition 图31:Status Codes-Generic Command Status Values
Value | Description | 00h | Successful Completion: The command completed without error. | 01h | Invalid Command Opcode: A reserved coded value or an unsupported value in the command opcode field. | 02h | Invalid Field in Command: A reserved coded value or an unsupported value in a defined field (other than the opcode field). This status code should be used unless another status code is explicitly specified for a particular condition. The field may be in the command parameters as part of the Submission Queue Entry or in data structures pointed to by the command parameters. | 03h | Command ID Conflict: The command identifier is already in use. Note: It is implementation specific how many commands are searched for a conflict. | 04h | Data Transfer Error: Transferring the data or metadata associated with a command had an error. | 05h | Commands Aborted due to Power Loss Notification: Indicates that the command was aborted due to a power loss notification. | 06h | Internal Error: The command was not completed successfully due to an internal error. Details on the internal device error are available to report as an asynchronous event. Refer toFigure 47 for Internal Error Asynchronous Event Information. | 07h | Command Abort Requested: The command was aborted due to a Command Abort command being received that specified the Submission Queue Identifier and Command Identifier of this command. | 08h | Command Aborted due to SQ Deletion: The command was aborted due to a Delete I/O Submission Queue request received for the Submission Queue to which the command was submitted. | 09h | Command Aborted due to Failed Fused Command: The command was aborted due to the other command in a fused operation failing. | 0Ah | Command Aborted due to Missing Fused Command: The Submission Queue does not contain the first command followed by the second command for a Fused Operation (refer to Figure 10). | 0Bh | Invalid Namespace or Format: The namespace or the format of that namespace is invalid. | 0Ch | Command Sequence Error: The command was aborted due to a protocol violation in a multi-command sequence (e.g. a violation of the Security Send and Security Receive sequencing rules in the TCG Storage Synchronous Interface Communications protocol (refer to TCG Storage Architecture Core Specification)). | 0Dh | Invalid SGL Segment Descriptor: The command includes an invalid SGL Last Segment or SGL Segment descriptor. This may occur when the SGL segment pointed to by an SGL Last Segment descriptor contains an SGL Segment descriptor or an SGL Last Segment descriptor or an SGL Segment descriptor. This may occur when an SGL Last Segment descriptor contains an invalid length (i.e., a length of zero or one that is not a multiple of 16). | 0Eh | Invalid Number of SGL Descriptors: There is an SGL Last Segment descriptor or an SGL Segment descriptor in a location other than the last descriptor of a segment based on the length indicated. | 0Fh | Data SGL Length Invalid: This may occur if the length of a Data SGL is too short. This may occur if the length of a Data SGL is too long and the controller does not support SGL transfers longer than the amount of data to be transferred as indicated in the SGL Support field of the Identify Controller data structure. | 10h | Metadata SGL Length Invalid: This may occur if the length of a Metadata SGL is too short. This may occur if the length of a Metadata SGL is too long and the controller does not support SGL transfers longer than the amount of data to be transferred as indicated in the SGL Support field of the Identify Controller data structure. | 11h | SGL Descriptor Type Invalid: The type of an SGL Descriptor is a type that is not supported by the controller. | 12h | Invalid Use of Controller Memory Buffer: The attempted use of the Controller Memory Buffer is not supported by the controller. Refer to section 4.7. | 13h | PRP Offset Invalid: The Offset field for a PRP entry is invalid. This may occur when there is a PRP entry with a non-zero offset after the first entry or when the Offset field in any PRP entry is not Dword aligned (i.e., bits 1:0 are not cleared to 00b). | 14h | Atomic Write Unit Exceeded: The length specified exceeds the atomic write unit size. | 15h | Operation Denied: The command was denied due to lack of access rights. Refer to the appropriate security specification (e.g., TCG Storage Interface Interactions Specification). For media access commands, the Access Denied status code should be used instead. | 16h | SGL Offset Invalid: The offset specified in a descriptor is invalid. This may occur when using capsules for data transfers in NVMe over Fabrics implementations and an invalid offset in the capsule is specified. | 17h | Reserved | 18h | Host Identifier Inconsistent Format: The NVM subsystem detected the simultaneous use of 64-bit and 128-bit Host Identifier values on different controllers. | 19h | Keep Alive Timeout Expired: The Keep Alive Timeout expired. | 1Ah | Keep Alive Timeout Invalid: The Keep Alive Timeout value specified is invalid. This may be due to an attempt to specify a value of 0h on a transport that requires Keep Alive to be enabled. This may be due to the value specified being too large for the associated NVMe Transport as defined in the NVMe Transport binding specification. | 1Bh | Command Aborted due to Preempt and Abort: The command was aborted due to a Reservation Acquire command with the Reservation Acquire Action (RACQA) set to 010b (Preempt and Abort). | 1Ch | Sanitize Failed: The most recent sanitize operation failed and no recovery action has been successfully completed. | 1Dh | Sanitize In Progress: The requested function (e.g., command) is prohibited while a sanitize operation is in progress. Refer to section 8.15.1. | 1Eh | SGL Data Block Granularity Invalid: The Address alignment or Length granularity for an SGL Data Block descriptor is invalid. This may occur when a controller supports Dword granularity only and the lower two bits of the Address or Length are not cleared to 00b. NOTE: An implementation compliant to revision 1.2.1 or earlier may use the status code value of 15h to indicate SGL Data Block Granularity Invalid. | 1Fh | Command Not Supported for Queue in CMB: The implementation does not support submission of the command to a Submission Queue in the Controller Memory Buffer or command completion to a Completion Queue in the Controller Memory Buffer. NOTE: Revision 1.3 uses this status code only for Sanitize commands. | 20h – 7Fh | Reserved | 80h – BFh | I/O Command Set Specific
80h | LBA Out of Range: The command references an LBA that exceeds the size of the namespace. | 81h | Capacity Exceeded: Execution of the command has caused the capacity of the namespace to be exceeded. This error occurs when the Namespace Utilization exceeds the Namespace Capacity, as reported in Figure 109. | 82h | Namespace Not Ready: The namespace is not ready to be accessed. The Do Not Retry bit indicates whether re-issuing the command at a later time may succeed. | 83h | Reservation Conflict: The command was aborted due to a conflict with a reservation held on the accessed namespace. Refer to section 8.8. | 84h | Format In Progress: A Format NVM command is in progress on the namespace. The Do Not Retry bit shall be cleared to ‘0’ to indicate that the command may succeed if it is resubmitted. | 85h – BFh | Reserved |
| C0h – FFh | Vendor Specific |
4.6.1.2.2 Command Specific Errors Definition 图33:Status Code-Command Specific Status Values
Value | Description | Commands Affected | 00h | Completion Queue Invalid | Create I/O Submission Queue | 01h | Invalid Queue Identifier | Create I/O Submission Queue, Create I/O Completion Queue, Delete I/O Completion Queue, Delete I/O Submission Queue | 02h | Invalid Queue Size | Create I/O Submission Queue, Create I/O Completion Queue | 03h | Abort Command Limit Exceeded | Abort | 04h | Reserved | 05h | Asynchronous Event Request Limit Exceeded | Asynchronous Event Request | 06h | Invalid Firmware Slot | Firmware Commit | 07h | Invalid Firmware Image | Firmware Commit | 08h | Invalid Interrupt Vector | Create I/O Completion Queue | 09h | Invalid Log Page | Get Log Page | 0Ah | Invalid Format | Format NVM, Namespace Management | 0Bh | Firmware Activation Requires Conventional Reset | Firmware Commit | 0Ch | Invalid Queue Deletion | Delete I/O Completion Queue | 0Dh | Feature Identifier Not Saveable | Set Features | 0Eh | Feature Not Changeable | Set Features | 0Fh | Feature Not Namespace Specific | Set Features | 10h | Firmware Activation Requires NVM Subsystem Reset | Firmware Commit, Sanitize | 11h | Firmware Activation Requires Reset | Firmware Commit | 12h | Firmware Activation Requires Maximum Time Violation | Firmware Commit | 13h | Firmware Activation Prohibited | Firmware Commit | 14h | Overlapping Range | Firmware Commit, Firmware Image Download, Set Features | 15h | Namespace Insufficient Capacity | Namespace Management | 16h | Namespace Identifier Unavailable | Namespace Management | 17h | Reserved | 18h | Namespace Already Attached | Namespace Attachment | 19h | Namespace Is Private | Namespace Attachment | 1Ah | Namespace Not Attached | Namespace Attachment | 1Bh | Thin Provisioning Not Supported | Namespace Management | 1Ch | Controller List Invalid | Namespace Attachment | 1Dh | Device Self-test In Progress | Device Self-test | 1Eh | Boot Partition Write Prohibited | Firmware Commit | 1Fh | Invalid Controller Identifier | Virtualization Management | 20h | Invalid Secondary Controller State | Virtualization Management | 21h | Invalid Number of Controller Resources | Virtualization Management | 22h | Invalid Resource Identifier | Virtualization Management | 23h – 6Fh | Reserved | 70h – 7Fh | Directive Specific | NOTE 1 | 80h – BFh | I/O Command Set Specific | NOTE 2
Value | Description | Commands Affected | 80h | Conflicting Attributes | Dataset Management, Read, Write | 81h | Invalid Protection Information | Compare, Read, Write, Write Zeroes | 82h | Attempted Write to Read Only Range | Dataset Management, Write, Write Uncorrectable, Write Zeroes | 83h - BFh | Reserved | | | | |
| C0h – FFh | Vendor Specific | NOTES: 1. The Directives Specific range defines Directives specific status values. Refer to section 9. 2. The I/O Command Set Specific range in the NVMe over Fabrics specification defines Fabrics command specific status values. |
4.6.1.2.3 Media and Data Integrity Errors Definition 图35:Status Code-Media and Data Integity Eror Values
Value | Description | 00h – 7Fh | Reserved | 80h – BFh | I/O Command Set Specific
Value | Description | 80h | Write Fault: The write data could not be committed to the media. | 81h | Unrecovered Read Error: The read data could not be recovered from the media. | 82h | End-to-end Guard Check Error: The command was aborted due to an end-to-end guard check failure. | 83h | End-to-end Application Tag Check Error: The command was aborted due to an end-to-end application tag check failure. | 84h | End-to-end Reference Tag Check Error: The command was aborted due to an end-to-end reference tag check failure. | 85h | Compare Failure: The command failed due to a miscompare during a Compare command. | 86h | Access Denied: Access to the namespace and/or LBA range is denied due to lack of access rights. Refer to the appropriate security specification (e.g., TCG Storage Interface Interactions Specification). | 87h | Deallocated or Unwritten Logical Block: The command failed due to an attempt to read from an LBA range containing a deallocated or unwritten logical block. | 88h – BFh | Reserved |
| C0h – FFh | Vendor Specific |
4.7 Controller Memory Buffer Controller Memory Buffer(CMB)是一个在Controller上的通用读/写内存区域,可以当做多种用途。Controller上的这块内存可以在CMBSZ寄存器中设置支持标识。 当SQ在Host的内存中时。controller需要发送一个PCIe-read命令来获取在Host上的SQ内的Queue Entries。 当SQ在Controller的内存中时。Host直接将整个的SQ Entry写入到Controller内部的内存空间。避免了Controller再想Host发送读请求读取数据。 这种方式在PCIe多Switch的拓扑结构中减少了命令运行延时,提高了效率。类似的,通过向Controller中写PRP和SGL的方式也可以死提高PRP List或者SGLs的获取效率。 CQ也可以端对端的使用在被放置到Controller中时。 对于小数据量的写来说,Host将data和metadata写入到Controller的内存比Controller到Host的内存中取是更有利的。 一块Controller内存在开始时是未被初始化的,Host应该在使用它之前去初始化它(例如:CQ Entries中的Phase Tag位应该在开始时被Host初始化成0)。 Controller内存中的Queue和Host内存中的Queue是一个用法,不同的是内存地址在Controller的内部内存中。Admin或者IO Queue可能被放置在Controller的内存空间。对于一个在Host内存或者Controller内存的特殊的Queue,与之相关的所有内存都应当被保留。 所有在Controller内存中的Queue都应该是一块连续的物理空间。 Controller可能会支持PRPs或者SGLs在自己的内存中。对于和一条命令相关的PRP List或者SGLs,所有在Controller或者Host内存中的和PRPs或者SGLs相关的内存区域都应该被保留。如果SQ放置在了Controller的内存中,那么和SQ Entry相关的PRP List或者SGLs都应该放置在Controller内存中。 Controller也可能支持Data和Metadata都在Controller内存中。与特定命令相关的所有Data和Metadata(如果有的话)都应该位于Controller内存或者Host内存中。 如果Host违法使用了Controller内存,则相关联的命令应该回复一个Invalid Use of CMB status的状态。 CMB的地址空间申请应该是4KB对齐的。推荐的对齐方式示8KB对齐。Controller应该支持最大为Maxmum payload size的Burst传输,支持字节访问,支持任意字节对齐。在更新SQ Tail Doorbell寄存器之前,Host应该确保命令已经被写入到CMB中了。 |