git: 25bad5a2dac8 - main - ctl: Add NVMF port type and ioctls

From: John Baldwin <jhb_at_FreeBSD.org>
Date: Fri, 03 May 2024 00:16:07 UTC
The branch main has been updated by jhb:

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

commit 25bad5a2dac8fb79063f79b48cb6498baf8e54ff
Author:     John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2024-05-02 23:34:26 +0000
Commit:     John Baldwin <jhb@FreeBSD.org>
CommitDate: 2024-05-02 23:38:30 +0000

    ctl: Add NVMF port type and ioctls
    
    - Add CTL_PORT_NVMF as a new port type.
    
    - Define a new CTL_NVMF ioctl for NVMF-specific operations similar to
      CTL_ISCSI.  This ioctl supports a command to handoff a single
      queue pair, a command to enumerate active associations, and a
      command to disconnect one or more active associations.
    
    Reviewed by:    imp
    Sponsored by:   Chelsio Communications
    Differential Revision:  https://reviews.freebsd.org/D44724
---
 sys/cam/ctl/ctl.c       | 17 ++++++++++++++
 sys/cam/ctl/ctl.h       |  1 +
 sys/cam/ctl/ctl_ioctl.h | 62 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 80 insertions(+)

diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c
index fde873f4f7e5..fac65e155890 100644
--- a/sys/cam/ctl/ctl.c
+++ b/sys/cam/ctl/ctl.c
@@ -3217,6 +3217,23 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
 		retval = fe->ioctl(dev, cmd, addr, flag, td);
 		break;
 	}
+	case CTL_NVMF: {
+		struct ctl_nvmf *cn;
+		struct ctl_frontend *fe;
+
+		cn = (struct ctl_nvmf *)addr;
+
+		fe = ctl_frontend_find("nvmf");
+		if (fe == NULL) {
+			cn->status = CTL_NVMF_ERROR;
+			snprintf(cn->error_str, sizeof(cn->error_str),
+			    "Frontend \"nvmf\" not found.");
+			break;
+		}
+
+		retval = fe->ioctl(dev, cmd, addr, flag, td);
+		break;
+	}
 	case CTL_PORT_REQ: {
 		struct ctl_req *req;
 		struct ctl_frontend *fe;
diff --git a/sys/cam/ctl/ctl.h b/sys/cam/ctl/ctl.h
index a211e249b2dc..4b0ae45d6699 100644
--- a/sys/cam/ctl/ctl.h
+++ b/sys/cam/ctl/ctl.h
@@ -55,6 +55,7 @@ typedef enum {
 	CTL_PORT_ISCSI		= 0x10,
 	CTL_PORT_SAS		= 0x20,
 	CTL_PORT_UMASS		= 0x40,
+	CTL_PORT_NVMF		= 0x80,
 	CTL_PORT_ALL		= 0xff,
 	CTL_PORT_ISC		= 0x100 // FC port for inter-shelf communication
 } ctl_port_type;
diff --git a/sys/cam/ctl/ctl_ioctl.h b/sys/cam/ctl/ctl_ioctl.h
index 9fef169c300c..326e4c931f93 100644
--- a/sys/cam/ctl/ctl_ioctl.h
+++ b/sys/cam/ctl/ctl_ioctl.h
@@ -48,6 +48,8 @@
 
 #include <sys/ioccom.h>
 #include <sys/nv.h>
+#include <dev/nvmf/nvmf.h>
+#include <dev/nvmf/nvmf_proto.h>
 
 #define	CTL_DEFAULT_DEV		"/dev/cam/ctl"
 /*
@@ -761,6 +763,65 @@ struct ctl_lun_map {
 	uint32_t		lun;
 };
 
+/*
+ * NVMe over Fabrics status
+ *
+ * OK:			Request completed successfully.
+ *
+ * ERROR:		An error occurred, look at the error string for a
+ *			description of the error.
+ */
+typedef enum {
+	CTL_NVMF_OK,
+	CTL_NVMF_ERROR,
+	CTL_NVMF_LIST_NEED_MORE_SPACE,
+	CTL_NVMF_ASSOCIATION_NOT_FOUND
+} ctl_nvmf_status;
+
+typedef enum {
+	CTL_NVMF_HANDOFF,
+	CTL_NVMF_LIST,
+	CTL_NVMF_TERMINATE
+} ctl_nvmf_type;
+
+struct ctl_nvmf_list_params {
+	uint32_t		alloc_len;	/* passed to kernel */
+	char                   *conn_xml;	/* filled in kernel */
+	uint32_t		fill_len;	/* passed to userland */
+	int			spare[4];
+};
+
+struct ctl_nvmf_terminate_params {
+	int			cntlid;		/* passed to kernel */
+	char			hostnqn[NVME_NQN_FIELD_SIZE];
+						/* passed to kernel */
+	int			all;		/* passed to kernel */
+	int			spare[4];
+};
+
+union ctl_nvmf_data {
+	struct nvmf_handoff_controller_qpair	handoff;
+	struct ctl_nvmf_list_params		list;
+	struct ctl_nvmf_terminate_params	terminate;
+};
+
+/*
+ * NVMe over Fabrics interface
+ *
+ * status:		The status of the request.  See above for the
+ *			description of the values of this field.
+ *
+ * error_str:		If the status indicates an error, this string will
+ *			be filled in to describe the error.
+ */
+struct ctl_nvmf {
+	ctl_nvmf_type		type;		/* passed to kernel */
+	union ctl_nvmf_data	data;		/* passed to kernel */
+	ctl_nvmf_status		status;		/* passed to userland */
+	char			error_str[CTL_ERROR_STR_LEN];
+						/* passed to userland */
+};
+
 #define	CTL_IO			_IOWR(CTL_MINOR, 0x00, union ctl_io)
 #define	CTL_ENABLE_PORT		_IOW(CTL_MINOR, 0x04, struct ctl_port_entry)
 #define	CTL_DISABLE_PORT	_IOW(CTL_MINOR, 0x05, struct ctl_port_entry)
@@ -778,6 +839,7 @@ struct ctl_lun_map {
 #define	CTL_LUN_MAP		_IOW(CTL_MINOR, 0x28, struct ctl_lun_map)
 #define	CTL_GET_LUN_STATS	_IOWR(CTL_MINOR, 0x29, struct ctl_get_io_stats)
 #define	CTL_GET_PORT_STATS	_IOWR(CTL_MINOR, 0x2a, struct ctl_get_io_stats)
+#define	CTL_NVMF		_IOWR(CTL_MINOR, 0x2b, struct ctl_nvmf)
 
 #endif /* _CTL_IOCTL_H_ */