summaryrefslogtreecommitdiffstats
path: root/src/nvme/mi.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2022-11-05 18:17:17 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2022-11-05 18:17:17 +0000
commit0e75b5495117b9888b7a557fab1db40145a9a705 (patch)
treee294b5156b7a85197e4b3192b6fba291a26dd5c6 /src/nvme/mi.h
parentAdding upstream version 1.1. (diff)
downloadlibnvme-0e75b5495117b9888b7a557fab1db40145a9a705.tar.xz
libnvme-0e75b5495117b9888b7a557fab1db40145a9a705.zip
Adding upstream version 1.2.upstream/1.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/nvme/mi.h')
-rw-r--r--src/nvme/mi.h1458
1 files changed, 1435 insertions, 23 deletions
diff --git a/src/nvme/mi.h b/src/nvme/mi.h
index a7ed240..ab4216d 100644
--- a/src/nvme/mi.h
+++ b/src/nvme/mi.h
@@ -367,6 +367,20 @@ struct nvme_mi_admin_resp_hdr {
__le32 cdw0, cdw1, cdw3;
} __attribute__((packed));
+/**
+ * nvme_mi_status_to_string() - return a string representation of the MI
+ * status.
+ * @status: MI response status
+ *
+ * Gives a string description of @status, as per section 4.1.2 of the NVMe-MI
+ * spec. The status value should be of type NVME_STATUS_MI, and extracted
+ * from the return value using nvme_status_get_value().
+ *
+ * Returned string is const, and should not be free()ed.
+ *
+ * Returns: A string representing the status value
+ */
+const char *nvme_mi_status_to_string(int status);
/**
* nvme_mi_create_root() - Create top-level MI (root) handle.
@@ -601,7 +615,8 @@ nvme_root_t nvme_mi_scan_mctp(void);
* so, all existing controller objects will be freed - the caller must not
* hold a reference to those across this call.
*
- * Return: 0 on success, non-zero on failure
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
*
* See: &nvme_mi_for_each_ctrl
*/
@@ -652,7 +667,8 @@ char *nvme_mi_endpoint_desc(nvme_mi_ep_t ep);
* Retrieves the Subsystem information - number of external ports and
* NVMe version information. See &struct nvme_mi_read_nvm_ss_info.
*
- * Return: 0 on success, non-zero on failure.
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise..
*/
int nvme_mi_mi_read_mi_data_subsys(nvme_mi_ep_t ep,
struct nvme_mi_read_nvm_ss_info *s);
@@ -670,7 +686,8 @@ int nvme_mi_mi_read_mi_data_subsys(nvme_mi_ep_t ep,
*
* See &struct nvme_mi_read_port_info.
*
- * Return: 0 on success, non-zero on failure.
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise..
*/
int nvme_mi_mi_read_mi_data_port(nvme_mi_ep_t ep, __u8 portid,
struct nvme_mi_read_port_info *p);
@@ -687,7 +704,8 @@ int nvme_mi_mi_read_mi_data_port(nvme_mi_ep_t ep, __u8 portid,
*
* See &struct nvme_ctrl_list.
*
- * Return: 0 on success, non-zero on failure.
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise..
*/
int nvme_mi_mi_read_mi_data_ctrl_list(nvme_mi_ep_t ep, __u8 start_ctrlid,
struct nvme_ctrl_list *list);
@@ -704,7 +722,8 @@ int nvme_mi_mi_read_mi_data_ctrl_list(nvme_mi_ep_t ep, __u8 start_ctrlid,
*
* See &struct nvme_mi_read_ctrl_info.
*
- * Return: 0 on success, non-zero on failure.
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise..
*/
int nvme_mi_mi_read_mi_data_ctrl(nvme_mi_ep_t ep, __u16 ctrl_id,
struct nvme_mi_read_ctrl_info *ctrl);
@@ -722,7 +741,8 @@ int nvme_mi_mi_read_mi_data_ctrl(nvme_mi_ep_t ep, __u16 ctrl_id,
*
* See &struct nvme_mi_nvm_ss_health_status.
*
- * Return: 0 on success, non-zero on failure.
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise..
*/
int nvme_mi_mi_subsystem_health_status_poll(nvme_mi_ep_t ep, bool clear,
struct nvme_mi_nvm_ss_health_status *nshds);
@@ -744,7 +764,8 @@ int nvme_mi_mi_subsystem_health_status_poll(nvme_mi_ep_t ep, bool clear,
*
* See &enum nvme_mi_config_id for identifiers.
*
- * Return: 0 on success, non-zero on failure.
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise..
*/
int nvme_mi_mi_config_get(nvme_mi_ep_t ep, __u32 dw0, __u32 dw1,
__u32 *nmresp);
@@ -761,7 +782,8 @@ int nvme_mi_mi_config_get(nvme_mi_ep_t ep, __u32 dw0, __u32 dw1,
*
* See &enum nvme_mi_config_id for identifiers.
*
- * Return: 0 on success, non-zero on failure.
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise..
*/
int nvme_mi_mi_config_set(nvme_mi_ep_t ep, __u32 dw0, __u32 dw1);
@@ -775,7 +797,8 @@ int nvme_mi_mi_config_set(nvme_mi_ep_t ep, __u32 dw0, __u32 dw1);
* the port specified in @port. On success, populates @freq with the port
* frequency
*
- * Return: 0 on success, non-zero on failure.
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise..
*/
static inline int nvme_mi_mi_config_get_smbus_freq(nvme_mi_ep_t ep, __u8 port,
enum nvme_mi_config_smbus_freq *freq)
@@ -787,7 +810,7 @@ static inline int nvme_mi_mi_config_get_smbus_freq(nvme_mi_ep_t ep, __u8 port,
rc = nvme_mi_mi_config_get(ep, dw0, 0, &tmp);
if (!rc)
- *freq = tmp & 0x3;
+ *freq = (enum nvme_mi_config_smbus_freq)(tmp & 0x3);
return rc;
}
@@ -803,7 +826,8 @@ static inline int nvme_mi_mi_config_get_smbus_freq(nvme_mi_ep_t ep, __u8 port,
* See &struct nvme_mi_read_port_info for the maximum supported SMBus frequency
* for the port.
*
- * Return: 0 on success, non-zero on failure.
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise..
*/
static inline int nvme_mi_mi_config_set_smbus_freq(nvme_mi_ep_t ep, __u8 port,
enum nvme_mi_config_smbus_freq freq)
@@ -828,7 +852,8 @@ static inline int nvme_mi_mi_config_set_smbus_freq(nvme_mi_ep_t ep, __u8 port,
* See &nvme_mi_mi_subsystem_health_status_poll(), &enum nvme_mi_ccs for
* values in @mask.
*
- * Return: 0 on success, non-zero on failure.
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise..
*/
static inline int nvme_mi_mi_config_set_health_status_change(nvme_mi_ep_t ep,
__u32 mask)
@@ -852,7 +877,8 @@ static inline int nvme_mi_mi_config_set_health_status_change(nvme_mi_ep_t ep,
* Some controllers may also use this as the maximum receive unit size, and
* may not accept MCTP messages larger than the configured MTU.
*
- * Return: 0 on success, non-zero on failure.
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise..
*/
static inline int nvme_mi_mi_config_get_mctp_mtu(nvme_mi_ep_t ep, __u8 port,
__u16 *mtu)
@@ -882,7 +908,8 @@ static inline int nvme_mi_mi_config_get_mctp_mtu(nvme_mi_ep_t ep, __u8 port,
* this value, you will likely need to change the MTU of the local MCTP
* interface(s) to match.
*
- * Return: 0 on success, non-zero on failure.
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise..
*/
static inline int nvme_mi_mi_config_set_mctp_mtu(nvme_mi_ep_t ep, __u8 port,
__u16 mtu)
@@ -918,7 +945,8 @@ static inline int nvme_mi_mi_config_set_mctp_mtu(nvme_mi_ep_t ep, __u8 port,
*
* See: &struct nvme_mi_admin_req_hdr and &struct nvme_mi_admin_resp_hdr.
*
- * Return: 0 on success, non-zero on failure.
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise..
*/
int nvme_mi_admin_xfer(nvme_mi_ctrl_t ctrl,
struct nvme_mi_admin_req_hdr *admin_req,
@@ -949,7 +977,8 @@ int nvme_mi_admin_xfer(nvme_mi_ctrl_t ctrl,
* of this. If the type of your identify command is standardized but not
* yet supported by libnvme-mi, please contact the maintainers.
*
- * Return: 0 on success, non-zero on failure
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
*
* See: &struct nvme_identify_args
*/
@@ -969,7 +998,8 @@ int nvme_mi_admin_identify_partial(nvme_mi_ctrl_t ctrl,
* Will return an error if the length of the response data (from the
* controller) is not a full &NVME_IDENTIFY_DATA_SIZE.
*
- * Return: 0 on success, non-zero on failure
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
*
* See: &struct nvme_identify_args
*/
@@ -997,7 +1027,8 @@ static inline int nvme_mi_admin_identify(nvme_mi_ctrl_t ctrl,
* Will return an error if the length of the response data (from the
* controller) is not a full &NVME_IDENTIFY_DATA_SIZE.
*
- * Return: 0 on success, non-zero on failure
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
*/
static inline int nvme_mi_admin_identify_cns_nsid(nvme_mi_ctrl_t ctrl,
enum nvme_identify_cns cns,
@@ -1019,6 +1050,69 @@ static inline int nvme_mi_admin_identify_cns_nsid(nvme_mi_ctrl_t ctrl,
}
/**
+ * nvme_mi_admin_identify_ns() - Perform an Admin identify command for a
+ * namespace
+ * @ctrl: Controller to process identify command
+ * @nsid: namespace ID
+ * @ns: Namespace identification to populate
+ *
+ * Perform an Identify (namespace) command, setting the namespace id data
+ * in @ns. The namespace is expected to active and allocated.
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_identify_ns(nvme_mi_ctrl_t ctrl, __u32 nsid,
+ struct nvme_id_ns *ns)
+{
+ return nvme_mi_admin_identify_cns_nsid(ctrl, NVME_IDENTIFY_CNS_NS,
+ nsid, ns);
+}
+
+/**
+ * nvme_mi_admin_identify_ns_descs() - Perform an Admin identify Namespace
+ * Identification Descriptor list command for a namespace
+ * @ctrl: Controller to process identify command
+ * @nsid: Namespace ID
+ * @descs: Namespace Identification Descriptor list to populate
+ *
+ * Perform an Identify namespace identification description list command,
+ * setting the namespace identification description list in @descs
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_identify_ns_descs(nvme_mi_ctrl_t ctrl,
+ __u32 nsid,
+ struct nvme_ns_id_desc *descs)
+{
+ return nvme_mi_admin_identify_cns_nsid(ctrl, NVME_IDENTIFY_CNS_NS_DESC_LIST,
+ nsid, descs);
+}
+
+/**
+ * nvme_mi_admin_identify_allocated_ns() - Perform an Admin identify command
+ * for an allocated namespace
+ * @ctrl: Controller to process identify command
+ * @nsid: namespace ID
+ * @ns: Namespace identification to populate
+ *
+ * Perform an Identify (namespace) command, setting the namespace id data
+ * in @ns.
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_identify_allocated_ns(nvme_mi_ctrl_t ctrl,
+ __u32 nsid,
+ struct nvme_id_ns *ns)
+{
+ return nvme_mi_admin_identify_cns_nsid(ctrl,
+ NVME_IDENTIFY_CNS_ALLOCATED_NS,
+ nsid, ns);
+}
+
+/**
* nvme_mi_admin_identify_ctrl() - Perform an Admin identify for a controller
* @ctrl: Controller to process identify command
* @id: Controller identify data to populate
@@ -1030,7 +1124,8 @@ static inline int nvme_mi_admin_identify_cns_nsid(nvme_mi_ctrl_t ctrl,
* controller) is not a full &NVME_IDENTIFY_DATA_SIZE, so @id will be
* fully populated on success.
*
- * Return: 0 on success, non-zero on failure
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
*
* See: &struct nvme_id_ctrl
*/
@@ -1055,7 +1150,8 @@ static inline int nvme_mi_admin_identify_ctrl(nvme_mi_ctrl_t ctrl,
* controller) is not a full &NVME_IDENTIFY_DATA_SIZE, so @id will be
* fully populated on success.
*
- * Return: 0 on success, non-zero on failure
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
*
* See: &struct nvme_ctrl_list
*/
@@ -1079,6 +1175,198 @@ static inline int nvme_mi_admin_identify_ctrl_list(nvme_mi_ctrl_t ctrl,
}
/**
+ * nvme_mi_admin_identify_nsid_ctrl_list() - Perform an Admin identify for a
+ * controller list with specific namespace ID
+ * @ctrl: Controller to process identify command
+ * @nsid: Namespace identifier
+ * @cntid: Controller ID to specify list start
+ * @list: List data to populate
+ *
+ * Perform an Identify command, for the controller list for @nsid, starting
+ * with IDs greater than or equal to @cntid.
+ *
+ * Will return an error if the length of the response data (from the
+ * controller) is not a full &NVME_IDENTIFY_DATA_SIZE, so @id will be
+ * fully populated on success.
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ *
+ * See: &struct nvme_ctrl_list
+ */
+static inline int nvme_mi_admin_identify_nsid_ctrl_list(nvme_mi_ctrl_t ctrl,
+ __u32 nsid, __u16 cntid,
+ struct nvme_ctrl_list *list)
+{
+ struct nvme_identify_args args = {
+ .result = NULL,
+ .data = list,
+ .args_size = sizeof(args),
+ .cns = NVME_IDENTIFY_CNS_CTRL_LIST,
+ .csi = NVME_CSI_NVM,
+ .nsid = nsid,
+ .cntid = cntid,
+ .cns_specific_id = NVME_CNSSPECID_NONE,
+ .uuidx = NVME_UUID_NONE,
+ };
+
+ return nvme_mi_admin_identify(ctrl, &args);
+}
+
+/**
+ * nvme_mi_admin_identify_allocated_ns_list() - Perform an Admin identify for
+ * an allocated namespace list
+ * @ctrl: Controller to process identify command
+ * @nsid: Namespace ID to specify list start
+ * @list: List data to populate
+ *
+ * Perform an Identify command, for the allocated namespace list starting with
+ * IDs greater than or equal to @nsid. Specify &NVME_NSID_NONE for the start
+ * of the list.
+ *
+ * Will return an error if the length of the response data (from the
+ * controller) is not a full &NVME_IDENTIFY_DATA_SIZE, so @list will be
+ * be fully populated on success.
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ *
+ * See: &struct nvme_ns_list
+ */
+static inline int nvme_mi_admin_identify_allocated_ns_list(nvme_mi_ctrl_t ctrl,
+ __u32 nsid,
+ struct nvme_ns_list *list)
+{
+ struct nvme_identify_args args = {
+ .result = NULL,
+ .data = list,
+ .args_size = sizeof(args),
+ .cns = NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST,
+ .csi = NVME_CSI_NVM,
+ .nsid = nsid,
+ .cns_specific_id = NVME_CNSSPECID_NONE,
+ .uuidx = NVME_UUID_NONE,
+ };
+
+ return nvme_mi_admin_identify(ctrl, &args);
+}
+
+/**
+ * nvme_mi_admin_identify_active_ns_list() - Perform an Admin identify for an
+ * active namespace list
+ * @ctrl: Controller to process identify command
+ * @nsid: Namespace ID to specify list start
+ * @list: List data to populate
+ *
+ * Perform an Identify command, for the active namespace list starting with
+ * IDs greater than or equal to @nsid. Specify &NVME_NSID_NONE for the start
+ * of the list.
+ *
+ * Will return an error if the length of the response data (from the
+ * controller) is not a full &NVME_IDENTIFY_DATA_SIZE, so @list will be
+ * be fully populated on success.
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ *
+ * See: &struct nvme_ns_list
+ */
+static inline int nvme_mi_admin_identify_active_ns_list(nvme_mi_ctrl_t ctrl,
+ __u32 nsid,
+ struct nvme_ns_list *list)
+{
+ struct nvme_identify_args args = {
+ .result = NULL,
+ .data = list,
+ .args_size = sizeof(args),
+ .cns = NVME_IDENTIFY_CNS_NS_ACTIVE_LIST,
+ .csi = NVME_CSI_NVM,
+ .nsid = nsid,
+ .cns_specific_id = NVME_CNSSPECID_NONE,
+ .uuidx = NVME_UUID_NONE,
+ };
+
+ return nvme_mi_admin_identify(ctrl, &args);
+}
+
+/**
+ * nvme_mi_admin_identify_primary_ctrl() - Perform an Admin identify for
+ * primary controller capabilities data structure.
+ * @ctrl: Controller to process identify command
+ * @cntid: Controller ID to specify
+ * @cap: Primary Controller Capabilities data structure to populate
+ *
+ * Perform an Identify command to get the Primary Controller Capabilities data
+ * for the controller specified by @cntid
+ *
+ * Will return an error if the length of the response data (from the
+ * controller) is not a full &NVME_IDENTIFY_DATA_SIZE, so @cap will be
+ * be fully populated on success.
+ *
+ * Return: 0 on success, non-zero on failure
+ *
+ * See: &struct nvme_primary_ctrl_cap
+ */
+static inline int nvme_mi_admin_identify_primary_ctrl(nvme_mi_ctrl_t ctrl,
+ __u16 cntid,
+ struct nvme_primary_ctrl_cap *cap)
+{
+ struct nvme_identify_args args = {
+ .result = NULL,
+ .data = cap,
+ .args_size = sizeof(args),
+ .cns = NVME_IDENTIFY_CNS_PRIMARY_CTRL_CAP,
+ .csi = NVME_CSI_NVM,
+ .nsid = NVME_NSID_NONE,
+ .cntid = cntid,
+ .cns_specific_id = NVME_CNSSPECID_NONE,
+ .uuidx = NVME_UUID_NONE,
+ };
+
+ return nvme_mi_admin_identify(ctrl, &args);
+}
+
+/**
+ * nvme_mi_admin_identify_secondary_ctrl_list() - Perform an Admin identify for
+ * a secondary controller list.
+ * @ctrl: Controller to process identify command
+ * @nsid: Namespace ID to specify list start
+ * @cntid: Controller ID to specify list start
+ * @list: List data to populate
+ *
+ * Perform an Identify command, for the secondary controllers associated with
+ * the current primary controller. Only entries with IDs greater than or
+ * equal to @cntid are returned.
+ *
+ * Will return an error if the length of the response data (from the
+ * controller) is not a full &NVME_IDENTIFY_DATA_SIZE, so @list will be
+ * be fully populated on success.
+ *
+ * Return: 0 on success, non-zero on failure
+ *
+ * See: &struct nvme_secondary_ctrl_list
+ */
+static inline int nvme_mi_admin_identify_secondary_ctrl_list(nvme_mi_ctrl_t ctrl,
+ __u32 nsid,
+ __u16 cntid,
+ struct nvme_secondary_ctrl_list *list)
+{
+ struct nvme_identify_args args = {
+ .result = NULL,
+ .data = list,
+ .args_size = sizeof(args),
+ .cns = NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST,
+ .csi = NVME_CSI_NVM,
+ .nsid = nsid,
+ .cntid = cntid,
+ .cns_specific_id = NVME_CNSSPECID_NONE,
+ .uuidx = NVME_UUID_NONE,
+ };
+
+ return nvme_mi_admin_identify(ctrl, &args);
+}
+
+/**
* nvme_mi_admin_get_log() - Retrieve log page data from controller
* @ctrl: Controller to query
* @args: Get Log Page command arguments
@@ -1091,13 +1379,851 @@ static inline int nvme_mi_admin_identify_ctrl_list(nvme_mi_ctrl_t ctrl,
* This request may be implemented as multiple log page commands, in order
* to fit within MI message-size limits.
*
- * Return: 0 on success, non-zero on failure
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
*
* See: &struct nvme_get_log_args
*/
int nvme_mi_admin_get_log(nvme_mi_ctrl_t ctrl, struct nvme_get_log_args *args);
/**
+ * nvme_mi_admin_get_nsid_log() - Helper for Get Log Page functions
+ * @ctrl: Controller to query
+ * @rae: Retain Asynchronous Events
+ * @lid: Log identifier
+ * @nsid: Namespace ID
+ * @len: length of log buffer
+ * @log: pointer for resulting log data
+ *
+ * Performs a Get Log Page Admin command for a specific log ID @lid and
+ * namespace ID @nsid. Log data is expected to be @len bytes, and is stored
+ * in @log on success. The @rae flag is passed as-is to the Get Log Page
+ * command, and is specific to the Log Page requested.
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_get_nsid_log(nvme_mi_ctrl_t ctrl, bool rae,
+ enum nvme_cmd_get_log_lid lid,
+ __u32 nsid, __u32 len, void *log)
+{
+ struct nvme_get_log_args args = {
+ .lpo = 0,
+ .result = NULL,
+ .log = log,
+ .args_size = sizeof(args),
+ .lid = lid,
+ .len = len,
+ .nsid = nsid,
+ .csi = NVME_CSI_NVM,
+ .lsi = NVME_LOG_LSI_NONE,
+ .lsp = NVME_LOG_LSP_NONE,
+ .uuidx = NVME_UUID_NONE,
+ .rae = rae,
+ .ot = false,
+ };
+
+ return nvme_mi_admin_get_log(ctrl, &args);
+}
+
+/**
+ * nvme_mi_admin_get_log_simple() - Helper for Get Log Page functions with no
+ * NSID or RAE requirements
+ * @ctrl: Controller to query
+ * @lid: Log identifier
+ * @len: length of log buffer
+ * @log: pointer for resulting log data
+ *
+ * Performs a Get Log Page Admin command for a specific log ID @lid, using
+ * NVME_NSID_ALL for the namespace identifier, and rae set to false.
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_get_log_simple(nvme_mi_ctrl_t ctrl,
+ enum nvme_cmd_get_log_lid lid,
+ __u32 len, void *log)
+{
+ return nvme_mi_admin_get_nsid_log(ctrl, false, lid, NVME_NSID_ALL,
+ len, log);
+}
+
+/**
+ * nvme_mi_admin_get_log_supported_log_pages() - Retrieve nmve supported log
+ * pages
+ * @ctrl: Controller to query
+ * @rae: Retain asynchronous events
+ * @log: Array of LID supported and Effects data structures
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_get_log_supported_log_pages(nvme_mi_ctrl_t ctrl,
+ bool rae,
+ struct nvme_supported_log_pages *log)
+{
+ return nvme_mi_admin_get_nsid_log(ctrl, rae,
+ NVME_LOG_LID_SUPPORTED_LOG_PAGES,
+ NVME_NSID_ALL, sizeof(*log), log);
+}
+
+/**
+ * nvme_mi_admin_get_log_error() - Retrieve nvme error log
+ * @ctrl: Controller to query
+ * @nr_entries: Number of error log entries allocated
+ * @rae: Retain asynchronous events
+ * @err_log: Array of error logs of size 'entries'
+ *
+ * This log page describes extended error information for a command that
+ * completed with error, or may report an error that is not specific to a
+ * particular command.
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_get_log_error(nvme_mi_ctrl_t ctrl,
+ unsigned int nr_entries, bool rae,
+ struct nvme_error_log_page *err_log)
+{
+ return nvme_mi_admin_get_nsid_log(ctrl, rae, NVME_LOG_LID_ERROR,
+ NVME_NSID_ALL, sizeof(*err_log) * nr_entries,
+ err_log);
+}
+
+/**
+ * nvme_mi_admin_get_log_smart() - Retrieve nvme smart log
+ * @ctrl: Controller to query
+ * @nsid: Optional namespace identifier
+ * @rae: Retain asynchronous events
+ * @smart_log: User address to store the smart log
+ *
+ * This log page provides SMART and general health information. The information
+ * provided is over the life of the controller and is retained across power
+ * cycles. To request the controller log page, the namespace identifier
+ * specified is FFFFFFFFh. The controller may also support requesting the log
+ * page on a per namespace basis, as indicated by bit 0 of the LPA field in the
+ * Identify Controller data structure.
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_get_log_smart(nvme_mi_ctrl_t ctrl, __u32 nsid,
+ bool rae,
+ struct nvme_smart_log *smart_log)
+{
+ return nvme_mi_admin_get_nsid_log(ctrl, rae, NVME_LOG_LID_SMART,
+ nsid, sizeof(*smart_log), smart_log);
+}
+
+/**
+ * nvme_mi_admin_get_log_fw_slot() - Retrieves the controller firmware log
+ * @ctrl: Controller to query
+ * @rae: Retain asynchronous events
+ * @fw_log: User address to store the log page
+ *
+ * This log page describes the firmware revision stored in each firmware slot
+ * supported. The firmware revision is indicated as an ASCII string. The log
+ * page also indicates the active slot number.
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_get_log_fw_slot(nvme_mi_ctrl_t ctrl, bool rae,
+ struct nvme_firmware_slot *fw_log)
+{
+ return nvme_mi_admin_get_nsid_log(ctrl, rae, NVME_LOG_LID_FW_SLOT,
+ NVME_NSID_ALL, sizeof(*fw_log), fw_log);
+}
+
+/**
+ * nvme_mi_admin_get_log_changed_ns_list() - Retrieve namespace changed list
+ * @ctrl: Controller to query
+ * @rae: Retain asynchronous events
+ * @ns_log: User address to store the log page
+ *
+ * This log page describes namespaces attached to this controller that have
+ * changed since the last time the namespace was identified, been added, or
+ * deleted.
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_get_log_changed_ns_list(nvme_mi_ctrl_t ctrl,
+ bool rae,
+ struct nvme_ns_list *ns_log)
+{
+ return nvme_mi_admin_get_nsid_log(ctrl, rae, NVME_LOG_LID_CHANGED_NS,
+ NVME_NSID_ALL, sizeof(*ns_log), ns_log);
+}
+
+/**
+ * nvme_mi_admin_get_log_cmd_effects() - Retrieve nvme command effects log
+ * @ctrl: Controller to query
+ * @csi: Command Set Identifier
+ * @effects_log: User address to store the effects log
+ *
+ * This log page describes the commands that the controller supports and the
+ * effects of those commands on the state of the NVM subsystem.
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_get_log_cmd_effects(nvme_mi_ctrl_t ctrl,
+ enum nvme_csi csi,
+ struct nvme_cmd_effects_log *effects_log)
+{
+ struct nvme_get_log_args args = {
+ .lpo = 0,
+ .result = NULL,
+ .log = effects_log,
+ .args_size = sizeof(args),
+ .lid = NVME_LOG_LID_CMD_EFFECTS,
+ .len = sizeof(*effects_log),
+ .nsid = NVME_NSID_ALL,
+ .csi = csi,
+ .lsi = NVME_LOG_LSI_NONE,
+ .lsp = NVME_LOG_LSP_NONE,
+ .uuidx = NVME_UUID_NONE,
+ .rae = false,
+ .ot = false,
+ };
+ return nvme_mi_admin_get_log(ctrl, &args);
+}
+
+/**
+ * nvme_mi_admin_get_log_device_self_test() - Retrieve the device self test log
+ * @ctrl: Controller to query
+ * @log: Userspace address of the log payload
+ *
+ * The log page indicates the status of an in progress self test and the
+ * percent complete of that operation, and the results of the previous 20
+ * self-test operations.
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_get_log_device_self_test(nvme_mi_ctrl_t ctrl,
+ struct nvme_self_test_log *log)
+{
+ return nvme_mi_admin_get_nsid_log(ctrl, false,
+ NVME_LOG_LID_DEVICE_SELF_TEST,
+ NVME_NSID_ALL, sizeof(*log), log);
+}
+
+/**
+ * nvme_mi_admin_get_log_create_telemetry_host() - Create host telemetry log
+ * @ctrl: Controller to query
+ * @log: Userspace address of the log payload
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_get_log_create_telemetry_host(nvme_mi_ctrl_t ctrl,
+ struct nvme_telemetry_log *log)
+{
+ struct nvme_get_log_args args = {
+ .lpo = 0,
+ .result = NULL,
+ .log = log,
+ .args_size = sizeof(args),
+ .lid = NVME_LOG_LID_TELEMETRY_HOST,
+ .len = sizeof(*log),
+ .nsid = NVME_NSID_NONE,
+ .csi = NVME_CSI_NVM,
+ .lsi = NVME_LOG_LSI_NONE,
+ .lsp = NVME_LOG_TELEM_HOST_LSP_CREATE,
+ .uuidx = NVME_UUID_NONE,
+ .rae = false,
+ .ot = false,
+ };
+ return nvme_mi_admin_get_log(ctrl, &args);
+}
+
+/**
+ * nvme_mi_admin_get_log_telemetry_host() - Get Telemetry Host-Initiated log
+ * page
+ * @ctrl: Controller to query
+ * @offset: Offset into the telemetry data
+ * @len: Length of provided user buffer to hold the log data in bytes
+ * @log: User address for log page data
+ *
+ * Retrieves the Telemetry Host-Initiated log page at the requested offset
+ * using the previously existing capture.
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_get_log_telemetry_host(nvme_mi_ctrl_t ctrl,
+ __u64 offset, __u32 len,
+ void *log)
+{
+ struct nvme_get_log_args args = {
+ .lpo = offset,
+ .result = NULL,
+ .log = log,
+ .args_size = sizeof(args),
+ .lid = NVME_LOG_LID_TELEMETRY_HOST,
+ .len = len,
+ .nsid = NVME_NSID_NONE,
+ .csi = NVME_CSI_NVM,
+ .lsi = NVME_LOG_LSI_NONE,
+ .lsp = NVME_LOG_TELEM_HOST_LSP_RETAIN,
+ .uuidx = NVME_UUID_NONE,
+ .rae = false,
+ .ot = false,
+ };
+ return nvme_mi_admin_get_log(ctrl, &args);
+}
+
+/**
+ * nvme_mi_admin_get_log_telemetry_ctrl() - Get Telemetry Controller-Initiated
+ * log page
+ * @ctrl: Controller to query
+ * @rae: Retain asynchronous events
+ * @offset: Offset into the telemetry data
+ * @len: Length of provided user buffer to hold the log data in bytes
+ * @log: User address for log page data
+ *
+ * Retrieves the Telemetry Controller-Initiated log page at the requested offset
+ * using the previously existing capture.
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_get_log_telemetry_ctrl(nvme_mi_ctrl_t ctrl,
+ bool rae,
+ __u64 offset, __u32 len,
+ void *log)
+{
+ struct nvme_get_log_args args = {
+ .lpo = offset,
+ .result = NULL,
+ .log = log,
+ .args_size = sizeof(args),
+ .lid = NVME_LOG_LID_TELEMETRY_CTRL,
+ .len = len,
+ .nsid = NVME_NSID_NONE,
+ .csi = NVME_CSI_NVM,
+ .lsi = NVME_LOG_LSI_NONE,
+ .lsp = NVME_LOG_LSP_NONE,
+ .uuidx = NVME_UUID_NONE,
+ .rae = rae,
+ .ot = false,
+ };
+ return nvme_mi_admin_get_log(ctrl, &args);
+}
+
+/**
+ * nvme_mi_admin_get_log_endurance_group() - Get Endurance Group log
+ * @ctrl: Controller to query
+ * @endgid: Starting group identifier to return in the list
+ * @log: User address to store the endurance log
+ *
+ * This log page indicates if an Endurance Group Event has occurred for a
+ * particular Endurance Group. If an Endurance Group Event has occurred, the
+ * details of the particular event are included in the Endurance Group
+ * Information log page for that Endurance Group. An asynchronous event is
+ * generated when an entry for an Endurance Group is newly added to this log
+ * page.
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_get_log_endurance_group(nvme_mi_ctrl_t ctrl,
+ __u16 endgid,
+ struct nvme_endurance_group_log *log)
+{
+ struct nvme_get_log_args args = {
+ .lpo = 0,
+ .result = NULL,
+ .log = log,
+ .args_size = sizeof(args),
+ .lid = NVME_LOG_LID_ENDURANCE_GROUP,
+ .len = sizeof(*log),
+ .nsid = NVME_NSID_NONE,
+ .csi = NVME_CSI_NVM,
+ .lsi = endgid,
+ .lsp = NVME_LOG_LSP_NONE,
+ .uuidx = NVME_UUID_NONE,
+ .rae = false,
+ .ot = false,
+ };
+ return nvme_mi_admin_get_log(ctrl, &args);
+}
+
+/**
+ * nvme_mi_admin_get_log_predictable_lat_nvmset() - Predictable Latency Per NVM
+ * Set
+ * @ctrl: Controller to query
+ * @nvmsetid: NVM set id
+ * @log: User address to store the predictable latency log
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_get_log_predictable_lat_nvmset(nvme_mi_ctrl_t ctrl,
+ __u16 nvmsetid,
+ struct nvme_nvmset_predictable_lat_log *log)
+{
+ struct nvme_get_log_args args = {
+ .lpo = 0,
+ .result = NULL,
+ .log = log,
+ .args_size = sizeof(args),
+ .lid = NVME_LOG_LID_PREDICTABLE_LAT_NVMSET,
+ .len = sizeof(*log),
+ .nsid = NVME_NSID_NONE,
+ .csi = NVME_CSI_NVM,
+ .lsi = nvmsetid,
+ .lsp = NVME_LOG_LSP_NONE,
+ .uuidx = NVME_UUID_NONE,
+ .rae = false,
+ .ot = false,
+ };
+ return nvme_mi_admin_get_log(ctrl, &args);
+}
+
+/**
+ * nvme_mi_admin_get_log_predictable_lat_event() - Retrieve Predictable Latency
+ * Event Aggregate Log Page
+ * @ctrl: Controller to query
+ * @rae: Retain asynchronous events
+ * @offset: Offset into the predictable latency event
+ * @len: Length of provided user buffer to hold the log data in bytes
+ * @log: User address for log page data
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_get_log_predictable_lat_event(nvme_mi_ctrl_t ctrl,
+ bool rae,
+ __u32 offset,
+ __u32 len,
+ void *log)
+{
+ struct nvme_get_log_args args = {
+ .lpo = offset,
+ .result = NULL,
+ .log = log,
+ .args_size = sizeof(args),
+ .lid = NVME_LOG_LID_PREDICTABLE_LAT_AGG,
+ .len = len,
+ .nsid = NVME_NSID_NONE,
+ .csi = NVME_CSI_NVM,
+ .lsi = NVME_LOG_LSI_NONE,
+ .lsp = NVME_LOG_LSP_NONE,
+ .uuidx = NVME_UUID_NONE,
+ .rae = rae,
+ .ot = false,
+ };
+ return nvme_mi_admin_get_log(ctrl, &args);
+}
+
+/**
+ * nvme_mi_admin_get_log_ana() - Retrieve Asymmetric Namespace Access log page
+ * @ctrl: Controller to query
+ * @lsp: Log specific, see &enum nvme_get_log_ana_lsp
+ * @rae: Retain asynchronous events
+ * @offset: Offset to the start of the log page
+ * @len: The allocated length of the log page
+ * @log: User address to store the ana log
+ *
+ * This log consists of a header describing the log and descriptors containing
+ * the asymmetric namespace access information for ANA Groups that contain
+ * namespaces that are attached to the controller processing the command.
+ *
+ * See &struct nvme_ana_rsp_hdr for the definition of the returned structure.
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_get_log_ana(nvme_mi_ctrl_t ctrl,
+ enum nvme_log_ana_lsp lsp, bool rae,
+ __u64 offset, __u32 len, void *log)
+{
+ struct nvme_get_log_args args = {
+ .lpo = offset,
+ .result = NULL,
+ .log = log,
+ .args_size = sizeof(args),
+ .lid = NVME_LOG_LID_ANA,
+ .len = len,
+ .nsid = NVME_NSID_NONE,
+ .csi = NVME_CSI_NVM,
+ .lsi = NVME_LOG_LSI_NONE,
+ .lsp = (__u8)lsp,
+ .uuidx = NVME_UUID_NONE,
+ .rae = false,
+ .ot = false,
+ };
+ return nvme_mi_admin_get_log(ctrl, &args);
+}
+
+/**
+ * nvme_mi_admin_get_log_ana_groups() - Retrieve Asymmetric Namespace Access
+ * groups only log page
+ * @ctrl: Controller to query
+ * @rae: Retain asynchronous events
+ * @len: The allocated length of the log page
+ * @log: User address to store the ana group log
+ *
+ * See &struct nvme_ana_group_desc for the definition of the returned structure.
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_get_log_ana_groups(nvme_mi_ctrl_t ctrl,
+ bool rae, __u32 len,
+ struct nvme_ana_group_desc *log)
+{
+ return nvme_mi_admin_get_log_ana(ctrl, NVME_LOG_ANA_LSP_RGO_GROUPS_ONLY, rae, 0,
+ len, log);
+}
+
+/**
+ * nvme_mi_admin_get_log_lba_status() - Retrieve LBA Status
+ * @ctrl: Controller to query
+ * @rae: Retain asynchronous events
+ * @offset: Offset to the start of the log page
+ * @len: The allocated length of the log page
+ * @log: User address to store the log page
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_get_log_lba_status(nvme_mi_ctrl_t ctrl, bool rae,
+ __u64 offset, __u32 len,
+ void *log)
+{
+ struct nvme_get_log_args args = {
+ .lpo = offset,
+ .result = NULL,
+ .log = log,
+ .args_size = sizeof(args),
+ .lid = NVME_LOG_LID_LBA_STATUS,
+ .len = len,
+ .nsid = NVME_NSID_NONE,
+ .csi = NVME_CSI_NVM,
+ .lsi = NVME_LOG_LSI_NONE,
+ .lsp = NVME_LOG_LSP_NONE,
+ .uuidx = NVME_UUID_NONE,
+ .rae = rae,
+ .ot = false,
+ };
+ return nvme_mi_admin_get_log(ctrl, &args);
+}
+
+/**
+ * nvme_mi_admin_get_log_endurance_grp_evt() - Retrieve Rotational Media
+ * Information
+ * @ctrl: Controller to query
+ * @rae: Retain asynchronous events
+ * @offset: Offset to the start of the log page
+ * @len: The allocated length of the log page
+ * @log: User address to store the log page
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_get_log_endurance_grp_evt(nvme_mi_ctrl_t ctrl,
+ bool rae,
+ __u32 offset,
+ __u32 len,
+ void *log)
+{
+ struct nvme_get_log_args args = {
+ .lpo = offset,
+ .result = NULL,
+ .log = log,
+ .args_size = sizeof(args),
+ .lid = NVME_LOG_LID_ENDURANCE_GRP_EVT,
+ .len = len,
+ .nsid = NVME_NSID_NONE,
+ .csi = NVME_CSI_NVM,
+ .lsi = NVME_LOG_LSI_NONE,
+ .lsp = NVME_LOG_LSP_NONE,
+ .uuidx = NVME_UUID_NONE,
+ .rae = rae,
+ .ot = false,
+ };
+ return nvme_mi_admin_get_log(ctrl, &args);
+}
+
+/**
+ * nvme_mi_admin_get_log_fid_supported_effects() - Retrieve Feature Identifiers
+ * Supported and Effects
+ * @ctrl: Controller to query
+ * @rae: Retain asynchronous events
+ * @log: FID Supported and Effects data structure
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_get_log_fid_supported_effects(nvme_mi_ctrl_t ctrl,
+ bool rae,
+ struct nvme_fid_supported_effects_log *log)
+{
+ return nvme_mi_admin_get_nsid_log(ctrl, rae,
+ NVME_LOG_LID_FID_SUPPORTED_EFFECTS,
+ NVME_NSID_NONE, sizeof(*log), log);
+}
+
+/**
+ * nvme_mi_admin_get_log_mi_cmd_supported_effects() - displays the MI Commands
+ * Supported by the controller
+ * @ctrl: Controller to query
+ * @rae: Retain asynchronous events
+ * @log: MI Command Supported and Effects data structure
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_get_log_mi_cmd_supported_effects(nvme_mi_ctrl_t ctrl,
+ bool rae,
+ struct nvme_mi_cmd_supported_effects_log *log)
+{
+ return nvme_mi_admin_get_nsid_log(ctrl, rae, NVME_LOG_LID_MI_CMD_SUPPORTED_EFFECTS,
+ NVME_NSID_NONE, sizeof(*log), log);
+}
+
+/**
+ * nvme_mi_admin_get_log_boot_partition() - Retrieve Boot Partition
+ * @ctrl: Controller to query
+ * @rae: Retain asynchronous events
+ * @lsp: The log specified field of LID
+ * @len: The allocated size, minimum
+ * struct nvme_boot_partition
+ * @part: User address to store the log page
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_get_log_boot_partition(nvme_mi_ctrl_t ctrl,
+ bool rae, __u8 lsp,
+ __u32 len,
+ struct nvme_boot_partition *part)
+{
+ struct nvme_get_log_args args = {
+ .lpo = 0,
+ .result = NULL,
+ .log = part,
+ .args_size = sizeof(args),
+ .lid = NVME_LOG_LID_BOOT_PARTITION,
+ .len = len,
+ .nsid = NVME_NSID_NONE,
+ .csi = NVME_CSI_NVM,
+ .lsi = NVME_LOG_LSI_NONE,
+ .lsp = NVME_LOG_LSP_NONE,
+ .uuidx = NVME_UUID_NONE,
+ .rae = rae,
+ .ot = false,
+ };
+ return nvme_mi_admin_get_log(ctrl, &args);
+}
+
+/**
+ * nvme_mi_admin_get_log_discovery() - Retrieve Discovery log page
+ * @ctrl: Controller to query
+ * @rae: Retain asynchronous events
+ * @offset: Offset of this log to retrieve
+ * @len: The allocated size for this portion of the log
+ * @log: User address to store the discovery log
+ *
+ * Supported only by fabrics discovery controllers, returning discovery
+ * records.
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_get_log_discovery(nvme_mi_ctrl_t ctrl, bool rae,
+ __u32 offset, __u32 len,
+ void *log)
+{
+ struct nvme_get_log_args args = {
+ .lpo = offset,
+ .result = NULL,
+ .log = log,
+ .args_size = sizeof(args),
+ .lid = NVME_LOG_LID_DISCOVER,
+ .len = len,
+ .nsid = NVME_NSID_NONE,
+ .csi = NVME_CSI_NVM,
+ .lsi = NVME_LOG_LSI_NONE,
+ .lsp = NVME_LOG_LSP_NONE,
+ .uuidx = NVME_UUID_NONE,
+ .rae = rae,
+ .ot = false,
+ };
+ return nvme_mi_admin_get_log(ctrl, &args);
+}
+
+/**
+ * nvme_mi_admin_get_log_media_unit_stat() - Retrieve Media Unit Status
+ * @ctrl: Controller to query
+ * @domid: Domain Identifier selection, if supported
+ * @mus: User address to store the Media Unit statistics log
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_get_log_media_unit_stat(nvme_mi_ctrl_t ctrl,
+ __u16 domid,
+ struct nvme_media_unit_stat_log *mus)
+{
+ struct nvme_get_log_args args = {
+ .lpo = 0,
+ .result = NULL,
+ .log = mus,
+ .args_size = sizeof(args),
+ .lid = NVME_LOG_LID_MEDIA_UNIT_STATUS,
+ .len = sizeof(*mus),
+ .nsid = NVME_NSID_NONE,
+ .csi = NVME_CSI_NVM,
+ .lsi = domid,
+ .lsp = NVME_LOG_LSP_NONE,
+ .uuidx = NVME_UUID_NONE,
+ .rae = false,
+ .ot = false,
+ };
+ return nvme_mi_admin_get_log(ctrl, &args);
+}
+
+/**
+ * nvme_mi_admin_get_log_support_cap_config_list() - Retrieve Supported
+ * Capacity Configuration List
+ * @ctrl: Controller to query
+ * @domid: Domain Identifier selection, if supported
+ * @cap: User address to store supported capabilities config list
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_get_log_support_cap_config_list(nvme_mi_ctrl_t ctrl,
+ __u16 domid,
+ struct nvme_supported_cap_config_list_log *cap)
+{
+ struct nvme_get_log_args args = {
+ .lpo = 0,
+ .result = NULL,
+ .log = cap,
+ .args_size = sizeof(args),
+ .lid = NVME_LOG_LID_SUPPORTED_CAP_CONFIG_LIST,
+ .len = sizeof(*cap),
+ .nsid = NVME_NSID_NONE,
+ .csi = NVME_CSI_NVM,
+ .lsi = domid,
+ .lsp = NVME_LOG_LSP_NONE,
+ .uuidx = NVME_UUID_NONE,
+ .rae = false,
+ .ot = false,
+ };
+ return nvme_mi_admin_get_log(ctrl, &args);
+}
+
+/**
+ * nvme_mi_admin_get_log_reservation() - Retrieve Reservation Notification
+ * @ctrl: Controller to query
+ * @rae: Retain asynchronous events
+ * @log: User address to store the reservation log
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_get_log_reservation(nvme_mi_ctrl_t ctrl,
+ bool rae,
+ struct nvme_resv_notification_log *log)
+{
+ return nvme_mi_admin_get_nsid_log(ctrl, rae, NVME_LOG_LID_RESERVATION,
+ NVME_NSID_ALL, sizeof(*log), log);
+}
+
+/**
+ * nvme_mi_admin_get_log_sanitize() - Retrieve Sanitize Status
+ * @ctrl: Controller to query
+ * @rae: Retain asynchronous events
+ * @log: User address to store the sanitize log
+ *
+ * The Sanitize Status log page reports sanitize operation time estimates and
+ * information about the most recent sanitize operation.
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_get_log_sanitize(nvme_mi_ctrl_t ctrl, bool rae,
+ struct nvme_sanitize_log_page *log)
+{
+ return nvme_mi_admin_get_nsid_log(ctrl, rae, NVME_LOG_LID_SANITIZE,
+ NVME_NSID_ALL, sizeof(*log), log);
+}
+
+/**
+ * nvme_mi_admin_get_log_zns_changed_zones() - Retrieve list of zones that have
+ * changed
+ * @ctrl: Controller to query
+ * @nsid: Namespace ID
+ * @rae: Retain asynchronous events
+ * @log: User address to store the changed zone log
+ *
+ * The list of zones that have changed state due to an exceptional event.
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_get_log_zns_changed_zones(nvme_mi_ctrl_t ctrl,
+ __u32 nsid, bool rae,
+ struct nvme_zns_changed_zone_log *log)
+{
+ struct nvme_get_log_args args = {
+ .lpo = 0,
+ .result = NULL,
+ .log = log,
+ .args_size = sizeof(args),
+ .lid = NVME_LOG_LID_ZNS_CHANGED_ZONES,
+ .len = sizeof(*log),
+ .nsid = nsid,
+ .csi = NVME_CSI_ZNS,
+ .lsi = NVME_LOG_LSI_NONE,
+ .lsp = NVME_LOG_LSP_NONE,
+ .uuidx = NVME_UUID_NONE,
+ .rae = rae,
+ .ot = false,
+ };
+ return nvme_mi_admin_get_log(ctrl, &args);
+}
+
+/**
+ * nvme_mi_admin_get_log_persistent_event() - Retrieve Persistent Event Log
+ * @ctrl: Controller to query
+ * @action: Action the controller should take during processing this command
+ * @size: Size of @pevent_log
+ * @pevent_log: User address to store the persistent event log
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_get_log_persistent_event(nvme_mi_ctrl_t ctrl,
+ enum nvme_pevent_log_action action,
+ __u32 size, void *pevent_log)
+{
+ struct nvme_get_log_args args = {
+ .lpo = 0,
+ .result = NULL,
+ .log = pevent_log,
+ .args_size = sizeof(args),
+ .lid = NVME_LOG_LID_PERSISTENT_EVENT,
+ .len = size,
+ .nsid = NVME_NSID_ALL,
+ .csi = NVME_CSI_NVM,
+ .lsi = NVME_LOG_LSI_NONE,
+ .lsp = (__u8)action,
+ .uuidx = NVME_UUID_NONE,
+ .rae = false,
+ .ot = false,
+ };
+ return nvme_mi_admin_get_log(ctrl, &args);
+}
+
+/**
* nvme_mi_admin_security_send() - Perform a Security Send command on a
* controller.
* @ctrl: Controller to send command to
@@ -1111,7 +2237,8 @@ int nvme_mi_admin_get_log(nvme_mi_ctrl_t ctrl, struct nvme_get_log_args *args);
* Security Send data length should not be greater than 4096 bytes to
* comply with specification limits.
*
- * Return: 0 on success, non-zero on failure
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
*
* See: &struct nvme_get_log_args
*/
@@ -1132,12 +2259,297 @@ int nvme_mi_admin_security_send(nvme_mi_ctrl_t ctrl,
* Security Receive data length should not be greater than 4096 bytes to
* comply with specification limits.
*
- * Return: 0 on success, non-zero on failure
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
*
* See: &struct nvme_get_log_args
*/
int nvme_mi_admin_security_recv(nvme_mi_ctrl_t ctrl,
struct nvme_security_receive_args *args);
+/**
+ * nvme_mi_admin_get_features - Perform a Get Feature command on a controller
+ * @ctrl: Controller to send command to
+ * @args: Get Features command arguments
+ *
+ * Performs a Get Features Admin command as specified by @args. Returned
+ * feature data will be stored in @args->result and @args->data, depending
+ * on the specification of the feature itself; most features do not return
+ * additional data. See section 5.27.1 of the NVMe spec (v2.0b) for
+ * feature-specific information.
+ *
+ * On success, @args->data_len will be updated with the actual data length
+ * received.
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+int nvme_mi_admin_get_features(nvme_mi_ctrl_t ctrl,
+ struct nvme_get_features_args *args);
+
+/**
+ * nvme_mi_admin_get_features_data() - Helper function for &nvme_mi_admin_get_features()
+ * @ctrl: Controller to send command to
+ * @fid: Feature identifier
+ * @nsid: Namespace ID, if applicable for @fid
+ * @data_len: Length of feature data, if applicable for @fid, in bytes
+ * @data: User address of feature data, if applicable
+ * @result: The command completion result from CQE dword0
+ *
+ * Helper for optionally features that optionally return data, using the
+ * SEL_CURRENT selector value.
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_get_features_data(nvme_mi_ctrl_t ctrl,
+ enum nvme_features_id fid,
+ __u32 nsid, __u32 data_len,
+ void *data, __u32 *result)
+{
+ struct nvme_get_features_args args = {
+ .result = result,
+ .data = data,
+ .args_size = sizeof(args),
+ .nsid = nsid,
+ .sel = NVME_GET_FEATURES_SEL_CURRENT,
+ .cdw11 = 0,
+ .data_len = data_len,
+ .fid = (__u8)fid,
+ .uuidx = NVME_UUID_NONE,
+ };
+
+ return nvme_mi_admin_get_features(ctrl, &args);
+}
+
+/**
+ * nvme_mi_admin_get_features_simple - Get a simple feature value with no data
+ * @ctrl: Controller to send command to
+ * @fid: Feature identifier
+ * @nsid: Namespace id, if required by @fid
+ * @result: output feature data
+ */
+static inline int nvme_mi_admin_get_features_simple(nvme_mi_ctrl_t ctrl,
+ enum nvme_features_id fid,
+ __u32 nsid,
+ __u32 *result)
+{
+ return nvme_mi_admin_get_features_data(ctrl, fid, nsid,
+ 0, NULL, result);
+}
+
+/**
+ * nvme_mi_admin_set_features - Perform a Set Features command on a controller
+ * @ctrl: Controller to send command to
+ * @args: Set Features command arguments
+ *
+ * Performs a Set Features Admin command as specified by @args. Result
+ * data will be stored in @args->result.
+ * on the specification of the feature itself; most features do not return
+ * additional data. See section 5.27.1 of the NVMe spec (v2.0b) for
+ * feature-specific information.
+ *
+ * On success, @args->data_len will be updated with the actual data length
+ * received.
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+int nvme_mi_admin_set_features(nvme_mi_ctrl_t ctrl,
+ struct nvme_set_features_args *args);
+
+/**
+ * nvme_mi_admin_ns_mgmt - Issue a Namespace Management command
+ * @ctrl: Controller to send command to
+ * @args: Namespace management command arguments
+ *
+ * Issues a Namespace Management command to @ctrl, with arguments specified
+ * from @args.
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+int nvme_mi_admin_ns_mgmt(nvme_mi_ctrl_t ctrl,
+ struct nvme_ns_mgmt_args *args);
+
+/**
+ * nvme_mi_admin_ns_mgmt_create - Helper for Namespace Management Create command
+ * @ctrl: Controller to send command to
+ * @ns: New namespace parameters
+ * @csi: Command Set Identifier for new NS
+ * @nsid: Set to new namespace ID on create
+ *
+ * Issues a Namespace Management (Create) command to @ctrl, to create a
+ * new namespace specified by @ns, using command set @csi. On success,
+ * the new namespace ID will be written to @nsid.
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_ns_mgmt_create(nvme_mi_ctrl_t ctrl,
+ struct nvme_id_ns *ns,
+ __u8 csi, __u32 *nsid)
+{
+ struct nvme_ns_mgmt_args args = {
+ .result = nsid,
+ .ns = ns,
+ .args_size = sizeof(args),
+ .nsid = NVME_NSID_NONE,
+ .sel = NVME_NS_MGMT_SEL_CREATE,
+ .csi = csi,
+ };
+
+ return nvme_mi_admin_ns_mgmt(ctrl, &args);
+}
+
+/**
+ * nvme_mi_admin_ns_mgmt_delete - Helper for Namespace Management Delete command
+ * @ctrl: Controller to send command to
+ * @nsid: Namespace ID to delete
+ *
+ * Issues a Namespace Management (Delete) command to @ctrl, to delete the
+ * namespace with id @nsid.
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_ns_mgmt_delete(nvme_mi_ctrl_t ctrl, __u32 nsid)
+{
+ struct nvme_ns_mgmt_args args = {
+ .args_size = sizeof(args),
+ .nsid = nsid,
+ .sel = NVME_NS_MGMT_SEL_DELETE,
+ };
+
+ return nvme_mi_admin_ns_mgmt(ctrl, &args);
+}
+
+/**
+ * nvme_mi_admin_ns_attach() - Attach or detach namespace to controller(s)
+ * @ctrl: Controller to send command to
+ * @args: Namespace Attach command arguments
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+int nvme_mi_admin_ns_attach(nvme_mi_ctrl_t ctrl,
+ struct nvme_ns_attach_args *args);
+
+/**
+ * nvme_mi_admin_ns_attach_ctrls() - Attach namespace to controllers
+ * @ctrl: Controller to send command to
+ * @nsid: Namespace ID to attach
+ * @ctrlist: Controller list to modify attachment state of nsid
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_ns_attach_ctrls(nvme_mi_ctrl_t ctrl, __u32 nsid,
+ struct nvme_ctrl_list *ctrlist)
+{
+ struct nvme_ns_attach_args args = {
+ .result = NULL,
+ .ctrlist = ctrlist,
+ .args_size = sizeof(args),
+ .nsid = nsid,
+ .sel = NVME_NS_ATTACH_SEL_CTRL_ATTACH,
+ };
+
+ return nvme_mi_admin_ns_attach(ctrl, &args);
+}
+
+/**
+ * nvme_mi_admin_ns_detach_ctrls() - Detach namespace from controllers
+ * @ctrl: Controller to send command to
+ * @nsid: Namespace ID to detach
+ * @ctrlist: Controller list to modify attachment state of nsid
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+static inline int nvme_mi_admin_ns_detach_ctrls(nvme_mi_ctrl_t ctrl, __u32 nsid,
+ struct nvme_ctrl_list *ctrlist)
+{
+ struct nvme_ns_attach_args args = {
+ .result = NULL,
+ .ctrlist = ctrlist,
+ .args_size = sizeof(args),
+ .nsid = nsid,
+ .sel = NVME_NS_ATTACH_SEL_CTRL_DEATTACH,
+ };
+
+ return nvme_mi_admin_ns_attach(ctrl, &args);
+}
+
+/**
+ * nvme_mi_admin_fw_download() - Download part or all of a firmware image to
+ * the controller
+ * @ctrl: Controller to send firmware data to
+ * @args: &struct nvme_fw_download_args argument structure
+ *
+ * The Firmware Image Download command downloads all or a portion of an image
+ * for a future update to the controller. The Firmware Image Download command
+ * downloads a new image (in whole or in part) to the controller.
+ *
+ * The image may be constructed of multiple pieces that are individually
+ * downloaded with separate Firmware Image Download commands. Each Firmware
+ * Image Download command includes a Dword Offset and Number of Dwords that
+ * specify a dword range.
+ *
+ * The new firmware image is not activated as part of the Firmware Image
+ * Download command. Use the nvme_mi_admin_fw_commit() to activate a newly
+ * downloaded image.
+ *
+ * Return: 0 on success, non-zero on failure
+ */
+int nvme_mi_admin_fw_download(nvme_mi_ctrl_t ctrl,
+ struct nvme_fw_download_args *args);
+
+/**
+ * nvme_mi_admin_fw_commit() - Commit firmware using the specified action
+ * @ctrl: Controller to send firmware data to
+ * @args: &struct nvme_fw_download_args argument structure
+ *
+ * The Firmware Commit command modifies the firmware image or Boot Partitions.
+ *
+ * Return: 0 on success, non-zero on failure
+ */
+int nvme_mi_admin_fw_commit(nvme_mi_ctrl_t ctrl,
+ struct nvme_fw_commit_args *args);
+
+/**
+ * nvme_mi_admin_format_nvm() - Format NVMe namespace
+ * @ctrl: Controller to send command to
+ * @args: Format NVM command arguments
+ *
+ * Perform a low-level format to set the LBA data & metadata size. May destroy
+ * data & metadata on the specified namespaces
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+int nvme_mi_admin_format_nvm(nvme_mi_ctrl_t ctrl,
+ struct nvme_format_nvm_args *args);
+
+/**
+ * nvme_mi_admin_sanitize_nvm() - Start a subsystem Sanitize operation
+ * @ctrl: Controller to send command to
+ * @args: Sanitize command arguments
+ *
+ * A sanitize operation alters all user data in the NVM subsystem such that
+ * recovery of any previous user data from any cache, the non-volatile media,
+ * or any Controller Memory Buffer is not possible.
+ *
+ * The Sanitize command starts a sanitize operation or to recover from a
+ * previously failed sanitize operation. The sanitize operation types that may
+ * be supported are Block Erase, Crypto Erase, and Overwrite. All sanitize
+ * operations are processed in the background, i.e., completion of the sanitize
+ * command does not indicate completion of the sanitize operation.
+ *
+ * Return: The nvme command status if a response was received (see
+ * &enum nvme_status_field) or -1 with errno set otherwise.
+ */
+int nvme_mi_admin_sanitize_nvm(nvme_mi_ctrl_t ctrl,
+ struct nvme_sanitize_nvm_args *args);
#endif /* _LIBNVME_MI_MI_H */