diff --git a/sys/cam/ctl/ctl.h b/sys/cam/ctl/ctl.h --- a/sys/cam/ctl/ctl.h +++ b/sys/cam/ctl/ctl.h @@ -55,6 +55,7 @@ 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.c b/sys/cam/ctl/ctl.c --- a/sys/cam/ctl/ctl.c +++ b/sys/cam/ctl/ctl.c @@ -3217,6 +3217,23 @@ 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_ioctl.h b/sys/cam/ctl/ctl_ioctl.h --- a/sys/cam/ctl/ctl_ioctl.h +++ b/sys/cam/ctl/ctl_ioctl.h @@ -48,6 +48,8 @@ #include #include +#include +#include #define CTL_DEFAULT_DEV "/dev/cam/ctl" /* @@ -761,6 +763,65 @@ 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 @@ #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_ */