aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2024-05-02 23:31:34 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2024-05-02 23:31:34 +0000
commit6f308bcf572467c0884db833e169d9f14b7b49b2 (patch)
tree8477d2ac403e285fa18facf64b54c3c6c1abafad
parent75577946b5a16df329c7e4b3a4a1e1ba7805b921 (diff)
downloadsrc-6f308bcf572467c0884db833e169d9f14b7b49b2.tar.gz
src-6f308bcf572467c0884db833e169d9f14b7b49b2.zip
ctl: Support NVMe requests in debug trace functions
Reviewed by: imp Sponsored by: Chelsio Communications Differential Revision: https://reviews.freebsd.org/D44719
-rw-r--r--sys/cam/ctl/ctl_nvme_all.c244
-rw-r--r--sys/cam/ctl/ctl_nvme_all.h17
-rw-r--r--sys/cam/ctl/ctl_util.c55
-rw-r--r--sys/conf/files1
-rw-r--r--sys/modules/ctl/Makefile1
-rw-r--r--usr.sbin/bhyve/Makefile1
-rw-r--r--usr.sbin/ctladm/Makefile2
7 files changed, 308 insertions, 13 deletions
diff --git a/sys/cam/ctl/ctl_nvme_all.c b/sys/cam/ctl/ctl_nvme_all.c
new file mode 100644
index 000000000000..739efadf5614
--- /dev/null
+++ b/sys/cam/ctl/ctl_nvme_all.c
@@ -0,0 +1,244 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (C) 2012-2014 Intel Corporation
+ * All rights reserved.
+ *
+ * Copyright (c) 2023 Chelsio Communications, Inc.
+ */
+
+#include <sys/types.h>
+#include <sys/sbuf.h>
+#ifndef _KERNEL
+#include <sys/time.h>
+#include <stdio.h>
+#endif
+
+#include <dev/nvme/nvme.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);
+}
+
+#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");
+}
diff --git a/sys/cam/ctl/ctl_nvme_all.h b/sys/cam/ctl/ctl_nvme_all.h
new file mode 100644
index 000000000000..df0bf585c3ae
--- /dev/null
+++ b/sys/cam/ctl/ctl_nvme_all.h
@@ -0,0 +1,17 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2023 Chelsio Communications, Inc.
+ */
+
+#ifndef __CTL_NVME_ALL_H__
+#define __CTL_NVME_ALL_H__
+
+__BEGIN_DECLS
+
+void ctl_nvme_command_string(struct ctl_nvmeio *ctnio, struct sbuf *sb);
+void ctl_nvme_status_string(struct ctl_nvmeio *ctnio, struct sbuf *sb);
+
+__END_DECLS
+
+#endif /* !__CTL_NVME_ALL_H__ */
diff --git a/sys/cam/ctl/ctl_util.c b/sys/cam/ctl/ctl_util.c
index d039e3f6fe6e..3174c3c7cf40 100644
--- a/sys/cam/ctl/ctl_util.c
+++ b/sys/cam/ctl/ctl_util.c
@@ -56,6 +56,7 @@
#include <sys/callout.h>
#include <cam/scsi/scsi_all.h>
#include <cam/ctl/ctl_io.h>
+#include <cam/ctl/ctl_nvme_all.h>
#include <cam/ctl/ctl_scsi_all.h>
#include <cam/ctl/ctl_util.h>
@@ -759,6 +760,12 @@ ctl_io_sbuf(union ctl_io *io, struct sbuf *sb)
break;
}
break;
+ case CTL_IO_NVME:
+ case CTL_IO_NVME_ADMIN:
+ sbuf_cat(sb, path_str);
+ ctl_nvme_command_string(&io->nvmeio, sb);
+ sbuf_printf(sb, " CID: 0x%x\n", le16toh(io->nvmeio.cmd.cid));
+ break;
default:
break;
}
@@ -793,15 +800,29 @@ ctl_io_error_sbuf(union ctl_io *io, struct scsi_inquiry_data *inq_data,
else
sbuf_printf(sb, "CTL Status: %s\n", status_desc->description);
- if ((io->io_hdr.io_type == CTL_IO_SCSI)
- && ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_SCSI_ERROR)) {
- sbuf_cat(sb, path_str);
- sbuf_printf(sb, "SCSI Status: %s\n",
+ switch (io->io_hdr.io_type) {
+ case CTL_IO_SCSI:
+ if ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_SCSI_ERROR) {
+ sbuf_cat(sb, path_str);
+ sbuf_printf(sb, "SCSI Status: %s\n",
ctl_scsi_status_string(&io->scsiio));
- if (io->scsiio.scsi_status == SCSI_STATUS_CHECK_COND)
- ctl_scsi_sense_sbuf(&io->scsiio, inq_data,
- sb, SSS_FLAG_NONE);
+ if (io->scsiio.scsi_status == SCSI_STATUS_CHECK_COND)
+ ctl_scsi_sense_sbuf(&io->scsiio, inq_data,
+ sb, SSS_FLAG_NONE);
+ }
+ break;
+ case CTL_IO_NVME:
+ case CTL_IO_NVME_ADMIN:
+ if ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_NVME_ERROR) {
+ sbuf_cat(sb, path_str);
+ sbuf_printf(sb, "NVMe Status: ");
+ ctl_nvme_status_string(&io->nvmeio, sb);
+ sbuf_printf(sb, "\n");
+ }
+ break;
+ default:
+ break;
}
}
@@ -853,24 +874,34 @@ ctl_data_print(union ctl_io *io)
char str[128];
char path_str[64];
struct sbuf sb;
+ uintmax_t tag_num;
int i, j, len;
- if (io->io_hdr.io_type != CTL_IO_SCSI)
+ switch (io->io_hdr.io_type) {
+ case CTL_IO_SCSI:
+ tag_num = io->scsiio.tag_num;
+ break;
+ case CTL_IO_NVME:
+ case CTL_IO_NVME_ADMIN:
+ tag_num = le16toh(io->nvmeio.cmd.cid);
+ break;
+ default:
return;
+ }
if (io->io_hdr.flags & CTL_FLAG_BUS_ADDR)
return;
- if (io->scsiio.kern_sg_entries > 0) /* XXX: Implement */
+ if (ctl_kern_sg_entries(io) > 0) /* XXX: Implement */
return;
ctl_scsi_path_string(&io->io_hdr, path_str, sizeof(path_str));
- len = min(io->scsiio.kern_data_len, 4096);
+ len = min(ctl_kern_data_len(io), 4096);
for (i = 0; i < len; ) {
sbuf_new(&sb, str, sizeof(str), SBUF_FIXEDLEN);
sbuf_cat(&sb, path_str);
- sbuf_printf(&sb, " %#jx:%04x:", io->scsiio.tag_num, i);
+ sbuf_printf(&sb, " %#jx:%04x:", tag_num, i);
for (j = 0; j < 16 && i < len; i++, j++) {
if (j == 8)
sbuf_cat(&sb, " ");
- sbuf_printf(&sb, " %02x", io->scsiio.kern_data_ptr[i]);
+ sbuf_printf(&sb, " %02x", ctl_kern_data_ptr(io)[i]);
}
sbuf_cat(&sb, "\n");
sbuf_finish(&sb);
diff --git a/sys/conf/files b/sys/conf/files
index 4a631d979c78..266018c5c70d 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -108,6 +108,7 @@ cam/ctl/ctl_frontend_cam_sim.c optional ctl
cam/ctl/ctl_frontend_ioctl.c optional ctl
cam/ctl/ctl_frontend_iscsi.c optional ctl cfiscsi
cam/ctl/ctl_ha.c optional ctl
+cam/ctl/ctl_nvme_all.c optional ctl
cam/ctl/ctl_scsi_all.c optional ctl
cam/ctl/ctl_tpc.c optional ctl
cam/ctl/ctl_tpc_local.c optional ctl
diff --git a/sys/modules/ctl/Makefile b/sys/modules/ctl/Makefile
index 960cd60bfa9a..32f150b41300 100644
--- a/sys/modules/ctl/Makefile
+++ b/sys/modules/ctl/Makefile
@@ -12,6 +12,7 @@ SRCS+= ctl_frontend.c
SRCS+= ctl_frontend_cam_sim.c
SRCS+= ctl_frontend_ioctl.c
SRCS+= ctl_ha.c
+SRCS+= ctl_nvme_all.c
SRCS+= ctl_scsi_all.c
SRCS+= ctl_tpc.c
SRCS+= ctl_tpc_local.c
diff --git a/usr.sbin/bhyve/Makefile b/usr.sbin/bhyve/Makefile
index d5d7dfc26ab9..8b6631de1519 100644
--- a/usr.sbin/bhyve/Makefile
+++ b/usr.sbin/bhyve/Makefile
@@ -27,6 +27,7 @@ SRCS= \
config.c \
console.c \
crc16.c \
+ ctl_nvme_all.c \
ctl_scsi_all.c \
ctl_util.c \
hda_codec.c \
diff --git a/usr.sbin/ctladm/Makefile b/usr.sbin/ctladm/Makefile
index f9ddd251f96c..5e0df8065cce 100644
--- a/usr.sbin/ctladm/Makefile
+++ b/usr.sbin/ctladm/Makefile
@@ -3,7 +3,7 @@
PACKAGE= iscsi
PROG= ctladm
-SRCS= ctladm.c util.c ctl_util.c ctl_scsi_all.c
+SRCS= ctladm.c util.c ctl_util.c ctl_nvme_all.c ctl_scsi_all.c
.PATH: ${SRCTOP}/sys/cam/ctl
SDIR= ${SRCTOP}/sys
CFLAGS+= -I${SDIR}