The branch main has been updated by jhb:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=f2a587b8b7779ac3adce38c5f34e08ddaef39cfb

commit f2a587b8b7779ac3adce38c5f34e08ddaef39cfb
Author:     John Baldwin <j...@freebsd.org>
AuthorDate: 2025-06-02 15:05:26 +0000
Commit:     John Baldwin <j...@freebsd.org>
CommitDate: 2025-06-02 15:05:26 +0000

    cam nvme: Move opcode and status code tables from CTL to base CAM
    
    This adds support for decoding admin opcodes to the existing opcode
    decoding and also removes one of the duplicate NVMe opcode string
    tables.
    
    - Add nvme_opcode_sbuf and nvme_cpl_sbuf which are CCB
      type-independent and handle the guts of the CTL-specific routines.
    
    - Use nvme_opcode_sbuf to decode the opcode in nvme_command_sbuf.
    
    - Add nvme_status_sbuf to decode the CPL/CQE in a ccb_nvmeio.
    
    Reviewed by:    imp
    Sponsored by:   Chelsio Communications
    Differential Revision:  https://reviews.freebsd.org/D50631
---
 sys/cam/ctl/ctl_nvme_all.c | 220 +----------------------------------
 sys/cam/nvme/nvme_all.c    | 282 +++++++++++++++++++++++++++++++++++++++------
 sys/cam/nvme/nvme_all.h    |   3 +
 3 files changed, 254 insertions(+), 251 deletions(-)

diff --git a/sys/cam/ctl/ctl_nvme_all.c b/sys/cam/ctl/ctl_nvme_all.c
index 739efadf5614..2d868ff24833 100644
--- a/sys/cam/ctl/ctl_nvme_all.c
+++ b/sys/cam/ctl/ctl_nvme_all.c
@@ -14,231 +14,21 @@
 #include <stdio.h>
 #endif
 
-#include <dev/nvme/nvme.h>
+#include <cam/cam.h>
+#include <cam/nvme/nvme_all.h>
 
 #include <cam/ctl/ctl_io.h>
 #include <cam/ctl/ctl_nvme_all.h>
 
-/* XXX: This duplicates lists in nvme_qpair.c. */
-
-#define OPC_ENTRY(x)           [NVME_OPC_ ## x] = #x
-
-static const char *admin_opcode[256] = {
-       OPC_ENTRY(DELETE_IO_SQ),
-       OPC_ENTRY(CREATE_IO_SQ),
-       OPC_ENTRY(GET_LOG_PAGE),
-       OPC_ENTRY(DELETE_IO_CQ),
-       OPC_ENTRY(CREATE_IO_CQ),
-       OPC_ENTRY(IDENTIFY),
-       OPC_ENTRY(ABORT),
-       OPC_ENTRY(SET_FEATURES),
-       OPC_ENTRY(GET_FEATURES),
-       OPC_ENTRY(ASYNC_EVENT_REQUEST),
-       OPC_ENTRY(NAMESPACE_MANAGEMENT),
-       OPC_ENTRY(FIRMWARE_ACTIVATE),
-       OPC_ENTRY(FIRMWARE_IMAGE_DOWNLOAD),
-       OPC_ENTRY(DEVICE_SELF_TEST),
-       OPC_ENTRY(NAMESPACE_ATTACHMENT),
-       OPC_ENTRY(KEEP_ALIVE),
-       OPC_ENTRY(DIRECTIVE_SEND),
-       OPC_ENTRY(DIRECTIVE_RECEIVE),
-       OPC_ENTRY(VIRTUALIZATION_MANAGEMENT),
-       OPC_ENTRY(NVME_MI_SEND),
-       OPC_ENTRY(NVME_MI_RECEIVE),
-       OPC_ENTRY(CAPACITY_MANAGEMENT),
-       OPC_ENTRY(LOCKDOWN),
-       OPC_ENTRY(DOORBELL_BUFFER_CONFIG),
-       OPC_ENTRY(FABRICS_COMMANDS),
-       OPC_ENTRY(FORMAT_NVM),
-       OPC_ENTRY(SECURITY_SEND),
-       OPC_ENTRY(SECURITY_RECEIVE),
-       OPC_ENTRY(SANITIZE),
-       OPC_ENTRY(GET_LBA_STATUS),
-};
-
-static const char *nvm_opcode[256] = {
-       OPC_ENTRY(FLUSH),
-       OPC_ENTRY(WRITE),
-       OPC_ENTRY(READ),
-       OPC_ENTRY(WRITE_UNCORRECTABLE),
-       OPC_ENTRY(COMPARE),
-       OPC_ENTRY(WRITE_ZEROES),
-       OPC_ENTRY(DATASET_MANAGEMENT),
-       OPC_ENTRY(VERIFY),
-       OPC_ENTRY(RESERVATION_REGISTER),
-       OPC_ENTRY(RESERVATION_REPORT),
-       OPC_ENTRY(RESERVATION_ACQUIRE),
-       OPC_ENTRY(RESERVATION_RELEASE),
-       OPC_ENTRY(COPY),
-};
-
 void
 ctl_nvme_command_string(struct ctl_nvmeio *ctnio, struct sbuf *sb)
 {
-       const char *s, *type;
-
-       if (ctnio->io_hdr.io_type == CTL_IO_NVME_ADMIN) {
-               s = admin_opcode[ctnio->cmd.opc];
-               type = "ADMIN";
-       } else {
-               s = nvm_opcode[ctnio->cmd.opc];
-               type = "NVM";
-       }
-       if (s == NULL)
-               sbuf_printf(sb, "%s:0x%02x", type, ctnio->cmd.opc);
-       else
-               sbuf_printf(sb, "%s", s);
+       nvme_opcode_sbuf(ctnio->io_hdr.io_type == CTL_IO_NVME_ADMIN,
+           ctnio->cmd.opc, sb);
 }
 
