From acf73199fa227b97217238334236af367c8ab2d7 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Tue, 26 Jul 2022 07:25:24 +0200 Subject: Adding upstream version 1.1~rc0. Signed-off-by: Daniel Baumann --- src/nvme/api-types.h | 913 +++++++++++++ src/nvme/cleanup.c | 1 + src/nvme/cleanup.h | 1 + src/nvme/fabrics.c | 158 ++- src/nvme/fabrics.h | 12 +- src/nvme/ioctl.c | 185 ++- src/nvme/ioctl.h | 1312 +++++-------------- src/nvme/linux.h | 10 +- src/nvme/log.c | 13 +- src/nvme/mi-mctp.c | 751 +++++++++++ src/nvme/mi.c | 930 ++++++++++++++ src/nvme/mi.h | 1111 ++++++++++++++++ src/nvme/private.h | 71 +- src/nvme/tree.c | 108 +- src/nvme/tree.h | 62 +- src/nvme/types.h | 3456 ++++++++++++++++++++++++++------------------------ src/nvme/util.c | 39 +- src/nvme/util.h | 63 +- 18 files changed, 6309 insertions(+), 2887 deletions(-) create mode 100644 src/nvme/api-types.h create mode 100644 src/nvme/mi-mctp.c create mode 100644 src/nvme/mi.c create mode 100644 src/nvme/mi.h (limited to 'src/nvme') diff --git a/src/nvme/api-types.h b/src/nvme/api-types.h new file mode 100644 index 0000000..0de41a6 --- /dev/null +++ b/src/nvme/api-types.h @@ -0,0 +1,913 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/* + * Types used as part of the libnvme/libnvme-mi API, rather than specified + * by the NVM Express specification. + * + * These are shared across both libnvme and libnvme-mi interfaces. + * + * This file is part of libnvme. + * Copyright (c) 2022 Code Construct + * + * Authors: Jeremy Kerr + */ +#ifndef _LIBNVME_API_TYPES_H +#define _LIBNVME_API_TYPES_H + +#include +#include "types.h" + +/* + * _args struct definitions. These are used by both the ioctl-based and + * MI-based interfaces, as the call interface for (admin/io/etc) NVMe commands, + * passed to the nvme_*() and nvme_mi_*() functions. + * + * On MI-based interfaces, the fd and timeout members are unused, and should + * be set to zero. + */ + +/** + * struct nvme_identify_args - Arguments for the NVMe Identify command + * @result: The command completion result from CQE dword0 + * @data: User space destination address to transfer the data + * @args_size: Size of &struct nvme_identify_args + * @fd: File descriptor of nvme device + * @timeout: Timeout in ms (0 for default timeout) + * @cns: The Controller or Namespace structure, see @enum nvme_identify_cns + * @csi: Command Set Identifier + * @nsid: Namespace identifier, if applicable + * @cntid: The Controller Identifier, if applicable + * @cns_specific_id: Identifier that is required for a particular CNS value + * @uuidx: UUID Index if controller supports this id selection method + */ +struct nvme_identify_args { + __u32 *result; + void *data; + int args_size; + int fd; + __u32 timeout; + enum nvme_identify_cns cns; + enum nvme_csi csi; + __u32 nsid; + __u16 cntid; + __u16 cns_specific_id; + __u8 uuidx; +}; + +/** + * struct nvme_get_log_args - Arguments for the NVMe Admin Get Log command + * @lpo: Log page offset for partial log transfers + * @result: The command completion result from CQE dword0 + * @log: User space destination address to transfer the data + * @args_size: Length of the structure + * @fd: File descriptor of nvme device + * @timeout: Timeout in ms + * @lid: Log page identifier, see &enum nvme_cmd_get_log_lid for known + * values + * @len: Length of provided user buffer to hold the log data in bytes + * @nsid: Namespace identifier, if applicable + * @csi: Command set identifier, see &enum nvme_csi for known values + * @lsi: Log Specific Identifier + * @lsp: Log specific field + * @uuidx: UUID selection, if supported + * @rae: Retain asynchronous events + * @ot: Offset Type; if set @lpo specifies the index into the list + * of data structures, otherwise @lpo specifies the byte offset + * into the log page. + */ +struct nvme_get_log_args { + __u64 lpo; + __u32 *result; + void *log; + int args_size; + int fd; + __u32 timeout; + enum nvme_cmd_get_log_lid lid; + __u32 len; + __u32 nsid; + enum nvme_csi csi; + __u16 lsi; + __u8 lsp; + __u8 uuidx; + bool rae; + bool ot; +}; + +/** + * struct nvme_set_features_args - Arguments for the NVMe Admin Set Feature command + * @result: The command completion result from CQE dword0 + * @data: User address of feature data, if applicable + * @args_size: Size of &struct nvme_set_features_args + * @fd: File descriptor of nvme device + * @timeout: Timeout in ms + * @nsid: Namespace ID, if applicable + * @cdw11: Value to set the feature to + * @cdw12: Feature specific command dword12 field + * @cdw13: Feature specific command dword13 field + * @cdw15: Feature specific command dword15 field + * @data_len: Length of feature data, if applicable, in bytes + * @save: Save value across power states + * @uuidx: UUID Index for differentiating vendor specific encoding + * @fid: Feature identifier + */ +struct nvme_set_features_args { + __u32 *result; + void *data; + int args_size; + int fd; + __u32 timeout; + __u32 nsid; + __u32 cdw11; + __u32 cdw12; + __u32 cdw13; + __u32 cdw15; + __u32 data_len; + bool save; + __u8 uuidx; + __u8 fid; +}; + +/** + * struct nvme_get_features_args - Arguments for the NVMe Admin Get Feature command + * @args_size: Size of &struct nvme_get_features_args + * @fd: File descriptor of nvme device + * @result: The command completion result from CQE dword0 + * @timeout: Timeout in ms + * @nsid: Namespace ID, if applicable + * @sel: Select which type of attribute to return, + * see &enum nvme_get_features_sel + * @cdw11: Feature specific command dword11 field + * @data_len: Length of feature data, if applicable, in bytes + * @data: User address of feature data, if applicable + * @fid: Feature identifier, see &enum nvme_features_id + * @uuidx: UUID Index for differentiating vendor specific encoding + */ +struct nvme_get_features_args { + __u32 *result; + void *data; + int args_size; + int fd; + __u32 timeout; + __u32 nsid; + enum nvme_get_features_sel sel; + __u32 cdw11; + __u32 data_len; + __u8 fid; + __u8 uuidx; +}; + +/** + * struct nvme_format_nvm_args - Arguments for the Format Nvme Namespace command + * @result: The command completion result from CQE dword0 + * @args_size: Size of &struct nvme_format_nvm_args + * @fd: File descriptor of nvme device + * @timeout: Set to override default timeout to this value in milliseconds; + * useful for long running formats. 0 will use system default. + * @nsid: Namespace ID to format + * @mset: Metadata settings (extended or separated), true if extended + * @pi: Protection information type + * @pil: Protection information location (beginning or end), true if end + * @ses: Secure erase settings + * @lbaf: Logical block address format least significant 4 bits + * @rsvd1: Reserved + * @lbafu: Logical block address format most significant 2 bits + */ +struct nvme_format_nvm_args { + __u32 *result; + int args_size; + int fd; + __u32 timeout; + __u32 nsid; + enum nvme_cmd_format_mset mset; + enum nvme_cmd_format_pi pi; + enum nvme_cmd_format_pil pil; + enum nvme_cmd_format_ses ses; + __u8 lbaf; + __u8 rsvd1[7]; + __u8 lbafu; +}; + +/** + * struct nvme_ns_mgmt_args - Arguments for NVMe Namespace Management command + * @result: NVMe command result + * @ns: Namespace identification descriptors + * @args_size: Size of &struct nvme_ns_mgmt_args + * @fd: File descriptor of nvme device + * @timeout: Timeout in ms + * @nsid: Namespace identifier + * @sel: Type of management operation to perform + * @csi: Command Set Identifier + */ +struct nvme_ns_mgmt_args { + __u32 *result; + struct nvme_id_ns *ns; + int args_size; + int fd; + __u32 timeout; + __u32 nsid; + enum nvme_ns_mgmt_sel sel; + __u8 csi; +}; + +/** + * struct nvme_ns_attach_args - Arguments for Nvme Namespace Management command + * @result: NVMe command result + * @ctrlist: Controller list to modify attachment state of nsid + * @args_size: Size of &struct nvme_ns_attach_args + * @fd: File descriptor of nvme device + * @timeout: Timeout in ms + * @nsid: Namespace ID to execute attach selection + * @sel: Attachment selection, see &enum nvme_ns_attach_sel + */ +struct nvme_ns_attach_args { + __u32 *result; + struct nvme_ctrl_list *ctrlist; + int args_size; + int fd; + __u32 timeout; + __u32 nsid; + enum nvme_ns_attach_sel sel; +}; + +/** + * struct nvme_fw_download_args - Arguments for the NVMe Firmware Download command + * @args_size: Size of &struct nvme_fw_download_args + * @fd: File descriptor of nvme device + * @result: The command completion result from CQE dword0 + * @timeout: Timeout in ms + * @offset: Offset in the firmware data + * @data: Userspace address of the firmware data + * @data_len: Length of data in this command in bytes + */ +struct nvme_fw_download_args { + __u32 *result; + void *data; + int args_size; + int fd; + __u32 timeout; + __u32 offset; + __u32 data_len; +}; + +/** + * struct nvme_fw_commit_args - Arguments for the NVMe Firmware Commit command + * @args_size: Size of &struct nvme_fw_commit_args + * @fd: File descriptor of nvme device + * @action: Action to use for the firmware image, see &enum nvme_fw_commit_ca + * @timeout: Timeout in ms + * @result: The command completion result from CQE dword0 + * @slot: Firmware slot to commit the downloaded image + * @bpid: Set to true to select the boot partition id + */ +struct nvme_fw_commit_args { + __u32 *result; + int args_size; + int fd; + __u32 timeout; + enum nvme_fw_commit_ca action; + __u8 slot; + bool bpid; +}; + +/** + * struct nvme_security_send_args - Arguments for the NVMe Security Send command + * @result: The command completion result from CQE dword0 + * @data: Security data payload to send + * @args_size: Size of &struct nvme_security_send_args + * @fd: File descriptor of nvme device + * @timeout: Timeout in ms + * @nsid: Namespace ID to issue security command on + * @tl: Protocol specific transfer length + * @data_len: Data length of the payload in bytes + * @nssf: NVMe Security Specific field + * @spsp0: Security Protocol Specific field + * @spsp1: Security Protocol Specific field + * @secp: Security Protocol + */ +struct nvme_security_send_args { + __u32 *result; + void *data; + int args_size; + int fd; + __u32 timeout; + __u32 nsid; + __u32 tl; + __u32 data_len; + __u8 nssf; + __u8 spsp0; + __u8 spsp1; + __u8 secp; +}; + +/** + * struct nvme_security_receive_args - Arguments for the NVMe Security Receive command + * @result: The command completion result from CQE dword0 + * @data: Security data payload to send + * @args_size: Size of &struct nvme_security_receive_args + * @fd: File descriptor of nvme device + * @timeout: Timeout in ms + * @nsid: Namespace ID to issue security command on + * @al: Protocol specific allocation length + * @data_len: Data length of the payload in bytes + * @nssf: NVMe Security Specific field + * @spsp0: Security Protocol Specific field + * @spsp1: Security Protocol Specific field + * @secp: Security Protocol + */ +struct nvme_security_receive_args { + __u32 *result; + void *data; + int args_size; + int fd; + __u32 timeout; + __u32 nsid; + __u32 al; + __u32 data_len; + __u8 nssf; + __u8 spsp0; + __u8 spsp1; + __u8 secp; +}; + +/** + * struct nvme_get_lba_status_args - Arguments for the NVMe Get LBA Status command + * @lbas: Data payload to return status descriptors + * @result: The command completion result from CQE dword0 + * @slba: Starting logical block address to check statuses + * @args_size: Size of &struct nvme_get_lba_status_args + * @fd: File descriptor of nvme device + * @timeout: Timeout in ms + * @nsid: Namespace ID to retrieve LBA status + * @mndw: Maximum number of dwords to return + * @atype: Action type mechanism to determine LBA status descriptors to + * return, see &enum nvme_lba_status_atype + * @rl: Range length from slba to perform the action + */ +struct nvme_get_lba_status_args { + __u64 slba; + __u32 *result; + struct nvme_lba_status *lbas; + int args_size; + int fd; + __u32 timeout; + __u32 nsid; + __u32 mndw; + enum nvme_lba_status_atype atype; + __u16 rl; +}; + +/** + * struct nvme_directive_send_args - Arguments for the NVMe Directive Send command + * @result: If successful, the CQE dword0 value + * @data: Data payload to be send + * @args_size: Size of &struct nvme_directive_send_args + * @fd: File descriptor of nvme device + * @timeout: Timeout in ms + * @nsid: Namespace ID, if applicable + * @doper: Directive send operation, see &enum nvme_directive_send_doper + * @dtype: Directive type, see &enum nvme_directive_dtype + * @cdw12: Directive specific command dword12 + * @data_len: Length of data payload in bytes + * @dspec: Directive specific field + */ +struct nvme_directive_send_args { + __u32 *result; + void *data; + int args_size; + int fd; + __u32 timeout; + __u32 nsid; + enum nvme_directive_send_doper doper; + enum nvme_directive_dtype dtype; + __u32 cdw12; + __u32 data_len; + __u16 dspec; +}; + +/** + * struct nvme_directive_recv_args - Arguments for the NVMe Directive Receive command + * @result: If successful, the CQE dword0 value + * @data: Userspace address of data payload + * @args_size: Size of &struct nvme_directive_recv_args + * @fd: File descriptor of nvme device + * @timeout: Timeout in ms + * @nsid: Namespace ID, if applicable + * @doper: Directive send operation, see &enum nvme_directive_send_doper + * @dtype: Directive type, see &enum nvme_directive_dtype + * @cdw12: Directive specific command dword12 + * @data_len: Length of data payload in bytes + * @dspec: Directive specific field + */ +struct nvme_directive_recv_args { + __u32 *result; + void *data; + int args_size; + int fd; + __u32 timeout; + __u32 nsid; + enum nvme_directive_receive_doper doper; + enum nvme_directive_dtype dtype; + __u32 cdw12; + __u32 data_len; + __u16 dspec; +}; + +/** + * struct nvme_capacity_mgmt_args - Arguments for the NVMe Capacity Management command + * @result: If successful, the CQE dword0 value + * @args_size: Size of &struct nvme_capacity_mgmt_args + * @fd: File descriptor of nvme device + * @cdw11: Least significant 32 bits of the capacity in bytes of the + * Endurance Group or NVM Set to be created + * @cdw12: Most significant 32 bits of the capacity in bytes of the + * Endurance Group or NVM Set to be created + * @timeout: Timeout in ms + * @element_id: Value specific to the value of the Operation field + * @op: Operation to be performed by the controller + */ +struct nvme_capacity_mgmt_args { + __u32 *result; + int args_size; + int fd; + __u32 timeout; + __u32 cdw11; + __u32 cdw12; + __u16 element_id; + __u8 op; +}; + +/** + * struct nvme_lockdown_args - Arguments for the NVME Lockdown command + * @args_size: Size of &struct nvme_lockdown_args + * @fd: File descriptor of nvme device + * @result: The command completion result from CQE dword0 + * @timeout: Timeout in ms (0 for default timeout) + * @scp: Scope of the command + * @prhbt: Prohibit or allow the command opcode or Set Features command + * @ifc: Affected interface + * @ofi: Opcode or Feature Identifier + * @uuidx: UUID Index if controller supports this id selection method + */ +struct nvme_lockdown_args { + __u32 *result; + int args_size; + int fd; + __u32 timeout; + __u8 scp; + __u8 prhbt; + __u8 ifc; + __u8 ofi; + __u8 uuidx; +}; + +/** + * struct nvme_set_property_args - Arguments for NVMe Set Property command + * @args_size: Size of &struct nvme_set_property_args + * @fd: File descriptor of nvme device + * @result: The command completion result from CQE dword0 + * @timeout: Timeout in ms + * @offset: Property offset from the base to set + * @value: The value to set the property + */ +struct nvme_set_property_args { + __u64 value; + __u32 *result; + int args_size; + int fd; + __u32 timeout; + int offset; +}; + +/** + * struct nvme_get_property_args - Arguments for NVMe Get Property command + * @value: Where the property's value will be stored on success + * @args_size: Size of &struct nvme_get_property_args + * @fd: File descriptor of nvme device + * @offset: Property offset from the base to retrieve + * @timeout: Timeout in ms + */ +struct nvme_get_property_args { + __u64 *value; + int args_size; + int fd; + __u32 timeout; + int offset; +}; + +/** + * struct nvme_sanitize_nvm_args - Arguments for the NVMe Sanitize NVM command + * @result: The command completion result from CQE dword0 + * @args_size: Size of &struct nvme_sanitize_nvm_args + * @fd: File descriptor of nvme device + * @timeout: Timeout in ms + * @ovrpat: Overwrite pattern + * @sanact: Sanitize action, see &enum nvme_sanitize_sanact + * @ause: Set to allow unrestricted sanitize exit + * @owpass: Overwrite pass count + * @oipbp: Set to overwrite invert pattern between passes + * @nodas: Set to not deallocate blocks after sanitizing + */ +struct nvme_sanitize_nvm_args { + __u32 *result; + int args_size; + int fd; + __u32 timeout; + enum nvme_sanitize_sanact sanact; + __u32 ovrpat; + bool ause; + __u8 owpass; + bool oipbp; + bool nodas; +}; + +/** + * struct nvme_dev_self_test_args - Arguments for the NVMe Device Self Test command + * @result: The command completion result from CQE dword0 + * @args_size: Size of &struct nvme_dev_self_test_args + * @fd: File descriptor of nvme device + * @nsid: Namespace ID to test + * @stc: Self test code, see &enum nvme_dst_stc + * @timeout: Timeout in ms + */ +struct nvme_dev_self_test_args { + __u32 *result; + int args_size; + int fd; + __u32 timeout; + __u32 nsid; + enum nvme_dst_stc stc; +}; + +/** + * struct nvme_virtual_mgmt_args - Arguments for the NVMe Virtualization + * resource management command + * @args_size: Size of &struct nvme_virtual_mgmt_args + * @fd: File descriptor of nvme device + * @result: If successful, the CQE dword0 + * @timeout: Timeout in ms + * @act: Virtual resource action, see &enum nvme_virt_mgmt_act + * @rt: Resource type to modify, see &enum nvme_virt_mgmt_rt + * @cntlid: Controller id for which resources are bing modified + * @nr: Number of resources being allocated or assigned + */ +struct nvme_virtual_mgmt_args { + __u32 *result; + int args_size; + int fd; + __u32 timeout; + enum nvme_virt_mgmt_act act; + enum nvme_virt_mgmt_rt rt; + __u16 cntlid; + __u16 nr; +}; + +/** + * struct nvme_io_args - Arguments for NVMe I/O commands + * @slba: Starting logical block + * @storage_tag: This filed specifies Variable Sized Expected Logical Block + * Storage Tag (ELBST) or Logical Block Storage Tag (LBST) + * @result: The command completion result from CQE dword0 + * @data: Pointer to user address of the data buffer + * @metadata: Pointer to user address of the metadata buffer + * @args_size: Size of &struct nvme_io_args + * @fd: File descriptor of nvme device + * @timeout: Timeout in ms + * @nsid: Namespace ID + * @data_len: Length of user buffer, @data, in bytes + * @metadata_len:Length of user buffer, @metadata, in bytes + * @nlb: Number of logical blocks to send (0's based value) + * @control: Command control flags, see &enum nvme_io_control_flags. + * @apptag: This field specifies the Application Tag Mask expected value. + * Used only if the namespace is formatted to use end-to-end + * protection information. + * @appmask: This field specifies the Application Tag expected value. Used + * only if the namespace is formatted to use end-to-end protection + * information. + * @reftag: This field specifies the variable sized Expected Initial + * Logical Block Reference Tag (EILBRT) or Initial Logical Block + * Reference Tag (ILBRT). Used only if the namespace is formatted + * to use end-to-end protection information. + * @dspec: Directive specific value + * @dsm: Data set management attributes, see &enum nvme_io_dsm_flags + * @rsvd1: Reserved + * @reftag_u64: This field specifies the variable sized Expected Initial + * Logical Block Reference Tag (EILBRT) or Initial Logical Block + * Reference Tag (ILBRT). It is the 8 byte version required for + * enhanced protection information. Used only if the namespace is + * formatted to use end-to-end protection information. + * @sts: Storage tag size in bits, set by namespace Extended LBA Format + * @pif: Protection information format, determines how variable sized + * storage_tag and reftag are put into dwords 2, 3, and 14. Set by + * namespace Extended LBA Format. + */ +struct nvme_io_args { + __u64 slba; + __u64 storage_tag; + __u32 *result; + void *data; + void *metadata; + int args_size; + int fd; + __u32 timeout; + __u32 nsid; + __u32 reftag; + __u32 data_len; + __u32 metadata_len; + __u16 nlb; + __u16 control; + __u16 apptag; + __u16 appmask; + __u16 dspec; + __u8 dsm; + __u8 rsvd1[1]; + __u64 reftag_u64; + __u8 sts; + __u8 pif; +}; + +/** + * struct nvme_dsm_args - Arguments for the NVMe Dataset Management command + * @result: The command completion result from CQE dword0 + * @dsm: The data set management attributes + * @args_size: Size of &struct nvme_dsm_args + * @fd: File descriptor of nvme device + * @timeout: Timeout in ms + * @nsid: Namespace identifier + * @attrs: DSM attributes, see &enum nvme_dsm_attributes + * @nr_ranges: Number of block ranges in the data set management attributes + */ +struct nvme_dsm_args { + __u32 *result; + struct nvme_dsm_range *dsm; + int args_size; + int fd; + __u32 timeout; + __u32 nsid; + __u32 attrs; + __u16 nr_ranges; +}; + +/** + * struct nvme_copy_args - Arguments for the NVMe Copy command + * @sdlba: Start destination LBA + * @result: The command completion result from CQE dword0 + * @copy: Range description + * @args_size: Size of &struct nvme_copy_args + * @fd: File descriptor of the nvme device + * @timeout: Timeout in ms + * @nsid: Namespace identifier + * @ilbrt: Initial logical block reference tag + * @lr: Limited retry + * @fua: Force unit access + * @nr: Number of ranges + * @dspec: Directive specific value + * @lbatm: Logical block application tag mask + * @lbat: Logical block application tag + * @prinfor: Protection information field for read + * @prinfow: Protection information field for write + * @dtype: Directive type + * @format: Descriptor format + * @ilbrt_u64: Initial logical block reference tag - 8 byte + * version required for enhanced protection info + */ +struct nvme_copy_args { + __u64 sdlba; + __u32 *result; + struct nvme_copy_range *copy; + int args_size; + int fd; + __u32 timeout; + __u32 nsid; + __u32 ilbrt; + int lr; + int fua; + __u16 nr; + __u16 dspec; + __u16 lbatm; + __u16 lbat; + __u8 prinfor; + __u8 prinfow; + __u8 dtype; + __u8 format; + __u64 ilbrt_u64; +}; + +/** + * struct nvme_resv_acquire_args - Arguments for the NVMe Reservation Acquire Command + * @nrkey: The reservation key to be unregistered from the namespace if + * the action is preempt + * @iekey: Set to ignore the existing key + * @result: The command completion result from CQE dword0 + * @args_size: Size of &struct nvme_resv_acquire_args + * @fd: File descriptor of nvme device + * @timeout: Timeout in ms + * @nsid: Namespace identifier + * @rtype: The type of reservation to be create, see &enum nvme_resv_rtype + * @racqa: The action that is performed by the command, see &enum nvme_resv_racqa + * @crkey: The current reservation key associated with the host + */ +struct nvme_resv_acquire_args { + __u64 crkey; + __u64 nrkey; + __u32 *result; + int args_size; + int fd; + __u32 timeout; + __u32 nsid; + enum nvme_resv_rtype rtype; + enum nvme_resv_racqa racqa; + bool iekey; +}; + +/** + * struct nvme_resv_register_args - Arguments for the NVMe Reservation Register command + * @crkey: The current reservation key associated with the host + * @nrkey: The new reservation key to be register if action is register or + * replace + * @result: The command completion result from CQE dword0 + * @args_size: Size of &struct nvme_resv_register_args + * @fd: File descriptor of nvme device + * @nsid: Namespace identifier + * @rrega: The registration action, see &enum nvme_resv_rrega + * @cptpl: Change persist through power loss, see &enum nvme_resv_cptpl + * @iekey: Set to ignore the existing key + * @timeout: Timeout in ms + */ +struct nvme_resv_register_args { + __u64 crkey; + __u64 nrkey; + __u32 *result; + int args_size; + int fd; + __u32 timeout; + __u32 nsid; + enum nvme_resv_rrega rrega; + enum nvme_resv_cptpl cptpl; + bool iekey; +}; + +/** + * struct nvme_resv_release_args - Arguments for the NVMe Reservation Release Command + * @crkey: The current reservation key to release + * @result: The command completion result from CQE dword0 + * @args_size: Size of &struct nvme_resv_release_args + * @fd: File descriptor of nvme device + * @timeout: Timeout in ms + * @nsid: Namespace identifier + * @rtype: The type of reservation to be create, see &enum nvme_resv_rtype + * @rrela: Reservation release action, see &enum nvme_resv_rrela + * @iekey: Set to ignore the existing key + */ +struct nvme_resv_release_args { + __u64 crkey; + __u32 *result; + int args_size; + int fd; + __u32 timeout; + __u32 nsid; + enum nvme_resv_rtype rtype; + enum nvme_resv_rrela rrela; + bool iekey; +}; + +/** + * struct nvme_resv_report_args - Arguments for the NVMe Reservation Report command + * @result: The command completion result from CQE dword0 + * @report: The user space destination address to store the reservation + * report + * @args_size: Size of &struct nvme_resv_report_args + * @fd: File descriptor of nvme device + * @timeout: Timeout in ms + * @nsid: Namespace identifier + * @len: Number of bytes to request transferred with this command + * @eds: Request extended Data Structure + */ +struct nvme_resv_report_args { + __u32 *result; + struct nvme_resv_status *report; + int args_size; + int fd; + __u32 timeout; + __u32 nsid; + __u32 len; + bool eds; +}; + +/** + * struct nvme_zns_mgmt_send_args - Arguments for the NVMe ZNS Management Send command + * @slba: Starting logical block address + * @result: The command completion result from CQE dword0 + * @data: Userspace address of the data + * @args_size: Size of &struct nvme_zns_mgmt_send_args + * @fd: File descriptor of nvme device + * @timeout: timeout in ms + * @nsid: Namespace ID + * @zsa: Zone send action + * @data_len: Length of @data + * @select_all: Select all flag + * @zsaso: Zone Send Action Specific Option + */ +struct nvme_zns_mgmt_send_args { + __u64 slba; + __u32 *result; + void *data; + int args_size; + int fd; + __u32 timeout; + __u32 nsid; + enum nvme_zns_send_action zsa; + __u32 data_len; + bool select_all; + __u8 zsaso; +}; + +/** + * struct nvme_zns_mgmt_recv_args - Arguments for the NVMe ZNS Management Receive command + * @slba: Starting logical block address + * @result: The command completion result from CQE dword0 + * @data: Userspace address of the data + * @args_size: Size of &struct nvme_zns_mgmt_recv_args + * @fd: File descriptor of nvme device + * @timeout: timeout in ms + * @nsid: Namespace ID + * @zra: zone receive action + * @data_len: Length of @data + * @zrasf: Zone receive action specific field + * @zras_feat: Zone receive action specific features + */ +struct nvme_zns_mgmt_recv_args { + __u64 slba; + __u32 *result; + void *data; + int args_size; + int fd; + __u32 timeout; + __u32 nsid; + enum nvme_zns_recv_action zra; + __u32 data_len; + __u16 zrasf; + bool zras_feat; +}; + +/** + * struct nvme_zns_append_args - Arguments for the NVMe ZNS Append command + * @zslba: Zone start logical block address + * @result: The command completion result from CQE dword0 + * @data: Userspace address of the data + * @metadata: Userspace address of the metadata + * @args_size: Size of &struct nvme_zns_append_args + * @fd: File descriptor of nvme device + * @timeout: Timeout in ms + * @nsid: Namespace ID + * @ilbrt: Initial logical block reference tag + * @data_len: Length of @data + * @metadata_len: Length of @metadata + * @nlb: Number of logical blocks + * @control: + * @lbat: Logical block application tag + * @lbatm: Logical block application tag mask + * @rsvd1: Reserved + * @ilbrt_u64: Initial logical block reference tag - 8 byte + * version required for enhanced protection info + * + */ +struct nvme_zns_append_args { + __u64 zslba; + __u64 *result; + void *data; + void *metadata; + int args_size; + int fd; + __u32 timeout; + __u32 nsid; + __u32 ilbrt; + __u32 data_len; + __u32 metadata_len; + __u16 nlb; + __u16 control; + __u16 lbat; + __u16 lbatm; + __u8 rsvd1[4]; + __u64 ilbrt_u64; +}; + +/** + * struct nvme_dim_args - Arguments for the Discovery Information Management (DIM) command + * @result: Set on completion to the command's CQE DWORD 0 controller response. + * @data: Pointer to the DIM data + * @args_size: Length of the structure + * @fd: File descriptor of nvme device + * @timeout: Timeout in ms + * @data_len: Length of @data + * @tas: Task field of the Command Dword 10 (cdw10) + */ +struct nvme_dim_args { + __u32 *result; + void *data; + int args_size; + int fd; + __u32 timeout; + __u32 data_len; + __u8 tas; +}; + +#endif /* _LIBNVME_API_TYPES_H */ diff --git a/src/nvme/cleanup.c b/src/nvme/cleanup.c index 0d5d910..e652e33 100644 --- a/src/nvme/cleanup.c +++ b/src/nvme/cleanup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later #include #include "cleanup.h" diff --git a/src/nvme/cleanup.h b/src/nvme/cleanup.h index 89a4984..b7e1533 100644 --- a/src/nvme/cleanup.h +++ b/src/nvme/cleanup.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later #ifndef __CLEANUP_H #define __CLEANUP_H diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 2a26843..ee20da2 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -118,8 +118,21 @@ static const char * const eflags_strings[] = { [NVMF_DISC_EFLAGS_NONE] = "not specified", [NVMF_DISC_EFLAGS_EPCSD] = "explicit discovery connections", [NVMF_DISC_EFLAGS_DUPRETINFO] = "duplicate discovery information", - [NVMF_DISC_EFLAGS_BOTH] = "explicit discovery connections, " + [NVMF_DISC_EFLAGS_EPCSD | + NVMF_DISC_EFLAGS_DUPRETINFO] = "explicit discovery connections, " "duplicate discovery information", + [NVMF_DISC_EFLAGS_NCC] = "no cdc connectivity", + [NVMF_DISC_EFLAGS_EPCSD | + NVMF_DISC_EFLAGS_NCC] = "explicit discovery connections, " + "no cdc connectivity", + [NVMF_DISC_EFLAGS_DUPRETINFO | + NVMF_DISC_EFLAGS_NCC] = "duplicate discovery information, " + "no cdc connectivity", + [NVMF_DISC_EFLAGS_EPCSD | + NVMF_DISC_EFLAGS_DUPRETINFO | + NVMF_DISC_EFLAGS_NCC] = "explicit discovery connections, " + "duplicate discovery information, " + "no cdc connectivity", }; const char *nvmf_eflags_str(__u16 eflags) @@ -316,16 +329,19 @@ static int inet6_pton(nvme_root_t r, const char *src, uint16_t port, { int ret = -EINVAL; struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr; + const char *scope = NULL; + char *p; if (strlen(src) > INET6_ADDRSTRLEN) return -EINVAL; char *tmp = strdup(src); - if (!tmp) + if (!tmp) { nvme_msg(r, LOG_ERR, "cannot copy: %s\n", src); + return -ENOMEM; + } - const char *scope = NULL; - char *p = strchr(tmp, SCOPE_DELIMITER); + p = strchr(tmp, '%'); if (p) { *p = '\0'; scope = src + (p - tmp) + 1; @@ -521,13 +537,33 @@ static int __nvmf_add_ctrl(nvme_root_t r, const char *argstr) (int)strcspn(argstr,"\n"), argstr); ret = write(fd, argstr, len); if (ret != len) { - nvme_msg(r, LOG_ERR, "Failed to write to %s: %s\n", + nvme_msg(r, LOG_NOTICE, "Failed to write to %s: %s\n", nvmf_dev, strerror(errno)); - ret = -ENVME_CONNECT_WRITE; + switch (errno) { + case EALREADY: + ret = -ENVME_CONNECT_ALREADY; + break; + case EINVAL: + ret = -ENVME_CONNECT_INVAL; + break; + case EADDRINUSE: + ret = -ENVME_CONNECT_ADDRINUSE; + break; + case ENODEV: + ret = -ENVME_CONNECT_NODEV; + break; + case EOPNOTSUPP: + ret = -ENVME_CONNECT_OPNOTSUPP; + break; + default: + ret = -ENVME_CONNECT_WRITE; + break; + } goto out_close; } - len = read(fd, buf, sizeof(buf)); + memset(buf, 0x0, sizeof(buf)); + len = read(fd, buf, sizeof(buf) - 1); if (len < 0) { nvme_msg(r, LOG_ERR, "Failed to read from %s: %s\n", nvmf_dev, strerror(errno)); @@ -555,10 +591,37 @@ out_close: int nvmf_add_ctrl(nvme_host_t h, nvme_ctrl_t c, const struct nvme_fabrics_config *cfg) { + nvme_subsystem_t s; char *argstr; int ret; + /* highest prio have configs from command line */ cfg = merge_config(c, cfg); + + /* apply configuration from config file (JSON) */ + s = nvme_lookup_subsystem(h, NULL, nvme_ctrl_get_subsysnqn(c)); + if (s) { + nvme_ctrl_t fc; + + fc = __nvme_lookup_ctrl(s, nvme_ctrl_get_transport(c), + nvme_ctrl_get_traddr(c), + nvme_ctrl_get_host_traddr(c), + nvme_ctrl_get_host_iface(c), + nvme_ctrl_get_trsvcid(c), + NULL); + if (fc) { + cfg = merge_config(c, nvme_ctrl_get_config(fc)); + /* + * An authentication key might already been set + * in @cfg, so ensure to update @c with the correct + * controller key. + */ + if (fc->dhchap_key) + nvme_ctrl_set_dhchap_key(c, fc->dhchap_key); + } + + } + nvme_ctrl_set_discovered(c, true); if (traddr_is_hostname(h->r, c)) { char *traddr = c->traddr; @@ -702,8 +765,6 @@ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, if (!ret) return c; } - nvme_msg(h->r, LOG_ERR, "failed to connect controller, error %d\n", - errno); nvme_free_ctrl(c); return NULL; } @@ -734,54 +795,27 @@ int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, int max_retries) { nvme_root_t r = c->s && c->s->h ? c->s->h->r : NULL; - struct nvmf_discovery_log *log; - int hdr, ret, retries = 0; + struct nvmf_discovery_log *log = NULL; + int ret, retries = 0; const char *name = nvme_ctrl_get_name(c); uint64_t genctr, numrec; unsigned int size; - hdr = sizeof(struct nvmf_discovery_log); - log = malloc(hdr); - if (!log) { - nvme_msg(r, LOG_ERR, - "could not allocate memory for discovery log header\n"); - errno = ENOMEM; - return -1; - } - memset(log, 0, hdr); - - nvme_msg(r, LOG_DEBUG, "%s: discover length %d\n", name, 0x100); - ret = nvme_discovery_log(nvme_ctrl_get_fd(c), 0x100, log, true); - if (ret) { - nvme_msg(r, LOG_INFO, "%s: discover failed, error %d\n", - name, errno); - goto out_free_log; - } - do { - numrec = le64_to_cpu(log->numrec); - genctr = le64_to_cpu(log->genctr); - - if (numrec == 0) { - *logp = log; - return 0; - } - - size = sizeof(struct nvmf_discovery_log) + - sizeof(struct nvmf_disc_log_entry) * (numrec); + size = sizeof(struct nvmf_discovery_log); free(log); - log = malloc(size); + log = calloc(1, size); if (!log) { nvme_msg(r, LOG_ERR, - "could not alloc memory for discovery log page\n"); + "could not allocate memory for discovery log header\n"); errno = ENOMEM; return -1; } - memset(log, 0, size); - nvme_msg(r, LOG_DEBUG, "%s: discover length %d\n", name, size); - ret = nvme_discovery_log(nvme_ctrl_get_fd(c), size, log, false); + nvme_msg(r, LOG_DEBUG, "%s: get header (try %d/%d)\n", + name, retries, max_retries); + ret = nvme_discovery_log(nvme_ctrl_get_fd(c), size, log, true); if (ret) { nvme_msg(r, LOG_INFO, "%s: discover try %d/%d failed, error %d\n", @@ -789,11 +823,29 @@ int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, goto out_free_log; } + numrec = le64_to_cpu(log->numrec); genctr = le64_to_cpu(log->genctr); + + if (numrec == 0) + break; + + size = sizeof(struct nvmf_discovery_log) + + sizeof(struct nvmf_disc_log_entry) * numrec; + + free(log); + log = calloc(1, size); + if (!log) { + nvme_msg(r, LOG_ERR, + "could not alloc memory for discovery log page\n"); + errno = ENOMEM; + return -1; + } + nvme_msg(r, LOG_DEBUG, - "%s: discover genctr %" PRIu64 ", retry\n", - name, genctr); - ret = nvme_discovery_log(nvme_ctrl_get_fd(c), hdr, log, true); + "%s: get header and %" PRIu64 + " records (length %d genctr %" PRIu64 ")\n", + name, numrec, size, genctr); + ret = nvme_discovery_log(nvme_ctrl_get_fd(c), size, log, false); if (ret) { nvme_msg(r, LOG_INFO, "%s: discover try %d/%d failed, error %d\n", @@ -1264,12 +1316,14 @@ static const char *dctype_str[] = { * sysfs. We must get them directly from the controller by performing an * identify command. */ -static void nvme_fetch_cntrltype_dctype_from_id(nvme_ctrl_t c) +static int nvme_fetch_cntrltype_dctype_from_id(nvme_ctrl_t c) { struct nvme_id_ctrl id = { 0 }; + int ret; - if (nvme_ctrl_identify(c, &id)) - return; + ret = nvme_ctrl_identify(c, &id); + if (ret) + return ret; if (!c->cntrltype) { if (id.cntrltype > NVME_CTRL_CNTRLTYPE_ADMIN || !cntrltype_str[id.cntrltype]) @@ -1284,12 +1338,14 @@ static void nvme_fetch_cntrltype_dctype_from_id(nvme_ctrl_t c) else c->dctype = strdup(dctype_str[id.dctype]); } + return 0; } bool nvmf_is_registration_supported(nvme_ctrl_t c) { if (!c->cntrltype || !c->dctype) - nvme_fetch_cntrltype_dctype_from_id(c); + if (nvme_fetch_cntrltype_dctype_from_id(c)) + return false; return !strcmp(c->dctype, "ddc") || !strcmp(c->dctype, "cdc"); } diff --git a/src/nvme/fabrics.h b/src/nvme/fabrics.h index 7f8a373..9e099fe 100644 --- a/src/nvme/fabrics.h +++ b/src/nvme/fabrics.h @@ -4,7 +4,7 @@ * Copyright (c) 2020 Western Digital Corporation or its affiliates. * * Authors: Keith Busch - * Chaitanya Kulkarni + * Chaitanya Kulkarni */ #ifndef _LIBNVME_FABRICS_H #define _LIBNVME_FABRICS_H @@ -195,7 +195,7 @@ int nvmf_add_ctrl(nvme_host_t h, nvme_ctrl_t c, /** * nvmf_get_discovery_log() - Return the discovery log page - * @c: Discover controller to use + * @c: Discover controller to use * @logp: Pointer to the log page to be returned * @max_retries: maximum number of log page entries to be returned * @@ -213,7 +213,7 @@ char *nvmf_hostnqn_generate(); /** * nvmf_hostnqn_from_file() - Reads the host nvm qualified name from the config - * default location in @SYSCONFDIR@/nvme/ + * default location in @SYSCONFDIR@/nvme/ * Return: The host nqn, or NULL if unsuccessful. If found, the caller * is responsible to free the string. */ @@ -221,9 +221,9 @@ char *nvmf_hostnqn_from_file(); /** * nvmf_hostid_from_file() - Reads the host identifier from the config default - * location in @SYSCONFDIR@/nvme/. + * location in @SYSCONFDIR@/nvme/. * Return: The host identifier, or NULL if unsuccessful. If found, the caller - * is responsible to free the string. + * is responsible to free the string. */ char *nvmf_hostid_from_file(); @@ -231,7 +231,7 @@ char *nvmf_hostid_from_file(); * nvmf_connect_disc_entry() - Connect controller based on the discovery log page entry * @h: Host to which the controller should be connected * @e: Discovery log page entry - * @defcfg: Default configurationn to be used for the new controller + * @defcfg: Default configuration to be used for the new controller * @discover: Set to 'true' if the new controller is a discovery controller * * Return: Pointer to the new controller diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index f48b465..3333993 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -195,7 +195,7 @@ int nvme_admin_passthru(int fd, __u8 opcode, __u8 flags, __u16 rsvd, enum nvme_cmd_dword_fields { NVME_DEVICE_SELF_TEST_CDW10_STC_SHIFT = 0, - NVME_DEVICE_SELF_TEST_CDW10_STC_MASK = 0x7, + NVME_DEVICE_SELF_TEST_CDW10_STC_MASK = 0xf, NVME_DIRECTIVE_CDW11_DOPER_SHIFT = 0, NVME_DIRECTIVE_CDW11_DTYPE_SHIFT = 8, NVME_DIRECTIVE_CDW11_DPSEC_SHIFT = 16, @@ -230,11 +230,11 @@ enum nvme_cmd_dword_fields { NVME_LOG_CDW14_CSI_SHIFT = 24, NVME_LOG_CDW14_OT_SHIFT = 23, NVME_LOG_CDW10_LID_MASK = 0xff, - NVME_LOG_CDW10_LSP_MASK = 0xf, + NVME_LOG_CDW10_LSP_MASK = 0x7f, NVME_LOG_CDW10_RAE_MASK = 0x1, NVME_LOG_CDW10_NUMDL_MASK = 0xffff, NVME_LOG_CDW11_NUMDU_MASK = 0xffff, - NVME_LOG_CDW11_LSI_MASK = 0xff, + NVME_LOG_CDW11_LSI_MASK = 0xffff, NVME_LOG_CDW14_UUID_MASK = 0x7f, NVME_LOG_CDW14_CSI_MASK = 0xff, NVME_LOG_CDW14_OT_MASK = 0x1, @@ -267,11 +267,13 @@ enum nvme_cmd_dword_fields { NVME_FORMAT_CDW10_PI_SHIFT = 5, NVME_FORMAT_CDW10_PIL_SHIFT = 8, NVME_FORMAT_CDW10_SES_SHIFT = 9, + NVME_FORMAT_CDW10_LBAFU_SHIFT = 12, NVME_FORMAT_CDW10_LBAF_MASK = 0xf, NVME_FORMAT_CDW10_MSET_MASK = 0x1, NVME_FORMAT_CDW10_PI_MASK = 0x7, NVME_FORMAT_CDW10_PIL_MASK = 0x1, NVME_FORMAT_CDW10_SES_MASK = 0x7, + NVME_FORMAT_CDW10_LBAFU_MASK = 0x3, NVME_SANITIZE_CDW10_SANACT_SHIFT = 0, NVME_SANITIZE_CDW10_AUSE_SHIFT = 3, NVME_SANITIZE_CDW10_OWPASS_SHIFT = 4, @@ -1159,11 +1161,25 @@ int nvme_get_features_iocs_profile(int fd, enum nvme_get_features_sel sel, int nvme_format_nvm(struct nvme_format_nvm_args *args) { - __u32 cdw10 = NVME_SET(args->lbaf, FORMAT_CDW10_LBAF) | - NVME_SET(args->mset, FORMAT_CDW10_MSET) | - NVME_SET(args->pi, FORMAT_CDW10_PI) | - NVME_SET(args->pil, FORMAT_CDW10_PIL) | - NVME_SET(args->ses, FORMAT_CDW10_SES); + const size_t size_v1 = sizeof_args(struct nvme_format_nvm_args, lbaf, __u64); + const size_t size_v2 = sizeof_args(struct nvme_format_nvm_args, lbafu, __u64); + __u32 cdw10; + + if (args->args_size < size_v1 || args->args_size > size_v2) { + errno = EINVAL; + return -1; + } + + cdw10 = NVME_SET(args->lbaf, FORMAT_CDW10_LBAF) | + NVME_SET(args->mset, FORMAT_CDW10_MSET) | + NVME_SET(args->pi, FORMAT_CDW10_PI) | + NVME_SET(args->pil, FORMAT_CDW10_PIL) | + NVME_SET(args->ses, FORMAT_CDW10_SES); + + if (args->args_size == size_v2) { + /* set lbafu extension */ + cdw10 |= NVME_SET(args->lbafu, FORMAT_CDW10_LBAFU); + } struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_format_nvm, @@ -1172,10 +1188,6 @@ int nvme_format_nvm(struct nvme_format_nvm_args *args) .timeout_ms = args->timeout, }; - if (args->args_size < sizeof(*args)) { - errno = EINVAL; - return -1; - } return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } @@ -1588,16 +1600,81 @@ int nvme_io_passthru(int fd, __u8 opcode, __u8 flags, __u16 rsvd, timeout_ms, result); } +static int nvme_set_var_size_tags(__u32 *cmd_dw2, __u32 *cmd_dw3, __u32 *cmd_dw14, + __u8 pif, __u8 sts, __u64 reftag, __u64 storage_tag) +{ + __u32 cdw2 = 0, cdw3 = 0, cdw14; + + switch (pif) { + /* 16b Protection Information */ + case 0: + cdw14 = reftag & 0xffffffff; + cdw14 |= ((storage_tag << (32 - sts)) & 0xffffffff); + break; + /* 32b Protection Information */ + case 1: + cdw14 = reftag & 0xffffffff; + cdw3 = reftag >> 32; + cdw14 |= ((storage_tag << (80 - sts)) & 0xffff0000); + if (sts >= 48) + cdw3 |= ((storage_tag >> (sts - 48)) & 0xffffffff); + else + cdw3 |= ((storage_tag << (48 - sts)) & 0xffffffff); + cdw2 = (storage_tag >> (sts - 16)) & 0xffff; + break; + /* 64b Protection Information */ + case 2: + cdw14 = reftag & 0xffffffff; + cdw3 = (reftag >> 32) & 0xffff; + cdw14 |= ((storage_tag << (48 - sts)) & 0xffffffff); + if (sts >= 16) + cdw3 |= ((storage_tag >> (sts - 16)) & 0xffff); + else + cdw3 |= ((storage_tag << (16 - sts)) & 0xffff); + break; + default: + perror("Unsupported Protection Information Format"); + errno = EINVAL; + return -1; + } + + *cmd_dw2 = cdw2; + *cmd_dw3 = cdw3; + *cmd_dw14 = cdw14; + return 0; +} + int nvme_io(struct nvme_io_args *args, __u8 opcode) { - __u32 cdw2 = args->storage_tag & 0xffffffff; - __u32 cdw3 = (args->storage_tag >> 32) & 0xffff; - __u32 cdw10 = args->slba & 0xffffffff; - __u32 cdw11 = args->slba >> 32; - __u32 cdw12 = args->nlb | (args->control << 16); - __u32 cdw13 = args->dsm | (args->dspec << 16); - __u32 cdw14 = args->reftag; - __u32 cdw15 = args->apptag | (args->appmask << 16); + const size_t size_v1 = sizeof_args(struct nvme_io_args, dsm, __u64); + const size_t size_v2 = sizeof_args(struct nvme_io_args, pif, __u64); + __u32 cdw2, cdw3, cdw10, cdw11, cdw12, cdw13, cdw14, cdw15; + + if (args->args_size < size_v1 || args->args_size > size_v2) { + errno = EINVAL; + return -1; + } + + cdw10 = args->slba & 0xffffffff; + cdw11 = args->slba >> 32; + cdw12 = args->nlb | (args->control << 16); + cdw13 = args->dsm | (args->dspec << 16); + cdw15 = args->apptag | (args->appmask << 16); + + if (args->args_size == size_v1) { + cdw2 = (args->storage_tag >> 32) & 0xffff; + cdw3 = args->storage_tag & 0xffffffff; + cdw14 = args->reftag; + } else { + if (nvme_set_var_size_tags(&cdw2, &cdw3, &cdw14, + args->pif, + args->sts, + args->reftag_u64, + args->storage_tag)) { + errno = EINVAL; + return -1; + } + } struct nvme_passthru_cmd cmd = { .opcode = opcode, @@ -1617,10 +1694,6 @@ int nvme_io(struct nvme_io_args *args, __u8 opcode) .timeout_ms = args->timeout, }; - if (args->args_size < sizeof(*args)) { - errno = EINVAL; - return -1; - } return nvme_submit_io_passthru(args->fd, &cmd, args->result); } @@ -1645,29 +1718,48 @@ int nvme_dsm(struct nvme_dsm_args *args) int nvme_copy(struct nvme_copy_args *args) { - __u32 cdw12 = ((args->nr - 1) & 0xff) | ((args->format & 0xf) << 8) | + const size_t size_v1 = sizeof_args(struct nvme_copy_args, format, __u64); + const size_t size_v2 = sizeof_args(struct nvme_copy_args, ilbrt_u64, __u64); + __u32 cdw3, cdw12, cdw14, data_len; + + if (args->args_size < size_v1 || args->args_size > size_v2) { + errno = EINVAL; + return -1; + } + + cdw12 = ((args->nr - 1) & 0xff) | ((args->format & 0xf) << 8) | ((args->prinfor & 0xf) << 12) | ((args->dtype & 0xf) << 20) | ((args->prinfow & 0xf) << 26) | ((args->fua & 0x1) << 30) | ((args->lr & 0x1) << 31); + if (args->args_size == size_v1) { + cdw3 = 0; + cdw14 = args->ilbrt; + } else { + cdw3 = (args->ilbrt_u64 >> 32) & 0xffffffff; + cdw14 = args->ilbrt_u64 & 0xffffffff; + } + + if (args->format == 1) + data_len = args->nr * sizeof(struct nvme_copy_range_f1); + else + data_len = args->nr * sizeof(struct nvme_copy_range); + struct nvme_passthru_cmd cmd = { .opcode = nvme_cmd_copy, .nsid = args->nsid, .addr = (__u64)(uintptr_t)args->copy, - .data_len = args->nr * sizeof(*args->copy), + .data_len = data_len, + .cdw3 = cdw3, .cdw10 = args->sdlba & 0xffffffff, .cdw11 = args->sdlba >> 32, .cdw12 = cdw12, .cdw13 = (args->dspec & 0xffff) << 16, - .cdw14 = args->ilbrt, + .cdw14 = cdw14, .cdw15 = (args->lbatm << 16) | args->lbat, .timeout_ms = args->timeout, }; - if (args->args_size < sizeof(*args)) { - errno = EINVAL; - return -1; - } return nvme_submit_io_passthru(args->fd, &cmd, args->result); } @@ -1821,15 +1913,32 @@ int nvme_zns_mgmt_recv(struct nvme_zns_mgmt_recv_args *args) int nvme_zns_append(struct nvme_zns_append_args *args) { - __u32 cdw10 = args->zslba & 0xffffffff; - __u32 cdw11 = args->zslba >> 32; - __u32 cdw12 = args->nlb | (args->control << 16); - __u32 cdw14 = args->ilbrt; - __u32 cdw15 = args->lbat | (args->lbatm << 16); + const size_t size_v1 = sizeof_args(struct nvme_zns_append_args, lbatm, __u64); + const size_t size_v2 = sizeof_args(struct nvme_zns_append_args, ilbrt_u64, __u64); + __u32 cdw3, cdw10, cdw11, cdw12, cdw14, cdw15; + + if (args->args_size < size_v1 || args->args_size > size_v2) { + errno = EINVAL; + return -1; + } + + cdw10 = args->zslba & 0xffffffff; + cdw11 = args->zslba >> 32; + cdw12 = args->nlb | (args->control << 16); + cdw15 = args->lbat | (args->lbatm << 16); + + if (args->args_size == size_v1) { + cdw3 = 0; + cdw14 = args->ilbrt; + } else { + cdw3 = (args->ilbrt_u64 >> 32) & 0xffffffff; + cdw14 = args->ilbrt_u64 & 0xffffffff; + } struct nvme_passthru_cmd64 cmd = { .opcode = nvme_zns_cmd_append, .nsid = args->nsid, + .cdw3 = cdw3, .cdw10 = cdw10, .cdw11 = cdw11, .cdw12 = cdw12, @@ -1842,10 +1951,6 @@ int nvme_zns_append(struct nvme_zns_append_args *args) .timeout_ms = args->timeout, }; - if (args->args_size < sizeof(*args)) { - errno = EINVAL; - return -1; - } return nvme_submit_io_passthru64(args->fd, &cmd, args->result); } diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index ab3797d..379c43a 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -4,7 +4,7 @@ * Copyright (c) 2020 Western Digital Corporation or its affiliates. * * Authors: Keith Busch - * Chaitanya Kulkarni + * Chaitanya Kulkarni */ #ifndef _LIBNVME_IOCTL_H @@ -13,6 +13,7 @@ #include #include #include "types.h" +#include "api-types.h" /* * We can not always count on the kernel UAPI being installed. Use the same @@ -94,29 +95,71 @@ struct nvme_passthru_cmd { * @cdw14: Command Dword 14 (command specific) * @cdw15: Command Dword 15 (command specific) * @timeout_ms: If non-zero, overrides system default timeout in milliseconds - * @rsvd2: Reserved for future use (and fills an impicit struct pad + * @rsvd2: Reserved for future use (and fills an implicit struct pad * @result: Set on completion to the command's CQE DWORD 0-1 controller response */ struct nvme_passthru_cmd64 { - __u8 opcode; - __u8 flags; - __u16 rsvd1; - __u32 nsid; - __u32 cdw2; - __u32 cdw3; - __u64 metadata; - __u64 addr; - __u32 metadata_len; - __u32 data_len; - __u32 cdw10; - __u32 cdw11; - __u32 cdw12; - __u32 cdw13; - __u32 cdw14; - __u32 cdw15; - __u32 timeout_ms; - __u32 rsvd2; - __u64 result; + __u8 opcode; + __u8 flags; + __u16 rsvd1; + __u32 nsid; + __u32 cdw2; + __u32 cdw3; + __u64 metadata; + __u64 addr; + __u32 metadata_len; + __u32 data_len; + __u32 cdw10; + __u32 cdw11; + __u32 cdw12; + __u32 cdw13; + __u32 cdw14; + __u32 cdw15; + __u32 timeout_ms; + __u32 rsvd2; + __u64 result; +}; + +/** + * struct nvme_uring_cmd - nvme uring command structure + * @opcode: Operation code, see &enum nvme_io_opcodes and &enum nvme_admin_opcodes + * @flags: Not supported: intended for command flags (eg: SGL, FUSE) + * @rsvd1: Reserved for future use + * @nsid: Namespace Identifier, or Fabrics type + * @cdw2: Command Dword 2 (no spec defined use) + * @cdw3: Command Dword 3 (no spec defined use) + * @metadata: User space address to metadata buffer (NULL if not used) + * @addr: User space address to data buffer (NULL if not used) + * @metadata_len: Metadata buffer transfer length + * @data_len: Data buffer transfer length + * @cdw10: Command Dword 10 (command specific) + * @cdw11: Command Dword 11 (command specific) + * @cdw12: Command Dword 12 (command specific) + * @cdw13: Command Dword 13 (command specific) + * @cdw14: Command Dword 14 (command specific) + * @cdw15: Command Dword 15 (command specific) + * @timeout_ms: If non-zero, overrides system default timeout in milliseconds + * @rsvd2: Reserved for future use (and fills an implicit struct pad + */ +struct nvme_uring_cmd { + __u8 opcode; + __u8 flags; + __u16 rsvd1; + __u32 nsid; + __u32 cdw2; + __u32 cdw3; + __u64 metadata; + __u64 addr; + __u32 metadata_len; + __u32 data_len; + __u32 cdw10; + __u32 cdw11; + __u32 cdw12; + __u32 cdw13; + __u32 cdw14; + __u32 cdw15; + __u32 timeout_ms; + __u32 rsvd2; }; #define NVME_IOCTL_ID _IO('N', 0x40) @@ -128,13 +171,31 @@ struct nvme_passthru_cmd64 { #define NVME_IOCTL_ADMIN64_CMD _IOWR('N', 0x47, struct nvme_passthru_cmd64) #define NVME_IOCTL_IO64_CMD _IOWR('N', 0x48, struct nvme_passthru_cmd64) +/* io_uring async commands: */ +#define NVME_URING_CMD_IO _IOWR('N', 0x80, struct nvme_uring_cmd) +#define NVME_URING_CMD_IO_VEC _IOWR('N', 0x81, struct nvme_uring_cmd) + #endif /* _UAPI_LINUX_NVME_IOCTL_H */ #endif /* _LINUX_NVME_IOCTL_H */ +/** + * sizeof_args - Helper function used to determine structure sizes + * @type: Argument structure type + * @member: Member inside the type + * @align: Alignment information + */ +#define sizeof_args(type, member, align) \ +({ \ + type s; \ + size_t t = offsetof(type, member) + sizeof(s.member); \ + size_t p = (sizeof(align) - (t % sizeof(align))) % sizeof(align); \ + t + p; \ +}) + /** * nvme_submit_admin_passthru64() - Submit a 64-bit nvme passthrough admin - * command + * command * @fd: File descriptor of nvme device * @cmd: The nvme admin command to send * @result: Optional field to return the result from the CQE DW0-1 @@ -152,7 +213,7 @@ int nvme_submit_admin_passthru64(int fd, struct nvme_passthru_cmd64 *cmd, * @fd: File descriptor of nvme device * @opcode: The nvme io command to send * @flags: NVMe command flags (not used) - * @rsvd: Reserevd for future use + * @rsvd: Reserved for future use * @nsid: Namespace identifier * @cdw2: Command dword 2 * @cdw3: Command dword 3 @@ -162,9 +223,9 @@ int nvme_submit_admin_passthru64(int fd, struct nvme_passthru_cmd64 *cmd, * @cdw13: Command dword 13 * @cdw14: Command dword 14 * @cdw15: Command dword 15 - * @data_len: Length of the data transfered in this command in bytes + * @data_len: Length of the data transferred in this command in bytes * @data: Pointer to user address of the data buffer - * @metadata_len:Length of metadata transfered in this command + * @metadata_len:Length of metadata transferred in this command * @metadata: Pointer to user address of the metadata buffer * @timeout_ms: How long the kernel waits for the command to complete * @result: Optional field to return the result from the CQE dword 0 @@ -202,7 +263,7 @@ int nvme_submit_admin_passthru(int fd, struct nvme_passthru_cmd *cmd, * @fd: File descriptor of nvme device * @opcode: The nvme io command to send * @flags: NVMe command flags (not used) - * @rsvd: Reserevd for future use + * @rsvd: Reserved for future use * @nsid: Namespace identifier * @cdw2: Command dword 2 * @cdw3: Command dword 3 @@ -212,9 +273,9 @@ int nvme_submit_admin_passthru(int fd, struct nvme_passthru_cmd *cmd, * @cdw13: Command dword 13 * @cdw14: Command dword 14 * @cdw15: Command dword 15 - * @data_len: Length of the data transfered in this command in bytes + * @data_len: Length of the data transferred in this command in bytes * @data: Pointer to user address of the data buffer - * @metadata_len:Length of metadata transfered in this command + * @metadata_len:Length of metadata transferred in this command * @metadata: Pointer to user address of the metadata buffer * @timeout_ms: How long the kernel waits for the command to complete * @result: Optional field to return the result from the CQE dword 0 @@ -252,7 +313,7 @@ int nvme_submit_io_passthru64(int fd, struct nvme_passthru_cmd64 *cmd, * @fd: File descriptor of nvme device * @opcode: The nvme io command to send * @flags: NVMe command flags (not used) - * @rsvd: Reserevd for future use + * @rsvd: Reserved for future use * @nsid: Namespace identifier * @cdw2: Command dword 2 * @cdw3: Command dword 3 @@ -262,9 +323,9 @@ int nvme_submit_io_passthru64(int fd, struct nvme_passthru_cmd64 *cmd, * @cdw13: Command dword 13 * @cdw14: Command dword 14 * @cdw15: Command dword 15 - * @data_len: Length of the data transfered in this command in bytes + * @data_len: Length of the data transferred in this command in bytes * @data: Pointer to user address of the data buffer - * @metadata_len:Length of metadata transfered in this command + * @metadata_len:Length of metadata transferred in this command * @metadata: Pointer to user address of the metadata buffer * @timeout_ms: How long the kernel waits for the command to complete * @result: Optional field to return the result from the CQE dword 0 @@ -303,7 +364,7 @@ int nvme_submit_io_passthru(int fd, struct nvme_passthru_cmd *cmd, * @fd: File descriptor of nvme device * @opcode: The nvme io command to send * @flags: NVMe command flags (not used) - * @rsvd: Reserevd for future use + * @rsvd: Reserved for future use * @nsid: Namespace identifier * @cdw2: Command dword 2 * @cdw3: Command dword 3 @@ -313,9 +374,9 @@ int nvme_submit_io_passthru(int fd, struct nvme_passthru_cmd *cmd, * @cdw13: Command dword 13 * @cdw14: Command dword 14 * @cdw15: Command dword 15 - * @data_len: Length of the data transfered in this command in bytes + * @data_len: Length of the data transferred in this command in bytes * @data: Pointer to user address of the data buffer - * @metadata_len:Length of metadata transfered in this command + * @metadata_len:Length of metadata transferred in this command * @metadata: Pointer to user address of the metadata buffer * @timeout_ms: How long the kernel waits for the command to complete * @result: Optional field to return the result from the CQE dword 0 @@ -379,34 +440,6 @@ int nvme_ns_rescan(int fd); */ int nvme_get_nsid(int fd, __u32 *nsid); -/** - * struct nvme_identify_args - Arguments for the NVMe Identify command - * @result: The command completion result from CQE dword0 - * @data: User space destination address to transfer the data - * @args_size: Size of &struct nvme_identify_args - * @fd: File descriptor of nvme device - * @timeout: Timeout in ms (0 for default timeout) - * @cns: The Controller or Namespace structure, see @enum nvme_identify_cns - * @csi: Command Set Identifier - * @nsid: Namespace identifier, if applicable - * @cntid: The Controller Identifier, if applicable - * @cns_specific_id: Identifier that is required for a particular CNS value - * @uuidx: UUID Index if controller supports this id selection method - */ -struct nvme_identify_args { - __u32 *result; - void *data; - int args_size; - int fd; - __u32 timeout; - enum nvme_identify_cns cns; - enum nvme_csi csi; - __u32 nsid; - __u16 cntid; - __u16 cns_specific_id; - __u8 uuidx; -}; - /** * nvme_identify() - Send the NVMe Identify command * @args: &struct nvme_identify_args argument structure @@ -419,8 +452,8 @@ struct nvme_identify_args { */ int nvme_identify(struct nvme_identify_args *args); -static int nvme_identify_cns_nsid(int fd, enum nvme_identify_cns cns, - __u32 nsid, void *data) +static inline int nvme_identify_cns_nsid(int fd, enum nvme_identify_cns cns, + __u32 nsid, void *data) { struct nvme_identify_args args = { .result = NULL, @@ -484,7 +517,7 @@ static inline int nvme_identify_ns(int fd, __u32 nsid, struct nvme_id_ns *ns) /** * nvme_identify_allocated_ns() - Same as nvme_identify_ns, but only for - * allocated namespaces + * allocated namespaces * @fd: File descriptor of nvme device * @nsid: Namespace to identify * @ns: User space destination address to transfer the data @@ -502,7 +535,7 @@ static inline int nvme_identify_allocated_ns(int fd, __u32 nsid, /** * nvme_identify_active_ns_list() - Retrieves active namespaces id list * @fd: File descriptor of nvme device - * @nsid: Return namespaces greater than this identifer + * @nsid: Return namespaces greater than this identifier * @list: User space destination address to transfer the data * * A list of 1024 namespace IDs is returned to the host containing NSIDs in @@ -524,7 +557,7 @@ static inline int nvme_identify_active_ns_list(int fd, __u32 nsid, /** * nvme_identify_allocated_ns_list() - Retrieves allocated namespace id list * @fd: File descriptor of nvme device - * @nsid: Return namespaces greater than this identifer + * @nsid: Return namespaces greater than this identifier * @list: User space destination address to transfer the data * * A list of 1024 namespace IDs is returned to the host containing NSIDs in @@ -617,14 +650,14 @@ static inline int nvme_identify_nsid_ctrl_list(int fd, __u32 nsid, __u16 cntid, /** * nvme_identify_ns_descs() - Retrieves namespace descriptor list * @fd: File descriptor of nvme device - * @nsid: The namespace id to retrieve destriptors + * @nsid: The namespace id to retrieve descriptors * @descs: User space destination address to transfer the data * * A list of Namespace Identification Descriptor structures is returned to the * host for the namespace specified in the Namespace Identifier (NSID) field if * it is an active NSID. * - * The data returned is in the form of an arrray of 'struct nvme_ns_id_desc'. + * The data returned is in the form of an array of 'struct nvme_ns_id_desc'. * * See &struct nvme_ns_id_desc for the definition of the returned structure. * @@ -649,7 +682,7 @@ static inline int nvme_identify_ns_descs(int fd, __u32 nsid, * Identifier supported by the NVM subsystem that is equal to or greater than * the NVM Set Identifier. * - * See &struct nvme_id_nvmset_list for the defintion of the returned structure. + * See &struct nvme_id_nvmset_list 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. @@ -676,12 +709,12 @@ static inline int nvme_identify_nvmset_list(int fd, __u16 nvmsetid, /** * nvme_identify_primary_ctrl() - Retrieve NVMe Primary Controller - * identification + * identification * @fd: File descriptor of nvme device * @cntid: Return controllers starting at this identifier * @cap: User space destination buffer address to transfer the data * - * See &struct nvme_primary_ctrl_cap for the defintion of the returned structure, @cap. + * See &struct nvme_primary_ctrl_cap for the definition of the returned structure, @cap. * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. @@ -718,7 +751,7 @@ static inline int nvme_identify_primary_ctrl(int fd, __u16 cntid, * The list contains entries for controller identifiers greater than or equal * to the value specified in the Controller Identifier (cntid). * - * See &struct nvme_secondary_ctrls_list for a defintion of the returned + * See &struct nvme_secondary_ctrls_list for a definition of the returned * structure. * * Return: The nvme command status if a response was received (see @@ -746,7 +779,7 @@ static inline int nvme_identify_secondary_ctrl_list(int fd, __u32 nsid, /** * nvme_identify_ns_granularity() - Retrieves namespace granularity - * identification + * identification * @fd: File descriptor of nvme device * @gr_list: User space destination address to transfer the data * @@ -794,7 +827,7 @@ static inline int nvme_identify_uuid(int fd, struct nvme_id_uuid_list *uuid_list * @csi: Command Set Identifier * @data: User space destination address to transfer the data * - * An I/O Command Set specific Identify Namespace data structre is returned + * An I/O Command Set specific Identify Namespace data structure is returned * for the namespace specified in @nsid. * * Return: The nvme command status if a response was received (see @@ -853,7 +886,7 @@ static inline int nvme_identify_ctrl_csi(int fd, enum nvme_csi csi, void *data) } /** - * nvme_identify_active_ns_list_csi() - Active namespace ID list associated with a specified I/O command set + * nvme_identify_active_ns_list_csi() - Active namespace ID list associated with a specified I/O command set * @fd: File descriptor of nvme device * @nsid: Return namespaces greater than this identifier * @csi: Command Set Identifier @@ -960,11 +993,12 @@ static inline int nvme_identify_independent_identify_ns(int fd, __u32 nsid, } /** - * nvme_identify_ns_csi_user_data_format() - + * nvme_identify_ns_csi_user_data_format() - Identify namespace user data format * @fd: File descriptor of nvme device * @user_data_format: Return namespaces capability of identifier * @uuidx: UUID selection, if supported * @csi: Command Set Identifier + * @data: User space destination address to transfer the data * * Identify Namespace data structure for the specified User Data Format * index containing the namespace capabilities for the NVM Command Set. @@ -994,11 +1028,12 @@ static inline int nvme_identify_ns_csi_user_data_format(int fd, } /** - * nvme_identify_iocs_ns_csi_user_data_format() - + * nvme_identify_iocs_ns_csi_user_data_format() - Identify I/O command set namespace data structure * @fd: File descriptor of nvme device * @user_data_format: Return namespaces capability of identifier * @uuidx: UUID selection, if supported * @csi: Command Set Identifier + * @data: User space destination address to transfer the data * * I/O Command Set specific Identify Namespace data structure for * the specified User Data Format index containing the namespace @@ -1048,7 +1083,7 @@ static inline int nvme_nvm_identify_ctrl(int fd, struct nvme_id_ctrl_nvm *id) * nvme_identify_domain_list() - Domain list data * @fd: File descriptor of nvme device * @domid: Domain ID - * @list: User space destiantion address to transfer data + * @list: User space destination address to transfer data * * A list of 31 domain IDs is returned to the host containing domain * attributes in increasing order that are greater than the value @@ -1182,45 +1217,6 @@ static inline int nvme_zns_identify_ctrl(int fd, struct nvme_zns_id_ctrl *id) return nvme_identify_ctrl_csi(fd, NVME_CSI_ZNS, id); } -/** - * struct nvme_get_log_args - Arguments for the NVMe Admin Get Log command - * @lpo: Log page offset for partial log transfers - * @result: The command completion result from CQE dword0 - * @log: User space destination address to transfer the data - * @args_size: Length of the structure - * @fd: File descriptor of nvme device - * @timeout: Timeout in ms - * @lid: Log page identifier, see &enum nvme_cmd_get_log_lid for known - * values - * @len: Length of provided user buffer to hold the log data in bytes - * @nsid: Namespace identifier, if applicable - * @csi: Command set identifier, see &enum nvme_csi for known values - * @lsi: Log Specific Identifier - * @lsp: Log specific field - * @uuidx: UUID selection, if supported - * @rae: Retain asynchronous events - * @ot: Offset Type; if set @lpo specifies the index into the list - * of data structures, otherwise @lpo specifies the byte offset - * into the log page. - */ -struct nvme_get_log_args { - __u64 lpo; - __u32 *result; - void *log; - int args_size; - int fd; - __u32 timeout; - enum nvme_cmd_get_log_lid lid; - __u32 len; - __u32 nsid; - enum nvme_csi csi; - __u16 lsi; - __u8 lsp; - __u8 uuidx; - bool rae; - bool ot; -}; - /** * nvme_get_log() - NVMe Admin Get Log command * @args: &struct nvme_get_log_args argument structure @@ -1291,8 +1287,8 @@ static inline int nvme_get_log_supported_log_pages(int fd, bool rae, * 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_get_log_error(int fd, unsigned nr_entries, bool rae, - struct nvme_error_log_page *err_log) +static inline int nvme_get_log_error(int fd, unsigned int nr_entries, bool rae, + struct nvme_error_log_page *err_log) { return nvme_get_nsid_log(fd, rae, NVME_LOG_LID_ERROR, NVME_NSID_ALL, sizeof(*err_log) * nr_entries, @@ -1421,6 +1417,9 @@ static inline int nvme_get_log_device_self_test(int fd, * nvme_get_log_create_telemetry_host() - Create host telemetry log * @fd: File descriptor of nvme device * @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_get_log_create_telemetry_host(int fd, struct nvme_telemetry_log *log) @@ -1446,13 +1445,13 @@ static inline int nvme_get_log_create_telemetry_host(int fd, } /** - * nvme_get_log_telemetry_host() - + * nvme_get_log_telemetry_host() - Get Telemetry Host-Initiated log page * @fd: File descriptor of nvme device * @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 * - * Retreives the Telemetry Host-Initiated log page at the requested offset + * 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 @@ -1482,12 +1481,18 @@ static inline int nvme_get_log_telemetry_host(int fd, __u64 offset, } /** - * nvme_get_log_telemetry_ctrl() - + * nvme_get_log_telemetry_ctrl() - Get Telemetry Controller-Initiated log page * @fd: File descriptor of nvme device * @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_get_log_telemetry_ctrl(int fd, bool rae, __u64 offset, __u32 len, void *log) @@ -1513,7 +1518,7 @@ static inline int nvme_get_log_telemetry_ctrl(int fd, bool rae, } /** - * nvme_get_log_endurance_group() - + * nvme_get_log_endurance_group() - Get Endurance Group log * @fd: File descriptor of nvme device * @endgid: Starting group identifier to return in the list * @log: User address to store the endurance log @@ -1552,7 +1557,7 @@ static inline int nvme_get_log_endurance_group(int fd, __u16 endgid, } /** - * nvme_get_log_predictable_lat_nvmset() - + * nvme_get_log_predictable_lat_nvmset() - Predictable Latency Per NVM Set * @fd: File descriptor of nvme device * @nvmsetid: NVM set id * @log: User address to store the predictable latency log @@ -1584,12 +1589,15 @@ static inline int nvme_get_log_predictable_lat_nvmset(int fd, __u16 nvmsetid, } /** - * nvme_get_log_predictable_lat_event() - + * nvme_get_log_predictable_lat_event() - Retrieve Predictable Latency Event Aggregate Log Page * @fd: File descriptor of nvme device * @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_get_log_predictable_lat_event(int fd, bool rae, __u32 offset, __u32 len, void *log) @@ -1615,25 +1623,25 @@ static inline int nvme_get_log_predictable_lat_event(int fd, bool rae, } /** - * nvme_get_log_ana() - + * nvme_get_log_ana() - Retrieve Asymmetric Namespace Access log page * @fd: File descriptor of nvme device * @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 + * @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 defintion of the returned structure. + * 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 int nvme_get_log_ana(int fd, enum nvme_log_ana_lsp lsp, bool rae, - __u64 offset, __u32 len, void *log) +static inline int nvme_get_log_ana(int fd, enum nvme_log_ana_lsp lsp, bool rae, + __u64 offset, __u32 len, void *log) { struct nvme_get_log_args args = { .lpo = offset, @@ -1647,7 +1655,7 @@ static int nvme_get_log_ana(int fd, enum nvme_log_ana_lsp lsp, bool rae, .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, .lsi = NVME_LOG_LSI_NONE, - .lsp = lsp, + .lsp = (__u8)lsp, .uuidx = NVME_UUID_NONE, .rae = false, .ot = false, @@ -1656,13 +1664,16 @@ static int nvme_get_log_ana(int fd, enum nvme_log_ana_lsp lsp, bool rae, } /** - * nvme_get_log_ana_groups() - + * nvme_get_log_ana_groups() - Retrieve Asymmetric Namespace Access groups only log page * @fd: File descriptor of nvme device * @rae: Retain asynchronous events * @len: The allocated length of the log page - * @log: User address to store the ana group log + * @log: User address to store the ana group log + * + * See &struct nvme_ana_group_desc for the definition of the returned structure. * - * See &struct nvme_ana_group_desc for the defintion 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_get_log_ana_groups(int fd, bool rae, __u32 len, struct nvme_ana_group_desc *log) @@ -1672,12 +1683,15 @@ static inline int nvme_get_log_ana_groups(int fd, bool rae, __u32 len, } /** - * nvme_get_log_lba_status() - + * nvme_get_log_lba_status() - Retrieve LBA Status * @fd: File descriptor of nvme device * @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 + * @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_get_log_lba_status(int fd, bool rae, __u64 offset, __u32 len, void *log) @@ -1703,12 +1717,15 @@ static inline int nvme_get_log_lba_status(int fd, bool rae, } /** - * nvme_get_log_endurance_grp_evt() - + * nvme_get_log_endurance_grp_evt() - Retrieve Rotational Media Information * @fd: File descriptor of nvme device * @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 + * @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_get_log_endurance_grp_evt(int fd, bool rae, __u32 offset, __u32 len, void *log) @@ -1734,7 +1751,7 @@ static inline int nvme_get_log_endurance_grp_evt(int fd, bool rae, } /** - * nvme_get_log_fid_supported_effects() - + * nvme_get_log_fid_supported_effects() - Retrieve Feature Identifiers Supported and Effects * @fd: File descriptor of nvme device * @rae: Retain asynchronous events * @log: FID Supported and Effects data structure @@ -1750,7 +1767,7 @@ static inline int nvme_get_log_fid_supported_effects(int fd, bool rae, } /** - * nvme_get_log_mi_cmd_supported_effects() - displays the MI Commands Supported byt the controller + * nvme_get_log_mi_cmd_supported_effects() - displays the MI Commands Supported by the controller * @fd: File descriptor of nvme device * @rae: Retain asynchronous events * @log: MI Command Supported and Effects data structure @@ -1766,13 +1783,13 @@ static inline int nvme_get_log_mi_cmd_supported_effects(int fd, bool rae, } /** - * nvme_get_log_boot_partition() - + * nvme_get_log_boot_partition() - Retrieve Boot Partition * @fd: File descriptor of nvme device * @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 + * @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 @@ -1801,7 +1818,7 @@ static inline int nvme_get_log_boot_partition(int fd, bool rae, } /** - * nvme_get_log_discovery() - + * nvme_get_log_discovery() - Retrieve Discovery log page * @fd: File descriptor of nvme device * @rae: Retain asynchronous events * @offset: Offset of this log to retrieve @@ -1838,7 +1855,7 @@ static inline int nvme_get_log_discovery(int fd, bool rae, } /** - * nvme_get_log_media_unit_stat() - + * nvme_get_log_media_unit_stat() - Retrieve Media Unit Status * @fd: File descriptor of nvme device * @domid: Domain Identifier selection, if supported * @mus: User address to store the Media Unit statistics log @@ -1870,9 +1887,10 @@ static inline int nvme_get_log_media_unit_stat(int fd, __u16 domid, } /** - * nvme_get_log_support_cap_config_list() - + * nvme_get_log_support_cap_config_list() - Retrieve Supported Capacity Configuration List * @fd: File descriptor of nvme device * @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 @@ -1901,10 +1919,13 @@ static inline int nvme_get_log_support_cap_config_list(int fd, __u16 domid, } /** - * nvme_get_log_reservation() - + * nvme_get_log_reservation() - Retrieve Reservation Notification * @fd: File descriptor of nvme device * @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_get_log_reservation(int fd, bool rae, struct nvme_resv_notification_log *log) @@ -1914,7 +1935,7 @@ static inline int nvme_get_log_reservation(int fd, bool rae, } /** - * nvme_get_log_sanitize() - + * nvme_get_log_sanitize() - Retrieve Sanitize Status * @fd: File descriptor of nvme device * @rae: Retain asynchronous events * @log: User address to store the sanitize log @@ -1933,7 +1954,7 @@ static inline int nvme_get_log_sanitize(int fd, bool rae, } /** - * nvme_get_log_zns_changed_zones() - + * nvme_get_log_zns_changed_zones() - Retrieve list of zones that have changed * @fd: File descriptor of nvme device * @nsid: Namespace ID * @rae: Retain asynchronous events @@ -1968,11 +1989,14 @@ static inline int nvme_get_log_zns_changed_zones(int fd, __u32 nsid, bool rae, } /** - * nvme_get_log_persistent_event() - + * nvme_get_log_persistent_event() - Retrieve Persistent Event Log * @fd: File descriptor of nvme device * @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_get_log_persistent_event(int fd, enum nvme_pevent_log_action action, @@ -1990,7 +2014,7 @@ static inline int nvme_get_log_persistent_event(int fd, .nsid = NVME_NSID_ALL, .csi = NVME_CSI_NVM, .lsi = NVME_LOG_LSI_NONE, - .lsp = action, + .lsp = (__u8)action, .uuidx = NVME_UUID_NONE, .rae = false, .ot = false, @@ -1998,39 +2022,6 @@ static inline int nvme_get_log_persistent_event(int fd, return nvme_get_log(&args); } -/** - * struct nvme_set_features_args - Arguments for the NVMe Admin Set Feature command - * @result: The command completion result from CQE dword0 - * @data: User address of feature data, if applicable - * @args_size: Size of &struct nvme_set_features_args - * @fd: File descriptor of nvme device - * @timeout: Timeout in ms - * @nsid: Namespace ID, if applicable - * @cdw11: Value to set the feature to - * @cdw12: Feature specific command dword12 field - * @cdw15: Feature specific command dword15 field - * @data_len: Length of feature data, if applicable, in bytes - * @save: Save value across power states - * @uuidx: UUID Index for differentiating vendor specific encoding - * @fid: Feature identifier - */ -struct nvme_set_features_args { - __u32 *result; - void *data; - int args_size; - int fd; - __u32 timeout; - __u32 nsid; - __u32 cdw11; - __u32 cdw12; - __u32 cdw13; - __u32 cdw15; - __u32 data_len; - bool save; - __u8 uuidx; - __u8 fid; -}; - /** * nvme_set_features() - Set a feature attribute * @args: &struct nvme_set_features_args argument structure @@ -2050,6 +2041,9 @@ int nvme_set_features(struct nvme_set_features_args *args); * @data_len: Length of feature data, if applicable, in bytes * @data: User address of feature data, if applicable * @result: The command completion result from CQE dword0 + * + * 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_set_features_data(int fd, __u8 fid, __u32 nsid, __u32 cdw11, bool save, __u32 data_len, void *data, @@ -2075,13 +2069,16 @@ static inline int nvme_set_features_data(int fd, __u8 fid, __u32 nsid, } /** - * nvme_set_features_simple() - Helper functionn for @nvme_set_features() + * nvme_set_features_simple() - Helper function for @nvme_set_features() * @fd: File descriptor of nvme device * @fid: Feature identifier * @nsid: Namespace ID, if applicable * @cdw11: Value to set the feature to * @save: Save value across power states * @result: The command completion result from CQE dword0 + * + * 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_set_features_simple(int fd, __u8 fid, __u32 nsid, __u32 cdw11, bool save, __u32 *result) @@ -2091,7 +2088,7 @@ static inline int nvme_set_features_simple(int fd, __u8 fid, __u32 nsid, } /** - * nvme_set_features_arbitration() - + * nvme_set_features_arbitration() - Set arbitration features * @fd: File descriptor of nvme device * @ab: Arbitration Burst * @lpw: Low Priority Weight @@ -2107,7 +2104,7 @@ int nvme_set_features_arbitration(int fd, __u8 ab, __u8 lpw, __u8 mpw, __u8 hpw, bool save, __u32 *result); /** - * nvme_set_features_power_mgmt() - + * nvme_set_features_power_mgmt() - Set power management feature * @fd: File descriptor of nvme device * @ps: Power State * @wh: Workload Hint @@ -2121,7 +2118,7 @@ int nvme_set_features_power_mgmt(int fd, __u8 ps, __u8 wh, bool save, __u32 *result); /** - * nvme_set_features_lba_range() - + * nvme_set_features_lba_range() - Set LBA range feature * @fd: File descriptor of nvme device * @nsid: Namespace ID * @nr_ranges: Number of ranges in @data @@ -2136,7 +2133,7 @@ int nvme_set_features_lba_range(int fd, __u32 nsid, __u32 nr_ranges, bool save, struct nvme_lba_range_type *data, __u32 *result); /** - * nvme_set_features_temp_thresh() - + * nvme_set_features_temp_thresh() - Set temperature threshold feature * @fd: File descriptor of nvme device * @tmpth: Temperature Threshold * @tmpsel: Threshold Temperature Select @@ -2152,7 +2149,7 @@ int nvme_set_features_temp_thresh(int fd, __u16 tmpth, __u8 tmpsel, bool save, __u32 *result); /** - * nvme_set_features_err_recovery() - + * nvme_set_features_err_recovery() - Set error recovery feature * @fd: File descriptor of nvme device * @nsid: Namespace ID * @tler: Time-limited error recovery value @@ -2167,7 +2164,7 @@ int nvme_set_features_err_recovery(int fd, __u32 nsid, __u16 tler, bool dulbe, bool save, __u32 *result); /** - * nvme_set_features_volatile_wc() - + * nvme_set_features_volatile_wc() - Set volatile write cache feature * @fd: File descriptor of nvme device * @wce: Write cache enable * @save: Save value across power states @@ -2180,7 +2177,7 @@ int nvme_set_features_volatile_wc(int fd, bool wce, bool save, __u32 *result); /** - * nvme_set_features_irq_coalesce() - + * nvme_set_features_irq_coalesce() - Set IRQ coalesce feature * @fd: File descriptor of nvme device * @thr: Aggregation Threshold * @time: Aggregation Time @@ -2194,7 +2191,7 @@ int nvme_set_features_irq_coalesce(int fd, __u8 thr, __u8 time, bool save, __u32 *result); /** - * nvme_set_features_irq_config() - + * nvme_set_features_irq_config() - Set IRQ config feature * @fd: File descriptor of nvme device * @iv: Interrupt Vector * @cd: Coalescing Disable @@ -2208,7 +2205,7 @@ int nvme_set_features_irq_config(int fd, __u16 iv, bool cd, bool save, __u32 *result); /** - * nvme_set_features_write_atomic() - + * nvme_set_features_write_atomic() - Set write atomic feature * @fd: File descriptor of nvme device * @dn: Disable Normal * @save: Save value across power states @@ -2221,7 +2218,7 @@ int nvme_set_features_write_atomic(int fd, bool dn, bool save, __u32 *result); /** - * nvme_set_features_async_event() - + * nvme_set_features_async_event() - Set asynchronous event feature * @fd: File descriptor of nvme device * @events: Events to enable * @save: Save value across power states @@ -2234,7 +2231,7 @@ int nvme_set_features_async_event(int fd, __u32 events, bool save, __u32 *result); /** - * nvme_set_features_auto_pst() - + * nvme_set_features_auto_pst() - Set autonomous power state feature * @fd: File descriptor of nvme device * @apste: Autonomous Power State Transition Enable * @apst: Autonomous Power State Transition @@ -2249,10 +2246,10 @@ int nvme_set_features_auto_pst(int fd, bool apste, bool save, __u32 *result); /** - * nvme_set_features_timestamp() - + * nvme_set_features_timestamp() - Set timestamp feature * @fd: File descriptor of nvme device * @save: Save value across power states - * @timestamp: The current timestamp value to assign to this this feature + * @timestamp: The current timestamp value to assign to this feature * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. @@ -2260,7 +2257,7 @@ int nvme_set_features_auto_pst(int fd, bool apste, bool save, int nvme_set_features_timestamp(int fd, bool save, __u64 timestamp); /** - * nvme_set_features_hctm() - + * nvme_set_features_hctm() - Set thermal management feature * @fd: File descriptor of nvme device * @tmt2: Thermal Management Temperature 2 * @tmt1: Thermal Management Temperature 1 @@ -2274,7 +2271,7 @@ int nvme_set_features_hctm(int fd, __u16 tmt2, __u16 tmt1, bool save, __u32 *result); /** - * nvme_set_features_nopsc() - + * nvme_set_features_nopsc() - Set non-operational power state feature * @fd: File descriptor of nvme device * @noppme: Non-Operational Power State Permissive Mode Enable * @save: Save value across power states @@ -2286,7 +2283,7 @@ int nvme_set_features_hctm(int fd, __u16 tmt2, __u16 tmt1, bool save, int nvme_set_features_nopsc(int fd, bool noppme, bool save, __u32 *result); /** - * nvme_set_features_rrl() - + * nvme_set_features_rrl() - Set read recovery level feature * @fd: File descriptor of nvme device * @rrl: Read recovery level setting * @nvmsetid: NVM set id @@ -2300,7 +2297,7 @@ int nvme_set_features_rrl(int fd, __u8 rrl, __u16 nvmsetid, bool save, __u32 *result); /** - * nvme_set_features_plm_config() - + * nvme_set_features_plm_config() - Set predictable latency feature * @fd: File descriptor of nvme device * @enable: Predictable Latency Enable * @nvmsetid: NVM Set Identifier @@ -2313,10 +2310,10 @@ int nvme_set_features_rrl(int fd, __u8 rrl, __u16 nvmsetid, bool save, */ int nvme_set_features_plm_config(int fd, bool enable, __u16 nvmsetid, bool save, struct nvme_plm_config *data, - __u32*result); + __u32 *result); /** - * nvme_set_features_plm_window() - + * nvme_set_features_plm_window() - Set window select feature * @fd: File descriptor of nvme device * @sel: Window Select * @nvmsetid: NVM Set Identifier @@ -2330,7 +2327,7 @@ int nvme_set_features_plm_window(int fd, enum nvme_feat_plm_window_select sel, __u16 nvmsetid, bool save, __u32 *result); /** - * nvme_set_features_lba_sts_interval() - + * nvme_set_features_lba_sts_interval() - Set LBA status information feature * @fd: File descriptor of nvme device * @save: Save value across power states * @lsiri: LBA Status Information Report Interval @@ -2344,7 +2341,7 @@ int nvme_set_features_lba_sts_interval(int fd, __u16 lsiri, __u16 lsipi, bool save, __u32 *result); /** - * nvme_set_features_host_behavior() - + * nvme_set_features_host_behavior() - Set host behavior feature * @fd: File descriptor of nvme device * @save: Save value across power states * @data: Pointer to structure nvme_feat_host_behavior @@ -2356,7 +2353,7 @@ int nvme_set_features_host_behavior(int fd, bool save, struct nvme_feat_host_behavior *data); /** - * nvme_set_features_sanitize() - + * nvme_set_features_sanitize() - Set sanitize feature * @fd: File descriptor of nvme device * @nodrm: No-Deallocate Response Mode * @save: Save value across power states @@ -2368,7 +2365,7 @@ int nvme_set_features_host_behavior(int fd, bool save, int nvme_set_features_sanitize(int fd, bool nodrm, bool save, __u32 *result); /** - * nvme_set_features_endurance_evt_cfg() - + * nvme_set_features_endurance_evt_cfg() - Set endurance event config feature * @fd: File descriptor of nvme device * @endgid: Endurance Group Identifier * @egwarn: Flags to enable warning, see &enum nvme_eg_critical_warning_flags @@ -2382,7 +2379,7 @@ int nvme_set_features_endurance_evt_cfg(int fd, __u16 endgid, __u8 egwarn, bool save, __u32 *result); /** - * nvme_set_features_sw_progress() - + * nvme_set_features_sw_progress() - Set pre-boot software load count feature * @fd: File descriptor of nvme device * @pbslc: Pre-boot Software Load Count * @save: Save value across power states @@ -2395,7 +2392,7 @@ int nvme_set_features_sw_progress(int fd, __u8 pbslc, bool save, __u32 *result); /** - * nvme_set_features_host_id() - + * nvme_set_features_host_id() - Set enable extended host identifers feature * @fd: File descriptor of nvme device * @exhid: Enable Extended Host Identifier * @save: Save value across power states @@ -2407,7 +2404,7 @@ int nvme_set_features_sw_progress(int fd, __u8 pbslc, bool save, int nvme_set_features_host_id(int fd, bool exhid, bool save, __u8 *hostid); /** - * nvme_set_features_resv_mask() - + * nvme_set_features_resv_mask() - Set reservation notification mask feature * @fd: File descriptor of nvme device * @mask: Reservation Notification Mask Field * @save: Save value across power states @@ -2419,7 +2416,7 @@ int nvme_set_features_host_id(int fd, bool exhid, bool save, __u8 *hostid); int nvme_set_features_resv_mask(int fd, __u32 mask, bool save, __u32 *result); /** - * nvme_set_features_resv_persist() - + * nvme_set_features_resv_persist() - Set persist through power loss feature * @fd: File descriptor of nvme device * @ptpl: Persist Through Power Loss * @save: Save value across power states @@ -2431,7 +2428,7 @@ int nvme_set_features_resv_mask(int fd, __u32 mask, bool save, __u32 *result); int nvme_set_features_resv_persist(int fd, bool ptpl, bool save, __u32 *result); /** - * nvme_set_features_write_protect() - + * nvme_set_features_write_protect() - Set write protect feature * @fd: File descriptor of nvme device * @state: Write Protection State * @save: Save value across power states @@ -2442,34 +2439,6 @@ int nvme_set_features_resv_persist(int fd, bool ptpl, bool save, __u32 *result); */ int nvme_set_features_write_protect(int fd, enum nvme_feat_nswpcfg_state state, bool save, __u32 *result); -/** - * struct nvme_get_features_args - Arguments for the NVMe Admin Get Feature command - * @args_size: Size of &struct nvme_get_features_args - * @fd: File descriptor of nvme device - * @result: The command completion result from CQE dword0 - * @timeout: Timeout in ms - * @nsid: Namespace ID, if applicable - * @sel: Select which type of attribute to return, - * see &enum nvme_get_features_sel - * @cdw11: Feature specific command dword11 field - * @data_len: Length of feature data, if applicable, in bytes - * @data: User address of feature data, if applicable - * @fid: Feature identifier, see &enum nvme_features_id - * @uuidx: UUID Index for differentiating vendor specific encoding - */ -struct nvme_get_features_args { - __u32 *result; - void *data; - int args_size; - int fd; - __u32 timeout; - __u32 nsid; - enum nvme_get_features_sel sel; - __u32 cdw11; - __u32 data_len; - __u8 fid; - __u8 uuidx; -}; /** * nvme_get_features() - Retrieve a feature attribute @@ -2488,6 +2457,9 @@ int nvme_get_features(struct nvme_get_features_args *args); * @data_len: Length of feature data, if applicable, in bytes * @data: User address of feature data, if applicable * @result: The command completion result from CQE dword0 + * + * 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_get_features_data(int fd, enum nvme_features_id fid, __u32 nsid, __u32 data_len, void *data, __u32 *result) @@ -2502,7 +2474,7 @@ static inline int nvme_get_features_data(int fd, enum nvme_features_id fid, .sel = NVME_GET_FEATURES_SEL_CURRENT, .cdw11 = 0, .data_len = data_len, - .fid = fid, + .fid = (__u8)fid, .uuidx = NVME_UUID_NONE, }; @@ -2515,6 +2487,9 @@ static inline int nvme_get_features_data(int fd, enum nvme_features_id fid, * @fid: Feature identifier * @nsid: Namespace ID, if applicable * @result: The command completion result from CQE dword0 + * + * 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_get_features_simple(int fd, enum nvme_features_id fid, __u32 nsid, __u32 *result) @@ -2523,7 +2498,7 @@ static inline int nvme_get_features_simple(int fd, enum nvme_features_id fid, } /** - * nvme_get_features_arbitration() - + * nvme_get_features_arbitration() - Get arbitration feature * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 @@ -2535,7 +2510,7 @@ int nvme_get_features_arbitration(int fd, enum nvme_get_features_sel sel, __u32 *result); /** - * nvme_get_features_power_mgmt() - + * nvme_get_features_power_mgmt() - Get power management feature * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 @@ -2547,7 +2522,7 @@ int nvme_get_features_power_mgmt(int fd, enum nvme_get_features_sel sel, __u32 *result); /** - * nvme_get_features_lba_range() - + * nvme_get_features_lba_range() - Get LBA range feature * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @data: User address of feature data, if applicable @@ -2561,7 +2536,7 @@ int nvme_get_features_lba_range(int fd, enum nvme_get_features_sel sel, __u32 *result); /** - * nvme_get_features_temp_thresh() - + * nvme_get_features_temp_thresh() - Get temperature threshold feature * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 @@ -2573,7 +2548,7 @@ int nvme_get_features_temp_thresh(int fd, enum nvme_get_features_sel sel, __u32 *result); /** - * nvme_get_features_err_recovery() - + * nvme_get_features_err_recovery() - Get error recovery feature * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 @@ -2585,7 +2560,7 @@ int nvme_get_features_err_recovery(int fd, enum nvme_get_features_sel sel, __u32 *result); /** - * nvme_get_features_volatile_wc() - + * nvme_get_features_volatile_wc() - Get volatile write cache feature * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 @@ -2597,7 +2572,7 @@ int nvme_get_features_volatile_wc(int fd, enum nvme_get_features_sel sel, __u32 *result); /** - * nvme_get_features_num_queues() - + * nvme_get_features_num_queues() - Get number of queues feature * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 @@ -2609,7 +2584,7 @@ int nvme_get_features_num_queues(int fd, enum nvme_get_features_sel sel, __u32 *result); /** - * nvme_get_features_irq_coalesce() - + * nvme_get_features_irq_coalesce() - Get IRQ coalesce feature * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 @@ -2621,7 +2596,7 @@ int nvme_get_features_irq_coalesce(int fd, enum nvme_get_features_sel sel, __u32 *result); /** - * nvme_get_features_irq_config() - + * nvme_get_features_irq_config() - Get IRQ config feature * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @iv: @@ -2634,7 +2609,7 @@ int nvme_get_features_irq_config(int fd, enum nvme_get_features_sel sel, __u16 iv, __u32 *result); /** - * nvme_get_features_write_atomic() - + * nvme_get_features_write_atomic() - Get write atomic feature * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 @@ -2646,7 +2621,7 @@ int nvme_get_features_write_atomic(int fd, enum nvme_get_features_sel sel, __u32 *result); /** - * nvme_get_features_async_event() - + * nvme_get_features_async_event() - Get asynchronous event feature * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 @@ -2658,7 +2633,7 @@ int nvme_get_features_async_event(int fd, enum nvme_get_features_sel sel, __u32 *result); /** - * nvme_get_features_auto_pst() - + * nvme_get_features_auto_pst() - Get autonomous power state feature * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @apst: @@ -2671,7 +2646,7 @@ int nvme_get_features_auto_pst(int fd, enum nvme_get_features_sel sel, struct nvme_feat_auto_pst *apst, __u32 *result); /** - * nvme_get_features_host_mem_buf() - + * nvme_get_features_host_mem_buf() - Get host memory buffer feature * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 @@ -2683,7 +2658,7 @@ int nvme_get_features_host_mem_buf(int fd, enum nvme_get_features_sel sel, __u32 *result); /** - * nvme_get_features_timestamp() - + * nvme_get_features_timestamp() - Get timestamp feature * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @ts: Current timestamp @@ -2695,7 +2670,7 @@ int nvme_get_features_timestamp(int fd, enum nvme_get_features_sel sel, struct nvme_timestamp *ts); /** - * nvme_get_features_kato() - + * nvme_get_features_kato() - Get keep alive timeout feature * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 @@ -2706,7 +2681,7 @@ int nvme_get_features_timestamp(int fd, enum nvme_get_features_sel sel, int nvme_get_features_kato(int fd, enum nvme_get_features_sel sel, __u32 *result); /** - * nvme_get_features_hctm() - + * nvme_get_features_hctm() - Get thermal management feature * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 @@ -2717,7 +2692,7 @@ int nvme_get_features_kato(int fd, enum nvme_get_features_sel sel, __u32 *result int nvme_get_features_hctm(int fd, enum nvme_get_features_sel sel, __u32 *result); /** - * nvme_get_features_nopsc() - + * nvme_get_features_nopsc() - Get non-operational power state feature * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 @@ -2728,7 +2703,7 @@ int nvme_get_features_hctm(int fd, enum nvme_get_features_sel sel, __u32 *result int nvme_get_features_nopsc(int fd, enum nvme_get_features_sel sel, __u32 *result); /** - * nvme_get_features_rrl() - + * nvme_get_features_rrl() - Get read recovery level feature * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 @@ -2739,7 +2714,7 @@ int nvme_get_features_nopsc(int fd, enum nvme_get_features_sel sel, __u32 *resul int nvme_get_features_rrl(int fd, enum nvme_get_features_sel sel, __u32 *result); /** - * nvme_get_features_plm_config() - + * nvme_get_features_plm_config() - Get predictable latency feature * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @nvmsetid: NVM set id @@ -2754,7 +2729,7 @@ int nvme_get_features_plm_config(int fd, enum nvme_get_features_sel sel, __u32 *result); /** - * nvme_get_features_plm_window() - + * nvme_get_features_plm_window() - Get window select feature * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @nvmsetid: NVM set id @@ -2767,7 +2742,7 @@ int nvme_get_features_plm_window(int fd, enum nvme_get_features_sel sel, __u16 nvmsetid, __u32 *result); /** - * nvme_get_features_lba_sts_interval() - + * nvme_get_features_lba_sts_interval() - Get LBA status information feature * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 @@ -2779,10 +2754,10 @@ int nvme_get_features_lba_sts_interval(int fd, enum nvme_get_features_sel sel, __u32 *result); /** - * nvme_get_features_host_behavior() - + * nvme_get_features_host_behavior() - Get host behavior feature * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel - * @data: Poniter to structure nvme_feat_host_behavior + * @data: Pointer to structure nvme_feat_host_behavior * @result: The command completion result from CQE dword0 * * Return: The nvme command status if a response was received (see @@ -2793,7 +2768,7 @@ int nvme_get_features_host_behavior(int fd, enum nvme_get_features_sel sel, __u32 *result); /** - * nvme_get_features_sanitize() - + * nvme_get_features_sanitize() - Get sanitize feature * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 @@ -2805,7 +2780,7 @@ int nvme_get_features_sanitize(int fd, enum nvme_get_features_sel sel, __u32 *result); /** - * nvme_get_features_endurance_event_cfg() - + * nvme_get_features_endurance_event_cfg() - Get endurance event config feature * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @endgid: Endurance Group Identifier @@ -2818,7 +2793,7 @@ int nvme_get_features_endurance_event_cfg(int fd, enum nvme_get_features_sel sel __u16 endgid, __u32 *result); /** - * nvme_get_features_sw_progress() - + * nvme_get_features_sw_progress() - Get software progress feature * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 @@ -2830,7 +2805,7 @@ int nvme_get_features_sw_progress(int fd, enum nvme_get_features_sel sel, __u32 *result); /** - * nvme_get_features_host_id() - + * nvme_get_features_host_id() - Get host id feature * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @exhid: Enable Extended Host Identifier @@ -2844,7 +2819,7 @@ int nvme_get_features_host_id(int fd, enum nvme_get_features_sel sel, bool exhid, __u32 len, __u8 *hostid); /** - * nvme_get_features_resv_mask() - + * nvme_get_features_resv_mask() - Get reservation mask feature * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 @@ -2856,7 +2831,7 @@ int nvme_get_features_resv_mask(int fd, enum nvme_get_features_sel sel, __u32 *result); /** - * nvme_get_features_resv_persist() - + * nvme_get_features_resv_persist() - Get reservation persist feature * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 @@ -2868,7 +2843,7 @@ int nvme_get_features_resv_persist(int fd, enum nvme_get_features_sel sel, __u32 *result); /** - * nvme_get_features_write_protect() - + * nvme_get_features_write_protect() - Get write protect feature * @fd: File descriptor of nvme device * @nsid: Namespace ID * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel @@ -2882,7 +2857,7 @@ int nvme_get_features_write_protect(int fd, __u32 nsid, __u32 *result); /** - * nvme_get_features_iocs_profile() - + * nvme_get_features_iocs_profile() - Get IOCS profile feature * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 @@ -2893,33 +2868,6 @@ int nvme_get_features_write_protect(int fd, __u32 nsid, int nvme_get_features_iocs_profile(int fd, enum nvme_get_features_sel sel, __u32 *result); -/** - * struct nvme_format_nvm_args - Arguments for the Format Nvme Namespace command - * @result: The command completion result from CQE dword0 - * @args_size: Size of &struct nvme_format_nvm_args - * @fd: File descriptor of nvme device - * @timeout: Set to override default timeout to this value in milliseconds; - * useful for long running formats. 0 will use system default. - * @nsid: Namespace ID to format - * @mset: Metadata settings (extended or separated), true if extended - * @pi: Protection information type - * @pil: Protection information location (beginning or end), true if end - * @ses: Secure erase settings - * @lbaf: Logical block address format - */ -struct nvme_format_nvm_args { - __u32 *result; - int args_size; - int fd; - __u32 timeout; - __u32 nsid; - enum nvme_cmd_format_mset mset; - enum nvme_cmd_format_pi pi; - enum nvme_cmd_format_pil pil; - enum nvme_cmd_format_ses ses; - __u8 lbaf; -}; - /** * nvme_format_nvm() - Format nvme namespace(s) * @args: &struct nvme_format_nvme_args argument structure @@ -2934,41 +2882,22 @@ struct nvme_format_nvm_args { */ int nvme_format_nvm(struct nvme_format_nvm_args *args); -/** - * struct nvme_ns_mgmt_args - Arguments for NVMe Namespace Management command - * @result: NVMe command result - * @ns: Namespace identication descriptors - * @args_size: Size of &struct nvme_ns_mgmt_args - * @fd: File descriptor of nvme device - * @timeout: Timeout in ms - * @nsid: Namespace identifier - * @sel: Type of management operation to perform - * @csi: Command Set Identifier - */ -struct nvme_ns_mgmt_args { - __u32 *result; - struct nvme_id_ns *ns; - int args_size; - int fd; - __u32 timeout; - __u32 nsid; - enum nvme_ns_mgmt_sel sel; - __u8 csi; -}; - /** * nvme_ns_mgmt() - Issue a Namespace management command * @args: &struct nvme_ns_mgmt_args Argument structure + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_ns_mgmt(struct nvme_ns_mgmt_args *args); /** - * nvme_ns_mgmt_create() - + * nvme_ns_mgmt_create() - Create a non attached namespace * @fd: File descriptor of nvme device * @ns: Namespace identification that defines ns creation parameters * @nsid: On success, set to the namespace id that was created - * @timeout: Overide the default timeout to this value in milliseconds; - * set to 0 to use the system default. + * @timeout: Override the default timeout to this value in milliseconds; + * set to 0 to use the system default. * @csi: Command Set Identifier * * On successful creation, the namespace exists in the subsystem, but is not @@ -2996,7 +2925,7 @@ static inline int nvme_ns_mgmt_create(int fd, struct nvme_id_ns *ns, } /** - * nvme_ns_mgmt_delete() - + * nvme_ns_mgmt_delete() - Delete a non attached namespace * @fd: File descriptor of nvme device * @nsid: Namespace identifier to delete * @@ -3023,37 +2952,23 @@ static inline int nvme_ns_mgmt_delete(int fd, __u32 nsid) return nvme_ns_mgmt(&args); } -/** - * struct nvme_ns_attach_args - Arguments for Nvme Namespace Management command - * @result: NVMe command result - * @ctrlist: Controller list to modify attachment state of nsid - * @args_size: Size of &struct nvme_ns_attach_args - * @fd: File descriptor of nvme device - * @timeout: Timeout in ms - * @nsid: Namespace ID to execute attach selection - * @sel: Attachment selection, see &enum nvme_ns_attach_sel - */ -struct nvme_ns_attach_args { - __u32 *result; - struct nvme_ctrl_list *ctrlist; - int args_size; - int fd; - __u32 timeout; - __u32 nsid; - enum nvme_ns_attach_sel sel; -}; - /** * nvme_ns_attach() - Attach or detach namespace to controller(s) * @args: &struct nvme_ns_attach_args Argument structure + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_ns_attach(struct nvme_ns_attach_args *args); /** - * nvme_ns_attach_ctrls() - + * nvme_ns_attach_ctrls() - Attach namespace to controllers * @fd: File descriptor of nvme device * @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_ns_attach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist) @@ -3072,10 +2987,13 @@ static inline int nvme_ns_attach_ctrls(int fd, __u32 nsid, } /** - * nvme_ns_detach_ctrls() - + * nvme_ns_detach_ctrls() - Detach namespace from controllers * @fd: File descriptor of nvme device * @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_ns_detach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist) @@ -3093,29 +3011,9 @@ static inline int nvme_ns_detach_ctrls(int fd, __u32 nsid, return nvme_ns_attach(&args); } -/** - * struct nvme_fw_download_args - Arguments for the NVMe Firmware Download command - * @args_size: Size of &struct nvme_fw_download_args - * @fd: File descriptor of nvme device - * @result: The command completion result from CQE dword0 - * @timeout: Timeout in ms - * @offset: Offset in the firmware data - * @data: Userspace address of the firmware data - * @data_len: Length of data in this command in bytes - */ -struct nvme_fw_download_args { - __u32 *result; - void *data; - int args_size; - int fd; - __u32 timeout; - __u32 offset; - __u32 data_len; -}; - /** * nvme_fw_download() - Download part or all of a firmware image to the - * controller + * controller * @args: &struct nvme_fw_download_args argument structure * * The Firmware Image Download command downloads all or a portion of an image @@ -3136,26 +3034,6 @@ struct nvme_fw_download_args { */ int nvme_fw_download(struct nvme_fw_download_args *args); -/** - * struct nvme_fw_commit_args - Arguments for the NVMe Firmware Commit command - * @args_size: Size of &struct nvme_fw_commit_args - * @fd: File descriptor of nvme device - * @action: Action to use for the firmware image, see &enum nvme_fw_commit_ca - * @timeout: Timeout in ms - * @result: The command completion result from CQE dword0 - * @slot: Firmware slot to commit the downloaded image - * @bpid: Set to true to select the boot partition id - */ -struct nvme_fw_commit_args { - __u32 *result; - int args_size; - int fd; - __u32 timeout; - enum nvme_fw_commit_ca action; - __u8 slot; - bool bpid; -}; - /** * nvme_fw_commit() - Commit firmware using the specified action * @args: &struct nvme_fw_commit_args argument structure @@ -3170,37 +3048,7 @@ struct nvme_fw_commit_args { int nvme_fw_commit(struct nvme_fw_commit_args *args); /** - * struct nvme_security_send_args - Arguments for the NVMe Security Send command - * @result: The command completion result from CQE dword0 - * @data: Security data payload to send - * @args_size: Size of &struct nvme_security_send_args - * @fd: File descriptor of nvme device - * @timeout: Timeout in ms - * @nsid: Namespace ID to issue security command on - * @tl: Protocol specific transfer length - * @data_len: Data length of the payload in bytes - * @nssf: NVMe Security Specific field - * @spsp0: Security Protocol Specific field - * @spsp1: Security Protocol Specific field - * @secp: Security Protocol - */ -struct nvme_security_send_args { - __u32 *result; - void *data; - int args_size; - int fd; - __u32 timeout; - __u32 nsid; - __u32 tl; - __u32 data_len; - __u8 nssf; - __u8 spsp0; - __u8 spsp1; - __u8 secp; -}; - -/** - * nvme_security_send() - + * nvme_security_send() - Security Send command * @args: &struct nvme_security_send argument structure * * The Security Send command transfers security protocol data to the @@ -3218,71 +3066,14 @@ struct nvme_security_send_args { int nvme_security_send(struct nvme_security_send_args *args); /** - * struct nvme_security_receive_args - Arguments for the NVMe Security Receive command - * @result: The command completion result from CQE dword0 - * @data: Security data payload to send - * @args_size: Size of &struct nvme_security_receive_args - * @fd: File descriptor of nvme device - * @timeout: Timeout in ms - * @nsid: Namespace ID to issue security command on - * @al: Protocol specific allocation length - * @data_len: Data length of the payload in bytes - * @nssf: NVMe Security Specific field - * @spsp0: Security Protocol Specific field - * @spsp1: Security Protocol Specific field - * @secp: Security Protocol - */ -struct nvme_security_receive_args { - __u32 *result; - void *data; - int args_size; - int fd; - __u32 timeout; - __u32 nsid; - __u32 al; - __u32 data_len; - __u8 nssf; - __u8 spsp0; - __u8 spsp1; - __u8 secp; -}; - -/** - * nvme_security_receive() - - * @args: &struct nvme_security_recevice argument structure + * nvme_security_receive() - Security Receive command + * @args: &struct nvme_security_receive argument structure * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_security_receive(struct nvme_security_receive_args *args); -/** - * struct nvme_get_lba_status_args - Arguments for the NVMe Get LBA Status command - * @lbas: Data payload to return status descriptors - * @result: The command completion result from CQE dword0 - * @slba: Starting logical block address to check statuses - * @args_size: Size of &struct nvme_get_lba_status_args - * @fd: File descriptor of nvme device - * @timeout: Timeout in ms - * @nsid: Namespace ID to retrieve LBA status - * @mndw: Maximum number of dwords to return - * @atype: Action type mechanism to determine LBA status desctriptors to - * return, see &enum nvme_lba_status_atype - * @rl: Range length from slba to perform the action - */ -struct nvme_get_lba_status_args { - __u64 slba; - __u32 *result; - struct nvme_lba_status *lbas; - int args_size; - int fd; - __u32 timeout; - __u32 nsid; - __u32 mndw; - enum nvme_lba_status_atype atype; - __u16 rl; -}; - /** * nvme_get_lba_status() - Retrieve information on possibly unrecoverable LBAs * @args: &struct nvme_get_lba_status_args argument structure @@ -3295,34 +3086,6 @@ struct nvme_get_lba_status_args { */ int nvme_get_lba_status(struct nvme_get_lba_status_args *args); -/** - * struct nvme_directive_send_args - Arguments for the NVMe Directive Send command - * @result: If successful, the CQE dword0 value - * @data: Data payload to to be send - * @args_size: Size of &struct nvme_directive_send_args - * @fd: File descriptor of nvme device - * @timeout: Timeout in ms - * @nsid: Namespace ID, if applicable - * @doper: Directive send operation, see &enum nvme_directive_send_doper - * @dtype: Directive type, see &enum nvme_directive_dtype - * @cdw12: Directive specific command dword12 - * @data_len: Length of data payload in bytes - * @dspec: Directive specific field - */ -struct nvme_directive_send_args { - __u32 *result; - void *data; - int args_size; - int fd; - __u32 timeout; - __u32 nsid; - enum nvme_directive_send_doper doper; - enum nvme_directive_dtype dtype; - __u32 cdw12; - __u32 data_len; - __u16 dspec; -}; - /** * nvme_directive_send() - Send directive command * @args: &struct nvme_directive_send_args argument structure @@ -3339,7 +3102,7 @@ struct nvme_directive_send_args { int nvme_directive_send(struct nvme_directive_send_args *args); /** - * nvme_directive_send_id_endir() - + * nvme_directive_send_id_endir() - Directive Send Enable Directive * @fd: File descriptor of nvme device * @nsid: Namespace Identifier * @endir: Enable Directive @@ -3354,7 +3117,7 @@ int nvme_directive_send_id_endir(int fd, __u32 nsid, bool endir, struct nvme_id_directives *id); /** - * nvme_directive_send_stream_release_identifier() - + * nvme_directive_send_stream_release_identifier() - Directive Send Stream release * @fd: File descriptor of nvme device * @nsid: Namespace ID * @stream_id: Stream identifier @@ -3383,7 +3146,7 @@ static inline int nvme_directive_send_stream_release_identifier(int fd, } /** - * nvme_directive_send_stream_release_resource() - + * nvme_directive_send_stream_release_resource() - Directive Send Stream release resources * @fd: File descriptor of nvme device * @nsid: Namespace ID * @@ -3409,34 +3172,6 @@ static inline int nvme_directive_send_stream_release_resource(int fd, __u32 nsid return nvme_directive_send(&args); } -/** - * struct nvme_directive_recv_args - Arguments for the NVMe Directive Receive command - * @result: If successful, the CQE dword0 value - * @data: Usespace address of data payload - * @args_size: Size of &struct nvme_directive_recv_args - * @fd: File descriptor of nvme device - * @timeout: Timeout in ms - * @nsid: Namespace ID, if applicable - * @doper: Directive send operation, see &enum nvme_directive_send_doper - * @dtype: Directive type, see &enum nvme_directive_dtype - * @cdw12: Directive specific command dword12 - * @data_len: Length of data payload in bytes - * @dspec: Directive specific field - */ -struct nvme_directive_recv_args { - __u32 *result; - void *data; - int args_size; - int fd; - __u32 timeout; - __u32 nsid; - enum nvme_directive_receive_doper doper; - enum nvme_directive_dtype dtype; - __u32 cdw12; - __u32 data_len; - __u16 dspec; -}; - /** * nvme_directive_recv() - Receive directive specific data * @args: &struct nvme_directive_recv_args argument structure @@ -3447,7 +3182,7 @@ struct nvme_directive_recv_args { int nvme_directive_recv(struct nvme_directive_recv_args *args); /** - * nvme_directive_recv_identify_parameters() - + * nvme_directive_recv_identify_parameters() - Directive receive identifier parameters * @fd: File descriptor of nvme device * @nsid: Namespace ID * @id: Identify parameters buffer @@ -3476,7 +3211,7 @@ static inline int nvme_directive_recv_identify_parameters(int fd, __u32 nsid, } /** - * nvme_directive_recv_stream_parameters() - + * nvme_directive_recv_stream_parameters() - Directive receive stream parameters * @fd: File descriptor of nvme device * @nsid: Namespace ID * @parms: Streams directive parameters buffer @@ -3505,7 +3240,7 @@ static inline int nvme_directive_recv_stream_parameters(int fd, __u32 nsid, } /** - * nvme_directive_recv_stream_status() - + * nvme_directive_recv_stream_status() - Directive receive stream status * @fd: File descriptor of nvme device * @nsid: Namespace ID * @nr_entries: Number of streams to receive @@ -3515,7 +3250,7 @@ static inline int nvme_directive_recv_stream_parameters(int fd, __u32 nsid, * &enum nvme_status_field) or -1 with errno set otherwise. */ static inline int nvme_directive_recv_stream_status(int fd, __u32 nsid, - unsigned nr_entries, + unsigned int nr_entries, struct nvme_streams_directive_status *id) { struct nvme_directive_recv_args args = { @@ -3536,7 +3271,7 @@ static inline int nvme_directive_recv_stream_status(int fd, __u32 nsid, } /** - * nvme_directive_recv_stream_allocate() - + * nvme_directive_recv_stream_allocate() - Directive receive stream allocate * @fd: File descriptor of nvme device * @nsid: Namespace ID * @nsr: Namespace Streams Requested @@ -3566,31 +3301,7 @@ static inline int nvme_directive_recv_stream_allocate(int fd, __u32 nsid, } /** - * struct nvme_capacity_mgmt_args - Arguments for the NVMe Capacity Management command - * @result: If successful, the CQE dword0 value - * @args_size: Size of &struct nvme_capacity_mgmt_args - * @fd: File descriptor of nvme device - * @cdw11: Least significant 32 bits of the capacity in bytes of the - * Endurance Group or NVM Set to be created - * @cdw12: Most significant 32 bits of the capacity in bytes of the - * Endurance Group or NVM Set to be created - * @timeout: Timeout in ms - * @element_id: Value specific to the value of the Operation field - * @op: Operation to be performed by the controller - */ -struct nvme_capacity_mgmt_args { - __u32 *result; - int args_size; - int fd; - __u32 timeout; - __u32 cdw11; - __u32 cdw12; - __u16 element_id; - __u8 op; -}; - -/** - * nvme_capacity_mgmt() - + * nvme_capacity_mgmt() - Capacity management command * @args: &struct nvme_capacity_mgmt_args argument structure * * Return: The nvme command status if a response was received (see @@ -3598,30 +3309,6 @@ struct nvme_capacity_mgmt_args { */ int nvme_capacity_mgmt(struct nvme_capacity_mgmt_args *args); -/** - * struct nvme_lockdown_args - Arguments for the NVME Lockdown command - * @args_size: Size of &struct nvme_lockdown_args - * @fd: File descriptor of nvme device - * @result: The command completion result from CQE dword0 - * @timeout: Timeout in ms (0 for default timeout) - * @scp: Scope of the command - * @prhbt: Prohibit or allow the command opcode or Set Features command - * @ifc: Affected interface - * @ofi: Opcode or Feature Identifier - * @uuidx: UUID Index if controller supports this id selection method - */ -struct nvme_lockdown_args { - __u32 *result; - int args_size; - int fd; - __u32 timeout; - __u8 scp; - __u8 prhbt; - __u8 ifc; - __u8 ofi; - __u8 uuidx; -}; - /** * nvme_lockdown() - Issue lockdown command * @args: &struct nvme_lockdown_args argument structure @@ -3631,24 +3318,6 @@ struct nvme_lockdown_args { */ int nvme_lockdown(struct nvme_lockdown_args *args); -/** - * struct nvme_set_property_args - Arguments for NVMe Set Property command - * @args_size: Size of &struct nvme_set_property_args - * @fd: File descriptor of nvme device - * @result: The command completion result from CQE dword0 - * @timeout: Timeout in ms - * @offset: Property offset from the base to set - * @value: The value to set the property - */ -struct nvme_set_property_args { - __u64 value; - __u32 *result; - int args_size; - int fd; - __u32 timeout; - int offset; -}; - /** * nvme_set_property() - Set controller property * @args: &struct nvme_set_property_args argument structure @@ -3661,22 +3330,6 @@ struct nvme_set_property_args { */ int nvme_set_property(struct nvme_set_property_args *args); -/** - * struct nvme_get_property_args - Arguments for NVMe Get Property command - * @value: Where the property's value will be stored on success - * @args_size: Size of &struct nvme_get_property_args - * @fd: File descriptor of nvme device - * @offset: Property offset from the base to retrieve - * @timeout: Timeout in ms - */ -struct nvme_get_property_args { - __u64 *value; - int args_size; - int fd; - __u32 timeout; - int offset; -}; - /** * nvme_get_property() - Get a controller property * @args: &struct nvme_get_propert_args argument structure @@ -3689,32 +3342,6 @@ struct nvme_get_property_args { */ int nvme_get_property(struct nvme_get_property_args *args); -/** - * struct nvme_sanitize_nvm_args - Arguments for the NVMe Sanitize NVM command - * @result: The command completion result from CQE dword0 - * @args_size: Size of &struct nvme_sanitize_nvm_args - * @fd: File descriptor of nvme device - * @timeout: Timeout in ms - * @ovrpat: Overwrite pattern - * @sanact: Sanitize action, see &enum nvme_sanitize_sanact - * @ause: Set to allow unrestriced sanitize exit - * @owpass: Overwrite pass count - * @oipbp: Set to overwrite invert pattern between passes - * @nodas: Set to not deallocate blocks after sanitizing - */ -struct nvme_sanitize_nvm_args { - __u32 *result; - int args_size; - int fd; - __u32 timeout; - enum nvme_sanitize_sanact sanact; - __u32 ovrpat; - bool ause; - __u8 owpass; - bool oipbp; - bool nodas; -}; - /** * nvme_sanitize_nvm() - Start a sanitize operation * @args: &struct nvme_sanitize_nvm_args argument structure @@ -3734,24 +3361,6 @@ struct nvme_sanitize_nvm_args { */ int nvme_sanitize_nvm(struct nvme_sanitize_nvm_args *args); -/** - * struct nvme_dev_self_test_args - Arguments for the NVMe Device Self Test command - * @result: The command completion result from CQE dword0 - * @args_size: Size of &struct nvme_dev_self_test_args - * @fd: File descriptor of nvme device - * @nsid: Namespace ID to test - * @stc: Self test code, see &enum nvme_dst_stc - * @timeout: Timeout in ms - */ -struct nvme_dev_self_test_args { - __u32 *result; - int args_size; - int fd; - __u32 timeout; - __u32 nsid; - enum nvme_dst_stc stc; -}; - /** * nvme_dev_self_test() - Start or abort a self test * @args: &struct nvme_dev_self_test argument structure @@ -3772,29 +3381,6 @@ struct nvme_dev_self_test_args { */ int nvme_dev_self_test(struct nvme_dev_self_test_args *args); -/** - * struct nvme_virtual_mgmt_args - Arguments for the NVMe Virtualization - * resource management command - * @args_size: Size of &struct nvme_virtual_mgmt_args - * @fd: File descriptor of nvme device - * @result: If successful, the CQE dword0 - * @timeout: Timeout in ms - * @act: Virtual resource action, see &enum nvme_virt_mgmt_act - * @rt: Resource type to modify, see &enum nvme_virt_mgmt_rt - * @cntlid: Controller id for which resources are bing modified - * @nr: Number of resources being allocated or assigned - */ -struct nvme_virtual_mgmt_args { - __u32 *result; - int args_size; - int fd; - __u32 timeout; - enum nvme_virt_mgmt_act act; - enum nvme_virt_mgmt_rt rt; - __u16 cntlid; - __u16 nr; -}; - /** * nvme_virtual_mgmt() - Virtualization resource management * @args: &struct nvme_virtual_mgmt_args argument structure @@ -3823,7 +3409,8 @@ int nvme_virtual_mgmt(struct nvme_virtual_mgmt_args *args); * 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_flush(int fd, __u32 nsid) { +static inline int nvme_flush(int fd, __u32 nsid) +{ struct nvme_passthru_cmd cmd = {}; cmd.opcode = nvme_cmd_flush; @@ -3832,56 +3419,6 @@ static inline int nvme_flush(int fd, __u32 nsid) { return nvme_submit_io_passthru(fd, &cmd, NULL); } -/** - * struct nvme_io_args - Arguments for NVMe I/O commands - * @slba: Starting logical block - * @storage_tag: This filed specifies Variable Sized Expected Logical Block - * Storage Tag (ELBST) and Expected Logical Block Reference - * Tag (ELBRT) - * @result: The command completion result from CQE dword0 - * @data: Pointer to user address of the data buffer - * @metadata: Pointer to user address of the metadata buffer - * @args_size: Size of &struct nvme_io_args - * @fd: File descriptor of nvme device - * @timeout: Timeout in ms - * @nsid: Namespace ID - * @data_len: Length of user buffer, @data, in bytes - * @metadata_len:Length of user buffer, @metadata, in bytes - * @nlb: Number of logical blocks to send (0's based value) - * @control: Command control flags, see &enum nvme_io_control_flags. - * @apptag: This field specifies the Application Tag Mask expected value. - * Used only if the namespace is formatted to use end-to-end - * protection information. - * @appmask: This field specifies the Application Tag expected value. Used - * only if the namespace is formatted to use end-to-end protection - * information. - * @reftag: This field specifies the Initial Logical Block Reference Tag - * expected value. Used only if the namespace is formatted to use - * end-to-end protection information. - * @dspec: Directive specific value - * @dsm: Data set management attributes, see &enum nvme_io_dsm_flags - */ -struct nvme_io_args { - __u64 slba; - __u64 storage_tag; - __u32 *result; - void *data; - void *metadata; - int args_size; - int fd; - __u32 timeout; - __u32 nsid; - __u32 reftag; - __u32 data_len; - __u32 metadata_len; - __u16 nlb; - __u16 control; - __u16 apptag; - __u16 appmask; - __u16 dspec; - __u8 dsm; -}; - /** * nvme_io() - Submit an nvme user I/O command * @args: &struct nvme_io_args argument structure @@ -3978,28 +3515,6 @@ static inline int nvme_verify(struct nvme_io_args *args) return nvme_io(args, nvme_cmd_verify); } -/** - * struct nvme_dsm_args - Arguments for the NVMe Dataset Management command - * @result: The command completion result from CQE dword0 - * @dsm: The data set management attributes - * @args_size: Size of &struct nvme_dsm_args - * @fd: File descriptor of nvme device - * @timeout: Timeout in ms - * @nsid: Namespace identifier - * @attrs: DSM attributes, see &enum nvme_dsm_attributes - * @nr_ranges: Number of block ranges in the data set management attributes - */ -struct nvme_dsm_args { - __u32 *result; - struct nvme_dsm_range *dsm; - int args_size; - int fd; - __u32 timeout; - __u32 nsid; - __u32 attrs; - __u16 nr_ranges; -}; - /** * nvme_dsm() - Send an nvme data set management command * @args: &struct nvme_dsm_args argument structure @@ -4016,49 +3531,7 @@ struct nvme_dsm_args { int nvme_dsm(struct nvme_dsm_args *args); /** - * struct nvme_copy_args - Arguments for the NVMe Copy command - * @sdlba: Start destination LBA - * @result: The command completion result from CQE dword0 - * @copy: Range descriptior - * @args_size: Size of &struct nvme_copy_args - * @fd: File descriptor of the nvme device - * @timeout: Timeout in ms - * @nsid: Namespace identifier - * @ilbrt: Initial logical block reference tag - * @lr: Limited retry - * @fua: Force unit access - * @nr: Number of ranges - * @dspec: Directive specific value - * @lbatm: Logical block application tag mask - * @lbat: Logical block application tag - * @prinfor: Protection information field for read - * @prinfow: Protection information field for write - * @dtype: Directive type - * @format: Descriptor format - */ -struct nvme_copy_args { - __u64 sdlba; - __u32 *result; - struct nvme_copy_range *copy; - int args_size; - int fd; - __u32 timeout; - __u32 nsid; - __u32 ilbrt; - int lr; - int fua; - __u16 nr; - __u16 dspec; - __u16 lbatm; - __u16 lbat; - __u8 prinfor; - __u8 prinfow; - __u8 dtype; - __u8 format; -}; - -/** - * nvme_copy() - + * nvme_copy() - Copy command * * @args: &struct nvme_copy_args argument structure * @@ -4067,33 +3540,6 @@ struct nvme_copy_args { */ int nvme_copy(struct nvme_copy_args *args); -/** - * struct nvme_resv_acquire_args - Arguments for the NVMe Reservation Acquire Comand - * @nrkey: The reservation key to be unregistered from the namespace if - * the action is preempt - * @iekey: Set to ignore the existing key - * @result: The command completion result from CQE dword0 - * @args_size: Size of &struct nvme_resv_acquire_args - * @fd: File descriptor of nvme device - * @timeout: Timeout in ms - * @nsid: Namespace identifier - * @rtype: The type of reservation to be create, see &enum nvme_resv_rtype - * @racqa: The action that is performed by the command, see &enum nvme_resv_racqa - * @crkey: The current reservation key associated with the host - */ -struct nvme_resv_acquire_args { - __u64 crkey; - __u64 nrkey; - __u32 *result; - int args_size; - int fd; - __u32 timeout; - __u32 nsid; - enum nvme_resv_rtype rtype; - enum nvme_resv_racqa racqa; - bool iekey; -}; - /** * nvme_resv_acquire() - Send an nvme reservation acquire * @args: &struct nvme_resv_acquire argument structure @@ -4107,33 +3553,6 @@ struct nvme_resv_acquire_args { */ int nvme_resv_acquire(struct nvme_resv_acquire_args *args); -/** - * struct nvme_resv_register_args - Arguments for the NVMe Reservation Register command - * @crkey: The current reservation key associated with the host - * @nrkey: The new reservation key to be register if action is register or - * replace - * @result: The command completion result from CQE dword0 - * @args_size: Size of &struct nvme_resv_register_args - * @fd: File descriptor of nvme device - * @nsid: Namespace identifier - * @rrega: The registration action, see &enum nvme_resv_rrega - * @cptpl: Change persist through power loss, see &enum nvme_resv_cptpl - * @iekey: Set to ignore the existing key - * @timeout: Timeout in ms - */ -struct nvme_resv_register_args { - __u64 crkey; - __u64 nrkey; - __u32 *result; - int args_size; - int fd; - __u32 timeout; - __u32 nsid; - enum nvme_resv_rrega rrega; - enum nvme_resv_cptpl cptpl; - bool iekey; -}; - /** * nvme_resv_register() - Send an nvme reservation register * @args: &struct nvme_resv_register_args argument structure @@ -4146,30 +3565,6 @@ struct nvme_resv_register_args { */ int nvme_resv_register(struct nvme_resv_register_args *args); -/** - * struct nvme_resv_release_args - Arguments for the NVMe Reservation Release Command - * @crkey: The current reservation key to release - * @result: The command completion result from CQE dword0 - * @args_size: Size of &struct nvme_resv_release_args - * @fd: File descriptor of nvme device - * @timeout: Timeout in ms - * @nsid: Namespace identifier - * @rtype: The type of reservation to be create, see &enum nvme_resv_rtype - * @rrela: Reservation releast action, see &enum nvme_resv_rrela - * @iekey: Set to ignore the existing key - */ -struct nvme_resv_release_args { - __u64 crkey; - __u32 *result; - int args_size; - int fd; - __u32 timeout; - __u32 nsid; - enum nvme_resv_rtype rtype; - enum nvme_resv_rrela rrela; - bool iekey; -}; - /** * nvme_resv_release() - Send an nvme reservation release * @args: &struct nvme_resv_release_args argument structure @@ -4179,35 +3574,12 @@ struct nvme_resv_release_args { */ int nvme_resv_release(struct nvme_resv_release_args *args); -/** - * struct nvme_resv_report_args - Arguments for the NVMe Reservation Report command - * @result: The command completion result from CQE dword0 - * @report: The user space destination address to store the reservation - * report - * @args_size: Size of &struct nvme_resv_report_args - * @fd: File descriptor of nvme device - * @timeout: Timeout in ms - * @nsid: Namespace identifier - * @len: Number of bytes to request transfered with this command - * @eds: Request extended Data Structure - */ -struct nvme_resv_report_args { - __u32 *result; - struct nvme_resv_status *report; - int args_size; - int fd; - __u32 timeout; - __u32 nsid; - __u32 len; - bool eds; -}; - /** * nvme_resv_report() - Send an nvme reservation report * @args: struct nvme_resv_report_args argument structure * * Returns a Reservation Status data structure to memory that describes the - * registration and reservation status of a namespace. See the defintion for + * registration and reservation status of a namespace. See the definition for * the returned structure, &struct nvme_reservation_status, for more details. * * Return: The nvme command status if a response was received (see @@ -4216,35 +3588,7 @@ struct nvme_resv_report_args { int nvme_resv_report(struct nvme_resv_report_args *args); /** - * struct nvme_zns_mgmt_send_args - Arguments for the NVMe ZNS Management Send command - * @slba: Starting logical block address - * @result: The command completion result from CQE dword0 - * @data: Userspace address of the data - * @args_size: Size of &struct nvme_zns_mgmt_send_args - * @fd: File descriptor of nvme device - * @timeout: timeout in ms - * @nsid: Namespace ID - * @zsa: Zone send action - * @data_len: Length of @data - * @select_all: Select all flag - * @zsaso: Zone Send Action Specific Option - */ -struct nvme_zns_mgmt_send_args { - __u64 slba; - __u32 *result; - void *data; - int args_size; - int fd; - __u32 timeout; - __u32 nsid; - enum nvme_zns_send_action zsa; - __u32 data_len; - bool select_all; - __u8 zsaso; -}; - -/** - * nvme_zns_mgmt_send() - + * nvme_zns_mgmt_send() - ZNS management send command * @args: &struct nvme_zns_mgmt_send_args argument structure * * Return: The nvme command status if a response was received (see @@ -4254,35 +3598,7 @@ int nvme_zns_mgmt_send(struct nvme_zns_mgmt_send_args *args); /** - * struct nvme_zns_mgmt_recv_args - Arguments for the NVMe ZNS Management Receive command - * @slba: Starting logical block address - * @result: The command completion result from CQE dword0 - * @data: Userspace address of the data - * @args_size: Size of &struct nvme_zns_mgmt_recv_args - * @fd: File descriptor of nvme device - * @timeout: timeout in ms - * @nsid: Namespace ID - * @zra: zone receive action - * @data_len: Length of @data - * @zrasf: Zone receive action specific field - * @zras_feat: Zone receive action specific features - */ -struct nvme_zns_mgmt_recv_args { - __u64 slba; - __u32 *result; - void *data; - int args_size; - int fd; - __u32 timeout; - __u32 nsid; - enum nvme_zns_recv_action zra; - __u32 data_len; - __u16 zrasf; - bool zras_feat; -}; - -/** - * nvme_zns_mgmt_recv() - + * nvme_zns_mgmt_recv() - ZNS management receive command * @args: &struct nvme_zns_mgmt_recv_args argument structure * * Return: The nvme command status if a response was received (see @@ -4323,49 +3639,13 @@ static inline int nvme_zns_report_zones(int fd, __u32 nsid, __u64 slba, .zra = extended ? NVME_ZNS_ZRA_EXTENDED_REPORT_ZONES : NVME_ZNS_ZRA_REPORT_ZONES, .data_len = data_len, - .zrasf = opts, + .zrasf = (__u16)opts, .zras_feat = partial, }; return nvme_zns_mgmt_recv(&args); } -/** - * struct nvme_zns_append_args - Arguments for the NVMe ZNS Append command - * @zslba: Zone start logical block address - * @result: The command completion result from CQE dword0 - * @data: Userspace address of the data - * @metadata: Userspace address of the metadata - * @args_size: Size of &struct nvme_zns_append_args - * @fd: File descriptor of nvme device - * @timeout: Timeout in ms - * @nsid: Namespace ID - * @ilbrt: Initial logical block reference tag - * @data_len: Length of @data - * @metadata_len: Length of @metadata - * @nlb: Number of logical blocks - * @control: - * @lbat: Logical block application tag - * @lbatm: Logical block application tag mask - */ -struct nvme_zns_append_args { - __u64 zslba; - __u64 *result; - void *data; - void *metadata; - int args_size; - int fd; - __u32 timeout; - __u32 nsid; - __u32 ilbrt; - __u32 data_len; - __u32 metadata_len; - __u16 nlb; - __u16 control; - __u16 lbat; - __u16 lbatm; -}; - /** * nvme_zns_append() - Append data to a zone * @args: &struct nvme_zns_append_args argument structure @@ -4375,26 +3655,6 @@ struct nvme_zns_append_args { */ int nvme_zns_append(struct nvme_zns_append_args *args); -/** - * struct nvme_dim_args - Arguments for the Discovery Information Management (DIM) command - * @result: Set on completion to the command's CQE DWORD 0 controller response. - * @data: Pointer to the DIM data - * @args_size: Length of the structure - * @fd: File descriptor of nvme device - * @timeout: Timeout in ms - * @data_len: Length of @data - * @tas: Task field of the Command Dword 10 (cdw10) - */ -struct nvme_dim_args { - __u32 *result; - void *data; - int args_size; - int fd; - __u32 timeout; - __u32 data_len; - __u8 tas; -}; - /** * nvme_dim_send - Send a Discovery Information Management (DIM) command * @args: &struct nvme_dim_args argument structure diff --git a/src/nvme/linux.h b/src/nvme/linux.h index 6223c0a..8a6d426 100644 --- a/src/nvme/linux.h +++ b/src/nvme/linux.h @@ -25,7 +25,7 @@ * @fd: File descriptor of nvme device * @size: Total size of the firmware image to transfer * @xfer: Maximum size to send with each partial transfer - * @offset: Starting offset to send with this firmware downlaod + * @offset: Starting offset to send with this firmware download * @buf: Address of buffer containing all or part of the firmware image. * * Return: The nvme command status if a response was received (see @@ -109,7 +109,7 @@ int nvme_get_new_host_telemetry(int fd, struct nvme_telemetry_log **log, int nvme_get_log_page(int fd, __u32 xfer_len, struct nvme_get_log_args *args); /** - * nvme_get_ana_log_len() - Retreive size of the current ANA log + * nvme_get_ana_log_len() - Retrieve size of the current ANA log * @fd: File descriptor of nvme device * @analen: Pointer to where the length will be set on success * @@ -130,11 +130,11 @@ int nvme_get_ana_log_len(int fd, size_t *analen); int nvme_get_logical_block_size(int fd, __u32 nsid, int *blksize); /** - * nvme_get_lba_status_log() - Retreive the LBA Status log page + * nvme_get_lba_status_log() - Retrieve the LBA Status log page * @fd: File descriptor of the nvme device * @rae: Retain asynchronous events - * @log: On success, set to the value of the allocated and retreived log. - * + * @log: On success, set to the value of the allocated and retrieved log. + * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ diff --git a/src/nvme/log.c b/src/nvme/log.c index 1bc44f2..e4697df 100644 --- a/src/nvme/log.c +++ b/src/nvme/log.c @@ -1,16 +1,9 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later /* + * This file is part of libnvme. * Copyright (C) 2021 SUSE LLC * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Authors: Hannes Reinecke * * This file implements basic logging functionality. */ diff --git a/src/nvme/mi-mctp.c b/src/nvme/mi-mctp.c new file mode 100644 index 0000000..81704aa --- /dev/null +++ b/src/nvme/mi-mctp.c @@ -0,0 +1,751 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/* + * This file is part of libnvme. + * Copyright (c) 2021 Code Construct Pty Ltd + * + * Authors: Jeremy Kerr + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#if HAVE_LINUX_MCTP_H +#include +#endif + +#include + +#ifdef CONFIG_LIBSYSTEMD +#include +#include +#include + +#define MCTP_DBUS_PATH "/xyz/openbmc_project/mctp" +#define MCTP_DBUS_IFACE "xyz.openbmc_project.MCTP" +#define MCTP_DBUS_IFACE_ENDPOINT "xyz.openbmc_project.MCTP.Endpoint" +#endif + +#include "private.h" +#include "log.h" +#include "mi.h" + + +#if !defined(AF_MCTP) +#define AF_MCTP 45 +#endif + +#if !HAVE_LINUX_MCTP_H +/* As of kernel v5.15, these AF_MCTP-related definitions are provided by + * linux/mctp.h. However, we provide a set here while that header percolates + * through to standard includes. + * + * These were all introduced in the same version as AF_MCTP was defined, + * so we can key off the presence of that. + */ + +typedef __u8 mctp_eid_t; + +struct mctp_addr { + mctp_eid_t s_addr; +}; + +struct sockaddr_mctp { + unsigned short int smctp_family; + __u16 __smctp_pad0; + unsigned int smctp_network; + struct mctp_addr smctp_addr; + __u8 smctp_type; + __u8 smctp_tag; + __u8 __smctp_pad1; +}; + +#define MCTP_NET_ANY 0x0 + +#define MCTP_ADDR_NULL 0x00 +#define MCTP_ADDR_ANY 0xff + +#define MCTP_TAG_MASK 0x07 +#define MCTP_TAG_OWNER 0x08 + +#endif /* !AF_MCTP */ + +#define MCTP_TYPE_NVME 0x04 +#define MCTP_TYPE_MIC 0x80 + +struct nvme_mi_transport_mctp { + int net; + __u8 eid; + int sd; +}; + +static int ioctl_tag(int sd, unsigned long req, struct mctp_ioc_tag_ctl *ctl) +{ + return ioctl(sd, req, ctl); +} + +static struct __mi_mctp_socket_ops ops = { + socket, + sendmsg, + recvmsg, + ioctl_tag, +}; + +void __nvme_mi_mctp_set_ops(const struct __mi_mctp_socket_ops *newops) +{ + ops = *newops; +} +static const struct nvme_mi_transport nvme_mi_transport_mctp; + +#ifdef SIOCMCTPALLOCTAG +static __u8 nvme_mi_mctp_tag_alloc(struct nvme_mi_ep *ep) +{ + struct nvme_mi_transport_mctp *mctp; + struct mctp_ioc_tag_ctl ctl = { 0 }; + static bool logged; + int rc; + + mctp = ep->transport_data; + + ctl.peer_addr = mctp->eid; + + errno = 0; + rc = ops.ioctl_tag(mctp->sd, SIOCMCTPALLOCTAG, &ctl); + if (rc) { + if (!logged) { + /* not necessarily fatal, just means we can't handle + * "more processing required" messages */ + nvme_msg(ep->root, LOG_INFO, + "System does not support explicit tag allocation\n"); + logged = true; + } + return MCTP_TAG_OWNER; + } + + return ctl.tag; +} + +static void nvme_mi_mctp_tag_drop(struct nvme_mi_ep *ep, __u8 tag) +{ + struct nvme_mi_transport_mctp *mctp; + struct mctp_ioc_tag_ctl ctl = { 0 }; + + mctp = ep->transport_data; + + if (!(tag & MCTP_TAG_PREALLOC)) + return; + + ctl.peer_addr = mctp->eid; + ctl.tag = tag; + + ops.ioctl_tag(mctp->sd, SIOCMCTPDROPTAG, &ctl); +} + +#else /* !defined SIOMCTPTAGALLOC */ + +static __u8 nvme_mi_mctp_tag_alloc(struct nvme_mi_ep *ep) +{ + static bool logged; + if (!logged) { + nvme_msg(ep->root, LOG_INFO, + "Build does not support explicit tag allocation\n"); + logged = true; + } + return MCTP_TAG_OWNER; +} + +static void nvme_mi_mctp_tag_drop(struct nvme_mi_ep *ep, __u8 tag) +{ +} + +#endif /* !defined SIOMCTPTAGALLOC */ + +static bool nvme_mi_mctp_resp_is_mpr(struct nvme_mi_resp *resp, size_t len) +{ + struct nvme_mi_msg_resp *msg; + __le32 mic; + __u32 crc; + + if (len != sizeof(*msg) + sizeof(mic)) + return false; + + msg = (struct nvme_mi_msg_resp *)resp->hdr; + + if (msg->status != NVME_MI_RESP_MPR) + return false; + + /* We can't use verify_resp_mic here, as the response structure has + * not been laid-out properly in resp yet (this is deferred until + * we have the actual response). + * + * We know the data is a fixed size, and linear in the hdr buf, so + * calculation is fairly simple. We do need to find the MIC data + * though, which could either be in the header buf (if the original + * header was larger than the minimal header message), or the start of + * the data buf (otherwise). + */ + if (resp->hdr_len > sizeof(*msg)) + mic = *(__le32 *)(msg + 1); + else + mic = *(__le32 *)(resp->data); + + crc = ~nvme_mi_crc32_update(0xffffffff, msg, sizeof(*msg)); + if (le32_to_cpu(mic) != crc) + return false; + + return true; +} + +static int nvme_mi_mctp_submit(struct nvme_mi_ep *ep, + struct nvme_mi_req *req, + struct nvme_mi_resp *resp) +{ + struct nvme_mi_transport_mctp *mctp; + struct iovec req_iov[3], resp_iov[3]; + struct msghdr req_msg, resp_msg; + struct sockaddr_mctp addr; + int i, rc, errno_save; + ssize_t len; + __le32 mic; + __u8 tag; + + if (ep->transport != &nvme_mi_transport_mctp) { + errno = EINVAL; + return -1; + } + + /* we need enough space for at least a generic (/error) response */ + if (resp->hdr_len < sizeof(struct nvme_mi_msg_resp)) { + errno = EINVAL; + return -1; + } + + mctp = ep->transport_data; + tag = nvme_mi_mctp_tag_alloc(ep); + + memset(&addr, 0, sizeof(addr)); + addr.smctp_family = AF_MCTP; + addr.smctp_network = mctp->net; + addr.smctp_addr.s_addr = mctp->eid; + addr.smctp_type = MCTP_TYPE_NVME | MCTP_TYPE_MIC; + addr.smctp_tag = tag; + + i = 0; + req_iov[i].iov_base = ((__u8 *)req->hdr) + 1; + req_iov[i].iov_len = req->hdr_len - 1; + i++; + + if (req->data_len) { + req_iov[i].iov_base = req->data; + req_iov[i].iov_len = req->data_len; + i++; + } + + mic = cpu_to_le32(req->mic); + req_iov[i].iov_base = &mic; + req_iov[i].iov_len = sizeof(mic); + i++; + + memset(&req_msg, 0, sizeof(req_msg)); + req_msg.msg_name = &addr; + req_msg.msg_namelen = sizeof(addr); + req_msg.msg_iov = req_iov; + req_msg.msg_iovlen = i; + + len = ops.sendmsg(mctp->sd, &req_msg, 0); + if (len < 0) { + errno_save = errno; + nvme_msg(ep->root, LOG_ERR, + "Failure sending MCTP message: %m\n"); + errno = errno_save; + rc = -1; + goto out; + } + + resp_iov[0].iov_base = ((__u8 *)resp->hdr) + 1; + resp_iov[0].iov_len = resp->hdr_len - 1; + + resp_iov[1].iov_base = ((__u8 *)resp->data); + resp_iov[1].iov_len = resp->data_len; + + resp_iov[2].iov_base = &mic; + resp_iov[2].iov_len = sizeof(mic); + + memset(&resp_msg, 0, sizeof(resp_msg)); + resp_msg.msg_name = &addr; + resp_msg.msg_namelen = sizeof(addr); + resp_msg.msg_iov = resp_iov; + resp_msg.msg_iovlen = 3; + +retry: + rc = -1; + len = ops.recvmsg(mctp->sd, &resp_msg, 0); + + if (len < 0) { + errno_save = errno; + nvme_msg(ep->root, LOG_ERR, + "Failure receiving MCTP message: %m\n"); + errno = errno_save; + goto out; + } + + + if (len == 0) { + nvme_msg(ep->root, LOG_WARNING, "No data from MCTP endpoint\n"); + errno = EIO; + goto out; + } + + /* Re-add the type byte, so we can work on aligned lengths from here */ + resp->hdr->type = MCTP_TYPE_NVME | MCTP_TYPE_MIC; + len += 1; + + /* The smallest response data is 8 bytes: generic 4-byte message header + * plus four bytes of error data (excluding MIC). Ensure we have enough. + */ + if (len < 8 + sizeof(mic)) { + nvme_msg(ep->root, LOG_ERR, + "Invalid MCTP response: too short (%zd bytes, needed %zd)\n", + len, 8 + sizeof(mic)); + errno = EPROTO; + goto out; + } + + /* We can't have header/payload data that isn't a multiple of 4 bytes */ + if (len & 0x3) { + nvme_msg(ep->root, LOG_WARNING, + "Response message has unaligned length (%zd)!\n", + len); + errno = EPROTO; + goto out; + } + + /* Check for a More Processing Required response. This is a slight + * layering violation, as we're pre-checking the MIC and inspecting + * header fields. However, we need to do this in the transport in order + * to keep the tag allocated and retry the recvmsg + */ + if (nvme_mi_mctp_resp_is_mpr(resp, len)) { + nvme_msg(ep->root, LOG_DEBUG, + "Received More Processing Required, waiting for response\n"); + /* TODO: when we implement timeouts, inspect the MPR response + * for the estimated completion time. */ + goto retry; + } + + /* If we have a shorter than expected response, we need to find the + * MIC and the correct split between header & data. We know that the + * split is 4-byte aligned, so the MIC will be entirely within one + * of the iovecs. + */ + if (len == resp->hdr_len + resp->data_len + sizeof(mic)) { + /* Common case: expected data length. Header, data and MIC + * are already laid-out correctly. Nothing to do. */ + + } else if (len < resp->hdr_len + sizeof(mic)) { + /* Response is smaller than the expected header. MIC is + * somewhere in the header buf */ + resp->hdr_len = len - sizeof(mic); + resp->data_len = 0; + memcpy(&mic, ((uint8_t *)resp->hdr) + resp->hdr_len, + sizeof(mic)); + + } else { + /* We have a full header, but data is truncated - possibly + * zero bytes. MIC is somewhere in the data buf */ + resp->data_len = len - resp->hdr_len - sizeof(mic); + memcpy(&mic, ((uint8_t *)resp->data) + resp->data_len, + sizeof(mic)); + } + + resp->mic = le32_to_cpu(mic); + + rc = 0; + +out: + nvme_mi_mctp_tag_drop(ep, tag); + + return rc; +} + +static void nvme_mi_mctp_close(struct nvme_mi_ep *ep) +{ + struct nvme_mi_transport_mctp *mctp; + + if (ep->transport != &nvme_mi_transport_mctp) + return; + + mctp = ep->transport_data; + close(mctp->sd); + free(ep->transport_data); +} + +static int nvme_mi_mctp_desc_ep(struct nvme_mi_ep *ep, char *buf, size_t len) +{ + struct nvme_mi_transport_mctp *mctp; + + if (ep->transport != &nvme_mi_transport_mctp) { + errno = EINVAL; + return -1; + } + + mctp = ep->transport_data; + + snprintf(buf, len, "net %d eid %d", mctp->net, mctp->eid); + + return 0; +} + +static const struct nvme_mi_transport nvme_mi_transport_mctp = { + .name = "mctp", + .mic_enabled = true, + .submit = nvme_mi_mctp_submit, + .close = nvme_mi_mctp_close, + .desc_ep = nvme_mi_mctp_desc_ep, +}; + +nvme_mi_ep_t nvme_mi_open_mctp(nvme_root_t root, unsigned int netid, __u8 eid) +{ + struct nvme_mi_transport_mctp *mctp; + struct nvme_mi_ep *ep; + int errno_save; + + ep = nvme_mi_init_ep(root); + if (!ep) + return NULL; + + mctp = malloc(sizeof(*mctp)); + if (!mctp) + goto err_free_ep; + + mctp->net = netid; + mctp->eid = eid; + + mctp->sd = ops.socket(AF_MCTP, SOCK_DGRAM, 0); + if (mctp->sd < 0) + goto err_free_ep; + + ep->transport = &nvme_mi_transport_mctp; + ep->transport_data = mctp; + + return ep; + +err_free_ep: + errno_save = errno; + free(ep); + errno = errno_save; + return NULL; +} + +#ifdef CONFIG_LIBSYSTEMD + +/* helper for handling dbus errors: D-Bus API returns a negtive errno on + * failure; set errno and log. + */ +static void _dbus_err(nvme_root_t root, int rc, int line) +{ + nvme_msg(root, LOG_ERR, "MCTP D-Bus failed line %d: %s %d\n", + line, strerror(-rc), rc); + errno = -rc; +} + +#define dbus_err(r, rc) _dbus_err(r, rc, __LINE__) + +static int nvme_mi_mctp_add(nvme_root_t root, unsigned int netid, __u8 eid) +{ + nvme_mi_ep_t ep = NULL; + + /* ensure we don't already have an endpoint with the same net/eid. if + * we do, just skip, no need to re-add. */ + list_for_each(&root->endpoints, ep, root_entry) { + if (ep->transport != &nvme_mi_transport_mctp) { + continue; + } + const struct nvme_mi_transport_mctp *t = ep->transport_data; + if (t->eid == eid && t->net == netid) + return 0; + } + + ep = nvme_mi_open_mctp(root, netid, eid); + if (!ep) + return -1; + + return 0; +} + +/* We can't rely on sd_bus_message_enter_container() == 0 at the end of + a dictionary (it returns -ENXIO) so we test separately */ +static bool container_end(sd_bus_message *m) +{ + return sd_bus_message_peek_type(m, NULL, NULL) == 0; +} + +static int handle_mctp_endpoint(nvme_root_t root, const char* objpath, + sd_bus_message *m) +{ + bool have_eid = false, have_net = false, have_nvmemi = false; + mctp_eid_t eid; + int net; + int rc; + + /* Iterate properties on this interface */ + while (!container_end(m)) { + /* Enter property dict */ + rc = sd_bus_message_enter_container(m, 'a', "{sv}"); + if (rc < 0) { + dbus_err(root, rc); + return -1; + } + + while (!container_end(m)) { + char *propname = NULL; + size_t sz; + const uint8_t *types = NULL; + /* Enter property item */ + rc = sd_bus_message_enter_container(m, 'e', "sv"); + if (rc < 0) { + dbus_err(root, rc); + return -1; + } + + rc = sd_bus_message_read(m, "s", &propname); + if (rc < 0) { + dbus_err(root, rc); + return -1; + } + + if (strcmp(propname, "EID") == 0) { + rc = sd_bus_message_read(m, "v", "y", &eid); + have_eid = true; + } else if (strcmp(propname, "NetworkId") == 0) { + rc = sd_bus_message_read(m, "v", "i", &net); + have_net = true; + } else if (strcmp(propname, "SupportedMessageTypes") == 0) { + sd_bus_message_enter_container(m, 'v', "ay"); + rc = sd_bus_message_read_array(m, 'y', (const void**)&types, &sz); + if (rc >= 0) + for (size_t s = 0; s < sz; s++) + if (types[s] == MCTP_TYPE_NVME) + have_nvmemi = true; + sd_bus_message_exit_container(m); + } else { + rc = sd_bus_message_skip(m, "v"); + } + + if (rc < 0) { + dbus_err(root, rc); + return -1; + } + + /* Exit prop item */ + rc = sd_bus_message_exit_container(m); + if (rc < 0) { + dbus_err(root, rc); + return -1; + } + } + + /* Exit property dict */ + rc = sd_bus_message_exit_container(m); + if (rc < 0) { + dbus_err(root, rc); + return -1; + } + } + + if (have_nvmemi) { + if (!(have_eid && have_net)) { + nvme_msg(root, LOG_ERR, + "Missing property for %s\n", objpath); + errno = ENOENT; + return -1; + } + rc = nvme_mi_mctp_add(root, net, eid); + if (rc < 0) { + int errno_save = errno; + nvme_msg(root, LOG_ERR, + "Error adding net %d eid %d: %m\n", net, eid); + errno = errno_save; + } + } else { + /* Ignore other endpoints */ + rc = 0; + } + return rc; +} + +static int handle_mctp_obj(nvme_root_t root, sd_bus_message *m) +{ + char *objpath = NULL; + char *ifname = NULL; + int rc; + + rc = sd_bus_message_read(m, "o", &objpath); + if (rc < 0) { + dbus_err(root, rc); + return -1; + } + + /* Enter response object: our array of (string, property dict) + * values */ + rc = sd_bus_message_enter_container(m, 'a', "{sa{sv}}"); + if (rc < 0) { + dbus_err(root, rc); + return -1; + } + + + /* for each interface */ + while (!container_end(m)) { + /* Enter interface item */ + rc = sd_bus_message_enter_container(m, 'e', "sa{sv}"); + if (rc < 0) { + dbus_err(root, rc); + return -1; + } + + rc = sd_bus_message_read(m, "s", &ifname); + if (rc < 0) { + dbus_err(root, rc); + return -1; + } + + if (!strcmp(ifname, MCTP_DBUS_IFACE_ENDPOINT)) { + + rc = handle_mctp_endpoint(root, objpath, m); + if (rc < 0) { + /* continue to next object */ + } + } else { + /* skip the interfaces we don't care about */ + rc = sd_bus_message_skip(m, "a{sv}"); + if (rc < 0) { + dbus_err(root, rc); + return -1; + } + } + + /* Exit interface item */ + rc = sd_bus_message_exit_container(m); + if (rc < 0) { + dbus_err(root, rc); + return -1; + } + } + + /* Exit response object */ + rc = sd_bus_message_exit_container(m); + if (rc < 0) { + dbus_err(root, rc); + return -1; + } + + return 0; +} + +nvme_root_t nvme_mi_scan_mctp(void) +{ + sd_bus *bus = NULL; + sd_bus_message *resp = NULL; + sd_bus_error berr = SD_BUS_ERROR_NULL; + int rc, errno_save; + nvme_root_t root; + + root = nvme_mi_create_root(NULL, DEFAULT_LOGLEVEL); + if (!root) { + errno = ENOMEM; + rc = -1; + goto out; + } + + rc = sd_bus_default_system(&bus); + if (rc < 0) { + nvme_msg(root, LOG_ERR, "Failed opening D-Bus: %s\n", + strerror(-rc)); + errno = -rc; + rc = -1; + goto out; + } + + rc = sd_bus_call_method(bus, + MCTP_DBUS_IFACE, + MCTP_DBUS_PATH, + "org.freedesktop.DBus.ObjectManager", + "GetManagedObjects", + &berr, + &resp, + ""); + if (rc < 0) { + nvme_msg(root, LOG_ERR, "Failed querying MCTP D-Bus: %s (%s)\n", + berr.message, berr.name); + errno = -rc; + rc = -1; + goto out; + } + + rc = sd_bus_message_enter_container(resp, 'a', "{oa{sa{sv}}}"); + if (rc != 1) { + dbus_err(root, rc); + if (rc == 0) + errno = EPROTO; + rc = -1; + goto out; + } + + /* Iterate over all managed objects */ + while (!container_end(resp)) { + rc = sd_bus_message_enter_container(resp, 'e', "oa{sa{sv}}"); + if (rc < 0) { + dbus_err(root, rc); + rc = -1; + goto out; + } + + handle_mctp_obj(root, resp); + + rc = sd_bus_message_exit_container(resp); + if (rc < 0) { + dbus_err(root, rc); + rc = -1; + goto out; + } + } + + rc = sd_bus_message_exit_container(resp); + if (rc < 0) { + dbus_err(root, rc); + rc = -1; + goto out; + } + rc = 0; + +out: + errno_save = errno; + sd_bus_error_free(&berr); + sd_bus_message_unref(resp); + sd_bus_unref(bus); + + if (rc < 0) { + if (root) { + nvme_mi_free_root(root); + } + errno = errno_save; + root = NULL; + } + return root; +} + +#else /* CONFIG_LIBSYSTEMD */ + +nvme_root_t nvme_mi_scan_mctp(void) +{ + return NULL; +} + +#endif /* CONFIG_LIBSYSTEMD */ diff --git a/src/nvme/mi.c b/src/nvme/mi.c new file mode 100644 index 0000000..8e868d1 --- /dev/null +++ b/src/nvme/mi.c @@ -0,0 +1,930 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/* + * This file is part of libnvme. + * Copyright (c) 2021 Code Construct Pty Ltd + * + * Authors: Jeremy Kerr + */ + +#include +#include +#include +#include + +#include + +#include "log.h" +#include "mi.h" +#include "private.h" + +/* MI-equivalent of nvme_create_root, but avoids clashing symbol names + * when linking against both libnvme and libnvme-mi. + */ +nvme_root_t nvme_mi_create_root(FILE *fp, int log_level) +{ + struct nvme_root *r = calloc(1, sizeof(*r)); + + if (!r) { + return NULL; + } + r->log_level = log_level; + r->fp = stderr; + if (fp) + r->fp = fp; + list_head_init(&r->hosts); + list_head_init(&r->endpoints); + return r; +} + +void nvme_mi_free_root(nvme_root_t root) +{ + nvme_mi_ep_t ep, tmp; + + nvme_mi_for_each_endpoint_safe(root, ep, tmp) + nvme_mi_close(ep); + + free(root); +} + +struct nvme_mi_ep *nvme_mi_init_ep(nvme_root_t root) +{ + struct nvme_mi_ep *ep; + + ep = calloc(1, sizeof(*ep)); + if (!ep) + return NULL; + + list_node_init(&ep->root_entry); + ep->root = root; + ep->controllers_scanned = false; + list_head_init(&ep->controllers); + + list_add(&root->endpoints, &ep->root_entry); + + return ep; +} + +struct nvme_mi_ctrl *nvme_mi_init_ctrl(nvme_mi_ep_t ep, __u16 ctrl_id) +{ + struct nvme_mi_ctrl *ctrl; + + ctrl = malloc(sizeof(*ctrl)); + if (!ctrl) + return NULL; + + ctrl->ep = ep; + ctrl->id = ctrl_id; + + list_add_tail(&ep->controllers, &ctrl->ep_entry); + + return ctrl; +} + +int nvme_mi_scan_ep(nvme_mi_ep_t ep, bool force_rescan) +{ + struct nvme_ctrl_list list; + unsigned int i, n_ctrl; + int rc; + + if (ep->controllers_scanned) { + if (force_rescan) { + struct nvme_mi_ctrl *ctrl, *tmp; + nvme_mi_for_each_ctrl_safe(ep, ctrl, tmp) + nvme_mi_close_ctrl(ctrl); + } else { + return 0; + } + } + + rc = nvme_mi_mi_read_mi_data_ctrl_list(ep, 0, &list); + if (rc) + return -1; + + n_ctrl = le16_to_cpu(list.num); + if (n_ctrl > NVME_ID_CTRL_LIST_MAX) { + errno = EPROTO; + return -1; + } + + for (i = 0; i < n_ctrl; i++) { + struct nvme_mi_ctrl *ctrl; + __u16 id; + + id = le32_to_cpu(list.identifier[i]); + if (!id) + continue; + + ctrl = nvme_mi_init_ctrl(ep, id); + if (!ctrl) + break; + } + + ep->controllers_scanned = true; + return 0; +} + +__u32 nvme_mi_crc32_update(__u32 crc, void *data, size_t len) +{ + int i; + + while (len--) { + crc ^= *(unsigned char *)(data++); + for (i = 0; i < 8; i++) + crc = (crc >> 1) ^ ((crc & 1) ? 0x82F63B78 : 0); + } + return crc; +} + +static void nvme_mi_calc_req_mic(struct nvme_mi_req *req) +{ + __u32 crc = 0xffffffff; + + crc = nvme_mi_crc32_update(crc, req->hdr, req->hdr_len); + crc = nvme_mi_crc32_update(crc, req->data, req->data_len); + + req->mic = ~crc; +} + +/* returns zero on correct MIC */ +static int nvme_mi_verify_resp_mic(struct nvme_mi_resp *resp) +{ + __u32 crc = 0xffffffff; + + crc = nvme_mi_crc32_update(crc, resp->hdr, resp->hdr_len); + crc = nvme_mi_crc32_update(crc, resp->data, resp->data_len); + + return resp->mic != ~crc; +} + +int nvme_mi_submit(nvme_mi_ep_t ep, struct nvme_mi_req *req, + struct nvme_mi_resp *resp) +{ + int rc; + + if (req->hdr_len < sizeof(struct nvme_mi_msg_hdr)) { + errno = EINVAL; + return -1; + } + + if (req->hdr_len & 0x3) { + errno = EINVAL; + return -1; + } + + if (req->data_len & 0x3) { + errno = EINVAL; + return -1; + } + + if (resp->hdr_len < sizeof(struct nvme_mi_msg_hdr)) { + errno = EINVAL; + return -1; + } + + if (resp->hdr_len & 0x3) { + errno = EINVAL; + return -1; + } + + if (resp->data_len & 0x3) { + errno = EINVAL; + return -1; + } + + if (ep->transport->mic_enabled) + nvme_mi_calc_req_mic(req); + + rc = ep->transport->submit(ep, req, resp); + if (rc) { + nvme_msg(ep->root, LOG_INFO, "transport failure\n"); + return rc; + } + + if (ep->transport->mic_enabled) { + rc = nvme_mi_verify_resp_mic(resp); + if (rc) { + nvme_msg(ep->root, LOG_WARNING, "crc mismatch\n"); + return rc; + } + } + + /* basic response checks */ + if (resp->hdr_len < sizeof(struct nvme_mi_msg_hdr)) { + nvme_msg(ep->root, LOG_DEBUG, + "Bad response header len: %zd\n", resp->hdr_len); + errno = EPROTO; + return -1; + } + + if (resp->hdr->type != NVME_MI_MSGTYPE_NVME) { + nvme_msg(ep->root, LOG_DEBUG, + "Invalid message type 0x%02x\n", resp->hdr->type); + errno = EPROTO; + return -1; + } + + if (!(resp->hdr->nmp & (NVME_MI_ROR_RSP << 7))) { + nvme_msg(ep->root, LOG_DEBUG, + "ROR value in response indicates a request\n"); + errno = EIO; + return -1; + } + + if ((resp->hdr->nmp & 0x1) != (req->hdr->nmp & 0x1)) { + nvme_msg(ep->root, LOG_WARNING, + "Command slot mismatch: req %d, resp %d\n", + req->hdr->nmp & 0x1, + resp->hdr->nmp & 0x1); + errno = EIO; + return -1; + } + + return 0; +} + +static void nvme_mi_admin_init_req(struct nvme_mi_req *req, + struct nvme_mi_admin_req_hdr *hdr, + __u16 ctrl_id, __u8 opcode) +{ + memset(req, 0, sizeof(*req)); + memset(hdr, 0, sizeof(*hdr)); + + hdr->hdr.type = NVME_MI_MSGTYPE_NVME; + hdr->hdr.nmp = (NVME_MI_ROR_REQ << 7) | + (NVME_MI_MT_ADMIN << 3); /* we always use command slot 0 */ + hdr->opcode = opcode; + hdr->ctrl_id = cpu_to_le16(ctrl_id); + + req->hdr = &hdr->hdr; + req->hdr_len = sizeof(*hdr); +} + +static void nvme_mi_admin_init_resp(struct nvme_mi_resp *resp, + struct nvme_mi_admin_resp_hdr *hdr) +{ + memset(resp, 0, sizeof(*resp)); + resp->hdr = &hdr->hdr; + resp->hdr_len = sizeof(*hdr); +} + +int nvme_mi_admin_xfer(nvme_mi_ctrl_t ctrl, + struct nvme_mi_admin_req_hdr *admin_req, + size_t req_data_size, + struct nvme_mi_admin_resp_hdr *admin_resp, + off_t resp_data_offset, + size_t *resp_data_size) +{ + struct nvme_mi_resp resp; + struct nvme_mi_req req; + int rc; + + /* length/offset checks. The common _submit() API will do further + * checking on the message lengths too, so these are kept specific + * to the requirements of the Admin command set + */ + + /* NVMe-MI v1.2 imposes a limit of 4096 bytes on the dlen field */ + if (*resp_data_size > 4096) { + errno = EINVAL; + return -1; + } + + /* we only have 32 bits of offset */ + if (resp_data_offset > 0xffffffff) { + errno = EINVAL; + return -1; + } + + /* must be aligned */ + if (resp_data_offset & 0x3) { + errno = EINVAL; + return -1; + } + + /* bidirectional not permitted (see DLEN definition) */ + if (req_data_size && *resp_data_size) { + errno = EINVAL; + return -1; + } + + if (!*resp_data_size && resp_data_offset) { + errno = EINVAL; + return -1; + } + + admin_req->hdr.type = NVME_MI_MSGTYPE_NVME; + admin_req->hdr.nmp = (NVME_MI_ROR_REQ << 7) | + (NVME_MI_MT_ADMIN << 3); + memset(&req, 0, sizeof(req)); + req.hdr = &admin_req->hdr; + req.hdr_len = sizeof(*admin_req); + req.data = admin_req + 1; + req.data_len = req_data_size; + + nvme_mi_calc_req_mic(&req); + + memset(&resp, 0, sizeof(resp)); + resp.hdr = &admin_resp->hdr; + resp.hdr_len = sizeof(*admin_resp); + resp.data = admin_resp + 1; + resp.data_len = *resp_data_size; + + /* limit the response size, specify offset */ + admin_req->flags = 0x3; + admin_req->dlen = cpu_to_le32(resp.data_len & 0xffffffff); + admin_req->doff = cpu_to_le32(resp_data_offset & 0xffffffff); + + rc = nvme_mi_submit(ctrl->ep, &req, &resp); + if (rc) + return rc; + + *resp_data_size = resp.data_len; + + return 0; +} + +int nvme_mi_admin_identify_partial(nvme_mi_ctrl_t ctrl, + struct nvme_identify_args *args, + off_t offset, size_t size) +{ + struct nvme_mi_admin_resp_hdr resp_hdr; + struct nvme_mi_admin_req_hdr req_hdr; + struct nvme_mi_resp resp; + struct nvme_mi_req req; + int rc; + + if (args->args_size < sizeof(*args)) { + errno = EINVAL; + return -1; + } + + if (!size || size > 0xffffffff) { + errno = EINVAL; + return -1; + } + + nvme_mi_admin_init_req(&req, &req_hdr, ctrl->id, nvme_admin_identify); + req_hdr.cdw1 = cpu_to_le32(args->nsid); + req_hdr.cdw10 = cpu_to_le32(args->cntid << 16 | args->cns); + req_hdr.cdw11 = cpu_to_le32((args->csi & 0xff) << 24 | + args->cns_specific_id); + req_hdr.cdw14 = cpu_to_le32(args->uuidx); + req_hdr.dlen = cpu_to_le32(size & 0xffffffff); + req_hdr.flags = 0x1; + if (offset) { + req_hdr.flags |= 0x2; + req_hdr.doff = cpu_to_le32(offset); + } + + nvme_mi_calc_req_mic(&req); + + nvme_mi_admin_init_resp(&resp, &resp_hdr); + resp.data = args->data; + resp.data_len = size; + + rc = nvme_mi_submit(ctrl->ep, &req, &resp); + if (rc) + return rc; + + if (resp_hdr.status) + return resp_hdr.status; + + if (args->result) + *args->result = le32_to_cpu(resp_hdr.cdw0); + + /* callers will expect a full response; if the data buffer isn't + * fully valid, return an error */ + if (resp.data_len != size) { + errno = EPROTO; + return -1; + } + + return 0; +} + +/* retrieves a MCTP-messsage-sized chunk of log page data. offset and len are + * specified within the args->data area */ +static int __nvme_mi_admin_get_log_page(nvme_mi_ctrl_t ctrl, + const struct nvme_get_log_args *args, + off_t offset, size_t *lenp, bool final) +{ + struct nvme_mi_admin_resp_hdr resp_hdr; + struct nvme_mi_admin_req_hdr req_hdr; + struct nvme_mi_resp resp; + struct nvme_mi_req req; + size_t len; + __u32 ndw; + int rc; + + /* MI spec requires that the data length field is less than or equal + * to 4096 */ + len = *lenp; + if (!len || len > 4096 || len < 4) { + errno = EINVAL; + return -1; + } + + if (offset < 0 || offset >= len) { + errno = EINVAL; + return -1; + } + + ndw = (len >> 2) - 1; + + nvme_mi_admin_init_req(&req, &req_hdr, ctrl->id, nvme_admin_get_log_page); + req_hdr.cdw1 = cpu_to_le32(args->nsid); + req_hdr.cdw10 = cpu_to_le32((ndw & 0xffff) << 16 | + ((!final || args->rae) ? 1 : 0) << 15 | + args->lsp << 8 | + (args->lid & 0xff)); + req_hdr.cdw11 = cpu_to_le32(args->lsi << 16 | + ndw >> 16); + req_hdr.cdw12 = cpu_to_le32(args->lpo & 0xffffffff); + req_hdr.cdw13 = cpu_to_le32(args->lpo >> 32); + req_hdr.cdw14 = cpu_to_le32(args->csi << 24 | + (args->ot ? 1 : 0) << 23 | + args->uuidx); + req_hdr.flags = 0x1; + req_hdr.dlen = cpu_to_le32(len & 0xffffffff); + if (offset) { + req_hdr.flags |= 0x2; + req_hdr.doff = cpu_to_le32(offset); + } + + nvme_mi_calc_req_mic(&req); + + nvme_mi_admin_init_resp(&resp, &resp_hdr); + resp.data = args->log + offset; + resp.data_len = len; + + rc = nvme_mi_submit(ctrl->ep, &req, &resp); + if (rc) + return rc; + + if (resp_hdr.status) + return resp_hdr.status; + + *lenp = resp.data_len; + + return 0; +} + +int nvme_mi_admin_get_log_page(nvme_mi_ctrl_t ctrl, + struct nvme_get_log_args *args) +{ + const size_t xfer_size = 4096; + off_t xfer_offset; + int rc = 0; + + if (args->args_size < sizeof(*args)) { + errno = EINVAL; + return -1; + } + + for (xfer_offset = 0; xfer_offset < args->len;) { + size_t tmp, cur_xfer_size = xfer_size; + bool final; + + if (xfer_offset + cur_xfer_size > args->len) + cur_xfer_size = args->len - xfer_offset; + + tmp = cur_xfer_size; + + final = xfer_offset + cur_xfer_size >= args->len; + + rc = __nvme_mi_admin_get_log_page(ctrl, args, xfer_offset, + &tmp, final); + if (rc) + break; + + xfer_offset += tmp; + /* if we returned less data than expected, consider that + * the end of the log page */ + if (tmp != cur_xfer_size) + break; + } + + if (!rc) + args->len = xfer_offset; + + return rc; +} + +int nvme_mi_admin_security_send(nvme_mi_ctrl_t ctrl, + struct nvme_security_send_args *args) +{ + + struct nvme_mi_admin_resp_hdr resp_hdr; + struct nvme_mi_admin_req_hdr req_hdr; + struct nvme_mi_resp resp; + struct nvme_mi_req req; + int rc; + + if (args->args_size < sizeof(*args)) { + errno = EINVAL; + return -1; + } + + if (args->data_len > 4096) { + errno = EINVAL; + return -1; + } + + nvme_mi_admin_init_req(&req, &req_hdr, ctrl->id, + nvme_admin_security_send); + + req_hdr.cdw10 = cpu_to_le32(args->secp << 24 | + args->spsp0 << 16 | + args->spsp1 << 8 | + args->nssf); + + req_hdr.cdw11 = cpu_to_le32(args->data_len & 0xffffffff); + + req_hdr.flags = 0x1; + req_hdr.dlen = cpu_to_le32(args->data_len & 0xffffffff); + req.data = args->data; + req.data_len = args->data_len; + + nvme_mi_calc_req_mic(&req); + + nvme_mi_admin_init_resp(&resp, &resp_hdr); + + rc = nvme_mi_submit(ctrl->ep, &req, &resp); + if (rc) + return rc; + + if (resp_hdr.status) + return resp_hdr.status; + + if (args->result) + *args->result = le32_to_cpu(resp_hdr.cdw0); + + return 0; +} + +int nvme_mi_admin_security_recv(nvme_mi_ctrl_t ctrl, + struct nvme_security_receive_args *args) +{ + + struct nvme_mi_admin_resp_hdr resp_hdr; + struct nvme_mi_admin_req_hdr req_hdr; + struct nvme_mi_resp resp; + struct nvme_mi_req req; + int rc; + + if (args->args_size < sizeof(*args)) { + errno = EINVAL; + return -1; + } + + if (args->data_len > 4096) { + errno = EINVAL; + return -1; + } + + nvme_mi_admin_init_req(&req, &req_hdr, ctrl->id, + nvme_admin_security_recv); + + req_hdr.cdw10 = cpu_to_le32(args->secp << 24 | + args->spsp0 << 16 | + args->spsp1 << 8 | + args->nssf); + + req_hdr.cdw11 = cpu_to_le32(args->data_len & 0xffffffff); + + req_hdr.flags = 0x1; + req_hdr.dlen = cpu_to_le32(args->data_len & 0xffffffff); + + nvme_mi_calc_req_mic(&req); + + nvme_mi_admin_init_resp(&resp, &resp_hdr); + resp.data = args->data; + resp.data_len = args->data_len; + + rc = nvme_mi_submit(ctrl->ep, &req, &resp); + if (rc) + return rc; + + if (resp_hdr.status) + return resp_hdr.status; + + if (args->result) + *args->result = resp_hdr.cdw0; + + args->data_len = resp.data_len; + + return 0; +} + +static int nvme_mi_read_data(nvme_mi_ep_t ep, __u32 cdw0, + void *data, size_t *data_len) +{ + struct nvme_mi_mi_resp_hdr resp_hdr; + struct nvme_mi_mi_req_hdr req_hdr; + struct nvme_mi_resp resp; + struct nvme_mi_req req; + int rc; + + memset(&req_hdr, 0, sizeof(req_hdr)); + req_hdr.hdr.type = NVME_MI_MSGTYPE_NVME; + req_hdr.hdr.nmp = (NVME_MI_ROR_REQ << 7) | + (NVME_MI_MT_MI << 3); /* we always use command slot 0 */ + req_hdr.opcode = nvme_mi_mi_opcode_mi_data_read; + req_hdr.cdw0 = cdw0; + + memset(&req, 0, sizeof(req)); + req.hdr = &req_hdr.hdr; + req.hdr_len = sizeof(req_hdr); + + memset(&resp, 0, sizeof(resp)); + resp.hdr = &resp_hdr.hdr; + resp.hdr_len = sizeof(resp_hdr); + resp.data = data; + resp.data_len = *data_len; + + rc = nvme_mi_submit(ep, &req, &resp); + if (rc) + return rc; + + if (resp_hdr.status) + return resp_hdr.status; + + *data_len = resp.data_len; + + return 0; +} + +int nvme_mi_mi_read_mi_data_subsys(nvme_mi_ep_t ep, + struct nvme_mi_read_nvm_ss_info *s) +{ + size_t len; + __u32 cdw0; + int rc; + + cdw0 = (__u8)nvme_mi_dtyp_subsys_info << 24; + len = sizeof(*s); + + rc = nvme_mi_read_data(ep, cdw0, s, &len); + if (rc) + return rc; + + if (len != sizeof(*s)) { + nvme_msg(ep->root, LOG_WARNING, + "MI read data length mismatch: " + "got %zd bytes, expected %zd\n", + len, sizeof(*s)); + errno = EPROTO; + return -1; + } + + return 0; +} + +int nvme_mi_mi_read_mi_data_port(nvme_mi_ep_t ep, __u8 portid, + struct nvme_mi_read_port_info *p) +{ + size_t len; + __u32 cdw0; + int rc; + + cdw0 = ((__u8)nvme_mi_dtyp_port_info << 24) | (portid << 16); + len = sizeof(*p); + + rc = nvme_mi_read_data(ep, cdw0, p, &len); + if (rc) + return rc; + + if (len != sizeof(*p)) { + errno = EPROTO; + return -1; + } + + return 0; +} + +int nvme_mi_mi_read_mi_data_ctrl_list(nvme_mi_ep_t ep, __u8 start_ctrlid, + struct nvme_ctrl_list *list) +{ + size_t len; + __u32 cdw0; + int rc; + + cdw0 = ((__u8)nvme_mi_dtyp_ctrl_list << 24) | (start_ctrlid << 16); + len = sizeof(*list); + + rc = nvme_mi_read_data(ep, cdw0, list, &len); + if (rc) + return rc; + + return 0; +} + +int nvme_mi_mi_read_mi_data_ctrl(nvme_mi_ep_t ep, __u16 ctrl_id, + struct nvme_mi_read_ctrl_info *ctrl) +{ + size_t len; + __u32 cdw0; + int rc; + + cdw0 = ((__u8)nvme_mi_dtyp_ctrl_info << 24) | cpu_to_le16(ctrl_id); + len = sizeof(*ctrl); + + rc = nvme_mi_read_data(ep, cdw0, ctrl, &len); + if (rc) + return rc; + + if (len != sizeof(*ctrl)) { + errno = EPROTO; + return -1; + } + + return 0; +} + +int nvme_mi_mi_subsystem_health_status_poll(nvme_mi_ep_t ep, bool clear, + struct nvme_mi_nvm_ss_health_status *sshs) +{ + struct nvme_mi_mi_resp_hdr resp_hdr; + struct nvme_mi_mi_req_hdr req_hdr; + struct nvme_mi_resp resp; + struct nvme_mi_req req; + int rc; + + memset(&req_hdr, 0, sizeof(req_hdr)); + req_hdr.hdr.type = NVME_MI_MSGTYPE_NVME;; + req_hdr.hdr.nmp = (NVME_MI_ROR_REQ << 7) | + (NVME_MI_MT_MI << 3); + req_hdr.opcode = nvme_mi_mi_opcode_subsys_health_status_poll; + req_hdr.cdw1 = (clear ? 1 : 0) << 31; + + memset(&req, 0, sizeof(req)); + req.hdr = &req_hdr.hdr; + req.hdr_len = sizeof(req_hdr); + + memset(&resp, 0, sizeof(resp)); + resp.hdr = &resp_hdr.hdr; + resp.hdr_len = sizeof(resp_hdr); + resp.data = sshs; + resp.data_len = sizeof(*sshs); + + rc = nvme_mi_submit(ep, &req, &resp); + if (rc) + return rc; + + if (resp_hdr.status) + return resp_hdr.status; + + if (resp.data_len != sizeof(*sshs)) { + nvme_msg(ep->root, LOG_WARNING, + "MI Subsystem Health Status length mismatch: " + "got %zd bytes, expected %zd\n", + resp.data_len, sizeof(*sshs)); + errno = EPROTO; + return -1; + } + + return 0; +} + +int nvme_mi_mi_config_get(nvme_mi_ep_t ep, __u32 dw0, __u32 dw1, + __u32 *nmresp) +{ + struct nvme_mi_mi_resp_hdr resp_hdr; + struct nvme_mi_mi_req_hdr req_hdr; + struct nvme_mi_resp resp; + struct nvme_mi_req req; + int rc; + + memset(&req_hdr, 0, sizeof(req_hdr)); + req_hdr.hdr.type = NVME_MI_MSGTYPE_NVME; + req_hdr.hdr.nmp = (NVME_MI_ROR_REQ << 7) | (NVME_MI_MT_MI << 3); + req_hdr.opcode = nvme_mi_mi_opcode_configuration_get; + req_hdr.cdw0 = cpu_to_le32(dw0); + req_hdr.cdw1 = cpu_to_le32(dw1); + + memset(&req, 0, sizeof(req)); + req.hdr = &req_hdr.hdr; + req.hdr_len = sizeof(req_hdr); + + memset(&resp, 0, sizeof(resp)); + resp.hdr = &resp_hdr.hdr; + resp.hdr_len = sizeof(resp_hdr); + + rc = nvme_mi_submit(ep, &req, &resp); + if (rc) + return rc; + + if (resp_hdr.status) + return resp_hdr.status; + + *nmresp = resp_hdr.nmresp[0] | + resp_hdr.nmresp[1] << 8 | + resp_hdr.nmresp[2] << 16; + + return 0; +} + +int nvme_mi_mi_config_set(nvme_mi_ep_t ep, __u32 dw0, __u32 dw1) +{ + struct nvme_mi_mi_resp_hdr resp_hdr; + struct nvme_mi_mi_req_hdr req_hdr; + struct nvme_mi_resp resp; + struct nvme_mi_req req; + int rc; + + memset(&req_hdr, 0, sizeof(req_hdr)); + req_hdr.hdr.type = NVME_MI_MSGTYPE_NVME; + req_hdr.hdr.nmp = (NVME_MI_ROR_REQ << 7) | (NVME_MI_MT_MI << 3); + req_hdr.opcode = nvme_mi_mi_opcode_configuration_set; + req_hdr.cdw0 = cpu_to_le32(dw0); + req_hdr.cdw1 = cpu_to_le32(dw1); + + memset(&req, 0, sizeof(req)); + req.hdr = &req_hdr.hdr; + req.hdr_len = sizeof(req_hdr); + + memset(&resp, 0, sizeof(resp)); + resp.hdr = &resp_hdr.hdr; + resp.hdr_len = sizeof(resp_hdr); + + rc = nvme_mi_submit(ep, &req, &resp); + if (rc) + return rc; + + if (resp_hdr.status) + return resp_hdr.status; + + return 0; +} + +void nvme_mi_close(nvme_mi_ep_t ep) +{ + struct nvme_mi_ctrl *ctrl, *tmp; + + /* don't look for controllers during destruction */ + ep->controllers_scanned = true; + + nvme_mi_for_each_ctrl_safe(ep, ctrl, tmp) + nvme_mi_close_ctrl(ctrl); + + if (ep->transport->close) + ep->transport->close(ep); + list_del(&ep->root_entry); + free(ep); +} + +void nvme_mi_close_ctrl(nvme_mi_ctrl_t ctrl) +{ + list_del(&ctrl->ep_entry); + free(ctrl); +} + +char *nvme_mi_endpoint_desc(nvme_mi_ep_t ep) +{ + char tsbuf[101], *s = NULL; + size_t tslen; + int rc; + + rc = -1; + memset(tsbuf, 0, sizeof(tsbuf)); + if (ep->transport->desc_ep) + rc = ep->transport->desc_ep(ep, tsbuf, sizeof(tsbuf) - 1); + + if (!rc) { + /* don't overflow if the transport gives us an invalid string */ + tsbuf[sizeof(tsbuf)-1] = '\0'; + tslen = strlen(tsbuf); + } else { + tslen = 0; + } + + if (tslen) + rc = asprintf(&s, "%s: %s", ep->transport->name, tsbuf); + else + rc = asprintf(&s, "%s endpoint", ep->transport->name); + + if (rc < 0) + return NULL; + + return s; +} + +nvme_mi_ep_t nvme_mi_first_endpoint(nvme_root_t m) +{ + return list_top(&m->endpoints, struct nvme_mi_ep, root_entry); +} + +nvme_mi_ep_t nvme_mi_next_endpoint(nvme_root_t m, nvme_mi_ep_t ep) +{ + return ep ? list_next(&m->endpoints, ep, root_entry) : NULL; +} + +nvme_mi_ctrl_t nvme_mi_first_ctrl(nvme_mi_ep_t ep) +{ + return list_top(&ep->controllers, struct nvme_mi_ctrl, ep_entry); +} + +nvme_mi_ctrl_t nvme_mi_next_ctrl(nvme_mi_ep_t ep, nvme_mi_ctrl_t c) +{ + return c ? list_next(&ep->controllers, c, ep_entry) : NULL; +} diff --git a/src/nvme/mi.h b/src/nvme/mi.h new file mode 100644 index 0000000..81cb00f --- /dev/null +++ b/src/nvme/mi.h @@ -0,0 +1,1111 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/* + * This file is part of libnvme. + * Copyright (c) 2021 Code Construct Pty Ltd + * + * Authors: Jeremy Kerr + */ + +/** + * DOC: mi.h - NVMe Management Interface library (libnvme-mi) definitions. + * + * These provide an abstraction for the MI messaging between controllers + * and a host, typically over an MCTP-over-i2c link to a NVMe device, used + * as part of the out-of-band management of a system. + * + * We have a few data structures define here to reflect the topology + * of a MI connection with an NVMe subsystem: + * + * - &nvme_mi_ep_t: an MI endpoint - our mechanism of communication with a + * NVMe subsystem. For MCTP, an endpoint will be the component that + * holds the MCTP address (EID), and receives our request message. + * + * endpoints are defined in the NVMe-MI spec, and are specific to the MI + * interface. + * + * Each endpoint will provide access to one or more of: + * + * - &nvme_mi_ctrl_t: a NVMe controller, as defined by the NVMe base spec. + * The controllers are responsible for processing any NVMe standard + * commands (eg, the Admin command set). An endpoint (&nvme_mi_ep_t) + * may provide access to multiple controllers - so each of the controller- + * type commands will require a &nvme_mi_ctrl_t to be specified, rather than + * an endpoint + * + * A couple of conventions with the libnvme-mi API: + * + * - All types and functions have the nvme_mi prefix, to distinguish from + * the libnvme core. + * + * - We currently support either MI commands and Admin commands. The + * former adds a _mi prefix, the latter an _admin prefix. [This does + * result in the MI functions having a double _mi, like + * &nvme_mi_mi_subsystem_health_status_poll, which is apparently amusing + * for our German-speaking readers] + * + * For return values: unless specified in the per-function documentation, + * all functions: + * + * - return 0 on success + * + * - return -1, with errno set, for errors communicating with the MI device, + * either in request or response data + * + * - return >1 on MI status errors. This value is the 8-bit MI status + * value, represented by &enum nvme_mi_resp_status. Note that the + * status values may be vendor-defined above 0xe0. + * + * For the second case, we have a few conventions for errno values: + * + * - EPROTO: response data violated the MI protocol, and libnvme cannot + * validly interpret the response + * + * - EIO: Other I/O error communicating with device (eg., valid but + * unexpected response data) + * + * - EINVAL: invalid input arguments for a command + * + * In line with the core NVMe API, the Admin command functions take an + * `_args` structure to provide the command-specific parameters. However, + * for the MI interface, the fd and timeout members of these _args structs + * are ignored. + * + * References to the specifications here will either to be the NVM Express + * Management Interface ("NVMe-MI") or the NVM Express Base specification + * ("NVMe"). At the time of writing, the versions we're referencing here + * are: + * - NVMe-MI 1.2b + * - NVMe 2.0b + * with a couple of accommodations for older spec types, particularly NVMe-MI + * 1.1, where possible. + * + */ + +#ifndef _LIBNVME_MI_MI_H +#define _LIBNVME_MI_MI_H + +#include +#include + +#include "types.h" +#include "tree.h" + +/** + * NVME_MI_MSGTYPE_NVME - MCTP message type for NVMe-MI messages. + * + * This is defined by MCTP, but is referenced as part of the NVMe-MI message + * spec. This is the MCTP NVMe message type (0x4), with the message-integrity + * bit (0x80) set. + */ +#define NVME_MI_MSGTYPE_NVME 0x84 + +/* Basic MI message definitions */ + +/** + * enum nvme_mi_message_type - NVMe-MI message type field. + * @NVME_MI_MT_CONTROL: NVME-MI Control Primitive + * @NVME_MI_MT_MI: NVMe-MI command + * @NVME_MI_MT_ADMIN: NVMe Admin command + * @NVME_MI_MT_PCIE: PCIe command + * + * Used as byte 1 of both request and response messages (NMIMT bits of NMP + * byte). Not to be confused with the MCTP message type in byte 0. + */ +enum nvme_mi_message_type { + NVME_MI_MT_CONTROL = 0, + NVME_MI_MT_MI = 1, + NVME_MI_MT_ADMIN = 2, + NVME_MI_MT_PCIE = 4, +}; + +/** + * enum nvme_mi_ror: Request or response field. + * @NVME_MI_ROR_REQ: request message + * @NVME_MI_ROR_RSP: response message + */ +enum nvme_mi_ror { + NVME_MI_ROR_REQ = 0, + NVME_MI_ROR_RSP = 1, +}; + +/** + * enum nvme_mi_resp_status - values for the response status field + * @NVME_MI_RESP_SUCCESS: success + * @NVME_MI_RESP_MPR: More Processing Required + * @NVME_MI_RESP_INTERNAL_ERR: Internal Error + * @NVME_MI_RESP_INVALID_OPCODE: Invalid command opcode + * @NVME_MI_RESP_INVALID_PARAM: Invalid command parameter + * @NVME_MI_RESP_INVALID_CMD_SIZE: Invalid command size + * @NVME_MI_RESP_INVALID_INPUT_SIZE: Invalid command input data size + * @NVME_MI_RESP_ACCESS_DENIED: Access Denied + * @NVME_MI_RESP_VPD_UPDATES_EXCEEDED: More VPD updates than allowed + * @NVME_MI_RESP_PCIE_INACCESSIBLE: PCIe functionality currently unavailable + * @NVME_MI_RESP_MEB_SANITIZED: MEB has been cleared due to sanitize + * @NVME_MI_RESP_ENC_SERV_FAILURE: Enclosure services process failed + * @NVME_MI_RESP_ENC_SERV_XFER_FAILURE: Transfer with enclosure services failed + * @NVME_MI_RESP_ENC_FAILURE: Unreoverable enclosure failure + * @NVME_MI_RESP_ENC_XFER_REFUSED: Enclosure services transfer refused + * @NVME_MI_RESP_ENC_FUNC_UNSUP: Unsupported enclosure services function + * @NVME_MI_RESP_ENC_SERV_UNAVAIL: Enclosure services unavailable + * @NVME_MI_RESP_ENC_DEGRADED: Noncritical failure detected by enc. services + * @NVME_MI_RESP_SANITIZE_IN_PROGRESS: Command prohibited during sanitize + */ +enum nvme_mi_resp_status { + NVME_MI_RESP_SUCCESS = 0x00, + NVME_MI_RESP_MPR = 0x01, + NVME_MI_RESP_INTERNAL_ERR = 0x02, + NVME_MI_RESP_INVALID_OPCODE = 0x03, + NVME_MI_RESP_INVALID_PARAM = 0x04, + NVME_MI_RESP_INVALID_CMD_SIZE = 0x05, + NVME_MI_RESP_INVALID_INPUT_SIZE = 0x06, + NVME_MI_RESP_ACCESS_DENIED = 0x07, + /* 0x08 - 0x1f: reserved */ + NVME_MI_RESP_VPD_UPDATES_EXCEEDED = 0x20, + NVME_MI_RESP_PCIE_INACCESSIBLE = 0x21, + NVME_MI_RESP_MEB_SANITIZED = 0x22, + NVME_MI_RESP_ENC_SERV_FAILURE = 0x23, + NVME_MI_RESP_ENC_SERV_XFER_FAILURE = 0x24, + NVME_MI_RESP_ENC_FAILURE = 0x25, + NVME_MI_RESP_ENC_XFER_REFUSED = 0x26, + NVME_MI_RESP_ENC_FUNC_UNSUP = 0x27, + NVME_MI_RESP_ENC_SERV_UNAVAIL = 0x28, + NVME_MI_RESP_ENC_DEGRADED = 0x29, + NVME_MI_RESP_SANITIZE_IN_PROGRESS = 0x2a, + /* 0x2b - 0xdf: reserved */ + /* 0xe0 - 0xff: vendor specific */ +}; + +/** + * struct nvme_mi_msg_hdr - General MI message header. + * @type: MCTP message type, will always be NVME_MI_MSGTYPE_NVME + * @nmp: NVMe-MI message parameters (including MI message type) + * @meb: Management Endpoint Buffer flag; unused for libnvme-mi implementation + * @rsvd0: currently reserved + * + * Wire format shared by both request and response messages, per NVMe-MI + * section 3.1. This is used for all message types, MI and Admin. + */ +struct nvme_mi_msg_hdr { + __u8 type; + __u8 nmp; + __u8 meb; + __u8 rsvd0; +} __attribute__((packed)); + +/** + * struct nvme_mi_msg_resp - Generic response type. + * @hdr: the general request/response message header + * @status: response status value (see &enum nvme_mi_resp_status) + * @rsvd0: reserved data, may be defined by specific response + * + * Every response will start with one of these; command-specific responses + * will define parts of the reserved data, and may add further fields. + */ +struct nvme_mi_msg_resp { + struct nvme_mi_msg_hdr hdr; + __u8 status; + __u8 rsvd0[3]; +}; + +/** + * enum nvme_mi_mi_opcode - Operation code for supported NVMe-MI commands. + * @nvme_mi_mi_opcode_mi_data_read: Read NVMe-MI Data Structure + * @nvme_mi_mi_opcode_subsys_health_status_poll: Subsystem Health Status Poll + * @nvme_mi_mi_opcode_configuration_set: MI Configuration Set + * @nvme_mi_mi_opcode_configuration_get: MI Configuration Get + */ +enum nvme_mi_mi_opcode { + nvme_mi_mi_opcode_mi_data_read = 0x00, + nvme_mi_mi_opcode_subsys_health_status_poll = 0x01, + nvme_mi_mi_opcode_configuration_set = 0x03, + nvme_mi_mi_opcode_configuration_get = 0x04, +}; + +/** + * struct nvme_mi_mi_req_hdr - MI request message header. + * @hdr: generic MI message header + * @opcode: opcode (OPC) for the specific MI command + * @rsvd0: reserved bytes + * @cdw0: Management Request Doubleword 0 - command specific usage + * @cdw1: Management Request Doubleword 1 - command specific usage + * + * Wire format for MI request message headers, defined in section 5 of NVMe-MI. + */ +struct nvme_mi_mi_req_hdr { + struct nvme_mi_msg_hdr hdr; + __u8 opcode; + __u8 rsvd0[3]; + __le32 cdw0, cdw1; +}; + +/** + * struct nvme_mi_mi_resp_hdr - MI response message header. + * @hdr: generic MI message header + * @status: generic response status from command; non-zero on failure. + * @nmresp: NVMe Management Response: command-type-specific response data + * + * Wire format for MI response message header, defined in section 5 of NVMe-MI. + */ +struct nvme_mi_mi_resp_hdr { + struct nvme_mi_msg_hdr hdr; + __u8 status; + __u8 nmresp[3]; +}; + +/** + * enum nvme_mi_dtyp - Data Structure Type field. + * @nvme_mi_dtyp_subsys_info: NVM Subsystem Information + * @nvme_mi_dtyp_port_info: Port information + * @nvme_mi_dtyp_ctrl_list: Controller List + * @nvme_mi_dtyp_ctrl_info: Controller Information + * @nvme_mi_dtyp_opt_cmd_support: Optionally Supported Command List + * @nvme_mi_dtyp_meb_support: Management Endpoint Buffer Command Support List + * + * Data Structure Type field for Read NVMe-MI Data Structure command, used to + * indicate the particular structure to query from the endpoint. + */ +enum nvme_mi_dtyp { + nvme_mi_dtyp_subsys_info = 0x00, + nvme_mi_dtyp_port_info = 0x01, + nvme_mi_dtyp_ctrl_list = 0x02, + nvme_mi_dtyp_ctrl_info = 0x03, + nvme_mi_dtyp_opt_cmd_support = 0x04, + nvme_mi_dtyp_meb_support = 0x05, +}; + +/** + * enum nvme_mi_config_id - NVMe-MI Configuration identifier. + * @NVME_MI_CONFIG_SMBUS_FREQ: Current SMBus/I2C frequency + * @NVME_MI_CONFIG_HEALTH_STATUS_CHANGE: Health Status change - used to clear + * health status bits in CCS bits of + * status poll. Only for Set ops. + * @NVME_MI_CONFIG_MCTP_MTU: MCTP maximum transmission unit size of port + * specified in dw 0 + * + * Configuration parameters for the MI Get/Set Configuration commands. + * + * See &nvme_mi_mi_config_get() and &nvme_mi_config_set(). + */ +enum nvme_mi_config_id { + NVME_MI_CONFIG_SMBUS_FREQ = 0x1, + NVME_MI_CONFIG_HEALTH_STATUS_CHANGE = 0x2, + NVME_MI_CONFIG_MCTP_MTU = 0x3, +}; + +/** + * enum nvme_mi_config_smbus_freq - SMBus/I2C frequency values + * @NVME_MI_CONFIG_SMBUS_FREQ_100kHz: 100kHz + * @NVME_MI_CONFIG_SMBUS_FREQ_400kHz: 400kHz + * @NVME_MI_CONFIG_SMBUS_FREQ_1MHz: 1MHz + * + * Values used in the SMBus Frequency device configuration. See + * &nvme_mi_mi_config_get_smbus_freq() and &nvme_mi_mi_config_set_smbus_freq(). + */ +enum nvme_mi_config_smbus_freq { + NVME_MI_CONFIG_SMBUS_FREQ_100kHz = 0x1, + NVME_MI_CONFIG_SMBUS_FREQ_400kHz = 0x2, + NVME_MI_CONFIG_SMBUS_FREQ_1MHz = 0x3, +}; + +/* Admin command definitions */ + +/** + * struct nvme_mi_admin_req_hdr - Admin command request header. + * @hdr: Generic MI message header + * @opcode: Admin command opcode (using enum nvme_admin_opcode) + * @flags: Command Flags, indicating dlen and doff validity; Only defined in + * NVMe-MI version 1.1, no fields defined in 1.2 (where the dlen/doff + * are always considered valid). + * @ctrl_id: Controller ID target of command + * @cdw1: Submission Queue Entry doubleword 1 + * @cdw2: Submission Queue Entry doubleword 2 + * @cdw3: Submission Queue Entry doubleword 3 + * @cdw4: Submission Queue Entry doubleword 4 + * @cdw5: Submission Queue Entry doubleword 5 + * @doff: Offset of data to return from command + * @dlen: Length of sent/returned data + * @rsvd0: Reserved + * @rsvd1: Reserved + * @cdw10: Submission Queue Entry doubleword 10 + * @cdw11: Submission Queue Entry doubleword 11 + * @cdw12: Submission Queue Entry doubleword 12 + * @cdw13: Submission Queue Entry doubleword 13 + * @cdw14: Submission Queue Entry doubleword 14 + * @cdw15: Submission Queue Entry doubleword 15 + * + * Wire format for Admin command message headers, defined in section 6 of + * NVMe-MI. + */ +struct nvme_mi_admin_req_hdr { + struct nvme_mi_msg_hdr hdr; + __u8 opcode; + __u8 flags; + __le16 ctrl_id; + __le32 cdw1, cdw2, cdw3, cdw4, cdw5; + __le32 doff; + __le32 dlen; + __le32 rsvd0, rsvd1; + __le32 cdw10, cdw11, cdw12, cdw13, cdw14, cdw15; +} __attribute((packed)); + +/** + * struct nvme_mi_admin_resp_hdr - Admin command response header. + * @hdr: Generic MI message header + * @status: Generic response code, non-zero on failure + * @rsvd0: Reserved + * @cdw0: Completion Queue Entry doubleword 0 + * @cdw1: Completion Queue Entry doubleword 1 + * @cdw3: Completion Queue Entry doubleword 3 + * + * This is the generic response format with the three doublewords of completion + * queue data, plus optional response data. + */ +struct nvme_mi_admin_resp_hdr { + struct nvme_mi_msg_hdr hdr; + __u8 status; + __u8 rsvd0[3]; + __le32 cdw0, cdw1, cdw3; +} __attribute__((packed)); + + +/** + * nvme_mi_create_root() - Create top-level MI (root) handle. + * @fp: File descriptor for logging messages + * @log_level: Logging level to use + * + * Create the top-level (library) handle for creating subsequent endpoint + * objects. Similar to nvme_create_root(), but we provide this to allow linking + * without the core libnvme. + * + * Return: new root object, or NULL on failure. + * + * See &nvme_create_root. + */ +nvme_root_t nvme_mi_create_root(FILE *fp, int log_level); + +/** + * nvme_mi_free_root() - Free root object. + * @root: root to free + */ +void nvme_mi_free_root(nvme_root_t root); + +/* Top level management object: NVMe-MI Management Endpoint */ +struct nvme_mi_ep; + +/** + * typedef nvme_mi_ep_t - MI Endpoint object. + * + * Represents our communication endpoint on the remote MI-capable device. + * To be used for direct MI commands for the endpoint (through the + * nvme_mi_mi_* functions(), or to communicate with individual controllers + * (see &nvme_mi_init_ctrl). + * + * Endpoints are created through a transport-specific constructor; currently + * only MCTP-connected endpoints are supported, through &nvme_mi_open_mctp. + * Subsequent operations on the endpoint (and related controllers) are + * transport-independent. + */ +typedef struct nvme_mi_ep * nvme_mi_ep_t; + +/** + * nvme_mi_first_endpoint - Start endpoint iterator + * @m: &nvme_root_t object + * + * Return: first MI endpoint object under this root, or NULL if no endpoints + * are present. + * + * See: &nvme_mi_next_endpoint, &nvme_mi_for_each_endpoint + */ +nvme_mi_ep_t nvme_mi_first_endpoint(nvme_root_t m); + +/** + * nvme_mi_next_endpoint - Continue endpoint iterator + * @m: &nvme_root_t object + * @e: &nvme_mi_ep_t current position of iterator + * + * Return: next endpoint MI endpoint object after @e under this root, or NULL + * if no further endpoints are present. + * + * See: &nvme_mi_first_endpoint, &nvme_mi_for_each_endpoint + */ +nvme_mi_ep_t nvme_mi_next_endpoint(nvme_root_t m, nvme_mi_ep_t e); + +/** + * nvme_mi_for_each_endpoint - Iterator for NVMe-MI endpoints. + * @m: &nvme_root_t containing endpoints + * @e: &nvme_mi_ep_t object, set on each iteration + */ +#define nvme_mi_for_each_endpoint(m, e) \ + for (e = nvme_mi_first_endpoint(m); e != NULL; \ + e = nvme_mi_next_endpoint(m, e)) + +/** + * nvme_mi_for_each_endpoint_safe - Iterator for NVMe-MI endpoints, allowing + * deletion during traversal + * @m: &nvme_root_t containing endpoints + * @e: &nvme_mi_ep_t object, set on each iteration + * @_e: &nvme_mi_ep_t object used as temporary storage + */ +#define nvme_mi_for_each_endpoint_safe(m, e, _e) \ + for (e = nvme_mi_first_endpoint(m), _e = nvme_mi_next_endpoint(m, e); \ + e != NULL; \ + e = _e, _e = nvme_mi_next_endpoint(m, e)) + +struct nvme_mi_ctrl; + +/** + * typedef nvme_mi_ctrl_t - NVMe-MI Controller object. + * + * Provides NVMe command functionality, through the MI interface. + */ +typedef struct nvme_mi_ctrl * nvme_mi_ctrl_t; + +/** + * nvme_mi_first_ctrl - Start controller iterator + * @ep: &nvme_mi_ep_t object + * + * Return: first MI controller object under this root, or NULL if no controllers + * are present. + * + * See: &nvme_mi_next_ctrl, &nvme_mi_for_each_ctrl + */ +nvme_mi_ctrl_t nvme_mi_first_ctrl(nvme_mi_ep_t ep); + +/** + * nvme_mi_next_ctrl - Continue ctrl iterator + * @ep: &nvme_mi_ep_t object + * @c: &nvme_mi_ctrl_t current position of iterator + * + * Return: next MI controller object after @c under this endpoint, or NULL + * if no further controllers are present. + * + * See: &nvme_mi_first_ctrl, &nvme_mi_for_each_ctrl + */ +nvme_mi_ctrl_t nvme_mi_next_ctrl(nvme_mi_ep_t ep, nvme_mi_ctrl_t c); + +/** + * nvme_mi_for_each_ctrl - Iterator for NVMe-MI controllers. + * @ep: &nvme_mi_ep_t containing endpoints + * @c: &nvme_mi_ctrl_t object, set on each iteration + * + * Allows iteration of the list of controllers behind an endpoint. Unless the + * controllers have already been created explicitly, you'll probably want to + * call &nvme_mi_scan_ep() to scan for the controllers first. + * + * See: &nvme_mi_scan_ep() + */ +#define nvme_mi_for_each_ctrl(ep, c) \ + for (c = nvme_mi_first_ctrl(ep); c != NULL; \ + c = nvme_mi_next_ctrl(ep, c)) + +/** + * nvme_mi_for_each_ctrl_safe - Iterator for NVMe-MI controllers, allowing + * deletion during traversal + * @ep: &nvme_mi_ep_t containing controllers + * @c: &nvme_mi_ctrl_t object, set on each iteration + * @_c: &nvme_mi_ctrl_t object used as temporary storage + * + * Allows iteration of the list of controllers behind an endpoint, safe against + * deletion during iteration. Unless the controllers have already been created + * explicitly (or you're just iterating to destroy controllers) you'll probably + * want to call &nvme_mi_scan_ep() to scan for the controllers first. + * + * See: &nvme_mi_scan_ep() + */ +#define nvme_mi_for_each_ctrl_safe(ep, c, _c) \ + for (c = nvme_mi_first_ctrl(ep), _c = nvme_mi_next_ctrl(ep, c); \ + c != NULL; \ + c = _c, _c = nvme_mi_next_ctrl(ep, c)) + +/** + * nvme_mi_open_mctp() - Create an endpoint using a MCTP connection. + * @root: root object to create under + * @netid: MCTP network ID on this system + * @eid: MCTP endpoint ID + * + * Transport-specific endpoint initialization for MI-connected endpoints. Once + * an endpoint is created, the rest of the API is transport-independent. + * + * Return: New endpoint object for @netid & @eid, or NULL on failure. + * + * See &nvme_mi_close + */ +nvme_mi_ep_t nvme_mi_open_mctp(nvme_root_t root, unsigned int netid, uint8_t eid); + +/** + * nvme_mi_close() - Close an endpoint connection and release resources, + * including controller objects. + * + * @ep: Endpoint object to close + */ +void nvme_mi_close(nvme_mi_ep_t ep); + +/** + * nvme_mi_scan_mctp - look for MCTP-connected NVMe-MI endpoints. + * + * Description: This function queries the system MCTP daemon ("mctpd") over + * D-Bus, to find MCTP endpoints that report support for NVMe-MI over MCTP. + * + * This requires libvnme-mi to be compiled with D-Bus support; if not, this + * will return NULL. + * + * Return: A @nvme_root_t populated with a set of MCTP-connected endpoints, + * or NULL on failure + */ +nvme_root_t nvme_mi_scan_mctp(void); + +/** + * nvme_mi_scan_ep - query an endpoint for its NVMe controllers. + * @ep: Endpoint to scan + * @force_rescan: close existing controllers and rescan + * + * This function queries an MI endpoint for the controllers available, by + * performing an MI Read MI Data Structure command (requesting the + * controller list). The controllers are stored in the endpoint's internal + * list, and can be iterated with nvme_mi_for_each_ctrl. + * + * This will only scan the endpoint once, unless @force_rescan is set. If + * 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 + * + * See: &nvme_mi_for_each_ctrl + */ +int nvme_mi_scan_ep(nvme_mi_ep_t ep, bool force_rescan); + +/** + * nvme_mi_init_ctrl() - initialise a NVMe controller. + * @ep: Endpoint to create under + * @ctrl_id: ID of controller to initialize. + * + * Create a connection to a controller behind the endpoint specified in @ep. + * Controller IDs may be queried from the endpoint through + * &nvme_mi_mi_read_mi_data_ctrl_list. + * + * Return: New controller object, or NULL on failure. + * + * See &nvme_mi_close_ctrl + */ +nvme_mi_ctrl_t nvme_mi_init_ctrl(nvme_mi_ep_t ep, __u16 ctrl_id); + +/** + * nvme_mi_close_ctrl() - free a controller + * @ctrl: controller to free + */ +void nvme_mi_close_ctrl(nvme_mi_ctrl_t ctrl); + +/** + * nvme_mi_endpoint_desc - Get a string describing a MI endpoint. + * @ep: endpoint to describe + * + * Generates a human-readable string describing the endpoint, with possibly + * transport-specific data. The string is allocated during the call, and the + * caller is responsible for free()-ing the string. + * + * Return: a newly-allocated string containing the endpoint description, or + * NULL on failure. + */ +char *nvme_mi_endpoint_desc(nvme_mi_ep_t ep); + +/* MI Command API: nvme_mi_mi_ prefix */ + +/** + * nvme_mi_mi_read_mi_data_subsys() - Perform a Read MI Data Structure command, + * retrieving subsystem data. + * @ep: endpoint for MI communication + * @s: subsystem information to populate + * + * 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. + */ +int nvme_mi_mi_read_mi_data_subsys(nvme_mi_ep_t ep, + struct nvme_mi_read_nvm_ss_info *s); + +/** + * nvme_mi_mi_read_mi_data_port() - Perform a Read MI Data Structure command, + * retrieving port data. + * @ep: endpoint for MI communication + * @portid: id of port data to retrieve + * @p: port information to populate + * + * Retrieves the Port information, for the specified port ID. The subsystem + * data (from &nvme_mi_mi_read_mi_data_subsys) nmp field contains the allowed + * range of port IDs. + * + * See &struct nvme_mi_read_port_info. + * + * Return: 0 on success, non-zero on failure. + */ +int nvme_mi_mi_read_mi_data_port(nvme_mi_ep_t ep, __u8 portid, + struct nvme_mi_read_port_info *p); + +/** + * nvme_mi_mi_read_mi_data_ctrl_list() - Perform a Read MI Data Structure + * command, retrieving the list of attached controllers. + * @ep: endpoint for MI communication + * @start_ctrlid: starting controller ID + * @list: controller list to populate + * + * Retrieves the list of attached controllers, with IDs greater than or + * equal to @start_ctrlid. + * + * See &struct nvme_ctrl_list. + * + * Return: 0 on success, non-zero on failure. + */ +int nvme_mi_mi_read_mi_data_ctrl_list(nvme_mi_ep_t ep, __u8 start_ctrlid, + struct nvme_ctrl_list *list); + +/** + * nvme_mi_mi_read_mi_data_ctrl() - Perform a Read MI Data Structure command, + * retrieving controller information + * @ep: endpoint for MI communication + * @ctrl_id: ID of controller to query + * @ctrl: controller data to populate + * + * Retrieves the Controller Information Data Structure for the attached + * controller with ID @ctrlid. + * + * See &struct nvme_mi_read_ctrl_info. + * + * Return: 0 on success, non-zero on failure. + */ +int nvme_mi_mi_read_mi_data_ctrl(nvme_mi_ep_t ep, __u16 ctrl_id, + struct nvme_mi_read_ctrl_info *ctrl); + +/** + * nvme_mi_mi_subsystem_health_status_poll() - Read the Subsystem Health + * Data Structure from the NVM subsystem + * @ep: endpoint for MI communication + * @clear: flag to clear the Composite Controller Status state + * @nshds: subsystem health status data to populate + * + * Retrieves the Subsystem Health Data Structure into @nshds. If @clear is + * set, requests that the Composite Controller Status bits are cleared after + * the read. See NVMe-MI section 5.6 for details on the CCS bits. + * + * See &struct nvme_mi_nvm_ss_health_status. + * + * Return: 0 on success, non-zero on failure. + */ +int nvme_mi_mi_subsystem_health_status_poll(nvme_mi_ep_t ep, bool clear, + struct nvme_mi_nvm_ss_health_status *nshds); + +/** + * nvme_mi_mi_config_get - query a configuration parameter + * @ep: endpoint for MI communication + * @dw0: management doubleword 0, containing configuration identifier, plus + * config-specific fields + * @dw1: management doubleword 0, config-specific. + * @nmresp: set to queried configuration data in NMRESP field of response. + * + * Performs a MI Configuration Get command, with the configuration identifier + * as the LSB of @dw0. Other @dw0 and @dw1 data is configuration-identifier + * specific. + * + * On a successful Configuration Get, the @nmresp pointer will be populated with + * the bytes from the 3-byte NMRESP field, converted to native endian. + * + * See &enum nvme_mi_config_id for identifiers. + * + * Return: 0 on success, non-zero on failure. + */ +int nvme_mi_mi_config_get(nvme_mi_ep_t ep, __u32 dw0, __u32 dw1, + __u32 *nmresp); + +/** + * nvme_mi_mi_config_set - set a configuration parameter + * @ep: endpoint for MI communication + * @dw0: management doubleword 0, containing configuration identifier, plus + * config-specific fields + * @dw1: management doubleword 0, config-specific. + * + * Performs a MI Configuration Set command, with the command as the LSB of + * @dw0. Other @dw0 and @dw1 data is configuration-identifier specific. + * + * See &enum nvme_mi_config_id for identifiers. + * + * Return: 0 on success, non-zero on failure. + */ +int nvme_mi_mi_config_set(nvme_mi_ep_t ep, __u32 dw0, __u32 dw1); + +/** + * nvme_mi_mi_config_get_smbus_freq - get configuration: SMBus port frequency + * @ep: endpoint for MI communication + * @port: port ID to query + * @freq: output value for current frequency configuration + * + * Performs a MI Configuration Get, to query the current SMBus frequency of + * the port specified in @port. On success, populates @freq with the port + * frequency + * + * Return: 0 on success, non-zero on failure. + */ +static inline int nvme_mi_mi_config_get_smbus_freq(nvme_mi_ep_t ep, __u8 port, + enum nvme_mi_config_smbus_freq *freq) +{ + __u32 tmp, dw0; + int rc; + + dw0 = port << 24 | NVME_MI_CONFIG_SMBUS_FREQ; + + rc = nvme_mi_mi_config_get(ep, dw0, 0, &tmp); + if (!rc) + *freq = tmp & 0x3; + return rc; +} + +/** + * nvme_mi_mi_config_set_smbus_freq - set configuration: SMBus port frequency + * @ep: endpoint for MI communication + * @port: port ID to set + * @freq: new frequency configuration + * + * Performs a MI Configuration Set, to update the current SMBus frequency of + * the port specified in @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. + */ +static inline int nvme_mi_mi_config_set_smbus_freq(nvme_mi_ep_t ep, __u8 port, + enum nvme_mi_config_smbus_freq freq) +{ + __u32 dw0 = port << 24 | + (freq & 0x3) << 8 | + NVME_MI_CONFIG_SMBUS_FREQ; + + return nvme_mi_mi_config_set(ep, dw0, 0); +} + +/** + * nvme_mi_mi_config_set_health_status_change - clear CCS bits in health status + * @ep: endpoint for MI communication + * @mask: bitmask to clear + * + * Performs a MI Configuration Set, to update the current health status poll + * values of the Composite Controller Status bits. Bits set in @mask will + * be cleared from future health status poll data, and may be re-triggered by + * a future health change event. + * + * See &nvme_mi_mi_subsystem_health_status_poll(), &enum nvme_mi_ccs for + * values in @mask. + * + * Return: 0 on success, non-zero on failure. + */ +static inline int nvme_mi_mi_config_set_health_status_change(nvme_mi_ep_t ep, + __u32 mask) +{ + return nvme_mi_mi_config_set(ep, NVME_MI_CONFIG_HEALTH_STATUS_CHANGE, + mask); +} + +/** + * nvme_mi_mi_config_get_mctp_mtu - get configuration: MCTP MTU + * @ep: endpoint for MI communication + * @port: port ID to query + * @mtu: output value for current MCTP MTU configuration + * + * Performs a MI Configuration Get, to query the current MCTP Maximum + * Transmission Unit size (MTU) of the port specified in @port. On success, + * populates @mtu with the MTU. + * + * The default reset value is 64, corresponding to the MCTP baseline MTU. + * + * 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. + */ +static inline int nvme_mi_mi_config_get_mctp_mtu(nvme_mi_ep_t ep, __u8 port, + __u16 *mtu) +{ + __u32 tmp, dw0; + int rc; + + dw0 = port << 24 | NVME_MI_CONFIG_MCTP_MTU; + + rc = nvme_mi_mi_config_get(ep, dw0, 0, &tmp); + if (!rc) + *mtu = tmp & 0xffff; + return rc; +} + +/** + * nvme_mi_mi_config_set_mctp_mtu - set configuration: MCTP MTU + * @ep: endpoint for MI communication + * @port: port ID to set + * @mtu: new MTU configuration + * + * Performs a MI Configuration Set, to update the current MCTP MTU value for + * the port specified in @port. + * + * Some controllers may also use this as the maximum receive unit size, and + * may not accept MCTP messages larger than the configured MTU. When setting + * 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. + */ +static inline int nvme_mi_mi_config_set_mctp_mtu(nvme_mi_ep_t ep, __u8 port, + __u16 mtu) +{ + __u32 dw0 = port << 24 | NVME_MI_CONFIG_MCTP_MTU; + + return nvme_mi_mi_config_set(ep, dw0, mtu); +} + +/* Admin channel functions */ + +/** + * nvme_mi_admin_xfer() - Raw admin transfer interface. + * @ctrl: controller to send the admin command to + * @admin_req: request data + * @req_data_size: size of request data payload + * @admin_resp: buffer for response data + * @resp_data_offset: offset into request data to retrieve from controller + * @resp_data_size: size of response data buffer, updated to received size + * + * Performs an arbitrary NVMe Admin command, using the provided request data, + * in @admin_req. The size of the request data *payload* is specified in + * @req_data_size - this does not include the standard header length (so a + * header-only request would have a size of 0). + * + * On success, response data is stored in @admin_resp, which has an optional + * appended payload buffer of @resp_data_size bytes. The actual payload + * transferred will be stored in @resp_data_size. These sizes do not include + * the Admin request header, so 0 represents no payload. + * + * As with all Admin commands, we can request partial data from the Admin + * Response payload, offset by @resp_data_offset. + * + * See: &struct nvme_mi_admin_req_hdr and &struct nvme_mi_admin_resp_hdr. + * + * Return: 0 on success, non-zero on failure. + */ +int nvme_mi_admin_xfer(nvme_mi_ctrl_t ctrl, + struct nvme_mi_admin_req_hdr *admin_req, + size_t req_data_size, + struct nvme_mi_admin_resp_hdr *admin_resp, + off_t resp_data_offset, + size_t *resp_data_size); + +/** + * nvme_mi_admin_identify_partial() - Perform an Admin identify command, + * and retrieve partial response data. + * @ctrl: Controller to process identify command + * @args: Identify command arguments + * @offset: offset of identify data to retrieve from response + * @size: size of identify data to return + * + * Perform an Identify command, using the Identify command parameters in @args. + * The @offset and @size arguments allow the caller to retrieve part of + * the identify response. See NVMe-MI section 6.2 for the semantics (and some + * handy diagrams) of the offset & size parameters. + * + * Will return an error if the length of the response data (from the controller) + * did not match @size. + * + * Unless you're performing a vendor-unique identify command, You'll probably + * want to use one of the identify helpers (nvme_mi_admin_identify, + * nvme_mi_admin_identify_cns_nsid, or nvme_mi_admin_identify_) instead + * 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 + * + * See: &struct nvme_identify_args + */ +int nvme_mi_admin_identify_partial(nvme_mi_ctrl_t ctrl, + struct nvme_identify_args *args, + off_t offset, size_t size); + +/** + * nvme_mi_admin_identify() - Perform an Admin identify command. + * @ctrl: Controller to process identify command + * @args: Identify command arguments + * + * Perform an Identify command, using the Identify command parameters in @args. + * Stores the identify data in ->data, and (if set) the result from cdw0 + * into args->result. + * + * 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 + * + * See: &struct nvme_identify_args + */ +static inline int nvme_mi_admin_identify(nvme_mi_ctrl_t ctrl, + struct nvme_identify_args *args) +{ + return nvme_mi_admin_identify_partial(ctrl, args, + 0, NVME_IDENTIFY_DATA_SIZE); +} + +/** + * nvme_mi_admin_identify_cns_nsid() - Perform an Admin identify command using + * specific CNS/NSID parameters. + * @ctrl: Controller to process identify command + * @cns: Controller or Namespace Structure, specifying identified object + * @nsid: namespace ID + * @data: buffer for identify data response + * + * Perform an Identify command, using the CNS specifier @cns, and the + * namespace ID @nsid if required by the CNS type. + * + * Stores the identify data in @data, which is expected to be a buffer of + * &NVME_IDENTIFY_DATA_SIZE bytes. + * + * 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 + */ +static inline int nvme_mi_admin_identify_cns_nsid(nvme_mi_ctrl_t ctrl, + enum nvme_identify_cns cns, + __u32 nsid, void *data) +{ + struct nvme_identify_args args = { + .result = NULL, + .data = data, + .args_size = sizeof(args), + .cns = cns, + .csi = NVME_CSI_NVM, + .nsid = nsid, + .cntid = NVME_CNTLID_NONE, + .cns_specific_id = NVME_CNSSPECID_NONE, + .uuidx = NVME_UUID_NONE, + }; + + return nvme_mi_admin_identify(ctrl, &args); +} + +/** + * nvme_mi_admin_identify_ctrl() - Perform an Admin identify for a controller + * @ctrl: Controller to process identify command + * @id: Controller identify data to populate + * + * Perform an Identify command, for the controller specified by @ctrl, + * writing identify data to @id. + * + * 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: 0 on success, non-zero on failure + * + * See: &struct nvme_id_ctrl + */ +static inline int nvme_mi_admin_identify_ctrl(nvme_mi_ctrl_t ctrl, + struct nvme_id_ctrl *id) +{ + return nvme_mi_admin_identify_cns_nsid(ctrl, NVME_IDENTIFY_CNS_CTRL, + NVME_NSID_NONE, id); +} + +/** + * nvme_mi_admin_identify_ctrl_list() - Perform an Admin identify for a + * controller list. + * @ctrl: Controller to process identify command + * @cntid: Controller ID to specify list start + * @list: List data to populate + * + * Perform an Identify command, for the controller list 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: 0 on success, non-zero on failure + * + * See: &struct nvme_ctrl_list + */ +static inline int nvme_mi_admin_identify_ctrl_list(nvme_mi_ctrl_t ctrl, + __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 = 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_get_log_page() - Retrieve log page data from controller + * @ctrl: Controller to query + * @args: Get Log Page command arguments + * + * Performs a Get Log Page Admin command as specified by @args. Response data + * is stored in @args->data, which should be a buffer of @args->data_len bytes. + * Resulting data length is stored in @args->data_len on successful + * command completion. + * + * 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 + * + * See: &struct nvme_get_log_args + */ +int nvme_mi_admin_get_log_page(nvme_mi_ctrl_t ctrl, + struct nvme_get_log_args *args); + +/** + * nvme_mi_admin_security_send() - Perform a Security Send command on a + * controller. + * @ctrl: Controller to send command to + * @args: Security Send command arguments + * + * Performs a Security Send Admin command as specified by @args. Response data + * is stored in @args->data, which should be a buffer of @args->data_len bytes. + * Resulting data length is stored in @args->data_len on successful + * command completion. + * + * Security Send data length should not be greater than 4096 bytes to + * comply with specification limits. + * + * Return: 0 on success, non-zero on failure + * + * See: &struct nvme_get_log_args + */ +int nvme_mi_admin_security_send(nvme_mi_ctrl_t ctrl, + struct nvme_security_send_args *args); + +/** + * nvme_mi_admin_security_recv() - Perform a Security Receive command on a + * controller. + * @ctrl: Controller to send command to + * @args: Security Receive command arguments + * + * Performs a Security Receive Admin command as specified by @args. Response + * data is stored in @args->data, which should be a buffer of @args->data_len + * bytes. Resulting data length is stored in @args->data_len on successful + * command completion. + * + * Security Receive data length should not be greater than 4096 bytes to + * comply with specification limits. + * + * Return: 0 on success, non-zero on failure + * + * See: &struct nvme_get_log_args + */ +int nvme_mi_admin_security_recv(nvme_mi_ctrl_t ctrl, + struct nvme_security_receive_args *args); + + +#endif /* _LIBNVME_MI_MI_H */ diff --git a/src/nvme/private.h b/src/nvme/private.h index bea1ae9..da699ba 100644 --- a/src/nvme/private.h +++ b/src/nvme/private.h @@ -10,10 +10,12 @@ #define _LIBNVME_PRIVATE_H #include +#include #include "fabrics.h" +#include "mi.h" -#include +#include extern const char *nvme_ctrl_sysfs_dir; @@ -117,6 +119,7 @@ struct nvme_host { struct nvme_root { char *config_file; struct list_head hosts; + struct list_head endpoints; /* MI endpoints */ FILE *fp; int log_level; bool log_pid; @@ -132,6 +135,11 @@ int json_update_config(nvme_root_t r, const char *config_file); int json_dump_tree(nvme_root_t r); +nvme_ctrl_t __nvme_lookup_ctrl(nvme_subsystem_t s, const char *transport, + const char *traddr, const char *host_traddr, + const char *host_iface, const char *trsvcid, + nvme_ctrl_t p); + #if (LOG_FUNCNAME == 1) #define __nvme_log_func __func__ #else @@ -148,4 +156,65 @@ __nvme_msg(nvme_root_t r, int lvl, const char *func, const char *format, ...); format, ##__VA_ARGS__); \ } while (0) +/* mi internal headers */ + +/* internal transport API */ +struct nvme_mi_req { + struct nvme_mi_msg_hdr *hdr; + size_t hdr_len; + void *data; + size_t data_len; + __u32 mic; +}; + +struct nvme_mi_resp { + struct nvme_mi_msg_hdr *hdr; + size_t hdr_len; + void *data; + size_t data_len; + __u32 mic; +}; + +struct nvme_mi_transport { + const char *name; + bool mic_enabled; + int (*submit)(struct nvme_mi_ep *ep, + struct nvme_mi_req *req, + struct nvme_mi_resp *resp); + void (*close)(struct nvme_mi_ep *ep); + int (*desc_ep)(struct nvme_mi_ep *ep, char *buf, size_t len); +}; + +struct nvme_mi_ep { + struct nvme_root *root; + const struct nvme_mi_transport *transport; + void *transport_data; + struct list_node root_entry; + struct list_head controllers; + bool controllers_scanned; +}; + +struct nvme_mi_ctrl { + struct nvme_mi_ep *ep; + __u16 id; + struct list_node ep_entry; +}; + +struct nvme_mi_ep *nvme_mi_init_ep(struct nvme_root *root); + +/* for tests, we need to calculate the correct MICs */ +__u32 nvme_mi_crc32_update(__u32 crc, void *data, size_t len); + +/* we have a facility to mock MCTP socket operations in the mi-mctp transport, + * using this ops type. This should only be used for test, and isn't exposed + * in the shared lib */; +struct mctp_ioc_tag_ctl; +struct __mi_mctp_socket_ops { + int (*socket)(int, int, int); + ssize_t (*sendmsg)(int, const struct msghdr *, int); + ssize_t (*recvmsg)(int, struct msghdr *, int); + int (*ioctl_tag)(int, unsigned long, struct mctp_ioc_tag_ctl *); +}; +void __nvme_mi_mctp_set_ops(const struct __mi_mctp_socket_ops *newops); + #endif /* _LIBNVME_PRIVATE_H */ diff --git a/src/nvme/tree.c b/src/nvme/tree.c index a2cfa6a..9161791 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -141,6 +141,7 @@ nvme_root_t nvme_create_root(FILE *fp, int log_level) if (fp) r->fp = fp; list_head_init(&r->hosts); + list_head_init(&r->endpoints); return r; } @@ -414,7 +415,8 @@ struct nvme_subsystem *nvme_lookup_subsystem(struct nvme_host *h, struct nvme_subsystem *s; nvme_for_each_subsystem(h, s) { - if (strcmp(s->subsysnqn, subsysnqn)) + if (subsysnqn && s->subsysnqn && + strcmp(s->subsysnqn, subsysnqn)) continue; if (name && s->name && strcmp(s->name, name)) @@ -578,6 +580,7 @@ static int nvme_scan_subsystem(struct nvme_root *r, const char *name, nvme_msg(r, LOG_WARNING, "NQN mismatch for subsystem '%s'\n", name); s = NULL; + free(subsysnqn); errno = EINVAL; return -1; } @@ -957,6 +960,8 @@ static bool traddr_is_hostname(const char *transport, const char *traddr) if (!traddr || !transport) return false; + if (!strcmp(traddr, "none")) + return false; if (strcmp(transport, "tcp") && strcmp(transport, "rdma")) return false; @@ -1018,17 +1023,14 @@ struct nvme_ctrl *nvme_create_ctrl(nvme_root_t r, return c; } -nvme_ctrl_t nvme_lookup_ctrl(nvme_subsystem_t s, const char *transport, - const char *traddr, const char *host_traddr, - const char *host_iface, const char *trsvcid, - nvme_ctrl_t p) +nvme_ctrl_t __nvme_lookup_ctrl(nvme_subsystem_t s, const char *transport, + const char *traddr, const char *host_traddr, + const char *host_iface, const char *trsvcid, + nvme_ctrl_t p) + { - nvme_root_t r; struct nvme_ctrl *c; - if (!s || !transport) - return NULL; - r = s->h ? s->h->r : NULL; c = p ? nvme_subsystem_next_ctrl(s, p) : nvme_subsystem_first_ctrl(s); for (; c != NULL; c = nvme_subsystem_next_ctrl(s, c)) { if (strcmp(c->transport, transport)) @@ -1047,6 +1049,27 @@ nvme_ctrl_t nvme_lookup_ctrl(nvme_subsystem_t s, const char *transport, continue; return c; } + + return NULL; +} + +nvme_ctrl_t nvme_lookup_ctrl(nvme_subsystem_t s, const char *transport, + const char *traddr, const char *host_traddr, + const char *host_iface, const char *trsvcid, + nvme_ctrl_t p) +{ + nvme_root_t r; + struct nvme_ctrl *c; + + if (!s || !transport) + return NULL; + + c = __nvme_lookup_ctrl(s, transport, traddr, host_traddr, + host_iface, trsvcid, p); + if (c) + return c; + + r = s->h ? s->h->r : NULL; c = nvme_create_ctrl(r, s->subsysnqn, transport, traddr, host_traddr, host_iface, trsvcid); if (c) { @@ -1092,20 +1115,26 @@ static char *nvme_ctrl_lookup_subsystem_name(nvme_root_t r, struct dirent **subsys; char *subsys_name = NULL; int ret, i; - char path[PATH_MAX]; ret = nvme_scan_subsystems(&subsys); if (ret < 0) return NULL; for (i = 0; i < ret; i++) { struct stat st; + char *path; - sprintf(path, "%s/%s/%s", nvme_subsys_sysfs_dir, - subsys[i]->d_name, ctrl_name); + if (asprintf(&path, "%s/%s/%s", nvme_subsys_sysfs_dir, + subsys[i]->d_name, ctrl_name) < 0) { + errno = ENOMEM; + return NULL; + } nvme_msg(r, LOG_DEBUG, "lookup subsystem %s\n", path); - if (stat(path, &st) < 0) + if (stat(path, &st) < 0) { + free(path); continue; + } subsys_name = strdup(subsys[i]->d_name); + free(path); break; } nvme_free_dirents(subsys, ret); @@ -1293,12 +1322,10 @@ skip_address: free(transport); if (address) free(address); - if (!c) { - if (!p) { - nvme_msg(r, LOG_ERR, "failed to lookup ctrl\n"); - errno = ENODEV; - } else - errno = ENOMEM; + if (!c && !p) { + nvme_msg(r, LOG_ERR, "failed to lookup ctrl\n"); + errno = ENODEV; + free(addr); return NULL; } c->address = addr; @@ -1360,6 +1387,7 @@ nvme_ctrl_t nvme_scan_ctrl(nvme_root_t r, const char *name) nvme_msg(r, LOG_ERR, "failed to lookup subsystem for controller %s\n", name); + free(subsysnqn); free(path); errno = ENXIO; return NULL; @@ -1815,7 +1843,7 @@ nvme_ns_t nvme_scan_namespace(const char *name) static int nvme_ctrl_scan_namespace(nvme_root_t r, struct nvme_ctrl *c, char *name) { - struct nvme_ns *n; + struct nvme_ns *n, *_n, *__n; nvme_msg(r, LOG_DEBUG, "scan controller %s namespace %s\n", c->name, name); @@ -1829,7 +1857,11 @@ static int nvme_ctrl_scan_namespace(nvme_root_t r, struct nvme_ctrl *c, nvme_msg(r, LOG_DEBUG, "failed to scan namespace %s\n", name); return -1; } - + nvme_ctrl_for_each_ns_safe(c, _n, __n) { + if (strcmp(n->name, _n->name)) + continue; + __nvme_free_ns(_n); + } n->s = c->s; n->c = c; list_add(&c->namespaces, &n->entry); @@ -1865,7 +1897,7 @@ static void nvme_subsystem_set_ns_path(nvme_subsystem_t s, nvme_ns_t n) static int nvme_subsystem_scan_namespace(nvme_root_t r, nvme_subsystem_t s, char *name, nvme_scan_filter_t f, void *f_args) { - struct nvme_ns *n; + struct nvme_ns *n, *_n, *__n; nvme_msg(r, LOG_DEBUG, "scan subsystem %s namespace %s\n", s->name, name); @@ -1879,6 +1911,19 @@ static int nvme_subsystem_scan_namespace(nvme_root_t r, nvme_subsystem_t s, __nvme_free_ns(n); return 0; } + nvme_subsystem_for_each_ns_safe(s, _n, __n) { + struct nvme_path *p, *_p; + + if (strcmp(n->name, _n->name)) + continue; + /* Detach paths */ + nvme_namespace_for_each_path_safe(_n, p, _p) { + list_del_init(&p->nentry); + p->n = NULL; + } + list_head_init(&_n->paths); + __nvme_free_ns(_n); + } n->s = s; list_add(&s->namespaces, &n->entry); nvme_subsystem_set_ns_path(s, n); @@ -1888,22 +1933,11 @@ static int nvme_subsystem_scan_namespace(nvme_root_t r, nvme_subsystem_t s, struct nvme_ns *nvme_subsystem_lookup_namespace(struct nvme_subsystem *s, __u32 nsid) { - nvme_root_t r = s->h ? s->h->r : NULL; struct nvme_ns *n; - char *name; - int ret; - ret = asprintf(&name, "%sn%u", s->name, nsid); - if (ret < 0) - return NULL; - n = __nvme_scan_namespace(s->sysfs_dir, name); - free(name); - if (!n) { - nvme_msg(r, LOG_DEBUG, "failed to scan namespace %d\n", nsid); - return NULL; + nvme_subsystem_for_each_ns(s, n) { + if (nvme_ns_get_nsid(n) == nsid) + return n; } - - n->s = s; - list_add(&s->namespaces, &n->entry); - return n; + return NULL; } diff --git a/src/nvme/tree.h b/src/nvme/tree.h index 9f7a621..3a103c0 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -15,7 +15,7 @@ #include #include -#include +#include #include "ioctl.h" #include "util.h" @@ -142,9 +142,9 @@ nvme_subsystem_t nvme_next_subsystem(nvme_host_t h, nvme_subsystem_t s); * @subsysnqn: Subsystem NQN * * Lookup a &nvme_subsystem_t object in @h base on @name (if present) - * and @subsystemnqn or create one if not found. + * and @subsysnqn or create one if not found. * - * Return: nvme_subsystme_t object + * Return: nvme_subsystem_t object */ nvme_subsystem_t nvme_lookup_subsystem(struct nvme_host *h, const char *name, @@ -232,7 +232,7 @@ nvme_path_t nvme_namespace_first_path(nvme_ns_t ns); * * Return: Next &nvme_path_t object of an @ns iterator */ -nvme_path_t nvme_namespace_next_path(nvme_ns_t c, nvme_path_t p); +nvme_path_t nvme_namespace_next_path(nvme_ns_t ns, nvme_path_t p); /** * nvme_lookup_ctrl() - Lookup nvme_ctrl_t object @@ -304,7 +304,7 @@ nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n); #define nvme_for_each_host_safe(r, h, _h) \ for (h = nvme_first_host(r), \ _h = nvme_next_host(r, h); \ - h != NULL; \ + h != NULL; \ h = _h, _h = nvme_next_host(r, h)) /** @@ -324,8 +324,8 @@ nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n); */ #define nvme_for_each_subsystem_safe(h, s, _s) \ for (s = nvme_first_subsystem(h), \ - _s = nvme_next_subsystem(h, s); \ - s != NULL; \ + _s = nvme_next_subsystem(h, s); \ + s != NULL; \ s = _s, _s = nvme_next_subsystem(h, s)) /** @@ -345,8 +345,8 @@ nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n); */ #define nvme_subsystem_for_each_ctrl_safe(s, c, _c) \ for (c = nvme_subsystem_first_ctrl(s), \ - _c = nvme_subsystem_next_ctrl(s, c); \ - c != NULL; \ + _c = nvme_subsystem_next_ctrl(s, c); \ + c != NULL; \ c = _c, _c = nvme_subsystem_next_ctrl(s, c)) /** @@ -366,8 +366,8 @@ nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n); */ #define nvme_ctrl_for_each_ns_safe(c, n, _n) \ for (n = nvme_ctrl_first_ns(c), \ - _n = nvme_ctrl_next_ns(c, n); \ - n != NULL; \ + _n = nvme_ctrl_next_ns(c, n); \ + n != NULL; \ n = _n, _n = nvme_ctrl_next_ns(c, n)) /** @@ -387,8 +387,8 @@ nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n); */ #define nvme_ctrl_for_each_path_safe(c, p, _p) \ for (p = nvme_ctrl_first_path(c), \ - _p = nvme_ctrl_next_path(c, p); \ - p != NULL; \ + _p = nvme_ctrl_next_path(c, p); \ + p != NULL; \ p = _p, _p = nvme_ctrl_next_path(c, p)) /** @@ -408,8 +408,8 @@ nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n); */ #define nvme_subsystem_for_each_ns_safe(s, n, _n) \ for (n = nvme_subsystem_first_ns(s), \ - _n = nvme_subsystem_next_ns(s, n); \ - n != NULL; \ + _n = nvme_subsystem_next_ns(s, n); \ + n != NULL; \ n = _n, _n = nvme_subsystem_next_ns(s, n)) /** @@ -423,27 +423,27 @@ nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n); /** * nvme_namespace_for_each_path_safe() - Traverse paths - * @ns: Namespace instance + * @n: Namespace instance * @p: &nvme_path_t object * @_p: A &nvme_path_t_node to use as temporary storage */ #define nvme_namespace_for_each_path_safe(n, p, _p) \ for (p = nvme_namespace_first_path(n), \ _p = nvme_namespace_next_path(n, p); \ - p != NULL; \ + p != NULL; \ p = _p, _p = nvme_namespace_next_path(n, p)) /** * nvme_namespace_for_each_path() - Traverse paths - * @ns: Namespace instance + * @n: Namespace instance * @p: &nvme_path_t object */ -#define nvme_namespace_for_each_path(c, p) \ - for (p = nvme_namespace_first_path(c); p != NULL; \ - p = nvme_namespace_next_path(c, p)) +#define nvme_namespace_for_each_path(n, p) \ + for (p = nvme_namespace_first_path(n); p != NULL; \ + p = nvme_namespace_next_path(n, p)) /** - * nvme_ns_get_fd() - Get associated filedescriptor + * nvme_ns_get_fd() - Get associated file descriptor * @n: Namespace instance * * Return: File descriptor associated with @n or -1 @@ -483,10 +483,10 @@ int nvme_ns_get_meta_size(nvme_ns_t n); uint64_t nvme_ns_get_lba_count(nvme_ns_t n); /** - * nvme_ns_get_lba_util() - LBA utilisation of a namespace + * nvme_ns_get_lba_util() - LBA utilization of a namespace * @n: Namespace instance * - * Return: LBA utilisation of @n + * Return: LBA utilization of @n */ uint64_t nvme_ns_get_lba_util(nvme_ns_t n); @@ -805,7 +805,7 @@ const char *nvme_ctrl_get_queue_count(nvme_ctrl_t c); /** * nvme_ctrl_get_serial() - Serial number of a controller - * @c: Conroller instance + * @c: Controller instance * * Return: Serial number string of @c */ @@ -1019,7 +1019,7 @@ void nvme_unlink_ctrl(struct nvme_ctrl *c); * nvme_subsystem_get_nqn() - Retrieve NQN from subsystem * @s: nvme_subsystem_t object * - * Return: NQN of systemstem + * Return: NQN of subsystem */ const char *nvme_subsystem_get_nqn(nvme_subsystem_t s); @@ -1150,7 +1150,7 @@ int nvme_dump_tree(nvme_root_t r); * @attr: sysfs attribute name * * Return: String with the contents of @attr or %NULL in case of an empty value - * or in case of an error (indicated by non-zero errno code). + * or in case of an error (indicated by non-zero errno code). */ char *nvme_get_attr(const char *d, const char *attr); @@ -1160,7 +1160,7 @@ char *nvme_get_attr(const char *d, const char *attr); * @attr: sysfs attribute name * * Return: String with the contents of @attr or %NULL in case of an empty value - * or in case of an error (indicated by non-zero errno code). + * or in case of an error (indicated by non-zero errno code). */ char *nvme_get_subsys_attr(nvme_subsystem_t s, const char *attr); @@ -1170,7 +1170,7 @@ char *nvme_get_subsys_attr(nvme_subsystem_t s, const char *attr); * @attr: sysfs attribute name * * Return: String with the contents of @attr or %NULL in case of an empty value - * or in case of an error (indicated by non-zero errno code). + * or in case of an error (indicated by non-zero errno code). */ char *nvme_get_ctrl_attr(nvme_ctrl_t c, const char *attr); @@ -1180,7 +1180,7 @@ char *nvme_get_ctrl_attr(nvme_ctrl_t c, const char *attr); * @attr: sysfs attribute name * * Return: String with the contents of @attr or %NULL in case of an empty value - * or in case of an error (indicated by non-zero errno code). + * or in case of an error (indicated by non-zero errno code). */ char *nvme_get_ns_attr(nvme_ns_t n, const char *attr); @@ -1200,7 +1200,7 @@ nvme_ns_t nvme_subsystem_lookup_namespace(struct nvme_subsystem *s, * @attr: sysfs attribute name * * Return: String with the contents of @attr or %NULL in case of an empty value - * or in case of an error (indicated by non-zero errno code). + * or in case of an error (indicated by non-zero errno code). */ char *nvme_get_path_attr(nvme_path_t p, const char *attr); diff --git a/src/nvme/types.h b/src/nvme/types.h index 84acb01..3d67bc8 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -4,7 +4,7 @@ * Copyright (c) 2020 Western Digital Corporation or its affiliates. * * Authors: Keith Busch - * Chaitanya Kulkarni + * Chaitanya Kulkarni */ #ifndef _LIBNVME_TYPES_H @@ -48,28 +48,28 @@ /** * enum nvme_constants - A place to stash various constant nvme values * @NVME_NSID_ALL: A broadcast value that is used to specify all - * namespaces + * namespaces * @NVME_NSID_NONE: The invalid namespace id, for when the nsid - * parameter is not used in a command + * parameter is not used in a command * @NVME_UUID_NONE: Use to omit a uuid command parameter * @NVME_CNTLID_NONE: Use to omit a cntlid command parameter - * @NVME_CNSSPECID_NONE: Use to omit a cns_specific_id command parameter + * @NVME_CNSSPECID_NONE: Use to omit a cns_specific_id command parameter * @NVME_LOG_LSP_NONE: Use to omit a log lsp command parameter * @NVME_LOG_LSI_NONE: Use to omit a log lsi command parameter * @NVME_LOG_LPO_NONE: Use to omit a log lpo command parameter * @NVME_IDENTIFY_DATA_SIZE: The transfer size for nvme identify commands - * @NVME_LOG_SUPPORTED_LOG_PAGES_MAX: The lagest possible index in the supported + * @NVME_LOG_SUPPORTED_LOG_PAGES_MAX: The largest possible index in the supported * log pages log. * @NVME_ID_NVMSET_LIST_MAX: The largest possible nvmset index in identify - * nvmeset + * nvmeset * @NVME_ID_UUID_LIST_MAX: The largest possible uuid index in identify - * uuid list + * uuid list * @NVME_ID_CTRL_LIST_MAX: The largest possible controller index in - * identify controller list + * identify controller list * @NVME_ID_NS_LIST_MAX: The largest possible namespace index in - * identify namespace list + * identify namespace list * @NVME_ID_SECONDARY_CTRL_MAX: The largest possible secondary controller index - * in identify secondary controller + * in identify secondary controller * @NVME_ID_DOMAIN_LIST_MAX: The largest possible domain index in the * in domain list * @NVME_ID_ENDURANCE_GROUP_LIST_MAX: The largest possible endurance group @@ -78,10 +78,10 @@ * index in the namespace granularity descriptor * list * @NVME_FEAT_LBA_RANGE_MAX: The largest possible LBA range index in feature - * lba range type + * lba range type * @NVME_LOG_ST_MAX_RESULTS: The largest possible self test result index in the - * device self test log - * @NVME_LOG_FID_SUPPORTED_EFFECTS_MAX: The largest possible FID index in the + * device self test log + * @NVME_LOG_FID_SUPPORTED_EFFECTS_MAX: The largest possible FID index in the * feature identifiers effects log. * @NVME_LOG_MI_CMD_SUPPORTED_EFFECTS_MAX: The largest possible MI Command index * in the MI Command effects log. @@ -89,7 +89,7 @@ * effects log. * @NVME_LOG_TELEM_BLOCK_SIZE: Specification defined size of Telemetry Data Blocks * @NVME_DSM_MAX_RANGES: The largest possible range index in a data-set - * management command + * management command * @NVME_NQN_LENGTH: Max length for NVMe Qualified Name * @NVMF_TRADDR_SIZE: Max Transport Address size * @NVMF_TSAS_SIZE: Max Transport Specific Address Subtype size @@ -142,8 +142,8 @@ enum nvme_csi { /** * enum nvme_register_offsets - controller registers for all transports. This - * is the layout of BAR0/1 for PCIe, and - * properties for fabrics. + * is the layout of BAR0/1 for PCIe, and + * properties for fabrics. * @NVME_REG_CAP: Controller Capabilities * @NVME_REG_VS: Version * @NVME_REG_INTMS: Interrupt Mask Set @@ -161,6 +161,7 @@ enum nvme_csi { * @NVME_REG_BPMBL: Boot Partition Memory Buffer Location * @NVME_REG_CMBMSC: Controller Memory Buffer Memory Space Control * @NVME_REG_CMBSTS: Controller Memory Buffer Status + * @NVME_REG_CRTO: Controller Ready Timeouts * @NVME_REG_PMRCAP: Persistent Memory Capabilities * @NVME_REG_PMRCTL: Persistent Memory Region Control * @NVME_REG_PMRSTS: Persistent Memory Region Status @@ -180,25 +181,26 @@ enum nvme_register_offsets { NVME_REG_AQA = 0x0024, NVME_REG_ASQ = 0x0028, NVME_REG_ACQ = 0x0030, - NVME_REG_CMBLOC = 0x0038, + NVME_REG_CMBLOC = 0x0038, NVME_REG_CMBSZ = 0x003c, NVME_REG_BPINFO = 0x0040, NVME_REG_BPRSEL = 0x0044, NVME_REG_BPMBL = 0x0048, NVME_REG_CMBMSC = 0x0050, NVME_REG_CMBSTS = 0x0058, - NVME_REG_PMRCAP = 0x0e00, - NVME_REG_PMRCTL = 0x0e04, - NVME_REG_PMRSTS = 0x0e08, - NVME_REG_PMREBS = 0x0e0c, + NVME_REG_CRTO = 0x0068, + NVME_REG_PMRCAP = 0x0e00, + NVME_REG_PMRCTL = 0x0e04, + NVME_REG_PMRSTS = 0x0e08, + NVME_REG_PMREBS = 0x0e0c, NVME_REG_PMRSWTP = 0x0e10, - NVME_REG_PMRMSCL = 0x0e14, - NVME_REG_PMRMSCU = 0x0e18, + NVME_REG_PMRMSCL = 0x0e14, + NVME_REG_PMRMSCU = 0x0e18, }; /** * nvme_is_64bit_reg() - Checks if offset of the controller register is a know - * 64bit value. + * 64bit value. * @offset: Offset of controller register field in bytes * * This function does not care about transport so that the offset is not going @@ -206,7 +208,7 @@ enum nvme_register_offsets { * specific transport. For example, BPMBL(Boot Partition Memory Buffer * Location) register is not supported by fabrics, but it can be checked here. * - * Returns true if given offset is 64bit register, otherwise it returns false. + * Returns: true if given offset is 64bit register, otherwise it returns false. */ static inline bool nvme_is_64bit_reg(__u32 offset) { @@ -235,6 +237,7 @@ enum nvme_cap { NVME_CAP_MPSMAX_SHIFT = 52, NVME_CAP_PMRS_SHIFT = 56, NVME_CAP_CMBS_SHIFT = 57, + NVME_CAP_CRMS_SHIFT = 59, NVME_CAP_MQES_MASK = 0xffff, NVME_CAP_CQR_MASK = 0x1, NVME_CAP_AMS_MASK = 0x3, @@ -247,11 +250,14 @@ enum nvme_cap { NVME_CAP_MPSMAX_MASK = 0xf, NVME_CAP_PMRS_MASK = 0x1, NVME_CAP_CMBS_MASK = 0x1, + NVME_CAP_CRMS_MASK = 0x3, NVME_CAP_AMS_WRR = 1 << 0, NVME_CAP_AMS_VS = 1 << 1, NVME_CAP_CSS_NVM = 1 << 0, NVME_CAP_CSS_CSI = 1 << 6, NVME_CAP_CSS_ADMIN = 1 << 7, + NVME_CAP_CRWMS = 1 << 0, + NVME_CAP_CRIMS = 1 << 1, }; #define NVME_CAP_MQES(cap) NVME_GET(cap, CAP_MQES) @@ -264,8 +270,9 @@ enum nvme_cap { #define NVME_CAP_BPS(cap) NVME_GET(cap, CAP_BPS) #define NVME_CAP_MPSMIN(cap) NVME_GET(cap, CAP_MPSMIN) #define NVME_CAP_MPSMAX(cap) NVME_GET(cap, CAP_MPSMAX) -#define NVME_CAP_CMBS(cap) NVME_GET(cap, CAP_CMBS) #define NVME_CAP_PMRS(cap) NVME_GET(cap, CAP_PMRS) +#define NVME_CAP_CMBS(cap) NVME_GET(cap, CAP_CMBS) +#define NVME_CAP_CRMS(cap) NVME_GET(cap, CAP_CRMS) enum nvme_vs { NVME_VS_TER_SHIFT = 0, @@ -292,15 +299,17 @@ enum nvme_cc { NVME_CC_SHN_SHIFT = 14, NVME_CC_IOSQES_SHIFT = 16, NVME_CC_IOCQES_SHIFT = 20, + NVME_CC_CRIME_SHIFT = 24, NVME_CC_EN_MASK = 0x1, NVME_CC_CSS_MASK = 0x7, NVME_CC_MPS_MASK = 0xf, NVME_CC_AMS_MASK = 0x7, NVME_CC_SHN_MASK = 0x3, + NVME_CC_CRIME_MASK = 0x1, NVME_CC_IOSQES_MASK = 0xf, NVME_CC_IOCQES_MASK = 0xf, NVME_CC_CSS_NVM = 0, - NVME_CC_CSS_CSI = 6, + NVME_CC_CSS_CSI = 6, NVME_CC_CSS_ADMIN = 7, NVME_CC_AMS_RR = 0, NVME_CC_AMS_WRRU = 1, @@ -308,6 +317,8 @@ enum nvme_cc { NVME_CC_SHN_NONE = 0, NVME_CC_SHN_NORMAL = 1, NVME_CC_SHN_ABRUPT = 2, + NVME_CC_CRWME = 0, + NVME_CC_CRIME = 1, }; #define NVME_CC_EN(cc) NVME_GET(cc, CC_EN) @@ -317,6 +328,7 @@ enum nvme_cc { #define NVME_CC_SHN(cc) NVME_GET(cc, CC_SHN) #define NVME_CC_IOSQES(cc) NVME_GET(cc, CC_IOSQES) #define NVME_CC_IOCQES(cc) NVME_GET(cc, CC_IOCQES) +#define NVME_CC_CRIME(cc) NVME_GET(cc, CC_CRIME) enum nvme_csts { NVME_CSTS_RDY_SHIFT = 0, @@ -415,7 +427,7 @@ enum nvme_cmbsz { * nvme_cmb_size() - Calculate size of the controller memory buffer * @cmbsz: Value from controller register %NVME_REG_CMBSZ * - * Returns size of controller memory buffer in bytes + * Returns: size of controller memory buffer in bytes */ static inline __u64 nvme_cmb_size(__u32 cmbsz) { @@ -473,6 +485,16 @@ enum nvme_cmbsts { #define NVME_CMBSTS_CBAI(cmbsts) NVME_GET(cmbsts, CMBSTS_CBAI) +enum nvme_crto { + NVME_CRTO_CRIMT_SHIFT = 16, + NVME_CRTO_CRIMT_MASK = 0xffff0000, + NVME_CRTO_CRWMT_SHIFT = 0, + NVME_CRTO_CRWMT_MASK = 0x0000ffff, +}; + +#define NVME_CRTO_CRIMT(crto) NVME_GET(crto, CRTO_CRIMT) +#define NVME_CRTO_CRWMT(crto) NVME_GET(crto, CRTO_CRWMT) + enum nvme_pmrcap { NVME_PMRCAP_RDS_SHIFT = 3, NVME_PMRCAP_WDS_SHIFT = 4, @@ -542,10 +564,10 @@ enum nvme_pmrebs { /** * nvme_pmr_size() - Calculate size of persistent memory region elasticity - * buffer + * buffer * @pmrebs: Value from controller register %NVME_REG_PMREBS * - * Returns size of controller persistent memory buffer in bytes + * Returns: size of controller persistent memory buffer in bytes */ static inline __u64 nvme_pmr_size(__u32 pmrebs) { @@ -571,7 +593,7 @@ enum nvme_pmrswtp { * nvme_pmr_throughput() - Calculate throughput of persistent memory buffer * @pmrswtp: Value from controller register %NVME_REG_PMRSWTP * - * Returns throughput of controller persistent memory buffer in bytes/second + * Returns: throughput of controller persistent memory buffer in bytes/second */ static inline __u64 nvme_pmr_throughput(__u32 pmrswtp) { @@ -592,15 +614,15 @@ static const __u64 NVME_PMRMSC_CBA_MASK = 0xfffffffffffffull; /** * enum nvme_psd_flags - Possible flag values in nvme power state descriptor * @NVME_PSD_FLAGS_MXPS: Indicates the scale for the Maximum Power - * field. If this bit is cleared, then the scale of the - * Maximum Power field is in 0.01 Watts. If this bit is - * set, then the scale of the Maximum Power field is in - * 0.0001 Watts. + * field. If this bit is cleared, then the scale of the + * Maximum Power field is in 0.01 Watts. If this bit is + * set, then the scale of the Maximum Power field is in + * 0.0001 Watts. * @NVME_PSD_FLAGS_NOPS: Indicates whether the controller processes I/O - * commands in this power state. If this bit is cleared, - * then the controller processes I/O commands in this - * power state. If this bit is set, then the controller - * does not process I/O commands in this power state. + * commands in this power state. If this bit is cleared, + * then the controller processes I/O commands in this + * power state. If this bit is set, then the controller + * does not process I/O commands in this power state. */ enum nvme_psd_flags { NVME_PSD_FLAGS_MXPS = 1 << 0, @@ -609,12 +631,14 @@ enum nvme_psd_flags { /** * enum nvme_psd_ps - Known values for &struct nvme_psd %ips and %aps. Use with - * nvme_psd_power_scale() to extract the power scale field - * to match this enum. + * nvme_psd_power_scale() to extract the power scale field + * to match this enum. + * @NVME_PSD_PS_NOT_REPORTED: Not reported * @NVME_PSD_PS_100_MICRO_WATT: 0.0001 watt scale * @NVME_PSD_PS_10_MILLI_WATT: 0.01 watt scale */ enum nvme_psd_ps { + NVME_PSD_PS_NOT_REPORTED = 0, NVME_PSD_PS_100_MICRO_WATT = 1, NVME_PSD_PS_10_MILLI_WATT = 2, }; @@ -622,6 +646,8 @@ enum nvme_psd_ps { /** * nvme_psd_power_scale() - power scale occupies the upper 3 bits * @ps: power scale value + * + * Returns: power scale value */ static inline unsigned int nvme_psd_power_scale(__u8 ps) { @@ -630,15 +656,16 @@ static inline unsigned int nvme_psd_power_scale(__u8 ps) /** * enum nvme_psd_workload - Specifies a workload hint in the Power Management - * Feature (see &struct nvme_psd.apw) to inform the - * NVM subsystem or indicate the conditions for the - * active power level. + * Feature (see &struct nvme_psd.apw) to inform the + * NVM subsystem or indicate the conditions for the + * active power level. + * @NVME_PSD_WORKLOAD_NP: The workload is unknown or not provided. * @NVME_PSD_WORKLOAD_1: Extended Idle Period with a Burst of Random Write - * consists of five minutes of idle followed by - * thirty-two random write commands of size 1 MiB - * submitted to a single controller while all other - * controllers in the NVM subsystem are idle, and then - * thirty (30) seconds of idle. + * consists of five minutes of idle followed by + * thirty-two random write commands of size 1 MiB + * submitted to a single controller while all other + * controllers in the NVM subsystem are idle, and then + * thirty (30) seconds of idle. * @NVME_PSD_WORKLOAD_2: Heavy Sequential Writes consists of 80,000 * sequential write commands of size 128 KiB submitted to * a single controller while all other controllers in the @@ -648,50 +675,51 @@ static inline unsigned int nvme_psd_power_scale(__u8 ps) * times during the workload. */ enum nvme_psd_workload { + NVME_PSD_WORKLOAD_NP = 0, NVME_PSD_WORKLOAD_1 = 1, NVME_PSD_WORKLOAD_2 = 2, }; /** - * struct nvme_id_psd - + * struct nvme_id_psd - Power Management data structure * @mp: Maximum Power indicates the sustained maximum power consumed by the - * NVM subsystem in this power state. The power in Watts is equal to - * the value in this field multiplied by the scale specified in the Max - * Power Scale bit (see &enum nvme_psd_flags). A value of 0 indicates - * Maximum Power is not reported. + * NVM subsystem in this power state. The power in Watts is equal to + * the value in this field multiplied by the scale specified in the Max + * Power Scale bit (see &enum nvme_psd_flags). A value of 0 indicates + * Maximum Power is not reported. * @rsvd2: Reserved * @flags: Additional decoding flags, see &enum nvme_psd_flags. * @enlat: Entry Latency indicates the maximum latency in microseconds - * associated with entering this power state. A value of 0 indicates - * Entry Latency is not reported. + * associated with entering this power state. A value of 0 indicates + * Entry Latency is not reported. * @exlat: Exit Latency indicates the maximum latency in microseconds - * associated with exiting this power state. A value of 0 indicates - * Exit Latency is not reported. + * associated with exiting this power state. A value of 0 indicates + * Exit Latency is not reported. * @rrt: Relative Read Throughput indicates the read throughput rank - * associated with this power state relative to others. The value in - * this is less than the number of supported power states. - * @rrl: Relative Reade Latency indicates the read latency rank associated - * with this power state relative to others. The value in this field is - * less than the number of supported power states. + * associated with this power state relative to others. The value in + * this is less than the number of supported power states. + * @rrl: Relative Read Latency indicates the read latency rank associated + * with this power state relative to others. The value in this field is + * less than the number of supported power states. * @rwt: Relative Write Throughput indicates write throughput rank associated - * with this power state relative to others. The value in this field is - * less than the number of supported power states + * with this power state relative to others. The value in this field is + * less than the number of supported power states * @rwl: Relative Write Latency indicates the write latency rank associated - * with this power state relative to others. The value in this field is - * less than the number of supported power states + * with this power state relative to others. The value in this field is + * less than the number of supported power states * @idlp: Idle Power indicates the typical power consumed by the NVM - * subsystem over 30 seconds in this power state when idle. + * subsystem over 30 seconds in this power state when idle. * @ips: Idle Power Scale indicates the scale for &struct nvme_id_psd.idlp, - * see &enum nvme_psd_ps for decoding this field. + * see &enum nvme_psd_ps for decoding this field. * @rsvd19: Reserved * @actp: Active Power indicates the largest average power consumed by the - * NVM subsystem over a 10 second period in this power state with - * the workload indicated in the Active Power Workload field. + * NVM subsystem over a 10 second period in this power state with + * the workload indicated in the Active Power Workload field. * @apws: Bits 7-6: Active Power Scale(APS) indicates the scale for the &struct - * nvme_id_psd.actp, see &enum nvme_psd_ps for decoding this value. - * Bits 2-0: Active Power Workload(APW) indicates the workload - * used to calculate maximum power for this power state. - * See &enum nvme_psd_workload for decoding this field. + * nvme_id_psd.actp, see &enum nvme_psd_ps for decoding this value. + * Bits 2-0: Active Power Workload(APW) indicates the workload + * used to calculate maximum power for this power state. + * See &enum nvme_psd_workload for decoding this field. * @rsvd23: Reserved */ struct nvme_id_psd { @@ -715,155 +743,155 @@ struct nvme_id_psd { /** * struct nvme_id_ctrl - Identify Controller data structure * @vid: PCI Vendor ID, the company vendor identifier that is assigned by - * the PCI SIG. + * the PCI SIG. * @ssvid: PCI Subsystem Vendor ID, the company vendor identifier that is - * assigned by the PCI SIG for the subsystem. - * @sn: Serial Number in ascii - * @mn: Model Number in ascii - * @fr: Firmware Revision in ascii, the currently active firmware - * revision for the NVM subsystem + * assigned by the PCI SIG for the subsystem. + * @sn: Serial Number in ASCII + * @mn: Model Number in ASCII + * @fr: Firmware Revision in ASCII, the currently active firmware + * revision for the NVM subsystem * @rab: Recommended Arbitration Burst, reported as a power of two * @ieee: IEEE assigned Organization Unique Identifier * @cmic: Controller Multipath IO and Namespace Sharing Capabilities of - * the controller and NVM subsystem. See &enum nvme_id_ctrl_cmic. + * the controller and NVM subsystem. See &enum nvme_id_ctrl_cmic. * @mdts: Max Data Transfer Size is the largest data transfer size. The - * host should not submit a command that exceeds this maximum data - * transfer size. The value is in units of the minimum memory page - * size (CAP.MPSMIN) and is reported as a power of two + * host should not submit a command that exceeds this maximum data + * transfer size. The value is in units of the minimum memory page + * size (CAP.MPSMIN) and is reported as a power of two * @cntlid: Controller ID, the NVM subsystem unique controller identifier - * associated with the controller. + * associated with the controller. * @ver: Version, this field contains the value reported in the Version - * register, or property (see &enum nvme_registers %NVME_REG_VS). + * register, or property (see &enum nvme_registers %NVME_REG_VS). * @rtd3r: RTD3 Resume Latency, the expected latency in microseconds to resume - * from Runtime D3 + * from Runtime D3 * @rtd3e: RTD3 Exit Latency, the typical latency in microseconds to enter - * Runtime D3. + * Runtime D3. * @oaes: Optional Async Events Supported, see @enum nvme_id_ctrl_oaes. * @ctratt: Controller Attributes, see @enum nvme_id_ctrl_ctratt. * @rrls: Read Recovery Levels. If a bit is set, then the corresponding - * Read Recovery Level is supported. If a bit is cleared, then the - * corresponding Read Recovery Level is not supported. - * @rsvd102: Reserved + * Read Recovery Level is supported. If a bit is cleared, then the + * corresponding Read Recovery Level is not supported. + * @rsvd102: Reserved * @cntrltype: Controller Type, see &enum nvme_id_ctrl_cntrltype * @fguid: FRU GUID, a 128-bit value that is globally unique for a given - * Field Replaceable Unit - * @crdt1: Controller Retry Delay time in 100 millisecod units if CQE CRD + * Field Replaceable Unit + * @crdt1: Controller Retry Delay time in 100 millisecond units if CQE CRD * field is 1 - * @crdt2: Controller Retry Delay time in 100 millisecod units if CQE CRD - * field is 2 - * @crdt3: Controller Retry Delay time in 100 millisecod units if CQE CRD - * field is 3 + * @crdt2: Controller Retry Delay time in 100 millisecond units if CQE CRD + * field is 2 + * @crdt3: Controller Retry Delay time in 100 millisecond units if CQE CRD + * field is 3 * @rsvd134: Reserved * @nvmsr: NVM Subsystem Report, see &enum nvme_id_ctrl_nvmsr * @vwci: VPD Write Cycle Information, see &enum nvme_id_ctrl_vwci * @mec: Management Endpoint Capabilities, see &enum nvme_id_ctrl_mec * @oacs: Optional Admin Command Support,the optional Admin commands and - * features supported by the controller, see &enum nvme_id_ctrl_oacs. + * features supported by the controller, see &enum nvme_id_ctrl_oacs. * @acl: Abort Command Limit, the maximum number of concurrently - * executing Abort commands supported by the controller. This is a - * 0's based value. + * executing Abort commands supported by the controller. This is a + * 0's based value. * @aerl: Async Event Request Limit, the maximum number of concurrently - * outstanding Asynchronous Event Request commands supported by the - * controller This is a 0's based value. + * outstanding Asynchronous Event Request commands supported by the + * controller This is a 0's based value. * @frmw: Firmware Updates indicates capabilities regarding firmware - * updates. See &enum nvme_id_ctrl_frmw. + * updates. See &enum nvme_id_ctrl_frmw. * @lpa: Log Page Attributes, see &enum nvme_id_ctrl_lpa. * @elpe: Error Log Page Entries, the maximum number of Error Information - * log entries that are stored by the controller. This field is a - * 0's based value. + * log entries that are stored by the controller. This field is a + * 0's based value. * @npss: Number of Power States Supported, the number of NVM Express - * power states supported by the controller, indicating the number - * of valid entries in &struct nvme_id_ctrl.psd. This is a 0's - * based value. + * power states supported by the controller, indicating the number + * of valid entries in &struct nvme_id_ctrl.psd. This is a 0's + * based value. * @avscc: Admin Vendor Specific Command Configuration, see - * &enum nvme_id_ctrl_avscc. + * &enum nvme_id_ctrl_avscc. * @apsta: Autonomous Power State Transition Attributes, see - * &enum nvme_id_ctrl_apsta. + * &enum nvme_id_ctrl_apsta. * @wctemp: Warning Composite Temperature Threshold indicates - * the minimum Composite Temperature field value (see &struct - * nvme_smart_log.critical_comp_time) that indicates an overheating - * condition during which controller operation continues. + * the minimum Composite Temperature field value (see &struct + * nvme_smart_log.critical_comp_time) that indicates an overheating + * condition during which controller operation continues. * @cctemp: Critical Composite Temperature Threshold, field indicates the - * minimum Composite Temperature field value (see &struct - * nvme_smart_log.critical_comp_time) that indicates a critical - * overheating condition. + * minimum Composite Temperature field value (see &struct + * nvme_smart_log.critical_comp_time) that indicates a critical + * overheating condition. * @mtfa: Maximum Time for Firmware Activation indicates the maximum time - * the controller temporarily stops processing commands to activate - * the firmware image, specified in 100 millisecond units. This - * field is always valid if the controller supports firmware - * activation without a reset. + * the controller temporarily stops processing commands to activate + * the firmware image, specified in 100 millisecond units. This + * field is always valid if the controller supports firmware + * activation without a reset. * @hmpre: Host Memory Buffer Preferred Size indicates the preferred size - * that the host is requested to allocate for the Host Memory - * Buffer feature in 4 KiB units. + * that the host is requested to allocate for the Host Memory + * Buffer feature in 4 KiB units. * @hmmin: Host Memory Buffer Minimum Size indicates the minimum size that - * the host is requested to allocate for the Host Memory Buffer - * feature in 4 KiB units. + * the host is requested to allocate for the Host Memory Buffer + * feature in 4 KiB units. * @tnvmcap: Total NVM Capacity, the total NVM capacity in the NVM subsystem. - * The value is in bytes. + * The value is in bytes. * @unvmcap: Unallocated NVM Capacity, the unallocated NVM capacity in the - * NVM subsystem. The value is in bytes. - * @rpmbs: Replay Protected Memory Block Support, see - * &enum nvme_id_ctrl_rpmbs. - * @edstt: Extended Device Self-test Time, if Device Self-test command is - * supported (see &struct nvme_id_ctrl.oacs, %NVME_CTRL_OACS_SELF_TEST), - * then this field indicates the nominal amount of time in one - * minute units that the controller takes to complete an extended - * device self-test operation when in power state 0. + * NVM subsystem. The value is in bytes. + * @rpmbs: Replay Protected Memory Block Support, see + * &enum nvme_id_ctrl_rpmbs. + * @edstt: Extended Device Self-test Time, if Device Self-test command is + * supported (see &struct nvme_id_ctrl.oacs, %NVME_CTRL_OACS_SELF_TEST), + * then this field indicates the nominal amount of time in one + * minute units that the controller takes to complete an extended + * device self-test operation when in power state 0. * @dsto: Device Self-test Options, see &enum nvme_id_ctrl_dsto. * @fwug: Firmware Update Granularity indicates the granularity and - * alignment requirement of the firmware image being updated by the - * Firmware Image Download command. The value is reported in 4 KiB - * units. A value of 0h indicates no information on granularity is - * provided. A value of FFh indicates no restriction + * alignment requirement of the firmware image being updated by the + * Firmware Image Download command. The value is reported in 4 KiB + * units. A value of 0h indicates no information on granularity is + * provided. A value of FFh indicates no restriction * @kas: Keep Alive Support indicates the granularity of the Keep Alive - * Timer in 100 millisecond units. + * Timer in 100 millisecond units. * @hctma: Host Controlled Thermal Management Attributes, see - * &enum nvme_id_ctrl_hctm. + * &enum nvme_id_ctrl_hctm. * @mntmt: Minimum Thermal Management Temperature indicates the minimum - * temperature, in degrees Kelvin, that the host may request in the - * Thermal Management Temperature 1 field and Thermal Management - * Temperature 2 field of a Set Features command with the Feature - * Identifier field set to %NVME_FEAT_FID_HCTM. + * temperature, in degrees Kelvin, that the host may request in the + * Thermal Management Temperature 1 field and Thermal Management + * Temperature 2 field of a Set Features command with the Feature + * Identifier field set to %NVME_FEAT_FID_HCTM. * @mxtmt: Maximum Thermal Management Temperature indicates the maximum - * temperature, in degrees Kelvin, that the host may request in the - * Thermal Management Temperature 1 field and Thermal Management - * Temperature 2 field of the Set Features command with the Feature - * Identifier set to %NVME_FEAT_FID_HCTM. + * temperature, in degrees Kelvin, that the host may request in the + * Thermal Management Temperature 1 field and Thermal Management + * Temperature 2 field of the Set Features command with the Feature + * Identifier set to %NVME_FEAT_FID_HCTM. * @sanicap: Sanitize Capabilities, see &enum nvme_id_ctrl_sanicap * @hmminds: Host Memory Buffer Minimum Descriptor Entry Size indicates the - * minimum usable size of a Host Memory Buffer Descriptor Entry in - * 4 KiB units. + * minimum usable size of a Host Memory Buffer Descriptor Entry in + * 4 KiB units. * @hmmaxd: Host Memory Maximum Descriptors Entries indicates the number of - * usable Host Memory Buffer Descriptor Entries. + * usable Host Memory Buffer Descriptor Entries. * @nsetidmax: NVM Set Identifier Maximum, defines the maximum value of a valid - * NVM Set Identifier for any controller in the NVM subsystem. + * NVM Set Identifier for any controller in the NVM subsystem. * @endgidmax: Endurance Group Identifier Maximum, defines the maximum value of - * a valid Endurance Group Identifier for any controller in the NVM - * subsystem. + * a valid Endurance Group Identifier for any controller in the NVM + * subsystem. * @anatt: ANA Transition Time indicates the maximum amount of time, in - * seconds, for a transition between ANA states or the maximum - * amount of time, in seconds, that the controller reports the ANA - * change state. + * seconds, for a transition between ANA states or the maximum + * amount of time, in seconds, that the controller reports the ANA + * change state. * @anacap: Asymmetric Namespace Access Capabilities, see - * &enum nvme_id_ctrl_anacap. + * &enum nvme_id_ctrl_anacap. * @anagrpmax: ANA Group Identifier Maximum indicates the maximum value of a - * valid ANA Group Identifier for any controller in the NVM - * subsystem. + * valid ANA Group Identifier for any controller in the NVM + * subsystem. * @nanagrpid: Number of ANA Group Identifiers indicates the number of ANA - * groups supported by this controller. + * groups supported by this controller. * @pels: Persistent Event Log Size indicates the maximum reportable size - * for the Persistent Event Log. + * for the Persistent Event Log. * @domainid: Domain Identifier indicates the identifier of the domain - * that contains this controller. + * that contains this controller. * @rsvd358: Reserved * @megcap: Max Endurance Group Capacity indicates the maximum capacity - * of a single Endurance Group. + * of a single Endurance Group. * @rsvd384: Reserved * @sqes: Submission Queue Entry Size, see &enum nvme_id_ctrl_sqes. * @cqes: Completion Queue Entry Size, see &enum nvme_id_ctrl_cqes. * @maxcmd: Maximum Outstanding Commands indicates the maximum number of - * commands that the controller processes at one time for a - * particular queue. + * commands that the controller processes at one time for a + * particular queue. * @nn: Number of Namespaces indicates the maximum value of a valid * nsid for the NVM subsystem. If the MNAN (&struct nvme_id_ctrl.mnan * field is cleared to 0h, then this field also indicates the @@ -873,53 +901,53 @@ struct nvme_id_psd { * @fna: Format NVM Attributes, see &enum nvme_id_ctrl_fna. * @vwc: Volatile Write Cache, see &enum nvme_id_ctrl_vwc. * @awun: Atomic Write Unit Normal indicates the size of the write - * operation guaranteed to be written atomically to the NVM across - * all namespaces with any supported namespace format during normal - * operation. This field is specified in logical blocks and is a - * 0's based value. + * operation guaranteed to be written atomically to the NVM across + * all namespaces with any supported namespace format during normal + * operation. This field is specified in logical blocks and is a + * 0's based value. * @awupf: Atomic Write Unit Power Fail indicates the size of the write - * operation guaranteed to be written atomically to the NVM across - * all namespaces with any supported namespace format during a - * power fail or error condition. This field is specified in - * logical blocks and is a 0’s based value. + * operation guaranteed to be written atomically to the NVM across + * all namespaces with any supported namespace format during a + * power fail or error condition. This field is specified in + * logical blocks and is a 0’s based value. * @icsvscc: NVM Vendor Specific Command Configuration, see - * &enum nvme_id_ctrl_nvscc. + * &enum nvme_id_ctrl_nvscc. * @nwpc: Namespace Write Protection Capabilities, see - * &enum nvme_id_ctrl_nwpc. + * &enum nvme_id_ctrl_nwpc. * @acwu: Atomic Compare & Write Unit indicates the size of the write - * operation guaranteed to be written atomically to the NVM across - * all namespaces with any supported namespace format for a Compare - * and Write fused operation. This field is specified in logical - * blocks and is a 0’s based value. + * operation guaranteed to be written atomically to the NVM across + * all namespaces with any supported namespace format for a Compare + * and Write fused operation. This field is specified in logical + * blocks and is a 0’s based value. * @ocfs: Optional Copy Formats Supported, each bit n means controller - * supports Copy Format n. + * supports Copy Format n. * @sgls: SGL Support, see &enum nvme_id_ctrl_sgls * @mnan: Maximum Number of Allowed Namespaces indicates the maximum - * number of namespaces supported by the NVM subsystem. + * number of namespaces supported by the NVM subsystem. * @maxdna: Maximum Domain Namespace Attachments indicates the maximum - * of the sum of the numver of namespaces attached to each I/O - * controller in the Domain. + * of the sum of the number of namespaces attached to each I/O + * controller in the Domain. * @maxcna: Maximum I/O Controller Namespace Attachments indicates the - * maximum number of namespaces that are allowed to be attached to - * this I/O controller. + * maximum number of namespaces that are allowed to be attached to + * this I/O controller. * @rsvd564: Reserved * @subnqn: NVM Subsystem NVMe Qualified Name, UTF-8 null terminated string * @rsvd1024: Reserved * @ioccsz: I/O Queue Command Capsule Supported Size, defines the maximum - * I/O command capsule size in 16 byte units. + * I/O command capsule size in 16 byte units. * @iorcsz: I/O Queue Response Capsule Supported Size, defines the maximum - * I/O response capsule size in 16 byte units. + * I/O response capsule size in 16 byte units. * @icdoff: In Capsule Data Offset, defines the offset where data starts - * within a capsule. This value is applicable to I/O Queues only. + * within a capsule. This value is applicable to I/O Queues only. * @fcatt: Fabrics Controller Attributes, see &enum nvme_id_ctrl_fcatt. * @msdbd: Maximum SGL Data Block Descriptors indicates the maximum - * number of SGL Data Block or Keyed SGL Data Block descriptors - * that a host is allowed to place in a capsule. A value of 0h - * indicates no limit. + * number of SGL Data Block or Keyed SGL Data Block descriptors + * that a host is allowed to place in a capsule. A value of 0h + * indicates no limit. * @ofcs: Optional Fabric Commands Support, see &enum nvme_id_ctrl_ofcs. * @dctype: Discovery Controller Type (DCTYPE). This field indicates what - * type of Discovery controller the controller is (see enum - * nvme_id_ctrl_dctype) + * type of Discovery controller the controller is (see enum + * nvme_id_ctrl_dctype) * @rsvd1807: Reserved * @psd: Power State Descriptors, see &struct nvme_id_psd. * @vs: Vendor Specific @@ -1027,24 +1055,24 @@ struct nvme_id_ctrl { /** * enum nvme_id_ctrl_cmic - Controller Multipath IO and Namespace Sharing - * Capabilities of the controller and NVM subsystem. - * @NVME_CTRL_CMIC_MULTI_PORT: If set, then the NVM subsystem may contain - * more than one NVM subsystem port, otherwise - * the NVM subsystem contains only a single - * NVM subsystem port. - * @NVME_CTRL_CMIC_MULTI_CTRL: If set, then the NVM subsystem may contain - * two or more controllers, otherwise the - * NVM subsystem contains only a single - * controller. An NVM subsystem that contains - * multiple controllers may be used by - * multiple hosts, or may provide multiple - * paths for a single host. - * @NVME_CTRL_CMIC_MULTI_SRIOV: If set, then the controller is associated - * with an SR-IOV Virtual Function, otherwise - * it is associated with a PCI Function - * or a Fabrics connection. + * Capabilities of the controller and NVM subsystem. + * @NVME_CTRL_CMIC_MULTI_PORT: If set, then the NVM subsystem may contain + * more than one NVM subsystem port, otherwise + * the NVM subsystem contains only a single + * NVM subsystem port. + * @NVME_CTRL_CMIC_MULTI_CTRL: If set, then the NVM subsystem may contain + * two or more controllers, otherwise the + * NVM subsystem contains only a single + * controller. An NVM subsystem that contains + * multiple controllers may be used by + * multiple hosts, or may provide multiple + * paths for a single host. + * @NVME_CTRL_CMIC_MULTI_SRIOV: If set, then the controller is associated + * with an SR-IOV Virtual Function, otherwise + * it is associated with a PCI Function + * or a Fabrics connection. * @NVME_CTRL_CMIC_MULTI_ANA_REPORTING: If set, then the NVM subsystem supports - * Asymmetric Namespace Access Reporting. + * Asymmetric Namespace Access Reporting. */ enum nvme_id_ctrl_cmic { NVME_CTRL_CMIC_MULTI_PORT = 1 << 0, @@ -1059,10 +1087,10 @@ enum nvme_id_ctrl_cmic { * @NVME_CTRL_OAES_FA: Firmware Activation Notices event supported * @NVME_CTRL_OAES_ANA: ANA Change Notices supported * @NVME_CTRL_OAES_PLEA: Predictable Latency Event Aggregate Log - * Change Notices event supported + * Change Notices event supported * @NVME_CTRL_OAES_LBAS: LBA Status Information Notices event supported * @NVME_CTRL_OAES_EGE: Endurance Group Events Aggregate Log Change - * Notices event supported + * Notices event supported * @NVME_CTRL_OAES_NS: Normal NVM Subsystem Shutdown event supported * @NVME_CTRL_OAES_ZD: Zone Descriptor Change Notifications supported * @NVME_CTRL_OAES_DL: Discover Log Page Change Notifications supported @@ -1083,19 +1111,19 @@ enum nvme_id_ctrl_oaes { * enum nvme_id_ctrl_ctratt - Controller attributes * @NVME_CTRL_CTRATT_128_ID: 128-bit Host Identifier supported * @NVME_CTRL_CTRATT_NON_OP_PSP: Non-Operational Poser State Permissive Mode - * supported + * supported * @NVME_CTRL_CTRATT_NVM_SETS: NVM Sets supported * @NVME_CTRL_CTRATT_READ_RECV_LVLS: Read Recovery Levels supported * @NVME_CTRL_CTRATT_ENDURANCE_GROUPS: Endurance Groups supported * @NVME_CTRL_CTRATT_PREDICTABLE_LAT: Predictable Latency Mode supported * @NVME_CTRL_CTRATT_TBKAS: Traffic Based Keep Alive Support * @NVME_CTRL_CTRATT_NAMESPACE_GRANULARITY: Namespace Granularity reporting - * supported + * supported * @NVME_CTRL_CTRATT_SQ_ASSOCIATIONS: SQ Associations supported * @NVME_CTRL_CTRATT_UUID_LIST: UUID List reporting supported * @NVME_CTRL_CTRATT_MDS: Multi-Domain Subsystem supported * @NVME_CTRL_CTRATT_FIXED_CAP: Fixed Capacity Management supported - * @NVME_CTRL_CTRATT_VARIABLE_CAP: Variable Capacity Managment supported + * @NVME_CTRL_CTRATT_VARIABLE_CAP: Variable Capacity Management supported * @NVME_CTRL_CTRATT_DEL_ENDURANCE_GROUPS: Delete Endurance Groups supported * @NVME_CTRL_CTRATT_DEL_NVM_SETS: Delete NVM Sets supported * @NVME_CTRL_CTRATT_ELBAS: Extended LBA Formats supported @@ -1134,8 +1162,8 @@ enum nvme_id_ctrl_cntrltype { /** * enum nvme_id_ctrl_dctype - Discovery Controller types * @NVME_CTRL_DCTYPE_NOT_REPORTED: Not reported (I/O, Admin, and pre-TP8010) - * @NVME_CTRL_DCTYPE_DDC: Direct Discovery controller - * @NVME_CTRL_DCTYPE_CDC: Central Discovery controller + * @NVME_CTRL_DCTYPE_DDC: Direct Discovery controller + * @NVME_CTRL_DCTYPE_CDC: Central Discovery controller */ enum nvme_id_ctrl_dctype { NVME_CTRL_DCTYPE_NOT_REPORTED = 0, @@ -1145,10 +1173,10 @@ enum nvme_id_ctrl_dctype { /** * enum nvme_id_ctrl_nvmsr - This field reports information associated with the - * NVM Subsystem, see &struct nvme_id_ctrl.nvmsr. + * NVM Subsystem, see &struct nvme_id_ctrl.nvmsr. * @NVME_CTRL_NVMSR_NVMESD: If set, then the NVM Subsystem is part of an NVMe - * Storage Device; if cleared, then the NVM Subsystem - * is not part of an NVMe Storage Device. + * Storage Device; if cleared, then the NVM Subsystem + * is not part of an NVMe Storage Device. * @NVME_CTRL_NVMSR_NVMEE: If set’, then the NVM Subsystem is part of an NVMe * Enclosure; if cleared, then the NVM Subsystem is * not part of an NVMe Enclosure. @@ -1160,21 +1188,21 @@ enum nvme_id_ctrl_nvmsr { /** * enum nvme_id_ctrl_vwci - This field indicates information about remaining - * number of times that VPD contents are able to be - * updated using the VPD Write command, see &struct - * nvme_id_ctrl.vwci. + * number of times that VPD contents are able to be + * updated using the VPD Write command, see &struct + * nvme_id_ctrl.vwci. * @NVME_CTRL_VWCI_VWCR: Mask to get value of VPD Write Cycles Remaining. If - * the VPD Write Cycle Remaining Valid bit is set, then - * this field contains a value indicating the remaining - * number of times that VPD contents are able to be - * updated using the VPD Write command. If this field is - * set to 7Fh, then the remaining number of times that - * VPD contents are able to be updated using the VPD - * Write command is greater than or equal to 7Fh. + * the VPD Write Cycle Remaining Valid bit is set, then + * this field contains a value indicating the remaining + * number of times that VPD contents are able to be + * updated using the VPD Write command. If this field is + * set to 7Fh, then the remaining number of times that + * VPD contents are able to be updated using the VPD + * Write command is greater than or equal to 7Fh. * @NVME_CTRL_VWCI_VWCRV: VPD Write Cycle Remaining Valid. If this bit is set, - * then the VPD Write Cycle Remaining field is valid. If - * this bit is cleared, then the VPD Write Cycles - * Remaining field is invalid and cleared to 0h. + * then the VPD Write Cycle Remaining field is valid. If + * this bit is cleared, then the VPD Write Cycles + * Remaining field is invalid and cleared to 0h. */ enum nvme_id_ctrl_vwci { NVME_CTRL_VWCI_VWCR = 0x7f << 0, @@ -1182,12 +1210,12 @@ enum nvme_id_ctrl_vwci { }; /** - * enum nvme_id_ctrl_mec - Flags indicatings the capabilities of the Management - * Endpoint in the Controller, &struct nvme_id_ctrl.mec. + * enum nvme_id_ctrl_mec - Flags indicating the capabilities of the Management + * Endpoint in the Controller, &struct nvme_id_ctrl.mec. * @NVME_CTRL_MEC_SMBUSME: If set, then the NVM Subsystem contains a Management - * Endpoint on an SMBus/I2C port. + * Endpoint on an SMBus/I2C port. * @NVME_CTRL_MEC_PCIEME: If set, then the NVM Subsystem contains a Management - * Endpoint on a PCIe port. + * Endpoint on a PCIe port. */ enum nvme_id_ctrl_mec { NVME_CTRL_MEC_SMBUSME = 1 << 0, @@ -1196,29 +1224,31 @@ enum nvme_id_ctrl_mec { /** * enum nvme_id_ctrl_oacs - Flags indicating the optional Admin commands and - * features supported by the controller, see - * &struct nvme_id_ctrl.oacs. + * features supported by the controller, see + * &struct nvme_id_ctrl.oacs. * @NVME_CTRL_OACS_SECURITY: If set, then the controller supports the - * Security Send and Security Receive commands. + * Security Send and Security Receive commands. * @NVME_CTRL_OACS_FORMAT: If set then the controller supports the Format - * NVM command. + * NVM command. * @NVME_CTRL_OACS_FW: If set, then the controller supports the - * Firmware Commit and Firmware Image Download commands. + * Firmware Commit and Firmware Image Download commands. * @NVME_CTRL_OACS_NS_MGMT: If set, then the controller supports the - * Namespace Management capability + * Namespace Management capability * @NVME_CTRL_OACS_SELF_TEST: If set, then the controller supports the Device - * Self-test command. + * Self-test command. * @NVME_CTRL_OACS_DIRECTIVES: If set, then the controller supports Directives * and the Directive Send and Directive Receive * commands. * @NVME_CTRL_OACS_NVME_MI: If set, then the controller supports the NVMe-MI - * Send and NVMe-MI Receive commands. + * Send and NVMe-MI Receive commands. * @NVME_CTRL_OACS_VIRT_MGMT: If set, then the controller supports the - * Virtualization Management command. + * Virtualization Management command. * @NVME_CTRL_OACS_DBBUF_CFG: If set, then the controller supports the - * Doorbell Buffer Config command. + * Doorbell Buffer Config command. * @NVME_CTRL_OACS_LBA_STATUS: If set, then the controller supports the Get LBA - * Status capability. + * Status capability. + * @NVME_CTRL_OACS_CMD_FEAT_LD: If set, then the controller supports the command + * and feature lockdown capability. */ enum nvme_id_ctrl_oacs { NVME_CTRL_OACS_SECURITY = 1 << 0, @@ -1231,31 +1261,55 @@ enum nvme_id_ctrl_oacs { NVME_CTRL_OACS_VIRT_MGMT = 1 << 7, NVME_CTRL_OACS_DBBUF_CFG = 1 << 8, NVME_CTRL_OACS_LBA_STATUS = 1 << 9, + NVME_CTRL_OACS_CMD_FEAT_LD = 1 << 10, }; /** * enum nvme_id_ctrl_frmw - Flags and values indicates capabilities regarding - * firmware updates from &struct nvme_id_ctrl.frmw. + * firmware updates from &struct nvme_id_ctrl.frmw. * @NVME_CTRL_FRMW_1ST_RO: If set, the first firmware slot is readonly * @NVME_CTRL_FRMW_NR_SLOTS: Mask to get the value of the number of - * firmware slots that the controller supports. + * firmware slots that the controller supports. * @NVME_CTRL_FRMW_FW_ACT_NO_RESET: If set, the controller supports firmware - * activation without a reset. + * activation without a reset. + * @NVME_CTRL_FRMW_MP_UP_DETECTION: If set, the controller is able to detect + * overlapping firmware/boot partition + * image update. */ enum nvme_id_ctrl_frmw { NVME_CTRL_FRMW_1ST_RO = 1 << 0, NVME_CTRL_FRMW_NR_SLOTS = 3 << 1, NVME_CTRL_FRMW_FW_ACT_NO_RESET = 1 << 4, + NVME_CTRL_FRMW_MP_UP_DETECTION = 1 << 5, }; /** * enum nvme_id_ctrl_lpa - Flags indicating optional attributes for log pages - * that are accessed via the Get Log Page command. - * @NVME_CTRL_LPA_SMART_PER_NS: - * @NVME_CTRL_LPA_CMD_EFFECTS: - * @NVME_CTRL_LPA_EXTENDED: - * @NVME_CTRL_LPA_TELEMETRY: - * @NVME_CTRL_LPA_PERSETENT_EVENT: + * that are accessed via the Get Log Page command. + * @NVME_CTRL_LPA_SMART_PER_NS: If set, controller supports SMART/Health log + * page on a per namespace basis. + * @NVME_CTRL_LPA_CMD_EFFECTS: If Set, the controller supports the commands + * supported and effects log page. + * @NVME_CTRL_LPA_EXTENDED: If set, the controller supports extended data + * for log page command including extended number + * of dwords and log page offset fields. + * @NVME_CTRL_LPA_TELEMETRY: If set, the controller supports the telemetry + * host-initiated and telemetry controller-initiated + * log pages and sending telemetry log notices. + * @NVME_CTRL_LPA_PERSETENT_EVENT: If set, the controller supports + * persistent event log. + * @NVME_CTRL_LPA_LI0_LI5_LI12_LI13: If set, the controller supports + * - log pages log page. + * - returning scope of each command in + * commands supported and effects log + * page. + * - feature identifiers supported and + * effects log page. + * - NVMe-MI commands supported and + * effects log page. + * @NVME_CTRL_LPA_DA4_TELEMETRY: If set, the controller supports data + * area 4 for telemetry host-initiated and + * telemetry. */ enum nvme_id_ctrl_lpa { NVME_CTRL_LPA_SMART_PER_NS = 1 << 0, @@ -1263,14 +1317,16 @@ enum nvme_id_ctrl_lpa { NVME_CTRL_LPA_EXTENDED = 1 << 2, NVME_CTRL_LPA_TELEMETRY = 1 << 3, NVME_CTRL_LPA_PERSETENT_EVENT = 1 << 4, + NVME_CTRL_LPA_LI0_LI5_LI12_LI13 = 1 << 5, + NVME_CTRL_LPA_DA4_TELEMETRY = 1 << 6, }; /** * enum nvme_id_ctrl_avscc - Flags indicating the configuration settings for - * Admin Vendor Specific command handling. + * Admin Vendor Specific command handling. * @NVME_CTRL_AVSCC_AVS: If set, all Admin Vendor Specific Commands use the - * optional vendor specific command format with NDT and - * NDM fields. + * optional vendor specific command format with NDT and + * NDM fields. */ enum nvme_id_ctrl_avscc { NVME_CTRL_AVSCC_AVS = 1 << 0, @@ -1278,9 +1334,9 @@ enum nvme_id_ctrl_avscc { /** * enum nvme_id_ctrl_apsta - Flags indicating the attributes of the autonomous - * power state transition feature. + * power state transition feature. * @NVME_CTRL_APSTA_APST: If set, then the controller supports autonomous power - * state transitions. + * state transitions. */ enum nvme_id_ctrl_apsta { NVME_CTRL_APSTA_APST = 1 << 0, @@ -1288,11 +1344,11 @@ enum nvme_id_ctrl_apsta { /** * enum nvme_id_ctrl_rpmbs - This field indicates if the controller supports - * one or more Replay Protected Memory Blocks, from - * &struct nvme_id_ctrl.rpmbs. + * one or more Replay Protected Memory Blocks, from + * &struct nvme_id_ctrl.rpmbs. * @NVME_CTRL_RPMBS_NR_UNITS: Mask to get the value of the Number of RPMB Units * @NVME_CTRL_RPMBS_AUTH_METHOD: Mask to get the value of the Authentication Method - * @NVME_CTRL_RPMBS_TOTAL_SIZE: Mask to get the value of Total Size + * @NVME_CTRL_RPMBS_TOTAL_SIZE: Mask to get the value of Total Size * @NVME_CTRL_RPMBS_ACCESS_SIZE: Mask to get the value of Access Size */ enum nvme_id_ctrl_rpmbs { @@ -1304,10 +1360,10 @@ enum nvme_id_ctrl_rpmbs { /** * enum nvme_id_ctrl_dsto - Flags indicating the optional Device Self-test - * command or operation behaviors supported by the - * controller or NVM subsystem. + * command or operation behaviors supported by the + * controller or NVM subsystem. * @NVME_CTRL_DSTO_ONE_DST: If set, then the NVM subsystem supports only one - * device self-test operation in progress at a time. + * device self-test operation in progress at a time. */ enum nvme_id_ctrl_dsto { NVME_CTRL_DSTO_ONE_DST = 1 << 0, @@ -1315,11 +1371,11 @@ enum nvme_id_ctrl_dsto { /** * enum nvme_id_ctrl_hctm - Flags indicate the attributes of the host - * controlled thermal management feature + * controlled thermal management feature * @NVME_CTRL_HCTMA_HCTM: then the controller supports host controlled thermal - * management, and the Set Features command and Get - * Features command with the Feature Identifier field - * set to %NVME_FEAT_FID_HCTM. + * management, and the Set Features command and Get + * Features command with the Feature Identifier field + * set to %NVME_FEAT_FID_HCTM. */ enum nvme_id_ctrl_hctm { NVME_CTRL_HCTMA_HCTM = 1 << 0, @@ -1328,18 +1384,18 @@ enum nvme_id_ctrl_hctm { /** * enum nvme_id_ctrl_sanicap - Indicates attributes for sanitize operations. * @NVME_CTRL_SANICAP_CES: Crypto Erase Support. If set, then the - * controller supports the Crypto Erase sanitize operation. + * controller supports the Crypto Erase sanitize operation. * @NVME_CTRL_SANICAP_BES: Block Erase Support. If set, then the controller - * supports the Block Erase sanitize operation. + * supports the Block Erase sanitize operation. * @NVME_CTRL_SANICAP_OWS: Overwrite Support. If set, then the controller - * supports the Overwrite sanitize operation. + * supports the Overwrite sanitize operation. * @NVME_CTRL_SANICAP_NDI: No-Deallocate Inhibited. If set and the No- - * Deallocate Response Mode bit is set, then the - * controller deallocates after the sanitize - * operation even if the No-Deallocate After - * Sanitize bit is set in a Sanitize command. + * Deallocate Response Mode bit is set, then the + * controller deallocates after the sanitize + * operation even if the No-Deallocate After + * Sanitize bit is set in a Sanitize command. * @NVME_CTRL_SANICAP_NODMMAS: No-Deallocate Modifies Media After Sanitize, - * mask to extract value. + * mask to extract value. */ enum nvme_id_ctrl_sanicap { NVME_CTRL_SANICAP_CES = 1 << 0, @@ -1351,25 +1407,25 @@ enum nvme_id_ctrl_sanicap { /** * enum nvme_id_ctrl_anacap - This field indicates the capabilities associated - * with Asymmetric Namespace Access Reporting. - * @NVME_CTRL_ANACAP_OPT: If set, then the controller is able to - * report ANA Optimized state. - * @NVME_CTRL_ANACAP_NON_OPT: If set, then the controller is able to - * report ANA Non-Optimized state. + * with Asymmetric Namespace Access Reporting. + * @NVME_CTRL_ANACAP_OPT: If set, then the controller is able to + * report ANA Optimized state. + * @NVME_CTRL_ANACAP_NON_OPT: If set, then the controller is able to + * report ANA Non-Optimized state. * @NVME_CTRL_ANACAP_INACCESSIBLE: If set, then the controller is able to - * report ANA Inaccessible state. + * report ANA Inaccessible state. * @NVME_CTRL_ANACAP_PERSISTENT_LOSS: If set, then the controller is able to - * report ANA Persistent Loss state. - * @NVME_CTRL_ANACAP_CHANGE: If set, then the controller is able to - * report ANA Change state. + * report ANA Persistent Loss state. + * @NVME_CTRL_ANACAP_CHANGE: If set, then the controller is able to + * report ANA Change state. * @NVME_CTRL_ANACAP_GRPID_NO_CHG: If set, then the ANAGRPID field in the - * Identify Namespace data structure - * (&struct nvme_id_ns.anagrpid), does not - * change while the namespace is attached to - * any controller. + * Identify Namespace data structure + * (&struct nvme_id_ns.anagrpid), does not + * change while the namespace is attached to + * any controller. * @NVME_CTRL_ANACAP_GRPID_MGMT: If set, then the controller supports a - * non-zero value in the ANAGRPID field of - * the Namespace Management command. + * non-zero value in the ANAGRPID field of + * the Namespace Management command. */ enum nvme_id_ctrl_anacap { NVME_CTRL_ANACAP_OPT = 1 << 0, @@ -1383,11 +1439,11 @@ enum nvme_id_ctrl_anacap { /** * enum nvme_id_ctrl_sqes - Defines the required and maximum Submission Queue - * entry size when using the NVM Command Set. + * entry size when using the NVM Command Set. * @NVME_CTRL_SQES_MIN: Mask to get the value of the required Submission Queue - * Entry size when using the NVM Command Set. + * Entry size when using the NVM Command Set. * @NVME_CTRL_SQES_MAX: Mask to get the value of the maximum Submission Queue - * entry size when using the NVM Command Set. + * entry size when using the NVM Command Set. */ enum nvme_id_ctrl_sqes { NVME_CTRL_SQES_MIN = 0xf << 0, @@ -1396,11 +1452,11 @@ enum nvme_id_ctrl_sqes { /** * enum nvme_id_ctrl_cqes - Defines the required and maximum Completion Queue - * entry size when using the NVM Command Set. + * entry size when using the NVM Command Set. * @NVME_CTRL_CQES_MIN: Mask to get the value of the required Completion Queue - * Entry size when using the NVM Command Set. + * Entry size when using the NVM Command Set. * @NVME_CTRL_CQES_MAX: Mask to get the value of the maximum Completion Queue - * entry size when using the NVM Command Set. + * entry size when using the NVM Command Set. */ enum nvme_id_ctrl_cqes { NVME_CTRL_CQES_MIN = 0xf << 0, @@ -1409,26 +1465,28 @@ enum nvme_id_ctrl_cqes { /** * enum nvme_id_ctrl_oncs - This field indicates the optional NVM commands and - * features supported by the controller. + * features supported by the controller. * @NVME_CTRL_ONCS_COMPARE: If set, then the controller supports - * the Compare command. + * the Compare command. * @NVME_CTRL_ONCS_WRITE_UNCORRECTABLE: If set, then the controller supports - * the Write Uncorrectable command. + * the Write Uncorrectable command. * @NVME_CTRL_ONCS_DSM: If set, then the controller supports - * the Dataset Management command. + * the Dataset Management command. * @NVME_CTRL_ONCS_WRITE_ZEROES: If set, then the controller supports - * the Write Zeroes command. + * the Write Zeroes command. * @NVME_CTRL_ONCS_SAVE_FEATURES: If set, then the controller supports - * the Save field set to a non-zero value - * in the Set Features command and the - * Select field set to a non-zero value in - * the Get Features command. + * the Save field set to a non-zero value + * in the Set Features command and the + * Select field set to a non-zero value in + * the Get Features command. * @NVME_CTRL_ONCS_RESERVATIONS: If set, then the controller supports - * reservations. + * reservations. * @NVME_CTRL_ONCS_TIMESTAMP: If set, then the controller supports - * the Timestamp feature. + * the Timestamp feature. * @NVME_CTRL_ONCS_VERIFY: If set, then the controller supports - * the Verify command. + * the Verify command. + * @NVME_CTRL_ONCS_COPY: If set, then the controller supports + * the copy command. */ enum nvme_id_ctrl_oncs { NVME_CTRL_ONCS_COMPARE = 1 << 0, @@ -1439,13 +1497,14 @@ enum nvme_id_ctrl_oncs { NVME_CTRL_ONCS_RESERVATIONS = 1 << 5, NVME_CTRL_ONCS_TIMESTAMP = 1 << 6, NVME_CTRL_ONCS_VERIFY = 1 << 7, + NVME_CTRL_ONCS_COPY = 1 << 8, }; /** * enum nvme_id_ctrl_fuses - This field indicates the fused operations that the - * controller supports. + * controller supports. * @NVME_CTRL_FUSES_COMPARE_AND_WRITE: If set, then the controller supports the - * Compare and Write fused operation. + * Compare and Write fused operation. */ enum nvme_id_ctrl_fuses { NVME_CTRL_FUSES_COMPARE_AND_WRITE = 1 << 0, @@ -1453,39 +1512,44 @@ enum nvme_id_ctrl_fuses { /** * enum nvme_id_ctrl_fna - This field indicates attributes for the Format NVM - * command. + * command. * @NVME_CTRL_FNA_FMT_ALL_NAMESPACES: If set, then all namespaces in an NVM - * subsystem shall be configured with the - * same attributes and a format (excluding - * secure erase) of any namespace results in - * a format of all namespaces in an NVM - * subsystem. If cleared, then the - * controller supports format on a per - * namespace basis. + * subsystem shall be configured with the + * same attributes and a format (excluding + * secure erase) of any namespace results in + * a format of all namespaces in an NVM + * subsystem. If cleared, then the + * controller supports format on a per + * namespace basis. * @NVME_CTRL_FNA_SEC_ALL_NAMESPACES: If set, then any secure erase performed - * as part of a format operation results in - * a secure erase of all namespaces in the - * NVM subsystem. If cleared, then any - * secure erase performed as part of a - * format results in a secure erase of the - * particular namespace specified. - * @NVME_CTRL_FNA_CRYPTO_ERASE: If set, then cryptographic erase is - * supported. If cleared, then cryptographic - * erase is not supported. + * as part of a format operation results in + * a secure erase of all namespaces in the + * NVM subsystem. If cleared, then any + * secure erase performed as part of a + * format results in a secure erase of the + * particular namespace specified. + * @NVME_CTRL_FNA_CRYPTO_ERASE: If set, then cryptographic erase is + * supported. If cleared, then cryptographic + * erase is not supported. + * @NVME_CTRL_FNA_NSID_FFFFFFFF: If set, then format does not support + * nsid value set to FFFFFFFFh. If cleared, + * format supports nsid value set to + * FFFFFFFFh. */ enum nvme_id_ctrl_fna { NVME_CTRL_FNA_FMT_ALL_NAMESPACES = 1 << 0, NVME_CTRL_FNA_SEC_ALL_NAMESPACES = 1 << 1, NVME_CTRL_FNA_CRYPTO_ERASE = 1 << 2, + NVME_CTRL_FNA_NSID_FFFFFFFF = 1 << 3, }; /** - * enum nvme_id_ctrl_vwc - + * enum nvme_id_ctrl_vwc - Volatile write cache * @NVME_CTRL_VWC_PRESENT: If set, indicates a volatile write cache is present. - * If a volatile write cache is present, then the host - * controls whether the volatile write cache is enabled - * with a Set Features command specifying the value - * %NVME_FEAT_FID_VOLATILE_WC. + * If a volatile write cache is present, then the host + * controls whether the volatile write cache is enabled + * with a Set Features command specifying the value + * %NVME_FEAT_FID_VOLATILE_WC. * @NVME_CTRL_VWC_FLUSH: Mask to get the value of the flush command behavior. */ enum nvme_id_ctrl_vwc { @@ -1495,9 +1559,9 @@ enum nvme_id_ctrl_vwc { /** * enum nvme_id_ctrl_nvscc - This field indicates the configuration settings - * for NVM Vendor Specific command handling. + * for NVM Vendor Specific command handling. * @NVME_CTRL_NVSCC_FMT: If set, all NVM Vendor Specific Commands use the - * format format with NDT and NDM fields. + * format with NDT and NDM fields. */ enum nvme_id_ctrl_nvscc { NVME_CTRL_NVSCC_FMT = 1 << 0, @@ -1505,22 +1569,22 @@ enum nvme_id_ctrl_nvscc { /** * enum nvme_id_ctrl_nwpc - This field indicates the optional namespace write - * protection capabilities supported by the - * controller. + * protection capabilities supported by the + * controller. * @NVME_CTRL_NWPC_WRITE_PROTECT: If set, then the controller shall - * support the No Write Protect and - * Write Protect namespace write - * protection states and may support - * the Write Protect Until Power - * Cycle state and Permanent Write - * Protect namespace write - * protection states. + * support the No Write Protect and + * Write Protect namespace write + * protection states and may support + * the Write Protect Until Power + * Cycle state and Permanent Write + * Protect namespace write + * protection states. * @NVME_CTRL_NWPC_WRITE_PROTECT_POWER_CYCLE: If set, then the controller - * supports the Write Protect Until - * Power Cycle state. + * supports the Write Protect Until + * Power Cycle state. * @NVME_CTRL_NWPC_WRITE_PROTECT_PERMANENT: If set, then the controller - * supports the Permanent Write - * Protect state. + * supports the Permanent Write + * Protect state. */ enum nvme_id_ctrl_nwpc { NVME_CTRL_NWPC_WRITE_PROTECT = 1 << 0, @@ -1530,7 +1594,7 @@ enum nvme_id_ctrl_nwpc { /** * enum nvme_id_ctrl_sgls - This field indicates if SGLs are supported for the - * NVM Command Set and the particular SGL types supported. + * NVM Command Set and the particular SGL types supported. * @NVME_CTRL_SGLS_SUPPORTED: * @NVME_CTRL_SGLS_KEYED: * @NVME_CTRL_SGLS_BIT_BUCKET: @@ -1553,10 +1617,10 @@ enum nvme_id_ctrl_sgls { /** * enum nvme_id_ctrl_fcatt - This field indicates attributes of the controller - * that are specific to NVMe over Fabrics. + * that are specific to NVMe over Fabrics. * @NVME_CTRL_FCATT_DYNAMIC: If cleared, then the NVM subsystem uses a dynamic - * controller model. If set, then the NVM subsystem - * uses a static controller model. + * controller model. If set, then the NVM subsystem + * uses a static controller model. */ enum nvme_id_ctrl_fcatt { NVME_CTRL_FCATT_DYNAMIC = 1 << 0, @@ -1564,10 +1628,10 @@ enum nvme_id_ctrl_fcatt { /** * enum nvme_id_ctrl_ofcs - Indicate whether the controller supports optional - * fabric commands. + * fabric commands. * @NVME_CTRL_OFCS_DISCONNECT: If set, then the controller supports the - * Disconnect command and deletion of individual - * I/O Queues. + * Disconnect command and deletion of individual + * I/O Queues. */ enum nvme_id_ctrl_ofcs { NVME_CTRL_OFCS_DISCONNECT = 1 << 0, @@ -1576,9 +1640,9 @@ enum nvme_id_ctrl_ofcs { /** * struct nvme_lbaf - LBA Format Data Structure * @ms: Metadata Size indicates the number of metadata bytes provided per LBA - * based on the LBA Data Size indicated. + * based on the LBA Data Size indicated. * @ds: LBA Data Size indicates the LBA data size supported, reported as a - * power of two. + * power of two. * @rp: Relative Performance, see &enum nvme_lbaf_rp. */ struct nvme_lbaf { @@ -1589,14 +1653,14 @@ struct nvme_lbaf { /** * enum nvme_lbaf_rp - This field indicates the relative performance of the LBA - * format indicated relative to other LBA formats supported - * by the controller. + * format indicated relative to other LBA formats supported + * by the controller. * @NVME_LBAF_RP_BEST: Best performance * @NVME_LBAF_RP_BETTER: Better performance * @NVME_LBAF_RP_GOOD: Good performance * @NVME_LBAF_RP_DEGRADED: Degraded performance * @NVME_LBAF_RP_MASK: Mask to get the relative performance value from the - * field + * field */ enum nvme_lbaf_rp { NVME_LBAF_RP_BEST = 0, @@ -1609,97 +1673,97 @@ enum nvme_lbaf_rp { /** * struct nvme_id_ns - Identify Namespace data structure * @nsze: Namespace Size indicates the total size of the namespace in - * logical blocks. The number of logical blocks is based on the - * formatted LBA size. + * logical blocks. The number of logical blocks is based on the + * formatted LBA size. * @ncap: Namespace Capacity indicates the maximum number of logical blocks - * that may be allocated in the namespace at any point in time. The - * number of logical blocks is based on the formatted LBA size. + * that may be allocated in the namespace at any point in time. The + * number of logical blocks is based on the formatted LBA size. * @nuse: Namespace Utilization indicates the current number of logical - * blocks allocated in the namespace. This field is smaller than or - * equal to the Namespace Capacity. The number of logical blocks is - * based on the formatted LBA size. + * blocks allocated in the namespace. This field is smaller than or + * equal to the Namespace Capacity. The number of logical blocks is + * based on the formatted LBA size. * @nsfeat: Namespace Features, see &enum nvme_id_nsfeat. * @nlbaf: Number of LBA Formats defines the number of supported LBA data - * size and metadata size combinations supported by the namespace - * and the highest possible index to &struct nvme_id_ns.lbaf. + * size and metadata size combinations supported by the namespace + * and the highest possible index to &struct nvme_id_ns.lbaf. * @flbas: Formatted LBA Size, see &enum nvme_id_ns_flbas. - * @mc: Metadata Capabilities, see &enum nvme_id_ns_mc. + * @mc: Metadata Capabilities, see &enum nvme_id_ns_mc. * @dpc: End-to-end Data Protection Capabilities, see - * &enum nvme_id_ns_dpc. + * &enum nvme_id_ns_dpc. * @dps: End-to-end Data Protection Type Settings, see - * &enum nvme_id_ns_dps. + * &enum nvme_id_ns_dps. * @nmic: Namespace Multi-path I/O and Namespace Sharing Capabilities, see - * &enum nvme_id_ns_nmic. + * &enum nvme_id_ns_nmic. * @rescap: Reservation Capabilities, see &enum nvme_id_ns_rescap. * @fpi: Format Progress Indicator, see &enum nvme_nd_ns_fpi. * @dlfeat: Deallocate Logical Block Features, see &enum nvme_id_ns_dlfeat. * @nawun: Namespace Atomic Write Unit Normal indicates the - * namespace specific size of the write operation guaranteed to be - * written atomically to the NVM during normal operation. + * namespace specific size of the write operation guaranteed to be + * written atomically to the NVM during normal operation. * @nawupf: Namespace Atomic Write Unit Power Fail indicates the - * namespace specific size of the write operation guaranteed to be - * written atomically to the NVM during a power fail or error - * condition. + * namespace specific size of the write operation guaranteed to be + * written atomically to the NVM during a power fail or error + * condition. * @nacwu: Namespace Atomic Compare & Write Unit indicates the namespace - * specific size of the write operation guaranteed to be written - * atomically to the NVM for a Compare and Write fused command. + * specific size of the write operation guaranteed to be written + * atomically to the NVM for a Compare and Write fused command. * @nabsn: Namespace Atomic Boundary Size Normal indicates the atomic - * boundary size for this namespace for the NAWUN value. This field - * is specified in logical blocks. + * boundary size for this namespace for the NAWUN value. This field + * is specified in logical blocks. * @nabo: Namespace Atomic Boundary Offset indicates the LBA on this - * namespace where the first atomic boundary starts. + * namespace where the first atomic boundary starts. * @nabspf: Namespace Atomic Boundary Size Power Fail indicates the atomic - * boundary size for this namespace specific to the Namespace Atomic - * Write Unit Power Fail value. This field is specified in logical - * blocks. + * boundary size for this namespace specific to the Namespace Atomic + * Write Unit Power Fail value. This field is specified in logical + * blocks. * @noiob: Namespace Optimal I/O Boundary indicates the optimal I/O boundary - * for this namespace. This field is specified in logical blocks. - * The host should construct Read and Write commands that do not - * cross the I/O boundary to achieve optimal performance. + * for this namespace. This field is specified in logical blocks. + * The host should construct Read and Write commands that do not + * cross the I/O boundary to achieve optimal performance. * @nvmcap: NVM Capacity indicates the total size of the NVM allocated to - * this namespace. The value is in bytes. + * this namespace. The value is in bytes. * @npwg: Namespace Preferred Write Granularity indicates the smallest - * recommended write granularity in logical blocks for this - * namespace. This is a 0's based value. + * recommended write granularity in logical blocks for this + * namespace. This is a 0's based value. * @npwa: Namespace Preferred Write Alignment indicates the recommended - * write alignment in logical blocks for this namespace. This is a - * 0's based value. + * write alignment in logical blocks for this namespace. This is a + * 0's based value. * @npdg: Namespace Preferred Deallocate Granularity indicates the - * recommended granularity in logical blocks for the Dataset - * Management command with the Attribute - Deallocate bit. + * recommended granularity in logical blocks for the Dataset + * Management command with the Attribute - Deallocate bit. * @npda: Namespace Preferred Deallocate Alignment indicates the - * recommended alignment in logical blocks for the Dataset - * Management command with the Attribute - Deallocate bit + * recommended alignment in logical blocks for the Dataset + * Management command with the Attribute - Deallocate bit * @nows: Namespace Optimal Write Size indicates the size in logical blocks - * for optimal write performance for this namespace. This is a 0's - * based value. + * for optimal write performance for this namespace. This is a 0's + * based value. * @mssrl: Maximum Single Source Range Length indicates the maximum number - * of logical blocks that may be specified in each valid Source Range - * field of a Copy command. + * of logical blocks that may be specified in each valid Source Range + * field of a Copy command. * @mcl: Maximum Copy Length indicates the maximum number of logical - * blocks that may be specified in a Copy command. + * blocks that may be specified in a Copy command. * @msrc: Maximum Source Range Count indicates the maximum number of Source - * Range entries that may be used to specify source data in a Copy - * command. This is a 0’s based value. + * Range entries that may be used to specify source data in a Copy + * command. This is a 0’s based value. * @rsvd81: Reserved * @nulbaf: Number of Unique Capability LBA Formats defines the number of - * supported user data size and metadata size combinations supported - * by the namespace that may not share the same capabilities. LBA - * formats shall be allocated in order and packed sequentially. + * supported user data size and metadata size combinations supported + * by the namespace that may not share the same capabilities. LBA + * formats shall be allocated in order and packed sequentially. * @rsvd83: Reserved * @anagrpid: ANA Group Identifier indicates the ANA Group Identifier of the - * ANA group of which the namespace is a member. + * ANA group of which the namespace is a member. * @rsvd96: Reserved * @nsattr: Namespace Attributes, see &enum nvme_id_ns_attr. * @nvmsetid: NVM Set Identifier indicates the NVM Set with which this - * namespace is associated. + * namespace is associated. * @endgid: Endurance Group Identifier indicates the Endurance Group with - * which this namespace is associated. + * which this namespace is associated. * @nguid: Namespace Globally Unique Identifier contains a 128-bit value - * that is globally unique and assigned to the namespace when the - * namespace is created. This field remains fixed throughout the - * life of the namespace and is preserved across namespace and - * controller operations + * that is globally unique and assigned to the namespace when the + * namespace is created. This field remains fixed throughout the + * life of the namespace and is preserved across namespace and + * controller operations * @eui64: IEEE Extended Unique Identifier contains a 64-bit IEEE Extended * Unique Identifier (EUI-64) that is globally unique and assigned * to the namespace when the namespace is created. This field @@ -1757,24 +1821,24 @@ struct nvme_id_ns { /** * enum nvme_id_nsfeat - This field defines features of the namespace. * @NVME_NS_FEAT_THIN: If set, indicates that the namespace supports thin - * provisioning. Specifically, the Namespace Capacity - * reported may be less than the Namespace Size. + * provisioning. Specifically, the Namespace Capacity + * reported may be less than the Namespace Size. * @NVME_NS_FEAT_NATOMIC: If set, indicates that the fields NAWUN, NAWUPF, and - * NACWU are defined for this namespace and should be - * used by the host for this namespace instead of the - * AWUN, AWUPF, and ACWU fields in the Identify - * Controller data structure. + * NACWU are defined for this namespace and should be + * used by the host for this namespace instead of the + * AWUN, AWUPF, and ACWU fields in the Identify + * Controller data structure. * @NVME_NS_FEAT_DULBE: If set, indicates that the controller supports the - * Deallocated or Unwritten Logical Block error for - * this namespace. + * Deallocated or Unwritten Logical Block error for + * this namespace. * @NVME_NS_FEAT_ID_REUSE: If set, indicates that the value in the NGUID field - * for this namespace, if non- zero, is never reused by - * the controller and that the value in the EUI64 field - * for this namespace, if non-zero, is never reused by - * the controller. + * for this namespace, if non- zero, is never reused by + * the controller and that the value in the EUI64 field + * for this namespace, if non-zero, is never reused by + * the controller. * @NVME_NS_FEAT_IO_OPT: If set, indicates that the fields NPWG, NPWA, NPDG, - * NPDA, and NOWS are defined for this namespace and - * should be used by the host for I/O optimization + * NPDA, and NOWS are defined for this namespace and + * should be used by the host for I/O optimization */ enum nvme_id_nsfeat { NVME_NS_FEAT_THIN = 1 << 0, @@ -1786,8 +1850,8 @@ enum nvme_id_nsfeat { /** * enum nvme_id_ns_flbas - This field indicates the LBA data size & metadata - * size combination that the namespace has been - * formatted with + * size combination that the namespace has been + * formatted with * @NVME_NS_FLBAS_LOWER_MASK: Mask to get the index of one of the supported * LBA Formats's least significant * 4bits indicated in @@ -1798,7 +1862,7 @@ enum nvme_id_nsfeat { * extended data LBA. If cleared, indicates that all * of the metadata for a command is transferred as a * separate contiguous buffer of data. - * @NVME_NS_FLBAS_HIGHER_MASK: Mask to get the index of one of + * @NVME_NS_FLBAS_HIGHER_MASK: Mask to get the index of one of * the supported LBA Formats's most significant * 2bits indicated in * :c:type:`struct nvme_id_ns `.lbaf. @@ -1809,13 +1873,25 @@ enum nvme_id_ns_flbas { NVME_NS_FLBAS_HIGHER_MASK = 3 << 5, }; +/** + * enum nvme_nvm_id_ns_elbaf - This field indicates the extended LBA format + * @NVME_NVM_ELBAF_STS_MASK: Mask to get the storage tag size used to determine + * the variable-sized storage tag/reference tag fields + * @NVME_NVM_ELBAF_PIF_MASK: Mask to get the protection information format for + * the extended LBA format. + */ +enum nvme_nvm_id_ns_elbaf { + NVME_NVM_ELBAF_STS_MASK = 127 << 0, + NVME_NVM_ELBAF_PIF_MASK = 3 << 7, +}; + /** * enum nvme_id_ns_mc - This field indicates the capabilities for metadata. * @NVME_NS_MC_EXTENDED: If set, indicates the namespace supports the metadata - * being transferred as part of a separate buffer that is - * specified in the Metadata Pointer. + * being transferred as part of a separate buffer that is + * specified in the Metadata Pointer. * @NVME_NS_MC_SEPARATE: If set, indicates that the namespace supports the - * metadata being transferred as part of an extended data LBA. + * metadata being transferred as part of an extended data LBA. */ enum nvme_id_ns_mc { NVME_NS_MC_EXTENDED = 1 << 0, @@ -1824,19 +1900,19 @@ enum nvme_id_ns_mc { /** * enum nvme_id_ns_dpc - This field indicates the capabilities for the - * end-to-end data protection feature. + * end-to-end data protection feature. * @NVME_NS_DPC_PI_TYPE1: If set, indicates that the namespace supports - * Protection Information Type 1. + * Protection Information Type 1. * @NVME_NS_DPC_PI_TYPE2: If set, indicates that the namespace supports - * Protection Information Type 2. + * Protection Information Type 2. * @NVME_NS_DPC_PI_TYPE3: If set, indicates that the namespace supports - * Protection Information Type 3. + * Protection Information Type 3. * @NVME_NS_DPC_PI_FIRST: If set, indicates that the namespace supports - * protection information transferred as the first eight - * bytes of metadata. + * protection information transferred as the first eight + * bytes of metadata. * @NVME_NS_DPC_PI_LAST: If set, indicates that the namespace supports - * protection information transferred as the last eight - * bytes of metadata. + * protection information transferred as the last eight + * bytes of metadata. */ enum nvme_id_ns_dpc { NVME_NS_DPC_PI_TYPE1 = 1 << 0, @@ -1848,15 +1924,15 @@ enum nvme_id_ns_dpc { /** * enum nvme_id_ns_dps - This field indicates the Type settings for the - * end-to-end data protection feature. + * end-to-end data protection feature. * @NVME_NS_DPS_PI_NONE: Protection information is not enabled * @NVME_NS_DPS_PI_TYPE1: Protection information is enabled, Type 1 * @NVME_NS_DPS_PI_TYPE2: Protection information is enabled, Type 2 * @NVME_NS_DPS_PI_TYPE3: Protection information is enabled, Type 3 * @NVME_NS_DPS_PI_MASK: Mask to get the value of the PI type * @NVME_NS_DPS_PI_FIRST: If set, indicates that the protection information, if - * enabled, is transferred as the first eight bytes of - * metadata. + * enabled, is transferred as the first eight bytes of + * metadata. */ enum nvme_id_ns_dps { NVME_NS_DPS_PI_NONE = 0, @@ -1869,9 +1945,9 @@ enum nvme_id_ns_dps { /** * enum nvme_id_ns_nmic - This field specifies multi-path I/O and namespace - * sharing capabilities of the namespace. + * sharing capabilities of the namespace. * @NVME_NS_NMIC_SHARED: If set, then the namespace may be attached to two or - * more controllers in the NVM subsystem concurrently + * more controllers in the NVM subsystem concurrently */ enum nvme_id_ns_nmic { NVME_NS_NMIC_SHARED = 1 << 0, @@ -1879,23 +1955,23 @@ enum nvme_id_ns_nmic { /** * enum nvme_id_ns_rescap - This field indicates the reservation capabilities - * of the namespace. + * of the namespace. * @NVME_NS_RESCAP_PTPL: If set, indicates that the namespace supports the - * Persist Through Power Loss capability. - * @NVME_NS_RESCAP_WE: If set, indicates that the namespace supports the - * Write Exclusive reservation type. - * @NVME_NS_RESCAP_EA: If set, indicates that the namespace supports the - * Exclusive Access reservation type. + * Persist Through Power Loss capability. + * @NVME_NS_RESCAP_WE: If set, indicates that the namespace supports the + * Write Exclusive reservation type. + * @NVME_NS_RESCAP_EA: If set, indicates that the namespace supports the + * Exclusive Access reservation type. * @NVME_NS_RESCAP_WERO: If set, indicates that the namespace supports the - * Write Exclusive - Registrants Only reservation type. + * Write Exclusive - Registrants Only reservation type. * @NVME_NS_RESCAP_EARO: If set, indicates that the namespace supports the - * Exclusive Access - Registrants Only reservation type. + * Exclusive Access - Registrants Only reservation type. * @NVME_NS_RESCAP_WEAR: If set, indicates that the namespace supports the - * Write Exclusive - All Registrants reservation type. + * Write Exclusive - All Registrants reservation type. * @NVME_NS_RESCAP_EAAR: If set, indicates that the namespace supports the - * Exclusive Access - All Registrants reservation type. + * Exclusive Access - All Registrants reservation type. * @NVME_NS_RESCAP_IEK_13: If set, indicates that Ignore Existing Key is used - * as defined in revision 1.3 or later of this specification. + * as defined in revision 1.3 or later of this specification. */ enum nvme_id_ns_rescap { NVME_NS_RESCAP_PTPL = 1 << 0, @@ -1910,11 +1986,11 @@ enum nvme_id_ns_rescap { /** * enum nvme_nd_ns_fpi - If a format operation is in progress, this field - * indicates the percentage of the namespace that remains - * to be formatted. + * indicates the percentage of the namespace that remains + * to be formatted. * @NVME_NS_FPI_REMAINING: Mask to get the format percent remaining value * @NVME_NS_FPI_SUPPORTED: If set, indicates that the namespace supports the - * Format Progress Indicator defined for the field. + * Format Progress Indicator defined for the field. */ enum nvme_nd_ns_fpi { NVME_NS_FPI_REMAINING = 0x7f << 0, @@ -1923,22 +1999,22 @@ enum nvme_nd_ns_fpi { /** * enum nvme_id_ns_dlfeat - This field indicates information about features - * that affect deallocating logical blocks for this - * namespace. - * @NVME_NS_DLFEAT_RB: Mask to get the value of the read behavior - * @NVME_NS_DLFEAT_RB_NR: Read behvaior is not reported - * @NVME_NS_DLFEAT_RB_ALL_0S: A deallocated logical block returns all bytes + * that affect deallocating logical blocks for this + * namespace. + * @NVME_NS_DLFEAT_RB: Mask to get the value of the read behavior + * @NVME_NS_DLFEAT_RB_NR: Read behvaior is not reported + * @NVME_NS_DLFEAT_RB_ALL_0S: A deallocated logical block returns all bytes * cleared to 0h. - * @NVME_NS_DLFEAT_RB_ALL_FS: A deallocated logical block returns all bytes - * set to FFh. + * @NVME_NS_DLFEAT_RB_ALL_FS: A deallocated logical block returns all bytes + * set to FFh. * @NVME_NS_DLFEAT_WRITE_ZEROES: If set, indicates that the controller supports - * the Deallocate bit in the Write Zeroes command - * for this namespace. - * @NVME_NS_DLFEAT_CRC_GUARD: If set, indicates that the Guard field for - * deallocated logical blocks that contain - * protection information is set to the CRC for - * the value read from the deallocated logical - * block and its metadata + * the Deallocate bit in the Write Zeroes command + * for this namespace. + * @NVME_NS_DLFEAT_CRC_GUARD: If set, indicates that the Guard field for + * deallocated logical blocks that contain + * protection information is set to the CRC for + * the value read from the deallocated logical + * block and its metadata */ enum nvme_id_ns_dlfeat { NVME_NS_DLFEAT_RB = 7 << 0, @@ -1952,22 +2028,22 @@ enum nvme_id_ns_dlfeat { /** * enum nvme_id_ns_attr - Specifies attributes of the namespace. * @NVME_NS_NSATTR_WRITE_PROTECTED: If set, then the namespace is currently - * write protected and all write access to the - * namespace shall fail. + * write protected and all write access to the + * namespace shall fail. */ enum nvme_id_ns_attr { NVME_NS_NSATTR_WRITE_PROTECTED = 1 << 0 }; /** - * struct nvme_ns_id_desc - + * struct nvme_ns_id_desc - Namespace identifier type descriptor * @nidt: Namespace Identifier Type, see &enum nvme_ns_id_desc_nidt * @nidl: Namespace Identifier Length contains the length in bytes of the - * &struct nvme_id_ns.nid. + * &struct nvme_id_ns.nid. * @rsvd: Reserved * @nid: Namespace Identifier contains a value that is globally unique and - * assigned to the namespace when the namespace is created. The length - * is defined in &struct nvme_id_ns.nidl. + * assigned to the namespace when the namespace is created. The length + * is defined in &struct nvme_id_ns.nidl. */ struct nvme_ns_id_desc { __u8 nidt; @@ -1979,12 +2055,12 @@ struct nvme_ns_id_desc { /** * enum nvme_ns_id_desc_nidt - Known namespace identifier types * @NVME_NIDT_EUI64: IEEE Extended Unique Identifier, the NID field contains a - * copy of the EUI64 field in the struct nvme_id_ns.eui64. + * copy of the EUI64 field in the struct nvme_id_ns.eui64. * @NVME_NIDT_NGUID: Namespace Globally Unique Identifier, the NID field - * contains a copy of the NGUID field in struct nvme_id_ns.nguid. + * contains a copy of the NGUID field in struct nvme_id_ns.nguid. * @NVME_NIDT_UUID: The NID field contains a 128-bit Universally Unique - * Identifier (UUID) as specified in RFC 4122. - * @NVME_NIDT_CSI: The NID field contains the command set indentifier. + * Identifier (UUID) as specified in RFC 4122. + * @NVME_NIDT_CSI: The NID field contains the command set identifier. */ enum nvme_ns_id_desc_nidt { NVME_NIDT_EUI64 = 1, @@ -2026,7 +2102,7 @@ struct nvme_nvmset_attr { }; /** - * struct nvme_id_nvmset_list - + * struct nvme_id_nvmset_list - NVM set list * @nid: Nvmset id * @rsvd1: Reserved * @ent: nvmset id list @@ -2038,10 +2114,10 @@ struct nvme_id_nvmset_list { }; /** - * struct nvme_id_independent_id_ns - + * struct nvme_id_independent_id_ns - Identify - I/O Command Set Independent Identify Namespace Data Structure * @nsfeat: common namespace features * @nmic: Namespace Multi-path I/O and Namespace - * Sharing Capabilities + * Sharing Capabilities * @rescap: Reservation Capabilities * @fpi: Format Progress Indicator * @anagrpid: ANA Group Identifier @@ -2067,7 +2143,7 @@ struct nvme_id_independent_id_ns { }; /** - * struct nvme_id_ns_granularity_desc - + * struct nvme_id_ns_granularity_desc - Namespace Granularity Descriptor * @nszegran: Namespace Size Granularity * @ncapgran: Namespace Capacity Granularity */ @@ -2077,7 +2153,7 @@ struct nvme_id_ns_granularity_desc { }; /** - * struct nvme_id_ns_granularity_list - + * struct nvme_id_ns_granularity_list - Namespace Granularity List * @attributes: Namespace Granularity Attributes * @num_descriptors: Number of Descriptors * @rsvd5: reserved @@ -2093,7 +2169,7 @@ struct nvme_id_ns_granularity_list { }; /** - * struct nvme_id_uuid_list_entry - + * struct nvme_id_uuid_list_entry - UUID List Entry * @header: UUID Lists Entry Header * @rsvd1: reserved * @uuid: 128-bit Universally Unique Identifier @@ -2105,7 +2181,7 @@ struct nvme_id_uuid_list_entry { }; /** - * enum nvme_id_uuid - + * enum nvme_id_uuid - Identifier Association * @NVME_ID_UUID_HDR_ASSOCIATION_MASK: * @NVME_ID_UUID_ASSOCIATION_NONE: * @NVME_ID_UUID_ASSOCIATION_VENDOR: @@ -2119,7 +2195,7 @@ enum nvme_id_uuid { }; /** - * struct nvme_id_uuid_list - + * struct nvme_id_uuid_list - UUID list * @rsvd0: reserved * @entry: UUID list entry */ @@ -2129,7 +2205,7 @@ struct nvme_id_uuid_list { }; /** - * struct nvme_ctrl_list - + * struct nvme_ctrl_list - Controller List * @num: Number of Identifiers * @identifier: NVM subsystem unique controller identifier */ @@ -2139,7 +2215,7 @@ struct nvme_ctrl_list { }; /** - * struct nvme_ns_list - + * struct nvme_ns_list - Namespace List * @ns: Namespace Identifier */ struct nvme_ns_list { @@ -2147,7 +2223,7 @@ struct nvme_ns_list { }; /** - * struct nvme_id_ctrl_nvm - + * struct nvme_id_ctrl_nvm - I/O Command Set Specific Identify Controller data structure * @vsl: Verify Size Limit * @wzsl: Write Zeroes Size Limit * @wusl: Write Uncorrectable Size Limit @@ -2157,17 +2233,17 @@ struct nvme_ns_list { * @rsvd16: reserved */ struct nvme_id_ctrl_nvm { - __u8 vsl; - __u8 wzsl; - __u8 wusl; - __u8 dmrl; - __u32 dmrsl; - __u64 dmsl; - __u8 rsvd16[4080]; + __u8 vsl; + __u8 wzsl; + __u8 wusl; + __u8 dmrl; + __u32 dmrsl; + __u64 dmsl; + __u8 rsvd16[4080]; }; /** - * struct nvme_nvm_id_ns - + * struct nvme_nvm_id_ns - NVME Command Set I/O Command Set Specific Identify Namespace Data Structure * @lbstm: Logical Block Storage Tag Mask * @pic: Protection Information Capabilities * @rsvd9: Reserved @@ -2183,7 +2259,7 @@ struct nvme_nvm_id_ns { }; /** - * struct nvme_zns_lbafe - + * struct nvme_zns_lbafe - LBA Format Extension Data Structure * @zsze: Zone Size * @zdes: Zone Descriptor Extension Size * @rsvd9: reserved @@ -2195,8 +2271,7 @@ struct nvme_zns_lbafe { }; /** - * struct nvme_zns_id_ns - Zoned Namespace Command Set Specific - * Identify Namespace Data Structure + * struct nvme_zns_id_ns - Zoned Namespace Command Set Specific Identify Namespace Data Structure * @zoc: Zone Operation Characteristics * @ozcs: Optional Zoned Command Support * @mar: Maximum Active Resources @@ -2215,7 +2290,7 @@ struct nvme_zns_lbafe { * @zrwacap: ZRWA Capability * @rsvd53: Reserved * @lbafe: LBA Format Extension - * @vs: Vendor Specific + * @vs: Vendor Specific */ struct nvme_zns_id_ns { __le16 zoc; @@ -2240,9 +2315,9 @@ struct nvme_zns_id_ns { }; /** - * struct nvme_zns_id_ctrl - - * @zasl: - * @rsvd1: Reserved + * struct nvme_zns_id_ctrl - I/O Command Set Specific Identify Controller Data Structure for the Zoned Namespace Command Set + * @zasl: Zone Append Size Limit + * @rsvd1: Reserved */ struct nvme_zns_id_ctrl { __u8 zasl; @@ -2250,7 +2325,7 @@ struct nvme_zns_id_ctrl { }; /** - * struct nvme_primary_ctrl_cap - + * struct nvme_primary_ctrl_cap - Identify - Controller Capabilities Structure * @cntlid: Controller Identifier * @portid: Port Identifier * @crt: Controller Resource Types @@ -2292,7 +2367,7 @@ struct nvme_primary_ctrl_cap { }; /** - * struct nvme_secondary_ctrl - + * struct nvme_secondary_ctrl - Secondary Controller Entry * @scid: Secondary Controller Identifier * @pcid: Primary Controller Identifier * @scs: Secondary Controller State @@ -2314,7 +2389,7 @@ struct nvme_secondary_ctrl { }; /** - * struct nvme_secondary_ctrl_list - + * struct nvme_secondary_ctrl_list - Secondary Controller List * @num: Number of Identifiers * @rsvd: Reserved * @sc_entry: Secondary Controller Entry @@ -2352,7 +2427,7 @@ struct nvme_id_domain_attr { }; /** - * struct nvme_id_domain_list - + * struct nvme_id_domain_list - Domain List * @num: Number of domain attributes * @rsvd: Reserved * @domain_attr: List of domain attributes @@ -2364,7 +2439,7 @@ struct nvme_id_domain_list { }; /** - * struct nvme_id_endurance_group_list - + * struct nvme_id_endurance_group_list - Endurance Group List * @num: Number of Identifiers * @identifier: Endurance Group Identifier */ @@ -2374,7 +2449,7 @@ struct nvme_id_endurance_group_list { }; /** - * struct nvme_supported_log_pages - + * struct nvme_supported_log_pages - Supported Log Pages - Log * @lid_support: Log Page Identifier Supported * * Supported Log Pages (Log Identifier 00h) @@ -2386,62 +2461,62 @@ struct nvme_supported_log_pages { /** * struct nvme_error_log_page - Error Information Log Entry (Log Identifier 01h) * @error_count: Error Count: a 64-bit incrementing error count, - * indicating a unique identifier for this error. The error - * count starts at %1h, is incremented for each unique error - * log entry, and is retained across power off conditions. - * A value of %0h indicates an invalid entry; this value - * is used when there are lost entries or when there are - * fewer errors than the maximum number of entries the - * controller supports. If the value of this field is - * %FFFFFFFFh, then the field shall be set to 1h when - * incremented (i.e., rolls over to %1h). Prior to NVMe - * 1.4, processing of incrementing beyond %FFFFFFFFh is - * unspecified. + * indicating a unique identifier for this error. The error + * count starts at %1h, is incremented for each unique error + * log entry, and is retained across power off conditions. + * A value of %0h indicates an invalid entry; this value + * is used when there are lost entries or when there are + * fewer errors than the maximum number of entries the + * controller supports. If the value of this field is + * %FFFFFFFFh, then the field shall be set to 1h when + * incremented (i.e., rolls over to %1h). Prior to NVMe + * 1.4, processing of incrementing beyond %FFFFFFFFh is + * unspecified. * @sqid: Submission Queue ID: indicates the Submission Queue - * Identifier of the command that the error information is - * associated with. If the error is not specific to - * a particular command, then this field shall be set to - * %FFFFh. + * Identifier of the command that the error information is + * associated with. If the error is not specific to + * a particular command, then this field shall be set to + * %FFFFh. * @cmdid: Command ID: indicates the Command Identifier of the - * command that the error is associated with. If the error - * is not specific to a particular command, then this field - * shall be set to %FFFFh. + * command that the error is associated with. If the error + * is not specific to a particular command, then this field + * shall be set to %FFFFh. * @status_field: Bits 15-1: Status Field: indicates the Status Field for - * the command that completed. If the error is not specific - * to a particular command, then this field reports the most - * applicable status value. - * Bit 0: Phase Tag: may indicate the Phase Tag posted for - * the command. + * the command that completed. If the error is not specific + * to a particular command, then this field reports the most + * applicable status value. + * Bit 0: Phase Tag: may indicate the Phase Tag posted for + * the command. * @parm_error_location: Parameter Error Location: indicates the byte and bit of - * the command parameter that the error is associated with, - * if applicable. If the parameter spans multiple bytes or - * bits, then the location indicates the first byte and bit - * of the parameter. - * Bits 10-8: Bit in command that contained the error. - * Valid values are 0 to 7. + * the command parameter that the error is associated with, + * if applicable. If the parameter spans multiple bytes or + * bits, then the location indicates the first byte and bit + * of the parameter. + * Bits 10-8: Bit in command that contained the error. + * Valid values are 0 to 7. * Bits 7-0: Byte in command that contained the error. - * Valid values are 0 to 63. + * Valid values are 0 to 63. * @lba: LBA: This field indicates the first LBA that experienced - * the error condition, if applicable. + * the error condition, if applicable. * @nsid: Namespace: This field indicates the NSID of the namespace - * that the error is associated with, if applicable. + * that the error is associated with, if applicable. * @vs: Vendor Specific Information Available: If there is - * additional vendor specific error information available, - * this field provides the log page identifier associated - * with that page. A value of %0h indicates that no additional - * information is available. Valid values are in the range - * of %80h to %FFh. + * additional vendor specific error information available, + * this field provides the log page identifier associated + * with that page. A value of %0h indicates that no additional + * information is available. Valid values are in the range + * of %80h to %FFh. * @trtype: Transport Type (TRTYPE): indicates the Transport Type of - * the transport associated with the error. The values in - * this field are the same as the TRTYPE values in the - * Discovery Log Page Entry. If the error is not transport - * related, this field shall be cleared to %0h. If the error - * is transport related, this field shall be set to the type - * of the transport - see &enum nvme_trtype. + * the transport associated with the error. The values in + * this field are the same as the TRTYPE values in the + * Discovery Log Page Entry. If the error is not transport + * related, this field shall be cleared to %0h. If the error + * is transport related, this field shall be set to the type + * of the transport - see &enum nvme_trtype. * @rsvd: Reserved * @cs: Command Specific Information: This field contains command - * specific information. If used, the command definition - * specifies the information returned. + * specific information. If used, the command definition + * specifies the information returned. * @trtype_spec_info: Transport Type Specific Information * @rsvd2: Reserved */ @@ -2461,11 +2536,6 @@ struct nvme_error_log_page { __u8 rsvd2[22]; }; -/** - * enum nvme_err_pel - - * @NVME_ERR_PEL_BYTE_MASK: - * @NVME_ERR_PEL_BIT_MASK: - */ enum nvme_err_pel { NVME_ERR_PEL_BYTE_MASK = 0xf, NVME_ERR_PEL_BIT_MASK = 0x70, @@ -2473,153 +2543,153 @@ enum nvme_err_pel { /** * struct nvme_smart_log - SMART / Health Information Log (Log Identifier 02h) - * @critical_warning: This field indicates critical warnings for the state - * of the controller. Critical warnings may result in an - * asynchronous event notification to the host. Bits in - * this field represent the current associated state and - * are not persistent (see &enum nvme_smart_crit). + * @critical_warning: This field indicates critical warnings for the state + * of the controller. Critical warnings may result in an + * asynchronous event notification to the host. Bits in + * this field represent the current associated state and + * are not persistent (see &enum nvme_smart_crit). * @temperature: Composite Temperature: Contains a value corresponding - * to a temperature in Kelvins that represents the current - * composite temperature of the controller and namespace(s) - * associated with that controller. The manner in which - * this value is computed is implementation specific and - * may not represent the actual temperature of any physical - * point in the NVM subsystem. Warning and critical - * overheating composite temperature threshold values are - * reported by the WCTEMP and CCTEMP fields in the Identify - * Controller data structure. + * to a temperature in Kelvins that represents the current + * composite temperature of the controller and namespace(s) + * associated with that controller. The manner in which + * this value is computed is implementation specific and + * may not represent the actual temperature of any physical + * point in the NVM subsystem. Warning and critical + * overheating composite temperature threshold values are + * reported by the WCTEMP and CCTEMP fields in the Identify + * Controller data structure. * @avail_spare: Available Spare: Contains a normalized percentage (0% - * to 100%) of the remaining spare capacity available. + * to 100%) of the remaining spare capacity available. * @spare_thresh: Available Spare Threshold: When the Available Spare - * falls below the threshold indicated in this field, an - * asynchronous event completion may occur. The value is - * indicated as a normalized percentage (0% to 100%). - * The values 101 to 255 are reserved. + * falls below the threshold indicated in this field, an + * asynchronous event completion may occur. The value is + * indicated as a normalized percentage (0% to 100%). + * The values 101 to 255 are reserved. * @percent_used: Percentage Used: Contains a vendor specific estimate - * of the percentage of NVM subsystem life used based on - * the actual usage and the manufacturer's prediction of - * NVM life. A value of 100 indicates that the estimated - * endurance of the NVM in the NVM subsystem has been - * consumed, but may not indicate an NVM subsystem failure. - * The value is allowed to exceed 100. Percentages greater - * than 254 shall be represented as 255. This value shall - * be updated once per power-on hour (when the controller - * is not in a sleep state). + * of the percentage of NVM subsystem life used based on + * the actual usage and the manufacturer's prediction of + * NVM life. A value of 100 indicates that the estimated + * endurance of the NVM in the NVM subsystem has been + * consumed, but may not indicate an NVM subsystem failure. + * The value is allowed to exceed 100. Percentages greater + * than 254 shall be represented as 255. This value shall + * be updated once per power-on hour (when the controller + * is not in a sleep state). * @endu_grp_crit_warn_sumry: Endurance Group Critical Warning Summary: This field - * indicates critical warnings for the state of Endurance - * Groups. Bits in this field represent the current associated - * state and are not persistent (see &enum nvme_smart_egcw). + * indicates critical warnings for the state of Endurance + * Groups. Bits in this field represent the current associated + * state and are not persistent (see &enum nvme_smart_egcw). * @rsvd7: Reserved * @data_units_read: Data Units Read: Contains the number of 512 byte data - * units the host has read from the controller; this value - * does not include metadata. This value is reported in - * thousands (i.e., a value of 1 corresponds to 1000 - * units of 512 bytes read) and is rounded up (e.g., one - * indicates the that number of 512 byte data units read - * is from 1 to 1000, three indicates that the number of - * 512 byte data units read is from 2001 to 3000). When - * the LBA size is a value other than 512 bytes, the - * controller shall convert the amount of data read to - * 512 byte units. For the NVM command set, logical blocks - * read as part of Compare, Read, and Verify operations - * shall be included in this value. A value of %0h in - * this field indicates that the number of Data Units Read - * is not reported. - * @data_units_written: Data Units Written: Contains the number of 512 byte - * data units the host has written to the controller; - * this value does not include metadata. This value is - * reported in thousands (i.e., a value of 1 corresponds - * to 1000 units of 512 bytes written) and is rounded up - * (e.g., one indicates that the number of 512 byte data - * units written is from 1 to 1,000, three indicates that - * the number of 512 byte data units written is from 2001 - * to 3000). When the LBA size is a value other than 512 - * bytes, the controller shall convert the amount of data - * written to 512 byte units. For the NVM command set, - * logical blocks written as part of Write operations shall - * be included in this value. Write Uncorrectable commands - * and Write Zeroes commands shall not impact this value. - * A value of %0h in this field indicates that the number - * of Data Units Written is not reported. + * units the host has read from the controller; this value + * does not include metadata. This value is reported in + * thousands (i.e., a value of 1 corresponds to 1000 + * units of 512 bytes read) and is rounded up (e.g., one + * indicates the that number of 512 byte data units read + * is from 1 to 1000, three indicates that the number of + * 512 byte data units read is from 2001 to 3000). When + * the LBA size is a value other than 512 bytes, the + * controller shall convert the amount of data read to + * 512 byte units. For the NVM command set, logical blocks + * read as part of Compare, Read, and Verify operations + * shall be included in this value. A value of %0h in + * this field indicates that the number of Data Units Read + * is not reported. + * @data_units_written: Data Units Written: Contains the number of 512 byte + * data units the host has written to the controller; + * this value does not include metadata. This value is + * reported in thousands (i.e., a value of 1 corresponds + * to 1000 units of 512 bytes written) and is rounded up + * (e.g., one indicates that the number of 512 byte data + * units written is from 1 to 1,000, three indicates that + * the number of 512 byte data units written is from 2001 + * to 3000). When the LBA size is a value other than 512 + * bytes, the controller shall convert the amount of data + * written to 512 byte units. For the NVM command set, + * logical blocks written as part of Write operations shall + * be included in this value. Write Uncorrectable commands + * and Write Zeroes commands shall not impact this value. + * A value of %0h in this field indicates that the number + * of Data Units Written is not reported. * @host_reads: Host Read Commands: Contains the number of read commands - * completed by the controller. For the NVM command set, - * this value is the sum of the number of Compare commands - * and the number of Read commands. + * completed by the controller. For the NVM command set, + * this value is the sum of the number of Compare commands + * and the number of Read commands. * @host_writes: Host Write Commands: Contains the number of write - * commands completed by the controller. For the NVM - * command set, this is the number of Write commands. + * commands completed by the controller. For the NVM + * command set, this is the number of Write commands. * @ctrl_busy_time: Controller Busy Time: Contains the amount of time the - * controller is busy with I/O commands. The controller - * is busy when there is a command outstanding to an I/O - * Queue (specifically, a command was issued via an I/O - * Submission Queue Tail doorbell write and the corresponding - * completion queue entry has not been posted yet to the - * associated I/O Completion Queue). This value is - * reported in minutes. + * controller is busy with I/O commands. The controller + * is busy when there is a command outstanding to an I/O + * Queue (specifically, a command was issued via an I/O + * Submission Queue Tail doorbell write and the corresponding + * completion queue entry has not been posted yet to the + * associated I/O Completion Queue). This value is + * reported in minutes. * @power_cycles: Power Cycles: Contains the number of power cycles. * @power_on_hours: Power On Hours: Contains the number of power-on hours. - * This may not include time that the controller was - * powered and in a non-operational power state. + * This may not include time that the controller was + * powered and in a non-operational power state. * @unsafe_shutdowns: Unsafe Shutdowns: Contains the number of unsafe - * shutdowns. This count is incremented when a Shutdown - * Notification (CC.SHN) is not received prior to loss of power. + * shutdowns. This count is incremented when a Shutdown + * Notification (CC.SHN) is not received prior to loss of power. * @media_errors: Media and Data Integrity Errors: Contains the number - * of occurrences where the controller detected an - * unrecovered data integrity error. Errors such as - * uncorrectable ECC, CRC checksum failure, or LBA tag - * mismatch are included in this field. Errors introduced - * as a result of a Write Uncorrectable command may or - * may not be included in this field. + * of occurrences where the controller detected an + * unrecovered data integrity error. Errors such as + * uncorrectable ECC, CRC checksum failure, or LBA tag + * mismatch are included in this field. Errors introduced + * as a result of a Write Uncorrectable command may or + * may not be included in this field. * @num_err_log_entries: Number of Error Information Log Entries: Contains the - * number of Error Information log entries over the life - * of the controller. - * @warning_temp_time: Warning Composite Temperature Time: Contains the amount - * of time in minutes that the controller is operational - * and the Composite Temperature is greater than or equal - * to the Warning Composite Temperature Threshold (WCTEMP) - * field and less than the Critical Composite Temperature - * Threshold (CCTEMP) field in the Identify Controller - * data structure. If the value of the WCTEMP or CCTEMP - * field is %0h, then this field is always cleared to %0h - * regardless of the Composite Temperature value. - * @critical_comp_time: Critical Composite Temperature Time: Contains the amount - * of time in minutes that the controller is operational - * and the Composite Temperature is greater than or equal - * to the Critical Composite Temperature Threshold (CCTEMP) - * field in the Identify Controller data structure. If - * the value of the CCTEMP field is %0h, then this field - * is always cleared to 0h regardless of the Composite - * Temperature value. + * number of Error Information log entries over the life + * of the controller. + * @warning_temp_time: Warning Composite Temperature Time: Contains the amount + * of time in minutes that the controller is operational + * and the Composite Temperature is greater than or equal + * to the Warning Composite Temperature Threshold (WCTEMP) + * field and less than the Critical Composite Temperature + * Threshold (CCTEMP) field in the Identify Controller + * data structure. If the value of the WCTEMP or CCTEMP + * field is %0h, then this field is always cleared to %0h + * regardless of the Composite Temperature value. + * @critical_comp_time: Critical Composite Temperature Time: Contains the amount + * of time in minutes that the controller is operational + * and the Composite Temperature is greater than or equal + * to the Critical Composite Temperature Threshold (CCTEMP) + * field in the Identify Controller data structure. If + * the value of the CCTEMP field is %0h, then this field + * is always cleared to 0h regardless of the Composite + * Temperature value. * @temp_sensor: Temperature Sensor 1-8: Contains the current temperature - * in degrees Kelvin reported by temperature sensors 1-8. - * The physical point in the NVM subsystem whose temperature - * is reported by the temperature sensor and the temperature - * accuracy is implementation specific. An implementation - * that does not implement the temperature sensor reports - * a value of %0h. + * in degrees Kelvin reported by temperature sensors 1-8. + * The physical point in the NVM subsystem whose temperature + * is reported by the temperature sensor and the temperature + * accuracy is implementation specific. An implementation + * that does not implement the temperature sensor reports + * a value of %0h. * @thm_temp1_trans_count: Thermal Management Temperature 1 Transition Count: - * Contains the number of times the controller transitioned - * to lower power active power states or performed vendor - * specific thermal management actions while minimizing - * the impact on performance in order to attempt to reduce - * the Composite Temperature because of the host controlled - * thermal management feature (i.e., the Composite - * Temperature rose above the Thermal Management - * Temperature 1). This counter shall not wrap once the - * value %FFFFFFFFh is reached. A value of %0h, indicates - * that this transition has never occurred or this field - * is not implemented. + * Contains the number of times the controller transitioned + * to lower power active power states or performed vendor + * specific thermal management actions while minimizing + * the impact on performance in order to attempt to reduce + * the Composite Temperature because of the host controlled + * thermal management feature (i.e., the Composite + * Temperature rose above the Thermal Management + * Temperature 1). This counter shall not wrap once the + * value %FFFFFFFFh is reached. A value of %0h, indicates + * that this transition has never occurred or this field + * is not implemented. * @thm_temp2_trans_count: Thermal Management Temperature 2 Transition Count * @thm_temp1_total_time: Total Time For Thermal Management Temperature 1: - * Contains the number of seconds that the controller - * had transitioned to lower power active power states or - * performed vendor specific thermal management actions - * while minimizing the impact on performance in order to - * attempt to reduce the Composite Temperature because of - * the host controlled thermal management feature. This - * counter shall not wrap once the value %FFFFFFFFh is - * reached. A value of %0h, indicates that this transition - * has never occurred or this field is not implemented. + * Contains the number of seconds that the controller + * had transitioned to lower power active power states or + * performed vendor specific thermal management actions + * while minimizing the impact on performance in order to + * attempt to reduce the Composite Temperature because of + * the host controlled thermal management feature. This + * counter shall not wrap once the value %FFFFFFFFh is + * reached. A value of %0h, indicates that this transition + * has never occurred or this field is not implemented. * @thm_temp2_total_time: Total Time For Thermal Management Temperature 2 * @rsvd232: Reserved */ @@ -2654,23 +2724,23 @@ struct nvme_smart_log { /** * enum nvme_smart_crit - Critical Warning * @NVME_SMART_CRIT_SPARE: If set, then the available spare capacity has fallen - * below the threshold. + * below the threshold. * @NVME_SMART_CRIT_TEMPERATURE: If set, then a temperature is either greater - * than or equal to an over temperature threshold; or - * less than or equal to an under temperature threshold. + * than or equal to an over temperature threshold; or + * less than or equal to an under temperature threshold. * @NVME_SMART_CRIT_DEGRADED: If set, then the NVM subsystem reliability has - * been degraded due to significant media related errors - * or any internal error that degrades NVM subsystem - * reliability. + * been degraded due to significant media related errors + * or any internal error that degrades NVM subsystem + * reliability. * @NVME_SMART_CRIT_MEDIA: If set, then all of the media has been placed in read - * only mode. The controller shall not set this bit if - * the read-only condition on the media is a result of - * a change in the write protection state of a namespace. + * only mode. The controller shall not set this bit if + * the read-only condition on the media is a result of + * a change in the write protection state of a namespace. * @NVME_SMART_CRIT_VOLATILE_MEMORY: If set, then the volatile memory backup - * device has failed. This field is only valid if the - * controller has a volatile memory backup solution. + * device has failed. This field is only valid if the + * controller has a volatile memory backup solution. * @NVME_SMART_CRIT_PMR_RO: If set, then the Persistent Memory Region has become - * read-only or unreliable. + * read-only or unreliable. */ enum nvme_smart_crit { NVME_SMART_CRIT_SPARE = 1 << 0, @@ -2684,15 +2754,15 @@ enum nvme_smart_crit { /** * enum nvme_smart_egcw - Endurance Group Critical Warning Summary * @NVME_SMART_EGCW_SPARE: If set, then the available spare capacity of one or - * more Endurance Groups has fallen below the threshold. + * more Endurance Groups has fallen below the threshold. * @NVME_SMART_EGCW_DEGRADED: If set, then the reliability of one or more - * Endurance Groups has been degraded due to significant - * media related errors or any internal error that - * degrades NVM subsystem reliability. - * @NVME_SMART_EGCW_RO: If set, then the namespaces in one or more Endurance - * Groups have been placed in read only mode not as - * a result of a change in the write protection state - * of a namespace. + * Endurance Groups has been degraded due to significant + * media related errors or any internal error that + * degrades NVM subsystem reliability. + * @NVME_SMART_EGCW_RO: If set, then the namespaces in one or more Endurance + * Groups have been placed in read only mode not as + * a result of a change in the write protection state + * of a namespace. */ enum nvme_smart_egcw { NVME_SMART_EGCW_SPARE = 1 << 0, @@ -2701,7 +2771,7 @@ enum nvme_smart_egcw { }; /** - * struct nvme_firmware_slot - + * struct nvme_firmware_slot - Firmware Slot Information Log * @afi: Active Firmware Info * @rsvd1: Reserved * @frs: Firmware Revision for Slot @@ -2715,7 +2785,7 @@ struct nvme_firmware_slot { }; /** - * struct nvme_cmd_effects_log - + * struct nvme_cmd_effects_log - Commands Supported and Effects Log * @acs: Admin Command Supported * @iocs: I/O Command Supported * @rsvd: Reserved @@ -2727,7 +2797,7 @@ struct nvme_cmd_effects_log { }; /** - * enum nvme_cmd_effects - + * enum nvme_cmd_effects - Commands Supported and Effects * @NVME_CMD_EFFECTS_CSUPP: Command Supported * @NVME_CMD_EFFECTS_LBCC: Logical Block Content Change * @NVME_CMD_EFFECTS_NCC: Namespace Capability Change @@ -2749,44 +2819,44 @@ enum nvme_cmd_effects { /** * struct nvme_st_result - Self-test Result * @dsts: Device Self-test Status: Indicates the device self-test code and the - * status of the operation (see &enum nvme_status_result and &enum nvme_st_code). + * status of the operation (see &enum nvme_status_result and &enum nvme_st_code). * @seg: Segment Number: Iindicates the segment number where the first self-test - * failure occurred. If Device Self-test Status (@dsts) is not set to - * #NVME_ST_RESULT_KNOWN_SEG_FAIL, then this field should be ignored. + * failure occurred. If Device Self-test Status (@dsts) is not set to + * #NVME_ST_RESULT_KNOWN_SEG_FAIL, then this field should be ignored. * @vdi: Valid Diagnostic Information: Indicates the diagnostic failure - * information that is reported. See &enum nvme_st_valid_diag_info. + * information that is reported. See &enum nvme_st_valid_diag_info. * @rsvd: Reserved * @poh: Power On Hours (POH): Indicates the number of power-on hours at the - * time the device self-test operation was completed or aborted. This - * does not include time that the controller was powered and in a low - * power state condition. + * time the device self-test operation was completed or aborted. This + * does not include time that the controller was powered and in a low + * power state condition. * @nsid: Namespace Identifier (NSID): Indicates the namespace that the Failing - * LBA occurred on. Valid only when the NSID Valid bit - * (#NVME_ST_VALID_DIAG_INFO_NSID) is set in the Valid Diagnostic - * Information (@vdi) field. + * LBA occurred on. Valid only when the NSID Valid bit + * (#NVME_ST_VALID_DIAG_INFO_NSID) is set in the Valid Diagnostic + * Information (@vdi) field. * @flba: Failing LBA: indicates the LBA of the logical block that caused the - * test to fail. If the device encountered more than one failed logical - * block during the test, then this field only indicates one of those - * failed logical blocks. Valid only when the NSID Valid bit - * (#NVME_ST_VALID_DIAG_INFO_FLBA) is set in the Valid Diagnostic - * Information (@vdi) field. + * test to fail. If the device encountered more than one failed logical + * block during the test, then this field only indicates one of those + * failed logical blocks. Valid only when the NSID Valid bit + * (#NVME_ST_VALID_DIAG_INFO_FLBA) is set in the Valid Diagnostic + * Information (@vdi) field. * @sct: Status Code Type: This field may contain additional information related - * to errors or conditions. Bits 2:0 may contain additional information - * relating to errors or conditions that occurred during the device - * self-test operation represented in the same format used in the Status - * Code Type field of the completion queue entry (refer to &enum nvme_status_field). - * Valid only when the NSID Valid bit (#NVME_ST_VALID_DIAG_INFO_SCT) is - * set in the Valid Diagnostic Information (@vdi) field. + * to errors or conditions. Bits 2:0 may contain additional information + * relating to errors or conditions that occurred during the device + * self-test operation represented in the same format used in the Status + * Code Type field of the completion queue entry (refer to &enum nvme_status_field). + * Valid only when the NSID Valid bit (#NVME_ST_VALID_DIAG_INFO_SCT) is + * set in the Valid Diagnostic Information (@vdi) field. * @sc: Status Code: This field may contain additional information relating - * to errors or conditions that occurred during the device self-test - * operation represented in the same format used in the Status Code field - * of the completion queue entry. Valid only when the SCT Valid bit - * (#NVME_ST_VALID_DIAG_INFO_SC) is set in the Valid Diagnostic - * Information (@vdi) field. + * to errors or conditions that occurred during the device self-test + * operation represented in the same format used in the Status Code field + * of the completion queue entry. Valid only when the SCT Valid bit + * (#NVME_ST_VALID_DIAG_INFO_SC) is set in the Valid Diagnostic + * Information (@vdi) field. * @vs: Vendor Specific. */ struct nvme_st_result { - __u8 dsts; + __u8 dsts; __u8 seg; __u8 vdi; __u8 rsvd; @@ -2804,23 +2874,23 @@ struct nvme_st_result { * @NVME_ST_RESULT_ABORTED: Operation was aborted by a Device Self-test command. * @NVME_ST_RESULT_CLR: Operation was aborted by a Controller Level Reset. * @NVME_ST_RESULT_NS_REMOVED: Operation was aborted due to a removal of - * a namespace from the namespace inventory. + * a namespace from the namespace inventory. * @NVME_ST_RESULT_ABORTED_FORMAT: Operation was aborted due to the processing - * of a Format NVM command. + * of a Format NVM command. * @NVME_ST_RESULT_FATAL_ERR: A fatal error or unknown test error occurred - * while the controller was executing the device - * self-test operation and the operation did - * not complete. + * while the controller was executing the device + * self-test operation and the operation did + * not complete. * @NVME_ST_RESULT_UNKNOWN_SEG_FAIL: Operation completed with a segment that failed - * and the segment that failed is not known. + * and the segment that failed is not known. * @NVME_ST_RESULT_KNOWN_SEG_FAIL: Operation completed with one or more failed - * segments and the first segment that failed - * is indicated in the Segment Number field. + * segments and the first segment that failed + * is indicated in the Segment Number field. * @NVME_ST_RESULT_ABORTED_UNKNOWN: Operation was aborted for unknown reason. * @NVME_ST_RESULT_ABORTED_SANITIZE: Operation was aborted due to a sanitize operation. * @NVME_ST_RESULT_NOT_USED: Entry not used (does not contain a test result). * @NVME_ST_RESULT_MASK: Mask to get the status result value from - * the &struct nvme_st_result.dsts field. + * the &struct nvme_st_result.dsts field. */ enum nvme_status_result { NVME_ST_RESULT_NO_ERR = 0x0, @@ -2844,7 +2914,7 @@ enum nvme_status_result { * @NVME_ST_CODE_EXTENDED: Extended device self-test operation. * @NVME_ST_CODE_VS: Vendor specific. * @NVME_ST_CODE_SHIFT: Shift amount to get the code value from the - * &struct nvme_st_result.dsts field. + * &struct nvme_st_result.dsts field. */ enum nvme_st_code { NVME_ST_CODE_RESERVED = 0x0, @@ -2862,9 +2932,9 @@ enum nvme_st_code { * @NVME_ST_CURR_OP_VS: Vendor specific. * @NVME_ST_CURR_OP_RESERVED: Reserved. * @NVME_ST_CURR_OP_MASK: Mask to get the current operation value from the - * &struct nvme_self_test_log.current_operation field. + * &struct nvme_self_test_log.current_operation field. * @NVME_ST_CURR_OP_CMPL_MASK: Mask to get the current operation completion value - * from the &struct nvme_self_test_log.completion field. + * from the &struct nvme_self_test_log.completion field. */ enum nvme_st_curr_op { NVME_ST_CURR_OP_NOT_RUNNING = 0x0, @@ -2879,13 +2949,13 @@ enum nvme_st_curr_op { /** * enum nvme_st_valid_diag_info - Valid Diagnostic Information * @NVME_ST_VALID_DIAG_INFO_NSID: NSID Valid: if set, then the contents of - * the Namespace Identifier field are valid. + * the Namespace Identifier field are valid. * @NVME_ST_VALID_DIAG_INFO_FLBA: FLBA Valid: if set, then the contents of - * the Failing LBA field are valid. + * the Failing LBA field are valid. * @NVME_ST_VALID_DIAG_INFO_SCT: SCT Valid: if set, then the contents of - * the Status Code Type field are valid. - * @NVME_ST_VALID_DIAG_INFO_SC: SC Valid: if set, then the contents of - * the Status Code field are valid. + * the Status Code Type field are valid. + * @NVME_ST_VALID_DIAG_INFO_SC: SC Valid: if set, then the contents of + * the Status Code field are valid. */ enum nvme_st_valid_diag_info { NVME_ST_VALID_DIAG_INFO_NSID = 1 << 0, @@ -2897,23 +2967,23 @@ enum nvme_st_valid_diag_info { /** * struct nvme_self_test_log - Device Self-test (Log Identifier 06h) * @current_operation: Current Device Self-Test Operation: indicates the status - * of the current device self-test operation. If a device - * self-test operation is in process (i.e., this field is set - * to #NVME_ST_CURR_OP_SHORT or #NVME_ST_CURR_OP_EXTENDED), - * then the controller shall not set this field to - * #NVME_ST_CURR_OP_NOT_RUNNING until a new Self-test Result - * Data Structure is created (i.e., if a device self-test - * operation completes or is aborted, then the controller - * shall create a Self-test Result Data Structure prior to - * setting this field to #NVME_ST_CURR_OP_NOT_RUNNING). - * See &enum nvme_st_curr_op. + * of the current device self-test operation. If a device + * self-test operation is in process (i.e., this field is set + * to #NVME_ST_CURR_OP_SHORT or #NVME_ST_CURR_OP_EXTENDED), + * then the controller shall not set this field to + * #NVME_ST_CURR_OP_NOT_RUNNING until a new Self-test Result + * Data Structure is created (i.e., if a device self-test + * operation completes or is aborted, then the controller + * shall create a Self-test Result Data Structure prior to + * setting this field to #NVME_ST_CURR_OP_NOT_RUNNING). + * See &enum nvme_st_curr_op. * @completion: Current Device Self-Test Completion: indicates the percentage - * of the device self-test operation that is complete (e.g., - * a value of 25 indicates that 25% of the device self-test - * operation is complete and 75% remains to be tested). - * If the @current_operation field is cleared to - * #NVME_ST_CURR_OP_NOT_RUNNING (indicating there is no device - * self-test operation in progress), then this field is ignored. + * of the device self-test operation that is complete (e.g., + * a value of 25 indicates that 25% of the device self-test + * operation is complete and 75% remains to be tested). + * If the @current_operation field is cleared to + * #NVME_ST_CURR_OP_NOT_RUNNING (indicating there is no device + * self-test operation in progress), then this field is ignored. * @rsvd: Reserved * @result: Self-test Result Data Structures, see &struct nvme_st_result. */ @@ -2925,9 +2995,9 @@ struct nvme_self_test_log { } __attribute__((packed)); /** - * enum nvme_cmd_get_log_telemetry_host_lsp - - * @NVME_LOG_TELEM_HOST_LSP_RETAIN: - * @NVME_LOG_TELEM_HOST_LSP_CREATE: + * enum nvme_cmd_get_log_telemetry_host_lsp - Telemetry Host-Initiated log specific field + * @NVME_LOG_TELEM_HOST_LSP_RETAIN: Get Telemetry Data Blocks + * @NVME_LOG_TELEM_HOST_LSP_CREATE: Create Telemetry Data Blocks */ enum nvme_cmd_get_log_telemetry_host_lsp { NVME_LOG_TELEM_HOST_LSP_RETAIN = 0, @@ -2936,37 +3006,37 @@ enum nvme_cmd_get_log_telemetry_host_lsp { /** * struct nvme_telemetry_log - Retrieve internal data specific to the - * manufacturer. + * manufacturer. * @lpi: Log Identifier, either %NVME_LOG_LID_TELEMETRY_HOST or - * %NVME_LOG_LID_TELEMETRY_CTRL + * %NVME_LOG_LID_TELEMETRY_CTRL * @rsvd1: Reserved * @ieee: IEEE OUI Identifier is the Organization Unique Identifier (OUI) - * for the controller vendor that is able to interpret the data. + * for the controller vendor that is able to interpret the data. * @dalb1: Telemetry Controller-Initiated Data Area 1 Last Block is - * the value of the last block in this area. + * the value of the last block in this area. * @dalb2: Telemetry Controller-Initiated Data Area 1 Last Block is - * the value of the last block in this area. + * the value of the last block in this area. * @dalb3: Telemetry Controller-Initiated Data Area 1 Last Block is - * the value of the last block in this area. + * the value of the last block in this area. * @rsvd14: Reserved * @dalb4: Telemetry Controller-Initiated Data Area 4 Last Block is - * the value of the last block in this area. + * the value of the last block in this area. * @rsvd20: Reserved * @hostdgn: Telemetry Host-Initiated Data Generation Number is a - * value that is incremented each time the host initiates a - * capture of its internal controller state in the controller . + * value that is incremented each time the host initiates a + * capture of its internal controller state in the controller . * @ctrlavail: Telemetry Controller-Initiated Data Available, if cleared, - * then the controller telemetry log does not contain saved - * internal controller state. If this field is set to 1h, the - * controller log contains saved internal controller state. If - * this field is set to 1h, the data will be latched until the - * host releases it by reading the log with RAE cleared. + * then the controller telemetry log does not contain saved + * internal controller state. If this field is set to 1h, the + * controller log contains saved internal controller state. If + * this field is set to 1h, the data will be latched until the + * host releases it by reading the log with RAE cleared. * @ctrldgn: Telemetry Controller-Initiated Data Generation Number is - * a value that is incremented each time the controller initiates a - * capture of its internal controller state in the controller . - * @rsnident: Reason Identifieris a vendor specific identifier that describes - * the operating conditions of the controller at the time of - * capture. + * a value that is incremented each time the controller initiates a + * capture of its internal controller state in the controller . + * @rsnident: Reason Identifiers a vendor specific identifier that describes + * the operating conditions of the controller at the time of + * capture. * @data_area: Telemetry data blocks, vendor specific information data. * * This log consists of a header describing the log and zero or more Telemetry @@ -2980,9 +3050,9 @@ struct nvme_telemetry_log { __le16 dalb1; __le16 dalb2; __le16 dalb3; - __u8 rsvd14[2]; - __le32 dalb4; - __u8 rsvd20[361]; + __u8 rsvd14[2]; + __le32 dalb4; + __u8 rsvd20[361]; __u8 hostdgn; __u8 ctrlavail; __u8 ctrldgn; @@ -2991,7 +3061,7 @@ struct nvme_telemetry_log { }; /** - * struct nvme_endurance_group_log - + * struct nvme_endurance_group_log - Endurance Group Information Log * @critical_warning: Critical Warning * @rsvd1: Reserved * @avl_spare: Available Spare @@ -3027,10 +3097,12 @@ struct nvme_endurance_group_log { }; /** - * enum nvme_eg_critical_warning_flags - - * @NVME_EG_CRITICAL_WARNING_SPARE: - * @NVME_EG_CRITICAL_WARNING_DEGRADED: - * @NVME_EG_CRITICAL_WARNING_READ_ONLY: + * enum nvme_eg_critical_warning_flags - Endurance Group Information Log - Critical Warning + * @NVME_EG_CRITICAL_WARNING_SPARE: Available spare capacity of the Endurance Group + * has fallen below the threshold + * @NVME_EG_CRITICAL_WARNING_DEGRADED: Endurance Group reliability has been degraded + * @NVME_EG_CRITICAL_WARNING_READ_ONLY: Endurance Group have been placed in read only + * mode */ enum nvme_eg_critical_warning_flags { NVME_EG_CRITICAL_WARNING_SPARE = 1 << 0, @@ -3039,7 +3111,7 @@ enum nvme_eg_critical_warning_flags { }; /** - * struct nvme_aggregate_endurance_group_event - + * struct nvme_aggregate_endurance_group_event - Endurance Group Event Aggregate * @num_entries: Number or entries * @entries: List of entries */ @@ -3049,7 +3121,7 @@ struct nvme_aggregate_endurance_group_event { }; /** - * struct nvme_nvmset_predictable_lat_log - + * struct nvme_nvmset_predictable_lat_log - Predictable Latency Mode - Deterministic Threshold Configuration Data * @status: Status * @rsvd1: Reserved * @event_type: Event Type @@ -3083,10 +3155,10 @@ struct nvme_nvmset_predictable_lat_log { }; /** - * enum nvme_nvmeset_pl_status - - * @NVME_NVMSET_PL_STATUS_DISABLED: - * @NVME_NVMSET_PL_STATUS_DTWIN: - * @NVME_NVMSET_PL_STATUS_NDWIN: + * enum nvme_nvmeset_pl_status - Predictable Latency Per NVM Set Log - Status + * @NVME_NVMSET_PL_STATUS_DISABLED: Not used (Predictable Latency Mode not enabled) + * @NVME_NVMSET_PL_STATUS_DTWIN: Deterministic Window (DTWIN) + * @NVME_NVMSET_PL_STATUS_NDWIN: Non-Deterministic Window (NDWIN) */ enum nvme_nvmeset_pl_status { NVME_NVMSET_PL_STATUS_DISABLED = 0, @@ -3095,12 +3167,16 @@ enum nvme_nvmeset_pl_status { }; /** - * enum nvme_nvmset_pl_events - - * @NVME_NVMSET_PL_EVENT_DTWIN_READ_WARN: - * @NVME_NVMSET_PL_EVENT_DTWIN_WRITE_WARN: - * @NVME_NVMSET_PL_EVENT_DTWIN_TIME_WARN: - * @NVME_NVMSET_PL_EVENT_DTWIN_EXCEEDED: - * @NVME_NVMSET_PL_EVENT_DTWIN_EXCURSION: + * enum nvme_nvmset_pl_events - Predictable Latency Per NVM Set Log - Event Type + * @NVME_NVMSET_PL_EVENT_DTWIN_READ_WARN: DTWIN Reads Warning + * @NVME_NVMSET_PL_EVENT_DTWIN_WRITE_WARN: DTWIN Writes Warning + * @NVME_NVMSET_PL_EVENT_DTWIN_TIME_WARN: DTWIN Time Warning + * @NVME_NVMSET_PL_EVENT_DTWIN_EXCEEDED: Autonomous transition from DTWIN + * to NDWIN due to typical or + * maximum value exceeded + * @NVME_NVMSET_PL_EVENT_DTWIN_EXCURSION: Autonomous transition from DTWIN + * to NDWIN due to Deterministic + * Excursion */ enum nvme_nvmset_pl_events { NVME_NVMSET_PL_EVENT_DTWIN_READ_WARN = 1 << 0, @@ -3111,7 +3187,7 @@ enum nvme_nvmset_pl_events { }; /** - * struct nvme_aggregate_predictable_lat_event - + * struct nvme_aggregate_predictable_lat_event - Predictable Latency Event Aggregate Log Page * @num_entries: Number of entries * @entries: Entry list */ @@ -3121,7 +3197,7 @@ struct nvme_aggregate_predictable_lat_event { }; /** - * struct nvme_ana_group_desc - + * struct nvme_ana_group_desc - ANA Group Descriptor * @grpid: ANA group id * @nnsids: Number of namespaces in @nsids * @chgcnt: Change counter @@ -3130,21 +3206,21 @@ struct nvme_aggregate_predictable_lat_event { * @nsids: List of namespaces */ struct nvme_ana_group_desc { - __le32 grpid; - __le32 nnsids; - __le64 chgcnt; - __u8 state; - __u8 rsvd17[15]; - __le32 nsids[]; + __le32 grpid; + __le32 nnsids; + __le64 chgcnt; + __u8 state; + __u8 rsvd17[15]; + __le32 nsids[]; }; /** - * enum nvme_ana_state - - * @NVME_ANA_STATE_OPTIMIZED: - * @NVME_ANA_STATE_NONOPTIMIZED: - * @NVME_ANA_STATE_INACCESSIBLE: - * @NVME_ANA_STATE_PERSISTENT_LOSS: - * @NVME_ANA_STATE_CHANGE: + * enum nvme_ana_state - ANA Group Descriptor - Asymmetric Namespace Access State + * @NVME_ANA_STATE_OPTIMIZED: ANA Optimized state + * @NVME_ANA_STATE_NONOPTIMIZED: ANA Non-Optimized state + * @NVME_ANA_STATE_INACCESSIBLE: ANA Inaccessible state + * @NVME_ANA_STATE_PERSISTENT_LOSS: ANA Persistent Loss state + * @NVME_ANA_STATE_CHANGE: ANA Change state */ enum nvme_ana_state { NVME_ANA_STATE_OPTIMIZED = 0x1, @@ -3155,7 +3231,7 @@ enum nvme_ana_state { }; /** - * struct nvme_ana_log - + * struct nvme_ana_log - Asymmetric Namespace Access Log * @chgcnt: Change Count * @ngrps: Number of ANA Group Descriptors * @rsvd10: Reserved @@ -3169,7 +3245,7 @@ struct nvme_ana_log { }; /** - * struct nvme_persistent_event_log - + * struct nvme_persistent_event_log - Persistent Event Log * @lid: Log Identifier * @rsvd1: Reserved * @tnev: Total Number of Events @@ -3206,14 +3282,14 @@ struct nvme_persistent_event_log { char sn[20]; char mn[40]; char subnqn[NVME_NQN_LENGTH]; - __le16 gen_number; - __le32 rci; - __u8 rsvd378[102]; + __le16 gen_number; + __le32 rci; + __u8 rsvd378[102]; __u8 seb[32]; } __attribute__((packed)); /** - * struct nvme_persistent_event_entry - + * struct nvme_persistent_event_entry - Persistent Event * @etype: Event Type * @etype_rev: Event Type Revision * @ehl: Event Header Length @@ -3239,39 +3315,39 @@ struct nvme_persistent_event_entry { } __attribute__((packed)); /** - * enum nvme_persistent_event_types - - * @NVME_PEL_SMART_HEALTH_EVENT: - * @NVME_PEL_FW_COMMIT_EVENT: - * @NVME_PEL_TIMESTAMP_EVENT: - * @NVME_PEL_POWER_ON_RESET_EVENT: - * @NVME_PEL_NSS_HW_ERROR_EVENT: - * @NVME_PEL_CHANGE_NS_EVENT: - * @NVME_PEL_FORMAT_START_EVENT: - * @NVME_PEL_FORMAT_COMPLETION_EVENT: - * @NVME_PEL_SANITIZE_START_EVENT: - * @NVME_PEL_SANITIZE_COMPLETION_EVENT: - * @NVME_PEL_SET_FEATURE_EVENT: - * @NVME_PEL_TELEMETRY_CRT: - * @NVME_PEL_THERMAL_EXCURSION_EVENT: + * enum nvme_persistent_event_types - Persistent event log events + * @NVME_PEL_SMART_HEALTH_EVENT: SMART / Health Log Snapshot Event + * @NVME_PEL_FW_COMMIT_EVENT: Firmware Commit Event + * @NVME_PEL_TIMESTAMP_EVENT: Timestamp Change Event + * @NVME_PEL_POWER_ON_RESET_EVENT: Power-on or Reset Event + * @NVME_PEL_NSS_HW_ERROR_EVENT: NVM Subsystem Hardware Error Event + * @NVME_PEL_CHANGE_NS_EVENT: Change Namespace Event + * @NVME_PEL_FORMAT_START_EVENT: Format NVM Start Event + * @NVME_PEL_FORMAT_COMPLETION_EVENT: Format NVM Completion Event + * @NVME_PEL_SANITIZE_START_EVENT: Sanitize Start Event + * @NVME_PEL_SANITIZE_COMPLETION_EVENT: Sanitize Completion Event + * @NVME_PEL_SET_FEATURE_EVENT: Set Feature Event + * @NVME_PEL_TELEMETRY_CRT: Telemetry Log Create Event + * @NVME_PEL_THERMAL_EXCURSION_EVENT: Thermal Excursion Event */ enum nvme_persistent_event_types { - NVME_PEL_SMART_HEALTH_EVENT = 0x01, - NVME_PEL_FW_COMMIT_EVENT = 0x02, - NVME_PEL_TIMESTAMP_EVENT = 0x03, - NVME_PEL_POWER_ON_RESET_EVENT = 0x04, - NVME_PEL_NSS_HW_ERROR_EVENT = 0x05, - NVME_PEL_CHANGE_NS_EVENT = 0x06, - NVME_PEL_FORMAT_START_EVENT = 0x07, - NVME_PEL_FORMAT_COMPLETION_EVENT = 0x08, - NVME_PEL_SANITIZE_START_EVENT = 0x09, - NVME_PEL_SANITIZE_COMPLETION_EVENT = 0x0a, - NVME_PEL_SET_FEATURE_EVENT = 0x0b, - NVME_PEL_TELEMETRY_CRT = 0x0c, - NVME_PEL_THERMAL_EXCURSION_EVENT = 0x0d, -}; - -/** - * struct nvme_fw_commit_event - + NVME_PEL_SMART_HEALTH_EVENT = 0x01, + NVME_PEL_FW_COMMIT_EVENT = 0x02, + NVME_PEL_TIMESTAMP_EVENT = 0x03, + NVME_PEL_POWER_ON_RESET_EVENT = 0x04, + NVME_PEL_NSS_HW_ERROR_EVENT = 0x05, + NVME_PEL_CHANGE_NS_EVENT = 0x06, + NVME_PEL_FORMAT_START_EVENT = 0x07, + NVME_PEL_FORMAT_COMPLETION_EVENT = 0x08, + NVME_PEL_SANITIZE_START_EVENT = 0x09, + NVME_PEL_SANITIZE_COMPLETION_EVENT = 0x0a, + NVME_PEL_SET_FEATURE_EVENT = 0x0b, + NVME_PEL_TELEMETRY_CRT = 0x0c, + NVME_PEL_THERMAL_EXCURSION_EVENT = 0x0d, +}; + +/** + * struct nvme_fw_commit_event - Firmware Commit Event Data * @old_fw_rev: Old Firmware Revision * @new_fw_rev: New Firmware Revision * @fw_commit_action: Firmware Commit Action @@ -3282,26 +3358,26 @@ enum nvme_persistent_event_types { */ struct nvme_fw_commit_event { __le64 old_fw_rev; - __le64 new_fw_rev; - __u8 fw_commit_action; - __u8 fw_slot; - __u8 sct_fw; - __u8 sc_fw; - __le16 vndr_assign_fw_commit_rc; + __le64 new_fw_rev; + __u8 fw_commit_action; + __u8 fw_slot; + __u8 sct_fw; + __u8 sc_fw; + __le16 vndr_assign_fw_commit_rc; } __attribute__((packed)); /** - * struct nvme_time_stamp_change_event - + * struct nvme_time_stamp_change_event - Timestamp Change Event * @previous_timestamp: Previous Timestamp * @ml_secs_since_reset: Milliseconds Since Reset */ struct nvme_time_stamp_change_event { - __le64 previous_timestamp; - __le64 ml_secs_since_reset; + __le64 previous_timestamp; + __le64 ml_secs_since_reset; }; /** - * struct nvme_power_on_reset_info_list - + * struct nvme_power_on_reset_info_list - Controller Reset Information * @cid: Controller ID * @fw_act: Firmware Activation * @op_in_prog: Operation in Progress @@ -3311,29 +3387,29 @@ struct nvme_time_stamp_change_event { * @ctrl_time_stamp: Controller Timestamp */ struct nvme_power_on_reset_info_list { - __le16 cid; - __u8 fw_act; - __u8 op_in_prog; - __u8 rsvd4[12]; - __le32 ctrl_power_cycle; - __le64 power_on_ml_seconds; - __le64 ctrl_time_stamp; + __le16 cid; + __u8 fw_act; + __u8 op_in_prog; + __u8 rsvd4[12]; + __le32 ctrl_power_cycle; + __le64 power_on_ml_seconds; + __le64 ctrl_time_stamp; } __attribute__((packed)); /** - * struct nvme_nss_hw_err_event - + * struct nvme_nss_hw_err_event - NVM Subsystem Hardware Error Event * @nss_hw_err_event_code: NVM Subsystem Hardware Error Event Code * @rsvd2: Reserved * @add_hw_err_info: Additional Hardware Error Information */ struct nvme_nss_hw_err_event { - __le16 nss_hw_err_event_code; - __u8 rsvd2[2]; - __u8 *add_hw_err_info; + __le16 nss_hw_err_event_code; + __u8 rsvd2[2]; + __u8 *add_hw_err_info; }; /** - * struct nvme_change_ns_event - + * struct nvme_change_ns_event - Change Namespace Event Data * @nsmgt_cdw10: Namespace Management CDW10 * @rsvd4: Reserved * @nsze: Namespace Size @@ -3365,21 +3441,21 @@ struct nvme_change_ns_event { }; /** - * struct nvme_format_nvm_start_event - + * struct nvme_format_nvm_start_event - Format NVM Start Event Data * @nsid: Namespace Identifier * @fna: Format NVM Attributes * @rsvd5: Reserved * @format_nvm_cdw10: Format NVM CDW10 */ struct nvme_format_nvm_start_event { - __le32 nsid; - __u8 fna; - __u8 rsvd5[3]; - __le32 format_nvm_cdw10; + __le32 nsid; + __u8 fna; + __u8 rsvd5[3]; + __le32 format_nvm_cdw10; }; /** - * struct nvme_format_nvm_compln_event - + * struct nvme_format_nvm_compln_event - Format NVM Completion Event Data * @nsid: Namespace Identifier * @smallest_fpi: Smallest Format Progress Indicator * @format_nvm_status: Format NVM Status @@ -3387,27 +3463,27 @@ struct nvme_format_nvm_start_event { * @status_field: Status Field */ struct nvme_format_nvm_compln_event { - __le32 nsid; - __u8 smallest_fpi; - __u8 format_nvm_status; - __le16 compln_info; - __le32 status_field; + __le32 nsid; + __u8 smallest_fpi; + __u8 format_nvm_status; + __le16 compln_info; + __le32 status_field; }; /** - * struct nvme_sanitize_start_event - + * struct nvme_sanitize_start_event - Sanitize Start Event Data * @sani_cap: SANICAP * @sani_cdw10: Sanitize CDW10 * @sani_cdw11: Sanitize CDW11 */ struct nvme_sanitize_start_event { - __le32 sani_cap; - __le32 sani_cdw10; - __le32 sani_cdw11; + __le32 sani_cap; + __le32 sani_cdw10; + __le32 sani_cdw11; }; /** - * struct nvme_sanitize_compln_event - + * struct nvme_sanitize_compln_event - Sanitize Completion Event Data * @sani_prog: Sanitize Progress * @sani_status: Sanitize Status * @cmpln_info: Completion Information @@ -3421,7 +3497,7 @@ struct nvme_sanitize_compln_event { }; /** - * struct nvme_set_feature_event - + * struct nvme_set_feature_event - Set Feature Event Data * @layout: Set Feature Event Layout * @cdw_mem: Command Dwords Memory buffer */ @@ -3431,17 +3507,17 @@ struct nvme_set_feature_event { }; /** - * struct nvme_thermal_exc_event - + * struct nvme_thermal_exc_event - Thermal Excursion Event Data * @over_temp: Over Temperature * @threshold: temperature threshold */ struct nvme_thermal_exc_event { - __u8 over_temp; - __u8 threshold; + __u8 over_temp; + __u8 threshold; }; /** - * struct nvme_lba_rd - + * struct nvme_lba_rd - LBA Range Descriptor * @rslba: Range Starting LBA * @rnlb: Range Number of Logical Blocks * @rsvd12: Reserved @@ -3453,10 +3529,10 @@ struct nvme_lba_rd { }; /** - * struct nvme_lbas_ns_element - + * struct nvme_lbas_ns_element - LBA Status Log Namespace Element * @neid: Namespace Element Identifier * @nlrd: Number of LBA Range Descriptors - * @ratype: Recommended Action Type + * @ratype: Recommended Action Type. see @enum nvme_lba_status_atype * @rsvd8: Reserved * @lba_rd: LBA Range Descriptor */ @@ -3469,9 +3545,10 @@ struct nvme_lbas_ns_element { }; /** - * enum nvme_lba_status_atype - - * @NVME_LBA_STATUS_ATYPE_SCAN_UNTRACKED: - * @NVME_LBA_STATUS_ATYPE_SCAN_TRACKED: + * enum nvme_lba_status_atype - Potentially Unrecoverable LBAs + * @NVME_LBA_STATUS_ATYPE_SCAN_UNTRACKED: Potentially Unrecoverable LBAs + * @NVME_LBA_STATUS_ATYPE_SCAN_TRACKED: Potentially Unrecoverable LBAs + * associated with physical storage */ enum nvme_lba_status_atype { NVME_LBA_STATUS_ATYPE_SCAN_UNTRACKED = 0x10, @@ -3479,7 +3556,7 @@ enum nvme_lba_status_atype { }; /** - * struct nvme_lba_status_log - + * struct nvme_lba_status_log - LBA Status Information Log * @lslplen: LBA Status Log Page Length * @nlslne: Number of LBA Status Log Namespace Elements * @estulb: Estimate of Unrecoverable Logical Blocks @@ -3497,7 +3574,7 @@ struct nvme_lba_status_log { }; /** - * struct nvme_eg_event_aggregate_log - + * struct nvme_eg_event_aggregate_log - Endurance Group Event Aggregate * @nr_entries: Number of Entries * @egids: Endurance Group Identifier */ @@ -3507,23 +3584,21 @@ struct nvme_eg_event_aggregate_log { }; /** - * enum nvme_fid_supported_effects - - * @NVME_FID_SUPPORTED_EFFECTS_FSUPP: - * @NVME_FID_SUPPORTED_EFFECTS_UDCC: - * @NVME_FID_SUPPORTED_EFFECTS_NCC: - * @NVME_FID_SUPPORTED_EFFECTS_NIC: - * @NVME_FID_SUPPORTED_EFFECTS_CCC: - * @NVME_FID_SUPPORTED_EFFECTS_UUID_SEL: - * @NVME_FID_SUPPORTED_EFFECTS_SCOPE_SHIFT: - * @NVME_FID_SUPPORTED_EFFECTS_SCOPE_MASK: - * @NVME_FID_SUPPORTED_EFFECTS_SCOPE_NS: - * @NVME_FID_SUPPORTED_EFFECTS_SCOPE_CTRL: - * @NVME_FID_SUPPORTED_EFFECTS_SCOPE_NVM_SET: - * @NVME_FID_SUPPORTED_EFFECTS_SCOPE_ENDGRP: - * @NVME_FID_SUPPORTED_EFFECTS_SCOPE_DOMAIN: - * @NVME_FID_SUPPORTED_EFFECTS_SCOPE_NSS: - * - * FID Supported and Effects Data Structure definitions + * enum nvme_fid_supported_effects - FID Supported and Effects Data Structure definitions + * @NVME_FID_SUPPORTED_EFFECTS_FSUPP: FID Supported + * @NVME_FID_SUPPORTED_EFFECTS_UDCC: User Data Content Change + * @NVME_FID_SUPPORTED_EFFECTS_NCC: Namespace Capability Change + * @NVME_FID_SUPPORTED_EFFECTS_NIC: Namespace Inventory Change + * @NVME_FID_SUPPORTED_EFFECTS_CCC: Controller Capability Change + * @NVME_FID_SUPPORTED_EFFECTS_UUID_SEL: UUID Selection Supported + * @NVME_FID_SUPPORTED_EFFECTS_SCOPE_SHIFT: FID Scope Shift + * @NVME_FID_SUPPORTED_EFFECTS_SCOPE_MASK: FID Scope Mask + * @NVME_FID_SUPPORTED_EFFECTS_SCOPE_NS: Namespace Scope + * @NVME_FID_SUPPORTED_EFFECTS_SCOPE_CTRL: Controller Scope + * @NVME_FID_SUPPORTED_EFFECTS_SCOPE_NVM_SET: NVM Set Scope + * @NVME_FID_SUPPORTED_EFFECTS_SCOPE_ENDGRP: Endurance Group Scope + * @NVME_FID_SUPPORTED_EFFECTS_SCOPE_DOMAIN: Domain Scope + * @NVME_FID_SUPPORTED_EFFECTS_SCOPE_NSS: NVM Subsystem Scope */ enum nvme_fid_supported_effects { NVME_FID_SUPPORTED_EFFECTS_FSUPP = 1 << 0, @@ -3543,19 +3618,18 @@ enum nvme_fid_supported_effects { }; /** - * struct nvme_fid_supported_effects_log - + * struct nvme_fid_supported_effects_log - Feature Identifiers Supported and Effects * @fid_support: Feature Identifier Supported * - * Feature Identifiers Supported and Effects (Log Identifier 12h) */ struct nvme_fid_supported_effects_log { __le32 fid_support[NVME_LOG_FID_SUPPORTED_EFFECTS_MAX]; }; /** - * enum nvme_mi_cmd_supported_effects - bit field definitions + * enum nvme_mi_cmd_supported_effects - MI Command Supported and Effects Data Structure * @NVME_MI_CMD_SUPPORTED_EFFECTS_CSUPP: Command Supported - * @NVME_MI_CMD_SUPPORTED_EFFECTS_UDCC: User Data Conttent Change + * @NVME_MI_CMD_SUPPORTED_EFFECTS_UDCC: User Data Content Change * @NVME_MI_CMD_SUPPORTED_EFFECTS_NCC: Namespace Capability Change * @NVME_MI_CMD_SUPPORTED_EFFECTS_NIC: Namespace Inventory Change * @NVME_MI_CMD_SUPPORTED_EFFECTS_CCC: Controller Capability Change @@ -3567,30 +3641,27 @@ struct nvme_fid_supported_effects_log { * @NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_ENDGRP: Endurance Group Scope * @NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_DOMAIN: Domain Scope * @NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_NSS: NVM Subsystem Scope - * - * MI Command Supported and Effects Data Structure definitions */ enum nvme_mi_cmd_supported_effects { - NVME_MI_CMD_SUPPORTED_EFFECTS_CSUPP = 1 << 0, - NVME_MI_CMD_SUPPORTED_EFFECTS_UDCC = 1 << 1, - NVME_MI_CMD_SUPPORTED_EFFECTS_NCC = 1 << 2, - NVME_MI_CMD_SUPPORTED_EFFECTS_NIC = 1 << 3, - NVME_MI_CMD_SUPPORTED_EFFECTS_CCC = 1 << 4, + NVME_MI_CMD_SUPPORTED_EFFECTS_CSUPP = 1 << 0, + NVME_MI_CMD_SUPPORTED_EFFECTS_UDCC = 1 << 1, + NVME_MI_CMD_SUPPORTED_EFFECTS_NCC = 1 << 2, + NVME_MI_CMD_SUPPORTED_EFFECTS_NIC = 1 << 3, + NVME_MI_CMD_SUPPORTED_EFFECTS_CCC = 1 << 4, NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_SHIFT = 20, NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_MASK = 0xfff, - NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_NS = 1 << 0, + NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_NS = 1 << 0, NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_CTRL = 1 << 1, NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_NVM_SET = 1 << 2, NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_ENDGRP = 1 << 3, NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_DOMAIN = 1 << 4, - NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_NSS = 1 << 5, + NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_NSS = 1 << 5, }; /** - * struct nvme_mi_cmd_supported_effects_log - - * @mi_cmd_support: NVMe-MI Commands Supported - * - * NVMe-MI Commands Supported and Effects (Log Identifier 13h) + * struct nvme_mi_cmd_supported_effects_log - NVMe-MI Commands Supported and Effects Log + * @mi_cmd_support: NVMe-MI Commands Supported + * @reserved1: Reserved */ struct nvme_mi_cmd_supported_effects_log { __le32 mi_cmd_support[NVME_LOG_MI_CMD_SUPPORTED_EFFECTS_MAX]; @@ -3598,13 +3669,13 @@ struct nvme_mi_cmd_supported_effects_log { }; /** - * struct nvme_boot_partition - + * struct nvme_boot_partition - Boot Partition Log * @lid: Boot Partition Identifier * @rsvd1: Reserved * @bpinfo: Boot Partition Information * @rsvd8: Reserved * @boot_partition_data: Contains the contents of the - * specified Boot Partition + * specified Boot Partition */ struct nvme_boot_partition { __u8 lid; @@ -3615,16 +3686,16 @@ struct nvme_boot_partition { }; /** - * struct nvme_media_unit_stat_desc - - * @muid: Media Unit Identifier - * @domainid: Domain Identifier - * @endgid: Endurance Group Identifier - * @nvmsetid: NVM Set Identifier + * struct nvme_media_unit_stat_desc - Media Unit Status Descriptor + * @muid: Media Unit Identifier + * @domainid: Domain Identifier + * @endgid: Endurance Group Identifier + * @nvmsetid: NVM Set Identifier * @cap_adj_fctr: Capacity Adjustment Factor - * @avl_spare: Available Spare + * @avl_spare: Available Spare * @percent_used: Percentage Used - * @mucs: Number of Channels attached to media units - * @cio: Channel Identifiers Offset + * @mucs: Number of Channels attached to media units + * @cio: Channel Identifiers Offset */ struct nvme_media_unit_stat_desc { __le16 muid; @@ -3639,12 +3710,12 @@ struct nvme_media_unit_stat_desc { }; /** - * struct nvme_media_unit_stat_log - - * @nmu: Number unit status descriptor - * @cchans: Number of Channels + * struct nvme_media_unit_stat_log - Media Unit Status + * @nmu: Number unit status descriptor + * @cchans: Number of Channels * @sel_config: Selected Configuration - * @rsvd6: Reserved - * @mus_desc: Media unit statistic descriptors + * @rsvd6: Reserved + * @mus_desc: Media unit statistic descriptors */ struct nvme_media_unit_stat_log { __le16 nmu; @@ -3655,12 +3726,10 @@ struct nvme_media_unit_stat_log { }; /** - * struct nvme_media_unit_config_desc - - * @muid: Media Unit Identifier - * @mudl: Media Unit Descriptor Length - * - * Media Unit Configuration Descriptor - * Structure Definitions + * struct nvme_media_unit_config_desc - Media Unit Configuration Descriptor + * @muid: Media Unit Identifier + * @rsvd2: Reserved + * @mudl: Media Unit Descriptor Length */ struct nvme_media_unit_config_desc { __le16 muid; @@ -3669,12 +3738,11 @@ struct nvme_media_unit_config_desc { }; /** - * struct nvme_channel_config_desc - - * @chanid: Channel Identifier - * @chmus: Number Channel Media Units - * - * Channel Configuration Descriptor - * Structure Definitions + * struct nvme_channel_config_desc - Channel Configuration Descriptor + * @chanid: Channel Identifier + * @chmus: Number Channel Media Units + * @mu_config_desc: Channel Unit config descriptors. + * See @struct nvme_media_unit_config_desc */ struct nvme_channel_config_desc { __le16 chanid; @@ -3683,11 +3751,10 @@ struct nvme_channel_config_desc { }; /** - * struct nvme_end_grp_chan_desc - - * @egchans: Number of Channels - * - * Endurance group Channel Configuration Descriptor - * Structure Definitions + * struct nvme_end_grp_chan_desc - Endurance Group Channel Configuration Descriptor + * @egchans: Number of Channels + * @chan_config_desc: Channel config descriptors. + * See @struct nvme_channel_config_desc */ struct nvme_end_grp_chan_desc { __le16 egchans; @@ -3695,17 +3762,16 @@ struct nvme_end_grp_chan_desc { }; /** - * struct nvme_end_grp_config_desc - + * struct nvme_end_grp_config_desc - Endurance Group Configuration Descriptor * @endgid: Endurance Group Identifier * @cap_adj_factor: Capacity Adjustment Factor + * @rsvd4: Reserved * @tegcap: Total Endurance Group Capacity * @segcap: Spare Endurance Group Capacity * @end_est: Endurance Estimate * @egsets: Number of NVM Sets + * @rsvd64: Reserved * @nvmsetid: NVM Set Identifier - * - * Endurance Group Configuration Descriptor - * Structure Definitions */ struct nvme_end_grp_config_desc { __le16 endgid; @@ -3720,13 +3786,14 @@ struct nvme_end_grp_config_desc { }; /** - * struct nvme_cap_config_desc - + * struct nvme_capacity_config_desc - Capacity Configuration structure definitions * @cap_config_id: Capacity Configuration Identifier * @domainid: Domain Identifier * @egcn: Number Endurance Group Configuration * Descriptors - * - * Capacity Configuration structure definitions + * @rsvd6: Reserved + * @egcd: Endurance Group Config descriptors. + * See @struct nvme_end_grp_config_desc */ struct nvme_capacity_config_desc { __le16 cap_config_id; @@ -3737,11 +3804,11 @@ struct nvme_capacity_config_desc { }; /** - * struct nvme_supported_cap_config_list_log - - * @sccn: number of capacity configuration - * - * Supported Capacity Configuration list log page - * structure definitions + * struct nvme_supported_cap_config_list_log - Supported Capacity Configuration list log page + * @sccn: Number of capacity configuration + * @rsvd1: Reserved + * @cap_config_desc: Capacity configuration descriptor. + * See @struct nvme_capacity_config_desc */ struct nvme_supported_cap_config_list_log { __u8 sccn; @@ -3750,7 +3817,7 @@ struct nvme_supported_cap_config_list_log { }; /** - * struct nvme_resv_notification_log - + * struct nvme_resv_notification_log - Reservation Notification Log * @lpc: Log Page Count * @rnlpt: See &enum nvme_resv_notify_rnlpt. * @nalp: Number of Available Log Pages @@ -3768,11 +3835,11 @@ struct nvme_resv_notification_log { }; /** - * enum nvme_resv_notify_rnlpt - - * @NVME_RESV_NOTIFY_RNLPT_EMPTY: - * @NVME_RESV_NOTIFY_RNLPT_REGISTRATION_PREEMPTED: - * @NVME_RESV_NOTIFY_RNLPT_RESERVATION_RELEASED: - * @NVME_RESV_NOTIFY_RNLPT_RESERVATION_PREEMPTED: + * enum nvme_resv_notify_rnlpt - Reservation Notification Log - Reservation Notification Log Page Type + * @NVME_RESV_NOTIFY_RNLPT_EMPTY: Empty Log Page + * @NVME_RESV_NOTIFY_RNLPT_REGISTRATION_PREEMPTED: Registration Preempted + * @NVME_RESV_NOTIFY_RNLPT_RESERVATION_RELEASED: Reservation Released + * @NVME_RESV_NOTIFY_RNLPT_RESERVATION_PREEMPTED: Reservation Preempted */ enum nvme_resv_notify_rnlpt { NVME_RESV_NOTIFY_RNLPT_EMPTY = 0, @@ -3784,70 +3851,70 @@ enum nvme_resv_notify_rnlpt { /** * struct nvme_sanitize_log_page - Sanitize Status (Log Identifier 81h) * @sprog: Sanitize Progress (SPROG): indicates the fraction complete of the - * sanitize operation. The value is a numerator of the fraction - * complete that has 65,536 (10000h) as its denominator. This value - * shall be set to FFFFh if the @sstat field is not set to - * %NVME_SANITIZE_SSTAT_STATUS_IN_PROGESS. + * sanitize operation. The value is a numerator of the fraction + * complete that has 65,536 (10000h) as its denominator. This value + * shall be set to FFFFh if the @sstat field is not set to + * %NVME_SANITIZE_SSTAT_STATUS_IN_PROGESS. * @sstat: Sanitize Status (SSTAT): indicates the status associated with - * the most recent sanitize operation. See &enum nvme_sanitize_sstat. + * the most recent sanitize operation. See &enum nvme_sanitize_sstat. * @scdw10: Sanitize Command Dword 10 Information (SCDW10): contains the value - * of the Command Dword 10 field of the Sanitize command that started - * the sanitize operation. + * of the Command Dword 10 field of the Sanitize command that started + * the sanitize operation. * @eto: Estimated Time For Overwrite: indicates the number of seconds required - * to complete an Overwrite sanitize operation with 16 passes in - * the background when the No-Deallocate Modifies Media After Sanitize - * field is not set to 10b. A value of 0h indicates that the sanitize - * operation is expected to be completed in the background when the - * Sanitize command that started that operation is completed. A value - * of FFFFFFFFh indicates that no time period is reported. + * to complete an Overwrite sanitize operation with 16 passes in + * the background when the No-Deallocate Modifies Media After Sanitize + * field is not set to 10b. A value of 0h indicates that the sanitize + * operation is expected to be completed in the background when the + * Sanitize command that started that operation is completed. A value + * of FFFFFFFFh indicates that no time period is reported. * @etbe: Estimated Time For Block Erase: indicates the number of seconds - * required to complete a Block Erase sanitize operation in the - * background when the No-Deallocate Modifies Media After Sanitize - * field is not set to 10b. A value of 0h indicates that the sanitize - * operation is expected to be completed in the background when the - * Sanitize command that started that operation is completed. - * A value of FFFFFFFFh indicates that no time period is reported. + * required to complete a Block Erase sanitize operation in the + * background when the No-Deallocate Modifies Media After Sanitize + * field is not set to 10b. A value of 0h indicates that the sanitize + * operation is expected to be completed in the background when the + * Sanitize command that started that operation is completed. + * A value of FFFFFFFFh indicates that no time period is reported. * @etce: Estimated Time For Crypto Erase: indicates the number of seconds - * required to complete a Crypto Erase sanitize operation in the - * background when the No-Deallocate Modifies Media After Sanitize - * field is not set to 10b. A value of 0h indicates that the sanitize - * operation is expected to be completed in the background when the - * Sanitize command that started that operation is completed. - * A value of FFFFFFFFh indicates that no time period is reported. + * required to complete a Crypto Erase sanitize operation in the + * background when the No-Deallocate Modifies Media After Sanitize + * field is not set to 10b. A value of 0h indicates that the sanitize + * operation is expected to be completed in the background when the + * Sanitize command that started that operation is completed. + * A value of FFFFFFFFh indicates that no time period is reported. * @etond: Estimated Time For Overwrite With No-Deallocate Media Modification: - * indicates the number of seconds required to complete an Overwrite - * sanitize operation and the associated additional media modification - * after the Overwrite sanitize operation in the background when - * the No-Deallocate After Sanitize bit was set to 1 in the Sanitize - * command that requested the Overwrite sanitize operation; and - * the No-Deallocate Modifies Media After Sanitize field is set to 10b. - * A value of 0h indicates that the sanitize operation is expected - * to be completed in the background when the Sanitize command that - * started that operation is completed. A value of FFFFFFFFh indicates - * that no time period is reported. + * indicates the number of seconds required to complete an Overwrite + * sanitize operation and the associated additional media modification + * after the Overwrite sanitize operation in the background when + * the No-Deallocate After Sanitize bit was set to 1 in the Sanitize + * command that requested the Overwrite sanitize operation; and + * the No-Deallocate Modifies Media After Sanitize field is set to 10b. + * A value of 0h indicates that the sanitize operation is expected + * to be completed in the background when the Sanitize command that + * started that operation is completed. A value of FFFFFFFFh indicates + * that no time period is reported. * @etbend: Estimated Time For Block Erase With No-Deallocate Media Modification: - * indicates the number of seconds required to complete a Block Erase - * sanitize operation and the associated additional media modification - * after the Block Erase sanitize operation in the background when - * the No-Deallocate After Sanitize bit was set to 1 in the Sanitize - * command that requested the Overwrite sanitize operation; and - * the No-Deallocate Modifies Media After Sanitize field is set to 10b. - * A value of 0h indicates that the sanitize operation is expected - * to be completed in the background when the Sanitize command that - * started that operation is completed. A value of FFFFFFFFh indicates - * that no time period is reported. + * indicates the number of seconds required to complete a Block Erase + * sanitize operation and the associated additional media modification + * after the Block Erase sanitize operation in the background when + * the No-Deallocate After Sanitize bit was set to 1 in the Sanitize + * command that requested the Overwrite sanitize operation; and + * the No-Deallocate Modifies Media After Sanitize field is set to 10b. + * A value of 0h indicates that the sanitize operation is expected + * to be completed in the background when the Sanitize command that + * started that operation is completed. A value of FFFFFFFFh indicates + * that no time period is reported. * @etcend: Estimated Time For Crypto Erase With No-Deallocate Media Modification: - * indicates the number of seconds required to complete a Crypto Erase - * sanitize operation and the associated additional media modification - * after the Crypto Erase sanitize operation in the background when - * the No-Deallocate After Sanitize bit was set to 1 in the Sanitize - * command that requested the Overwrite sanitize operation; and - * the No-Deallocate Modifies Media After Sanitize field is set to 10b. - * A value of 0h indicates that the sanitize operation is expected - * to be completed in the background when the Sanitize command that - * started that operation is completed. A value of FFFFFFFFh indicates - * that no time period is reported. - * @rsvd32: Reserved + * indicates the number of seconds required to complete a Crypto Erase + * sanitize operation and the associated additional media modification + * after the Crypto Erase sanitize operation in the background when + * the No-Deallocate After Sanitize bit was set to 1 in the Sanitize + * command that requested the Overwrite sanitize operation; and + * the No-Deallocate Modifies Media After Sanitize field is set to 10b. + * A value of 0h indicates that the sanitize operation is expected + * to be completed in the background when the Sanitize command that + * started that operation is completed. A value of FFFFFFFFh indicates + * that no time period is reported. + * @rsvd32: Reserved */ struct nvme_sanitize_log_page { __le16 sprog; @@ -3865,44 +3932,44 @@ struct nvme_sanitize_log_page { /** * enum nvme_sanitize_sstat - Sanitize Status (SSTAT) * @NVME_SANITIZE_SSTAT_STATUS_SHIFT: Shift amount to get the status value of - * the most recent sanitize operation from - * the &struct nvme_sanitize_log_page.sstat - * field. + * the most recent sanitize operation from + * the &struct nvme_sanitize_log_page.sstat + * field. * @NVME_SANITIZE_SSTAT_STATUS_MASK: Mask to get the status value of the most - * recent sanitize operation. + * recent sanitize operation. * @NVME_SANITIZE_SSTAT_STATUS_NEVER_SANITIZED: The NVM subsystem has never been - * sanitized. + * sanitized. * @NVME_SANITIZE_SSTAT_STATUS_COMPLETE_SUCCESS: The most recent sanitize operation - * completed successfully including any - * additional media modification. + * completed successfully including any + * additional media modification. * @NVME_SANITIZE_SSTAT_STATUS_IN_PROGESS: A sanitize operation is currently in progress. * @NVME_SANITIZE_SSTAT_STATUS_COMPLETED_FAILED: The most recent sanitize operation - * failed. + * failed. * @NVME_SANITIZE_SSTAT_STATUS_ND_COMPLETE_SUCCESS: The most recent sanitize operation - * for which No-Deallocate After Sanitize was - * requested has completed successfully with - * deallocation of all user data. + * for which No-Deallocate After Sanitize was + * requested has completed successfully with + * deallocation of all user data. * @NVME_SANITIZE_SSTAT_COMPLETED_PASSES_SHIFT: Shift amount to get the number - * of completed passes if the most recent - * sanitize operation was an Overwrite. This - * value shall be cleared to 0h if the most - * recent sanitize operation was not - * an Overwrite. + * of completed passes if the most recent + * sanitize operation was an Overwrite. This + * value shall be cleared to 0h if the most + * recent sanitize operation was not + * an Overwrite. * @NVME_SANITIZE_SSTAT_COMPLETED_PASSES_MASK: Mask to get the number of completed - * passes. + * passes. * @NVME_SANITIZE_SSTAT_GLOBAL_DATA_ERASED_SHIFT: Shift amount to get the Global - * Data Erased value from the - * &struct nvme_sanitize_log_page.sstat field. + * Data Erased value from the + * &struct nvme_sanitize_log_page.sstat field. * @NVME_SANITIZE_SSTAT_GLOBAL_DATA_ERASED_MASK: Mask to get the Global Data Erased - * value. + * value. * @NVME_SANITIZE_SSTAT_GLOBAL_DATA_ERASED: Global Data Erased: if set, then no - * namespace user data in the NVM subsystem - * has been written to and no Persistent - * Memory Region in the NVM subsystem has - * been enabled since being manufactured and - * the NVM subsystem has never been sanitized; - * or since the most recent successful sanitize - * operation. + * namespace user data in the NVM subsystem + * has been written to and no Persistent + * Memory Region in the NVM subsystem has + * been enabled since being manufactured and + * the NVM subsystem has never been sanitized; + * or since the most recent successful sanitize + * operation. */ enum nvme_sanitize_sstat { NVME_SANITIZE_SSTAT_STATUS_SHIFT = 0, @@ -3932,15 +3999,15 @@ struct nvme_zns_changed_zone_log { }; /** - * enum nvme_zns_zt - - * @NVME_ZONE_TYPE_SEQWRITE_REQ: + * enum nvme_zns_zt - Zone Descriptor Data Structure - Zone Type + * @NVME_ZONE_TYPE_SEQWRITE_REQ: Sequential Write Required */ enum nvme_zns_zt { NVME_ZONE_TYPE_SEQWRITE_REQ = 0x2, }; /** - * enum nvme_zns_za - + * enum nvme_zns_za - Zone Descriptor Data Structure * @NVME_ZNS_ZA_ZFC: Zone Finished by Controller * @NVME_ZNS_ZA_FZR: Finish Zone Recommended * @NVME_ZNS_ZA_RZR: Reset Zone Recommended @@ -3956,7 +4023,7 @@ enum nvme_zns_za { }; /** - * enum nvme_zns_zs - + * enum nvme_zns_zs - Zone Descriptor Data Structure - Zone State * @NVME_ZNS_ZS_EMPTY: Empty state * @NVME_ZNS_ZS_IMPL_OPEN: Implicitly open state * @NVME_ZNS_ZS_EXPL_OPEN: Explicitly open state @@ -3976,7 +4043,7 @@ enum nvme_zns_zs { }; /** - * struct nvme_zns_desc - + * struct nvme_zns_desc - Zone Descriptor Data Structure * @zt: Zone Type * @zs: Zone State * @za: Zone Attributes @@ -4000,7 +4067,7 @@ struct nvme_zns_desc { }; /** - * struct nvme_zone_report - + * struct nvme_zone_report - Report Zones Data Structure * @nr_zones: Number of descriptors in @entries * @rsvd8: Reserved * @entries: Zoned namespace descriptors @@ -4012,7 +4079,7 @@ struct nvme_zone_report { }; /** - * struct nvme_lba_status_desc - + * struct nvme_lba_status_desc - LBA Status Descriptor Entry * @dslba: Descriptor Starting LBA * @nlb: Number of Logical Blocks * @rsvd12: Reserved @@ -4028,7 +4095,7 @@ struct nvme_lba_status_desc { }; /** - * struct nvme_lba_status - + * struct nvme_lba_status - LBA Status Descriptor List * @nlsd: Number of LBA Status Descriptors * @cmpc: Completion Condition * @rsvd5: Reserved @@ -4042,7 +4109,7 @@ struct nvme_lba_status { }; /** - * struct nvme_feat_auto_pst - + * struct nvme_feat_auto_pst - Autonomous Power State Transition * @apst_entry: See &enum nvme_apst_entry */ struct nvme_feat_auto_pst { @@ -4050,11 +4117,11 @@ struct nvme_feat_auto_pst { }; /** - * enum nvme_apst_entry - - * @NVME_APST_ENTRY_ITPS_SHIFT: - * @NVME_APST_ENTRY_ITPT_SHIFT: - * @NVME_APST_ENTRY_ITPS_MASK: - * @NVME_APST_ENTRY_ITPT_MASK: + * enum nvme_apst_entry - Autonomous Power State Transition + * @NVME_APST_ENTRY_ITPS_SHIFT: Idle Transition Power State Shift + * @NVME_APST_ENTRY_ITPT_SHIFT: Idle Time Prior to Transition Shift + * @NVME_APST_ENTRY_ITPS_MASK: Idle Transition Power State Mask + * @NVME_APST_ENTRY_ITPT_MASK: Idle Time Prior to Transition Mask */ enum nvme_apst_entry { NVME_APST_ENTRY_ITPS_SHIFT = 3, @@ -4109,10 +4176,10 @@ struct nvme_host_metadata { * pre-boot environment. * @NVME_CTRL_METADATA_SYS_PROC_MODEL: Model of the processor. * @NVME_CTRL_METADATA_CHIPSET_DRV_NAME: Chipset driver name. - * @NVME_CTRL_METADATA_CHIPSET_DRV_VERSION: Chipsset driver version. + * @NVME_CTRL_METADATA_CHIPSET_DRV_VERSION: Chipset driver version. * @NVME_CTRL_METADATA_OS_NAME_AND_BUILD: Operating system name and build. * @NVME_CTRL_METADATA_SYS_PROD_NAME: System product name. - * @NVME_CTRL_METADATA_FIRMWARE_VERSION: Host firmware (e.g UEFI) version. + * @NVME_CTRL_METADATA_FIRMWARE_VERSION: Host firmware (e.g UEFI) version. * @NVME_CTRL_METADATA_OS_DRIVER_FILENAME: Operating system driver filename. * @NVME_CTRL_METADATA_DISPLAY_DRV_NAME: Display driver name. * @NVME_CTRL_METADATA_DISPLAY_DRV_VERSION: Display driver version. @@ -4139,7 +4206,7 @@ enum nvme_ctrl_metadata_type { /** * enum nvme_ns_metadata_type - Namespace Metadata Element Types - * @NVME_NS_METADATA_OS_NS_NAME: Name of the namespace in the the + * @NVME_NS_METADATA_OS_NS_NAME: Name of the namespace in the * operating system * @NVME_NS_METADATA_PRE_BOOT_NS_NAME: Name of the namespace in the pre-boot * environment. @@ -4156,7 +4223,7 @@ enum nvme_ns_metadata_type { }; /** - * struct nvme_timestamp - + * struct nvme_timestamp - Timestamp - Data Structure for Get Features * @timestamp: Timestamp value based on origin and synch field * @attr: Attribute * @rsvd: Reserved @@ -4168,7 +4235,7 @@ struct nvme_timestamp { }; /** - * struct nvme_lba_range_type_entry - + * struct nvme_lba_range_type_entry - LBA Range Type - Data Structure Entry * @type: Specifies the Type of the LBA range * @attributes: Specifies attributes of the LBA range * @rsvd2: Reserved @@ -4188,7 +4255,7 @@ struct nvme_lba_range_type_entry { }; /** - * enum nvme_lbart - + * enum nvme_lbart - LBA Range Type - Data Structure Entry * @NVME_LBART_TYPE_GP: General Purpose * @NVME_LBART_TYPE_FS: Filesystem * @NVME_LBART_TYPE_RAID: RAID @@ -4208,15 +4275,15 @@ enum nvme_lbart { }; /** - * struct nvme_lba_range_type - - * @entry: LBA range type entry + * struct nvme_lba_range_type - LBA Range Type + * @entry: LBA range type entry. See @struct nvme_lba_range_type_entry */ struct nvme_lba_range_type { struct nvme_lba_range_type_entry entry[NVME_FEAT_LBA_RANGE_MAX]; }; /** - * struct nvme_plm_config - + * struct nvme_plm_config - Predictable Latency Mode - Deterministic Threshold Configuration Data Structure * @ee: Enable Event * @rsvd2: Reserved * @dtwinrt: DTWIN Reads Threshold @@ -4234,7 +4301,7 @@ struct nvme_plm_config { }; /** - * struct nvme_feat_host_behavior - + * struct nvme_feat_host_behavior - Host Behavior Support - Data Structure * @acre: Advanced Command Retry Enable * @rsvd1: Reserved */ @@ -4244,15 +4311,15 @@ struct nvme_feat_host_behavior { }; /** - * enum nvme_host_behavior_support - + * enum nvme_host_behavior_support - Enable Advanced Command * @NVME_ENABLE_ACRE: Enable Advanced Command Retry Enable */ enum nvme_host_behavior_support { - NVME_ENABLE_ACRE = 1 << 0, + NVME_ENABLE_ACRE = 1 << 0, }; /** - * struct nvme_dsm_range - + * struct nvme_dsm_range - Dataset Management - Range Definition * @cattr: Context Attributes * @nlb: Length in logical blocks * @slba: Starting LBA @@ -4264,12 +4331,13 @@ struct nvme_dsm_range { }; /** - * struct nvme_copy_range - + * struct nvme_copy_range - Copy - Source Range Entries Descriptor Format * @rsvd0: Reserved * @slba: Starting LBA * @nlb: Number of Logical Blocks * @rsvd18: Reserved - * @eilbrt: Expected Initial Logical Block Reference Tag + * @eilbrt: Expected Initial Logical Block Reference Tag / + * Expected Logical Block Storage Tag * @elbatm: Expected Logical Block Application Tag Mask * @elbat: Expected Logical Block Application Tag */ @@ -4284,7 +4352,28 @@ struct nvme_copy_range { }; /** - * struct nvme_registered_ctrl - + * struct nvme_copy_range_f1 - Copy - Source Range Entries Descriptor Format 1h + * @rsvd0: Reserved + * @slba: Starting LBA + * @nlb: Number of Logical Blocks + * @rsvd18: Reserved + * @elbt: Expected Initial Logical Block Reference Tag / + * Expected Logical Block Storage Tag + * @elbatm: Expected Logical Block Application Tag Mask + * @elbat: Expected Logical Block Application Tag + */ +struct nvme_copy_range_f1 { + __u8 rsvd0[8]; + __le64 slba; + __le16 nlb; + __u8 rsvd18[8]; + __u8 elbt[10]; + __le16 elbatm; + __le16 elbat; +}; + +/** + * struct nvme_registered_ctrl - Registered Controller Data Structure * @cntlid: Controller ID * @rcsts: Reservation Status * @rsvd3: Reserved @@ -4300,7 +4389,7 @@ struct nvme_registered_ctrl { }; /** - * struct nvme_registered_ctrl_ext - + * struct nvme_registered_ctrl_ext - Registered Controller Extended Data Structure * @cntlid: Controller ID * @rcsts: Reservation Status * @rsvd3: Reserved @@ -4318,7 +4407,7 @@ struct nvme_registered_ctrl_ext { }; /** - * struct nvme_resv_status - + * struct nvme_resv_status - Reservation Status Data Structure * @gen: Generation * @rtype: Reservation Type * @regctl: Number of Registered Controllers @@ -4346,7 +4435,7 @@ struct nvme_resv_status { }; /** - * struct nvme_streams_directive_params - + * struct nvme_streams_directive_params - Streams Directive - Return Parameters Data Structure * @msl: Max Streams Limit * @nssa: NVM Subsystem Streams Available * @nsso: NVM Subsystem Streams Open @@ -4372,7 +4461,7 @@ struct nvme_streams_directive_params { }; /** - * struct nvme_streams_directive_status - + * struct nvme_streams_directive_status - Streams Directive - Get Status Data Structure * @osc: Open Stream Count * @sid: Stream Identifier */ @@ -4382,7 +4471,7 @@ struct nvme_streams_directive_status { }; /** - * struct nvme_id_directives - + * struct nvme_id_directives - Identify Directive - Return Parameters Data Structure * @supported: Identify directive is supported * @enabled: Identify directive is Enabled * @rsvd64: Reserved @@ -4394,7 +4483,7 @@ struct nvme_id_directives { }; /** - * enum nvme_directive_types - + * enum nvme_directive_types - Directives Supported or Enabled * @NVME_ID_DIR_ID_BIT: Identify directive is supported * @NVME_ID_DIR_SD_BIT: Streams directive is supported */ @@ -4404,7 +4493,7 @@ enum nvme_directive_types { }; /** - * struct nvme_host_mem_buf_attrs - + * struct nvme_host_mem_buf_attrs - Host Memory Buffer - Attributes Data Structure * @hsize: Host Memory Buffer Size * @hmdlal: Host Memory Descriptor List Lower Address * @hmdlau: Host Memory Descriptor List Upper Address @@ -4421,7 +4510,7 @@ struct nvme_host_mem_buf_attrs { }; /** - * enum nvme_ae_type - + * enum nvme_ae_type - Asynchronous Event Type * @NVME_AER_ERROR: Error event * @NVME_AER_SMART: SMART / Health Status event * @NVME_AER_NOTICE: Notice event @@ -4429,15 +4518,15 @@ struct nvme_host_mem_buf_attrs { * @NVME_AER_VS: Vendor Specific event */ enum nvme_ae_type { - NVME_AER_ERROR = 0, - NVME_AER_SMART = 1, - NVME_AER_NOTICE = 2, - NVME_AER_CSS = 6, - NVME_AER_VS = 7, + NVME_AER_ERROR = 0, + NVME_AER_SMART = 1, + NVME_AER_NOTICE = 2, + NVME_AER_CSS = 6, + NVME_AER_VS = 7, }; /** - * enum nvme_ae_info_error - + * enum nvme_ae_info_error - Asynchronous Event Information - Error Status * @NVME_AER_ERROR_INVALID_DB_REG: Write to Invalid Doorbell Register * @NVME_AER_ERROR_INVALID_DB_VAL: Invalid Doorbell Write Value * @NVME_AER_ERROR_DIAG_FAILURE: Diagnostic Failure @@ -4455,7 +4544,7 @@ enum nvme_ae_info_error { }; /** - * enum nvme_ae_info_smart - + * enum nvme_ae_info_smart - Asynchronous Event Information - SMART / Health Status * @NVME_AER_SMART_SUBSYSTEM_RELIABILITY: NVM subsystem Reliability * @NVME_AER_SMART_TEMPERATURE_THRESHOLD: Temperature Threshold * @NVME_AER_SMART_SPARE_THRESHOLD: Spare Below Threshold @@ -4467,11 +4556,11 @@ enum nvme_ae_info_smart { }; /** - * enum nvme_ae_info_css_nvm - + * enum nvme_ae_info_css_nvm - Asynchronous Event Information - I/O Command Specific Status * @NVME_AER_CSS_NVM_RESERVATION: Reservation Log Page Available * @NVME_AER_CSS_NVM_SANITIZE_COMPLETED: Sanitize Operation Completed * @NVME_AER_CSS_NVM_UNEXPECTED_SANITIZE_DEALLOC: Sanitize Operation Completed - * With Unexpected Deallocation + * With Unexpected Deallocation */ enum nvme_ae_info_css_nvm { NVME_AER_CSS_NVM_RESERVATION = 0x00, @@ -4480,7 +4569,7 @@ enum nvme_ae_info_css_nvm { }; /** - * enum nvme_ae_info_notice - + * enum nvme_ae_info_notice - Asynchronous Event Information - Notice * @NVME_AER_NOTICE_NS_CHANGED: Namespace Attribute Changed * @NVME_AER_NOTICE_FW_ACT_STARTING: Firmware Activation Starting * @NVME_AER_NOTICE_TELEMETRY: Telemetry Log Changed @@ -4491,34 +4580,34 @@ enum nvme_ae_info_css_nvm { * @NVME_AER_NOTICE_DISC_CHANGED: Discovery Log Page Change */ enum nvme_ae_info_notice { - NVME_AER_NOTICE_NS_CHANGED = 0x00, - NVME_AER_NOTICE_FW_ACT_STARTING = 0x01, - NVME_AER_NOTICE_TELEMETRY = 0x02, - NVME_AER_NOTICE_ANA = 0x03, - NVME_AER_NOTICE_PL_EVENT = 0x04, - NVME_AER_NOTICE_LBA_STATUS_ALERT = 0x05, - NVME_AER_NOTICE_EG_EVENT = 0x06, - NVME_AER_NOTICE_DISC_CHANGED = 0xf0, + NVME_AER_NOTICE_NS_CHANGED = 0x00, + NVME_AER_NOTICE_FW_ACT_STARTING = 0x01, + NVME_AER_NOTICE_TELEMETRY = 0x02, + NVME_AER_NOTICE_ANA = 0x03, + NVME_AER_NOTICE_PL_EVENT = 0x04, + NVME_AER_NOTICE_LBA_STATUS_ALERT = 0x05, + NVME_AER_NOTICE_EG_EVENT = 0x06, + NVME_AER_NOTICE_DISC_CHANGED = 0xf0, }; /** * enum nvme_subsys_type - Type of the NVM subsystem. * @NVME_NQN_DISC: Discovery type target subsystem. Describes a referral to another - * Discovery Service composed of Discovery controllers that provide - * additional discovery records. Multiple Referral entries may - * be reported for each Discovery Service (if that Discovery Service - * has multiple NVM subsystem ports or supports multiple protocols). + * Discovery Service composed of Discovery controllers that provide + * additional discovery records. Multiple Referral entries may + * be reported for each Discovery Service (if that Discovery Service + * has multiple NVM subsystem ports or supports multiple protocols). * @NVME_NQN_NVME: NVME type target subsystem. Describes an NVM subsystem whose - * controllers may have attached namespaces (an NVM subsystem - * that is not composed of Discovery controllers). Multiple NVM - * Subsystem entries may be reported for each NVM subsystem if - * that NVM subsystem has multiple NVM subsystem ports. + * controllers may have attached namespaces (an NVM subsystem + * that is not composed of Discovery controllers). Multiple NVM + * Subsystem entries may be reported for each NVM subsystem if + * that NVM subsystem has multiple NVM subsystem ports. * @NVME_NQN_CURR: Current Discovery type target subsystem. Describes this Discovery - * subsystem (the Discovery Service that contains the controller - * processing the Get Log Page command). Multiple Current Discovery - * Subsystem entries may be reported for this Discovery subsystem - * if the current Discovery subsystem has multiple NVM subsystem - * ports. + * subsystem (the Discovery Service that contains the controller + * processing the Get Log Page command). Multiple Current Discovery + * Subsystem entries may be reported for this Discovery subsystem + * if the current Discovery subsystem has multiple NVM subsystem + * ports. */ enum nvme_subsys_type { NVME_NQN_DISC = 1, @@ -4537,26 +4626,36 @@ enum nvme_subsys_type { /** * enum nvmf_disc_eflags - Discovery Log Page entry flags. * @NVMF_DISC_EFLAGS_NONE: Indicates that none of the DUPRETINFO or EPCSD - * features are supported. + * features are supported. * @NVMF_DISC_EFLAGS_DUPRETINFO: Duplicate Returned Information (DUPRETINFO): - * Indicates that using the content of this entry - * to access this Discovery Service returns the same - * information that is returned by using the content - * of other entries in this log page that also have - * this flag set. + * Indicates that using the content of this entry + * to access this Discovery Service returns the same + * information that is returned by using the content + * of other entries in this log page that also have + * this flag set. * @NVMF_DISC_EFLAGS_EPCSD: Explicit Persistent Connection Support for Discovery (EPCSD): - * Indicates that Explicit Persistent Connections are - * supported for the Discovery controller. - * @NVMF_DISC_EFLAGS_BOTH: Indicates that both the DUPRETINFO and EPCSD - * features are supported. + * Indicates that Explicit Persistent Connections are + * supported for the Discovery controller. + * @NVMF_DISC_EFLAGS_NCC: No CDC Connectivity (NCC): If set to + * '1', then no DDC that describes this entry + * is currently connected to the CDC. If + * cleared to '0', then at least one DDC that + * describes this entry is currently + * connected to the CDC. If the Discovery + * controller returning this log page is not + * a CDC, then this bit shall be cleared to + * '0' and should be ignored by the host. */ enum nvmf_disc_eflags { NVMF_DISC_EFLAGS_NONE = 0, - NVMF_DISC_EFLAGS_DUPRETINFO = 1, - NVMF_DISC_EFLAGS_EPCSD = 2, - NVMF_DISC_EFLAGS_BOTH = 3, + NVMF_DISC_EFLAGS_DUPRETINFO = 1 << 0, + NVMF_DISC_EFLAGS_EPCSD = 1 << 1, + NVMF_DISC_EFLAGS_NCC = 1 << 2, }; +/* Backwards compatibility. Will be removed with next major release */ +#define NVMF_DISC_EFLAGS_BOTH (NVMF_DISC_EFLAGS_DUPRETINFO | NVMF_DISC_EFLAGS_EPCSD) + /** * union nvmf_tsas - Transport Specific Address Subtype * @common: Common transport specific attributes @@ -4592,47 +4691,47 @@ union nvmf_tsas { /** * struct nvmf_disc_log_entry - Discovery Log Page entry * @trtype: Transport Type (TRTYPE): Specifies the NVMe Transport type. - * See &enum nvmf_trtype. + * See &enum nvmf_trtype. * @adrfam: Address Family (ADRFAM): Specifies the address family. - * See &enum nvmf_addr_family. + * See &enum nvmf_addr_family. * @subtype: Subsystem Type (SUBTYPE): Specifies the type of the NVM subsystem - * that is indicated in this entry. See &enum nvme_subsys_type. + * that is indicated in this entry. See &enum nvme_subsys_type. * @treq: Transport Requirements (TREQ): Indicates requirements for the NVMe - * Transport. See &enum nvmf_treq. + * Transport. See &enum nvmf_treq. * @portid: Port ID (PORTID): Specifies a particular NVM subsystem port. - * Different NVMe Transports or address families may utilize the same - * Port ID value (e.g. a Port ID may support both iWARP and RoCE). + * Different NVMe Transports or address families may utilize the same + * Port ID value (e.g. a Port ID may support both iWARP and RoCE). * @cntlid: Controller ID (CNTLID): Specifies the controller ID. If the NVM - * subsystem uses a dynamic controller model, then this field shall - * be set to FFFFh. If the NVM subsystem uses a static controller model, - * then this field may be set to a specific controller ID (values 0h - * to FFEFh are valid). If the NVM subsystem uses a static controller - * model and the value indicated is FFFEh, then the host should remember - * the Controller ID returned as part of the Fabrics Connect command - * in order to re-establish an association in the future with the same - * controller. + * subsystem uses a dynamic controller model, then this field shall + * be set to FFFFh. If the NVM subsystem uses a static controller model, + * then this field may be set to a specific controller ID (values 0h + * to FFEFh are valid). If the NVM subsystem uses a static controller + * model and the value indicated is FFFEh, then the host should remember + * the Controller ID returned as part of the Fabrics Connect command + * in order to re-establish an association in the future with the same + * controller. * @asqsz: Admin Max SQ Size (ASQSZ): Specifies the maximum size of an Admin - * Submission Queue. This applies to all controllers in the NVM - * subsystem. The value shall be a minimum of 32 entries. + * Submission Queue. This applies to all controllers in the NVM + * subsystem. The value shall be a minimum of 32 entries. * @eflags: Entry Flags (EFLAGS): Indicates additional information related to - * the current entry. See &enum nvmf_disc_eflags. + * the current entry. See &enum nvmf_disc_eflags. * @rsvd12: Reserved * @trsvcid: Transport Service Identifier (TRSVCID): Specifies the NVMe Transport - * service identifier as an ASCII string. The NVMe Transport service - * identifier is specified by the associated NVMe Transport binding - * specification. + * service identifier as an ASCII string. The NVMe Transport service + * identifier is specified by the associated NVMe Transport binding + * specification. * @rsvd64: Reserved * @subnqn: NVM Subsystem Qualified Name (SUBNQN): NVMe Qualified Name (NQN) - * that uniquely identifies the NVM subsystem. For a subsystem, if that - * Discovery subsystem has a unique NQN (i.e., the NVM Subsystem NVMe - * Qualified Name (SUBNQN) field in that Discovery subsystem's Identify - * Controller data structure contains a unique NQN value), then the - * value returned shall be that unique NQN. If the Discovery subsystem - * does not have a unique NQN, then the value returned shall be the - * well-known Discovery Service NQN (nqn.2014-08.org.nvmexpress.discovery). + * that uniquely identifies the NVM subsystem. For a subsystem, if that + * Discovery subsystem has a unique NQN (i.e., the NVM Subsystem NVMe + * Qualified Name (SUBNQN) field in that Discovery subsystem's Identify + * Controller data structure contains a unique NQN value), then the + * value returned shall be that unique NQN. If the Discovery subsystem + * does not have a unique NQN, then the value returned shall be the + * well-known Discovery Service NQN (nqn.2014-08.org.nvmexpress.discovery). * @traddr: Transport Address (TRADDR): Specifies the address of the NVM subsystem - * that may be used for a Connect command as an ASCII string. The - * Address Family field describes the reference for parsing this field. + * that may be used for a Connect command as an ASCII string. The + * Address Family field describes the reference for parsing this field. * @tsas: Transport specific attribute settings */ struct nvmf_disc_log_entry { @@ -4659,7 +4758,7 @@ struct nvmf_disc_log_entry { * @NVMF_TRTYPE_FC: Fibre Channel * @NVMF_TRTYPE_TCP: TCP * @NVMF_TRTYPE_LOOP: Intra-host Transport (i.e., loopback), reserved - * for host usage. + * for host usage. * @NVMF_TRTYPE_MAX: Maximum value for &enum nvmf_trtype */ enum nvmf_trtype { @@ -4679,7 +4778,7 @@ enum nvmf_trtype { * @NVMF_ADDR_FAMILY_IB: AF_IB: InfiniBand address family. * @NVMF_ADDR_FAMILY_FC: Fibre Channel address family. * @NVMF_ADDR_FAMILY_LOOP: Intra-host Transport (i.e., loopback), reserved - * for host usage. + * for host usage. */ enum nvmf_addr_family { NVMF_ADDR_FAMILY_PCI = 0, @@ -4717,7 +4816,7 @@ enum nvmf_rdma_qptype { /** * enum nvmf_rdma_prtype - RDMA Provider Type codes for Discovery Log Page - * entry TSAS RDMA_PRTYPE field + * entry TSAS RDMA_PRTYPE field * @NVMF_RDMA_PRTYPE_NOT_SPECIFIED: No Provider Specified * @NVMF_RDMA_PRTYPE_IB: InfiniBand * @NVMF_RDMA_PRTYPE_ROCE: InfiniBand RoCE @@ -4734,7 +4833,7 @@ enum nvmf_rdma_prtype { /** * enum nvmf_rdma_cms - RDMA Connection Management Service Type codes for - * Discovery Log Page entry TSAS RDMA_CMS field + * Discovery Log Page entry TSAS RDMA_CMS field * @NVMF_RDMA_CMS_RDMA_CM: Sockets based endpoint addressing * */ @@ -4744,12 +4843,12 @@ enum nvmf_rdma_cms { /** * enum nvmf_tcp_sectype - Transport Specific Address Subtype Definition for - * NVMe/TCP Transport + * NVMe/TCP Transport * @NVMF_TCP_SECTYPE_NONE: No Security * @NVMF_TCP_SECTYPE_TLS: Transport Layer Security version 1.2 * @NVMF_TCP_SECTYPE_TLS13: Transport Layer Security version 1.3 or a subsequent - * version. The TLS protocol negotiates the version and - * cipher suite for each TCP connection. + * version. The TLS protocol negotiates the version and + * cipher suite for each TCP connection. */ enum nvmf_tcp_sectype { NVMF_TCP_SECTYPE_NONE = 0, @@ -4760,15 +4859,15 @@ enum nvmf_tcp_sectype { /** * struct nvmf_discovery_log - Discovery Log Page (Log Identifier 70h) * @genctr: Generation Counter (GENCTR): Indicates the version of the discovery - * information, starting at a value of 0h. For each change in the - * Discovery Log Page, this counter is incremented by one. If the value - * of this field is FFFFFFFF_FFFFFFFFh, then the field shall be cleared - * to 0h when incremented (i.e., rolls over to 0h). + * information, starting at a value of 0h. For each change in the + * Discovery Log Page, this counter is incremented by one. If the value + * of this field is FFFFFFFF_FFFFFFFFh, then the field shall be cleared + * to 0h when incremented (i.e., rolls over to 0h). * @numrec: Number of Records (NUMREC): Indicates the number of records - * contained in the log. + * contained in the log. * @recfmt: Record Format (RECFMT): Specifies the format of the Discovery Log - * Page. If a new format is defined, this value is incremented by one. - * The format of the record specified in this definition shall be 0h. + * Page. If a new format is defined, this value is incremented by one. + * The format of the record specified in this definition shall be 0h. * @rsvd14: Reserved * @entries: Discovery Log Page Entries - see &struct nvmf_disc_log_entry. */ @@ -4804,8 +4903,7 @@ enum nvmf_dim_tas { * @NVMF_DIM_ENTFMT_BASIC: Basic discovery information entry * @NVMF_DIM_ENTFMT_EXTENDED: Extended discovery information entry */ -enum nvmf_dim_entfmt -{ +enum nvmf_dim_entfmt { NVMF_DIM_ENTFMT_BASIC = 0x01, NVMF_DIM_ENTFMT_EXTENDED = 0x02, }; @@ -4813,11 +4911,10 @@ enum nvmf_dim_entfmt /** * enum nvmf_dim_etype -Discovery Information Management Entity Type * @NVMF_DIM_ETYPE_HOST: Host - * @NVMF_DIM_ETYPE_DDC: Direct Discovery controller - * @NVMF_DIM_ETYPE_CDC: Centralized Discovery controller + * @NVMF_DIM_ETYPE_DDC: Direct Discovery controller + * @NVMF_DIM_ETYPE_CDC: Centralized Discovery controller */ -enum nvmf_dim_etype -{ +enum nvmf_dim_etype { NVMF_DIM_ETYPE_HOST = 0x01, NVMF_DIM_ETYPE_DDC = 0x02, NVMF_DIM_ETYPE_CDC = 0x03, @@ -4828,8 +4925,7 @@ enum nvmf_dim_etype * @NVMF_EXATTYPE_HOSTID: Host Identifier * @NVMF_EXATTYPE_SYMNAME: Symblic Name */ -enum nvmf_exattype -{ +enum nvmf_exattype { NVMF_EXATTYPE_HOSTID = 0x01, NVMF_EXATTYPE_SYMNAME = 0x02, }; @@ -4839,10 +4935,9 @@ enum nvmf_exattype * @exattype: Extended Attribute Type (EXATTYPE) - see @enum nvmf_exattype * @exatlen: Extended Attribute Length (EXATLEN) * @exatval: Extended Attribute Value (EXATVAL) - size allocated for array - * must be a multiple of 4 bytes + * must be a multiple of 4 bytes */ -struct nvmf_ext_attr -{ +struct nvmf_ext_attr { __le16 exattype; __le16 exatlen; __u8 exatval[]; @@ -4866,10 +4961,9 @@ struct nvmf_ext_attr * @tel: Total Entry Length * @numexat: Number of Extended Attributes * @resv1030: Reserved - * @exat: Extented Attributes 0 (&struct nvmf_ext_attr) + * @exat: Extended Attributes 0 (&struct nvmf_ext_attr) */ -struct nvmf_ext_die -{ +struct nvmf_ext_die { __u8 trtype; __u8 adrfam; __u8 subtype; @@ -4903,12 +4997,11 @@ struct nvmf_ext_die * "extended" field is akin to a linked-list, where one can "walk" * through the list. To move to the next entry, one simply adds the * current entry's length (TEL) to the "walk" pointer. The number of - * entries in the list is specified by NUMENT. Although extended - * entries are of a variable lengths (TEL), TEL is always a mutiple of + * entries in the list is specified by NUMENT. Although extended + * entries are of a variable lengths (TEL), TEL is always a multiple of * 4 bytes. */ -union nvmf_die -{ +union nvmf_die { struct nvmf_disc_log_entry basic[0]; struct nvmf_ext_die extended; }; @@ -4929,8 +5022,7 @@ union nvmf_die * @rsvd600: Reserved * @die: Discovery Information Entry (see @nument above) */ -struct nvmf_dim_data -{ +struct nvmf_dim_data { __le32 tdl; __u8 rsvd4[4]; __le64 nument; @@ -4965,7 +5057,7 @@ struct nvmf_connect_data { }; /** - * struct nvme_mi_read_nvm_ss_info - + * struct nvme_mi_read_nvm_ss_info - NVM Subsystem Information Data Structure * @nump: Number of Ports * @mjr: NVMe-MI Major Version Number * @mnr: NVMe-MI Minor Version Number @@ -4979,7 +5071,7 @@ struct nvme_mi_read_nvm_ss_info { }; /** - * struct nvme_mi_port_pcie - + * struct nvme_mi_port_pcie - PCIe Port Specific Data * @mps: PCIe Maximum Payload Size * @sls: PCIe Supported Link Speeds Vector * @cls: PCIe Current Link Speed @@ -4999,7 +5091,7 @@ struct nvme_mi_port_pcie { }; /** - * struct nvme_mi_port_smb - + * struct nvme_mi_port_smb - SMBus Port Specific Data * @vpd_addr: Current VPD SMBus/I2C Address * @mvpd_freq: Maximum VPD Access SMBus/I2C Frequency * @mme_addr: Current Management Endpoint SMBus/I2C Address @@ -5017,7 +5109,7 @@ struct nvme_mi_port_smb { }; /** - * struct nvme_mi_read_port_info - + * struct nvme_mi_read_port_info - Port Information Data Structure * @portt: Port Type * @rsvd1: Reserved * @mmctptus: Maximum MCTP Transmission Unit Size @@ -5037,7 +5129,7 @@ struct nvme_mi_read_port_info { }; /** - * struct nvme_mi_read_ctrl_info - + * struct nvme_mi_read_ctrl_info - Controller Information Data Structure * @portid: Port Identifier * @rsvd1: Reserved * @prii: PCIe Routing ID Information @@ -5061,7 +5153,7 @@ struct nvme_mi_read_ctrl_info { }; /** - * struct nvme_mi_osc - + * struct nvme_mi_osc - Optionally Supported Command Data Structure * @type: Command Type * @opc: Opcode */ @@ -5071,9 +5163,10 @@ struct nvme_mi_osc { }; /** - * struct nvme_mi_read_sc_list - + * struct nvme_mi_read_sc_list - Management Endpoint Buffer Supported Command List Data Structure * @numcmd: Number of Commands - * @cmds: MEB supported Command Data Structure + * @cmds: MEB supported Command Data Structure. + * See @struct nvme_mi_osc */ struct nvme_mi_read_sc_list { __le16 numcmd; @@ -5081,7 +5174,7 @@ struct nvme_mi_read_sc_list { }; /** - * struct nvme_mi_nvm_ss_health_status - + * struct nvme_mi_nvm_ss_health_status - Subsystem Management Data Structure * @nss: NVM Subsystem Status * @sw: Smart Warnings * @ctemp: Composite Temperature @@ -5099,37 +5192,51 @@ struct nvme_mi_nvm_ss_health_status { }; /** - * enum nvme_mi_css - + * enum nvme_mi_ccs - Get State Control Primitive Success Response Fields - Control Primitive Specific Response * @NVME_MI_CCS_RDY: Ready - * @NVME_MI_CSS_CFS: Controller Fatal Status - * @NVME_MI_CSS_SHST: Shutdown Status - * @NVME_MI_CSS_NSSRO: NVM Subsystem Reset Occurred - * @NVME_MI_CSS_CECO: Controller Enable Change Occurred - * @NVME_MI_CSS_NAC: Namespace Attribute Changed - * @NVME_MI_CSS_FA: Firmware Activated - * @NVME_MI_CSS_CSTS: Controller Status Change - * @NVME_MI_CSS_CTEMP: Composite Temperature Change - * @NVME_MI_CSS_PDLU: Percentage Used - * @NVME_MI_CSS_SPARE: Available Spare - * @NVME_MI_CSS_CCWARN: Critical Warning - */ -enum nvme_mi_css { + * @NVME_MI_CCS_CFS: Controller Fatal Status + * @NVME_MI_CCS_SHST: Shutdown Status + * @NVME_MI_CCS_NSSRO: NVM Subsystem Reset Occurred + * @NVME_MI_CCS_CECO: Controller Enable Change Occurred + * @NVME_MI_CCS_NAC: Namespace Attribute Changed + * @NVME_MI_CCS_FA: Firmware Activated + * @NVME_MI_CCS_CSTS: Controller Status Change + * @NVME_MI_CCS_CTEMP: Composite Temperature Change + * @NVME_MI_CCS_PDLU: Percentage Used + * @NVME_MI_CCS_SPARE: Available Spare + * @NVME_MI_CCS_CCWARN: Critical Warning + */ +enum nvme_mi_ccs { NVME_MI_CCS_RDY = 1 << 0, - NVME_MI_CSS_CFS = 1 << 1, - NVME_MI_CSS_SHST = 1 << 2, - NVME_MI_CSS_NSSRO = 1 << 4, - NVME_MI_CSS_CECO = 1 << 5, - NVME_MI_CSS_NAC = 1 << 6, - NVME_MI_CSS_FA = 1 << 7, - NVME_MI_CSS_CSTS = 1 << 8, - NVME_MI_CSS_CTEMP = 1 << 9, - NVME_MI_CSS_PDLU = 1 << 10, - NVME_MI_CSS_SPARE = 1 << 11, - NVME_MI_CSS_CCWARN = 1 << 12, -}; - -/** - * struct nvme_mi_ctrl_health_status - + NVME_MI_CCS_CFS = 1 << 1, + NVME_MI_CCS_SHST = 1 << 2, + NVME_MI_CCS_NSSRO = 1 << 4, + NVME_MI_CCS_CECO = 1 << 5, + NVME_MI_CCS_NAC = 1 << 6, + NVME_MI_CCS_FA = 1 << 7, + NVME_MI_CCS_CSTS = 1 << 8, + NVME_MI_CCS_CTEMP = 1 << 9, + NVME_MI_CCS_PDLU = 1 << 10, + NVME_MI_CCS_SPARE = 1 << 11, + NVME_MI_CCS_CCWARN = 1 << 12, +}; + +/* backwards compat for old "CCS" definitions */ +#define nvme_mi_css nvme_mi_ccs +#define NVME_MI_CSS_CFS NVME_MI_CCS_CFS +#define NVME_MI_CSS_SHST NVME_MI_CCS_SHST +#define NVME_MI_CSS_NSSRO NVME_MI_CCS_NSSRO +#define NVME_MI_CSS_CECO NVME_MI_CCS_CECO +#define NVME_MI_CSS_NAC NVME_MI_CCS_NAC +#define NVME_MI_CSS_FA NVME_MI_CCS_FA +#define NVME_MI_CSS_CSTS NVME_MI_CCS_CSTS +#define NVME_MI_CSS_CTEMP NVME_MI_CCS_CTEMP +#define NVME_MI_CSS_PDLU NVME_MI_CCS_PDLU +#define NVME_MI_CSS_SPARE NVME_MI_CCS_SPARE +#define NVME_MI_CSS_CCWARN NVME_MI_CCS_CCWARN + +/** + * struct nvme_mi_ctrl_health_status - Controller Health Data Structure (CHDS) * @ctlid: Controller Identifier * @csts: Controller Status * @ctemp: Composite Temperature @@ -5149,7 +5256,7 @@ struct nvme_mi_ctrl_health_status { }; /** - * enum nvme_mi_csts - + * enum nvme_mi_csts - Controller Health Data Structure (CHDS) - Controller Status (CSTS) * @NVME_MI_CSTS_RDY: Ready * @NVME_MI_CSTS_CFS: Controller Fatal Status * @NVME_MI_CSTS_SHST: Shutdown Status @@ -5169,7 +5276,7 @@ enum nvme_mi_csts { }; /** - * enum nvme_mi_cwarn - + * enum nvme_mi_cwarn - Controller Health Data Structure (CHDS) - Critical Warning (CWARN) * @NVME_MI_CWARN_ST: Spare Threshold * @NVME_MI_CWARN_TAUT: Temperature Above or Under Threshold * @NVME_MI_CWARN_RD: Reliability Degraded @@ -5185,7 +5292,7 @@ enum nvme_mi_cwarn { }; /** - * struct nvme_mi_vpd_mra - + * struct nvme_mi_vpd_mra - NVMe MultiRecord Area * @nmravn: NVMe MultiRecord Area Version Number * @ff: Form Factor * @rsvd7: Reserved @@ -5194,7 +5301,7 @@ enum nvme_mi_cwarn { * @i33vpwr: Initial 3.3 V Power Supply Requirements * @m33vpwr: Maximum 3.3 V Power Supply Requirements * @rsvd17: Reserved - * @m33vapsr: Maximum 3.3 V aux Power Supply Requirements + * @m33vapsr: Maximum 3.3 Vi aux Power Supply Requirements * @i5vapsr: Initial 5 V Power Supply Requirements * @m5vapsr: Maximum 5 V Power Supply Requirements * @i12vapsr: Initial 12 V Power Supply Requirements @@ -5223,7 +5330,7 @@ struct nvme_mi_vpd_mra { }; /** - * struct nvme_mi_vpd_ppmra - + * struct nvme_mi_vpd_ppmra - NVMe PCIe Port MultiRecord Area * @nppmravn: NVMe PCIe Port MultiRecord Area Version Number * @pn: PCIe Port Number * @ppi: Port Information @@ -5247,12 +5354,12 @@ struct nvme_mi_vpd_ppmra { }; /** - * struct nvme_mi_vpd_telem - + * struct nvme_mi_vpd_telem - Vital Product Data Element Descriptor * @type: Type of the Element Descriptor * @rev: Revision of the Element Descriptor * @len: Number of bytes in the Element Descriptor * @data: Type-specific information associated with - * the Element Descriptor + * the Element Descriptor */ struct nvme_mi_vpd_telem { __u8 type; @@ -5262,7 +5369,7 @@ struct nvme_mi_vpd_telem { }; /** - * enum nvme_mi_elem - + * enum nvme_mi_elem - Element Descriptor Types * @NVME_MI_ELEM_EED: Extended Element Descriptor * @NVME_MI_ELEM_USCE: Upstream Connector Element Descriptor * @NVME_MI_ELEM_ECED: Expansion Connector Element Descriptor @@ -5282,7 +5389,7 @@ enum nvme_mi_elem { }; /** - * struct nvme_mi_vpd_tra - + * struct nvme_mi_vpd_tra - Vital Product Data Topology MultiRecord * @vn: Version Number * @rsvd6: Reserved * @ec: Element Count @@ -5296,7 +5403,7 @@ struct nvme_mi_vpd_tra { }; /** - * struct nvme_mi_vpd_mr_common - + * struct nvme_mi_vpd_mr_common - NVMe MultiRecord Area * @type: NVMe Record Type ID * @rf: Record Format * @rlen: Record Length @@ -5321,7 +5428,7 @@ struct nvme_mi_vpd_mr_common { }; /** - * struct nvme_mi_vpd_hdr - + * struct nvme_mi_vpd_hdr - Vital Product Data Common Header * @ipmiver: IPMI Format Version Number * @iuaoff: Internal Use Area Starting Offset * @ciaoff: Chassis Info Area Starting Offset @@ -5346,178 +5453,182 @@ struct nvme_mi_vpd_hdr { /** * enum nvme_status_field - Defines all parts of the nvme status field: status - * code, status code type, and additional flags. + * code, status code type, and additional flags. * @NVME_SCT_GENERIC: Generic errors applicable to multiple opcodes * @NVME_SCT_CMD_SPECIFIC: Errors associated to a specific opcode * @NVME_SCT_MEDIA: Errors associated with media and data integrity * @NVME_SCT_PATH: Errors associated with the paths connection * @NVME_SCT_VS: Vendor specific errors * @NVME_SCT_MASK: Mask to get the value of the Status Code Type + * @NVME_SCT_SHIFT: Shift value to get the value of the Status + * Code Type * @NVME_SC_MASK: Mask to get the value of the status code. + * @NVME_SC_SHIFT: Shift value to get the value of the status + * code. * @NVME_SC_SUCCESS: Successful Completion: The command - * completed without error. + * completed without error. * @NVME_SC_INVALID_OPCODE: Invalid Command Opcode: A reserved coded - * value or an unsupported value in the - * command opcode field. + * value or an unsupported value in the + * command opcode field. * @NVME_SC_INVALID_FIELD: Invalid Field in Command: A reserved - * coded value or an unsupported value in a - * defined field. + * coded value or an unsupported value in a + * defined field. * @NVME_SC_CMDID_CONFLICT: Command ID Conflict: The command - * identifier is already in use. + * identifier is already in use. * @NVME_SC_DATA_XFER_ERROR: Data Transfer Error: Transferring the - * data or metadata associated with a - * command experienced an error. + * data or metadata associated with a + * command experienced an error. * @NVME_SC_POWER_LOSS: Commands Aborted due to Power Loss - * Notification: Indicates that the command - * was aborted due to a power loss - * notification. + * Notification: Indicates that the command + * was aborted due to a power loss + * notification. * @NVME_SC_INTERNAL: Internal Error: The command was not - * completed successfully due to an internal error. + * completed successfully due to an internal error. * @NVME_SC_ABORT_REQ: Command Abort Requested: The command was - * aborted due to an Abort command being - * received that specified the Submission - * Queue Identifier and Command Identifier - * of this command. + * aborted due to an Abort command being + * received that specified the Submission + * Queue Identifier and Command Identifier + * of this command. * @NVME_SC_ABORT_QUEUE: Command Aborted due to SQ Deletion: The - * command was aborted due to a Delete I/O - * Submission Queue request received for the - * Submission Queue to which the command was - * submitted. + * command was aborted due to a Delete I/O + * Submission Queue request received for the + * Submission Queue to which the command was + * submitted. * @NVME_SC_FUSED_FAIL: Command Aborted due to Failed Fused Command: - * The command was aborted due to the other - * command in a fused operation failing. + * The command was aborted due to the other + * command in a fused operation failing. * @NVME_SC_FUSED_MISSING: Aborted due to Missing Fused Command: The - * fused command was aborted due to the - * adjacent submission queue entry not - * containing a fused command that is the - * other command. + * fused command was aborted due to the + * adjacent submission queue entry not + * containing a fused command that is the + * other command. * @NVME_SC_INVALID_NS: Invalid Namespace or Format: The - * namespace or the format of that namespace - * is invalid. + * namespace or the format of that namespace + * is invalid. * @NVME_SC_CMD_SEQ_ERROR: Command Sequence Error: The command was - * aborted due to a protocol violation in a - * multi-command sequence. + * aborted due to a protocol violation in a + * multi-command sequence. * @NVME_SC_SGL_INVALID_LAST: Invalid SGL Segment Descriptor: The - * command includes an invalid SGL Last - * Segment or SGL Segment descriptor. + * command includes an invalid SGL Last + * Segment or SGL Segment descriptor. * @NVME_SC_SGL_INVALID_COUNT: Invalid Number of SGL Descriptors: There - * is an SGL Last Segment descriptor or an - * SGL Segment descriptor in a location - * other than the last descriptor of a - * segment based on the length indicated. + * is an SGL Last Segment descriptor or an + * SGL Segment descriptor in a location + * other than the last descriptor of a + * segment based on the length indicated. * @NVME_SC_SGL_INVALID_DATA: Data SGL Length Invalid: This may occur - * if the length of a Data SGL is too short. - * This may occur if the length of a Data - * SGL is too long and the controller does - * not support SGL transfers longer than the - * amount of data to be transferred as - * indicated in the SGL Support field of the - * Identify Controller data structure. + * if the length of a Data SGL is too short. + * This may occur if the length of a Data + * SGL is too long and the controller does + * not support SGL transfers longer than the + * amount of data to be transferred as + * indicated in the SGL Support field of the + * Identify Controller data structure. * @NVME_SC_SGL_INVALID_METADATA: Metadata SGL Length Invalid: This may - * occur if the length of a Metadata SGL is - * too short. This may occur if the length - * of a Metadata SGL is too long and the - * controller does not support SGL transfers - * longer than the amount of data to be - * transferred as indicated in the SGL - * Support field of the Identify Controller - * data structure. + * occur if the length of a Metadata SGL is + * too short. This may occur if the length + * of a Metadata SGL is too long and the + * controller does not support SGL transfers + * longer than the amount of data to be + * transferred as indicated in the SGL + * Support field of the Identify Controller + * data structure. * @NVME_SC_SGL_INVALID_TYPE: SGL Descriptor Type Invalid: The type of - * an SGL Descriptor is a type that is not - * supported by the controller. + * an SGL Descriptor is a type that is not + * supported by the controller. * @NVME_SC_CMB_INVALID_USE: Invalid Use of Controller Memory Buffer: - * The attempted use of the Controller - * Memory Buffer is not supported by the - * controller. - * @NVME_SC_PRP_INVALID_OFFSET: PRP Offset Invalid: The Offset field for - * a PRP entry is invalid. + * The attempted use of the Controller + * Memory Buffer is not supported by the + * controller. + * @NVME_SC_PRP_INVALID_OFFSET: PRP Offset Invalid: The Offset field for + * a PRP entry is invalid. * @NVME_SC_AWU_EXCEEDED: Atomic Write Unit Exceeded: The length - * specified exceeds the atomic write unit size. + * specified exceeds the atomic write unit size. * @NVME_SC_OP_DENIED: Operation Denied: The command was denied - * due to lack of access rights. Refer to - * the appropriate security specification. + * due to lack of access rights. Refer to + * the appropriate security specification. * @NVME_SC_SGL_INVALID_OFFSET: SGL Offset Invalid: The offset specified - * in a descriptor is invalid. This may - * occur when using capsules for data - * transfers in NVMe over Fabrics - * implementations and an invalid offset in - * the capsule is specified. + * in a descriptor is invalid. This may + * occur when using capsules for data + * transfers in NVMe over Fabrics + * implementations and an invalid offset in + * the capsule is specified. * @NVME_SC_HOSTID_FORMAT: Host Identifier Inconsistent Format: The - * NVM subsystem detected the simultaneous - * use of 64- bit and 128-bit Host - * Identifier values on different - * controllers. + * NVM subsystem detected the simultaneous + * use of 64- bit and 128-bit Host + * Identifier values on different + * controllers. * @NVME_SC_KAT_EXPIRED: Keep Alive Timer Expired: The Keep Alive - * Timer expired. + * Timer expired. * @NVME_SC_KAT_INVALID: Keep Alive Timeout Invalid: The Keep - * Alive Timeout value specified is invalid. + * Alive Timeout value specified is invalid. * @NVME_SC_CMD_ABORTED_PREMEPT: Command Aborted due to Preempt and Abort: - * The command was aborted due to a - * Reservation Acquire command. + * The command was aborted due to a + * Reservation Acquire command. * @NVME_SC_SANITIZE_FAILED: Sanitize Failed: The most recent sanitize - * operation failed and no recovery action - * has been successfully completed. + * operation failed and no recovery action + * has been successfully completed. * @NVME_SC_SANITIZE_IN_PROGRESS: Sanitize In Progress: The requested - * function (e.g., command) is prohibited - * while a sanitize operation is in - * progress. + * function (e.g., command) is prohibited + * while a sanitize operation is in + * progress. * @NVME_SC_SGL_INVALID_GRANULARITY: SGL Data Block Granularity Invalid: The - * Address alignment or Length granularity - * for an SGL Data Block descriptor is - * invalid. + * Address alignment or Length granularity + * for an SGL Data Block descriptor is + * invalid. * @NVME_SC_CMD_IN_CMBQ_NOT_SUPP: Command Not Supported for Queue in CMB: - * The implementation does not support - * submission of the command to a Submission - * Queue in the Controller Memory Buffer or - * command completion to a Completion Queue - * in the Controller Memory Buffer. + * The implementation does not support + * submission of the command to a Submission + * Queue in the Controller Memory Buffer or + * command completion to a Completion Queue + * in the Controller Memory Buffer. * @NVME_SC_NS_WRITE_PROTECTED: Namespace is Write Protected: The command - * is prohibited while the namespace is - * write protected as a result of a change - * in the namespace write protection state - * as defined by the Namespace Write - * Protection State Machine. + * is prohibited while the namespace is + * write protected as a result of a change + * in the namespace write protection state + * as defined by the Namespace Write + * Protection State Machine. * @NVME_SC_CMD_INTERRUPTED: Command Interrupted: Command processing - * was interrupted and the controller is - * unable to successfully complete the - * command. The host should retry the - * command. + * was interrupted and the controller is + * unable to successfully complete the + * command. The host should retry the + * command. * @NVME_SC_TRAN_TPORT_ERROR: Transient Transport Error: A transient - * transport error was detected. If the - * command is retried on the same - * controller, the command is likely to - * succeed. A command that fails with a - * transient transport error four or more - * times should be treated as a persistent - * transport error that is not likely to - * succeed if retried on the same - * controller. + * transport error was detected. If the + * command is retried on the same + * controller, the command is likely to + * succeed. A command that fails with a + * transient transport error four or more + * times should be treated as a persistent + * transport error that is not likely to + * succeed if retried on the same + * controller. * @NVME_SC_PROHIBITED_BY_CMD_AND_FEAT: Command Prohibited by Command and Feature - * Lockdown: The command was aborted due to - * command execution being prohibited by - * the Command and Feature Lockdown. + * Lockdown: The command was aborted due to + * command execution being prohibited by + * the Command and Feature Lockdown. * @NVME_SC_ADMIN_CMD_MEDIA_NOT_READY: Admin Command Media Not Ready: The Admin - * command requires access to media and - * the media is not ready. + * command requires access to media and + * the media is not ready. * @NVME_SC_LBA_RANGE: LBA Out of Range: The command references - * an LBA that exceeds the size of the namespace. + * an LBA that exceeds the size of the namespace. * @NVME_SC_CAP_EXCEEDED: Capacity Exceeded: Execution of the - * command has caused the capacity of the - * namespace to be exceeded. + * command has caused the capacity of the + * namespace to be exceeded. * @NVME_SC_NS_NOT_READY: Namespace Not Ready: The namespace is not - * ready to be accessed as a result of a - * condition other than a condition that is - * reported as an Asymmetric Namespace - * Access condition. + * ready to be accessed as a result of a + * condition other than a condition that is + * reported as an Asymmetric Namespace + * Access condition. * @NVME_SC_RESERVATION_CONFLICT: Reservation Conflict: The command was - * aborted due to a conflict with a - * reservation held on the accessed - * namespace. + * aborted due to a conflict with a + * reservation held on the accessed + * namespace. * @NVME_SC_FORMAT_IN_PROGRESS: Format In Progress: A Format NVM command - * is in progress on the namespace. + * is in progress on the namespace. * @NVME_SC_CQ_INVALID: Completion Queue Invalid: The Completion - * Queue identifier specified in the command - * does not exist. + * Queue identifier specified in the command + * does not exist. * @NVME_SC_QID_INVALID: Invalid Queue Identifier: The creation of * the I/O Completion Queue failed due to an * invalid queue identifier specified as @@ -5526,121 +5637,121 @@ struct nvme_mi_vpd_hdr { * use or one that is outside the range * supported by the controller. * @NVME_SC_QUEUE_SIZE: Invalid Queue Size: The host attempted to - * create an I/O Completion Queue with an - * invalid number of entries. + * create an I/O Completion Queue with an + * invalid number of entries. * @NVME_SC_ABORT_LIMIT: Abort Command Limit Exceeded: The number - * of concurrently outstanding Abort commands - * has exceeded the limit indicated in the - * Identify Controller data structure. + * of concurrently outstanding Abort commands + * has exceeded the limit indicated in the + * Identify Controller data structure. * @NVME_SC_ABORT_MISSING: Abort Command is missing: The abort - * command is missing. + * command is missing. * @NVME_SC_ASYNC_LIMIT: Asynchronous Event Request Limit - * Exceeded: The number of concurrently - * outstanding Asynchronous Event Request - * commands has been exceeded. + * Exceeded: The number of concurrently + * outstanding Asynchronous Event Request + * commands has been exceeded. * @NVME_SC_FIRMWARE_SLOT: Invalid Firmware Slot: The firmware slot - * indicated is invalid or read only. This - * error is indicated if the firmware slot - * exceeds the number supported. + * indicated is invalid or read only. This + * error is indicated if the firmware slot + * exceeds the number supported. * @NVME_SC_FIRMWARE_IMAGE: Invalid Firmware Image: The firmware - * image specified for activation is invalid - * and not loaded by the controller. + * image specified for activation is invalid + * and not loaded by the controller. * @NVME_SC_INVALID_VECTOR: Invalid Interrupt Vector: The creation of - * the I/O Completion Queue failed due to an - * invalid interrupt vector specified as - * part of the command. + * the I/O Completion Queue failed due to an + * invalid interrupt vector specified as + * part of the command. * @NVME_SC_INVALID_LOG_PAGE: Invalid Log Page: The log page indicated - * is invalid. This error condition is also - * returned if a reserved log page is - * requested. + * is invalid. This error condition is also + * returned if a reserved log page is + * requested. * @NVME_SC_INVALID_FORMAT: Invalid Format: The LBA Format specified - * is not supported. + * is not supported. * @NVME_SC_FW_NEEDS_CONV_RESET: Firmware Activation Requires Conventional Reset: - * The firmware commit was successful, - * however, activation of the firmware image - * requires a conventional reset. + * The firmware commit was successful, + * however, activation of the firmware image + * requires a conventional reset. * @NVME_SC_INVALID_QUEUE: Invalid Queue Deletion: Invalid I/O - * Completion Queue specified to delete. + * Completion Queue specified to delete. * @NVME_SC_FEATURE_NOT_SAVEABLE: Feature Identifier Not Saveable: The - * Feature Identifier specified does not - * support a saveable value. + * Feature Identifier specified does not + * support a saveable value. * @NVME_SC_FEATURE_NOT_CHANGEABLE: Feature Not Changeable: The Feature - * Identifier is not able to be changed. + * Identifier is not able to be changed. * @NVME_SC_FEATURE_NOT_PER_NS: Feature Not Namespace Specific: The - * Feature Identifier specified is not - * namespace specific. The Feature - * Identifier settings apply across all - * namespaces. + * Feature Identifier specified is not + * namespace specific. The Feature + * Identifier settings apply across all + * namespaces. * @NVME_SC_FW_NEEDS_SUBSYS_RESET: Firmware Activation Requires NVM - * Subsystem Reset: The firmware commit was - * successful, however, activation of the - * firmware image requires an NVM Subsystem. + * Subsystem Reset: The firmware commit was + * successful, however, activation of the + * firmware image requires an NVM Subsystem. * @NVME_SC_FW_NEEDS_RESET: Firmware Activation Requires Controller - * Level Reset: The firmware commit was - * successful; however, the image specified - * does not support being activated without - * a reset. + * Level Reset: The firmware commit was + * successful; however, the image specified + * does not support being activated without + * a reset. * @NVME_SC_FW_NEEDS_MAX_TIME: Firmware Activation Requires Maximum Time - * Violation: The image specified if - * activated immediately would exceed the - * Maximum Time for Firmware Activation - * (MTFA) value reported in Identify - * Controller. + * Violation: The image specified if + * activated immediately would exceed the + * Maximum Time for Firmware Activation + * (MTFA) value reported in Identify + * Controller. * @NVME_SC_FW_ACTIVATE_PROHIBITED: Firmware Activation Prohibited: The image - * specified is being prohibited from - * activation by the controller for vendor - * specific reasons. + * specified is being prohibited from + * activation by the controller for vendor + * specific reasons. * @NVME_SC_OVERLAPPING_RANGE: Overlapping Range: The downloaded - * firmware image has overlapping ranges. + * firmware image has overlapping ranges. * @NVME_SC_NS_INSUFFICIENT_CAP: Namespace Insufficient Capacity: Creating - * the namespace requires more free space - * than is currently available. + * the namespace requires more free space + * than is currently available. * @NVME_SC_NS_ID_UNAVAILABLE: Namespace Identifier Unavailable: The - * number of namespaces supported has been - * exceeded. + * number of namespaces supported has been + * exceeded. * @NVME_SC_NS_ALREADY_ATTACHED: Namespace Already Attached: The - * controller is already attached to the - * namespace specified. + * controller is already attached to the + * namespace specified. * @NVME_SC_NS_IS_PRIVATE: Namespace Is Private: The namespace is - * private and is already attached to one - * controller. + * private and is already attached to one + * controller. * @NVME_SC_NS_NOT_ATTACHED: Namespace Not Attached: The request to - * detach the controller could not be - * completed because the controller is not - * attached to the namespace. + * detach the controller could not be + * completed because the controller is not + * attached to the namespace. * @NVME_SC_THIN_PROV_NOT_SUPP: Thin Provisioning Not Supported: Thin - * provisioning is not supported by the - * controller. + * provisioning is not supported by the + * controller. * @NVME_SC_CTRL_LIST_INVALID: Controller List Invalid: The controller - * list provided contains invalid controller - * ids. + * list provided contains invalid controller + * ids. * @NVME_SC_SELF_TEST_IN_PROGRESS: Device Self-test In Progress: The controller - * or NVM subsystem already has a device - * self-test operation in process. + * or NVM subsystem already has a device + * self-test operation in process. * @NVME_SC_BP_WRITE_PROHIBITED: Boot Partition Write Prohibited: The - * command is trying to modify a locked Boot - * Partition. + * command is trying to modify a locked Boot + * Partition. * @NVME_SC_INVALID_CTRL_ID: Invalid Controller Identifier: * @NVME_SC_INVALID_SEC_CTRL_STATE: Invalid Secondary Controller State * @NVME_SC_INVALID_CTRL_RESOURCES: Invalid Number of Controller Resources * @NVME_SC_INVALID_RESOURCE_ID: Invalid Resource Identifier * @NVME_SC_PMR_SAN_PROHIBITED: Sanitize Prohibited While Persistent - * Memory Region is Enabled + * Memory Region is Enabled * @NVME_SC_ANA_GROUP_ID_INVALID: ANA Group Identifier Invalid: The specified - * ANA Group Identifier (ANAGRPID) is not - * supported in the submitted command. + * ANA Group Identifier (ANAGRPID) is not + * supported in the submitted command. * @NVME_SC_ANA_ATTACH_FAILED: ANA Attach Failed: The controller is not - * attached to the namespace as a result - * of an ANA condition. + * attached to the namespace as a result + * of an ANA condition. * @NVME_SC_INSUFFICIENT_CAP: Insufficient Capacity: Requested operation - * requires more free space than is currently - * available. + * requires more free space than is currently + * available. * @NVME_SC_NS_ATTACHMENT_LIMIT_EXCEEDED: Namespace Attachment Limit Exceeded: - * Attaching the ns to a controller causes - * max number of ns attachments allowed - * to be exceeded. + * Attaching the ns to a controller causes + * max number of ns attachments allowed + * to be exceeded. * @NVME_SC_PROHIBIT_CMD_EXEC_NOT_SUPPORTED: Prohibition of Command Execution - * Not Supported + * Not Supported * @NVME_SC_IOCS_NOT_SUPPORTED: I/O Command Set Not Supported * @NVME_SC_IOCS_NOT_ENABLED: I/O Command Set Not Enabled * @NVME_SC_IOCS_COMBINATION_REJECTED: I/O Command Set Combination Rejected @@ -5668,7 +5779,7 @@ struct nvme_mi_vpd_hdr { * transient condition. * @NVME_SC_REQSTD_FUNCTION_DISABLED: Fabric Zoning is not enabled on the * CDC - * @NVME_SC_ZONEGRP_ORIGINATOR_INVL: The NQN contained in the ZoneGroup + * @NVME_SC_ZONEGRP_ORIGINATOR_INVLD: The NQN contained in the ZoneGroup * Originator field does not match the * Host NQN used by the DDC to connect * to the CDC. @@ -5677,114 +5788,114 @@ struct nvme_mi_vpd_hdr { * @NVME_SC_READ_ONLY: Attempted Write to Read Only Range * @NVME_SC_CMD_SIZE_LIMIT_EXCEEDED: Command Size Limit Exceeded * @NVME_SC_CONNECT_FORMAT: Incompatible Format: The NVM subsystem - * does not support the record format - * specified by the host. + * does not support the record format + * specified by the host. * @NVME_SC_CONNECT_CTRL_BUSY: Controller Busy: The controller is - * already associated with a host. + * already associated with a host. * @NVME_SC_CONNECT_INVALID_PARAM: Connect Invalid Parameters: One or more - * of the command parameters. + * of the command parameters. * @NVME_SC_CONNECT_RESTART_DISC: Connect Restart Discovery: The NVM - * subsystem requested is not available. + * subsystem requested is not available. * @NVME_SC_CONNECT_INVALID_HOST: Connect Invalid Host: The host is either - * not allowed to establish an association - * to any controller in the NVM subsystem or - * the host is not allowed to establish an - * association to the specified controller + * not allowed to establish an association + * to any controller in the NVM subsystem or + * the host is not allowed to establish an + * association to the specified controller * @NVME_SC_DISCONNECT_INVALID_QTYPE: Invalid Queue Type: The command was sent - * on the wrong queue type. + * on the wrong queue type. * @NVME_SC_DISCOVERY_RESTART: Discover Restart: The snapshot of the - * records is now invalid or out of date. + * records is now invalid or out of date. * @NVME_SC_AUTH_REQUIRED: Authentication Required: NVMe in-band - * authentication is required and the queue - * has not yet been authenticated. + * authentication is required and the queue + * has not yet been authenticated. * @NVME_SC_WRITE_FAULT: Write Fault: The write data could not be - * committed to the media. + * committed to the media. * @NVME_SC_READ_ERROR: Unrecovered Read Error: The read data - * could not be recovered from the media. + * could not be recovered from the media. * @NVME_SC_GUARD_CHECK: End-to-end Guard Check Error: The command - * was aborted due to an end-to-end guard - * check failure. + * was aborted due to an end-to-end guard + * check failure. * @NVME_SC_APPTAG_CHECK: End-to-end Application Tag Check Error: - * The command was aborted due to an - * end-to-end application tag check failure. + * The command was aborted due to an + * end-to-end application tag check failure. * @NVME_SC_REFTAG_CHECK: End-to-end Reference Tag Check Error: The - * command was aborted due to an end-to-end - * reference tag check failure. + * command was aborted due to an end-to-end + * reference tag check failure. * @NVME_SC_COMPARE_FAILED: Compare Failure: The command failed due - * to a miscompare during a Compare command. + * to a miscompare during a Compare command. * @NVME_SC_ACCESS_DENIED: Access Denied: Access to the namespace - * and/or LBA range is denied due to lack of - * access rights. + * and/or LBA range is denied due to lack of + * access rights. * @NVME_SC_UNWRITTEN_BLOCK: Deallocated or Unwritten Logical Block: - * The command failed due to an attempt to - * read from or verify an LBA range - * containing a deallocated or unwritten - * logical block. + * The command failed due to an attempt to + * read from or verify an LBA range + * containing a deallocated or unwritten + * logical block. * @NVME_SC_STORAGE_TAG_CHECK: End-to-End Storage Tag Check Error: The - * command was aborted due to an end-to-end - * storage tag check failure. + * command was aborted due to an end-to-end + * storage tag check failure. * @NVME_SC_ANA_INTERNAL_PATH_ERROR: Internal Path Error: The command was not - * completed as the result of a controller - * internal error that is specific to the - * controller processing the command. + * completed as the result of a controller + * internal error that is specific to the + * controller processing the command. * @NVME_SC_ANA_PERSISTENT_LOSS: Asymmetric Access Persistent Loss: The - * requested function (e.g., command) is not - * able to be performed as a result of the - * relationship between the controller and - * the namespace being in the ANA Persistent - * Loss state. + * requested function (e.g., command) is not + * able to be performed as a result of the + * relationship between the controller and + * the namespace being in the ANA Persistent + * Loss state. * @NVME_SC_ANA_INACCESSIBLE: Asymmetric Access Inaccessible: The - * requested function (e.g., command) is not - * able to be performed as a result of the - * relationship between the controller and - * the namespace being in the ANA - * Inaccessible state. + * requested function (e.g., command) is not + * able to be performed as a result of the + * relationship between the controller and + * the namespace being in the ANA + * Inaccessible state. * @NVME_SC_ANA_TRANSITION: Asymmetric Access Transition: The - * requested function (e.g., command) is not - * able to be performed as a result of the - * relationship between the controller and - * the namespace transitioning between - * Asymmetric Namespace Access states. + * requested function (e.g., command) is not + * able to be performed as a result of the + * relationship between the controller and + * the namespace transitioning between + * Asymmetric Namespace Access states. * @NVME_SC_CTRL_PATH_ERROR: Controller Pathing Error: A pathing error - * was detected by the controller. + * was detected by the controller. * @NVME_SC_HOST_PATH_ERROR: Host Pathing Error: A pathing error was - * detected by the host. + * detected by the host. * @NVME_SC_CMD_ABORTED_BY_HOST: Command Aborted By Host: The command was - * aborted as a result of host action. + * aborted as a result of host action. * @NVME_SC_CRD: Mask to get value of Command Retry Delay - * index + * index * @NVME_SC_MORE: More bit. If set, more status information - * for this command as part of the Error - * Information log that may be retrieved with - * the Get Log Page command. + * for this command as part of the Error + * Information log that may be retrieved with + * the Get Log Page command. * @NVME_SC_DNR: Do Not Retry bit. If set, if the same - * command is re-submitted to any controller - * in the NVM subsystem, then that - * re-submitted command is expected to fail. + * command is re-submitted to any controller + * in the NVM subsystem, then that + * re-submitted command is expected to fail. * @NVME_SC_ZNS_INVALID_OP_REQUEST: Invalid Zone Operation Request: - * The operation requested is invalid. This may be due to - * various conditions, including: attempting to allocate a - * ZRWA when a zone is not in the ZSE:Empty state; or - * invalid Flush Explicit ZRWA Range Send Zone Action - * operation. + * The operation requested is invalid. This may be due to + * various conditions, including: attempting to allocate a + * ZRWA when a zone is not in the ZSE:Empty state; or + * invalid Flush Explicit ZRWA Range Send Zone Action + * operation. * @NVME_SC_ZNS_ZRWA_RESOURCES_UNAVAILABLE: ZRWA Resources Unavailable: - * No ZRWAs are available. + * No ZRWAs are available. * @NVME_SC_ZNS_BOUNDARY_ERROR: Zone Boundary Error: The command specifies - * logical blocks in more than one zone. + * logical blocks in more than one zone. * @NVME_SC_ZNS_FULL: Zone Is Full: The accessed zone is in the - * ZSF:Full state. + * ZSF:Full state. * @NVME_SC_ZNS_READ_ONLY: Zone Is Read Only: The accessed zone is - * in the ZSRO:Read Only state. + * in the ZSRO:Read Only state. * @NVME_SC_ZNS_OFFLINE: Zone Is Offline: The accessed zone is - * in the ZSO:Offline state. + * in the ZSO:Offline state. * @NVME_SC_ZNS_INVALID_WRITE: Zone Invalid Write: The write to a zone - * was not at the write pointer. + * was not at the write pointer. * @NVME_SC_ZNS_TOO_MANY_ACTIVE: Too Many Active Zones: The controller - * does not allow additional active zones. - * @NVME_SC_ZNS_TOO_MANY_OPENS: Too Many Open Zones: The controller does - * not allow additional open zones. + * does not allow additional active zones. + * @NVME_SC_ZNS_TOO_MANY_OPENS: Too Many Open Zones: The controller does + * not allow additional open zones. * @NVME_SC_ZNS_INVAL_TRANSITION: Invalid Zone State Transition: The request - * is not a valid zone state transition. + * is not a valid zone state transition. */ enum nvme_status_field { /* @@ -5935,16 +6046,16 @@ enum nvme_status_field { /* * I/O Command Set Specific - ZNS commands: */ - NVME_SC_ZNS_INVALID_OP_REQUEST = 0xb6, + NVME_SC_ZNS_INVALID_OP_REQUEST = 0xb6, NVME_SC_ZNS_ZRWA_RESOURCES_UNAVAILABLE = 0xb7, - NVME_SC_ZNS_BOUNDARY_ERROR = 0xb8, - NVME_SC_ZNS_FULL = 0xb9, - NVME_SC_ZNS_READ_ONLY = 0xba, - NVME_SC_ZNS_OFFLINE = 0xbb, - NVME_SC_ZNS_INVALID_WRITE = 0xbc, - NVME_SC_ZNS_TOO_MANY_ACTIVE = 0xbd, - NVME_SC_ZNS_TOO_MANY_OPENS = 0xbe, - NVME_SC_ZNS_INVAL_TRANSITION = 0xbf, + NVME_SC_ZNS_BOUNDARY_ERROR = 0xb8, + NVME_SC_ZNS_FULL = 0xb9, + NVME_SC_ZNS_READ_ONLY = 0xba, + NVME_SC_ZNS_OFFLINE = 0xbb, + NVME_SC_ZNS_INVALID_WRITE = 0xbc, + NVME_SC_ZNS_TOO_MANY_ACTIVE = 0xbd, + NVME_SC_ZNS_TOO_MANY_OPENS = 0xbe, + NVME_SC_ZNS_INVAL_TRANSITION = 0xbf, /* * Media and Data Integrity Errors: @@ -5980,9 +6091,10 @@ enum nvme_status_field { /** * nvme_status_code_type() - Returns the NVMe Status Code Type - * @status_field: The NVMe Completion Queue Entry's Status Field + * @status_field: The NVMe Completion Queue Entry's Status Field + * See &enum nvme_status_field * - * See &enum nvme_status_field + * Returns: status code type */ static inline __u16 nvme_status_code_type(__u16 status_field) { @@ -5991,9 +6103,10 @@ static inline __u16 nvme_status_code_type(__u16 status_field) /** * nvme_status_code() - Returns the NVMe Status Code - * @status_field: The NVMe Completion Queue Entry's Status Field + * @status_field: The NVMe Completion Queue Entry's Status Field + * See &enum nvme_status_field * - * See &enum nvme_status_field + * Returns: status code */ static inline __u16 nvme_status_code(__u16 status_field) { @@ -6077,40 +6190,43 @@ enum nvme_admin_opcode { }; /** - * enum nvme_identify_cns - + * enum nvme_identify_cns - Identify - CNS Values * @NVME_IDENTIFY_CNS_NS: Identify Namespace data structure - * @NVME_IDENTIFY_CNS_CTRL: Identify Controller data structur + * @NVME_IDENTIFY_CNS_CTRL: Identify Controller data structure * @NVME_IDENTIFY_CNS_NS_ACTIVE_LIST: Active Namespace ID list * @NVME_IDENTIFY_CNS_NS_DESC_LIST: Namespace Identification Descriptor list * @NVME_IDENTIFY_CNS_NVMSET_LIST: NVM Set List * @NVME_IDENTIFY_CNS_CSI_NS: I/O Command Set specific Identify - * Namespace data structure + * Namespace data structure * @NVME_IDENTIFY_CNS_CSI_CTRL: I/O Command Set specific Identify - * Controller data structure + * Controller data structure * @NVME_IDENTIFY_CNS_CSI_NS_ACTIVE_LIST: Active Namespace ID list associated - * with the specified I/O Command Set + * with the specified I/O Command Set * @NVME_IDENTIFY_CNS_CSI_INDEPENDENT_ID_NS: I/O Command Set Independent Identify - * Namespace data structure + * @NVME_IDENTIFY_CNS_NS_USER_DATA_FORMAT: Namespace user data format + * @NVME_IDENTIFY_CNS_CSI_NS_USER_DATA_FORMAT: I/O Command Set specific user data + * format + * Namespace data structure * @NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST: Allocated Namespace ID list * @NVME_IDENTIFY_CNS_ALLOCATED_NS: Identify Namespace data structure for - * the specified allocated NSID + * the specified allocated NSID * @NVME_IDENTIFY_CNS_NS_CTRL_LIST: Controller List of controllers attached - * to the specified NSID + * to the specified NSID * @NVME_IDENTIFY_CNS_CTRL_LIST: Controller List of controllers that exist - * in the NVM subsystem + * in the NVM subsystem * @NVME_IDENTIFY_CNS_PRIMARY_CTRL_CAP: Primary Controller Capabilities data - * structure for the specified primary controller + * structure for the specified primary controller * @NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST: Secondary Controller list of controllers - * associated with the primary controller - * processing the command - * @NVME_IDENTIFY_CNS_NS_GRANULARITY: A Namespace Granularity Lis + * associated with the primary controller + * processing the command + * @NVME_IDENTIFY_CNS_NS_GRANULARITY: A Namespace Granularity List * @NVME_IDENTIFY_CNS_UUID_LIST: A UUID List * @NVME_IDENTIFY_CNS_DOMAIN_LIST: Domain List * @NVME_IDENTIFY_CNS_ENDURANCE_GROUP_ID: Endurance Group List * @NVME_IDENTIFY_CNS_CSI_ALLOCATED_NS_LIST: I/O Command Set specific Allocated Namespace - * ID list + * ID list * @NVME_IDENTIFY_CNS_CSI_ID_NS_DATA_STRUCTURE: I/O Command Set specific ID Namespace - * Data Structure for Allocated Namespace ID + * Data Structure for Allocated Namespace ID * @NVME_IDENTIFY_CNS_COMMAND_SET_STRUCTURE: Base Specification 2.0a section 5.17.2.21 */ enum nvme_identify_cns { @@ -6141,7 +6257,7 @@ enum nvme_identify_cns { }; /** - * enum nvme_cmd_get_log_lid - + * enum nvme_cmd_get_log_lid - Get Log Page -Log Page Identifiers * @NVME_LOG_LID_SUPPORTED_LOG_PAGES: Supported Log Pages * @NVME_LOG_LID_ERROR: Error Information * @NVME_LOG_LID_SMART: SMART / Health Information @@ -6197,7 +6313,7 @@ enum nvme_cmd_get_log_lid { }; /** - * enum nvme_features_id - + * enum nvme_features_id - Features - Feature Identifiers * @NVME_FEAT_FID_ARBITRATION: Arbitration * @NVME_FEAT_FID_POWER_MGMT: Power Management * @NVME_FEAT_FID_LBA_RANGE: LBA Range Type @@ -6271,7 +6387,7 @@ enum nvme_features_id { }; /** - * enum nvme_feat - + * enum nvme_feat - Features Access Shifts/Masks values * @NVME_FEAT_ARBITRATION_BURST_SHIFT: * @NVME_FEAT_ARBITRATION_BURST_MASK: * @NVME_FEAT_ARBITRATION_LPW_SHIFT: @@ -6473,7 +6589,7 @@ enum nvme_feat { }; /** - * enum nvme_get_features_sel - + * enum nvme_get_features_sel - Get Features - Select * @NVME_GET_FEATURES_SEL_CURRENT: Current value * @NVME_GET_FEATURES_SEL_DEFAULT: Default value * @NVME_GET_FEATURES_SEL_SAVED: Saved value @@ -6489,9 +6605,9 @@ enum nvme_get_features_sel { /** * enum nvme_cmd_format_mset - Format NVM - Metadata Settings * @NVME_FORMAT_MSET_SEPARATE: indicates that the metadata is transferred - * as part of a separate buffer. + * as part of a separate buffer. * @NVME_FORMAT_MSET_EXTENDED: indicates that the metadata is transferred - * as part of an extended data LBA. + * as part of an extended data LBA. */ enum nvme_cmd_format_mset { NVME_FORMAT_MSET_SEPARATE = 0, @@ -6515,9 +6631,9 @@ enum nvme_cmd_format_pi { /** * enum nvme_cmd_format_pil - Format NVM - Protection Information Location * @NVME_FORMAT_PIL_LAST: Protection information is transferred as the last - * bytes of metadata. + * bytes of metadata. * @NVME_FORMAT_PIL_FIRST: Protection information is transferred as the first - * bytes of metadata. + * bytes of metadata. */ enum nvme_cmd_format_pil { NVME_FORMAT_PIL_LAST = 0, @@ -6528,16 +6644,16 @@ enum nvme_cmd_format_pil { * enum nvme_cmd_format_ses - Format NVM - Secure Erase Settings * @NVME_FORMAT_SES_NONE: No secure erase operation requested. * @NVME_FORMAT_SES_USER_DATA_ERASE: User Data Erase: All user data shall be erased, - * contents of the user data after the erase is - * indeterminate (e.g. the user data may be zero - * filled, one filled, etc.). If a User Data Erase - * is requested and all affected user data is - * encrypted, then the controller is allowed - * to use a cryptographic erase to perform - * the requested User Data Erase. + * contents of the user data after the erase is + * indeterminate (e.g. the user data may be zero + * filled, one filled, etc.). If a User Data Erase + * is requested and all affected user data is + * encrypted, then the controller is allowed + * to use a cryptographic erase to perform + * the requested User Data Erase. * @NVME_FORMAT_SES_CRYPTO_ERASE: Cryptographic Erase: All user data shall - * be erased cryptographically. This is - * accomplished by deleting the encryption key. + * be erased cryptographically. This is + * accomplished by deleting the encryption key. */ enum nvme_cmd_format_ses { NVME_FORMAT_SES_NONE = 0, @@ -6546,7 +6662,7 @@ enum nvme_cmd_format_ses { }; /** - * enum nvme_ns_mgmt_sel - + * enum nvme_ns_mgmt_sel - Namespace Management - Select * @NVME_NS_MGMT_SEL_CREATE: Namespace Create selection * @NVME_NS_MGMT_SEL_DELETE: Namespace Delete selection */ @@ -6556,7 +6672,7 @@ enum nvme_ns_mgmt_sel { }; /** - * enum nvme_ns_attach_sel - + * enum nvme_ns_attach_sel - Namespace Attachment - Select * @NVME_NS_ATTACH_SEL_CTRL_ATTACH: Namespace attach selection * @NVME_NS_ATTACH_SEL_CTRL_DEATTACH: Namespace detach selection */ @@ -6566,30 +6682,30 @@ enum nvme_ns_attach_sel { }; /** - * enum nvme_fw_commit_ca - + * enum nvme_fw_commit_ca - Firmware Commit - Commit Action * @NVME_FW_COMMIT_CA_REPLACE: Downloaded image replaces the existing - * image, if any, in the specified Firmware - * Slot. The newly placed image is not - * activated. + * image, if any, in the specified Firmware + * Slot. The newly placed image is not + * activated. * @NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE: Downloaded image replaces the existing - * image, if any, in the specified Firmware - * Slot. The newly placed image is activated - * at the next Controller Level Reset. + * image, if any, in the specified Firmware + * Slot. The newly placed image is activated + * at the next Controller Level Reset. * @NVME_FW_COMMIT_CA_SET_ACTIVE: The existing image in the specified - * Firmware Slot is activated at the - * next Controller Level Reset. + * Firmware Slot is activated at the + * next Controller Level Reset. * @NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE_IMMEDIATE: Downloaded image replaces the existing - * image, if any, in the specified Firmware - * Slot and is then activated immediately. - * If there is not a newly downloaded image, - * then the existing image in the specified - * firmware slot is activated immediately. + * image, if any, in the specified Firmware + * Slot and is then activated immediately. + * If there is not a newly downloaded image, + * then the existing image in the specified + * firmware slot is activated immediately. * @NVME_FW_COMMIT_CA_REPLACE_BOOT_PARTITION: Downloaded image replaces the Boot - * Partition specified by the Boot - * Partition ID field. + * Partition specified by the Boot + * Partition ID field. * @NVME_FW_COMMIT_CA_ACTIVATE_BOOT_PARTITION: Mark the Boot Partition specified in - * the BPID field as active and update - * BPINFO.ABPID. + * the BPID field as active and update + * BPINFO.ABPID. */ enum nvme_fw_commit_ca { NVME_FW_COMMIT_CA_REPLACE = 0, @@ -6601,7 +6717,7 @@ enum nvme_fw_commit_ca { }; /** - * enum nvme_directive_dtype - + * enum nvme_directive_dtype - Directive Types * @NVME_DIRECTIVE_DTYPE_IDENTIFY: Identify directive type * @NVME_DIRECTIVE_DTYPE_STREAMS: Streams directive type */ @@ -6611,7 +6727,7 @@ enum nvme_directive_dtype { }; /** - * enum nvme_directive_receive_doper - + * enum nvme_directive_receive_doper - Directive Receive Directive Operation * @NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM: * @NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM: * @NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS: @@ -6625,7 +6741,7 @@ enum nvme_directive_receive_doper { }; /** - * enum nvme_directive_send_doper - + * enum nvme_directive_send_doper - Directive Send Directive Operation * @NVME_DIRECTIVE_SEND_IDENTIFY_DOPER_ENDIR: * @NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_IDENTIFIER: * @NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE: @@ -6637,7 +6753,7 @@ enum nvme_directive_send_doper { }; /** - * enum nvme_directive_send_identify_endir - + * enum nvme_directive_send_identify_endir - Enable Directive * @NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_DISABLE: * @NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_ENABLE: */ @@ -6648,7 +6764,7 @@ enum nvme_directive_send_identify_endir { /** * enum nvme_sanitize_sanact - Sanitize Action - * @NVME_SANITIZE_SANACT_EXIT_FAILURE: Exit Failure Mode. + * @NVME_SANITIZE_SANACT_EXIT_FAILURE: Exit Failure Mode. * @NVME_SANITIZE_SANACT_START_BLOCK_ERASE: Start a Block Erase sanitize operation. * @NVME_SANITIZE_SANACT_START_OVERWRITE: Start an Overwrite sanitize operation. * @NVME_SANITIZE_SANACT_START_CRYPTO_ERASE: Start a Crypto Erase sanitize operation. @@ -6675,9 +6791,9 @@ enum nvme_dst_stc { }; /** - * enum nvme_virt_mgmt_act - + * enum nvme_virt_mgmt_act - Virtualization Management - Action * @NVME_VIRT_MGMT_ACT_PRIM_CTRL_FLEX_ALLOC: Primary Controller Flexible - * Allocation + * Allocation * @NVME_VIRT_MGMT_ACT_OFFLINE_SEC_CTRL: Secondary Controller Offline * @NVME_VIRT_MGMT_ACT_ASSIGN_SEC_CTRL: Secondary Controller Assign * @NVME_VIRT_MGMT_ACT_ONLINE_SEC_CTRL: Secondary Controller Online @@ -6690,7 +6806,7 @@ enum nvme_virt_mgmt_act { }; /** - * enum nvme_virt_mgmt_rt - + * enum nvme_virt_mgmt_rt - Virtualization Management - Resource Type * @NVME_VIRT_MGMT_RT_VQ_RESOURCE: VQ Resources * @NVME_VIRT_MGMT_RT_VI_RESOURCE: VI Resources */ @@ -6700,7 +6816,7 @@ enum nvme_virt_mgmt_rt { }; /** - * enum nvme_ns_write_protect_cfg - + * enum nvme_ns_write_protect_cfg - Write Protection - Write Protection State * @NVME_NS_WP_CFG_NONE: No Write Protect * @NVME_NS_WP_CFG_PROTECT: Write Protect * @NVME_NS_WP_CFG_PROTECT_POWER_CYCLE: Write Protect Until Power Cycle @@ -6714,7 +6830,7 @@ enum nvme_ns_write_protect_cfg { }; /** - * enum nvme_log_ana_lsp - + * enum nvme_log_ana_lsp - Asymmetric Namespace Access - Return Groups Only * @NVME_LOG_ANA_LSP_RGO_NAMESPACES: * @NVME_LOG_ANA_LSP_RGO_GROUPS_ONLY: */ @@ -6724,7 +6840,7 @@ enum nvme_log_ana_lsp { }; /** - * enum nvme_pevent_log_action - + * enum nvme_pevent_log_action - Persistent Event Log - Action * @NVME_PEVENT_LOG_READ: Read Log Data * @NVME_PEVENT_LOG_EST_CTX_AND_READ: Establish Context and Read Log Data * @NVME_PEVENT_LOG_RELEASE_CTX: Release Context @@ -6736,7 +6852,7 @@ enum nvme_pevent_log_action { }; /** - * enum nvme_feat_tmpthresh_thsel - + * enum nvme_feat_tmpthresh_thsel - Temperature Threshold - Threshold Type Select * @NVME_FEATURE_TEMPTHRESH_THSEL_OVER: Over temperature threshold select * @NVME_FEATURE_TEMPTHRESH_THSEL_UNDER: Under temperature threshold select */ @@ -6746,7 +6862,7 @@ enum nvme_feat_tmpthresh_thsel { }; /** - * enum nvme_features_async_event_config_flags - + * enum nvme_features_async_event_config_flags - Asynchronous Event Configuration configuration flags * @NVME_FEATURE_AENCFG_SMART_CRIT_SPARE: * @NVME_FEATURE_AENCFG_SMART_CRIT_TEMPERATURE: * @NVME_FEATURE_AENCFG_SMART_CRIT_DEGRADED: @@ -6780,7 +6896,7 @@ enum nvme_features_async_event_config_flags { }; /** - * enum nvme_feat_plm_window_select - + * enum nvme_feat_plm_window_select - Predictable Latency Per NVM Set Log * @NVME_FEATURE_PLM_DTWIN: Deterministic Window select * @NVME_FEATURE_PLM_NDWIN: Non-Deterministic Window select */ @@ -6790,7 +6906,7 @@ enum nvme_feat_plm_window_select { }; /** - * enum nvme_feat_resv_notify_flags - + * enum nvme_feat_resv_notify_flags - Reservation Notification Configuration * @NVME_FEAT_RESV_NOTIFY_REGPRE: Mask Registration Preempted Notification * @NVME_FEAT_RESV_NOTIFY_RESREL: Mask Reservation Released Notification * @NVME_FEAT_RESV_NOTIFY_RESPRE: Mask Reservation Preempted Notification @@ -6802,21 +6918,21 @@ enum nvme_feat_resv_notify_flags { }; /** - * enum nvme_feat_nswpcfg_state - + * enum nvme_feat_nswpcfg_state - Write Protection - Write Protection State * @NVME_FEAT_NS_NO_WRITE_PROTECT: No Write Protect * @NVME_FEAT_NS_WRITE_PROTECT: Write Protect * @NVME_FEAT_NS_WRITE_PROTECT_PWR_CYCLE: Write Protect Until Power Cycle * @NVME_FEAT_NS_WRITE_PROTECT_PERMANENT: Permanent Write Protect */ enum nvme_feat_nswpcfg_state { - NVME_FEAT_NS_NO_WRITE_PROTECT = 0, + NVME_FEAT_NS_NO_WRITE_PROTECT = 0, NVME_FEAT_NS_WRITE_PROTECT = 1, NVME_FEAT_NS_WRITE_PROTECT_PWR_CYCLE = 2, NVME_FEAT_NS_WRITE_PROTECT_PERMANENT = 3, }; /** - * enum nvme_fctype - + * enum nvme_fctype - Fabrics Command Types * @nvme_fabrics_type_property_set: Property set * @nvme_fabrics_type_connect: Connect * @nvme_fabrics_type_property_get: Property Get @@ -6834,7 +6950,7 @@ enum nvme_fctype { }; /** - * enum nvme_io_opcode - + * enum nvme_io_opcode - Opcodes for I/O Commands * @nvme_cmd_flush: Flush * @nvme_cmd_write: Write * @nvme_cmd_read: Read @@ -6872,8 +6988,9 @@ enum nvme_io_opcode { }; /** - * enum nvme_io_control_flags - + * enum nvme_io_control_flags - I/O control flags * @NVME_IO_DTYPE_STREAMS: Directive Type Streams + * @NVME_IO_STC: Storage Tag Check * @NVME_IO_DEAC: Deallocate * @NVME_IO_ZNS_APPEND_PIREMAP: Protection Information Remap * @NVME_IO_PRINFO_PRCHK_REF: Protection Information Check Reference Tag @@ -6885,6 +7002,7 @@ enum nvme_io_opcode { */ enum nvme_io_control_flags { NVME_IO_DTYPE_STREAMS = 1 << 4, + NVME_IO_STC = 1 << 8, NVME_IO_DEAC = 1 << 9, NVME_IO_ZNS_APPEND_PIREMAP = 1 << 9, NVME_IO_PRINFO_PRCHK_REF = 1 << 10, @@ -6896,18 +7014,18 @@ enum nvme_io_control_flags { }; /** - * enum nvme_io_dsm_flags - + * enum nvme_io_dsm_flags - Dataset Management flags * @NVME_IO_DSM_FREQ_UNSPEC: No frequency information provided * @NVME_IO_DSM_FREQ_TYPICAL: Typical number of reads and writes - * expected for this LBA range + * expected for this LBA range * @NVME_IO_DSM_FREQ_RARE: Infrequent writes and infrequent - * reads to the LBA range indicated + * reads to the LBA range indicated * @NVME_IO_DSM_FREQ_READS: Infrequent writes and frequent - * reads to the LBA range indicated + * reads to the LBA range indicated * @NVME_IO_DSM_FREQ_WRITES: Frequent writes and infrequent - * reads to the LBA range indicated + * reads to the LBA range indicated * @NVME_IO_DSM_FREQ_RW: Frequent writes and frequent reads - * to the LBA range indicated + * to the LBA range indicated * @NVME_IO_DSM_FREQ_ONCE: * @NVME_IO_DSM_FREQ_PREFETCH: * @NVME_IO_DSM_FREQ_TEMP: @@ -6937,10 +7055,10 @@ enum nvme_io_dsm_flags { }; /** - * enum nvme_dsm_attributes - - * @NVME_DSMGMT_IDR: Attribute – Integral Dataset for Read - * @NVME_DSMGMT_IDW: Attribute – Integral Dataset for Write - * @NVME_DSMGMT_AD: Attribute – Deallocate + * enum nvme_dsm_attributes - Dataset Management attributes + * @NVME_DSMGMT_IDR: Attribute -Integral Dataset for Read + * @NVME_DSMGMT_IDW: Attribute - Integral Dataset for Write + * @NVME_DSMGMT_AD: Attribute - Deallocate */ enum nvme_dsm_attributes { NVME_DSMGMT_IDR = 1 << 0, @@ -6949,7 +7067,7 @@ enum nvme_dsm_attributes { }; /** - * enum nvme_resv_rtype - + * enum nvme_resv_rtype - Reservation Type Encoding * @NVME_RESERVATION_RTYPE_WE: Write Exclusive Reservation * @NVME_RESERVATION_RTYPE_EA: Exclusive Access Reservation * @NVME_RESERVATION_RTYPE_WERO: Write Exclusive - Registrants Only Reservation @@ -6967,7 +7085,7 @@ enum nvme_resv_rtype { }; /** - * enum nvme_resv_racqa - + * enum nvme_resv_racqa - Reservation Acquire - Reservation Acquire Action * @NVME_RESERVATION_RACQA_ACQUIRE: Acquire * @NVME_RESERVATION_RACQA_PREEMPT: Preempt * @NVME_RESERVATION_RACQA_PREEMPT_AND_ABORT: Preempt and Abort @@ -6979,7 +7097,7 @@ enum nvme_resv_racqa { }; /** - * enum nvme_resv_rrega - + * enum nvme_resv_rrega - Reservation Register - Reservation Register Action * @NVME_RESERVATION_RREGA_REGISTER_KEY: Register Reservation Key * @NVME_RESERVATION_RREGA_UNREGISTER_KEY: Unregister Reservation Key * @NVME_RESERVATION_RREGA_REPLACE_KEY: Replace Reservation Key @@ -6991,12 +7109,12 @@ enum nvme_resv_rrega { }; /** - * enum nvme_resv_cptpl - + * enum nvme_resv_cptpl - Reservation Register - Change Persist Through Power Loss State * @NVME_RESERVATION_CPTPL_NO_CHANGE: No change to PTPL state * @NVME_RESERVATION_CPTPL_CLEAR: Reservations are released and - * registrants are cleared on a power on + * registrants are cleared on a power on * @NVME_RESERVATION_CPTPL_PERSIST: Reservations and registrants persist - * across a power loss + * across a power loss */ enum nvme_resv_cptpl { NVME_RESERVATION_CPTPL_NO_CHANGE = 0, @@ -7005,7 +7123,7 @@ enum nvme_resv_cptpl { }; /** - * enum nvme_resv_rrela - + * enum nvme_resv_rrela - Reservation Release - Reservation Release Action * @NVME_RESERVATION_RRELA_RELEASE: Release * @NVME_RESERVATION_RRELA_CLEAR: Clear */ @@ -7015,7 +7133,7 @@ enum nvme_resv_rrela { }; /** - * enum nvme_zns_send_action - + * enum nvme_zns_send_action - Zone Management Send - Zone Send Action * @NVME_ZNS_ZSA_CLOSE: Close Zone * @NVME_ZNS_ZSA_FINISH: Finish Zone * @NVME_ZNS_ZSA_OPEN: Open Zone @@ -7035,7 +7153,7 @@ enum nvme_zns_send_action { }; /** - * enum nvme_zns_recv_action - + * enum nvme_zns_recv_action - Zone Management Receive - Zone Receive Action Specific Features * @NVME_ZNS_ZRA_REPORT_ZONES: Report Zones * @NVME_ZNS_ZRA_EXTENDED_REPORT_ZONES: Extended Report Zones */ @@ -7045,7 +7163,7 @@ enum nvme_zns_recv_action { }; /** - * enum nvme_zns_report_options - + * enum nvme_zns_report_options - Zone Management Receive - Zone Receive Action Specific Field * @NVME_ZNS_ZRAS_REPORT_ALL: List all zones * @NVME_ZNS_ZRAS_REPORT_EMPTY: List the zones in the ZSE:Empty state * @NVME_ZNS_ZRAS_REPORT_IMPL_OPENED: List the zones in the ZSIO:Implicitly Opened state diff --git a/src/nvme/util.c b/src/nvme/util.c index 799c0cf..ff5e0d8 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -23,6 +23,9 @@ #include "util.h" #include "log.h" +/* Source Code Control System, query version of binary with 'what' */ +const char sccsid[] = "@(#)libnvme " GIT_VERSION; + static inline __u8 nvme_generic_status_to_errno(__u16 status) { switch (status) { @@ -389,6 +392,21 @@ void nvme_init_copy_range(struct nvme_copy_range *copy, __u16 *nlbs, } } +void nvme_init_copy_range_f1(struct nvme_copy_range_f1 *copy, __u16 *nlbs, + __u64 *slbas, __u64 *eilbrts, __u32 *elbatms, + __u32 *elbats, __u16 nr) +{ + int i; + + for (i = 0; i < nr; i++) { + copy[i].nlb = cpu_to_le16(nlbs[i]); + copy[i].slba = cpu_to_le64(slbas[i]); + copy[i].elbt[2] = cpu_to_le64(eilbrts[i]); + copy[i].elbatm = cpu_to_le16(elbatms[i]); + copy[i].elbat = cpu_to_le16(elbats[i]); + } +} + void nvme_init_dsm_range(struct nvme_dsm_range *dsm, __u32 *ctx_attrs, __u32 *llbas, __u64 *slbas, __u16 nr_ranges) { @@ -432,6 +450,9 @@ int nvme_get_feature_length(int fid, __u32 cdw11, __u32 *len) case NVME_FEAT_FID_HOST_ID: *len = (cdw11 & 0x1) ? 16 : 8; break; + case NVME_FEAT_FID_HOST_MEM_BUF: + *len = sizeof(struct nvme_host_mem_buf_attrs); + break; case NVME_FEAT_FID_ARBITRATION: case NVME_FEAT_FID_POWER_MGMT: case NVME_FEAT_FID_TEMP_THRESH: @@ -442,7 +463,6 @@ int nvme_get_feature_length(int fid, __u32 cdw11, __u32 *len) case NVME_FEAT_FID_IRQ_CONFIG: case NVME_FEAT_FID_WRITE_ATOMIC: case NVME_FEAT_FID_ASYNC_EVENT: - case NVME_FEAT_FID_HOST_MEM_BUF: case NVME_FEAT_FID_KATO: case NVME_FEAT_FID_HCTM: case NVME_FEAT_FID_NOPSC: @@ -516,6 +536,11 @@ static const char * const libnvme_status[] = { [ENVME_CONNECT_INVAL_TR] = "invalid transport type", [ENVME_CONNECT_LOOKUP_SUBSYS_NAME] = "failed to lookup subsystem name", [ENVME_CONNECT_LOOKUP_SUBSYS] = "failed to lookup subsystem", + [ENVME_CONNECT_ALREADY] = "already connnected", + [ENVME_CONNECT_INVAL] = "invalid arguments/configuration", + [ENVME_CONNECT_ADDRINUSE] = "hostnqn already in use", + [ENVME_CONNECT_NODEV] = "invalid interface", + [ENVME_CONNECT_OPNOTSUPP] ="not supported", }; const char *nvme_errno_to_string(int status) @@ -775,3 +800,15 @@ struct nvmf_ext_attr *nvmf_exat_ptr_next(struct nvmf_ext_attr *p) return (struct nvmf_ext_attr *) ((uintptr_t)p + (ptrdiff_t)nvmf_exat_size(le16_to_cpu(p->exatlen))); } + +const char *nvme_get_version(enum nvme_version type) +{ + switch(type) { + case NVME_VERSION_PROJECT: + return PROJECT_VERSION; + case NVME_VERSION_GIT: + return GIT_VERSION; + default: + return "n/a"; + } +} diff --git a/src/nvme/util.h b/src/nvme/util.h index 277b857..6f1d3e9 100644 --- a/src/nvme/util.h +++ b/src/nvme/util.h @@ -4,7 +4,7 @@ * Copyright (c) 2020 Western Digital Corporation or its affiliates. * * Authors: Keith Busch - * Chaitanya Kulkarni + * Chaitanya Kulkarni */ #ifndef _LIBNVME_UTIL_H #define _LIBNVME_UTIL_H @@ -31,6 +31,11 @@ * @ENVME_CONNECT_INVAL_TR: invalid transport type * @ENVME_CONNECT_LOOKUP_SUBSYS_NAME: failed to lookup subsystem name * @ENVME_CONNECT_LOOKUP_SUBSYS: failed to lookup subsystem + * @ENVME_CONNECT_ALREADY: the connect attempt failed, already connected + * @ENVME_CONNECT_INVAL: invalid arguments/configuration + * @ENVME_CONNECT_ADDRINUSE: hostnqn already in use + * @ENVME_CONNECT_NODEV: invalid interface + * @ENVME_CONNECT_OPNOTSUPP: not supported */ enum nvme_connect_err { ENVME_CONNECT_RESOLVE = 1000, @@ -45,11 +50,16 @@ enum nvme_connect_err { ENVME_CONNECT_INVAL_TR, ENVME_CONNECT_LOOKUP_SUBSYS_NAME, ENVME_CONNECT_LOOKUP_SUBSYS, + ENVME_CONNECT_ALREADY, + ENVME_CONNECT_INVAL, + ENVME_CONNECT_ADDRINUSE, + ENVME_CONNECT_NODEV, + ENVME_CONNECT_OPNOTSUPP, }; /** * nvme_status_to_errno() - Converts nvme return status to errno - * @status: Return status from an nvme passthrough commmand + * @status: Return status from an nvme passthrough command * @fabrics: Set to true if &status is to a fabrics target. * * Return: An errno representing the nvme status if it is an nvme status field, @@ -59,7 +69,7 @@ __u8 nvme_status_to_errno(int status, bool fabrics); /** * nvme_status_to_string() - Returns string describing nvme return status. - * @status: Return status from an nvme passthrough commmand + * @status: Return status from an nvme passthrough command * @fabrics: Set to true if &status is to a fabrics target. * * Return: String representation of the nvme status if it is an nvme status field, @@ -118,12 +128,26 @@ void nvme_init_copy_range(struct nvme_copy_range *copy, __u16 *nlbs, __u64 *slbas, __u32 *eilbrts, __u32 *elbatms, __u32 *elbats, __u16 nr); +/** + * nvme_init_copy_range_f1() - Constructs a copy range f1 structure + * @copy: Copy range array + * @nlbs: Number of logical blocks + * @slbas: Starting LBA + * @eilbrts: Expected initial logical block reference tag + * @elbatms: Expected logical block application tag mask + * @elbats: Expected logical block application tag + * @nr: Number of descriptors to construct + */ +void nvme_init_copy_range_f1(struct nvme_copy_range_f1 *copy, __u16 *nlbs, + __u64 *slbas, __u64 *eilbrts, __u32 *elbatms, + __u32 *elbats, __u16 nr); + /** * nvme_get_feature_length() - Retreive the command payload length for a - * specific feature identifier + * specific feature identifier * @fid: Feature identifier, see &enum nvme_features_id. * @cdw11: The cdw11 value may affect the transfer (only known fid is - * %NVME_FEAT_FID_HOST_ID) + * %NVME_FEAT_FID_HOST_ID) * @len: On success, set to this features payload length in bytes. * * Return: 0 on success, -1 with errno set to EINVAL if the function did not @@ -132,7 +156,7 @@ void nvme_init_copy_range(struct nvme_copy_range *copy, __u16 *nlbs, int nvme_get_feature_length(int fid, __u32 cdw11, __u32 *len); /** - * nvme_get_directive_receive_length() - + * nvme_get_directive_receive_length() - Get directive receive length * @dtype: Directive type, see &enum nvme_directive_dtype * @doper: Directive receive operation, see &enum nvme_directive_receive_doper * @len: On success, set to this directives payload length in bytes. @@ -400,8 +424,8 @@ static inline void nvme_feature_decode_namespace_write_protect(__u32 value, static inline void nvme_id_ns_flbas_to_lbaf_inuse(__u8 flbas, __u8 *lbaf_inuse) { - *lbaf_inuse = (((flbas & NVME_NS_FLBAS_HIGHER_MASK) >> 1) \ - | (flbas & NVME_NS_FLBAS_LOWER_MASK)); + *lbaf_inuse = (((flbas & NVME_NS_FLBAS_HIGHER_MASK) >> 1) | + (flbas & NVME_NS_FLBAS_LOWER_MASK)); } struct nvme_root; @@ -473,7 +497,7 @@ char *kv_keymatch(const char *kv, const char *key); * Return: If @s starts with @prefix, then return a pointer within @s at * the first character after the matched @prefix. NULL otherwise. */ -char* startswith(const char *s, const char *prefix); +char *startswith(const char *s, const char *prefix); #define __round_mask(val, mult) ((__typeof__(val))((mult)-1)) @@ -502,7 +526,7 @@ static inline __u16 nvmf_exat_len(size_t val_len) } /** - * nvmf_exat_size - Return min algined size to hold value + * nvmf_exat_size - Return min aligned size to hold value * @val_len: This is the length of the data to be copied to the "exatval" * field of a "struct nvmf_ext_attr". * @@ -532,4 +556,23 @@ static inline __u16 nvmf_exat_size(size_t val_len) */ struct nvmf_ext_attr *nvmf_exat_ptr_next(struct nvmf_ext_attr *p); +/** + * enum nvme_version - Selector for version to be returned by @nvme_get_version + * + * @NVME_VERSION_PROJECT: Project release version + * @NVME_VERSION_GIT: Git reference + */ +enum nvme_version { + NVME_VERSION_PROJECT = 0, + NVME_VERSION_GIT = 1, +}; + +/** + * nvme_get_version - Return version libnvme string + * @type: Selects which version type (see @struct nvme_version) + * + * Return: Returns version string for known types or else "n/a" + */ +const char *nvme_get_version(enum nvme_version type); + #endif /* _LIBNVME_UTIL_H */ -- cgit v1.2.3