-#define SC_ENTRY(x)            [NVME_SC_ ## x] = #x
-
-static const char *generic_status[256] = {
-       SC_ENTRY(SUCCESS),
-       SC_ENTRY(INVALID_OPCODE),
-       SC_ENTRY(INVALID_FIELD),
-       SC_ENTRY(COMMAND_ID_CONFLICT),
-       SC_ENTRY(DATA_TRANSFER_ERROR),
-       SC_ENTRY(ABORTED_POWER_LOSS),
-       SC_ENTRY(INTERNAL_DEVICE_ERROR),
-       SC_ENTRY(ABORTED_BY_REQUEST),
-       SC_ENTRY(ABORTED_SQ_DELETION),
-       SC_ENTRY(ABORTED_FAILED_FUSED),
-       SC_ENTRY(ABORTED_MISSING_FUSED),
-       SC_ENTRY(INVALID_NAMESPACE_OR_FORMAT),
-       SC_ENTRY(COMMAND_SEQUENCE_ERROR),
-       SC_ENTRY(INVALID_SGL_SEGMENT_DESCR),
-       SC_ENTRY(INVALID_NUMBER_OF_SGL_DESCR),
-       SC_ENTRY(DATA_SGL_LENGTH_INVALID),
-       SC_ENTRY(METADATA_SGL_LENGTH_INVALID),
-       SC_ENTRY(SGL_DESCRIPTOR_TYPE_INVALID),
-       SC_ENTRY(INVALID_USE_OF_CMB),
-       SC_ENTRY(PRP_OFFET_INVALID),
-       SC_ENTRY(ATOMIC_WRITE_UNIT_EXCEEDED),
-       SC_ENTRY(OPERATION_DENIED),
-       SC_ENTRY(SGL_OFFSET_INVALID),
-       SC_ENTRY(HOST_ID_INCONSISTENT_FORMAT),
-       SC_ENTRY(KEEP_ALIVE_TIMEOUT_EXPIRED),
-       SC_ENTRY(KEEP_ALIVE_TIMEOUT_INVALID),
-       SC_ENTRY(ABORTED_DUE_TO_PREEMPT),
-       SC_ENTRY(SANITIZE_FAILED),
-       SC_ENTRY(SANITIZE_IN_PROGRESS),
-       SC_ENTRY(SGL_DATA_BLOCK_GRAN_INVALID),
-       SC_ENTRY(NOT_SUPPORTED_IN_CMB),
-       SC_ENTRY(NAMESPACE_IS_WRITE_PROTECTED),
-       SC_ENTRY(COMMAND_INTERRUPTED),
-       SC_ENTRY(TRANSIENT_TRANSPORT_ERROR),
-
-       SC_ENTRY(LBA_OUT_OF_RANGE),
-       SC_ENTRY(CAPACITY_EXCEEDED),
-       SC_ENTRY(NAMESPACE_NOT_READY),
-       SC_ENTRY(RESERVATION_CONFLICT),
-       SC_ENTRY(FORMAT_IN_PROGRESS),
-};
-
-static const char *command_specific_status[256] = {
-       SC_ENTRY(COMPLETION_QUEUE_INVALID),
-       SC_ENTRY(INVALID_QUEUE_IDENTIFIER),
-       SC_ENTRY(MAXIMUM_QUEUE_SIZE_EXCEEDED),
-       SC_ENTRY(ABORT_COMMAND_LIMIT_EXCEEDED),
-       SC_ENTRY(ASYNC_EVENT_REQUEST_LIMIT_EXCEEDED),
-       SC_ENTRY(INVALID_FIRMWARE_SLOT),
-       SC_ENTRY(INVALID_FIRMWARE_IMAGE),
-       SC_ENTRY(INVALID_INTERRUPT_VECTOR),
-       SC_ENTRY(INVALID_LOG_PAGE),
-       SC_ENTRY(INVALID_FORMAT),
-       SC_ENTRY(FIRMWARE_REQUIRES_RESET),
-       SC_ENTRY(INVALID_QUEUE_DELETION),
-       SC_ENTRY(FEATURE_NOT_SAVEABLE),
-       SC_ENTRY(FEATURE_NOT_CHANGEABLE),
-       SC_ENTRY(FEATURE_NOT_NS_SPECIFIC),
-       SC_ENTRY(FW_ACT_REQUIRES_NVMS_RESET),
-       SC_ENTRY(FW_ACT_REQUIRES_RESET),
-       SC_ENTRY(FW_ACT_REQUIRES_TIME),
-       SC_ENTRY(FW_ACT_PROHIBITED),
-       SC_ENTRY(OVERLAPPING_RANGE),
-       SC_ENTRY(NS_INSUFFICIENT_CAPACITY),
-       SC_ENTRY(NS_ID_UNAVAILABLE),
-       SC_ENTRY(NS_ALREADY_ATTACHED),
-       SC_ENTRY(NS_IS_PRIVATE),
-       SC_ENTRY(NS_NOT_ATTACHED),
-       SC_ENTRY(THIN_PROV_NOT_SUPPORTED),
-       SC_ENTRY(CTRLR_LIST_INVALID),
-       SC_ENTRY(SELF_TEST_IN_PROGRESS),
-       SC_ENTRY(BOOT_PART_WRITE_PROHIB),
-       SC_ENTRY(INVALID_CTRLR_ID),
-       SC_ENTRY(INVALID_SEC_CTRLR_STATE),
-       SC_ENTRY(INVALID_NUM_OF_CTRLR_RESRC),
-       SC_ENTRY(INVALID_RESOURCE_ID),
-       SC_ENTRY(SANITIZE_PROHIBITED_WPMRE),
-       SC_ENTRY(ANA_GROUP_ID_INVALID),
-       SC_ENTRY(ANA_ATTACH_FAILED),
-
-       SC_ENTRY(CONFLICTING_ATTRIBUTES),
-       SC_ENTRY(INVALID_PROTECTION_INFO),
-       SC_ENTRY(ATTEMPTED_WRITE_TO_RO_PAGE),
-};
-
-static const char *media_error_status[256] = {
-       SC_ENTRY(WRITE_FAULTS),
-       SC_ENTRY(UNRECOVERED_READ_ERROR),
-       SC_ENTRY(GUARD_CHECK_ERROR),
-       SC_ENTRY(APPLICATION_TAG_CHECK_ERROR),
-       SC_ENTRY(REFERENCE_TAG_CHECK_ERROR),
-       SC_ENTRY(COMPARE_FAILURE),
-       SC_ENTRY(ACCESS_DENIED),
-       SC_ENTRY(DEALLOCATED_OR_UNWRITTEN),
-};
-
-static const char *path_related_status[256] = {
-       SC_ENTRY(INTERNAL_PATH_ERROR),
-       SC_ENTRY(ASYMMETRIC_ACCESS_PERSISTENT_LOSS),
-       SC_ENTRY(ASYMMETRIC_ACCESS_INACCESSIBLE),
-       SC_ENTRY(ASYMMETRIC_ACCESS_TRANSITION),
-       SC_ENTRY(CONTROLLER_PATHING_ERROR),
-       SC_ENTRY(HOST_PATHING_ERROR),
-       SC_ENTRY(COMMAND_ABORTED_BY_HOST),
-};
-
 void
 ctl_nvme_status_string(struct ctl_nvmeio *ctnio, struct sbuf *sb)
 {
-       const char *s, *type;
-       uint16_t status;
-
-       status = le16toh(ctnio->cpl.status);
-       switch (NVME_STATUS_GET_SCT(status)) {
-       case NVME_SCT_GENERIC:
-               s = generic_status[NVME_STATUS_GET_SC(status)];
-               type = "GENERIC";
-               break;
-       case NVME_SCT_COMMAND_SPECIFIC:
-               s = command_specific_status[NVME_STATUS_GET_SC(status)];
-               type = "COMMAND SPECIFIC";
-               break;
-       case NVME_SCT_MEDIA_ERROR:
-               s = media_error_status[NVME_STATUS_GET_SC(status)];
-               type = "MEDIA ERROR";
-               break;
-       case NVME_SCT_PATH_RELATED:
-               s = path_related_status[NVME_STATUS_GET_SC(status)];
-               type = "PATH RELATED";
-               break;
-       case NVME_SCT_VENDOR_SPECIFIC:
-               s = NULL;
-               type = "VENDOR SPECIFIC";
-               break;
-       default:
-               s = "RESERVED";
-               type = NULL;
-               break;
-       }
-
-       if (s == NULL)
-               sbuf_printf(sb, "%s:0x%02x", type, NVME_STATUS_GET_SC(status));
-       else
-               sbuf_printf(sb, "%s", s);
-       if (NVME_STATUS_GET_M(status) != 0)
-               sbuf_printf(sb, " M");
-       if (NVME_STATUS_GET_DNR(status) != 0)
-               sbuf_printf(sb, " DNR");
+       nvme_cpl_sbuf(&ctnio->cpl, sb);
 }
diff --git a/sys/cam/nvme/nvme_all.c b/sys/cam/nvme/nvme_all.c
index a3c3d676b349..3f264e2ff6eb 100644
--- a/sys/cam/nvme/nvme_all.c
+++ b/sys/cam/nvme/nvme_all.c
@@ -60,6 +60,168 @@
 #include <cam/cam_xpt_internal.h>
 #endif
 
+/* XXX: This duplicates lists in nvme_qpair.c. */
+
+#define OPC_ENTRY(x)           [NVME_OPC_ ## x] = #x
+
+static const char *admin_opcode[256] = {
+       OPC_ENTRY(DELETE_IO_SQ),
+       OPC_ENTRY(CREATE_IO_SQ),
+       OPC_ENTRY(GET_LOG_PAGE),
+       OPC_ENTRY(DELETE_IO_CQ),
+       OPC_ENTRY(CREATE_IO_CQ),
+       OPC_ENTRY(IDENTIFY),
+       OPC_ENTRY(ABORT),
+       OPC_ENTRY(SET_FEATURES),
+       OPC_ENTRY(GET_FEATURES),
+       OPC_ENTRY(ASYNC_EVENT_REQUEST),
+       OPC_ENTRY(NAMESPACE_MANAGEMENT),
+       OPC_ENTRY(FIRMWARE_ACTIVATE),
+       OPC_ENTRY(FIRMWARE_IMAGE_DOWNLOAD),
+       OPC_ENTRY(DEVICE_SELF_TEST),
+       OPC_ENTRY(NAMESPACE_ATTACHMENT),
+       OPC_ENTRY(KEEP_ALIVE),
+       OPC_ENTRY(DIRECTIVE_SEND),
+       OPC_ENTRY(DIRECTIVE_RECEIVE),
+       OPC_ENTRY(VIRTUALIZATION_MANAGEMENT),
+       OPC_ENTRY(NVME_MI_SEND),
+       OPC_ENTRY(NVME_MI_RECEIVE),
+       OPC_ENTRY(CAPACITY_MANAGEMENT),
+       OPC_ENTRY(LOCKDOWN),
+       OPC_ENTRY(DOORBELL_BUFFER_CONFIG),
+       OPC_ENTRY(FABRICS_COMMANDS),
+       OPC_ENTRY(FORMAT_NVM),
+       OPC_ENTRY(SECURITY_SEND),
+       OPC_ENTRY(SECURITY_RECEIVE),
+       OPC_ENTRY(SANITIZE),
+       OPC_ENTRY(GET_LBA_STATUS),
+};
+
+static const char *nvm_opcode[256] = {
+       OPC_ENTRY(FLUSH),
+       OPC_ENTRY(WRITE),
+       OPC_ENTRY(READ),
+       OPC_ENTRY(WRITE_UNCORRECTABLE),
+       OPC_ENTRY(COMPARE),
+       OPC_ENTRY(WRITE_ZEROES),
+       OPC_ENTRY(DATASET_MANAGEMENT),
+       OPC_ENTRY(VERIFY),
+       OPC_ENTRY(RESERVATION_REGISTER),
+       OPC_ENTRY(RESERVATION_REPORT),
+       OPC_ENTRY(RESERVATION_ACQUIRE),
+       OPC_ENTRY(RESERVATION_RELEASE),
+       OPC_ENTRY(COPY),
+};
+
+#define SC_ENTRY(x)            [NVME_SC_ ## x] = #x
+
+static const char *generic_status[256] = {
+       SC_ENTRY(SUCCESS),
+       SC_ENTRY(INVALID_OPCODE),
+       SC_ENTRY(INVALID_FIELD),
+       SC_ENTRY(COMMAND_ID_CONFLICT),
+       SC_ENTRY(DATA_TRANSFER_ERROR),
+       SC_ENTRY(ABORTED_POWER_LOSS),
+       SC_ENTRY(INTERNAL_DEVICE_ERROR),
+       SC_ENTRY(ABORTED_BY_REQUEST),
+       SC_ENTRY(ABORTED_SQ_DELETION),
+       SC_ENTRY(ABORTED_FAILED_FUSED),
+       SC_ENTRY(ABORTED_MISSING_FUSED),
+       SC_ENTRY(INVALID_NAMESPACE_OR_FORMAT),
+       SC_ENTRY(COMMAND_SEQUENCE_ERROR),
+       SC_ENTRY(INVALID_SGL_SEGMENT_DESCR),
+       SC_ENTRY(INVALID_NUMBER_OF_SGL_DESCR),
+       SC_ENTRY(DATA_SGL_LENGTH_INVALID),
+       SC_ENTRY(METADATA_SGL_LENGTH_INVALID),
+       SC_ENTRY(SGL_DESCRIPTOR_TYPE_INVALID),
+       SC_ENTRY(INVALID_USE_OF_CMB),
+       SC_ENTRY(PRP_OFFET_INVALID),
+       SC_ENTRY(ATOMIC_WRITE_UNIT_EXCEEDED),
+       SC_ENTRY(OPERATION_DENIED),
+       SC_ENTRY(SGL_OFFSET_INVALID),
+       SC_ENTRY(HOST_ID_INCONSISTENT_FORMAT),
+       SC_ENTRY(KEEP_ALIVE_TIMEOUT_EXPIRED),
+       SC_ENTRY(KEEP_ALIVE_TIMEOUT_INVALID),
+       SC_ENTRY(ABORTED_DUE_TO_PREEMPT),
+       SC_ENTRY(SANITIZE_FAILED),
+       SC_ENTRY(SANITIZE_IN_PROGRESS),
+       SC_ENTRY(SGL_DATA_BLOCK_GRAN_INVALID),
+       SC_ENTRY(NOT_SUPPORTED_IN_CMB),
+       SC_ENTRY(NAMESPACE_IS_WRITE_PROTECTED),
+       SC_ENTRY(COMMAND_INTERRUPTED),
+       SC_ENTRY(TRANSIENT_TRANSPORT_ERROR),
+
+       SC_ENTRY(LBA_OUT_OF_RANGE),
+       SC_ENTRY(CAPACITY_EXCEEDED),
+       SC_ENTRY(NAMESPACE_NOT_READY),
+       SC_ENTRY(RESERVATION_CONFLICT),
+       SC_ENTRY(FORMAT_IN_PROGRESS),
+};
+
+static const char *command_specific_status[256] = {
+       SC_ENTRY(COMPLETION_QUEUE_INVALID),
+       SC_ENTRY(INVALID_QUEUE_IDENTIFIER),
+       SC_ENTRY(MAXIMUM_QUEUE_SIZE_EXCEEDED),
+       SC_ENTRY(ABORT_COMMAND_LIMIT_EXCEEDED),
+       SC_ENTRY(ASYNC_EVENT_REQUEST_LIMIT_EXCEEDED),
+       SC_ENTRY(INVALID_FIRMWARE_SLOT),
+       SC_ENTRY(INVALID_FIRMWARE_IMAGE),
+       SC_ENTRY(INVALID_INTERRUPT_VECTOR),
+       SC_ENTRY(INVALID_LOG_PAGE),
+       SC_ENTRY(INVALID_FORMAT),
+       SC_ENTRY(FIRMWARE_REQUIRES_RESET),
+       SC_ENTRY(INVALID_QUEUE_DELETION),
+       SC_ENTRY(FEATURE_NOT_SAVEABLE),
+       SC_ENTRY(FEATURE_NOT_CHANGEABLE),
+       SC_ENTRY(FEATURE_NOT_NS_SPECIFIC),
+       SC_ENTRY(FW_ACT_REQUIRES_NVMS_RESET),
+       SC_ENTRY(FW_ACT_REQUIRES_RESET),
+       SC_ENTRY(FW_ACT_REQUIRES_TIME),
+       SC_ENTRY(FW_ACT_PROHIBITED),
+       SC_ENTRY(OVERLAPPING_RANGE),
+       SC_ENTRY(NS_INSUFFICIENT_CAPACITY),
+       SC_ENTRY(NS_ID_UNAVAILABLE),
+       SC_ENTRY(NS_ALREADY_ATTACHED),
+       SC_ENTRY(NS_IS_PRIVATE),
+       SC_ENTRY(NS_NOT_ATTACHED),
+       SC_ENTRY(THIN_PROV_NOT_SUPPORTED),
+       SC_ENTRY(CTRLR_LIST_INVALID),
+       SC_ENTRY(SELF_TEST_IN_PROGRESS),
+       SC_ENTRY(BOOT_PART_WRITE_PROHIB),
+       SC_ENTRY(INVALID_CTRLR_ID),
+       SC_ENTRY(INVALID_SEC_CTRLR_STATE),
+       SC_ENTRY(INVALID_NUM_OF_CTRLR_RESRC),
+       SC_ENTRY(INVALID_RESOURCE_ID),
+       SC_ENTRY(SANITIZE_PROHIBITED_WPMRE),
+       SC_ENTRY(ANA_GROUP_ID_INVALID),
+       SC_ENTRY(ANA_ATTACH_FAILED),
+
+       SC_ENTRY(CONFLICTING_ATTRIBUTES),
+       SC_ENTRY(INVALID_PROTECTION_INFO),
+       SC_ENTRY(ATTEMPTED_WRITE_TO_RO_PAGE),
+};
+
+static const char *media_error_status[256] = {
+       SC_ENTRY(WRITE_FAULTS),
+       SC_ENTRY(UNRECOVERED_READ_ERROR),
+       SC_ENTRY(GUARD_CHECK_ERROR),
+       SC_ENTRY(APPLICATION_TAG_CHECK_ERROR),
+       SC_ENTRY(REFERENCE_TAG_CHECK_ERROR),
+       SC_ENTRY(COMPARE_FAILURE),
+       SC_ENTRY(ACCESS_DENIED),
+       SC_ENTRY(DEALLOCATED_OR_UNWRITTEN),
+};
+
+static const char *path_related_status[256] = {
+       SC_ENTRY(INTERNAL_PATH_ERROR),
+       SC_ENTRY(ASYMMETRIC_ACCESS_PERSISTENT_LOSS),
+       SC_ENTRY(ASYMMETRIC_ACCESS_INACCESSIBLE),
+       SC_ENTRY(ASYMMETRIC_ACCESS_TRANSITION),
+       SC_ENTRY(CONTROLLER_PATHING_ERROR),
+       SC_ENTRY(HOST_PATHING_ERROR),
+       SC_ENTRY(COMMAND_ABORTED_BY_HOST),
+};
+
 void
 nvme_ns_cmd(struct ccb_nvmeio *nvmeio, uint8_t cmd, uint32_t nsid,
     uint32_t cdw10, uint32_t cdw11, uint32_t cdw12, uint32_t cdw13,
@@ -106,44 +268,19 @@ nvme_print_ident_short(const struct nvme_controller_data 
*cdata,
        sbuf_putc(sb, '>');
 }
 
-/* XXX need to do nvme admin opcodes too, but those aren't used yet by nda */
-static const char *
-nvme_opc2str[] = {
-       "FLUSH",
-       "WRITE",
-       "READ",
-       "RSVD-3",
-       "WRITE_UNCORRECTABLE",
-       "COMPARE",
-       "RSVD-6",
-       "RSVD-7",
-       "WRITE_ZEROES",
-       "DATASET_MANAGEMENT",
-       "RSVD-a",
-       "RSVD-b",
-       "RSVD-c",
-       "RESERVATION_REGISTER",
-       "RESERVATION_REPORT",
-       "RSVD-f",
-       "RSVD-10",
-       "RESERVATION_ACQUIRE",
-       "RSVD-12",
-       "RSVD-13",
-       "RSVD-14",
-       "RESERVATION_RELEASE",
-};
-
 const char *
 nvme_op_string(const struct nvme_command *cmd, int admin)
 {
+       const char *s;
 
-       if (admin) {
-               return "ADMIN";
-       } else {
-               if (cmd->opc >= nitems(nvme_opc2str))
-                       return "UNKNOWN";
-               return nvme_opc2str[cmd->opc];
-       }
+       if (admin)
+               s = admin_opcode[cmd->opc];
+       else
+               s = nvm_opcode[cmd->opc];
+       if (s == NULL)
+               return ("UNKNOWN");
+       else
+               return (s);
 }
 
 const char *
@@ -170,6 +307,24 @@ nvme_cmd_string(const struct nvme_command *cmd, char 
*cmd_string, size_t len)
        return(sbuf_data(&sb));
 }
 
+void
+nvme_opcode_sbuf(bool admin, uint8_t opc, struct sbuf *sb)
+{
+       const char *s, *type;
+
+       if (admin) {
+               s = admin_opcode[opc];
+               type = "ADMIN";
+       } else {
+               s = nvm_opcode[opc];
+               type = "NVM";
+       }
+       if (s == NULL)
+               sbuf_printf(sb, "%s:0x%02x", type, opc);
+       else
+               sbuf_printf(sb, "%s", s);
+}
+
 void
 nvme_cmd_sbuf(const struct nvme_command *cmd, struct sbuf *sb)
 {
@@ -193,12 +348,67 @@ int
 nvme_command_sbuf(struct ccb_nvmeio *nvmeio, struct sbuf *sb)
 {
 
-       sbuf_printf(sb, "%s. NCB: ", nvme_op_string(&nvmeio->cmd,
-           nvmeio->ccb_h.func_code == XPT_NVME_ADMIN));
+       nvme_opcode_sbuf(nvmeio->ccb_h.func_code == XPT_NVME_ADMIN,
+           nvmeio->cmd.opc, sb);
+       sbuf_cat(sb, ". NCB: ");
        nvme_cmd_sbuf(&nvmeio->cmd, sb);
        return(0);
 }
 
+void
+nvme_cpl_sbuf(const struct nvme_completion *cpl, struct sbuf *sb)
+{
+       const char *s, *type;
+       uint16_t status;
+
+       status = le16toh(cpl->status);
+       switch (NVME_STATUS_GET_SCT(status)) {
+       case NVME_SCT_GENERIC:
+               s = generic_status[NVME_STATUS_GET_SC(status)];
+               type = "GENERIC";
+               break;
+       case NVME_SCT_COMMAND_SPECIFIC:
+               s = command_specific_status[NVME_STATUS_GET_SC(status)];
+               type = "COMMAND SPECIFIC";
+               break;
+       case NVME_SCT_MEDIA_ERROR:
+               s = media_error_status[NVME_STATUS_GET_SC(status)];
+               type = "MEDIA ERROR";
+               break;
+       case NVME_SCT_PATH_RELATED:
+               s = path_related_status[NVME_STATUS_GET_SC(status)];
+               type = "PATH RELATED";
+               break;
+       case NVME_SCT_VENDOR_SPECIFIC:
+               s = NULL;
+               type = "VENDOR SPECIFIC";
+               break;
+       default:
+               s = "RESERVED";
+               type = NULL;
+               break;
+       }
+
+       if (s == NULL)
+               sbuf_printf(sb, "%s:0x%02x", type, NVME_STATUS_GET_SC(status));
+       else
+               sbuf_printf(sb, "%s", s);
+       if (NVME_STATUS_GET_M(status) != 0)
+               sbuf_printf(sb, " M");
+       if (NVME_STATUS_GET_DNR(status) != 0)
+               sbuf_printf(sb, " DNR");
+}
+
+/*
+ * nvme_status_sbuf() returns 0 for success and -1 for failure.
+ */
+int
+nvme_status_sbuf(struct ccb_nvmeio *nvmeio, struct sbuf *sb)
+{
+       nvme_cpl_sbuf(&nvmeio->cpl, sb);
+       return (0);
+}
+
 #ifdef _KERNEL
 const void *
 nvme_get_identify_cntrl(struct cam_periph *periph)
diff --git a/sys/cam/nvme/nvme_all.h b/sys/cam/nvme/nvme_all.h
index 2b6732fe7c74..a32668ddc1fb 100644
--- a/sys/cam/nvme/nvme_all.h
+++ b/sys/cam/nvme/nvme_all.h
@@ -44,8 +44,11 @@ void nvme_print_ident_short(const struct 
nvme_controller_data *,
     const struct nvme_namespace_data *, struct sbuf *);
 const char *nvme_op_string(const struct nvme_command *, int admin);
 const char *nvme_cmd_string(const struct nvme_command *, char *, size_t);
+void nvme_opcode_sbuf(bool admin, uint8_t opc, struct sbuf *sb);
 void nvme_cmd_sbuf(const struct nvme_command *, struct sbuf *sb);
 int nvme_command_sbuf(struct ccb_nvmeio *nvmeio, struct sbuf *sb);
+void nvme_cpl_sbuf(const struct nvme_completion *cpl, struct sbuf *sbuf);
+int nvme_status_sbuf(struct ccb_nvmeio *nvmeio, struct sbuf *sb);
 const void *nvme_get_identify_cntrl(struct cam_periph *);
 const void *nvme_get_identify_ns(struct cam_periph *);
 

Reply via email to