From 240089755db67e58bf4ad0fd21fc3e24396bccc3 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 6 Feb 2020 06:14:59 -0800 Subject: [PATCH 0001/1564] Initial libnvme commit Most of the planned features are developed, however many of the interfaces have only been lighlty touched as the features they implement are not broadly supported in hardware. The remaining gaps in command support from 1.4 are: Management Interface Send/Recieve OOB support Persistent Event Logs There is no plan to support Abort, AER, IO SQ/CQ Create/Delete, or Doorbell Buffer Config since that has high risk to abuse and interfere with the stability of a running system. Signed-off-by: Keith Busch --- .gitignore | 11 + Makefile | 17 + lib/Makefile | 91 ++ lib/libnvme.h | 12 + lib/libnvme.map | 6 + lib/libnvme.pc.in | 12 + lib/libnvme.spec | 59 ++ lib/nvme/cmd.h | 2245 ++++++++++++++++++++++++++++++++++++++++ lib/nvme/fabrics.c | 363 +++++++ lib/nvme/fabrics.h | 54 + lib/nvme/filters.c | 107 ++ lib/nvme/filters.h | 19 + lib/nvme/ioctl.c | 1654 ++++++++++++++++++++++++++++++ lib/nvme/ioctl.h | 355 +++++++ lib/nvme/private.h | 97 ++ lib/nvme/tree.c | 808 +++++++++++++++ lib/nvme/tree.h | 182 ++++ lib/nvme/types.h | 2430 ++++++++++++++++++++++++++++++++++++++++++++ lib/nvme/util.c | 579 +++++++++++ lib/nvme/util.h | 133 +++ test/test.c | 426 ++++++++ 21 files changed, 9660 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 lib/Makefile create mode 100644 lib/libnvme.h create mode 100644 lib/libnvme.map create mode 100644 lib/libnvme.pc.in create mode 100644 lib/libnvme.spec create mode 100644 lib/nvme/cmd.h create mode 100644 lib/nvme/fabrics.c create mode 100644 lib/nvme/fabrics.h create mode 100644 lib/nvme/filters.c create mode 100644 lib/nvme/filters.h create mode 100644 lib/nvme/ioctl.c create mode 100644 lib/nvme/ioctl.h create mode 100644 lib/nvme/private.h create mode 100644 lib/nvme/tree.c create mode 100644 lib/nvme/tree.h create mode 100644 lib/nvme/types.h create mode 100644 lib/nvme/util.c create mode 100644 lib/nvme/util.h create mode 100644 test/test.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..c225675465 --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +a.out +*.o +*.ol +*.os +*~ +*.swp +*.a +*.so.* +test/test + +cscope.* diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000..800b9e8850 --- /dev/null +++ b/Makefile @@ -0,0 +1,17 @@ +CFLAGS = -O2 -g -Wall -Werror -std=gnu99 -D_GNU_SOURCE +LDFLAGS = -Ilib -Llib -lnvme + +QUIET_CC = @echo ' ' CC $@; + +test: test/test.c libnvme + $(QUIET_CC)$(CC) $(CPPFLAGS) $(CFLAGS) $< -o test/test $(LDFLAGS) + +libnvme: + @$(MAKE) -C lib/ + +clean: + rm -f test/test + $(MAKE) -C lib clean + + +.PHONY: libnvme test diff --git a/lib/Makefile b/lib/Makefile new file mode 100644 index 0000000000..396e8caf8e --- /dev/null +++ b/lib/Makefile @@ -0,0 +1,91 @@ +NAME=libnvme +SPECFILE=$(NAME).spec +VERSION=$(shell awk '/Version:/ { print $$2 }' $(SPECFILE)) + +prefix ?= /usr +includedir ?= $(prefix)/include +libdir ?= $(prefix)/lib + +CFLAGS ?= -g -fomit-frame-pointer -O2 -I/usr/include -Invme/ +override CFLAGS += -Wall -fPIC +SO_CFLAGS=-shared $(CFLAGS) +L_CFLAGS=$(CFLAGS) +LINK_FLAGS= -L /usr/lib64 +LINK_FLAGS+=$(LDFLAGS) +ENABLE_SHARED ?= 1 +SED ?= sed +INSTALL ?= install + +soname=$(NAME).so.1 +minor=0 +micro=1 +libname=$(soname).$(minor).$(micro) +all_targets += $(NAME).a + +SED_PROCESS = \ + $(SED) -e "s%@prefix@%$(prefix)%g" \ + -e "s%@libdir@%$(libdir)%g" \ + -e "s%@includedir@%$(includedir)%g" \ + -e "s%@NAME@%$(NAME)%g" \ + -e "s%@VERSION@%$(VERSION)%g" \ + $< >$@ + +%.pc: %.pc.in Makefile + $(SED_PROCESS) + +ifeq ($(ENABLE_SHARED),1) +all_targets += $(libname) +endif + +ifneq ($(findstring $(MAKEFLAGS),s),s) +ifndef V + QUIET_CC = @echo ' ' CC $@; + QUIET_LINK = @echo ' ' LINK $@; + QUIET_AR = @echo ' ' AR $@; + QUIET_RANLIB = @echo '' RANLIB $@; +endif +endif + +all: $(all_targets) + +libnvme_srcs := nvme/ioctl.c nvme/filters.c nvme/fabrics.c nvme/util.c nvme/tree.c +libnvme_objs := $(patsubst %.c,%.ol,$(libnvme_srcs)) +libnvme_sobjs := $(patsubst %.c,%.os,$(libnvme_srcs)) + +$(libnvme_objs) $(libnvme_sobjs): libnvme.h nvme/types.h nvme/ioctl.h nvme/filters.h nvme/tree.h nvme/util.h nvme/cmd.h + +%.os: %.c + $(QUIET_CC)$(CC) $(SO_CFLAGS) -c -o $@ $< + +%.ol: %.c + $(QUIET_CC)$(CC) $(L_CFLAGS) -c -o $@ $< + +AR ?= ar +RANLIB ?= ranlib +libnvme.a: $(libnvme_objs) + @rm -f libnvme.a + $(QUIET_AR)$(AR) r libnvme.a $^ + $(QUIET_RANLIB)$(RANLIB) libnvme.a + +$(libname): $(libnvme_sobjs) libnvme.map + $(QUIET_CC)$(CC) $(SO_CFLAGS) -Wl,--version-script=libnvme.map -Wl,-soname=$(soname) -o $@ $(libnvme_sobjs) $(LINK_FLAGS) + +install: $(all_targets) $(NAME).pc + $(INSTALL) -D -m 644 nvme/types.h $(includedir)/nvme/types.h + $(INSTALL) -D -m 644 nvme/ioctl.h $(includedir)/nvme/ioctl.h + $(INSTALL) -D -m 644 nvme/fabrics.h $(includedir)/nvme/fabrics.h + $(INSTALL) -D -m 644 nvme/filters.h $(includedir)/nvme/filters.h + $(INSTALL) -D -m 644 libnvme.h $(includedir)/libnvme.h + $(INSTALL) -D -m 644 libnvme.a $(libdir)/libnvme.a + $(INSTALL) -D -m 644 $(NAME).pc $(DESTDIR)$(libdir)/pkgconfig/$(NAME).pc +ifeq ($(ENABLE_SHARED),1) + $(INSTALL) -D -m 755 $(libname) $(libdir)/$(libname) + ln -sf $(libname) $(libdir)/$(soname) + ln -sf $(libname) $(libdir)/libnvme.so +endif + +$(libnvme_objs): libnvme.h + +clean: + rm -f $(all_targets) $(libnvme_objs) $(libnvme_sobjs) $(soname).new $(NAME).pc + rm -f *.so* *.a *.o diff --git a/lib/libnvme.h b/lib/libnvme.h new file mode 100644 index 0000000000..c4921cbfce --- /dev/null +++ b/lib/libnvme.h @@ -0,0 +1,12 @@ +#ifndef _LIBNVME_H +#define _LIBNVME_H + +#include "nvme/types.h" +#include "nvme/cmd.h" +#include "nvme/ioctl.h" +#include "nvme/fabrics.h" +#include "nvme/filters.h" +#include "nvme/tree.h" +#include "nvme/util.h" + +#endif /* _LIBNVME_H */ diff --git a/lib/libnvme.map b/lib/libnvme.map new file mode 100644 index 0000000000..386dddbb96 --- /dev/null +++ b/lib/libnvme.map @@ -0,0 +1,6 @@ +{ + global: + nvme_submit_passthru; + local: + *; +}; diff --git a/lib/libnvme.pc.in b/lib/libnvme.pc.in new file mode 100644 index 0000000000..224dd54f20 --- /dev/null +++ b/lib/libnvme.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=${prefix} +libdir=@libdir@ +includedir=@includedir@ + +Name: @NAME@ +Version: @VERSION@ +Description: Manage "libnvme" subsystem devices (Non-volatile Memory Express) +URL: http://github.com/linux-nvme/nvme-cli/ + +Libs: -L${libdir} -lnvme +Cflags: -I${includedir} diff --git a/lib/libnvme.spec b/lib/libnvme.spec new file mode 100644 index 0000000000..d131af9fcc --- /dev/null +++ b/lib/libnvme.spec @@ -0,0 +1,59 @@ +Name: libnvme +Version: 0.1 +Release: 1 +Summary: Linux-native nvme device management library +License: LGPLv2+ +Group: System Environment/Libraries +Source: %{name}-%{version}.tar.gz +BuildRoot: %{_tmppath}/%{name}-root +URL: http://github.com/linux-nvme/nvme-cli + +%description +Provides library functions for accessing and managing nvme devices. + +%package devel +Summary: Development files for Linux-native nvme +Group: Development/System +Requires: libnvme +Provides: libnvme.so.1 + +%description devel +This package provides header files to include and libraries to link with +for the Linux-native nvme. + +%prep +%setup + +%build +./configure --prefix=/usr --libdir=/%{_libdir} --mandir=/usr/share/man +make + +%install +[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT + +make install DESTDIR=$RPM_BUILD_ROOT + +%clean +[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%files +%defattr(-,root,root) +%attr(0755,root,root) %{_libdir}/libnvme.so.* +%doc COPYING + +%files devel +%defattr(-,root,root) +%attr(-,root,root) %{_includedir}/libnvme/ +%attr(0644,root,root) %{_includedir}/libnvme.h +%attr(0755,root,root) %{_libdir}/libnvme.so +%attr(0644,root,root) %{_libdir}/libnvme.a +%attr(0644,root,root) %{_libdir}/pkgconfig/* +%attr(0644,root,root) %{_mandir}/man2/* + +%changelog +* Thu Dec 12 2019 Keith Busch - 0.1 +- Initial version diff --git a/lib/nvme/cmd.h b/lib/nvme/cmd.h new file mode 100644 index 0000000000..1b34d74457 --- /dev/null +++ b/lib/nvme/cmd.h @@ -0,0 +1,2245 @@ +#ifndef _LIBNVME_CMD_H +#define _LIBNVME_CMD_H + +#include "types.h" + +/** + * DOC: NVMe Admin command enums + */ + +/** + * enum nvme_admin_opcode - Known NVMe admin opcodes + * @nvme_admin_delete_sq: + * @nvme_admin_create_sq: + * @nvme_admin_get_log_page: + * @nvme_admin_delete_cq: + * @nvme_admin_create_cq: + * @nvme_admin_identify: + * @nvme_admin_abort_cmd: + * @nvme_admin_set_features: + * @nvme_admin_get_features: + * @nvme_admin_async_event: + * @nvme_admin_ns_mgmt: + * @nvme_admin_fw_commit: + * @nvme_admin_fw_download: + * @nvme_admin_dev_self_test: + * @nvme_admin_ns_attach: + * @nvme_admin_keep_alive: + * @nvme_admin_directive_send: + * @nvme_admin_directive_recv: + * @nvme_admin_virtual_mgmt: + * @nvme_admin_nvme_mi_send: + * @nvme_admin_nvme_mi_recv: + * @nvme_admin_dbbuf: + * @nvme_admin_fabrics: + * @nvme_admin_format_nvm: + * @nvme_admin_security_send: + * @nvme_admin_security_recv: + * @nvme_admin_sanitize_nvm: + * @nvme_admin_get_lba_status: + */ +enum nvme_admin_opcode { + nvme_admin_delete_sq = 0x00, + nvme_admin_create_sq = 0x01, + nvme_admin_get_log_page = 0x02, + nvme_admin_delete_cq = 0x04, + nvme_admin_create_cq = 0x05, + nvme_admin_identify = 0x06, + nvme_admin_abort_cmd = 0x08, + nvme_admin_set_features = 0x09, + nvme_admin_get_features = 0x0a, + nvme_admin_async_event = 0x0c, + nvme_admin_ns_mgmt = 0x0d, + nvme_admin_fw_commit = 0x10, + nvme_admin_fw_download = 0x11, + nvme_admin_dev_self_test = 0x14, + nvme_admin_ns_attach = 0x15, + nvme_admin_keep_alive = 0x18, + nvme_admin_directive_send = 0x19, + nvme_admin_directive_recv = 0x1a, + nvme_admin_virtual_mgmt = 0x1c, + nvme_admin_nvme_mi_send = 0x1d, + nvme_admin_nvme_mi_recv = 0x1e, + nvme_admin_dbbuf = 0x7c, + nvme_admin_fabrics = 0x7f, + nvme_admin_format_nvm = 0x80, + nvme_admin_security_send = 0x81, + nvme_admin_security_recv = 0x82, + nvme_admin_sanitize_nvm = 0x84, + nvme_admin_get_lba_status = 0x86, +}; + +/** + * enum nvme_identify_cns - + * @NVME_IDENTIFY_CNS_NS: + * @NVME_IDENTIFY_CNS_CTRL: + * @NVME_IDENTIFY_CNS_NS_ACTIVE_LIST: + * @NVME_IDENTIFY_CNS_NS_DESC_LIST: + * @NVME_IDENTIFY_CNS_NVMSET_LIST: + * @NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST: + * @NVME_IDENTIFY_CNS_ALLOCATED_NS: + * @NVME_IDENTIFY_CNS_NS_CTRL_LIST: + * @NVME_IDENTIFY_CNS_CTRL_LIST: + * @NVME_IDENTIFY_CNS_PRIMARY_CTRL_CAP: + * @NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST: + * @NVME_IDENTIFY_CNS_NS_GRANULARITY: + * @NVME_IDENTIFY_CNS_UUID_LIST: + */ +enum nvme_identify_cns { + NVME_IDENTIFY_CNS_NS = 0x00, + NVME_IDENTIFY_CNS_CTRL = 0x01, + NVME_IDENTIFY_CNS_NS_ACTIVE_LIST = 0x02, + NVME_IDENTIFY_CNS_NS_DESC_LIST = 0x03, + NVME_IDENTIFY_CNS_NVMSET_LIST = 0x04, + NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST = 0x10, + NVME_IDENTIFY_CNS_ALLOCATED_NS = 0x11, + NVME_IDENTIFY_CNS_NS_CTRL_LIST = 0x12, + NVME_IDENTIFY_CNS_CTRL_LIST = 0x13, + NVME_IDENTIFY_CNS_PRIMARY_CTRL_CAP = 0x14, + NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST = 0x15, + NVME_IDENTIFY_CNS_NS_GRANULARITY = 0x16, + NVME_IDENTIFY_CNS_UUID_LIST = 0x17, +}; + +/** + * enum nvme_cmd_get_log_lid - + * NVME_LOG_LID_ERROR: + * NVME_LOG_LID_SMART: + * NVME_LOG_LID_FW_SLOT: + * NVME_LOG_LID_CHANGED_NS: + * NVME_LOG_LID_CMD_EFFECTS: + * NVME_LOG_LID_DEVICE_SELF_TEST: + * NVME_LOG_LID_TELEMETRY_HOST: + * NVME_LOG_LID_TELEMETRY_CTRL: + * NVME_LOG_LID_ENDURANCE_GROUP: + * NVME_LOG_LID_PREDICTABLE_LAT_NVMSET: + * NVME_LOG_LID_PREDICTABLE_LAT_AGG: + * NVME_LOG_LID_ANA: + * NVME_LOG_LID_PERSISTENT_EVENT: + * NVME_LOG_LID_LBA_STATUS: + * NVME_LOG_LID_ENDURANCE_GRP_EVT: + * NVME_LOG_LID_DISC: + * NVME_LOG_LID_RESERVATION: + * NVME_LOG_LID_SANITIZE: + */ +enum nvme_cmd_get_log_lid { + NVME_LOG_LID_ERROR = 0x01, + NVME_LOG_LID_SMART = 0x02, + NVME_LOG_LID_FW_SLOT = 0x03, + NVME_LOG_LID_CHANGED_NS = 0x04, + NVME_LOG_LID_CMD_EFFECTS = 0x05, + NVME_LOG_LID_DEVICE_SELF_TEST = 0x06, + NVME_LOG_LID_TELEMETRY_HOST = 0x07, + NVME_LOG_LID_TELEMETRY_CTRL = 0x08, + NVME_LOG_LID_ENDURANCE_GROUP = 0x09, + NVME_LOG_LID_PREDICTABLE_LAT_NVMSET = 0x0a, + NVME_LOG_LID_PREDICTABLE_LAT_AGG = 0x0b, + NVME_LOG_LID_ANA = 0x0c, + NVME_LOG_LID_PERSISTENT_EVENT = 0x0d, + NVME_LOG_LID_LBA_STATUS = 0x0e, + NVME_LOG_LID_ENDURANCE_GRP_EVT = 0x0f, + NVME_LOG_LID_DISC = 0x70, + NVME_LOG_LID_RESERVATION = 0x80, + NVME_LOG_LID_SANITIZE = 0x81, +}; + +/** + * enum nvme_features_id - + * @NVME_FEAT_FID_ARBITRATION: + * @NVME_FEAT_FID_POWER_MGMT: + * @NVME_FEAT_FID_LBA_RANGE: + * @NVME_FEAT_FID_TEMP_THRESH: + * @NVME_FEAT_FID_ERR_RECOVERY: + * @NVME_FEAT_FID_VOLATILE_WC: + * @NVME_FEAT_FID_NUM_QUEUES: + * @NVME_FEAT_FID_IRQ_COALESCE: + * @NVME_FEAT_FID_IRQ_CONFIG: + * @NVME_FEAT_FID_WRITE_ATOMIC: + * @NVME_FEAT_FID_ASYNC_EVENT: + * @NVME_FEAT_FID_AUTO_PST: + * @NVME_FEAT_FID_HOST_MEM_BUF: + * @NVME_FEAT_FID_TIMESTAMP: + * @NVME_FEAT_FID_KATO: + * @NVME_FEAT_FID_HCTM: + * @NVME_FEAT_FID_NOPSC: + * @NVME_FEAT_FID_RRL: + * @NVME_FEAT_FID_PLM_CONFIG: + * @NVME_FEAT_FID_PLM_WINDOW: + * @NVME_FEAT_FID_LBA_STS_INTERVAL: + * @NVME_FEAT_FID_HOST_BEHAVIOR: + * @NVME_FEAT_FID_SANITIZE: + * @NVME_FEAT_FID_ENDURANCE_EVT_CFG: + * @NVME_FEAT_FID_SW_PROGRESS: + * @NVME_FEAT_FID_HOST_ID: + * @NVME_FEAT_FID_RESV_MASK: + * @NVME_FEAT_RESV_PERSIST: + * @NVME_FEAT_FID_WRITE_PROTECT: + */ +enum nvme_features_id { + NVME_FEAT_FID_ARBITRATION = 0x01, + NVME_FEAT_FID_POWER_MGMT = 0x02, + NVME_FEAT_FID_LBA_RANGE = 0x03, + NVME_FEAT_FID_TEMP_THRESH = 0x04, + NVME_FEAT_FID_ERR_RECOVERY = 0x05, + NVME_FEAT_FID_VOLATILE_WC = 0x06, + NVME_FEAT_FID_NUM_QUEUES = 0x07, + NVME_FEAT_FID_IRQ_COALESCE = 0x08, + NVME_FEAT_FID_IRQ_CONFIG = 0x09, + NVME_FEAT_FID_WRITE_ATOMIC = 0x0a, + NVME_FEAT_FID_ASYNC_EVENT = 0x0b, + NVME_FEAT_FID_AUTO_PST = 0x0c, + NVME_FEAT_FID_HOST_MEM_BUF = 0x0d, + NVME_FEAT_FID_TIMESTAMP = 0x0e, + NVME_FEAT_FID_KATO = 0x0f, + NVME_FEAT_FID_HCTM = 0X10, + NVME_FEAT_FID_NOPSC = 0X11, + NVME_FEAT_FID_RRL = 0x12, + NVME_FEAT_FID_PLM_CONFIG = 0x13, + NVME_FEAT_FID_PLM_WINDOW = 0x14, + NVME_FEAT_FID_LBA_STS_INTERVAL = 0x15, + NVME_FEAT_FID_HOST_BEHAVIOR = 0x16, + NVME_FEAT_FID_SANITIZE = 0x17, + NVME_FEAT_FID_ENDURANCE_EVT_CFG = 0x18, + NVME_FEAT_FID_SW_PROGRESS = 0x80, + NVME_FEAT_FID_HOST_ID = 0x81, + NVME_FEAT_FID_RESV_MASK = 0x82, + NVME_FEAT_RESV_PERSIST = 0x83, + NVME_FEAT_FID_WRITE_PROTECT = 0x84, +}; + +/** + * enum nvme_get_features_sel - + * @NVME_GET_FEATURES_SEL_CURRENT: + * @NVME_GET_FEATURES_SEL_DEFAULT: + * @NVME_GET_FEATURES_SEL_SAVED: + */ +enum nvme_get_features_sel { + NVME_GET_FEATURES_SEL_CURRENT = 0, + NVME_GET_FEATURES_SEL_DEFAULT = 1, + NVME_GET_FEATURES_SEL_SAVED = 2, +}; + +/** + * enum nvme_cmd_format_mset - + * @NVME_FORMAT_MSET_SEPARATE: + * @NVME_FORMAT_MSET_EXTENEDED: + */ +enum nvme_cmd_format_mset { + NVME_FORMAT_MSET_SEPARATE = 0, + NVME_FORMAT_MSET_EXTENEDED = 1, +}; + +/** + * enum nvme_cmd_format_pi - + * @NVME_FORMAT_PI_DISABLE: + * @NVME_FORMAT_PI_TYPE1: + * @NVME_FORMAT_PI_TYPE2: + * @NVME_FORMAT_PI_TYPE3: + */ +enum nvme_cmd_format_pi { + NVME_FORMAT_PI_DISABLE = 0, + NVME_FORMAT_PI_TYPE1 = 1, + NVME_FORMAT_PI_TYPE2 = 2, + NVME_FORMAT_PI_TYPE3 = 3, +}; + +/** + * @enum nvme_cmd_format_pil - + * @NVME_FORMAT_PIL_LAST: + * @NVME_FORMAT_PIL_FIRST: + */ +enum nvme_cmd_format_pil { + NVME_FORMAT_PIL_LAST = 0, + NVME_FORMAT_PIL_FIRST = 1, +}; + +/** + * enum nvme_cmd_format_ses - + * @NVME_FORMAT_SES_NONE: + * @NVME_FORMAT_SES_USER_DATA_ERASE: + * @NVME_FORMAT_SES_CRYPTO_ERASE: + */ +enum nvme_cmd_format_ses { + NVME_FORMAT_SES_NONE = 0, + NVME_FORMAT_SES_USER_DATA_ERASE = 1, + NVME_FORMAT_SES_CRYPTO_ERASE = 2, +}; + +/** + * enum nvme_ns_mgmt_sel - + * @NVME_NAMESPACE_MGMT_SEL_CREATE: + * @NVME_NAMESPACE_MGMT_SEL_DELETE: + */ +enum nvme_ns_mgmt_sel { + NVME_NS_MGMT_SEL_CREATE = 0, + NVME_NS_MGMT_SEL_DELETE = 1, +}; + +/** + * enum nvme_ns_attach_sel - + * NVME_NS_ATTACH_SEL_CTRL_ATTACH: + * NVME_NP_ATTACH_SEL_CTRL_DEATTACH: + */ +enum nvme_ns_attach_sel { + NVME_NS_ATTACH_SEL_CTRL_ATTACH = 0, + NVME_NS_ATTACH_SEL_CTRL_DEATTACH = 1, +}; + +/** + * enum nvme_fw_commit_ca - + * @NVME_FW_COMMIT_CA_REPLACE: + * @NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE: + * @NVME_FW_COMMIT_CA_SET_ACTIVE: + * @NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE_IMMEDIATE: + * @NVME_FW_COMMIT_CA_REPLACE_BOOT_PARTITION: + * @NVME_FW_COMMIT_CA_ACTIVATE_BOOT_PARTITION: + */ +enum nvme_fw_commit_ca { + NVME_FW_COMMIT_CA_REPLACE = 0, + NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE = 1, + NVME_FW_COMMIT_CA_SET_ACTIVE = 2, + NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE_IMMEDIATE = 3, + NVME_FW_COMMIT_CA_REPLACE_BOOT_PARTITION = 6, + NVME_FW_COMMIT_CA_ACTIVATE_BOOT_PARTITION = 7, +}; + +/** + * enum nvme_directive_dtype - + * @NVME_DIRECTIVE_DTYPE_IDENTIFY: + * @NVME_DIRECTIVE_DTYPE_STREAMS: + */ +enum nvme_directive_dtype { + NVME_DIRECTIVE_DTYPE_IDENTIFY = 0, + NVME_DIRECTIVE_DTYPE_STREAMS = 1, +}; + +/** + * enum - + */ +enum nvme_cmd_directive_receive_identify_doper { + NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM = 0x01, +}; + +/** + * enum - + */ +enum nvme_cmd_directive_receive_streams_doper { + NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM = 0x01, + NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS = 0x02, + NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE = 0x03, +}; + +/** + * enum - + */ +enum nvme_cmd_directive_send_identify_doper { + NVME_DIRECTIVE_SEND_IDENTIFY_DOPER_ENDIR = 0x01, +}; + +/** + * enum - + */ +enum nvme_cmd_directive_send_identify_endir { + NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_DISABLE = 0, + NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_ENABLE = 1, +}; + +/** + * enum - + */ +enum nvme_cmd_directive_send_streams_doper { + NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_IDENTIFIER = 0x01, + NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE = 0x02, +}; + +/** + * enum nvme_sanitize_sanact - + * @NVME_SANITIZE_SANACT_EXIT_FAILURE: + * @NVME_SANITIZE_SANACT_START_BLOCK_ERASE: + * @NVME_SANITIZE_SANACT_START_OVERWRITE: + * @NVME_SANITIZE_SANACT_START_CRYPTO_ERASE: + */ +enum nvme_sanitize_sanact { + NVME_SANITIZE_SANACT_EXIT_FAILURE = 1, + NVME_SANITIZE_SANACT_START_BLOCK_ERASE = 2, + NVME_SANITIZE_SANACT_START_OVERWRITE = 3, + NVME_SANITIZE_SANACT_START_CRYPTO_ERASE = 4, +}; + +/** + * enum nvme_dst_stc - + * @NVME_DST_STC_SHORT: + * @NVME_DST_STC_LONG: + * @NVME_DST_STC_VS: + * @NVME_DST_STC_ABORT: + */ +enum nvme_dst_stc { + NVME_DST_STC_SHORT = 0x1, + NVME_DST_STC_LONG = 0x2, + NVME_DST_STC_VS = 0xe, + NVME_DST_STC_ABORT = 0xf, +}; + +/** + * enum nvme_virt_mgmt_act - + * @NVME_VIRT_MGMT_ACT_PRIM_CTRL_FLEX_ALLOC: + * @NVME_VIRT_MGMT_ACT_OFFLINE_SEC_CTRL: + * @NVME_VIRT_MGMT_ACT_ASSIGN_SEC_CTRL: + * @NVME_VIRT_MGMT_ACT_ONLINE_SEC_CTRL: + */ +enum nvme_virt_mgmt_act { + NVME_VIRT_MGMT_ACT_PRIM_CTRL_FLEX_ALLOC = 1, + NVME_VIRT_MGMT_ACT_OFFLINE_SEC_CTRL = 7, + NVME_VIRT_MGMT_ACT_ASSIGN_SEC_CTRL = 8, + NVME_VIRT_MGMT_ACT_ONLINE_SEC_CTRL = 9, +}; + +/** + * enum nvme_virt_mgmt_rt - + * @NVME_VIRT_MGMT_RT_VQ_RESOURCE: + * @NVME_VIRT_MGMT_RT_VI_RESOURCE: + */ +enum nvme_virt_mgmt_rt { + NVME_VIRT_MGMT_RT_VQ_RESOURCE = 0, + NVME_VIRT_MGMT_RT_VI_RESOURCE = 1, +}; + +/** + * nvme_identify() - Send the NVMe Identify command + * @fd: File descriptor of nvme device + * @cns: The Controller or Namespace structure, see @enum nvme_identify_cns + * @nsid: Namespace identifier, if applicable + * @cntid: The Controller Identifier, if applicable + * @nvmsetid: The NVMe Set ID if CNS is 04h + * @uuidx: UUID Index if controller supports this id selection method + * @data: User space destination address to transfer the data + * + * The Identify command returns a data buffer that describes information about + * the NVM subsystem, the controller or the namespace(s). + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_identify(int fd, enum nvme_identify_cns cns, __u32 nsid, + __u16 cntid, __u16 nvmsetid, __u8 uuidx, void *data); + +/** + * nvme_identify_ctrl() - Retrieves nvme identify controller + * @fd: File descriptor of nvme device + * id: User space destination address to transfer the data, + * + * Sends nvme identify with CNS value %NVME_IDENTIFY_CNS_CTRL. + * + * See &struct nvme_id_ctrl for details on the data returned. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_identify_ctrl(int fd, struct nvme_id_ctrl *id); + +/** + * nvme_identify_ns() - Retrieves nvme identify namespace + * @fd: File descriptor of nvme device + * @nsid: Namespace to identify + * @ns: User space destination address to transfer the data + * + * If the Namespace Identifier (NSID) field specifies an active NSID, then the + * Identify Namespace data structure is returned to the host for that specified + * namespace. + * + * If the controller supports the Namespace Management capability and the NSID + * field is set to %NVME_NSID_ALL, then the controller returns an Identify Namespace + * data structure that specifies capabilities that are common across namespaces + * for this controller. + * + * See &struct nvme_id_ns for details on the structure returned. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +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 + * @fd: File descriptor of nvme device + * @nsid: Namespace to identify + * @ns: User space destination address to transfer the data + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_identify_allocated_ns(int fd, __u32 nsid, struct nvme_id_ns *ns); + +/** + * nvme_identify_active_ns_list() - Retrieves active namespaces id list + * @fd: File descriptor of nvme device + * @nsid: Return namespaces greater than this identifer + * @ns_list: User space destination address to transfer the data + * + * A list of 1024 namespace IDs is returned to the host containing NSIDs in + * increasing order that are greater than the value specified in the Namespace + * Identifier (nsid) field of the command. + * + * See &struct nvme_ns_list for the definition of the returned structure. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_identify_active_ns_list(int fd, __u32 nsid, struct nvme_ns_list *list); + +/** + * nvme_identify_allocated_ns_list() - Retrieves allocated namespace id list + * @fd: File descriptor of nvme device + * @nsid: Return namespaces greater than this identifer + * @ns_list: User space destination address to transfer the data + * + * A list of 1024 namespace IDs is returned to the host containing NSIDs in + * increasing order that are greater than the value specified in the Namespace + * Identifier (nsid) field of the command. + * + * See &struct nvme_ns_list for the definition of the returned structure. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_identify_allocated_ns_list(int fd, __u32 nsid, struct nvme_ns_list *list); + +/** + * nvme_identify_ctrl_list() - Retrieves identify controller list + * @fd: File descriptor of nvme device + * @cntlid: Starting CNTLID to return in the list + * @cntlist: User space destination address to transfer the data + * + * Up to 2047 controller identifiers is returned containing a controller + * identifier greater than or equal to the controller identifier specified in + * @cntid. + * + * See &struct nvme_ctrl_list for a definition of the structure returned. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_identify_ctrl_list(int fd, __u16 cntid, + struct nvme_ctrl_list *ctrlist); + +/** + * nvme_identify_nsid_ctrl_list() - + * @fd: File descriptor of nvme device + * @nsid: Return controllers that are attached to this nsid + * @cntlid: Starting CNTLID to return in the list + * @cntlist: User space destination address to transfer the data + * + * Up to 2047 controller identifiers is returned containing a controller + * identifier greater than or equal to the controller identifier specified in + * @cntid. + * + * See &struct nvme_ctrl_list for a definition of the structure returned. + * + * Return: The nvme command status if a response was received or -1 + */ +int nvme_identify_nsid_ctrl_list(int fd, __u32 nsid, __u16 cntid, + struct nvme_ctrl_list *ctrlist); + +/** + * nvme_identify_ns_descs() - Retrieves namespace descriptor list + * @fd: File descriptor of nvme device + * @nsid: The namespace id to retrieve destriptors + * @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'. + * + * See &struct nvme_ns_id_desc for the definition of the returned structure. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_identify_ns_descs(int fd, __u32 nsid, struct nvme_ns_id_desc *descs); + +/** + * nvme_identify_nvmset_list() - Retrieves NVM Set List + * @fd: File descriptor of nvme device + * @nvmeset_id: NVM Set Identifier + * @nvmset: User space destination address to transfer the data + * + * Retrieves an NVM Set List, struct nvme_id_nvmset. The data structure is an + * ordered list by NVM Set Identifier, starting with the first NVM Set + * 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. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_identify_nvmset_list(int fd, __u16 nvmsetid, struct nvme_id_nvmset_list *nvmset); + +/** + * nvme_identify_primary_ctrl() - Retrieve NVMe Primary Controller + * identification + * &fd: + * @cntid: + * @cap: + * + * See &struct nvme_primary_ctrl_cap for the defintion of the returned structure, @cap. + * + * Return: The nvme command status if a response was received or -1 + * with errno set otherwise. + */ +int nvme_identify_primary_ctrl(int fd, __u16 cntid, struct nvme_primary_ctrl_cap *cap); + +/** + * nvme_identify_secondary_ctrl_list() - Retrieves secondary controller list + * @fd: File descriptor of nvme device + * @cntid: Return controllers starting at this identifier + * @sc_list: User space destination address to transfer the data + * + * A Secondary Controller List is returned to the host for up to 127 secondary + * controllers associated with the primary controller processing this command. + * 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 + * structure. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_identify_secondary_ctrl_list(int fd, __u16 cntid, struct nvme_secondary_ctrl_list *list); + +/** + * nvme_identify_ns_granularity() - Retrieves namespace granularity + * identification + * @fd: File descriptor of nvme device + * @gr_list: User space destination address to transfer the data + * + * If the controller supports reporting of Namespace Granularity, then a + * Namespace Granularity List is returned to the host for up to sixteen + * namespace granularity descriptors + * + * See &struct nvme_id_ns_granularity_list for the definition of the returned + * structure. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_identify_ns_granularity(int fd, struct nvme_id_ns_granularity_list *list); + +/** + * nvme_identify_uuid() - Retrieves device's UUIDs + * @fd: File descriptor of nvme device + * @uuid_list: User space destination address to transfer the data + * + * Each UUID List entry is either 0h, the NVMe Invalid UUID, or a valid UUID. + * Valid UUIDs are those which are non-zero and are not the NVMe Invalid UUID. + * + * See &struct nvme_id_uuid_list for the definition of the returned structure. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_identify_uuid(int fd, struct nvme_id_uuid_list *list); + +/** + * nvme_get_log() - NVMe Admin Get Log command + * @fd: File descriptor of nvme device + * @lid: Log page identifier, see &enum nvme_cmd_get_log_lid for known values + * @nsid: Namespace identifier, if applicable + * @lpo: Log page offset for partial log transfers + * @lsp: Log specific field + * @lsi: Endurance group information + * @rae: Retain asynchronous events + * @uuidx: UUID selection, if supported + * @len: Length of provided user buffer to hold the log data in bytes + * @log: User space destination address to transfer the data + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, + __u8 lsp, __u16 lsi, bool rae, __u8 uuidx, __u32 len, void *log); + +/** + * nvme_get_log_error() - Retrieve nvme error log + * @fd: File descriptor of nvme device + * @entries: Number of error log entries allocated + * @rae: Retain asynchronous events + * @err_log: Array of error logs of size 'entries' + * + * This log page is used to describe extended error information for a command + * that completed with error, or may report an error that is not specific to a + * particular command. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_log_error(int fd, unsigned nr_entries, bool rae, + struct nvme_error_log_page *log); + +/** + * nvme_get_log_smart() - Retrieve nvme smart log + * @fd: File descriptor of nvme device + * @nsid: Optional namespace identifier + * @rae: Retain asynchronous events + * @smart_log: User address to store the smart log + * + * This log page is used to provide SMART and general health information. The + * information provided is over the life of the controller and is retained + * across power cycles. To request the controller log page, the namespace + * identifier specified is FFFFFFFFh. The controller may also support + * requesting the log page on a per namespace basis, as indicated by bit 0 of + * the LPA field in the Identify Controller data structure. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_log_smart(int fd, __u32 nsid, bool rae, struct nvme_smart_log *log); + +/** + * nvme_get_log_fw_slot() - Retrieves the controller firmware log + * @fd: File descriptor of nvme device + * @rae: Retain asynchronous events + * @fw_log: User address to store the log page + * + * This log page is used to describe the firmware revision stored in each + * firmware slot supported. The firmware revision is indicated as an ASCII + * string. The log page also indicates the active slot number. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_log_fw_slot(int fd, bool rae, struct nvme_firmware_slot *log); + +/** + * nvme_get_log_changed_ns_list() - Retrieve namespace changed list + * @fd: File descriptor of nvme device + * @rae: Retain asynchronous events + * @ns_list: User address to store the log page + * + * This log page is used to describe namespaces attached to this controller + * that have changed since the last time the namespace was identified, been + * added, or deleted. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_log_changed_ns_list(int fd, bool rae, struct nvme_ns_list *log); + +/** + * nvme_get_log_cmd_effects() - Retrieve nvme command effects log + * @fd: File descriptor of nvme device + * @effects_log:User address to store the effects log + * + * This log page is used to describe the commands that the controller supports + * and the effects of those commands on the state of the NVM subsystem. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_log_cmd_effects(int fd, struct nvme_cmd_effects_log *log); + +/** + * nvme_get_log_device_self_test() - Retrieve the device self test log + * @fd: File descriptor of nvme device + * @nsid: Namespace ID being tested + * @log: Userspace address of the log payload + * + * The log page is used to indicate the status of an in progress self test and + * the percent complete of that operation, and the results of the previous 20 + * self-test operations. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_log_device_self_test(int fd, struct nvme_self_test_log *log); + +/** + * nvme_get_log_create_telemetry_host() - + */ +int nvme_get_log_create_telemetry_host(int fd, struct nvme_telemetry_log *log); +/** * nvme_get_log_telemetry_host() - + * @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 + * using the previously existing capture. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_log_telemetry_host(int fd, __u64 offset, __u32 len, void *log); + +/** + * nvme_get_log_telemetry_ctrl() - + * @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 + */ +int nvme_get_log_telemetry_ctrl(int fd, bool rae, __u64 offset, __u32 len, void *log); + +/** + * nvme_get_log_endurance_group() - + * @fd: File descriptor of nvme device + * @endgid: Starting group identifier to return in the list + * @log: User address to store the endurance log + * + * This log page indicates if an Endurance Group Event has occurred for a + * particular Endurance Group. If an Endurance Group Event has occurred, the + * details of the particular event are included in the Endurance Group + * Information log page for that Endurance Group. An asynchronous event is + * generated when an entry for an Endurance Group is newly added to this log + * page. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_log_endurance_group(int fd, __u16 endgid, struct nvme_endurance_group_log *log); + +/** + * nvme_get_log_predictable_lat_nvmset() - + * @fd: + * @nvmsetid: + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_log_predictable_lat_nvmset(int fd, __u16 nvmsetid, + struct nvme_nvmset_predictable_lat_log *log); + +/** + * nvme_get_log_predictable_lat_event() - + * @fd: File descriptor of nvme device + * @rae: Retain asynchronous events + */ +int nvme_get_log_predictable_lat_event(int fd, bool rae, __u32 offset, + __u32 len, void *log); + +/** + * + */ +enum nvme_log_ana_lsp { + NVME_LOG_ANA_LSP_RGO_NAMESPACES = 0, + NVME_LOG_ANA_LSP_RGO_GROUPS_ONLY = 1, +}; + +/** + * nvme_get_log_ana() - + * @fd: File descriptor of nvme device + * @lsp: Log specific, see &enum nvme_get_log_ana_lsp + * @rae: Retain asynchronous events + * @len: The allocated length of the log page + * @log: User address to store the ana log + * + * This log consists of a header describing the log and descriptors containing + * the asymmetric namespace access information for ANA Groups that contain + * namespaces that are attached to the controller processing the command. + * + * See &struct nvme_ana_rsp_hdr for the defintion of the returned structure. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_log_ana(int fd, enum nvme_log_ana_lsp lsp, bool rae, __u64 offset, + __u32 len, void *log); + +/** + * nvme_get_log_ana_groups() - + * @fd: File descriptor of nvme device + * @rae: Retain asynchronous events + * + * See &struct nvme_ana_group_desc for the defintion of the returned structure. + */ +int nvme_get_log_ana_groups(int fd, bool rae, __u32 len, + struct nvme_ana_group_desc *log); + +/** + * nvme_get_log_lba_status() - + * @fd: File descriptor of nvme device + * @rae: Retain asynchronous events + */ +int nvme_get_log_lba_status(int fd, bool rae, __u64 offset, __u32 len, + void *log); + +/** + * nvme_get_log_endurance_grp_evt() - + * @fd: File descriptor of nvme device + * @rae: Retain asynchronous events + */ +int nvme_get_log_endurance_grp_evt(int fd, bool rae, __u32 offset, __u32 len, + void *log); + +/** + * nvme_get_log_discovery() - + * @fd: File descriptor of nvme device + * @rae: Retain asynchronous events + * @offset: Offset of this log to retrieve + * @len: The allocated size for this portion of the log + * @log: User address to store the discovery log + * + * Supported only by fabrics discovery controllers, returning discovery + * records. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_log_discovery(int fd, bool rae, __u32 offset, __u32 len, void *log); + +/** + * nvme_get_log_reservation() - + * @fd: File descriptor of nvme device + * @rae: Retain asynchronous events + */ +int nvme_get_log_reservation(int fd, bool rae, + struct nvme_resv_notification_log *log); + +/** + * nvme_get_log_sanitize() - + * @fd: File descriptor of nvme device + * @rae: Retain asynchronous events + * @log: User address to store the sanitize log + * + * The Sanitize Status log page is used to report sanitize operation time + * estimates and information about the most recent sanitize operation. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_log_sanitize(int fd, bool rae, + struct nvme_sanitize_log_page *log); + +/** + * nvme_set_feature() - Set a feature attribute + * @fd: File descriptor of nvme device + * @fid: Feature identifier + * @nsid: Namespace ID, if applicable + * @cdw11: Value to set the feature to + * @cdw12: Feature specific command dword12 field + * @save: Save value across power states + * @uuidx: UUID Index for differentiating vendor specific encoding + * @cdw14: Feature specific command dword15 field + * @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 or -1 with errno + * set otherwise. + */ +int nvme_set_features(int fd, __u8 fid, __u32 nsid, __u32 cdw11, __u32 cdw12, + bool save, __u8 uuidx, __u32 cdw15, __u32 data_len, + void *data, __u32 *result); + +/** + * nvme_set_features_arbitration() - + */ +int nvme_set_features_arbitration(int fd, __u8 ab, __u8 lpw, __u8 mpw, + __u8 hpw, bool save, __u32 *result); + +/** + * nvme_set_features_power_mgmt() - + */ +int nvme_set_features_power_mgmt(int fd, __u8 ps, __u8 wh, bool save, + __u32 *result); + +/** + * nvme_set_features_lba_range() - + */ +int nvme_set_features_lba_range(int fd, __u32 nsid, __u32 nr_ranges, bool save, + struct nvme_lba_range_type *data, __u32 *result); + + +/** + * enum nvme_feat_tmpthresh_thsel - + */ +enum nvme_feat_tmpthresh_thsel { + NVME_FEATURE_TEMPTHRESH_THSEL_OVER = 0, + NVME_FEATURETEMPTHRESH__THSEL_UNDER = 1, +}; + +/** + * nvme_set_features_temp_thresh() - + */ +int nvme_set_features_temp_thresh(int fd, __u16 tmpth, __u8 tmpsel, + enum nvme_feat_tmpthresh_thsel thsel, + bool save, __u32 *result); + +/** + * nvme_set_features_err_recovery() - + */ +int nvme_set_features_err_recovery(int fd, __u32 nsid, __u16 tler, + bool dulbe, bool save, __u32 *result); + + +/** + * nvme_set_features_volatile_wc() - + */ +int nvme_set_features_volatile_wc(int fd, bool wce, bool save, + __u32 *result); + +/** + * nvme_set_features_irq_coalesce() - + */ +int nvme_set_features_irq_coalesce(int fd, __u8 thr, __u8 time, + bool save, __u32 *result); + +/** + * nvme_set_features_irq_config() - + */ +int nvme_set_features_irq_config(int fd, __u16 iv, bool cd, bool save, + __u32 *result); + + +/** + * nvme_set_features_write_atomic() - + */ +int nvme_set_features_write_atomic(int fd, bool dn, bool save, + __u32 *result); + +/** + * enum nvme_features_async_event_config_flags - + */ +enum nvme_features_async_event_config_flags { + NVME_FEATURE_AENCFG_SMART_CRIT_SPARE = 1 << 0, + NVME_FEATURE_AENCFG_SMART_CRIT_TEMPERATURE = 1 << 1, + NVME_FEATURE_AENCFG_SMART_CRIT_DEGRADED = 1 << 2, + NVME_FEATURE_AENCFG_SMART_CRIT_READ_ONLY = 1 << 3, + NVME_FEATURE_AENCFG_SMART_CRIT_VOLATILE_BACKUP = 1 << 4, + NVME_FEATURE_AENCFG_SMART_CRIT_READ_ONLY_PMR = 1 << 5, + NVME_FEATURE_AENCFG_NOTICE_NAMESPACE_ATTRIBUTES = 1 << 8, + NVME_FEATURE_AENCFG_NOTICE_FIRMWARE_ACTIVATION = 1 << 9, + NVME_FEATURE_AENCFG_NOTICE_TELEMETRY_LOG = 1 << 10, + NVME_FEATURE_AENCFG_NOTICE_ANA_CHANGE = 1 << 11, + NVME_FEATURE_AENCFG_NOTICE_PL_EVENT = 1 << 12, + NVME_FEATURE_AENCFG_NOTICE_LBA_STATUS = 1 << 13, + NVME_FEATURE_AENCFG_NOTICE_EG_EVENT = 1 << 14, + NVME_FEATURE_AENCFG_NOTICE_DISCOVERY_CHANGE = 1 << 31, +}; + +/** + * nvme_set_features_async_event() - + */ +int nvme_set_features_async_event(int fd, __u32 events, bool save, + __u32 *result); + + +/** + * nvme_set_features_auto_pst() - + */ +int nvme_set_features_auto_pst(int fd, bool apste, bool save, + struct nvme_feat_auto_pst *apst, + __u32 *result); + +/** + * nvme_set_features_timestamp() - + */ +int nvme_set_features_timestamp(int fd, bool save, __u64 timestamp); + + +/** + * nvme_set_features_hctm() - + */ +int nvme_set_features_hctm(int fd, __u16 tmt2, __u16 tmt1, bool save, + __u32 *result); + +/** + * nvme_admin_set_features_nopsc() - + */ +int nvme_admin_set_features_nopsc(int fd, bool noppme, bool save, + __u32 *result); + +/** + * nvme_set_features_rrl() - + */ +int nvme_set_features_rrl(int fd, __u8 rrl, __u16 nvmsetid, bool save, + __u32 *result); + +/** + * nvme_set_features_plm_config() - + */ +int nvme_set_features_plm_config(int fd, bool enable, __u16 nvmsetid, + bool save, struct nvme_plm_config *data, + __u32*result); + +/** + * enum nvme_feat_plm_window_select - + */ +enum nvme_feat_plm_window_select { + NVME_FEATURE_PLM_DTWIN = 1, + NVME_FEATURE_PLM_NDWIN = 2, +}; + +/** + * nvme_set_features_plm_window() - + */ +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() - + */ +int nvme_set_features_lba_sts_interval(int fd, __u16 lsiri, __u16 lsipi, + bool save, __u32 *result); + + +/** + * nvme_set_features_host_behavior() - + */ +int nvme_set_features_host_behavior(int fd, bool save, + struct nvme_feat_host_behavior *data); + +/** + * nvme_set_features_sanitize() - + */ +int nvme_set_features_sanitize(int fd, bool nodrm, bool save, __u32 *result); + +/** + * nvme_set_features_endurance_evt_cfg() - + * @fd: + * @endgid: + * @egwarn: Flags to enable warning, see &enum nvme_eg_critical_warning_flags + */ +int nvme_set_features_endurance_evt_cfg(int fd, __u16 endgid, __u8 egwarn, + bool save, __u32 *result); + +/** + * nvme_set_features_sw_progress() - + */ +int nvme_set_features_sw_progress(int fd, __u8 pbslc, bool save, + __u32 *result); + + +/** + * nvme_set_features_host_id() - + */ +int nvme_set_features_host_id(int fd, bool exhid, bool save, __u8 *hostid); + +/** + * + */ +enum nvme_feat_resv_notify_flags { + NVME_FEAT_RESV_NOTIFY_REGPRE = 1 << 1, + NVME_FEAT_RESV_NOTIFY_RESREL = 1 << 2, + NVME_FEAT_RESV_NOTIFY_RESPRE = 1 << 3, +}; + +/** + * nvme_set_features_resv_mask() - + */ +int nvme_set_features_resv_mask(int fd, __u32 mask, bool save, __u32 *result); + +/** + * nvme_set_features_resv_persist() - + */ +int nvme_set_features_resv_persist(int fd, bool ptpl, bool save, __u32 *result); + +/** + * enum nvme_feat_ns_wp_cfg_state - + * @NVME_FEAT_NS_NO_WRITE_PROTECT: + * @NVME_FEAT_NS_WRITE_PROTECT: + * @NVME_FEAT_NS_WRITE_PROTECT_PWR_CYCLE: + * @NVME_FEAT_NS_WRITE_PROTECT_PERMANENT: + */ +enum nvme_feat_nswpcfg_state { + 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, +}; + +/** + * nvme_set_features_write_protect() - + */ +int nvme_set_features_write_protect(int fd, enum nvme_feat_nswpcfg_state state, + bool save, __u32 *result); + +/** + * nvme_get_features() - Retrieve a feature attribute + * @fd: File descriptor of nvme device + * @fid: Feature identifier + * @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 + * @uuidx: UUID Index for differentiating vendor specific encoding + * @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 or -1 with errno + * set otherwise. + */ +int nvme_get_features(int fd, enum nvme_features_id fid, __u32 nsid, + enum nvme_get_features_sel sel, __u32 cdw11, __u8 uuidx, + __u32 data_len, void *data, __u32 *result); + +/** + * nvme_get_features_arbitration() - + */ +int nvme_get_features_arbitration(int fd, enum nvme_get_features_sel sel, + __u32 *result); + +/** + * nvme_get_features_power_mgmt() - + */ +int nvme_get_features_power_mgmt(int fd, enum nvme_get_features_sel sel, + __u32 *result); + +/** + * nvme_get_features_lba_range() - + */ +int nvme_get_features_lba_range(int fd, enum nvme_get_features_sel sel, + struct nvme_lba_range_type *data, + __u32 *result); + +/** + * nvme_get_features_temp_thresh() - + */ +int nvme_get_features_temp_thresh(int fd, enum nvme_get_features_sel sel, + __u32 *result); + +/** + * nvme_get_features_err_recovery() - + */ +int nvme_get_features_err_recovery(int fd, enum nvme_get_features_sel sel, + __u32 *result); + +/** + * nvme_get_features_volatile_wc() - + */ +int nvme_get_features_volatile_wc(int fd, enum nvme_get_features_sel sel, + __u32 *result); + +/** + * nvme_get_features_num_queues() - + */ +int nvme_get_features_num_queues(int fd, enum nvme_get_features_sel sel, + __u32 *result); + +/** + * nvme_get_features_irq_coalesce() - + */ +int nvme_get_features_irq_coalesce(int fd, enum nvme_get_features_sel sel, + __u32 *result); + +/** + * nvme_get_features_irq_config() - + */ +int nvme_get_features_irq_config(int fd, enum nvme_get_features_sel sel, + __u16 iv, __u32 *result); + +/** + * nvme_get_features_write_atomic() - + */ +int nvme_get_features_write_atomic(int fd, enum nvme_get_features_sel sel, + __u32 *result); + +/** + * nvme_get_features_async_event() - + */ +int nvme_get_features_async_event(int fd, enum nvme_get_features_sel sel, + __u32 *result); + +/** + * nvme_get_features_auto_pst() - + */ +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() - + */ +int nvme_get_features_host_mem_buf(int fd, enum nvme_get_features_sel sel, + __u32 *result); + +/** + * nvme_get_features_timestamp() - + */ +int nvme_get_features_timestamp(int fd, enum nvme_get_features_sel sel, + struct nvme_timestamp *ts); + +/** + * nvme_get_features_kato() - + */ +int nvme_get_features_kato(int fd, enum nvme_get_features_sel sel, __u32 *result); + +/** + * nvme_get_features_hctm() - + */ +int nvme_get_features_hctm(int fd, enum nvme_get_features_sel sel, __u32 *result); + +/** + * nvme_get_features_nopsc() - + */ +int nvme_get_features_nopsc(int fd, enum nvme_get_features_sel sel, __u32 *result); + +/** + * nvme_get_features_rrl() - + */ +int nvme_get_features_rrl(int fd, enum nvme_get_features_sel sel, __u32 *result); + +/** + * nvme_get_features_plm_config() - + */ +int nvme_get_features_plm_config(int fd, enum nvme_get_features_sel sel, + __u16 nvmsetid, struct nvme_plm_config *data, + __u32 *result); + +/** + * nvme_get_features_plm_window() - + */ +int nvme_get_features_plm_window(int fd, enum nvme_get_features_sel sel, + __u16 nvmsetid, __u32 *result); + +/** + * nvme_get_features_lba_sts_interval() - + */ +int nvme_get_features_lba_sts_interval(int fd, enum nvme_get_features_sel sel, + __u32 *result); + +/** + * nvme_get_features_host_behavior() - + */ +int nvme_get_features_host_behavior(int fd, enum nvme_get_features_sel sel, + struct nvme_feat_host_behavior *data, + __u32 *result); + +/** + * nvme_get_features_sanitize() - + */ +int nvme_get_features_sanitize(int fd, enum nvme_get_features_sel sel, + __u32 *result); + +/** + * nvme_get_features_endurance_event_cfg() - + */ +int nvme_get_features_endurance_event_cfg(int fd, enum nvme_get_features_sel sel, + __u16 endgid, __u32 *result); + +/** + * nvme_get_features_sw_progress() - + */ +int nvme_get_features_sw_progress(int fd, enum nvme_get_features_sel sel, + __u32 *result); + +/** + * nvme_get_features_host_id() - + */ +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() - + */ +int nvme_get_features_resv_mask(int fd, enum nvme_get_features_sel sel, + __u32 *result); + +/** + * nvme_get_features_resv_persist() - + */ +int nvme_get_features_resv_persist(int fd, enum nvme_get_features_sel sel, + __u32 *result); + +/** + * nvme_get_features_write_protect() - + */ +int nvme_get_features_write_protect(int fd, __u32 nsid, + enum nvme_get_features_sel sel, + __u32 *result); + + +/** + * nvme_format_nvm() - Format nvme namespace(s) + * @fd: File descriptor of nvme device + * @nsid: Namespace ID to format + * @lbaf: Logical block address 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 + * @timeout: Set to override default timeout to this value in milliseconds; + * useful for long running formats. 0 will use system default. + * + * The Format NVM command is used to low level format the NVM media. This + * command is used by the host to change the LBA data size and/or metadata + * size. A low level format may destroy all data and metadata associated with + * all namespaces or only the specific namespace associated with the command + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_format_nvm(int fd, __u32 nsid, __u8 lbaf, + enum nvme_cmd_format_mset mset, + enum nvme_cmd_format_pi pi, + enum nvme_cmd_format_pil pil, + enum nvme_cmd_format_ses ses, + __u32 timeout); + +/** + * nvme_ns_mgmt() - + * @fd: File descriptor of nvme device + */ +int nvme_ns_mgmt(int fd, __u32 nsid, enum nvme_ns_mgmt_sel sel, + struct nvme_id_ns *ns, __u32 *result, __u32 timeout); + +/** + * nvme_ns_mgmt_create() - + * @fd: File descriptor of nvme device + * @ns: Namespace identifiaction that defines 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. + * + * On successful creation, the namespace exists in the subsystem, but is not + * attached to any controller. Use the nvme_ns_attach_ctrls() to assign the + * namespace to one or more controllers. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_ns_mgmt_create(int fd, struct nvme_id_ns *ns, __u32 *nsid, + __u32 timeout); + +/** + * nvme_ns_mgmt_delete() - + * @fd: File descriptor of nvme device + * @nsid: Namespace identifier to delete + * + * It is recommended that a namespace being deleted is not attached to any + * controller. Use the nvme_ns_detach_ctrls() first if the namespace is still + * attached. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_ns_mgmt_delete(int fd, __u32 nsid); + +/** + * nvme_ns_attach() - Attach or detach namespace to controller(s) + * @fd: File descriptor of nvme device + * @nsid: Namespace ID to execute attach selection + * @sel: Attachment selection, see &enum nvme_ns_attach_sel + * @ctrlist: Controller list to modify attachment state of nsid + */ +int nvme_ns_attach(int fd, __u32 nsid, enum nvme_ns_attach_sel sel, + struct nvme_ctrl_list *ctrlist); + +/** + * nvme_ns_attach_ctrls() - + * @fd: File descriptor of nvme device + * @nsid: Namespace ID to attach + * @ctrlist: Controller list to modify attachment state of nsid + */ +int nvme_ns_attach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist); + +/** + * nvme_ns_dettach_ctrls() - + * @fd: File descriptor of nvme device + * @nsid: Namespace ID to dettach + * @ctrlist: Controller list to modify attachment state of nsid + */ +int nvme_ns_dettach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist); + +/** + * nvme_fw_download() - Download part or all of a firmware image to the + * controller + * @fd: File descriptor of nvme device + * @offset: Offset in the firmware data + * @data_len: Length of data in this command in bytes + * @data: Userspace address of the firmware data + * + * The Firmware Image Download command is used to download all or a portion of + * an image for a future update to the controller. The Firmware Image Download + * command downloads a new image (in whole or in part) to the controller. + * + * The image may be constructed of multiple pieces that are individually + * downloaded with separate Firmware Image Download commands. Each Firmware + * Image Download command includes a Dword Offset and Number of Dwords that + * specify a dword range. + * + * The new firmware image is not activated as part of the Firmware Image + * Download command. Use the nvme_fw_commit() to activate a newly downloaded + * image. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_fw_download(int fd, __u32 offset, __u32 data_len, void *data); + +/** + * nvme_fw_commit() - Commit firmware using the specified action + * @fd: File descriptor of nvme device + * @slot: Firmware slot to commit the downloaded image + * @action: Action to use for the firmware image, see &enum nvme_fw_commit_ca + * @bpid: Set to true to select the boot partition id + * + * The Firmware Commit command is used to modify the firmware image or Boot + * Partitions. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. The command status response may specify additional + * reset actions required to complete the commit process. + */ +int nvme_fw_commit(int fd, __u8 slot, enum nvme_fw_commit_ca action, bool bpid); + +/** + * nvme_security_receive() - + * @fd: File descriptor of nvme device + * @nsid: Namespace ID to issue security command on + * @nssf: NVMe Security Specific field + * @spsp0: Security Protocol Specific field + * @spsp1: Security Protocol Specific field + * @secp: Security Protocol + * @tl: Protocol specific transfer length + * @data_len: Data length of the payload in bytes + * @data: Security data payload to send + * @result: The command completion result from CQE dword0 + * + * The Security Send command is used to transfer security protocol data to the + * controller. The data structure transferred to the controller as part of this + * command contains security protocol specific commands to be performed by the + * controller. The data structure transferred may also contain data or + * parameters associated with the security protocol commands. + * + * The security data is protocol specific and is not defined by the NVMe + * specification. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_security_send(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, + __u8 secp, __u32 tl, __u32 data_len, void *data, + __u32 *result); + +/** + * nvme_security_receive() - + * @fd: File descriptor of nvme device + * @nsid: Namespace ID to issue security command on + * @nssf: NVMe Security Specific field + * @spsp0: Security Protocol Specific field + * @spsp1: Security Protocol Specific field + * @secp: Security Protocol + * @al: Protocol specific allocation length + * @data_len: Data length of the payload in bytes + * @data: Security data payload to send + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_security_receive(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, + __u8 spsp1, __u8 secp, __u32 al, __u32 data_len, + void *data, __u32 *result); + +/** + * nvme_get_lba_status() - Retrieve information on possibly unrecoverable LBAs + * @fd: File descriptor of nvme device + * @nsid: Namespace ID to retrieve LBA status + * @slba: Starting logical block address to check statuses + * @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 + * @lbas: Data payload to return status descriptors + * + * The Get LBA Status command requests information about Potentially + * Unrecoverable LBAs. Refer to the specification for action type descriptions. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_lba_status(int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl, + enum nvme_lba_status_atype atype, + struct nvme_lba_status *lbas); + +/** + * nvme_directive_send() - Send directive command + * @fd: File descriptor of nvme device + * @nsid: Namespace ID, if applicable + * @dspec: Directive specific field + * @doper: Directive operation + * @dtype: Directive type, see &enum nvme_directive_dtype + * @dw12: Directive specific command dword12 + * @data_len: Length of data payload in bytes + * @data: Usespace address of data payload + * @result: If successful, the CQE dword0 value + * + * Directives is a mechanism to enable host and NVM subsystem or controller + * information exchange. The Directive Send command is used to transfer data + * related to a specific Directive Type from the host to the controller. + * + * See the NVMe specification for more information. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_directive_send(int fd, __u32 nsid, __u16 dspec, __u8 doper, + enum nvme_directive_dtype dtype, __u32 cdw12, + __u32 data_len, void *data, __u32 *result); + +/** + * nvme_directive_send_id_endir() - + * @fd: File descriptor of nvme device + * @nsid: Namespace ID + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_directive_send_id_endir(int fd, __u32 nsid, bool endir, + enum nvme_directive_dtype dtype, + struct nvme_id_directives *id); + +/** + * nvme_directive_send_stream_release_identifier() - + * @fd: File descriptor of nvme device + * @nsid: Namespace ID + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_directive_send_stream_release_identifier(int fd, __u32 nsid, + __u16 stream_id); + +/** + * nvme_directive_send_stream_release_resource() - + * @fd: File descriptor of nvme device + * @nsid: Namespace ID + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_directive_send_stream_release_resource(int fd, __u32 nsid); + +/** + * nvme_directive_recv() - Receive directive specific data + * @fd: File descriptor of nvme device + * @nsid: Namespace ID, if applicable + * @dspec: Directive specific field + * @doper: Directive operation + * @dtype: Directive type, see &enum nvme_directive_dtype + * @dw12: Directive specific command dword12 + * @data_len: Length of data payload + * @data: Usespace address of data payload in bytes + * @result: If successful, the CQE dword0 value + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_directive_recv(int fd, __u32 nsid, __u16 dspec, __u8 doper, + enum nvme_directive_dtype dtype, __u32 cdw12, + __u32 data_len, void *data, __u32 *result); + +/** + * nvme_directive_recv_identify_parameters() - + * @fd: File descriptor of nvme device + * @nsid: Namespace ID + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_directive_recv_identify_parameters(int fd, __u32 nsid, + struct nvme_id_directives *id); + +/** + * nvme_directive_recv_stream_parameters() - + * @fd: File descriptor of nvme device + * @nsid: Namespace ID + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_directive_recv_stream_parameters(int fd, __u32 nsid, + struct nvme_streams_directive_params *parms); + +/** + * nvme_directive_recv_stream_status() - + * @fd: File descriptor of nvme device + * @nsid: Namespace ID + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_directive_recv_stream_status(int fd, __u32 nsid, unsigned nr_entries, + struct nvme_streams_directive_status *id); + +/** + * nvme_directive_recv_stream_allocate() - + * @fd: File descriptor of nvme device + * @nsid: Namespace ID + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_directive_recv_stream_allocate(int fd, __u32 nsid, __u16 nsr, + __u32 *result); + +/** + * enum nvme_fctype - + * @nvme_fabrics_type_property_set: + * @nvme_fabrics_type_connect: + * @nvme_fabrics_type_property_get: + * @nvme_fabrics_type_auth_send: + * @nvme_fabrics_type_auth_receive: + * @nvme_fabrics_type_disconnect: + */ +enum nvme_fctype { + nvme_fabrics_type_property_set = 0x00, + nvme_fabrics_type_connect = 0x01, + nvme_fabrics_type_property_get = 0x04, + nvme_fabrics_type_auth_send = 0x05, + nvme_fabrics_type_auth_receive = 0x06, + nvme_fabrics_type_disconnect = 0x08, +}; + +/** + * nvme_set_property() - Set controller property + * @fd: File descriptor of nvme device + * @offset: Property offset from the base to set + * @value: The value to set the property + * + * This is an NVMe-over-Fabrics specific command, not applicable to PCIe. These + * properties align to the PCI MMIO controller registers. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_set_property(int fd, int offset, __u64 value); + +/** + * nvme_get_property() - Get a controller property + * @fd: File descriptor of nvme device + * @offset: Property offset from the base to retrieve + * @value: Where the property's value will be stored on success + * + * This is an NVMe-over-Fabrics specific command, not applicable to PCIe. These + * properties align to the PCI MMIO controller registers. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_property(int fd, int offset, __u64 *value); + +/** + * nvme_sanitize() - Start a sanitize operation + * @fd: File descriptor of nvme device + * @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 + * @ovrpat: Overwrite pattern + * + * A sanitize operation alters all user data in the NVM subsystem such that + * recovery of any previous user data from any cache, the non-volatile media, + * or any Controller Memory Buffer is not possible. + * + * The Sanitize command is used to start a sanitize operation or to recover + * from a previously failed sanitize operation. The sanitize operation types + * that may be supported are Block Erase, Crypto Erase, and Overwrite. All + * sanitize operations are processed in the background, i.e., completion of the + * sanitize command does not indicate completion of the sanitize operation. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_sanitize_nvm(int fd, enum nvme_sanitize_sanact sanact, bool ause, + __u8 owpass, bool oipbp, bool nodas, __u32 ovrpat); + +/** + * nvme_dev_self_test() - Start or abort a self test + * @fd: File descriptor of nvme device + * @nsid: Namespace ID to test + * @stc: Self test code, see &enum nvme_dst_stc + * + * The Device Self-test command is used to start a device self-test operation + * or abort a device self-test operation. A device self-test operation is a + * diagnostic testing sequence that tests the integrity and functionality of + * the controller and may include testing of the media associated with + * namespaces. The controller may return a response to this command immediately + * while running the self-test in the background. + * + * Set the 'nsid' field to 0 to not include namepsaces in the test. Set to + * 0xffffffff to test all namespaces. All other values tests a specific + * namespace, if present. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_dev_self_test(int fd, __u32 nsid, enum nvme_dst_stc stc); + +/** + * nvme_virtual_mgmt() - Virtualization resource management + * @fd: File descriptor of nvme device + * @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 + * @result: If successful, the CQE dword0 + * + * The Virtualization Management command is supported by primary controllers + * that support the Virtualization Enhancements capability. This command is + * used for several functions: + * + * - Modifying Flexible Resource allocation for the primary controller + * - Assigning Flexible Resources for secondary controllers + * - Setting the Online and Offline state for secondary controllers + * + * Return: The nvme command status if a response was received or -1 + * with errno set otherwise. + */ +int nvme_virtual_mgmt(int fd, enum nvme_virt_mgmt_act act, + enum nvme_virt_mgmt_rt rt, __u16 cntlid, __u16 nr, + __u32 *result); + +/** + * DOC: NVMe IO command enums + */ + +/** + * enum nvme_io_opcode - + * @nvme_cmd_flush: + * @nvme_cmd_write: + * @nvme_cmd_read: + * @nvme_cmd_write_uncor: + * @nvme_cmd_compare: + * @nvme_cmd_write_zeroes: + * @nvme_cmd_dsm: + * @nvme_cmd_verify: + * @nvme_cmd_resv_register: + * @nvme_cmd_resv_report: + * @nvme_cmd_resv_acquire: + * @nvme_cmd_resv_release: + */ +enum nvme_io_opcode { + nvme_cmd_flush = 0x00, + nvme_cmd_write = 0x01, + nvme_cmd_read = 0x02, + nvme_cmd_write_uncor = 0x04, + nvme_cmd_compare = 0x05, + nvme_cmd_write_zeroes = 0x08, + nvme_cmd_dsm = 0x09, + nvme_cmd_verify = 0x0c, + nvme_cmd_resv_register = 0x0d, + nvme_cmd_resv_report = 0x0e, + nvme_cmd_resv_acquire = 0x11, + nvme_cmd_resv_release = 0x15, +}; + +/** + * nvme_flush() - Send an nvme flush command + * @fd: File descriptor of nvme device + * @nsid: Namespace identifier + * + * The Flush command is used to request that the contents of volatile write + * cache be made non-volatile. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_flush(int fd, __u32 nsid); + +/** + * enum nvme_io_control_flags - + * @NVME_IO_DTYPE_STREAMS: + * @NVME_IO_DEAC: + * @NVME_IO_PRINFO_PRCHK_REF: + * @NVME_IO_PRINFO_PRCHK_APP: + * @NVME_IO_PRINFO_PRCHK_GUARD: + * @NVME_IO_PRINFO_PRACT: + * @NVME_IO_FUA: + * @NVME_IO_LR: + */ +enum nvme_io_control_flags { + NVME_IO_DTYPE_STREAMS = 1 << 4, + NVME_IO_DEAC = 1 << 9, + NVME_IO_PRINFO_PRCHK_REF = 1 << 10, + NVME_IO_PRINFO_PRCHK_APP = 1 << 11, + NVME_IO_PRINFO_PRCHK_GUARD = 1 << 12, + NVME_IO_PRINFO_PRACT = 1 << 13, + NVME_IO_FUA = 1 << 14, + NVME_IO_LR = 1 << 15, +}; + +/** + * enum nvme_io_dsm_flag - + * @NVME_IO_DSM_FREQ_UNSPEC: + * @NVME_IO_DSM_FREQ_TYPICAL: + * @NVME_IO_DSM_FREQ_RARE: + * @NVME_IO_DSM_FREQ_READS: + * @NVME_IO_DSM_FREQ_WRITES: + * @NVME_IO_DSM_FREQ_RW: + * @NVME_IO_DSM_FREQ_ONCE: + * @NVME_IO_DSM_FREQ_PREFETCH: + * @NVME_IO_DSM_FREQ_TEMP: + * @NVME_IO_DSM_LATENCY_NONE: + * @NVME_IO_DSM_LATENCY_IDLE: + * @NVME_IO_DSM_LATENCY_NORM: + * @NVME_IO_DSM_LATENCY_LOW: + * @NVME_IO_DSM_SEQ_REQ: + * @NVME_IO_DSM_COMPRESSED: + */ +enum nvme_io_dsm_flags { + NVME_IO_DSM_FREQ_UNSPEC = 0, + NVME_IO_DSM_FREQ_TYPICAL = 1, + NVME_IO_DSM_FREQ_RARE = 2, + NVME_IO_DSM_FREQ_READS = 3, + NVME_IO_DSM_FREQ_WRITES = 4, + NVME_IO_DSM_FREQ_RW = 5, + NVME_IO_DSM_FREQ_ONCE = 6, + NVME_IO_DSM_FREQ_PREFETCH = 7, + NVME_IO_DSM_FREQ_TEMP = 8, + NVME_IO_DSM_LATENCY_NONE = 0 << 4, + NVME_IO_DSM_LATENCY_IDLE = 1 << 4, + NVME_IO_DSM_LATENCY_NORM = 2 << 4, + NVME_IO_DSM_LATENCY_LOW = 3 << 4, + NVME_IO_DSM_SEQ_REQ = 1 << 6, + NVME_IO_DSM_COMPRESSED = 1 << 7, +}; + +/** + * nvme_read() - Submit an nvme user read command + * @fd: File descriptor of nvme device + * @nsid: + * @slba: Starting logical block + * @nblocks: Number of logical blocks to send (0's based value) + * @control: Command control flags, see &enum nvme_io_control_flags. + * @dsm: Data set management attributes, see &enum nvme_io_dsm_flags + * @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. + * @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. + * @data_len: Length of user buffer, @data, in bytes + * @data: Pointer to user address of the data buffer + * metadata_len:Length of user buffer, @metadata, in bytes + * @metadata: Pointer to user address of the metadata buffer + * + * Calls nvme_io() with nvme_cmd_read for the opcode. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_read(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, + __u8 dsm, __u32 reftag, __u16 apptag, __u16 appmask, + __u32 data_len, void *data, __u32 metadata_len, void *metadata); + +/** + * nvme_write() - Submit an nvme user write command + * @fd: File descriptor of nvme device + * @nsid: + * @slba: Starting logical block + * @nblocks: Number of logical blocks to send (0's based value) + * @control: Command control flags, see &enum nvme_io_control_flags. + * @dsm: Data set management attributes, see &enum nvme_io_dsm_flags + * @dspec: Directive specific command, eg: stream identifier + * @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. + * @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. + * @data_len: Length of user buffer, @data, in bytes + * @data: Pointer to user address of the data buffer + * metadata_len:Length of user buffer, @metadata, in bytes + * @metadata: Pointer to user address of the metadata buffer + * + * Calls nvme_io() with nvme_cmd_write for the opcode. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_write(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, + __u8 dsm, __u16 dspec, __u32 reftag, __u16 apptag, + __u16 appmask, __u32 data_len, void *data, __u32 metadata_len, + void *metadata); + +/** + * nvme_compare() - Submit an nvme user compare command + * @fd: File descriptor of nvme device + * @nsid: + * @slba: Starting logical block + * @nblocks: Number of logical blocks to send (0's based value) + * @control: Command control flags, see &enum nvme_io_control_flags. + * @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. + * @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. + * @data_len: Length of user buffer, @data, in bytes + * @data: Pointer to user address of the data buffer + * metadata_len:Length of user buffer, @metadata, in bytes + * @metadata: Pointer to user address of the metadata buffer + * + * Calls nvme_io() with nvme_cmd_compare for the opcode. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_compare(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, + __u32 reftag, __u16 apptag, __u16 appmask, __u32 data_len, + void *data, __u32 metadata_len, void *metadata); + +/** + * nvme_write_zeros() - Submit an nvme write zeroes command + * @fd: File descriptor of nvme device + * @nsid: Namespace identifier + * @slba: Starting logical block + * @nlb: Number of logical blocks to clear (0's based value) + * @control: Command control flags, see &enum nvme_io_control_flags. + * @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. + * @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. + * + * The Write Zeroes command is used to set a range of logical blocks to zero. + * After successful completion of this command, the value returned by + * subsequent reads of logical blocks in this range shall be all bytes cleared + * to 0h until a write occurs to this LBA range. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_write_zeros(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, + __u32 reftag, __u16 apptag, __u16 appmask); + +/** + * nvme_write_uncorrectable() - Submit an nvme write uncorrectable command + * @fd: File descriptor of nvme device + * @nsid: Namespace identifier + * @slba: Starting logical block + * @nlb: Number of logical blocks to invalidate (0's based value) + * + * The Write Uncorrectable command is used to mark a range of logical blocks as + * invalid. When the specified logical block(s) are read after this operation, + * a failure is returned with Unrecovered Read Error status. To clear the + * invalid logical block status, a write operation on those logical blocks is + * required. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_write_uncorrectable(int fd, __u32 nsid, __u64 slba, __u16 nlb); + +/** + * nvme_verify() - Send an nvme verify command + * @fd: File descriptor of nvme device + * @nsid: Namespace identifier + * @slba: Starting logical block + * @nlb: Number of logical blocks to verify (0's based value) + * @control: Command control flags, see &enum nvme_io_control_flags. + * @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. + * @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. + * + * The Verify command verifies integrity of stored information by reading data + * and metadata, if applicable, for the LBAs indicated without transferring any + * data or metadata to the host. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_verify(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, + __u32 reftag, __u16 apptag, __u16 appmask); + +/** + * enum nvme_dsm_attributes - + * @NVME_DSMGMT_IDR: + * @NVME_DSMGMT_IDW: + * @NVME_DSMGMT_AD: + */ +enum nvme_dsm_attributes { + NVME_DSMGMT_IDR = 1 << 0, + NVME_DSMGMT_IDW = 1 << 1, + NVME_DSMGMT_AD = 1 << 2, +}; + +/** + * nvme_dsm() - Send an nvme data set management command + * @fd: File descriptor of nvme device + * @nsid: Namespace identifier + * @attrs: DSM attributes, see &enum nvme_dsm_attributes + * &nr_ranges: Number of block ranges in the data set management attributes + * @dsm: The data set management attributes + * + * The Dataset Management command is used by the host to indicate attributes + * for ranges of logical blocks. This includes attributes like frequency that + * data is read or written, access size, and other information that may be used + * to optimize performance and reliability, and may be used to + * deallocate/unmap/trim those logical blocks. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_dsm(int fd, __u32 nsid, __u32 attrs, __u16 nr_ranges, + struct nvme_dsm_range *dsm); + +/** + * enum nvme_reservation_rtype - + * @NVME_RESERVATION_RTYPE_WE: + * @NVME_RESERVATION_RTYPE_EA: + * @NVME_RESERVATION_RTYPE_WERO: + * @NVME_RESERVATION_RTYPE_EARO: + * @NVME_RESERVATION_RTYPE_WEAR: + * @NVME_RESERVATION_RTYPE_EAAR: + */ +enum nvme_reservation_rtype { + NVME_RESERVATION_RTYPE_WE = 1, + NVME_RESERVATION_RTYPE_EA = 2, + NVME_RESERVATION_RTYPE_WERO = 3, + NVME_RESERVATION_RTYPE_EARO = 4, + NVME_RESERVATION_RTYPE_WEAR = 5, + NVME_RESERVATION_RTYPE_EAAR = 6, +}; + +/** + * enum nvme_reservation_racqa - + * @NVME_RESERVATION_RACQA_ACQUIRE: + * @NVME_RESERVATION_RACQA_PREEMPT: + * @NVME_RESERVATION_RACQA_PREEMPT_AND_ABORT: + */ +enum nvme_reservation_racqa { + NVME_RESERVATION_RACQA_ACQUIRE = 0, + NVME_RESERVATION_RACQA_PREEMPT = 1, + NVME_RESERVATION_RACQA_PREEMPT_AND_ABORT = 2, +}; + +/** + * nvme_resv_acquire() - Send an nvme reservation acquire + * @fd: File descriptor of nvme device + * @nsid: Namespace identifier + * @rtype: The type of reservation to be create, see &enum nvme_reservation_rtype + * @racqa: The action that is performed by the command, see &enum nvme_reservation_racqa + * @iekey: Set to ignore the existing key + * @crkey: The current reservation key associated with the host + * @nrkey: The reservation key to be unregistered from the namespace if + * the action is preempt + * + * The Reservation Acquire command is used to acquire a reservation on a + * namespace, preempt a reservation held on a namespace, and abort a + * reservation held on a namespace. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_resv_acquire(int fd, __u32 nsid, enum nvme_reservation_rtype rtype, + enum nvme_reservation_racqa racqa, bool iekey, + __u64 crkey, __u64 nrkey); + +/** + * enum nvme_reservation_rrega - + * @NVME_RESERVATION_RREGA_REGISTER_KEY: + * @NVME_RESERVATION_RREGA_UNREGISTER_KEY: + * @NVME_RESERVATION_RREGA_REPLACE_KEY: + */ +enum nvme_reservation_rrega { + NVME_RESERVATION_RREGA_REGISTER_KEY = 0, + NVME_RESERVATION_RREGA_UNREGISTER_KEY = 1, + NVME_RESERVATION_RREGA_REPLACE_KEY = 2, +}; + +/** + * enum nvme_reservation_cptpl - + * @NVME_RESERVATION_CPTPL_NO_CHANGE: + * @NVME_RESERVATION_CPTPL_CLEAR: + * @NVME_RESERVATION_CPTPL_PERSIST: + */ +enum nvme_reservation_cptpl { + NVME_RESERVATION_CPTPL_NO_CHANGE = 0, + NVME_RESERVATION_CPTPL_CLEAR = 2, + NVME_RESERVATION_CPTPL_PERSIST = 3, +}; + +/** + * nvme_resv_register() - Send an nvme reservation register + * @fd: File descriptor of nvme device + * @nsid: Namespace identifier + * @rrega: The registration action, see &enum nvme_reservation_rrega + * @cptpl: Change persist through power loss, see &enum nvme_reservation_cptpl + * @iekey: Set to ignore the existing key + * @crkey: The current reservation key associated with the host + * @nrkey: The new reservation key to be register if action is register or + * replace + * + * The Reservation Register command is used to register, unregister, or replace + * a reservation key. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_resv_register(int fd, __u32 nsid, enum nvme_reservation_rrega rrega, + enum nvme_reservation_cptpl cptpl, bool iekey, + __u64 crkey, __u64 nrkey); + +/** + * enum nvme_reservation_rrela - + * @NVME_RESERVATION_RRELA_RELEASE: + * @NVME_RESERVATION_RRELA_CLEAR: + */ +enum nvme_reservation_rrela { + NVME_RESERVATION_RRELA_RELEASE = 0, + NVME_RESERVATION_RRELA_CLEAR = 1 +}; + +/** + * nvme_resv_release() - Send an nvme reservation release + * @fd: File descriptor of nvme device + * @nsid: Namespace identifier + * @rtype: The type of reservation to be create, see &enum nvme_reservation_rtype + * @rrela: Reservation releast action, see &enum nvme_reservation_rrela + * @iekey: Set to ignore the existing key + * @crkey: The current reservation key to release + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_resv_release(int fd, __u32 nsid, enum nvme_reservation_rtype rtype, + enum nvme_reservation_rrela rrela, bool iekey, + __u64 crkey); + +/** + * nvme_resv_report() - Send an nvme reservation report + * @fd: File descriptor of nvme device + * @nsid: Namespace identifier + * @eds: Request extended Data Structure + * @len: Number of bytes to request transfered with this command + * @report: The user space destination address to store the reservation report + * + * Returns a Reservation Status data structure to memory that describes the + * registration and reservation status of a namespace. See the defintion for + * the returned structure, &struct nvme_reservation_status, for more details. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_resv_report(int fd, __u32 nsid, bool eds, __u32 len, + struct nvme_reservation_status *report); + +#endif /* _LIBNVME_CMD_H */ diff --git a/lib/nvme/fabrics.c b/lib/nvme/fabrics.c new file mode 100644 index 0000000000..c1119df050 --- /dev/null +++ b/lib/nvme/fabrics.c @@ -0,0 +1,363 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "fabrics.h" +#include "types.h" +#include "cmd.h" +#include "util.h" + +#define NVMF_HOSTID_SIZE 36 +#define NVME_HOSTNQN_ID SD_ID128_MAKE(c7,f4,61,81,12,be,49,32,8c,83,10,6f,9d,dd,d8,6b) +#define ARRAY_SIZE(x) (sizeof(x) / sizeof (*x)) + +const char *nvmf_dev = "/dev/nvme-fabrics"; +const char *nvmf_hostnqn_file = "/etc/nvme/hostnqn"; +const char *nvmf_hostid_file = "/etc/nvme/hostid"; + +static int add_bool_argument(char **argstr, char *tok, bool arg) +{ + char *nstr; + + if (arg) { + if (asprintf(&nstr, "%s,%s", *argstr, tok) < 0) { + errno = ENOMEM; + return -1; + } + free(*argstr); + *argstr = nstr; + } + return 0; +} + +static int add_int_argument(char **argstr, char *tok, int arg, + bool allow_zero) +{ + char *nstr; + + if ((arg && !allow_zero) || (arg != -1 && allow_zero)) { + if (asprintf(&nstr, "%s,%s=%d", *argstr, tok, arg) < 0) { + errno = ENOMEM; + return -1; + } + free(*argstr); + *argstr = nstr; + } + return 0; +} + +static int add_argument(char **argstr, const char *tok, const char *arg) +{ + char *nstr; + + if (arg && strcmp(arg, "none")) { + if (asprintf(&nstr, "%s,%s=%s", *argstr, tok, arg) < 0) { + errno = ENOMEM; + return -1; + } + free(*argstr); + *argstr = nstr; + } + return 0; +} + +static int build_options(char **argstr, struct nvme_fabrics_config *cfg) +{ + /* always specify nqn as first arg - this will init the string */ + if (asprintf(argstr, "nqn=%s", cfg->nqn) < 0) { + errno = ENOMEM; + return -1; + } + + + if (add_argument(argstr, "transport", cfg->transport) || + add_argument(argstr, "traddr", cfg->traddr) || + add_argument(argstr, "host_traddr", cfg->host_traddr) || + add_argument(argstr, "trsvcid", cfg->trsvcid) || + add_argument(argstr, "hostnqn", cfg->hostnqn) || + add_argument(argstr, "hostid", cfg->hostid) || + add_int_argument(argstr, "nr_write_queues", cfg->nr_write_queues, false) || + add_int_argument(argstr, "nr_poll_queues", cfg->nr_poll_queues, false) || + add_int_argument(argstr, "reconnect_delay", cfg->reconnect_delay, false) || + add_int_argument(argstr, "ctrl_loss_tmo", cfg->ctrl_loss_tmo, false) || + add_int_argument(argstr, "tos", cfg->tos, true) || + add_bool_argument(argstr, "duplicate_connect", cfg->duplicate_connect) || + add_bool_argument(argstr, "disable_sqflow", cfg->disable_sqflow) || + add_bool_argument(argstr, "hdr_digest", cfg->hdr_digest) || + add_bool_argument(argstr, "data_digest", cfg->data_digest) || + add_int_argument(argstr, "queue_size", cfg->queue_size, false) || + add_int_argument(argstr, "keep_alive_tmo", cfg->keep_alive_tmo, false) || + add_int_argument(argstr, "nr_io_queues", cfg->nr_io_queues, false)) { + free(*argstr); + return -1; + } + + return 0; +} +static int __nvmf_add_ctrl(const char *argstr) +{ + int ret, fd, len = strlen(argstr); + char buf[0x1000], *options, *p; + + fd = open(nvmf_dev, O_RDWR); + if (fd < 0) + return -1; + + ret = write(fd, argstr, len); + if (ret != len) { + ret = -1; + goto out_close; + } + + len = read(fd, buf, sizeof(buf)); + if (len < 0) { + ret = -1; + goto out_close; + } + + buf[len] = '\0'; + options = buf; + while ((p = strsep(&options, ",\n")) != NULL) { + if (!*p) + continue; + if (sscanf(p, "instance=%d", &ret) == 1) + goto out_close; + } + + errno = EINVAL; + ret = -1; +out_close: + close(fd); + return ret; +} + +int nvmf_add_ctrl_opts(struct nvme_fabrics_config *cfg) +{ + char *argstr; + int ret; + + ret = build_options(&argstr, cfg); + if (ret) + return ret; + + ret = __nvmf_add_ctrl(argstr); + printf("ctrl:%s ret:%d\n", argstr, ret); + + free(argstr); + return ret; +} + +nvme_ctrl_t nvmf_add_ctrl(struct nvme_fabrics_config *cfg) +{ + char d[32]; + int ret; + + ret = nvmf_add_ctrl_opts(cfg); + if (ret < 0) + return NULL; + + memset(d, 0, sizeof(d)); + if (snprintf(d, sizeof(d), "nvme%d", ret) < 0) + return NULL; + + return nvme_scan_ctrl(d); +} + +static void chomp(char *s, int l) +{ + while (l && (s[l] == '\0' || s[l] == ' ')) + s[l--] = '\0'; +} + +nvme_ctrl_t nvmf_connect_disc_entry(struct nvmf_disc_log_entry *e, + const struct nvme_fabrics_config *defcfg, bool *discover) +{ + struct nvme_fabrics_config cfg = { 0 }; + nvme_ctrl_t c; + + memcpy(&cfg, defcfg, sizeof(cfg)); + switch (e->subtype) { + case NVME_NQN_DISC: + if (discover) + *discover = true; + break; + case NVME_NQN_NVME: + break; + default: + errno = EINVAL; + return NULL; + } + + switch (e->trtype) { + case NVMF_TRTYPE_RDMA: + case NVMF_TRTYPE_TCP: + switch (e->adrfam) { + case NVMF_ADDR_FAMILY_IP4: + case NVMF_ADDR_FAMILY_IP6: + chomp(e->traddr, NVMF_TRADDR_SIZE); + chomp(e->trsvcid, NVMF_TRSVCID_SIZE); + cfg.traddr = e->traddr; + cfg.trsvcid = e->trsvcid; + break; + default: + errno = EINVAL; + return NULL; + } + break; + case NVMF_TRTYPE_FC: + switch (e->adrfam) { + case NVMF_ADDR_FAMILY_FC: + chomp(e->traddr, NVMF_TRADDR_SIZE), + cfg.traddr = e->traddr; + cfg.trsvcid = NULL; + break; + } + default: + errno = EINVAL; + return NULL; + } + cfg.transport = nvmf_trtype_str(e->trtype); + + cfg.nqn = e->subnqn; + if (e->treq & NVMF_TREQ_DISABLE_SQFLOW) + cfg.disable_sqflow = true; + + c = nvmf_add_ctrl(&cfg); + if (!c && errno == EINVAL && cfg.disable_sqflow) { + errno = 0; + /* disable_sqflow is unrecognized option on older kernels */ + cfg.disable_sqflow = false; + c = nvmf_add_ctrl(&cfg); + } + + return c; +} + +static int nvme_discovery_log(int fd, __u32 len, struct nvmf_discovery_log *log) +{ + return nvme_get_log_page(fd, 0, NVME_LOG_LID_DISC, true, len, log); +} + +int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, + int max_retries) +{ + struct nvmf_discovery_log *log; + int hdr, ret, retries = 0; + uint64_t genctr, numrec; + unsigned int size; + + hdr = sizeof(struct nvmf_discovery_log); + log = malloc(hdr); + if (!log) { + errno = ENOMEM; + return -1; + } + memset(log, 0, hdr); + + ret = nvme_discovery_log(nvme_ctrl_get_fd(c), 0x100, log); + if (ret) + goto out_free_log; + + do { + numrec = le64_to_cpu(log->numrec); + genctr = le64_to_cpu(log->genctr); + + free(log); + if (numrec == 0) { + *logp = log; + return 0; + } + + size = sizeof(struct nvmf_discovery_log) + + sizeof(struct nvmf_disc_log_entry) * (numrec); + + log = malloc(size); + if (!log) { + errno = ENOMEM; + return -1; + } + memset(log, 0, size); + + ret = nvme_discovery_log(nvme_ctrl_get_fd(c), size, log); + if (ret) + goto out_free_log; + + genctr = le64_to_cpu(log->genctr); + ret = nvme_discovery_log(nvme_ctrl_get_fd(c), hdr, log); + if (ret) + goto out_free_log; + } while (genctr != le64_to_cpu(log->genctr) && + ++retries < max_retries); + + if (genctr != le64_to_cpu(log->genctr)) { + errno = EAGAIN; + ret = -1; + } else if (numrec != le64_to_cpu(log->numrec)) { + errno = EBADSLT; + ret = -1; + } else { + *logp = log; + return 0; + } + +out_free_log: + free(log); + return ret; +} + +char *nvmf_hostnqn_generate() +{ + sd_id128_t id; + char *ret = NULL; + + if (sd_id128_get_machine_app_specific(NVME_HOSTNQN_ID, &id) < 0) + return NULL; + + if (asprintf(&ret, + "nqn.2014-08.org.nvmexpress:uuid:" SD_ID128_FORMAT_STR "\n", + SD_ID128_FORMAT_VAL(id)) < 0) + ret = NULL; + + return ret; +} + +static char *nvmf_read_file(const char *f, int len) +{ + char buf[len]; + int ret, fd; + + fd = open(f, O_RDONLY); + if (fd < 0) + return false; + + memset(buf, 0, len); + ret = read(fd, buf, sizeof(buf - 1)); + close (fd); + + if (ret < 0) + return NULL; + return strndup(buf, strcspn(buf, "\n")); +} + +char *nvmf_hostnqn_from_file() +{ + return nvmf_read_file(nvmf_hostnqn_file, NVMF_NQN_SIZE); +} + +char *nvmf_hostid_from_file() +{ + return nvmf_read_file(nvmf_hostid_file, NVMF_HOSTID_SIZE); +} diff --git a/lib/nvme/fabrics.h b/lib/nvme/fabrics.h new file mode 100644 index 0000000000..0f5e82ec33 --- /dev/null +++ b/lib/nvme/fabrics.h @@ -0,0 +1,54 @@ +#ifndef _LIBNVME_FABRICS_H +#define _LIBNVME_FABRICS_H + +#include +#include + +#include "tree.h" + +struct nvme_fabrics_config { + const char *transport; + const char *traddr; + const char *trsvcid; + const char *nqn; + const char *hostnqn; + const char *host_traddr; + const char *hostid; + + int queue_size; + int nr_io_queues; + int reconnect_delay; + int ctrl_loss_tmo; + int keep_alive_tmo; + int nr_write_queues; + int nr_poll_queues; + int tos; + + bool duplicate_connect; + bool disable_sqflow; + bool hdr_digest; + bool data_digest; + + uint8_t rsvd[0x200]; +}; + +int nvmf_add_ctrl_opts(struct nvme_fabrics_config *cfg); +nvme_ctrl_t nvmf_add_ctrl(struct nvme_fabrics_config *cfg); +int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, int max_retries); +char *nvmf_hostnqn_generate(); +char *nvmf_hostnqn_from_file(); +char *nvmf_hostid_from_file(); + + +const char *nvmf_trtype_str(__u8 trtype); +const char *nvmf_adrfam_str(__u8 adrfam); +const char *nvmf_subtype_str(__u8 subtype); +const char *nvmf_treq_str(__u8 treq); +const char *nvmf_sectype_str(__u8 sectype); +const char *nvmf_prtype_str(__u8 prtype); +const char *nvmf_qptype_str(__u8 qptype); +const char *nvmf_cms_str(__u8 cm); + +nvme_ctrl_t nvmf_connect_disc_entry(struct nvmf_disc_log_entry *e, + const struct nvme_fabrics_config *defcfg, bool *discover); +#endif /* _LIBNVME_FABRICS_H */ diff --git a/lib/nvme/filters.c b/lib/nvme/filters.c new file mode 100644 index 0000000000..ed0d402f50 --- /dev/null +++ b/lib/nvme/filters.c @@ -0,0 +1,107 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "filters.h" +#include "types.h" +#include "util.h" + +const char *nvme_ctrl_sysfs_dir = "/sys/class/nvme"; +const char *nvme_subsys_sysfs_dir = "/sys/class/nvme-subsystem"; + +int nvme_namespace_filter(const struct dirent *d) +{ + int i, n; + + if (d->d_name[0] == '.') + return 0; + + if (strstr(d->d_name, "nvme")) + if (sscanf(d->d_name, "nvme%dn%d", &i, &n) == 2) + return 1; + + return 0; +} + +int nvme_paths_filter(const struct dirent *d) +{ + int i, c, n; + + if (d->d_name[0] == '.') + return 0; + + if (strstr(d->d_name, "nvme")) + if (sscanf(d->d_name, "nvme%dc%dn%d", &i, &c, &n) == 3) + return 1; + + return 0; +} + +int nvme_ctrls_filter(const struct dirent *d) +{ + int i, c, n; + + if (d->d_name[0] == '.') + return 0; + + if (strstr(d->d_name, "nvme")) { + if (sscanf(d->d_name, "nvme%dc%dn%d", &i, &c, &n) == 3) + return 0; + if (sscanf(d->d_name, "nvme%dn%d", &i, &n) == 2) + return 0; + if (sscanf(d->d_name, "nvme%d", &i) == 1) + return 1; + } + + return 0; +} + +int nvme_subsys_filter(const struct dirent *d) +{ + int i; + + if (d->d_name[0] == '.') + return 0; + + if (strstr(d->d_name, "nvme-subsys")) + if (sscanf(d->d_name, "nvme-subsys%d", &i) == 1) + return 1; + + return 0; +} + +int nvme_scan_subsystems(struct dirent ***subsys) +{ + return scandir(nvme_subsys_sysfs_dir, subsys, nvme_subsys_filter, alphasort); +} + +int nvme_scan_subsystem_ctrls(nvme_subsystem_t s, struct dirent ***ctrls) +{ + return scandir(nvme_subsystem_get_sysfs_dir(s), ctrls, nvme_ctrls_filter, alphasort); +} + +int nvme_scan_subsystem_namespaces(nvme_subsystem_t s, struct dirent ***namespaces) +{ + return scandir(nvme_subsystem_get_sysfs_dir(s), namespaces, nvme_namespace_filter, alphasort); +} + +int nvme_scan_ctrl_namespace_paths(nvme_ctrl_t c, struct dirent ***namespaces) +{ + return scandir(nvme_ctrl_get_sysfs_dir(c), namespaces, nvme_paths_filter, alphasort); +} + +int nvme_scan_ctrl_namespaces(nvme_ctrl_t c, struct dirent ***namespaces) +{ + return scandir(nvme_ctrl_get_sysfs_dir(c), namespaces, nvme_namespace_filter, alphasort); +} diff --git a/lib/nvme/filters.h b/lib/nvme/filters.h new file mode 100644 index 0000000000..9021c1bc7c --- /dev/null +++ b/lib/nvme/filters.h @@ -0,0 +1,19 @@ +#ifndef _LIBNVME_FILTERS_H +#define _LIBNVME_FILTERS_H + +#include +#include "tree.h" + + +int nvme_namespace_filter(const struct dirent *d); +int nvme_paths_filter(const struct dirent *d); +int nvme_ctrls_filter(const struct dirent *d); +int nvme_subsys_filter(const struct dirent *d); + +int nvme_scan_subsystems(struct dirent ***subsys); +int nvme_scan_subsystem_ctrls(nvme_subsystem_t s, struct dirent ***ctrls); +int nvme_scan_subsystem_namespaces(nvme_subsystem_t s, struct dirent ***namespaces); +int nvme_scan_ctrl_namespace_paths(nvme_ctrl_t c, struct dirent ***namespaces); +int nvme_scan_ctrl_namespaces(nvme_ctrl_t c, struct dirent ***namespaces); + +#endif /* _LIBNVME_FILTERS_H */ diff --git a/lib/nvme/ioctl.c b/lib/nvme/ioctl.c new file mode 100644 index 0000000000..ca59e096bc --- /dev/null +++ b/lib/nvme/ioctl.c @@ -0,0 +1,1654 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "ioctl.h" +#include "cmd.h" +#include "types.h" + +static int nvme_verify_chr(int fd) +{ + static struct stat nvme_stat; + int err = fstat(fd, &nvme_stat); + + if (err < 0) { + perror("fstat"); + return errno; + } + if (!S_ISCHR(nvme_stat.st_mode)) { + errno = ENOTBLK; + return -1; + } + return 0; +} + +int nvme_subsystem_reset(int fd) +{ + int ret; + + ret = nvme_verify_chr(fd); + if (ret) + return ret; + return ioctl(fd, NVME_IOCTL_SUBSYS_RESET); +} + +int nvme_reset_controller(int fd) +{ + int ret; + + ret = nvme_verify_chr(fd); + if (ret) + return ret; + return ioctl(fd, NVME_IOCTL_RESET); +} + +int nvme_ns_rescan(int fd) +{ + int ret; + + ret = nvme_verify_chr(fd); + if (ret) + return ret; + return ioctl(fd, NVME_IOCTL_RESCAN); +} + +int nvme_get_nsid(int fd) +{ + static struct stat nvme_stat; + int err = fstat(fd, &nvme_stat); + + if (err < 0) + return -1; + + if (!S_ISBLK(nvme_stat.st_mode)) { + errno = ENOTBLK; + return -1; + } + return ioctl(fd, NVME_IOCTL_ID); +} + +static int nvme_submit_passthru64(int fd, unsigned long ioctl_cmd, + struct nvme_passthru_cmd64 *cmd, __u64 *result) +{ + int err = ioctl(fd, ioctl_cmd, cmd); + + if (err >= 0 && result) + *result = cmd->result; + return err; +} + +static int nvme_submit_passthru(int fd, unsigned long ioctl_cmd, + struct nvme_passthru_cmd *cmd, __u32 *result) +{ + int err = ioctl(fd, ioctl_cmd, cmd); + + if (err >= 0 && result) + *result = cmd->result; + return err; +} + +static int nvme_passthru64(int fd, unsigned long ioctl_cmd, __u8 opcode, + __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, + __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, + __u32 cdw14, __u32 cdw15, __u32 data_len, void *data, + __u32 metadata_len, void *metadata, __u32 timeout_ms, + __u64 *result) +{ + struct nvme_passthru_cmd64 cmd = { + .opcode = opcode, + .flags = flags, + .rsvd1 = rsvd, + .nsid = nsid, + .cdw2 = cdw2, + .cdw3 = cdw3, + .metadata = (__u64)(uintptr_t)metadata, + .addr = (__u64)(uintptr_t)data, + .metadata_len = metadata_len, + .data_len = data_len, + .cdw10 = cdw10, + .cdw11 = cdw11, + .cdw12 = cdw12, + .cdw13 = cdw13, + .cdw14 = cdw14, + .cdw15 = cdw15, + .timeout_ms = timeout_ms, + }; + + return nvme_submit_passthru64(fd, ioctl_cmd, &cmd, result); +} + +static int nvme_passthru(int fd, unsigned long ioctl_cmd, __u8 opcode, + __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, + __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, + __u32 cdw14, __u32 cdw15, __u32 data_len, void *data, + __u32 metadata_len, void *metadata, __u32 timeout_ms, + __u32 *result) +{ + struct nvme_passthru_cmd cmd = { + .opcode = opcode, + .flags = flags, + .rsvd1 = rsvd, + .nsid = nsid, + .cdw2 = cdw2, + .cdw3 = cdw3, + .metadata = (__u64)(uintptr_t)metadata, + .addr = (__u64)(uintptr_t)data, + .metadata_len = metadata_len, + .data_len = data_len, + .cdw10 = cdw10, + .cdw11 = cdw11, + .cdw12 = cdw12, + .cdw13 = cdw13, + .cdw14 = cdw14, + .cdw15 = cdw15, + .timeout_ms = timeout_ms, + }; + + return nvme_submit_passthru(fd, ioctl_cmd, &cmd, result); +} + +int nvme_submit_admin_passthru64(int fd, struct nvme_passthru_cmd64 *cmd, + __u64 *result) +{ + return nvme_submit_passthru64(fd, NVME_IOCTL_ADMIN64_CMD, cmd, result); +} + +int nvme_admin_passthru64(int fd, __u8 opcode, __u8 flags, __u16 rsvd, + __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, + __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, + __u32 data_len, void *data, __u32 metadata_len, void *metadata, + __u32 timeout_ms, __u64 *result) +{ + return nvme_passthru64(fd, NVME_IOCTL_ADMIN64_CMD, opcode, flags, rsvd, + nsid, cdw2, cdw3, cdw10, cdw11, cdw12, cdw13, cdw14, cdw15, + data_len, data, metadata_len, metadata, timeout_ms, result); +} + +int nvme_submit_admin_passthru(int fd, struct nvme_passthru_cmd *cmd, __u32 *result) +{ + return nvme_submit_passthru(fd, NVME_IOCTL_ADMIN_CMD, cmd, result); +} + +int nvme_admin_passthru(int fd, __u8 opcode, __u8 flags, __u16 rsvd, + __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, + __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, + __u32 data_len, void *data, __u32 metadata_len, void *metadata, + __u32 timeout_ms, __u32 *result) +{ + return nvme_passthru(fd, NVME_IOCTL_ADMIN_CMD, opcode, flags, rsvd, nsid, + cdw2, cdw3, cdw10, cdw11, cdw12, cdw13, cdw14, cdw15, data_len, + data, metadata_len, metadata, timeout_ms, result); +} + +enum nvme_cmd_dword_fields { + NVME_DEVICE_SELF_TEST_CDW10_STC_SHIFT = 0, + NVME_DEVICE_SELF_TEST_CDW10_STC_MASK = 0x7, + NVME_DIRECTIVE_CDW11_DOPER_SHIFT = 0, + NVME_DIRECTIVE_CDW11_DTYPE_SHIFT = 8, + NVME_DIRECTIVE_CDW11_DPSEC_SHIFT = 16, + NVME_DIRECTIVE_CDW11_DOPER_MASK = 0xff, + NVME_DIRECTIVE_CDW11_DTYPE_MASK = 0xff, + NVME_DIRECTIVE_CDW11_DPSEC_MASK = 0xffff, + NVME_DIRECTIVE_SEND_IDENTIFY_CDW12_ENDIR_SHIFT = 0, + NVME_DIRECTIVE_SEND_IDENTIFY_CDW12_DTYPE_SHIFT = 1, + NVME_DIRECTIVE_SEND_IDENTIFY_CDW12_ENDIR_MASK = 0x1, + NVME_DIRECTIVE_SEND_IDENTIFY_CDW12_DTYPE_MASK = 0x1, + NVME_FW_COMMIT_CDW10_FS_SHIFT = 0, + NVME_FW_COMMIT_CDW10_CA_SHIFT = 3, + NVME_FW_COMMIT_CDW10_BPID_SHIFT = 31, + NVME_FW_COMMIT_CDW10_FS_MASK = 0x7, + NVME_FW_COMMIT_CDW10_CA_MASK = 0x7, + NVME_FW_COMMIT_CDW10_BPID_MASK = 0x1, + NVME_GET_FEATURES_CDW10_SEL_SHIFT = 8, + NVME_GET_FEATURES_CDW10_SEL_MASK = 0x7, + NVME_SET_FEATURES_CDW10_SAVE_SHIFT = 31, + NVME_SET_FEATURES_CDW10_SAVE_MASK = 0x1, + NVME_FEATURES_CDW10_FID_SHIFT = 0, + NVME_FEATURES_CDW14_UUID_SHIFT = 0, + NVME_FEATURES_CDW10_FID_MASK = 0xff, + NVME_FEATURES_CDW14_UUID_MASK = 0x7f, + NVME_LOG_CDW10_LID_SHIFT = 0, + NVME_LOG_CDW10_LSP_SHIFT = 8, + NVME_LOG_CDW10_RAE_SHIFT = 15, + NVME_LOG_CDW10_NUMDL_SHIFT = 16, + NVME_LOG_CDW11_NUMDU_SHIFT = 0, + NVME_LOG_CDW11_LSI_SHIFT = 16, + NVME_LOG_CDW14_UUID_SHIFT = 0, + NVME_LOG_CDW10_LID_MASK = 0xff, + NVME_LOG_CDW10_LSP_MASK = 0xf, + NVME_LOG_CDW10_RAE_MASK = 0x1, + NVME_LOG_CDW10_NUMDL_MASK = 0xff, + NVME_LOG_CDW11_NUMDU_MASK = 0xff, + NVME_LOG_CDW11_LSI_MASK = 0xff, + NVME_LOG_CDW14_UUID_MASK = 0x7f, + NVME_IDENTIFY_CDW10_CNS_SHIFT = 0, + NVME_IDENTIFY_CDW10_CNTID_SHIFT = 16, + NVME_IDENTIFY_CDW11_NVMSETID_SHIFT = 0, + NVME_IDENTIFY_CDW14_UUID_SHIFT = 0, + NVME_IDENTIFY_CDW10_CNS_MASK = 0xff, + NVME_IDENTIFY_CDW10_CNTID_MASK = 0xffff, + NVME_IDENTIFY_CDW11_NVMSETID_MASK = 0xffff, + NVME_IDENTIFY_CDW14_UUID_MASK = 0x7f, + NVME_NAMESPACE_ATTACH_CDW10_SEL_SHIFT = 0, + NVME_NAMESPACE_ATTACH_CDW10_SEL_MASK = 0xf, + NVME_NAMESPACE_MGMT_CDW10_SEL_SHIFT = 0, + NVME_NAMESPACE_MGMT_CDW10_SEL_MASK = 0xf, + NVME_VIRT_MGMT_CDW10_ACT_SHIFT = 0, + NVME_VIRT_MGMT_CDW10_RT_SHIFT = 8, + NVME_VIRT_MGMT_CDW10_CNTLID_SHIFT = 16, + NVME_VIRT_MGMT_CDW11_NR_SHIFT = 0, + NVME_VIRT_MGMT_CDW10_ACT_MASK = 0, + NVME_VIRT_MGMT_CDW10_RT_MASK = 8, + NVME_VIRT_MGMT_CDW10_CNTLID_MASK = 16, + NVME_VIRT_MGMT_CDW11_NR_MASK = 0xffff, + NVME_FORMAT_CDW10_LBAF_SHIFT = 0, + NVME_FORMAT_CDW10_MSET_SHIFT = 4, + NVME_FORMAT_CDW10_PI_SHIFT = 5, + NVME_FORMAT_CDW10_PIL_SHIFT = 8, + NVME_FORMAT_CDW10_SES_SHIFT = 9, + 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_SANITIZE_CDW10_SANACT_SHIFT = 0, + NVME_SANITIZE_CDW10_AUSE_SHIFT = 3, + NVME_SANITIZE_CDW10_OWPASS_SHIFT = 4, + NVME_SANITIZE_CDW10_OIPBP_SHIFT = 8, + NVME_SANITIZE_CDW10_NODAS_SHIFT = 9, + NVME_SANITIZE_CDW10_SANACT_MASK = 0x7, + NVME_SANITIZE_CDW10_AUSE_MASK = 0x1, + NVME_SANITIZE_CDW10_OWPASS_MASK = 0xf, + NVME_SANITIZE_CDW10_OIPBP_MASK = 0x1, + NVME_SANITIZE_CDW10_NODAS_MASK = 0x1, + NVME_SECURITY_NSSF_SHIFT = 0, + NVME_SECURITY_SPSP0_SHIFT = 8, + NVME_SECURITY_SPSP1_SHIFT = 16, + NVME_SECURITY_SECP_SHIFT = 24, + NVME_SECURITY_NSSF_MASK = 0xff, + NVME_SECURITY_SPSP0_MASK = 0xff, + NVME_SECURITY_SPSP1_MASK = 0xff, + NVME_SECURITY_SECP_MASK = 0xffff, + NVME_GET_LBA_STATUS_CDW13_RL_SHIFT = 0, + NVME_GET_LBA_STATUS_CDW13_ATYPE_SHIFT = 24, + NVME_GET_LBA_STATUS_CDW13_RL_MASK = 0xffff, + NVME_GET_LBA_STATUS_CDW13_ATYPE_MASK = 0xff, +}; + +enum features { + NVME_FEATURES_ARBITRATION_BURST_SHIFT = 0, + NVME_FEATURES_ARBITRATION_LPW_SHIFT = 8, + NVME_FEATURES_ARBITRATION_MPW_SHIFT = 16, + NVME_FEATURES_ARBITRATION_HPW_SHIFT = 24, + NVME_FEATURES_ARBITRATION_BURST_MASK = 0x7, + NVME_FEATURES_ARBITRATION_LPW_MASK = 0xff, + NVME_FEATURES_ARBITRATION_MPW_MASK = 0xff, + NVME_FEATURES_ARBITRATION_HPW_MASK = 0xff, + NVME_FEATURES_PWRMGMT_PS_SHIFT = 0, + NVME_FEATURES_PWRMGMT_WH_SHIFT = 5, + NVME_FEATURES_PWRMGMT_PS_MASK = 0x1f, + NVME_FEATURES_PWRMGMT_WH_MASK = 0x7, + NVME_FEATURES_TMPTH_SHIFT = 0, + NVME_FEATURES_TMPSEL_SHIFT = 16, + NVME_FEATURES_THSEL_SHIFT = 20, + NVME_FEATURES_TMPTH_MASK = 0xff, + NVME_FEATURES_TMPSEL_MASK = 0xf, + NVME_FEATURES_THSEL_MASK = 0x3, + NVME_FEATURES_ERROR_RECOVERY_TLER_SHIFT = 0, + NVME_FEATURES_ERROR_RECOVERY_DULBE_SHIFT = 16, + NVME_FEATURES_ERROR_RECOVERY_TLER_MASK = 0xff, + NVME_FEATURES_ERROR_RECOVERY_DULBE_MASK = 0x1, + NVME_FEATURES_VWC_WCE_SHIFT = 0, + NVME_FEATURES_VWC_WCE_MASK = 0x1, + NVME_FEATURES_IRQC_THR_SHIFT = 0, + NVME_FEATURES_IRQC_TIME_SHIFT = 8, + NVME_FEATURES_IRQC_THR_MASK = 0xff, + NVME_FEATURES_IRQC_TIME_MASK = 0xff, + NVME_FEATURES_IVC_IV_SHIFT = 0, + NVME_FEATURES_IVC_CD_SHIFT = 16, + NVME_FEATURES_IVC_IV_MASK = 0xffff, + NVME_FEATURES_IVC_CD_MASK = 0x1, + NVME_FEATURES_WAN_DN_SHIFT = 0, + NVME_FEATURES_WAN_DN_MASK = 0x1, + NVME_FEATURES_APST_APSTE_SHIFT = 0, + NVME_FEATURES_APST_APSTE_MASK = 0x1, + NVME_FEATURES_HCTM_TMT2_SHIFT = 0, + NVME_FEATURES_HCTM_TMT1_SHIFT = 16, + NVME_FEATURES_HCTM_TMT2_MASK = 0xffff, + NVME_FEATURES_HCTM_TMT1_MASK = 0xffff, + NVME_FEATURES_NOPS_NOPPME_SHIFT = 0, + NVME_FEATURES_NOPS_NOPPME_MASK = 0x1, + NVME_FEATURES_PLM_PLE_SHIFT = 0, + NVME_FEATURES_PLM_PLE_MASK = 0x1, + NVME_FEATURES_PLM_WINDOW_SELECT_SHIFT = 0, + NVME_FEATURES_PLM_WINDOW_SELECT_MASK = 0xf, + NVME_FEATURES_LBAS_LSIRI_SHIFT = 0, + NVME_FEATURES_LBAS_LSIPI_SHIFT = 16, + NVME_FEATURES_LBAS_LSIRI_MASK = 0xffff, + NVME_FEATURES_LBAS_LSIPI_MASK = 0xffff, +}; + +#define DW(value, prefix) ((value) & (prefix ## _MASK)) << prefix ## _SHIFT + +int nvme_identify(int fd, enum nvme_identify_cns cns, __u32 nsid, __u16 cntid, + __u16 nvmsetid, __u8 uuidx, void *data) +{ + __u32 cdw10 = DW(cntid, NVME_IDENTIFY_CDW10_CNTID) | + DW(cns, NVME_IDENTIFY_CDW10_CNS); + __u32 cdw11 = DW(nvmsetid, NVME_IDENTIFY_CDW11_NVMSETID); + __u32 cdw14 = DW(uuidx, NVME_IDENTIFY_CDW14_UUID); + + struct nvme_passthru_cmd cmd = { + .opcode = nvme_admin_identify, + .nsid = nsid, + .addr = (__u64)(uintptr_t)data, + .data_len = NVME_IDENTIFY_DATA_SIZE, + .cdw10 = cdw10, + .cdw11 = cdw11, + .cdw14 = cdw14, + }; + + return nvme_submit_admin_passthru(fd, &cmd, NULL); +} + +static int __nvme_identify(int fd, __u8 cns, __u32 nsid, void *data) +{ + return nvme_identify(fd, cns, nsid, NVME_CNTLID_NONE, + NVME_NVMSETID_NONE, NVME_UUID_NONE, data); +} + +int nvme_identify_ctrl(int fd, struct nvme_id_ctrl *id) +{ + return __nvme_identify(fd, NVME_IDENTIFY_CNS_CTRL, NVME_NSID_NONE, id); +} + +int nvme_identify_ns(int fd, __u32 nsid, struct nvme_id_ns *ns) +{ + return __nvme_identify(fd, NVME_IDENTIFY_CNS_NS, nsid, ns); +} + +int nvme_identify_allocated_ns(int fd, __u32 nsid, struct nvme_id_ns *ns) +{ + return __nvme_identify(fd, NVME_IDENTIFY_CNS_ALLOCATED_NS, nsid, ns); +} + +int nvme_identify_active_ns_list(int fd, __u32 nsid, struct nvme_ns_list *list) +{ + return __nvme_identify(fd, NVME_IDENTIFY_CNS_NS_ACTIVE_LIST, nsid, + list); +} + +int nvme_identify_allocated_ns_list(int fd, __u32 nsid, + struct nvme_ns_list *list) +{ + return __nvme_identify(fd, NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST, nsid, + list); +} + +int nvme_identify_ctrl_list(int fd, __u16 cntid, + struct nvme_ctrl_list *ctrlist) +{ + return nvme_identify(fd, NVME_IDENTIFY_CNS_CTRL_LIST, + NVME_NSID_NONE, cntid, NVME_NVMSETID_NONE, + NVME_UUID_NONE, ctrlist); +} + +int nvme_identify_nsid_ctrl_list(int fd, __u32 nsid, __u16 cntid, + struct nvme_ctrl_list *ctrlist) +{ + return nvme_identify(fd, NVME_IDENTIFY_CNS_NS_CTRL_LIST, nsid, + cntid, NVME_NVMSETID_NONE, NVME_UUID_NONE, ctrlist); +} + +int nvme_identify_ns_descs(int fd, __u32 nsid, struct nvme_ns_id_desc *descs) +{ + return __nvme_identify(fd, NVME_IDENTIFY_CNS_NS_DESC_LIST, nsid, descs); +} + +int nvme_identify_nvmset_list(int fd, __u16 nvmsetid, + struct nvme_id_nvmset_list *nvmset) +{ + return nvme_identify(fd, NVME_IDENTIFY_CNS_NVMSET_LIST, + NVME_NSID_NONE, NVME_CNTLID_NONE, nvmsetid, NVME_UUID_NONE, + nvmset); +} + +int nvme_identify_primary_ctrl(int fd, __u16 cntid, + struct nvme_primary_ctrl_cap *cap) +{ + return nvme_identify(fd, NVME_IDENTIFY_CNS_PRIMARY_CTRL_CAP, + NVME_NSID_NONE, cntid, NVME_NVMSETID_NONE, NVME_UUID_NONE, + cap); +} + +int nvme_identify_secondary_ctrl_list(int fd, __u16 cntid, + struct nvme_secondary_ctrl_list *list) +{ + return nvme_identify(fd, NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST, + NVME_NSID_NONE, cntid, NVME_NVMSETID_NONE, NVME_UUID_NONE, + list); +} + +int nvme_identify_ns_granularity(int fd, + struct nvme_id_ns_granularity_list *list) +{ + return __nvme_identify(fd, NVME_IDENTIFY_CNS_NS_GRANULARITY, + NVME_NSID_NONE, list); +} + +int nvme_identify_uuid(int fd, struct nvme_id_uuid_list *list) +{ + return __nvme_identify(fd, NVME_IDENTIFY_CNS_UUID_LIST, NVME_NSID_NONE, + list); +} + +int nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, + __u8 lsp, __u16 lsi, bool rae, __u8 uuidx, __u32 len, void *log) +{ + __u32 numd = (len >> 2) - 1; + __u16 numdu = numd >> 16, numdl = numd & 0xffff; + + __u32 cdw10 = DW(lid, NVME_LOG_CDW10_LID) | + DW(lsp, NVME_LOG_CDW10_LSP) | + DW(!!rae, NVME_LOG_CDW10_RAE) | + DW(numdl, NVME_LOG_CDW10_NUMDL); + __u32 cdw11 = DW(numdu, NVME_LOG_CDW11_NUMDU) | + DW(lsi, NVME_LOG_CDW11_LSI); + __u32 cdw12 = lpo & 0xffffffff; + __u32 cdw13 = lpo >> 32; + __u32 cdw14 = DW(uuidx, NVME_LOG_CDW14_UUID); + + struct nvme_passthru_cmd cmd = { + .opcode = nvme_admin_get_log_page, + .nsid = nsid, + .addr = (__u64)(uintptr_t)log, + .data_len = len, + .cdw10 = cdw10, + .cdw11 = cdw11, + .cdw12 = cdw12, + .cdw13 = cdw13, + .cdw14 = cdw14, + }; + + return nvme_submit_admin_passthru(fd, &cmd, NULL); +} + +static int __nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, bool rae, + __u32 len, void *log) +{ + return nvme_get_log(fd, lid, NVME_NSID_ALL, 0, NVME_LOG_LSP_NONE, + NVME_LOG_LSI_NONE, NVME_UUID_NONE, rae, len, log); +} + +int nvme_get_log_error(int fd, unsigned nr_entries, bool rae, + struct nvme_error_log_page *log) +{ + return __nvme_get_log(fd, NVME_LOG_LID_ERROR, rae, + sizeof(*log) * nr_entries, log); +} + +int nvme_get_log_smart(int fd, __u32 nsid, bool rae, struct nvme_smart_log *log) +{ + return nvme_get_log(fd, NVME_LOG_LID_SMART, nsid, 0, + NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, + sizeof(*log), log); +} + +int nvme_get_log_fw_slot(int fd, bool rae, struct nvme_firmware_slot *log) +{ + return __nvme_get_log(fd, NVME_LOG_LID_FW_SLOT, rae, sizeof(*log), + log); +} + +int nvme_get_log_changed_ns_list(int fd, bool rae, struct nvme_ns_list *log) +{ + return __nvme_get_log(fd, NVME_LOG_LID_CHANGED_NS, rae, + sizeof(*log), log); +} + +int nvme_get_log_cmd_effects(int fd, struct nvme_cmd_effects_log *log) +{ + return __nvme_get_log(fd, NVME_LOG_LID_CMD_EFFECTS, false, + sizeof(*log), log); +} + +int nvme_get_log_device_self_test(int fd, struct nvme_self_test_log *log) +{ + return __nvme_get_log(fd, NVME_LOG_LID_DEVICE_SELF_TEST, false, + sizeof(*log), log); +} + +enum nvme_cmd_get_log_telemetry_host_lsp { + NVME_LOG_TELEM_HOST_LSP_RETAIN = 0, + NVME_LOG_TELEM_HOST_LSP_CREATE = 1, +}; + +int nvme_get_log_create_telemetry_host(int fd, struct nvme_telemetry_log *log) +{ + return nvme_get_log(fd, NVME_LOG_LID_TELEMETRY_HOST, NVME_NSID_NONE, 0, + NVME_LOG_TELEM_HOST_LSP_CREATE, NVME_LOG_LSI_NONE, false, + NVME_UUID_NONE, sizeof(*log), log); +} + +int nvme_get_log_telemetry_host(int fd, __u64 offset, __u32 len, void *log) +{ + return nvme_get_log(fd, NVME_LOG_LID_TELEMETRY_HOST, NVME_NSID_NONE, + offset, NVME_LOG_TELEM_HOST_LSP_RETAIN, NVME_LOG_LSI_NONE, + false, NVME_UUID_NONE, len, log); +} + +int nvme_get_log_telemetry_ctrl(int fd, bool rae, __u64 offset, __u32 len, + void *log) +{ + return nvme_get_log(fd, NVME_LOG_LID_TELEMETRY_CTRL, NVME_NSID_NONE, + offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, + NVME_UUID_NONE, len, log); +} + +int nvme_get_log_endurance_group(int fd, __u16 endgid, + struct nvme_endurance_group_log *log) +{ + return nvme_get_log(fd, NVME_LOG_LID_ENDURANCE_GROUP, NVME_NSID_NONE, + 0, NVME_LOG_LSP_NONE, endgid, false, NVME_UUID_NONE, + sizeof(*log), log); +} + +int nvme_get_log_predictable_lat_nvmset(int fd, __u16 nvmsetid, + struct nvme_nvmset_predictable_lat_log *log) +{ + return nvme_get_log(fd, NVME_LOG_LID_PREDICTABLE_LAT_NVMSET, + NVME_NSID_NONE, 0, NVME_LOG_LSP_NONE, nvmsetid, false, + NVME_UUID_NONE, sizeof(*log), log); +} + +int nvme_get_log_predictable_lat_event(int fd, bool rae, __u32 offset, + __u32 len, void *log) +{ + return nvme_get_log(fd, NVME_LOG_LID_PREDICTABLE_LAT_AGG, + NVME_NSID_NONE, offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, + rae, NVME_UUID_NONE, len, log); +} + +int nvme_get_log_ana(int fd, enum nvme_log_ana_lsp lsp, bool rae, __u64 offset, + __u32 len, void *log) +{ + return nvme_get_log(fd, NVME_LOG_LID_ANA, NVME_NSID_NONE, offset, lsp, + NVME_LOG_LSI_NONE, false, NVME_UUID_NONE, len, log); +} + +int nvme_get_log_ana_groups(int fd, bool rae, __u32 len, + struct nvme_ana_group_desc *log) +{ + return nvme_get_log_ana(fd, NVME_LOG_ANA_LSP_RGO_GROUPS_ONLY, rae, 0, + len, log); +} + +int nvme_get_log_lba_status(int fd, bool rae, __u64 offset, __u32 len, + void *log) +{ + return nvme_get_log(fd, NVME_LOG_LID_LBA_STATUS, NVME_NSID_NONE, + offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, + NVME_UUID_NONE, len, log); +} + +int nvme_get_log_endurance_grp_evt(int fd, bool rae, __u32 offset, __u32 len, + void *log) +{ + return nvme_get_log(fd, NVME_LOG_LID_ENDURANCE_GRP_EVT, + NVME_NSID_NONE, offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, + rae, NVME_UUID_NONE, len, log); +} + +int nvme_get_log_discovery(int fd, bool rae, __u32 offset, __u32 len, void *log) +{ + return nvme_get_log(fd, NVME_LOG_LID_DISC, NVME_NSID_NONE, offset, + NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, + len, log); +} + +int nvme_get_log_reservation(int fd, bool rae, + struct nvme_resv_notification_log *log) +{ + return __nvme_get_log(fd, NVME_LOG_LID_RESERVATION, rae, + sizeof(*log), log); +} + +int nvme_get_log_sanitize(int fd, bool rae, + struct nvme_sanitize_log_page *log) +{ + return __nvme_get_log(fd, NVME_LOG_LID_SANITIZE, rae, sizeof(*log), + log); +} + +int nvme_set_features(int fd, __u8 fid, __u32 nsid, __u32 cdw11, __u32 cdw12, + bool save, __u8 uuidx, __u32 cdw15, __u32 data_len, + void *data, __u32 *result) +{ + __u32 cdw10 = DW(fid, NVME_FEATURES_CDW10_FID) | + DW(!!save, NVME_SET_FEATURES_CDW10_SAVE); + __u32 cdw14 = DW(uuidx, NVME_FEATURES_CDW14_UUID); + + struct nvme_passthru_cmd cmd = { + .opcode = nvme_admin_set_features, + .nsid = nsid, + .addr = (__u64)(uintptr_t)data, + .data_len = data_len, + .cdw10 = cdw10, + .cdw11 = cdw11, + .cdw12 = cdw12, + .cdw14 = cdw14, + .cdw14 = cdw15, + }; + + return nvme_submit_admin_passthru(fd, &cmd, result); +} + +static int __nvme_set_features(int fd, __u8 fid, __u32 cdw11, bool save, + __u32 *result) +{ + return nvme_set_features(fd, fid, NVME_NSID_NONE, cdw11, 0, save, + NVME_UUID_NONE, 0, 0, NULL, result); +} + +int nvme_set_features_arbitration(int fd, __u8 ab, __u8 lpw, __u8 mpw, + __u8 hpw, bool save, __u32 *result) +{ + __u32 value = DW(ab, NVME_FEATURES_ARBITRATION_BURST) | + DW(lpw, NVME_FEATURES_ARBITRATION_LPW) | + DW(mpw, NVME_FEATURES_ARBITRATION_MPW) | + DW(hpw, NVME_FEATURES_ARBITRATION_HPW); + + return __nvme_set_features(fd, NVME_FEAT_FID_ARBITRATION, value, save, + result); +} + +int nvme_set_features_power_mgmt(int fd, __u8 ps, __u8 wh, bool save, + __u32 *result) +{ + __u32 value = DW(ps, NVME_FEATURES_PWRMGMT_PS) | + DW(wh, NVME_FEATURES_PWRMGMT_PS); + + return __nvme_set_features(fd, NVME_FEAT_FID_POWER_MGMT, value, save, + result); +} + +int nvme_set_features_lba_range(int fd, __u32 nsid, __u32 nr_ranges, bool save, + struct nvme_lba_range_type *data, __u32 *result) +{ + return -1; +} + +int nvme_set_features_temp_thresh(int fd, __u16 tmpth, __u8 tmpsel, + enum nvme_feat_tmpthresh_thsel thsel, bool save, __u32 *result) +{ + __u32 value = DW(tmpth, NVME_FEATURES_TMPTH) | + DW(tmpsel, NVME_FEATURES_TMPSEL) | + DW(thsel, NVME_FEATURES_THSEL); + + return __nvme_set_features(fd, NVME_FEAT_FID_TEMP_THRESH, value, save, + result); +} + +int nvme_set_features_err_recovery(int fd, __u32 nsid, __u16 tler, bool dulbe, + bool save, __u32 *result) +{ + __u32 value = DW(tler, NVME_FEATURES_ERROR_RECOVERY_TLER) | + DW(!!dulbe, NVME_FEATURES_ERROR_RECOVERY_DULBE); + + return __nvme_set_features(fd, NVME_FEAT_FID_ERR_RECOVERY, value, save, + result); +} + +int nvme_set_features_volatile_wc(int fd, bool wce, bool save, __u32 *result) +{ + __u32 value = DW(!!wce, NVME_FEATURES_VWC_WCE); + + return __nvme_set_features(fd, NVME_FEAT_FID_VOLATILE_WC, value, save, + result); +} + +int nvme_set_features_irq_coalesce(int fd, __u8 thr, __u8 time, bool save, + __u32 *result) +{ + __u32 value = DW(thr, NVME_FEATURES_IRQC_TIME) | + DW(time, NVME_FEATURES_IRQC_THR); + + return __nvme_set_features(fd, NVME_FEAT_FID_IRQ_COALESCE, value, save, + result); +} + +int nvme_set_features_irq_config(int fd, __u16 iv, bool cd, bool save, + __u32 *result) +{ + __u32 value = DW(iv, NVME_FEATURES_IVC_IV) | + DW(!!cd, NVME_FEATURES_IVC_CD); + + return __nvme_set_features(fd, NVME_FEAT_FID_IRQ_CONFIG, value, save, + result); +} + +int nvme_set_features_write_atomic(int fd, bool dn, bool save, __u32 *result) +{ + __u32 value = DW(!!dn, NVME_FEATURES_WAN_DN); + + return __nvme_set_features(fd, NVME_FEAT_FID_WRITE_ATOMIC, value, save, + result); +} + +int nvme_set_features_async_event(int fd, __u32 events, + bool save, __u32 *result) +{ + return __nvme_set_features(fd, NVME_FEAT_FID_ASYNC_EVENT, events, save, + result); +} + +int nvme_set_features_auto_pst(int fd, bool apste, bool save, + struct nvme_feat_auto_pst *apst, __u32 *result) +{ + __u32 value = DW(!!apste, NVME_FEATURES_APST_APSTE); + + return __nvme_set_features(fd, NVME_FEAT_FID_AUTO_PST, value, save, + result); +} + +int nvme_set_features_timestamp(int fd, bool save, __u64 timestamp) +{ + __le64 t = cpu_to_le64(timestamp); + struct nvme_timestamp ts; + + memcpy(&t, ts.timestamp, sizeof(ts.timestamp)); + return nvme_set_features(fd, NVME_FEAT_FID_TIMESTAMP, + NVME_NSID_NONE, 0, 0, save, NVME_UUID_NONE, 0, + sizeof(ts), &ts, NULL); +} + +int nvme_set_features_hctm(int fd, __u16 tmt2, __u16 tmt1, + bool save, __u32 *result) +{ + __u32 value = DW(tmt2, NVME_FEATURES_HCTM_TMT2) | + DW(tmt1, NVME_FEATURES_HCTM_TMT1); + + return __nvme_set_features(fd, NVME_FEAT_FID_HCTM, value, save, + result); +} + +int nvme_set_features_nopsc(int fd, bool noppme, bool save, __u32 *result) +{ + __u32 value = DW(noppme, NVME_FEATURES_NOPS_NOPPME); + + return __nvme_set_features(fd, NVME_FEAT_FID_NOPSC, value, save, + result); +} + +int nvme_set_features_rrl(int fd, __u8 rrl, __u16 nvmsetid, + bool save, __u32 *result) +{ + return nvme_set_features(fd, NVME_FEAT_FID_RRL, NVME_NSID_NONE, + nvmsetid, rrl, save, NVME_UUID_NONE, 0, 0, NULL, result); +} + +int nvme_set_features_plm_config(int fd, bool plm, __u16 nvmsetid, bool save, + struct nvme_plm_config *data, __u32 *result) +{ + return nvme_set_features(fd, NVME_FEAT_FID_PLM_CONFIG, + NVME_NSID_NONE, nvmsetid, !!plm, save, NVME_UUID_NONE, 0, 0, + NULL, result); +} + +int nvme_set_features_plm_window(int fd, enum nvme_feat_plm_window_select sel, + __u16 nvmsetid, bool save, __u32 *result) +{ + __u32 cdw12 = DW(sel, NVME_FEATURES_PLM_WINDOW_SELECT); + + return nvme_set_features(fd, NVME_FEAT_FID_PLM_WINDOW, NVME_NSID_NONE, + nvmsetid, cdw12, save, NVME_UUID_NONE, 0, 0, NULL, result); +} + +int nvme_set_features_lba_sts_interval(int fd, __u16 lsiri, __u16 lsipi, + bool save, __u32 *result) +{ + __u32 value = DW(lsiri, NVME_FEATURES_LBAS_LSIRI) | + DW(lsipi, NVME_FEATURES_LBAS_LSIPI); + + return __nvme_set_features(fd, NVME_FEAT_FID_LBA_STS_INTERVAL, value, + save, result); +} + +int nvme_set_features_host_behavior(int fd, bool save, + struct nvme_feat_host_behavior *data) +{ + return nvme_set_features(fd, NVME_FEAT_FID_HOST_BEHAVIOR, + NVME_NSID_NONE, save, 0, 0, NVME_UUID_NONE, 0, sizeof(*data), + data, NULL); +} + +int nvme_set_features_sanitize(int fd, bool nodrm, bool save, __u32 *result) +{ + return __nvme_set_features(fd, NVME_FEAT_FID_SANITIZE, !!nodrm, save, + result); +} + +int nvme_set_features_endurance_evt_cfg(int fd, __u16 endgid, __u8 egwarn, + bool save, __u32 *result) +{ + __u32 value = endgid | egwarn << 16; + return __nvme_set_features(fd, NVME_FEAT_FID_ENDURANCE_EVT_CFG, value, + save, result); +} + +int nvme_set_features_sw_progress(int fd, __u8 pbslc, bool save, + __u32 *result) +{ + return __nvme_set_features(fd, NVME_FEAT_FID_SW_PROGRESS, pbslc, save, + result); +} + +int nvme_set_features_host_id(int fd, bool save, bool exhid, __u8 *hostid) +{ + __u32 len = exhid ? 16 : 8; + __u32 value = !!exhid; + + return nvme_set_features(fd, NVME_FEAT_FID_HOST_ID, NVME_NSID_NONE, + save, value, 0, NVME_UUID_NONE, 0, len, hostid, NULL); +} + +int nvme_set_features_resv_mask(int fd, __u32 mask, bool save, __u32 *result) +{ + return __nvme_set_features(fd, NVME_FEAT_FID_RESV_MASK, mask, save, + result); +} + +int nvme_set_features_resv_persist(int fd, bool ptpl, bool save, __u32 *result) +{ + return __nvme_set_features(fd, NVME_FEAT_RESV_PERSIST, !!ptpl, save, + result); +} + +int nvme_set_features_write_protect(int fd, enum nvme_feat_nswpcfg_state state, + bool save, __u32 *result) +{ + return __nvme_set_features(fd, NVME_FEAT_FID_WRITE_PROTECT, state, + save, result); +} + +int nvme_get_features(int fd, enum nvme_features_id fid, __u32 nsid, + enum nvme_get_features_sel sel, __u32 cdw11, __u8 uuidx, + __u32 data_len, void *data, __u32 *result) +{ + __u32 cdw10 = DW(fid, NVME_FEATURES_CDW10_FID) | + DW(sel, NVME_GET_FEATURES_CDW10_SEL); + __u32 cdw14 = DW(uuidx, NVME_FEATURES_CDW14_UUID); + + struct nvme_passthru_cmd cmd = { + .opcode = nvme_admin_get_features, + .nsid = nsid, + .addr = (__u64)(uintptr_t)data, + .data_len = data_len, + .cdw10 = cdw10, + .cdw11 = cdw11, + .cdw14 = cdw14, + }; + + return nvme_submit_admin_passthru(fd, &cmd, result); +} + +static int __nvme_get_features(int fd, enum nvme_features_id fid, + enum nvme_get_features_sel sel, __u32 *result) +{ + return nvme_get_features(fd, fid, NVME_NSID_NONE, sel, 0, + NVME_UUID_NONE, 0, NULL, result); +} + +int nvme_get_features_arbitration(int fd, enum nvme_get_features_sel sel, + __u32 *result) +{ + return __nvme_get_features(fd, NVME_FEAT_FID_ARBITRATION, sel, result); +} + +int nvme_get_features_power_mgmt(int fd, enum nvme_get_features_sel sel, + __u32 *result) +{ + return __nvme_get_features(fd, NVME_FEAT_FID_POWER_MGMT, sel, result); +} + +int nvme_get_features_lba_range(int fd, enum nvme_get_features_sel sel, + struct nvme_lba_range_type *data, + __u32 *result) +{ + return nvme_get_features(fd, NVME_FEAT_FID_LBA_RANGE, NVME_NSID_NONE, sel, 0, + NVME_UUID_NONE, 0, NULL, result); +} + +int nvme_get_features_temp_thresh(int fd, enum nvme_get_features_sel sel, + __u32 *result) +{ + return __nvme_get_features(fd, NVME_FEAT_FID_TEMP_THRESH, sel, result); +} + +int nvme_get_features_err_recovery(int fd, enum nvme_get_features_sel sel, + __u32 *result) +{ + return __nvme_get_features(fd, NVME_FEAT_FID_ERR_RECOVERY, sel, + result); +} + +int nvme_get_features_volatile_wc(int fd, enum nvme_get_features_sel sel, + __u32 *result) +{ + return __nvme_get_features(fd, NVME_FEAT_FID_VOLATILE_WC, sel, result); +} + +int nvme_get_features_num_queues(int fd, enum nvme_get_features_sel sel, + __u32 *result) +{ + return __nvme_get_features(fd, NVME_FEAT_FID_NUM_QUEUES, sel, result); +} + +int nvme_get_features_irq_coalesce(int fd, enum nvme_get_features_sel sel, + __u32 *result) +{ + return __nvme_get_features(fd, NVME_FEAT_FID_IRQ_COALESCE, sel, + result); +} + +int nvme_get_features_irq_config(int fd, enum nvme_get_features_sel sel, + __u16 iv, __u32 *result) +{ + return nvme_get_features(fd, NVME_FEAT_FID_IRQ_CONFIG, NVME_NSID_NONE, sel, iv, + NVME_UUID_NONE, 0, NULL, result); +} + +int nvme_get_features_write_atomic(int fd, enum nvme_get_features_sel sel, + __u32 *result) +{ + return __nvme_get_features(fd, NVME_FEAT_FID_WRITE_ATOMIC, sel, + result); +} + +int nvme_get_features_async_event(int fd, enum nvme_get_features_sel sel, + __u32 *result) +{ + return __nvme_get_features(fd, NVME_FEAT_FID_ASYNC_EVENT, sel, result); +} + +int nvme_get_features_auto_pst(int fd, enum nvme_get_features_sel sel, + struct nvme_feat_auto_pst *apst, __u32 *result) +{ + return nvme_get_features(fd, NVME_FEAT_FID_AUTO_PST, NVME_NSID_NONE, sel, 0, + NVME_UUID_NONE, 0, NULL, result); +} + +int nvme_get_features_host_mem_buf(int fd, enum nvme_get_features_sel sel, + __u32 *result) +{ + return __nvme_get_features(fd, NVME_FEAT_FID_HOST_MEM_BUF, sel, result); +} + +int nvme_get_features_timestamp(int fd, + enum nvme_get_features_sel sel, struct nvme_timestamp *ts) +{ + return nvme_get_features(fd, NVME_FEAT_FID_TIMESTAMP, NVME_NSID_NONE, sel, 0, + NVME_UUID_NONE, 0, NULL, NULL); +} + +int nvme_get_features_kato(int fd, enum nvme_get_features_sel sel, __u32 *result) +{ + return __nvme_get_features(fd, NVME_FEAT_FID_KATO, sel, result); +} + +int nvme_get_features_hctm(int fd, enum nvme_get_features_sel sel, __u32 *result) +{ + return __nvme_get_features(fd, NVME_FEAT_FID_HCTM, sel, result); +} + +int nvme_get_features_nopsc(int fd, enum nvme_get_features_sel sel, __u32 *result) +{ + return __nvme_get_features(fd, NVME_FEAT_FID_NOPSC, sel, result); +} + +int nvme_get_features_rrl(int fd, enum nvme_get_features_sel sel, __u32 *result) +{ + return __nvme_get_features(fd, NVME_FEAT_FID_RRL, sel, result); +} + +int nvme_get_features_plm_config(int fd, enum nvme_get_features_sel sel, + __u16 nvmsetid, struct nvme_plm_config *data, __u32 *result) +{ + return nvme_get_features(fd, NVME_FEAT_FID_PLM_CONFIG, NVME_NSID_NONE, + sel, nvmsetid, NVME_UUID_NONE, 0, NULL, result); +} + +int nvme_get_features_plm_window(int fd, enum nvme_get_features_sel sel, + __u16 nvmsetid, __u32 *result) +{ + return nvme_get_features(fd, NVME_FEAT_FID_PLM_WINDOW, NVME_NSID_NONE, + sel, nvmsetid, NVME_UUID_NONE, 0, NULL, result); +} + +int nvme_get_features_lba_sts_interval(int fd, enum nvme_get_features_sel sel, __u32 *result) +{ + return __nvme_get_features(fd, NVME_FEAT_FID_LBA_STS_INTERVAL, sel, result); +} + +int nvme_get_features_host_behavior(int fd, enum nvme_get_features_sel sel, + struct nvme_feat_host_behavior *data, __u32 *result) +{ + return nvme_get_features(fd, NVME_FEAT_FID_HOST_BEHAVIOR, + NVME_NSID_NONE, sel, 0, NVME_UUID_NONE, 0, NULL, result); +} + +int nvme_get_features_sanitize(int fd, enum nvme_get_features_sel sel, __u32 *result) +{ + return __nvme_get_features(fd, NVME_FEAT_FID_SANITIZE, sel, result); +} + +int nvme_get_features_endurance_event_cfg(int fd, enum nvme_get_features_sel sel, __u16 endgid, __u32 *result) +{ + return nvme_get_features(fd, NVME_FEAT_FID_ENDURANCE_EVT_CFG, + NVME_NSID_NONE, sel, 0, NVME_UUID_NONE, 0, NULL, result); +} + +int nvme_get_features_sw_progress(int fd, enum nvme_get_features_sel sel, __u32 *result) +{ + return __nvme_get_features(fd, NVME_FEAT_FID_SW_PROGRESS, sel, result); +} + +int nvme_get_features_host_id(int fd, enum nvme_get_features_sel sel, + bool exhid, __u32 len, __u8 *hostid) +{ + return nvme_get_features(fd, NVME_FEAT_FID_HOST_ID, NVME_NSID_NONE, + sel, !!exhid, NVME_UUID_NONE, len, hostid, NULL); +} + +int nvme_get_features_resv_mask(int fd, + enum nvme_get_features_sel sel, __u32 *result) +{ + return __nvme_get_features(fd, NVME_FEAT_FID_RESV_MASK, sel, result); +} + +int nvme_get_features_resv_persist(int fd, + enum nvme_get_features_sel sel, __u32 *result) +{ + return __nvme_get_features(fd, NVME_FEAT_RESV_PERSIST, sel, result); +} + +int nvme_get_features_write_protect(int fd, __u32 nsid, + enum nvme_get_features_sel sel, __u32 *result) +{ + return nvme_get_features(fd, NVME_FEAT_FID_WRITE_PROTECT, nsid, sel, 0, + NVME_UUID_NONE, 0, NULL, result); +} + +int nvme_format_nvm(int fd, __u32 nsid, __u8 lbaf, + enum nvme_cmd_format_mset mset, enum nvme_cmd_format_pi pi, + enum nvme_cmd_format_pil pil, enum nvme_cmd_format_ses ses, + __u32 timeout) +{ + __u32 cdw10 = DW(lbaf, NVME_FORMAT_CDW10_LBAF) | + DW(mset, NVME_FORMAT_CDW10_MSET) | + DW(pi, NVME_FORMAT_CDW10_PI) | + DW(pil, NVME_FORMAT_CDW10_PIL) | + DW(ses, NVME_FORMAT_CDW10_SES); + + struct nvme_passthru_cmd cmd = { + .opcode = nvme_admin_format_nvm, + .nsid = nsid, + .cdw10 = cdw10, + .timeout_ms = timeout, + }; + + return nvme_submit_admin_passthru(fd, &cmd, NULL); +} + +int nvme_ns_mgmt(int fd, __u32 nsid, enum nvme_ns_mgmt_sel sel, + struct nvme_id_ns *ns, __u32 *result, __u32 timeout) +{ + __u32 cdw10 = DW(sel, NVME_NAMESPACE_MGMT_CDW10_SEL); + __u32 data_len = ns ? sizeof(*ns) : 0; + + struct nvme_passthru_cmd cmd = { + .nsid = nsid, + .opcode = nvme_admin_ns_mgmt, + .cdw10 = cdw10, + .timeout_ms = timeout, + .data_len = data_len, + .addr = (__u64)(uintptr_t)ns, + }; + + return nvme_submit_admin_passthru(fd, &cmd, result); +} + +int nvme_ns_mgmt_create(int fd, struct nvme_id_ns *ns, __u32 *nsid, + __u32 timeout) +{ + return nvme_ns_mgmt(fd, NVME_NSID_NONE, NVME_NS_MGMT_SEL_CREATE, ns, nsid, + timeout); +} + +int nvme_ns_mgmt_delete(int fd, __u32 nsid) +{ + return nvme_ns_mgmt(fd, nsid, NVME_NS_MGMT_SEL_DELETE, NULL, NULL, 0); +} + +int nvme_ns_attach(int fd, __u32 nsid, enum nvme_ns_attach_sel sel, + struct nvme_ctrl_list *ctrlist) +{ + __u32 cdw10 = DW(sel, NVME_NAMESPACE_ATTACH_CDW10_SEL); + + struct nvme_passthru_cmd cmd = { + .opcode = nvme_admin_ns_attach, + .nsid = nsid, + .cdw10 = cdw10, + .data_len = sizeof(*ctrlist), + .addr = (__u64)(uintptr_t)ctrlist, + }; + + return nvme_submit_admin_passthru(fd, &cmd, NULL); +} + +int nvme_ns_attach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist) +{ + return nvme_ns_attach(fd, nsid, NVME_NS_ATTACH_SEL_CTRL_ATTACH, ctrlist); +} + +int nvme_ns_dettach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist) +{ + return nvme_ns_attach(fd, nsid, NVME_NS_ATTACH_SEL_CTRL_DEATTACH, + ctrlist); +} + +int nvme_fw_download(int fd, __u32 offset, __u32 data_len, void *data) +{ + __u32 cdw10 = (data_len >> 2) - 1; + __u32 cdw11 = offset >> 2; + + struct nvme_passthru_cmd cmd = { + .opcode = nvme_admin_fw_download, + .cdw10 = cdw10, + .cdw11 = cdw11, + .data_len = data_len, + .addr = (__u64)(uintptr_t)data, + }; + + return nvme_submit_admin_passthru(fd, &cmd, NULL); +} + +int nvme_fw_commit(int fd, __u8 slot, enum nvme_fw_commit_ca action, bool bpid) +{ + __u32 cdw10 = DW(slot, NVME_FW_COMMIT_CDW10_FS) | + DW(action, NVME_FW_COMMIT_CDW10_CA) | + DW(bpid, NVME_FW_COMMIT_CDW10_BPID); + + struct nvme_passthru_cmd cmd = { + .opcode = nvme_admin_fw_commit, + .cdw10 = cdw10, + }; + + return nvme_submit_admin_passthru(fd, &cmd, NULL); +} + +int nvme_security_send(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, + __u8 secp, __u32 tl, __u32 data_len, void *data, + __u32 *result) +{ + __u32 cdw10 = DW(secp, NVME_SECURITY_SECP) | + DW(spsp0, NVME_SECURITY_SPSP0) | + DW(spsp1, NVME_SECURITY_SPSP1) | + DW(nssf, NVME_SECURITY_NSSF); + __u32 cdw11 = tl; + + struct nvme_passthru_cmd cmd = { + .opcode = nvme_admin_security_send, + .nsid = nsid, + .cdw10 = cdw10, + .cdw11 = cdw11, + .data_len = data_len, + .addr = (__u64)(uintptr_t)data, + }; + + return nvme_submit_admin_passthru(fd, &cmd, result); +} + +int nvme_security_receive(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, + __u8 spsp1, __u8 secp, __u32 al, __u32 data_len, + void *data, __u32 *result) +{ + __u32 cdw10 = DW(secp, NVME_SECURITY_SECP) | + DW(spsp0, NVME_SECURITY_SPSP0) | + DW(spsp1, NVME_SECURITY_SPSP1) | + DW(nssf, NVME_SECURITY_NSSF); + __u32 cdw11 = al; + + struct nvme_passthru_cmd cmd = { + .opcode = nvme_admin_security_recv, + .nsid = nsid, + .cdw10 = cdw10, + .cdw11 = cdw11, + .data_len = data_len, + .addr = (__u64)(uintptr_t)data, + }; + + return nvme_submit_admin_passthru(fd, &cmd, result); +} + +int nvme_get_lba_status(int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl, + enum nvme_lba_status_atype atype, + struct nvme_lba_status *lbas) +{ + __u32 cdw10 = slba & 0xffffffff; + __u32 cdw11 = slba >> 32; + __u32 cdw12 = mndw; + __u32 cdw13 = DW(rl, NVME_GET_LBA_STATUS_CDW13_RL) | + DW(atype, NVME_GET_LBA_STATUS_CDW13_ATYPE); + + struct nvme_passthru_cmd cmd = { + .opcode = nvme_admin_get_lba_status, + .nsid = nsid, + .addr = (__u64)(uintptr_t)lbas, + .cdw10 = cdw10, + .cdw11 = cdw11, + .cdw12 = cdw12, + .cdw13 = cdw13, + }; + + return nvme_submit_admin_passthru(fd, &cmd, NULL); +} + +int nvme_directive_send(int fd, __u32 nsid, __u16 dspec, __u8 doper, + enum nvme_directive_dtype dtype, __u32 cdw12, + __u32 data_len, void *data, __u32 *result) +{ + __u32 cdw10 = data_len ? (data_len >> 2) - 1 : 0; + __u32 cdw11 = DW(doper, NVME_DIRECTIVE_CDW11_DOPER) | + DW(dtype, NVME_DIRECTIVE_CDW11_DTYPE) | + DW(dspec, NVME_DIRECTIVE_CDW11_DPSEC); + + struct nvme_passthru_cmd cmd = { + .opcode = nvme_admin_directive_send, + .nsid = nsid, + .cdw10 = cdw10, + .cdw11 = cdw11, + .cdw12 = cdw12, + .data_len = data_len, + .addr = (__u64)(uintptr_t)data, + }; + + return nvme_submit_admin_passthru(fd, &cmd, result); +} + +int nvme_directive_send_id_endir(int fd, __u32 nsid, bool endir, + enum nvme_directive_dtype dtype, + struct nvme_id_directives *id) +{ + __u32 cdw12 = DW(dtype, NVME_DIRECTIVE_SEND_IDENTIFY_CDW12_DTYPE) | + DW(endir, NVME_DIRECTIVE_SEND_IDENTIFY_CDW12_ENDIR); + + return nvme_directive_send(fd, nsid, 0, NVME_DIRECTIVE_DTYPE_IDENTIFY, + NVME_DIRECTIVE_SEND_IDENTIFY_DOPER_ENDIR, cdw12, sizeof(*id), + id, NULL); +} + +int nvme_directive_send_stream_release_identifier(int fd, __u32 nsid, + __u16 stream_id) +{ + return nvme_directive_send(fd, nsid, stream_id, + NVME_DIRECTIVE_DTYPE_STREAMS, + NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_IDENTIFIER, 0, 0, + NULL, NULL); +} + +int nvme_directive_send_stream_release_resource(int fd, __u32 nsid) +{ + return nvme_directive_send(fd, nsid, 0, NVME_DIRECTIVE_DTYPE_STREAMS, + NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE, 0, 0, NULL, + NULL); +} + +int nvme_directive_recv(int fd, __u32 nsid, __u16 dspec, __u8 doper, + enum nvme_directive_dtype dtype, __u32 cdw12, + __u32 data_len, void *data, __u32 *result) +{ + __u32 cdw10 = data_len ? (data_len >> 2) - 1 : 0; + __u32 cdw11 = DW(doper, NVME_DIRECTIVE_CDW11_DOPER) | + DW(dtype, NVME_DIRECTIVE_CDW11_DTYPE) | + DW(dspec, NVME_DIRECTIVE_CDW11_DPSEC); + + struct nvme_passthru_cmd cmd = { + .opcode = nvme_admin_directive_recv, + .nsid = nsid, + .cdw10 = cdw10, + .cdw11 = cdw11, + .cdw12 = cdw12, + .data_len = data_len, + .addr = (__u64)(uintptr_t)data, + }; + + return nvme_submit_admin_passthru(fd, &cmd, result); +} + +int nvme_directive_recv_identify_parameters(int fd, __u32 nsid, + struct nvme_id_directives *id) +{ + return nvme_directive_recv(fd, nsid, 0, NVME_DIRECTIVE_DTYPE_IDENTIFY, + NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM, 0, sizeof(*id), + id, NULL); +} + +int nvme_directive_recv_stream_parameters(int fd, __u32 nsid, + struct nvme_streams_directive_params *parms) +{ + return nvme_directive_recv(fd, nsid, 0, NVME_DIRECTIVE_DTYPE_STREAMS, + NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM, 0, sizeof(*parms), + parms, NULL); +} + +int nvme_directive_recv_stream_status(int fd, __u32 nsid, unsigned nr_entries, + struct nvme_streams_directive_status *id) +{ + return nvme_directive_recv(fd, nsid, 0, NVME_DIRECTIVE_DTYPE_STREAMS, + NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS, 0, sizeof(*id), + id, NULL); +} + +int nvme_directive_recv_stream_allocate(int fd, __u32 nsid, __u16 nsr, + __u32 *result) +{ + return nvme_directive_recv(fd, nsid, 0, NVME_DIRECTIVE_DTYPE_STREAMS, + NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE, nsr, 0, NULL, + result); +} + +int nvme_set_property(int fd, int offset, __u64 value) +{ + __u32 cdw10 = is_64bit_reg(offset); + + struct nvme_passthru_cmd cmd = { + .opcode = nvme_admin_fabrics, + .nsid = nvme_fabrics_type_property_set, + .cdw10 = cdw10, + .cdw11 = offset, + .cdw12 = value & 0xffffffff, + .cdw13 = value >> 32, + }; + + return nvme_submit_admin_passthru(fd, &cmd, NULL); +} + +int nvme_get_property(int fd, int offset, __u64 *value) +{ + __u32 cdw10 = is_64bit_reg(offset); + + struct nvme_passthru_cmd64 cmd = { + .opcode = nvme_admin_fabrics, + .nsid = nvme_fabrics_type_property_get, + .cdw10 = cdw10, + .cdw11 = offset, + }; + + return nvme_submit_admin_passthru64(fd, &cmd, value); +} + +int nvme_sanitize_nvm(int fd, enum nvme_sanitize_sanact sanact, bool ause, + __u8 owpass, bool oipbp, bool nodas, __u32 ovrpat) +{ + __u32 cdw10 = DW(sanact, NVME_SANITIZE_CDW10_SANACT) | + DW(!!ause, NVME_SANITIZE_CDW10_AUSE) | + DW(owpass, NVME_SANITIZE_CDW10_OWPASS) | + DW(!!oipbp, NVME_SANITIZE_CDW10_OIPBP) | + DW(!!nodas, NVME_SANITIZE_CDW10_NODAS); + __u32 cdw11 = ovrpat; + + struct nvme_passthru_cmd cmd = { + .opcode = nvme_admin_sanitize_nvm, + .cdw10 = cdw10, + .cdw11 = cdw11, + }; + + return nvme_submit_admin_passthru(fd, &cmd, NULL); +} + +int nvme_dev_self_test(int fd, __u32 nsid, enum nvme_dst_stc stc) +{ + __u32 cdw10 = DW(stc, NVME_DEVICE_SELF_TEST_CDW10_STC); + + struct nvme_passthru_cmd cmd = { + .opcode = nvme_admin_dev_self_test, + .nsid = nsid, + .cdw10 = cdw10, + }; + + return nvme_submit_admin_passthru(fd, &cmd, NULL); +} + +int nvme_virtual_mgmt(int fd, enum nvme_virt_mgmt_act act, + enum nvme_virt_mgmt_rt rt, __u16 cntlid, __u16 nr, + __u32 *result) +{ + __u32 cdw10 = DW(act, NVME_VIRT_MGMT_CDW10_ACT) | + DW(rt, NVME_VIRT_MGMT_CDW10_RT) | + DW(cntlid, NVME_VIRT_MGMT_CDW10_CNTLID); + __u32 cdw11 = DW(nr, NVME_VIRT_MGMT_CDW11_NR); + + struct nvme_passthru_cmd cmd = { + .opcode = nvme_admin_virtual_mgmt, + .cdw10 = cdw10, + .cdw11 = cdw11, + }; + + return nvme_submit_admin_passthru(fd, &cmd, result); +} + +int nvme_submit_io_passthru64(int fd, struct nvme_passthru_cmd64 *cmd, + __u64 *result) +{ + return nvme_submit_passthru64(fd, NVME_IOCTL_IO64_CMD, cmd, result); +} + +int nvme_io_passthru64(int fd, __u8 opcode, __u8 flags, __u16 rsvd, + __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, + __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, + __u32 data_len, void *data, __u32 metadata_len, void *metadata, + __u32 timeout_ms, __u64 *result) +{ + return nvme_passthru64(fd, NVME_IOCTL_IO64_CMD, opcode, flags, rsvd, + nsid, cdw2, cdw3, cdw10, cdw11, cdw12, cdw13, cdw14, cdw15, + data_len, data, metadata_len, metadata, timeout_ms, result); +} + +int nvme_submit_io_passthru(int fd, struct nvme_passthru_cmd *cmd, __u32 *result) +{ + return nvme_submit_passthru(fd, NVME_IOCTL_IO_CMD, cmd, result); +} + +int nvme_io_passthru(int fd, __u8 opcode, __u8 flags, __u16 rsvd, + __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, + __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, + __u32 data_len, void *data, __u32 metadata_len, void *metadata, + __u32 timeout_ms, __u32 *result) +{ + return nvme_passthru(fd, NVME_IOCTL_IO_CMD, opcode, flags, rsvd, nsid, + cdw2, cdw3, cdw10, cdw11, cdw12, cdw13, cdw14, cdw15, data_len, + data, metadata_len, metadata, timeout_ms, result); +} + +int nvme_flush(int fd, __u32 nsid) +{ + struct nvme_passthru_cmd cmd = { + .opcode = nvme_cmd_flush, + .nsid = nsid, + }; + + return nvme_submit_io_passthru(fd, &cmd, NULL); +} + +static int nvme_io(int fd, __u8 opcode, __u32 nsid, __u64 slba, __u16 nlb, + __u16 control, __u32 flags, __u32 reftag, __u16 apptag, __u16 appmask, + __u32 data_len, void *data, __u32 metadata_len, void *metadata) +{ + __u32 cdw10 = slba & 0xffffffff; + __u32 cdw11 = slba >> 32; + __u32 cdw12 = nlb | (control << 16); + __u32 cdw13 = flags; + __u32 cdw14 = reftag; + __u32 cdw15 = apptag | (appmask << 16); + + struct nvme_passthru_cmd cmd = { + .opcode = opcode, + .nsid = nsid, + .cdw10 = cdw10, + .cdw11 = cdw11, + .cdw12 = cdw12, + .cdw13 = cdw13, + .cdw14 = cdw14, + .cdw15 = cdw15, + .data_len = data_len, + .metadata_len = metadata_len, + .addr = (__u64)(uintptr_t)data, + .metadata = (__u64)(uintptr_t)metadata, + }; + + return nvme_submit_io_passthru(fd, &cmd, NULL); +} + +int nvme_read(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, + __u8 dsm, __u32 reftag, __u16 apptag, __u16 appmask, + __u32 data_len, void *data, __u32 metadata_len, void *metadata) +{ + return nvme_io(fd, nvme_cmd_read, nsid, slba, nlb, control, dsm, + reftag, apptag, appmask, data_len, data, metadata_len, + metadata); +} + +int nvme_write(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, + __u8 dsm, __u16 dspec, __u32 reftag, __u16 apptag, + __u16 appmask, __u32 data_len, void *data, __u32 metadata_len, + void *metadata) +{ + __u32 flags = dsm | dspec << 16; + + return nvme_io(fd, nvme_cmd_write, nsid, slba, nlb, control, flags, + reftag, apptag, appmask, data_len, data, metadata_len, + metadata); +} + +int nvme_compare(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, + __u32 reftag, __u16 apptag, __u16 appmask, __u32 data_len, + void *data, __u32 metadata_len, void *metadata) +{ + return nvme_io(fd, nvme_cmd_compare, nsid, slba, nlb, control, 0, + reftag, apptag, appmask, data_len, data, metadata_len, + metadata); +} + +int nvme_write_zeros(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, + __u32 reftag, __u16 apptag, __u16 appmask) +{ + return nvme_io(fd, nvme_cmd_write_zeroes, nsid, slba, nlb, control, 0, + reftag, apptag, appmask, 0, NULL, 0, NULL); +} + +int nvme_verify(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, + __u32 reftag, __u16 apptag, __u16 appmask) +{ + return nvme_io(fd, nvme_cmd_verify, nsid, slba, nlb, control, 0, + reftag, apptag, appmask, 0, NULL, 0, NULL); +} + +int nvme_write_uncorrectable(int fd, __u32 nsid, __u64 slba, __u16 nlb) +{ + return nvme_io(fd, nvme_cmd_write_uncor, nsid, slba, nlb, 0, 0, 0, 0, + 0, 0, NULL, 0, NULL); +} + +int nvme_dsm(int fd, __u32 nsid, __u32 attrs, __u16 nr_ranges, + struct nvme_dsm_range *dsm) +{ + __u32 cdw11 = attrs; + + struct nvme_passthru_cmd cmd = { + .opcode = nvme_cmd_dsm, + .nsid = nsid, + .addr = (__u64)(uintptr_t)dsm, + .data_len = nr_ranges * sizeof(*dsm), + .cdw10 = nr_ranges - 1, + .cdw11 = cdw11, + }; + + return nvme_submit_io_passthru(fd, &cmd, NULL); +} + +int nvme_resv_acquire(int fd, __u32 nsid, enum nvme_reservation_rtype rtype, + enum nvme_reservation_racqa racqa, bool iekey, + __u64 crkey, __u64 nrkey) +{ + __le64 payload[2] = { cpu_to_le64(crkey), cpu_to_le64(nrkey) }; + __u32 cdw10 = (racqa & 0x7) | (iekey ? 1 << 3 : 0) | rtype << 8; + + struct nvme_passthru_cmd cmd = { + .opcode = nvme_cmd_resv_acquire, + .nsid = nsid, + .cdw10 = cdw10, + .data_len = sizeof(payload), + .addr = (__u64)(uintptr_t)(payload), + }; + + return nvme_submit_io_passthru(fd, &cmd, NULL); +} + +int nvme_resv_register(int fd, __u32 nsid, enum nvme_reservation_rrega rrega, + enum nvme_reservation_cptpl cptpl, bool iekey, + __u64 crkey, __u64 nrkey) +{ + __le64 payload[2] = { cpu_to_le64(crkey), cpu_to_le64(nrkey) }; + __u32 cdw10 = (rrega & 0x7) | (iekey ? 1 << 3 : 0) | cptpl << 30; + + struct nvme_passthru_cmd cmd = { + .opcode = nvme_cmd_resv_register, + .nsid = nsid, + .cdw10 = cdw10, + .data_len = sizeof(payload), + .addr = (__u64)(uintptr_t)(payload), + }; + + return nvme_submit_io_passthru(fd, &cmd, NULL); +} + +int nvme_resv_release(int fd, __u32 nsid, enum nvme_reservation_rtype rtype, + enum nvme_reservation_rrela rrela, bool iekey, + __u64 crkey) +{ + __le64 payload[1] = { cpu_to_le64(crkey) }; + __u32 cdw10 = (rrela & 0x7) | (iekey ? 1 << 3 : 0) | rtype << 8; + + struct nvme_passthru_cmd cmd = { + .opcode = nvme_cmd_resv_release, + .nsid = nsid, + .cdw10 = cdw10, + .addr = (__u64)(uintptr_t)(payload), + .data_len = sizeof(payload), + }; + + return nvme_submit_io_passthru(fd, &cmd, NULL); +} + +int nvme_resv_report(int fd, __u32 nsid, bool eds, __u32 len, + struct nvme_reservation_status *report) +{ + struct nvme_passthru_cmd cmd = { + .opcode = nvme_cmd_resv_report, + .nsid = nsid, + .cdw10 = (len >> 2) - 1, + .cdw11 = eds ? 1 : 0, + .addr = (__u64)(uintptr_t)report, + .data_len = len, + }; + + return nvme_submit_io_passthru(fd, &cmd, NULL); +} diff --git a/lib/nvme/ioctl.h b/lib/nvme/ioctl.h new file mode 100644 index 0000000000..e5477f0f80 --- /dev/null +++ b/lib/nvme/ioctl.h @@ -0,0 +1,355 @@ +#ifndef _LIBNVME_IOCTL_H +#define _LIBNVME_IOCTL_H + +#include +#include + +/* + * We can not always count on the kernel UAPI being installed. Use the same + * 'ifdef' guard to avoid double definitions just in case. + */ +#ifndef _UAPI_LINUX_NVME_IOCTL_H +#define _UAPI_LINUX_NVME_IOCTL_H + +/** + * struct nvme_passthru_cmd - + * @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 + * @result: Set on completion to the command's CQE DWORD 0 controller response + */ +struct nvme_passthru_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 result; +}; + +/** + * struct nvme_passthru_cmd64 - + * @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 impicit 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; +}; + +#define NVME_IOCTL_ID _IO('N', 0x40) +#define NVME_IOCTL_RESET _IO('N', 0x44) +#define NVME_IOCTL_SUBSYS_RESET _IO('N', 0x45) +#define NVME_IOCTL_RESCAN _IO('N', 0x46) +#define NVME_IOCTL_ADMIN_CMD _IOWR('N', 0x41, struct nvme_passthru_cmd) +#define NVME_IOCTL_IO_CMD _IOWR('N', 0x43, struct nvme_passthru_cmd) +#define NVME_IOCTL_ADMIN64_CMD _IOWR('N', 0x47, struct nvme_passthru_cmd64) +#define NVME_IOCTL_IO64_CMD _IOWR('N', 0x48, struct nvme_passthru_cmd64) + +#endif /* _UAPI_LINUX_NVME_IOCTL_H */ + +/** + * nvme_submit_admin_passthru64() - Submit a 64-bit nvme passthrough admin + * 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 + * + * Uses NVME_IOCTL_ADMIN64_CMD for the ioctl request. + * + * Return: The nvme command status if a response was received or -1 + * with errno set otherwise. + */ +int nvme_submit_admin_passthru64(int fd, struct nvme_passthru_cmd64 *cmd, + __u64 *result); + +/** + * nvme_admin_passthru64() - Submit an nvme passthrough command + * @fd: File descriptor of nvme device + * @opcode: The nvme io command to send + * @flags: NVMe command flags (not used) + * @rsvd: Reserevd for future use + * @nsid: Namespace identifier + * @cdw2: Command dword 2 + * @cdw3: Command dword 3 + * @cdw10: Command dword 10 + * @cdw11: Command dword 11 + * @cdw12: Command dword 12 + * @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: Pointer to user address of the data buffer + * @metadata_len:Length of metadata transfered 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 + * + * Parameterized form of nvme_submit_admin_passthru64(). This sets up and + * submits a &struct nvme_passthru_cmd64. + * + * Known values for @opcode are defined in &enum nvme_admin_opcode. + * + * Return: The nvme command status if a response was received or -1 + * with errno set otherwise. + */ +int nvme_admin_passthru64(int fd, __u8 opcode, __u8 flags, __u16 rsvd, + __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, + __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, + __u32 data_len, void *data, __u32 metadata_len, void *metadata, + __u32 timeout_ms, __u64 *result); + +/** + * nvme_submit_admin_passthru() - Submit an nvme passthrough admin 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 + * + * Uses NVME_IOCTL_ADMIN_CMD for the ioctl request. + * + * Return: The nvme command status if a response was received or -1 + * with errno set otherwise. + */ +int nvme_submit_admin_passthru(int fd, struct nvme_passthru_cmd *cmd, + __u32 *result); + +/** + * nvme_admin_passthru() - Submit an nvme passthrough command + * @fd: File descriptor of nvme device + * @opcode: The nvme io command to send + * @flags: NVMe command flags (not used) + * @rsvd: Reserevd for future use + * @nsid: Namespace identifier + * @cdw2: Command dword 2 + * @cdw3: Command dword 3 + * @cdw10: Command dword 10 + * @cdw11: Command dword 11 + * @cdw12: Command dword 12 + * @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: Pointer to user address of the data buffer + * @metadata_len:Length of metadata transfered 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 + * + * Parameterized form of nvme_submit_admin_passthru(). This sets up and + * submits a &struct nvme_passthru_cmd. + * + * Known values for @opcode are defined in &enum nvme_admin_opcode. + * + * Return: The nvme command status if a response was received or -1 + * with errno set otherwise. + */ +int nvme_admin_passthru(int fd, __u8 opcode, __u8 flags, __u16 rsvd, + __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, + __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, + __u32 data_len, void *data, __u32 metadata_len, void *metadata, + __u32 timeout_ms, __u32 *result); + +/** + * nvme_submit_passthru64() - Submit a 64-bit nvme passthrough command + * @fd: File descriptor of nvme device + * @cmd: The nvme io command to send + * @result: Optional field to return the result from the CQE DW0-1 + * + * Uses NVME_IOCTL_IO64_CMD for the ioctl request. + * + * Return: The nvme command status if a response was received or -1 + * with errno set otherwise. + */ +int nvme_submit_io_passthru64(int fd, struct nvme_passthru_cmd64 *cmd, + __u64 *result); + +/** + * nvme_io_passthru64() - Submit an nvme io passthrough command + * @fd: File descriptor of nvme device + * @opcode: The nvme io command to send + * @flags: NVMe command flags (not used) + * @rsvd: Reserevd for future use + * @nsid: Namespace identifier + * @cdw2: Command dword 2 + * @cdw3: Command dword 3 + * @cdw10: Command dword 10 + * @cdw11: Command dword 11 + * @cdw12: Command dword 12 + * @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: Pointer to user address of the data buffer + * @metadata_len:Length of metadata transfered 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 + * + * Parameterized form of nvme_submit_io_passthru64(). This sets up and submits + * a &struct nvme_passthru_cmd64. + * + * Known values for @opcode are defined in &enum nvme_io_opcode. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_io_passthru64(int fd, __u8 opcode, __u8 flags, __u16 rsvd, + __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, + __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, + __u32 data_len, void *data, __u32 metadata_len, void *metadata, + __u32 timeout_ms, __u64 *result); + +/** + * nvme_submit_passthru() - Submit an nvme passthrough command + * @fd: File descriptor of nvme device + * @cmd: The nvme io command to send + * @result: Optional field to return the result from the CQE dword 0 + * @result: Optional field to return the result from the CQE DW0 + * + * Uses NVME_IOCTL_IO_CMD for the ioctl request. + * + * Return: The nvme command status if a response was received or -1 + * with errno set otherwise. + */ +int nvme_submit_io_passthru(int fd, struct nvme_passthru_cmd *cmd, + __u32 *result); + +/** + * nvme_io_passthru() - Submit an nvme io passthrough command + * @fd: File descriptor of nvme device + * @opcode: The nvme io command to send + * @flags: NVMe command flags (not used) + * @rsvd: Reserevd for future use + * @nsid: Namespace identifier + * @cdw2: Command dword 2 + * @cdw3: Command dword 3 + * @cdw10: Command dword 10 + * @cdw11: Command dword 11 + * @cdw12: Command dword 12 + * @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: Pointer to user address of the data buffer + * @metadata_len:Length of metadata transfered 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 + * + * Parameterized form of nvme_submit_io_passthru(). This sets up and submits + * a &struct nvme_passthru_cmd. + * + * Known values for @opcode are defined in &enum nvme_io_opcode. + * + * Return: The nvme command status if a response was received or -1 + * with errno set otherwise. + */ +int nvme_io_passthru(int fd, __u8 opcode, __u8 flags, __u16 rsvd, + __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, + __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, + __u32 data_len, void *data, __u32 metadata_len, void *metadata, + __u32 timeout_ms, __u32 *result); + +/** + * nvme_subsystem_reset() - Initiate a subsystem reset + * @fd: File descriptor of nvme device + * + * This should only be sent to controller handles, not to namespaces. + * + * Return: Zero if a subsystem reset was initiated or -1 with errno set + * otherwise. + */ +int nvme_subsystem_reset(int fd); + +/** + * nvme_reset_ctrl() - Initiate a controller reset + * @fd: File descriptor of nvme device + * + * This should only be sent to controller handles, not to namespaces. + * + * Return: Zero if a reset was initiated or -1 with errno set otherwise. + */ +int nvme_reset_ctrl(int fd); + +/** + * nvme_ns_rescan() - Initiate a controller rescan + * @fd: File descriptor of nvme device + * + * This should only be sent to controller handles, not to namespaces. + * + * Return: Zero if a rescan was initiated or -1 with errno set otherwise. + */ +int nvme_ns_rescan(int fd); + +/** + * nvme_get_nsid() - Retrieve the NSID from a namespace file descriptor + * @fd: File descriptor of nvme namespace + * + * This should only be sent to namespace handles, not to controllers. + * + * Return: The namespace identifier if a succecssful or -1 with errno set + * otherwise. + */ +int nvme_get_nsid(int fd); + +#endif /* _LIBNVME_IOCTL_H */ diff --git a/lib/nvme/private.h b/lib/nvme/private.h new file mode 100644 index 0000000000..939aba7401 --- /dev/null +++ b/lib/nvme/private.h @@ -0,0 +1,97 @@ +#ifndef _LIBNVME_PRIVATE_H +#define _LIBNVME_PRIVATE_H + +#include +#include +#include +#include + +#include "tree.h" + +struct nvme_path { + TAILQ_ENTRY(nvme_path) entry; + TAILQ_ENTRY(nvme_path) nentry; + struct nvme_ctrl *c; + struct nvme_ns *n; + + char *name; + char *sysfs_dir; + char *ana_state; + int grpid; +}; + +struct nvme_ns { + TAILQ_ENTRY(nvme_ns) entry; + TAILQ_HEAD(, nvme_path) paths; + struct nvme_subsystem *s; + struct nvme_ctrl *c; + + int fd; + char *name; + char *sysfs_dir; + int nsid; + + int lba_size; + int meta_size; + uint64_t lba_count; + uint64_t lba_util; +}; + +struct nvme_ctrl { + TAILQ_ENTRY(nvme_ctrl) entry; + TAILQ_HEAD(, nvme_ns) namespaces; + TAILQ_HEAD(, nvme_path) paths; + struct nvme_subsystem *s; + + int fd; + char *name; + char *sysfs_dir; + char *address; + char *firmware; + char *model; + char *state; + char *numa_node; + char *queue_count; + char *serial; + char *sqsize; + char *transport; + char *subsysnqn; +}; + +struct nvme_subsystem { + TAILQ_ENTRY(nvme_subsystem) entry; + TAILQ_HEAD(, nvme_ctrl) ctrls; + TAILQ_HEAD(, nvme_ns) namespaces; + struct nvme_root *r; + + char *name; + char *sysfs_dir; + char *subsysnqn; +}; + +struct nvme_root { + TAILQ_HEAD(, nvme_subsystem) subsystems; +}; + +void nvme_free_ctrl(struct nvme_ctrl *c); +void nvme_ctrl_free_ns(struct nvme_ns *n); +void nvme_subsystem_free_ns(struct nvme_ns *n); +void nvme_free_path(struct nvme_path *p); +void nvme_free_subsystem(struct nvme_subsystem *s); + +int nvme_scan_subsystem(struct nvme_root *t, char *name, nvme_scan_filter_t f); +int nvme_subsystem_scan_namespace(struct nvme_subsystem *s, char *name); +int nvme_subsystem_scan_ctrls(struct nvme_subsystem *s); +int nvme_subsystem_scan_ctrl(struct nvme_subsystem *s, char *name); + +int nvme_ctrl_scan_namespace(struct nvme_ctrl *c, char *name); +int nvme_ctrl_scan_path(struct nvme_ctrl *c, char *name); + +static inline void nvme_free_dirents(struct dirent **d, int i) +{ + while (i-- > 0) + free(d[i]); + free(d); +} + +#endif /* _LIBNVME_PRIVATE_H */ diff --git a/lib/nvme/tree.c b/lib/nvme/tree.c new file mode 100644 index 0000000000..9de7d49301 --- /dev/null +++ b/lib/nvme/tree.c @@ -0,0 +1,808 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include + +#include "ioctl.h" +#include "filters.h" +#include "tree.h" +#include "private.h" +#include "filters.h" +#include "util.h" +#include "cmd.h" + +static int nvme_scan_topology(struct nvme_root *r, nvme_scan_filter_t f) +{ + struct dirent **subsys; + int i, ret; + + ret = nvme_scan_subsystems(&subsys); + if (ret < 0) + return ret; + + for (i = 0; i < ret; i++) + nvme_scan_subsystem(r, subsys[i]->d_name, f); + + nvme_free_dirents(subsys, i); + return 0; +} + +nvme_root_t nvme_scan_filter(nvme_scan_filter_t f) +{ + struct nvme_root *r = malloc(sizeof(*r)); + + if (!r) { + errno = ENOMEM; + return NULL; + } + + memset(r, 0, sizeof(*r)); + TAILQ_INIT(&r->subsystems); + nvme_scan_topology(r, f); + return r; +} + +nvme_root_t nvme_scan() +{ + return nvme_scan_filter(NULL); +} + +nvme_subsystem_t nvme_first_subsystem(nvme_root_t r) +{ + return TAILQ_FIRST(&r->subsystems); +} + +nvme_subsystem_t nvme_next_subsystem(nvme_root_t r, nvme_subsystem_t s) +{ + if (!s) + return NULL; + return TAILQ_NEXT(s, entry); +} + +void nvme_refresh_topology(nvme_root_t r) +{ + struct nvme_subsystem *s, *_s; + + nvme_for_each_subsystem_safe(r, s, _s) + nvme_free_subsystem(s); + nvme_scan_topology(r, NULL); +} + +void nvme_reset_topology(nvme_root_t r) +{ + struct nvme_subsystem *s, *_s; + + nvme_for_each_subsystem_safe(r, s, _s) + nvme_free_subsystem(s); + nvme_scan_topology(r, NULL); +} + +void nvme_free_tree(nvme_root_t r) +{ + struct nvme_subsystem *s, *_s; + + nvme_for_each_subsystem_safe(r, s, _s) + nvme_free_subsystem(s); + free(r); +} + +const char *nvme_subsystem_get_nqn(nvme_subsystem_t s) +{ + return s->subsysnqn; +} + +const char *nvme_subsystem_get_sysfs_dir(nvme_subsystem_t s) +{ + return s->sysfs_dir; +} + +const char *nvme_subsystem_get_name(nvme_subsystem_t s) +{ + return s->name; +} + +nvme_ctrl_t nvme_subsystem_first_ctrl(nvme_subsystem_t s) +{ + return TAILQ_FIRST(&s->ctrls); +} + +nvme_ctrl_t nvme_subsystem_next_ctrl(nvme_subsystem_t s, nvme_ctrl_t c) +{ + if (!c) + return NULL; + return TAILQ_NEXT(c, entry); +} + +nvme_ns_t nvme_subsystem_first_ns(nvme_subsystem_t s) +{ + return TAILQ_FIRST(&s->namespaces); +} + +nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n) +{ + if (!n) + return NULL; + return TAILQ_NEXT(n, entry); +} + +void nvme_free_subsystem(struct nvme_subsystem *s) +{ + struct nvme_ctrl *c, *_c; + struct nvme_ns *n, *_n; + + if (s->r) + TAILQ_REMOVE(&s->r->subsystems, s, entry); + + nvme_subsystem_for_each_ctrl_safe(s, c, _c) + nvme_free_ctrl(c); + + nvme_subsystem_for_each_ns_safe(s, n, _n) + nvme_subsystem_free_ns(n); + + free(s->name); + free(s->sysfs_dir); + free(s->subsysnqn); + free(s); +} + +static int nvme_subsystem_scan_namespaces(struct nvme_subsystem *s) +{ + struct dirent **namespaces; + int i, ret; + + ret = nvme_scan_subsystem_namespaces(s, &namespaces); + if (ret < 0) + return ret; + + for (i = 0; i < ret; i++) + nvme_subsystem_scan_namespace(s, namespaces[i]->d_name); + + nvme_free_dirents(namespaces, i); + return 0; +} + +int nvme_subsystem_scan_ctrls(struct nvme_subsystem *s) +{ + struct dirent **ctrls; + int i, ret; + + ret = nvme_scan_subsystem_ctrls(s, &ctrls); + if (ret < 0) + return ret; + + for (i = 0; i < ret; i++) + nvme_subsystem_scan_ctrl(s, ctrls[i]->d_name); + + nvme_free_dirents(ctrls, i); + return 0; +} + +int nvme_scan_subsystem(struct nvme_root *r, char *name, nvme_scan_filter_t f) +{ + struct nvme_subsystem *s; + char *path; + int ret; + + ret = asprintf(&path, "%s/%s", nvme_subsys_sysfs_dir, name); + if (ret < 0) + return ret; + + s = malloc(sizeof(*s)); + if (!s) { + errno = ENOMEM; + goto free_path; + } + memset(s, 0, sizeof(*s)); + + s->r = r; + s->name = strdup(name);; + s->sysfs_dir = path; + s->subsysnqn = nvme_get_subsys_attr(s, "subsysnqn"); + TAILQ_INIT(&s->ctrls); + TAILQ_INIT(&s->namespaces); + + nvme_subsystem_scan_namespaces(s); + nvme_subsystem_scan_ctrls(s); + TAILQ_INSERT_TAIL(&r->subsystems, s, entry); + + if (f && !f(s)) { + nvme_free_subsystem(s); + return -1; + } + + return 0; + +free_path: + free(path); + return -1; +} +nvme_ctrl_t nvme_path_get_subsystem(nvme_path_t p) +{ + return p->c; +} + +nvme_ns_t nvme_path_get_ns(nvme_path_t p) +{ + return p->n; +} + +const char *nvme_path_get_sysfs_dir(nvme_path_t p) +{ + return p->sysfs_dir; +} + +const char *nvme_path_get_name(nvme_path_t p) +{ + return p->name; +} + +const char *nvme_path_get_ana_state(nvme_path_t p) +{ + return p->ana_state; +} + +void nvme_free_path(struct nvme_path *p) +{ + TAILQ_REMOVE(&p->c->paths, p, entry); + TAILQ_REMOVE(&p->n->paths, p, nentry); + free(p->name); + free(p->sysfs_dir); + free(p->ana_state); + free(p); +} + +static void nvme_subsystem_set_path_ns(nvme_subsystem_t s, nvme_path_t p) +{ + char n_name[32] = { 0 }; + int i, c, nsid, ret; + nvme_ns_t n; + + ret = sscanf(nvme_path_get_name(p), "nvme%dc%dn%d", &i, &c, &nsid); + if (ret != 3) + return; + + sprintf(n_name, "nvme%dn%d", i, nsid); + nvme_subsystem_for_each_ns(s, n) { + if (!strcmp(n_name, nvme_ns_get_name(n))) { + TAILQ_INSERT_TAIL(&n->paths, p, nentry); + p->n = n; + } + } +} + +int nvme_ctrl_scan_path(struct nvme_ctrl *c, char *name) +{ + struct nvme_path *p; + char *path, *grpid; + int ret; + + ret = asprintf(&path, "%s/%s", c->sysfs_dir, name); + if (ret < 0) { + errno = ENOMEM; + return -1; + } + + p = malloc(sizeof(*p)); + if (!p) { + errno = ENOMEM; + goto free_path; + } + memset(p, 0, sizeof(*p)); + + p->c = c; + p->name = strdup(name); + p->sysfs_dir = path; + p->ana_state = nvme_get_path_attr(p, "ana_state"); + nvme_subsystem_set_path_ns(c->s, p); + + grpid = nvme_get_path_attr(p, "ana_grpid"); + if (grpid) { + sscanf(grpid, "%d", &p->grpid); + free(grpid); + } + + TAILQ_INSERT_TAIL(&c->paths, p, entry); + return 0; + +free_path: + free(path); + return -1; +} + +int nvme_ctrl_get_fd(nvme_ctrl_t c) +{ + return c->fd; +} + +nvme_subsystem_t nvme_ctrl_get_subsystem(nvme_ctrl_t c) +{ + return c->s; +} + +const char *nvme_ctrl_get_name(nvme_ctrl_t c) +{ + return c->name; +} + +const char *nvme_ctrl_get_sysfs_dir(nvme_ctrl_t c) +{ + return c->sysfs_dir; +} + +const char *nvme_ctrl_get_subsysnqn(nvme_ctrl_t c) +{ + return c->subsysnqn; +} + +const char *nvme_ctrl_get_address(nvme_ctrl_t c) +{ + return c->address; +} + +const char *nvme_ctrl_get_firmware(nvme_ctrl_t c) +{ + return c->firmware; +} + +const char *nvme_ctrl_get_model(nvme_ctrl_t c) +{ + return c->model; +} + +const char *nvme_ctrl_get_state(nvme_ctrl_t c) +{ + return c->state; +} + +const char *nvme_ctrl_get_numa_node(nvme_ctrl_t c) +{ + return c->numa_node; +} + +const char *nvme_ctrl_get_queue_count(nvme_ctrl_t c) +{ + return c->queue_count; +} + +const char *nvme_ctrl_get_serial(nvme_ctrl_t c) +{ + return c->serial; +} + +const char *nvme_ctrl_get_sqsize(nvme_ctrl_t c) +{ + return c->sqsize; +} + +const char *nvme_ctrl_get_transport(nvme_ctrl_t c) +{ + return c->transport; +} + +int nvme_ctrl_identify(nvme_ctrl_t c, struct nvme_id_ctrl *id) +{ + return nvme_identify_ctrl(nvme_ctrl_get_fd(c), id); +} + +nvme_ns_t nvme_ctrl_first_ns(nvme_ctrl_t c) +{ + return TAILQ_FIRST(&c->namespaces); +} + +nvme_ns_t nvme_ctrl_next_ns(nvme_ctrl_t c, nvme_ns_t n) +{ + if (!n) + return NULL; + return TAILQ_NEXT(n, entry); +} + +nvme_path_t nvme_ctrl_first_path(nvme_ctrl_t c) +{ + return TAILQ_FIRST(&c->paths); +} + +nvme_path_t nvme_ctrl_next_path(nvme_ctrl_t c, nvme_path_t p) +{ + if (!p) + return NULL; + return TAILQ_NEXT(p, entry); +} + +int nvme_ctrl_disconnect(nvme_ctrl_t c) +{ + return nvme_set_attr(nvme_ctrl_get_sysfs_dir(c), "delete_controller", "1"); +} + +void nvme_unlink_ctrl(nvme_ctrl_t c) +{ + if (c->s) + TAILQ_REMOVE(&c->s->ctrls, c, entry); + c->s = NULL; +} + +void nvme_free_ctrl(nvme_ctrl_t c) +{ + struct nvme_path *p, *_p; + struct nvme_ns *n, *_n; + + nvme_unlink_ctrl(c); + + nvme_ctrl_for_each_path_safe(c, p, _p) + nvme_free_path(p); + + nvme_ctrl_for_each_ns_safe(c, n, _n) + nvme_ctrl_free_ns(n); + + close(c->fd); + free(c->name); + free(c->sysfs_dir); + free(c->subsysnqn); + free(c->address); + free(c->firmware); + free(c->model); + free(c->state); + free(c->numa_node); + free(c->queue_count); + free(c->serial); + free(c->sqsize); + free(c->transport); + free(c); +} + +static int nvme_ctrl_scan_paths(struct nvme_ctrl *c) +{ + struct dirent **paths; + int i, ret; + + ret = nvme_scan_ctrl_namespace_paths(c, &paths); + if (ret < 0) + return ret; + + for (i = 0; i < ret; i++) + nvme_ctrl_scan_path(c, paths[i]->d_name); + + nvme_free_dirents(paths, i); + return 0; +} + +static int nvme_ctrl_scan_namespaces(struct nvme_ctrl *c) +{ + struct dirent **namespaces; + int i, ret; + + ret = nvme_scan_ctrl_namespaces(c, &namespaces); + for (i = 0; i < ret; i++) + nvme_ctrl_scan_namespace(c, namespaces[i]->d_name); + + nvme_free_dirents(namespaces, i); + return 0; +} + +static nvme_ctrl_t __nvme_ctrl_alloc(const char *path, const char *name) +{ + DIR *d; + nvme_ctrl_t c; + + d = opendir(path); + if (!d) + return NULL; + closedir(d); + + c = malloc(sizeof(*c)); + if (!c) { + errno = ENOMEM; + return NULL; + } + memset(c, 0, sizeof(*c)); + + c->fd = nvme_open(name); + if (c->fd < 0) + goto free_ctrl; + + TAILQ_INIT(&c->namespaces); + TAILQ_INIT(&c->paths); + c->name = strdup(name); + c->sysfs_dir = (char *)path; + c->subsysnqn = nvme_get_ctrl_attr(c, "subsysnqn"); + c->address = nvme_get_ctrl_attr(c, "address"); + c->firmware = nvme_get_ctrl_attr(c, "firmware_rev"); + c->model = nvme_get_ctrl_attr(c, "model"); + c->state = nvme_get_ctrl_attr(c, "state"); + c->numa_node = nvme_get_ctrl_attr(c, "numa_node"); + c->queue_count = nvme_get_ctrl_attr(c, "queue_count"); + c->serial = nvme_get_ctrl_attr(c, "serial"); + c->sqsize = nvme_get_ctrl_attr(c, "sqsize"); + c->transport = nvme_get_ctrl_attr(c, "transport"); + + return c; + +free_ctrl: + free(c); + return NULL; +} + +static nvme_ctrl_t nvme_ctrl_alloc(const char *sysfs, const char *name) +{ + nvme_ctrl_t c; + char *path; + int ret; + + ret = asprintf(&path, "%s/%s", sysfs, name); + if (ret < 0) { + errno = ENOMEM; + return NULL; + } + + c = __nvme_ctrl_alloc(path, name); + if (!c) + free(path); + return c; +} + +nvme_ctrl_t nvme_scan_ctrl(const char *name) +{ + return nvme_ctrl_alloc(nvme_ctrl_sysfs_dir, name); +} + +int nvme_subsystem_scan_ctrl(struct nvme_subsystem *s, char *name) +{ + nvme_ctrl_t c; + + c = nvme_ctrl_alloc(s->sysfs_dir, name); + if (!c) + return -1; + + c->s = s; + nvme_ctrl_scan_namespaces(c); + nvme_ctrl_scan_paths(c); + TAILQ_INSERT_TAIL(&s->ctrls, c, entry); + + return 0; +} + +static int nvme_bytes_to_lba(nvme_ns_t n, off_t offset, size_t count, __u64 *lba, + __u16 *nlb) +{ + int bs; + + bs = nvme_ns_get_lba_size(n); + if (!count || offset & bs || count & bs) { + errno = EINVAL; + return -1; + } + + *lba = offset / bs; + *nlb = (count / bs) - 1; + return 0; +} + +int nvme_ns_get_fd(nvme_ns_t n) +{ + return n->fd; +} + +nvme_subsystem_t nvme_ns_get_subsystem(nvme_ns_t n) +{ + return n->s; +} + +nvme_ctrl_t nvme_ns_get_ctrl(nvme_ns_t n) +{ + return n->c; +} + +int nvme_ns_get_nsid(nvme_ns_t n) +{ + return n->nsid; +} + +const char *nvme_ns_get_sysfs_dir(nvme_ns_t n) +{ + return n->sysfs_dir; +} + +const char *nvme_ns_get_name(nvme_ns_t n) +{ + return n->name; +} + +int nvme_ns_get_lba_size(nvme_ns_t n) +{ + return n->lba_size; +} + +uint64_t nvme_ns_get_lba_count(nvme_ns_t n) +{ + return n->lba_count; +} + +uint64_t nvme_ns_get_lba_util(nvme_ns_t n) +{ + return n->lba_util; +} + +int nvme_ns_identify(nvme_ns_t n, struct nvme_id_ns *ns) +{ + return nvme_identify_ns(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), ns); +} + +int nvme_ns_verify(nvme_ns_t n, off_t offset, size_t count) +{ + __u64 slba; + __u16 nlb; + + if (nvme_bytes_to_lba(n, offset, count, &slba, &nlb)) + return -1; + + return nvme_verify(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), slba, nlb, + 0, 0, 0, 0); +} + +int nvme_ns_write_uncorrectable(nvme_ns_t n, off_t offset, size_t count) +{ + __u64 slba; + __u16 nlb; + + if (nvme_bytes_to_lba(n, offset, count, &slba, &nlb)) + return -1; + + return nvme_write_uncorrectable(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), + slba, nlb); +} + +int nvme_ns_write_zeros(nvme_ns_t n, off_t offset, size_t count) +{ + __u64 slba; + __u16 nlb; + + if (nvme_bytes_to_lba(n, offset, count, &slba, &nlb)) + return -1; + + return nvme_write_zeros(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), slba, + nlb, 0, 0, 0, 0); +} + +int nvme_ns_write(nvme_ns_t n, void *buf, off_t offset, size_t count) +{ + __u64 slba; + __u16 nlb; + + if (nvme_bytes_to_lba(n, offset, count, &slba, &nlb)) + return -1; + + return nvme_write(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), slba, nlb, 0, + 0, 0, 0, 0, 0, count, buf, 0, NULL); +} + +int nvme_ns_read(nvme_ns_t n, void *buf, off_t offset, size_t count) +{ + __u64 slba; + __u16 nlb; + + if (nvme_bytes_to_lba(n, offset, count, &slba, &nlb)) + return -1; + + return nvme_read(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), slba, nlb, 0, + 0, 0, 0, 0, count, buf, 0, NULL); +} + +int nvme_ns_compare(nvme_ns_t n, void *buf, off_t offset, size_t count) +{ + __u64 slba; + __u16 nlb; + + if (nvme_bytes_to_lba(n, offset, count, &slba, &nlb)) + return -1; + + return nvme_compare(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), slba, nlb, + 0, 0, 0, 0, count, buf, 0, NULL); +} + +int nvme_ns_flush(nvme_ns_t n) +{ + return nvme_flush(nvme_ns_get_fd(n), nvme_ns_get_nsid(n)); +} + +static void nvme_free_ns(struct nvme_ns *n) +{ + close(n->fd); + free(n->name); + free(n->sysfs_dir); + free(n); +} + +void nvme_ctrl_free_ns(struct nvme_ns *n) +{ + TAILQ_REMOVE(&n->s->namespaces, n, entry); + nvme_free_ns(n); +} + +void nvme_subsystem_free_ns(struct nvme_ns *n) +{ + TAILQ_REMOVE(&n->s->namespaces, n, entry); + nvme_free_ns(n); +} + +static void nvme_ns_init(struct nvme_ns *n) +{ + struct nvme_id_ns ns = { 0 }; + + if (nvme_ns_identify(n, &ns) != 0) + return; + + n->lba_size = 1 << ns.lbaf[ns.flbas & NVME_NS_FLBAS_LBA_MASK].ds; + n->lba_count = le64_to_cpu(ns.nsze); + n->lba_util = le64_to_cpu(ns.nuse); +} + +static struct nvme_ns *__nvme_scan_namespace(const char *sysfs_dir, char *name) +{ + struct nvme_ns *n; + char *path; + int ret; + + ret = asprintf(&path, "%s/%s", sysfs_dir, name); + if (ret < 0) { + errno = ENOMEM; + return NULL; + } + + n = malloc(sizeof(*n)); + if (!n) { + errno = ENOMEM; + goto free_path; + } + memset(n, 0, sizeof(*n)); + + n->name = strdup(name); + n->sysfs_dir = path; + n->fd = nvme_open(name); + if (n->fd < 0) + goto free_ns; + + n->nsid = nvme_get_nsid(n->fd); + if (n->nsid < 0) + goto close_fd; + + TAILQ_INIT(&n->paths); + nvme_ns_init(n); + + return n; + +close_fd: + close(n->fd); +free_ns: + free(n); +free_path: + free(path); + return NULL; +} + +int nvme_ctrl_scan_namespace(struct nvme_ctrl *c, char *name) +{ + struct nvme_ns *n; + + n = __nvme_scan_namespace(c->sysfs_dir, name); + if (!n) + return -1; + + n->s = c->s; + n->c = c; + TAILQ_INSERT_TAIL(&c->namespaces, n, entry); + return 0; +} + +int nvme_subsystem_scan_namespace(struct nvme_subsystem *s, char *name) +{ + struct nvme_ns *n; + + n = __nvme_scan_namespace(s->sysfs_dir, name); + if (!n) + return -1; + + n->s = s; + TAILQ_INSERT_TAIL(&s->namespaces, n, entry); + return 0; +} diff --git a/lib/nvme/tree.h b/lib/nvme/tree.h new file mode 100644 index 0000000000..b5f53856b2 --- /dev/null +++ b/lib/nvme/tree.h @@ -0,0 +1,182 @@ +#ifndef _LIBNVME_TREE_H +#define _LIBNVME_TREE_H + +#include +#include + +#include + +#include "ioctl.h" +#include "util.h" + +extern const char *nvme_ctrl_sysfs_dir; +extern const char *nvme_subsys_sysfs_dir; + +typedef struct nvme_ns *nvme_ns_t; +typedef struct nvme_path *nvme_path_t; +typedef struct nvme_ctrl *nvme_ctrl_t; +typedef struct nvme_subsystem *nvme_subsystem_t; +typedef struct nvme_root *nvme_root_t; + +nvme_subsystem_t nvme_first_subsystem(nvme_root_t r); +nvme_subsystem_t nvme_next_subsystem(nvme_root_t r, nvme_subsystem_t s); + +nvme_ns_t nvme_ctrl_first_ns(nvme_ctrl_t c); +nvme_ns_t nvme_ctrl_next_ns(nvme_ctrl_t c, nvme_ns_t n); + +nvme_path_t nvme_ctrl_first_path(nvme_ctrl_t c); +nvme_path_t nvme_ctrl_next_path(nvme_ctrl_t c, nvme_path_t p); + +nvme_ctrl_t nvme_subsystem_first_ctrl(nvme_subsystem_t s); +nvme_ctrl_t nvme_subsystem_next_ctrl(nvme_subsystem_t s, nvme_ctrl_t c); + +nvme_ns_t nvme_subsystem_first_ns(nvme_subsystem_t s); +nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n); + +#define nvme_for_each_subsystem_safe(r, s, _s) \ + for (s = nvme_first_subsystem(r), \ + _s = nvme_next_subsystem(r, s); \ + s != NULL; \ + s = _s, _s = nvme_next_subsystem(r, s)) + +#define nvme_for_each_subsystem(r, s) \ + for (s = nvme_first_subsystem(r); s != NULL; \ + s = nvme_next_subsystem(r, s)) + +#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 = _c, _c = nvme_subsystem_next_ctrl(s, c)) + +#define nvme_subsystem_for_each_ctrl(s, c) \ + for (c = nvme_subsystem_first_ctrl(s); c != NULL; \ + c = nvme_subsystem_next_ctrl(s, c)) + +#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 = _n, _n = nvme_ctrl_next_ns(c, n)) + +#define nvme_ctrl_for_each_ns(c, n) \ + for (n = nvme_ctrl_first_ns(c); n != NULL; \ + n = nvme_ctrl_next_ns(c, 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 = _p, _p = nvme_ctrl_next_path(c, p)) + +#define nvme_ctrl_for_each_path(c, p) \ + for (p = nvme_ctrl_first_path(c); p != NULL; \ + p = nvme_ctrl_next_path(c, p)) + +#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 = _n, _n = nvme_subsystem_next_ns(s, n)) + +#define nvme_subsystem_for_each_ns(s, n) \ + for (n = nvme_subsystem_first_ns(s); n != NULL; \ + n = nvme_subsystem_next_ns(s, n)) + +int nvme_ns_get_fd(nvme_ns_t n); +int nvme_ns_get_nsid(nvme_ns_t n); +int nvme_ns_get_lba_size(nvme_ns_t n); +uint64_t nvme_ns_get_lba_count(nvme_ns_t n); +uint64_t nvme_ns_get_lba_util(nvme_ns_t n); +const char *nvme_ns_get_sysfs_dir(nvme_ns_t n); +const char *nvme_ns_get_name(nvme_ns_t n); +nvme_subsystem_t nvme_ns_get_subsystem(nvme_ns_t n); +nvme_ctrl_t nvme_ns_get_ctrl(nvme_ns_t n); + +/** + * nvme_ns_read() - + */ +int nvme_ns_read(nvme_ns_t n, void *buf, off_t offset, size_t count); + +/** + * nvme_ns_write() - + */ +int nvme_ns_write(nvme_ns_t n, void *buf, off_t offset, size_t count); + +/** + * nvme_ns_verify() - + */ +int nvme_ns_verify(nvme_ns_t n, off_t offset, size_t count); + +/** + * nvme_ns_compare() - + */ +int nvme_ns_compare(nvme_ns_t n, void *buf, off_t offset, size_t count); + +/** + * nvme_ns_write_zeros() - + */ +int nvme_ns_write_zeros(nvme_ns_t n, off_t offset, size_t count); + +/** + * nvme_ns_write_uncorrectable() - + */ +int nvme_ns_write_uncorrectable(nvme_ns_t n, off_t offset, size_t count); + +/** + * nvme_ns_flush() - + */ +int nvme_ns_flush(nvme_ns_t n); + +/** + * nvme_ns_identify() - + */ +int nvme_ns_identify(nvme_ns_t n, struct nvme_id_ns *ns); + +const char *nvme_path_get_name(nvme_path_t p); +const char *nvme_path_get_sysfs_dir(nvme_path_t p); +const char *nvme_path_get_ana_state(nvme_path_t p); +nvme_ctrl_t nvme_path_get_subsystem(nvme_path_t p); +nvme_ns_t nvme_path_get_ns(nvme_path_t p); + +int nvme_ctrl_get_fd(nvme_ctrl_t c); +const char *nvme_ctrl_get_name(nvme_ctrl_t c); +const char *nvme_ctrl_get_sysfs_dir(nvme_ctrl_t c); +const char *nvme_ctrl_get_address(nvme_ctrl_t c); +const char *nvme_ctrl_get_firmware(nvme_ctrl_t c); +const char *nvme_ctrl_get_model(nvme_ctrl_t c); +const char *nvme_ctrl_get_state(nvme_ctrl_t c); +const char *nvme_ctrl_get_numa_node(nvme_ctrl_t c); +const char *nvme_ctrl_get_queue_count(nvme_ctrl_t c); +const char *nvme_ctrl_get_serial(nvme_ctrl_t c); +const char *nvme_ctrl_get_sqsize(nvme_ctrl_t c); +const char *nvme_ctrl_get_transport(nvme_ctrl_t c); +const char *nvme_ctrl_get_nqn(nvme_ctrl_t c); +const char *nvme_ctrl_get_subsysnqn(nvme_ctrl_t c); +nvme_subsystem_t nvme_ctrl_get_subsystem(nvme_ctrl_t c); + +int nvme_ctrl_identify(nvme_ctrl_t c, struct nvme_id_ctrl *id); +int nvme_ctrl_disconnect(nvme_ctrl_t c); +nvme_ctrl_t nvme_scan_ctrl(const char *name); + +void nvme_free_ctrl(struct nvme_ctrl *c); +void nvme_unlink_ctrl(struct nvme_ctrl *c); + +const char *nvme_subsystem_get_nqn(nvme_subsystem_t s); +const char *nvme_subsystem_get_sysfs_dir(nvme_subsystem_t s); +const char *nvme_subsystem_get_name(nvme_subsystem_t s); + +typedef bool (*nvme_scan_filter_t)(nvme_subsystem_t); +nvme_root_t nvme_scan_filter(nvme_scan_filter_t f); + +nvme_root_t nvme_scan(); +void nvme_refresh_topology(nvme_root_t r); +void nvme_reset_topology(nvme_root_t r); +void nvme_free_tree(nvme_root_t r); + +char *nvme_get_subsys_attr(nvme_subsystem_t s, const char *attr); +char *nvme_get_ctrl_attr(nvme_ctrl_t c, const char *attr); +char *nvme_get_ns_attr(nvme_ns_t n, const char *attr); +char *nvme_get_path_attr(nvme_path_t p, const char *attr); + +#endif /* _LIBNVME_TREE_H */ diff --git a/lib/nvme/types.h b/lib/nvme/types.h new file mode 100644 index 0000000000..17d6851273 --- /dev/null +++ b/lib/nvme/types.h @@ -0,0 +1,2430 @@ +#ifndef _LIBNVME_TYPES_H +#define _LIBNVME_TYPES_H + +#include +#include +#include + +#include + +#ifdef __CHECKER__ +#define __force __attribute__((force)) +#else +#define __force +#endif + +static inline __le16 cpu_to_le16(uint16_t x) { return (__force __le16)htole16(x); } +static inline __le32 cpu_to_le32(uint32_t x) { return (__force __le32)htole32(x); } +static inline __le64 cpu_to_le64(uint64_t x) { return (__force __le64)htole64(x); } +static inline uint16_t le16_to_cpu(__le16 x) { return le16toh((__force __u16)x); } +static inline uint32_t le32_to_cpu(__le32 x) { return le32toh((__force __u32)x); } +static inline uint64_t le64_to_cpu(__le64 x) { return le64toh((__force __u64)x); } + +/** + * enum nvme_constants - + * @NVME_NSID_ALL: + * @NVME_NSID_NONE: + * @NVME_UUID_NONE: + * @NVME_CNTLID_NONE: + * @NVME_NVMSETID_NONE: + * @NVME_LOG_LSP_NONE: + * @NVME_LOG_LSI_NONE: + * @NVME_IDENTIFY_DATA_SIZE: + * @NVME_ID_NVMSET_LIST_MAX: + * @NVME_ID_UUID_LIST_MAX: + * @NVME_ID_CTRL_LIST_MAX: + * @NVME_ID_NS_LIST_MAX: + * @NVME_ID_SECONDARY_CTRL_MAX: + * @NVME_FEAT_LBA_RANGE_MAX: + * @NVME_LOG_ST_MAX_RESULTS: + * @NVME_DSM_MAX_RANGES: + */ +enum nvme_constants { + NVME_NSID_ALL = 0xffffffff, + NVME_NSID_NONE = 0, + NVME_UUID_NONE = 0, + NVME_CNTLID_NONE = 0, + NVME_NVMSETID_NONE = 0, + NVME_LOG_LSP_NONE = 0, + NVME_LOG_LSI_NONE = 0, + NVME_IDENTIFY_DATA_SIZE = 4096, + NVME_ID_NVMSET_LIST_MAX = 31, + NVME_ID_UUID_LIST_MAX = 127, + NVME_ID_CTRL_LIST_MAX = 2047, + NVME_ID_NS_LIST_MAX = 1024, + NVME_ID_SECONDARY_CTRL_MAX = 127, + NVME_FEAT_LBA_RANGE_MAX = 64, + NVME_LOG_ST_MAX_RESULTS = 20, + NVME_DSM_MAX_RANGES = 256, +}; + +/** + * DOC: NVMe controller registers/properties + */ + +/** + * enum nvme_registers - + * @NVME_REG_CAP: Controller Capabilities + * @NVME_REG_VS: Version + * @NVME_REG_INTMS: Interrupt Mask Set + * @NVME_REG_INTMC: Interrupt Mask Clear + * @NVME_REG_CC: Controller Configuration + * @NVME_REG_CSTS: Controller Status + * @NVME_REG_NSSR: NVM Subsystem Reset + * @NVME_REG_AQA: Admin Queue Attributes + * @NVME_REG_ASQ: Admin SQ Base Address + * @NVME_REG_ACQ: Admin CQ Base Address + * @NVME_REG_CMBLOC: Controller Memory Buffer Location + * @NVME_REG_CMBSZ: Controller Memory Buffer Size + * @NVME_REG_BPINFO: Boot Partition Information + * @NVME_REG_BPRSEL: Boot Partition Read Select + * @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_PMRCAP: Persistent Memory Capabilities + * @NVME_REG_PMRCTL: Persistent Memory Region Control + * @NVME_REG_PMRSTS: Persistent Memory Region Status + * @NVME_REG_PMREBS: Persistent Memory Region Elasticity Buffer Size + * @NVME_REG_PMRSWTP: Memory Region Sustained Write Throughput + * @NVME_REG_PMRMSC: Persistent Memory Region Controller Memory Space Control + * @NVME_REG_DBS: SQ 0 Tail Doorbell + */ +enum nvme_registers { + NVME_REG_CAP = 0x0000, + NVME_REG_VS = 0x0008, + NVME_REG_INTMS = 0x000c, + NVME_REG_INTMC = 0x0010, + NVME_REG_CC = 0x0014, + NVME_REG_CSTS = 0x001c, + NVME_REG_NSSR = 0x0020, + NVME_REG_AQA = 0x0024, + NVME_REG_ASQ = 0x0028, + NVME_REG_ACQ = 0x0030, + 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_PMRSWTP= 0x0e10, + NVME_REG_PMRMSC = 0x0e14, + NVME_REG_DBS = 0x1000, +}; + +#define NVME_CAP_MQES(cap) ((cap) & 0xffff) +#define NVME_CAP_CQR(cap) (((cap) >> 16) & 0x1) +#define NVME_CAP_AMS(cap) (((cap) >> 17) & 0x3) +#define NVME_CAP_TIMEOUT(cap) (((cap) >> 24) & 0xff) +#define NVME_CAP_STRIDE(cap) (((cap) >> 32) & 0xf) +#define NVME_CAP_NSSRC(cap) (((cap) >> 36) & 0x1) +#define NVME_CAP_CSS(cap) (((cap) >> 37) & 0xff) +#define NVME_CAP_BPS(cap) (((cap) >> 45) & 0x1) +#define NVME_CAP_MPSMIN(cap) (((cap) >> 48) & 0xf) +#define NVME_CAP_MPSMAX(cap) (((cap) >> 52) & 0xf) +#define NVME_CAP_CMBS(cap) (((cap) >> 57) & 1) +#define NVME_CAP_PMRS(cap) (((cap) >> 56) & 1) + +#define NVME_CMB_BIR(cmbloc) ((cmbloc) & 0x7) +#define NVME_CMB_OFST(cmbloc) (((cmbloc) >> 12) & 0xfffff) +#define NVME_CMB_SZ(cmbsz) (((cmbsz) >> 12) & 0xfffff) +#define NVME_CMB_SZU(cmbsz) (((cmbsz) >> 8) & 0xf) + +#define NVME_CMB_WDS(cmbsz) ((cmbsz) & 0x10) +#define NVME_CMB_RDS(cmbsz) ((cmbsz) & 0x8) +#define NVME_CMB_LISTS(cmbsz) ((cmbsz) & 0x4) +#define NVME_CMB_CQS(cmbsz) ((cmbsz) & 0x2) +#define NVME_CMB_SQS(cmbsz) ((cmbsz) & 0x1) + +/** + * enum - + */ +enum { + NVME_CC_ENABLE = 1 << 0, + NVME_CC_CSS_NVM = 0 << 4, + NVME_CC_EN_SHIFT = 0, + NVME_CC_CSS_SHIFT = 4, + NVME_CC_MPS_SHIFT = 7, + NVME_CC_AMS_SHIFT = 11, + NVME_CC_SHN_SHIFT = 14, + NVME_CC_IOSQES_SHIFT = 16, + NVME_CC_IOCQES_SHIFT = 20, + NVME_CC_AMS_RR = 0 << NVME_CC_AMS_SHIFT, + NVME_CC_AMS_WRRU = 1 << NVME_CC_AMS_SHIFT, + NVME_CC_AMS_VS = 7 << NVME_CC_AMS_SHIFT, + NVME_CC_SHN_NONE = 0 << NVME_CC_SHN_SHIFT, + NVME_CC_SHN_NORMAL = 1 << NVME_CC_SHN_SHIFT, + NVME_CC_SHN_ABRUPT = 2 << NVME_CC_SHN_SHIFT, + NVME_CC_SHN_MASK = 3 << NVME_CC_SHN_SHIFT, + NVME_CSTS_RDY = 1 << 0, + NVME_CSTS_CFS = 1 << 1, + NVME_CSTS_NSSRO = 1 << 4, + NVME_CSTS_PP = 1 << 5, + NVME_CSTS_SHST_NORMAL = 0 << 2, + NVME_CSTS_SHST_OCCUR = 1 << 2, + NVME_CSTS_SHST_CMPLT = 2 << 2, + NVME_CSTS_SHST_MASK = 3 << 2, +}; + +/* + * is_64bit_reg() - Checks if offset of the controller register is 64bit or not. + * @offset: Offset of controller register field in bytes + * + * This function does not care about transport so that the offset is not going + * to be checked inside of this function for the unsupported fields in a + * specific transport. For example, BPMBL(Boot Partition Memory Buffer + * Location) register is not supported by fabrics, but it can be chcked here. + * + * Returns true if given offset is 64bit register, otherwise it returns false. + */ +static inline bool is_64bit_reg(__u32 offset) +{ + switch (offset) { + case NVME_REG_CAP: + case NVME_REG_ASQ: + case NVME_REG_ACQ: + case NVME_REG_BPMBL: + return true; + default: + return false; + } +} + +/** + * DOC: NVMe Identify + */ + +/** + * struct nvme_id_psd - + * @mp: + * @flags: + * @enlat: + * @exlat: + * @rrt: + * @rrl: + * @rwt: + * @rwl: + * @idlp: + * @ips: + * @actp: + * @apw: + * @aps: + */ +struct nvme_id_psd { + __le16 mp; + __u8 rsvd2; + __u8 flags; + __le32 enlat; + __le32 exlat; + __u8 rrt; + __u8 rrl; + __u8 rwt; + __u8 rwl; + __le16 idlp; + __u8 ips; + __u8 rsvd19; + __le16 actp; + __u8 apw; + __u8 aps; + __u8 rsvd23[8]; +}; + +/** + * nvme_psd_power_scale() - power scale occupies the upper 3 bits + */ +static inline unsigned nvme_psd_power_scale(__u8 ps) +{ + return ps >> 6; +} + +/** + * enum - + * @NVME_PSD_FLAGS_MAX_POWER_SCALE: + * @NVME_PSD_FLAGS_NON_OP_STATE: + * @NVME_PSD_RELATIVE_MASK: + * @NVME_PSD_APW_MASK: + */ +enum { + NVME_PSD_FLAGS_MAX_POWER_SCALE = 1 << 0, + NVME_PSD_FLAGS_NON_OP_STATE = 1 << 1, + NVME_PSD_RELATIVE_MASK = 0x1f, + NVME_PSD_APW_MASK = 0x7, +}; + +/** + * struct nvme_id_ctrl - Identify Controller data structure + * @vid: Vendor ID + * @ssvid: Subsystem Vendor Id + * @sn: Serial Number + * @mn: Model Number + * @fr: Firmware Revision + * @rab: Recommended Arbitration Burst + * @ieee: IEEE + * @cmic: Controller Mulitpathing Capabilities + * @mdts: Max Data Transfer Size + * @cntlid: Controller Identifier + * @ver: Version + * @rtd3r: Runtime D3 Resume + * @rtd3e: Runtime D3 Exit + * @oaes: Optional Async Events Supported + * @ctratt: Controller Attributes + * @rrls: Read Recovery Levels + * @cntrltype: Controller Type + * @fguid: FRU GUID + * @crdt1: Controller Retry Delay 1 + * @crdt2: Controller Retry Delay 2 + * @crdt3: Controller Retry Delay 3 + * @nvmsr: + * @vwci: + * @mec: + * @oacs: Optional Admin Commands Supported + * @acl: Abort Command Limit + * @aerl: Async Event Request Limit + * @frmw: + * @lpa: Log Page Attributes + * @elpe: + * @npss: Number of Power States Supported + * @avscc: + * @apsta: + * @wctemp: + * @cctemp: + * @mtfa: + * @hmpre: + * @hmmin: + * @tnvmcap: + * @unvmcap: + * @rpmbs: + * @edstt: + * @dsto: + * @fwug: + * @kas: + * @hctma: + * @mntmt: + * @mxtmt: + * @sanicap: + * @hmminds: + * @hmmaxd: + * @nsetidmax: + * @endgidmax: + * @anatt: + * @anacap: + * @anagrpmax: + * @nanagrpid: + * @pels: + * @sqes: + * @cqes: + * @maxcmd: + * @nn: + * @onc: + * @fuses: + * @fna: + * @vwc: + * @awun: + * @awupf: + * @nvscc: + * @nwpc: + * @acwu: + * @sgls: + * @mnan: + * @subnqn: + * @ioccsz: + * @iorcsz: + * @icdoff: + * @fcatt: + * @msdbd: + * @ofcs: + * @psd: + * @vs: + */ +struct nvme_id_ctrl { + __le16 vid; + __le16 ssvid; + char sn[20]; + char mn[40]; + char fr[8]; + __u8 rab; + __u8 ieee[3]; + __u8 cmic; + __u8 mdts; + __le16 cntlid; + __le32 ver; + __le32 rtd3r; + __le32 rtd3e; + __le32 oaes; + __le32 ctratt; + __le16 rrls; + __u8 rsvd102[9]; + __u8 cntrltype; + __u8 fguid[16]; + __le16 crdt1; + __le16 crdt2; + __le16 crdt3; + __u8 rsvd134[119]; + __u8 nvmsr; + __u8 vwci; + __u8 mec; + __le16 oacs; + __u8 acl; + __u8 aerl; + __u8 frmw; + __u8 lpa; + __u8 elpe; + __u8 npss; + __u8 avscc; + __u8 apsta; + __le16 wctemp; + __le16 cctemp; + __le16 mtfa; + __le32 hmpre; + __le32 hmmin; + __u8 tnvmcap[16]; + __u8 unvmcap[16]; + __le32 rpmbs; + __le16 edstt; + __u8 dsto; + __u8 fwug; + __le16 kas; + __le16 hctma; + __le16 mntmt; + __le16 mxtmt; + __le32 sanicap; + __le32 hmminds; + __le16 hmmaxd; + __le16 nsetidmax; + __le16 endgidmax; + __u8 anatt; + __u8 anacap; + __le32 anagrpmax; + __le32 nanagrpid; + __le32 pels; + __u8 rsvd356[156]; + __u8 sqes; + __u8 cqes; + __le16 maxcmd; + __le32 nn; + __le16 oncs; + __le16 fuses; + __u8 fna; + __u8 vwc; + __le16 awun; + __le16 awupf; + __u8 nvscc; + __u8 nwpc; + __le16 acwu; + __u8 rsvd534[2]; + __le32 sgls; + __le32 mnan; + __u8 rsvd544[224]; + char subnqn[256]; + __u8 rsvd1024[768]; + + /* Fabrics Only */ + __le32 ioccsz; + __le32 iorcsz; + __le16 icdoff; + __u8 fcatt; + __u8 msdbd; + __le16 ofcs; + __u8 rsvd1806[242]; + + struct nvme_id_psd psd[32]; + __u8 vs[1024]; +}; + +/** + * enum - + */ +enum { + NVME_CTRL_CMIC_MULTI_PORT = 1 << 0, + NVME_CTRL_CMIC_MULTI_CTRL = 1 << 1, + NVME_CTRL_CMIC_MULTI_SRIOV = 1 << 2, + NVME_CTRL_CMIC_MULTI_ANA_REPORTING = 1 << 3, +}; + +/** + * enum - + */ +enum { + NVME_CTRL_OAES_NA = 1 << 8, + NVME_CTRL_OAES_FA = 1 << 9, + NVME_CTRL_OAES_ANA = 1 << 11, + NVME_CTRL_OAES_PLEA = 1 << 12, + NVME_CTRL_OAES_LBAS = 1 << 13, + NVME_CTRL_OAES_EGE = 1 << 14, +}; + +/** + * enum - + */ +enum { + NVME_CTRL_CTRATT_128_ID = 1 << 0, + NVME_CTRL_CTRATT_NON_OP_PSP = 1 << 1, + NVME_CTRL_CTRATT_NVM_SETS = 1 << 2, + NVME_CTRL_CTRATT_READ_RECV_LVLS = 1 << 3, + NVME_CTRL_CTRATT_ENDURANCE_GROUPS = 1 << 4, + NVME_CTRL_CTRATT_PREDICTABLE_LAT = 1 << 5, + NVME_CTRL_CTRATT_TBKAS = 1 << 6, + NVME_CTRL_CTRATT_NAMESPACE_GRANULARITY = 1 << 7, + NVME_CTRL_CTRATT_SQ_ASSOCIATIONS = 1 << 8, + NVME_CTRL_CTRATT_UUID_LIST = 1 << 9, +}; + +/** + * enum - + */ +enum { + NVME_CTRL_CNTRLTYPE_RESERVED = 0, + NVME_CTRL_CNTRLTYPE_IO = 1, + NVME_CTRL_CNTRLTYPE_DISCOVERY = 2, + NVME_CTRL_CNTRLTYPE_ADMIN = 3, +}; + +/** + * enum - + */ +enum { + NVME_CTRL_NVMSR_NVMESD = 1 << 0, + NVME_CTRL_NVMSR_NVMEE = 1 << 1, +}; + +/** + * enum - + */ +enum { + NVME_CTRL_VWCI_VWCR = 0x7f << 0, + NVME_CTRL_VWCI_VWCRV = 1 << 7, +}; + +/** + * enum - + */ +enum { + NVME_CTRL_MEC_SMBUSME = 1 << 0, + NVME_CTRL_MEC_PCIEME = 1 << 1, +}; + +/** + * enum - + */ +enum { + NVME_CTRL_OACS_SECURITY = 1 << 0, + NVME_CTRL_OACS_FORMAT = 1 << 1, + NVME_CTRL_OACS_FW = 1 << 2, + NVME_CTRL_OACS_NS_MGMT = 1 << 3, + NVME_CTRL_OACS_SELF_TEST = 1 << 4, + NVME_CTRL_OACS_DIRECTIVES = 1 << 5, + NVME_CTRL_OACS_NVME_MI = 1 << 6, + NVME_CTRL_OACS_VIRT_MGMT = 1 << 7, + NVME_CTRL_OACS_DBBUF_CFG = 1 << 8, + NVME_CTRL_OACS_LBA_STATUS = 1 << 9, +}; + +/** + * enum - + */ +enum { + NVME_CTRL_FRMW_1ST_RO = 1 << 0, + NVME_CTRL_FRMW_NR_SLOTS = 3 << 1, + NVME_CTRL_FRMW_FW_ACT_NO_RESET = 1 << 4, +}; + +/** + * enum - + */ +enum { + NVME_CTRL_LPA_SMART_PER_NS = 1 << 0, + NVME_CTRL_LPA_CMD_EFFECTS = 1 << 1, + NVME_CTRL_LPA_EXTENDED = 1 << 2, + NVME_CTRL_LPA_TELEMETRY = 1 << 3, + NVME_CTRL_LPA_PERSETENT_EVENT = 1 << 4, +}; + +/** + * enum - + */ +enum { + NVME_CTRL_AVSCC_AVS = 1 << 0, +}; + +/** + * enum - + */ +enum { + NVME_CTRL_APSTA_APST = 1 << 0, +}; + +/** + * enum - + */ +enum { + NVME_CTRL_RPMBS_NR_UNITS = 7 << 0, + NVME_CTRL_RPMBS_AUTH_METHOD = 7 << 3, + NVME_CTRL_RPMBS_TOTAL_SIZE = 255 << 16, + NVME_CTRL_RPMBS_ACCESS_SIZE = 255 << 24, +}; + +/** + * enum - + */ +enum { + NVME_CTRL_DSTO_ONE_DST = 1 << 0, +}; + +/** + * enum - + */ +enum { + NVME_CTRL_HCTMA_HCTM = 1 << 0, +}; + +/** + * enum - + */ +enum { + NVME_CTRL_SANICAP_CES = 1 << 0, + NVME_CTRL_SANICAP_BES = 1 << 1, + NVME_CTRL_SANICAP_OWS = 1 << 2, + NVME_CTRL_SANICAP_NDI = 1 << 29, + NVME_CTRL_SANICAP_NODMMAS = 3 << 30, +}; + +/** + * enum - + */ +enum { + NVME_CTRL_ANACAP_OPT = 1 << 0, + NVME_CTRL_ANACAP_NON_OPT = 1 << 1, + NVME_CTRL_ANACAP_INACCESSIBLE = 1 << 2, + NVME_CTRL_ANACAP_PERSISTENT_LOSS = 1 << 3, + NVME_CTRL_ANACAP_CHANGE = 1 << 4, + NVME_CTRL_ANACAP_GRPID_NO_CHG = 1 << 6, + NVME_CTRL_ANACAP_GRPID_MGMT = 1 << 7, +}; + +/** + * enum - + */ +enum { + NVME_CTRL_SQES_MIN = 15 << 0, + NVME_CTRL_SQES_MAX = 15 << 4, +}; + +/** + * enum - + */ +enum { + NVME_CTRL_CQES_MIN = 15 << 0, + NVME_CTRL_CQES_MAX = 15 << 4, +}; + +/** + * enum - + */ +enum { + NVME_CTRL_ONCS_COMPARE = 1 << 0, + NVME_CTRL_ONCS_WRITE_UNCORRECTABLE = 1 << 1, + NVME_CTRL_ONCS_DSM = 1 << 2, + NVME_CTRL_ONCS_WRITE_ZEROES = 1 << 3, + NVME_CTRL_ONCS_SAVE_FEATURES = 1 << 4, + NVME_CTRL_ONCS_RESERVATIONS = 1 << 5, + NVME_CTRL_ONCS_TIMESTAMP = 1 << 6, + NVME_CTRL_ONCS_VERIFY = 1 << 7, +}; + +/** + * enum - + */ +enum { + NVME_CTRL_FUSES_COMPARE_AND_WRITE = 1 << 0, +}; + +/** + * enum - + */ +enum { + NVME_CTRL_FNA_FMT_ALL_NAMESPACES = 1 << 0, + NVME_CTRL_FNA_SEC_ALL_NAMESPACES = 1 << 1, + NVME_CTRL_FNA_CRYPTO_ERASE = 1 << 2, +}; + +/** + * enum - + */ +enum { + NVME_CTRL_VWC_PRESENT = 1 << 0, + NVME_CTRL_VWC_FLUSH = 3 << 1, +}; + +/** + * enum - + */ +enum { + NVME_CTRL_NVSCC_FMT = 1 << 0, +}; + +/** + * enum - + */ +enum { + NVME_CTRL_NWPC_WRITE_PROTECT = 1 << 0, + NVME_CTRL_NWPC_WRITE_PROTECT_POWER_CYCLE= 1 << 1, + NVME_CTRL_NWPC_WRITE_PROTECT_PERMANENT = 1 << 2, +}; + +/** + * enum - + */ +enum { + NVME_CTRL_SGLS_SUPPORTED = 3 << 0, + NVME_CTRL_SGLS_KEYED = 1 << 2, + NVME_CTRL_SGLS_BIT_BUCKET = 1 << 16, + NVME_CTRL_SGLS_MPTR_BYTE_ALIGNED = 1 << 17, + NVME_CTRL_SGLS_OVERSIZE = 1 << 18, + NVME_CTRL_SGLS_MPTR_SGL = 1 << 19, + NVME_CTRL_SGLS_OFFSET = 1 << 20, + NVME_CTRL_SGLS_TPORT = 1 << 21, +}; + +/** + * enum - + */ +enum { + NVME_CTRL_FCATT_DYNAMIC = 1 << 0, +}; + +/** + * enum - + */ +enum { + NVME_CTRL_OFCS_DISCONNECT = 1 << 0, +}; + +/** + * struct nvme_lbaf - + * @ms: + * @ds: + * @rp: + */ +struct nvme_lbaf { + __le16 ms; + __u8 ds; + __u8 rp; +}; + +/** + * enum - + * @NVME_LBAF_RP_BEST: + * @NVME_LBAF_RP_BETTER: + * @NVME_LBAF_RP_GOOD: + * @NVME_LBAF_RP_DEGRADED: + */ +enum { + NVME_LBAF_RP_BEST = 0, + NVME_LBAF_RP_BETTER = 1, + NVME_LBAF_RP_GOOD = 2, + NVME_LBAF_RP_DEGRADED = 3, + NVME_LBAF_RP_MASK = 3, +}; + +/** + * struct nvme_id_ns - + * @nsze: + * @ncap: + * @nuse: + * @nsfeat: + * @nlbaf: + * @flbas: + * @mc: + * @dpc: + * @dps: + * @nmic: + * @rescap: + * @fpi: + * @dlfeat: + * @nawun: + * @nawupf: + * @nacwu: + * @nabsn: + * @nabo: + * @nabspf: + * @noiob: + * @nvmcap: + * @npwg: + * @npwa: + * @npdg: + * @npda: + * @nows: + * @anagrpid: + * @nsattr: + * @nvmsetid: + * @endgid: + * @nguid: + * @eui64: + * @lbaf: + * @vs: + */ +struct nvme_id_ns { + __le64 nsze; + __le64 ncap; + __le64 nuse; + __u8 nsfeat; + __u8 nlbaf; + __u8 flbas; + __u8 mc; + __u8 dpc; + __u8 dps; + __u8 nmic; + __u8 rescap; + __u8 fpi; + __u8 dlfeat; + __le16 nawun; + __le16 nawupf; + __le16 nacwu; + __le16 nabsn; + __le16 nabo; + __le16 nabspf; + __le16 noiob; + __u8 nvmcap[16]; + __le16 npwg; + __le16 npwa; + __le16 npdg; + __le16 npda; + __le16 nows; + __u8 rsvd74[18]; + __le32 anagrpid; + __u8 rsvd96[3]; + __u8 nsattr; + __le16 nvmsetid; + __le16 endgid; + __u8 nguid[16]; + __u8 eui64[8]; + struct nvme_lbaf lbaf[16]; + __u8 rsvd192[192]; + __u8 vs[3712]; +}; + +/** + * enum - + */ +enum { + NVME_NS_FEAT_THIN = 1 << 0, + NVME_NS_FEAT_NATOMIC = 1 << 1, + NVME_NS_FEAT_DULBE = 1 << 2, + NVME_NS_FEAT_ID_REUSE = 1 << 3, + NVME_NS_FEAT_IO_OPT = 1 << 4, +}; + +/** + * enum - + */ +enum { + NVME_NS_FLBAS_LBA_MASK = 15 << 0, + NVME_NS_FLBAS_META_EXT = 1 << 4, +}; + +/** + * enum - + */ +enum { + NVME_NS_MC_EXTENDED = 1 << 0, + NVME_NS_MC_SEPARATE = 1 << 1, +}; + +/** + * enum - + */ +enum { + NVME_NS_DPC_PI_TYPE1 = 1 << 0, + NVME_NS_DPC_PI_TYPE2 = 1 << 1, + NVME_NS_DPC_PI_TYPE3 = 1 << 2, + NVME_NS_DPC_PI_FIRST = 1 << 3, + NVME_NS_DPC_PI_LAST = 1 << 4, +}; + +/** + * enum - + */ +enum { + NVME_NS_DPS_PI_NONE = 0, + NVME_NS_DPS_PI_TYPE1 = 1, + NVME_NS_DPS_PI_TYPE2 = 2, + NVME_NS_DPS_PI_TYPE3 = 3, + NVME_NS_DPS_PI_MASK = 7 << 0, + NVME_NS_DPS_PI_FIRST = 1 << 3, +}; + +/** + * enum - + */ +enum { + NVME_NS_NMIC_SHARED = 1 << 0, +}; + +/** + * enum - + */ +enum { + NVME_NS_RESCAP_PTPL = 1 << 0, + NVME_NS_RESCAP_WE = 1 << 1, + NVME_NS_RESCAP_EA = 1 << 2, + NVME_NS_RESCAP_WERO = 1 << 3, + NVME_NS_RESCAP_EARO = 1 << 4, + NVME_NS_RESCAP_WEAR = 1 << 5, + NVME_NS_RESCAP_EAAR = 1 << 6, + NVME_NS_RESCAP_IEK_13 = 1 << 7, +}; + +/** + * enum - + */ +enum { + NVME_NS_FPI_REMAINING = 127 << 0, + NVME_NS_FPI_SUPPORTED = 1 << 7, +}; + +/** + * enum - + */ +enum { + NVME_NS_DLFEAT_RB = 7 << 0, + NVME_NS_DLFEAT_RB_NR = 0, + NVME_NS_DLFEAT_RB_ALL_0S = 1, + NVME_NS_DLFEAT_RB_ALL_FS = 2, + NVME_NS_DLFEAT_WRITE_ZEROES = 1 << 3, + NVME_NS_DLFEAT_CRC_GUARD = 1 << 4, +}; + +/** + * enum - + */ +enum { + NVME_NS_NSATTR_WRITE_PROTECTED = 1 << 0 +}; + +/** + * struct nvme_ns_id_desc - + */ +struct nvme_ns_id_desc { + __u8 nidt; + __u8 nidl; + __le16 reserved; + __u8 nid[]; +}; + +/** + * enum - + */ +enum { + NVME_NIDT_EUI64 = 1, + NVME_NIDT_NGUID = 2, + NVME_NIDT_UUID = 3, +}; + +/** + * struct nvme_nvmset_attr - + */ +struct nvme_nvmset_attr { + __le16 id; + __le16 endurance_group_id; + __u8 rsvd4[4]; + __le32 random_4k_read_typical; + __le32 opt_write_size; + __u8 total_nvmset_cap[16]; + __u8 unalloc_nvmset_cap[16]; + __u8 rsvd48[80]; +}; + +/** + * struct nvme_id_nvmset_list - + */ +struct nvme_id_nvmset_list { + __u8 nid; + __u8 rsvd1[127]; + struct nvme_nvmset_attr ent[NVME_ID_NVMSET_LIST_MAX]; +}; + +/** + * struct nvme_id_ns_granularity_list_entry - + */ +struct nvme_id_ns_granularity_list_entry { + __le64 namespace_size_granularity; + __le64 namespace_capacity_granularity; +}; + +/** + * struct nvme_id_ns_granularity_list - + */ +struct nvme_id_ns_granularity_list { + __le32 attributes; + __u8 num_descriptors; + __u8 rsvd[27]; + struct nvme_id_ns_granularity_list_entry entry[16]; +}; + +/** + * struct nvme_id_uuid_list_entry - + */ +struct nvme_id_uuid_list_entry { + __u8 header; + __u8 rsvd1[15]; + __u8 uuid[16]; +}; + +/** + * enum - + */ +enum { + NVME_ID_UUID_HDR_ASSOCIATION_MASK = 0x3, + NVME_ID_UUID_ASSOCIATION_NONE = 0, + NVME_ID_UUID_ASSOCIATION_VENDOR = 1, + NVME_ID_UUID_ASSOCIATION_SUBSYSTEM_VENDOR = 2, +}; + +/** + * struct nvme_id_uuid_list - + */ +struct nvme_id_uuid_list { + __u8 rsvd0[32]; + struct nvme_id_uuid_list_entry entry[NVME_ID_UUID_LIST_MAX]; +}; + +/** + * struct nvme_ctrl_list - + */ +struct nvme_ctrl_list { + __le16 num; + __le16 identifier[NVME_ID_CTRL_LIST_MAX]; +}; + +/** + * struct nvme_ns_list - + */ +struct nvme_ns_list { + __le32 ns[NVME_ID_NS_LIST_MAX]; +}; + +/** + * struct nvme_primary_ctrl_cap - + */ +struct nvme_primary_ctrl_cap { + __le16 cntlid; + __le16 portid; + __u8 crt; + __u8 rsvd5[27]; + __le32 vqfrt; + __le32 vqrfa; + __le16 vqrfap; + __le16 vqprt; + __le16 vqfrsm; + __le16 vqgran; + __u8 rsvd48[16]; + __le32 vifrt; + __le32 virfa; + __le16 virfap; + __le16 viprt; + __le16 vifrsm; + __le16 vigran; + __u8 rsvd80[4016]; +}; + +/** + * struct nvme_secondary_ctrl - + */ +struct nvme_secondary_ctrl { + __le16 scid; + __le16 pcid; + __u8 scs; + __u8 rsvd5[3]; + __le16 vfn; + __le16 nvq; + __le16 nvi; + __u8 rsvd14[18]; +}; + +/** + * struct nvme_secondary_ctrl_list - + */ +struct nvme_secondary_ctrl_list { + __u8 num; + __u8 rsvd[31]; + struct nvme_secondary_ctrl sc_entry[NVME_ID_SECONDARY_CTRL_MAX]; +}; + +/** + * DOC: NVMe Logs + */ + +/** + * struct nvme_error_log_page - + */ +struct nvme_error_log_page { + __le64 error_count; + __le16 sqid; + __le16 cmdid; + __le16 status_field; + __le16 parm_error_location; + __le64 lba; + __le32 nsid; + __u8 vs; + __u8 trtype; + __u8 resv[2]; + __le64 cs; + __le16 trtype_spec_info; + __u8 resv2[22]; +}; + +/** + * enum - + */ +enum { + NVME_ERR_PEL_BYTE_MASK = 0xf, + NVME_ERR_PEL_BIT_MASK = 0x70, +}; + +/** + * struct nvme_smart_log - + */ +struct nvme_smart_log { + __u8 critical_warning; + __u8 temperature[2]; + __u8 avail_spare; + __u8 spare_thresh; + __u8 percent_used; + __u8 endu_grp_crit_warn_sumry; + __u8 rsvd7[25]; + __u8 data_units_read[16]; + __u8 data_units_written[16]; + __u8 host_reads[16]; + __u8 host_writes[16]; + __u8 ctrl_busy_time[16]; + __u8 power_cycles[16]; + __u8 power_on_hours[16]; + __u8 unsafe_shutdowns[16]; + __u8 media_errors[16]; + __u8 num_err_log_entries[16]; + __le32 warning_temp_time; + __le32 critical_comp_time; + __le16 temp_sensor[8]; + __le32 thm_temp1_trans_count; + __le32 thm_temp2_trans_count; + __le32 thm_temp1_total_time; + __le32 thm_temp2_total_time; + __u8 rsvd232[280]; +}; + +/** + * enum - + */ +enum { + NVME_SMART_CRIT_SPARE = 1 << 0, + NVME_SMART_CRIT_TEMPERATURE = 1 << 1, + NVME_SMART_CRIT_DEGRADED = 1 << 2, + NVME_SMART_CRIT_MEDIA = 1 << 3, + NVME_SMART_CRIT_VOLATILE_MEMORY = 1 << 4, + NVME_SMART_CRIT_PMR_RO = 1 << 5, +}; + +/** + * enum - + */ +enum { + NVME_SMART_EGCW_SPARE = 1 << 0, + NVME_SMART_EGCW_DEGRADED = 1 << 2, + NVME_SMART_EGCW_RO = 1 << 3, +}; + +/** + * struct nvme_frs - + */ +struct nvme_frs { + char frs[8]; +}; + +/** + * struct nvme_firmware_slot - + */ +struct nvme_firmware_slot { + __u8 afi; + __u8 resv[7]; + struct nvme_frs frs[7]; + __u8 resv2[448]; +}; + +/** + * struct nvme_cmd_effects_log - + */ +struct nvme_cmd_effects_log { + __le32 acs[256]; + __le32 iocs[256]; + __u8 resv[2048]; +}; + +/** + * enum - + */ +enum { + NVME_CMD_EFFECTS_CSUPP = 1 << 0, + NVME_CMD_EFFECTS_LBCC = 1 << 1, + NVME_CMD_EFFECTS_NCC = 1 << 2, + NVME_CMD_EFFECTS_NIC = 1 << 3, + NVME_CMD_EFFECTS_CCC = 1 << 4, + NVME_CMD_EFFECTS_CSE_MASK = 3 << 16, + NVME_CMD_EFFECTS_UUID_SEL = 1 << 19, +}; + +/** + * struct nvme_st_result - + */ +struct nvme_st_result { + __u8 dsts; + __u8 seg; + __u8 vdi; + __u8 rsvd; + __le64 poh; + __le32 nsid; + __le64 flba; + __u8 sct; + __u8 sc; + __u8 vs[2]; +} __attribute__((packed)); + +/** + * enum - + */ +enum { + NVME_ST_RESULT_NO_ERR = 0x0, + NVME_ST_RESULT_ABORTED = 0x1, + NVME_ST_RESULT_CLR = 0x2, + NVME_ST_RESULT_NS_REMOVED = 0x3, + NVME_ST_RESULT_ABORTED_FORMAT = 0x4, + NVME_ST_RESULT_FATAL_ERR = 0x5, + NVME_ST_RESULT_UNKNOWN_SEG_FAIL = 0x6, + NVME_ST_RESULT_KNOWN_SEG_FAIL = 0x7, + NVME_ST_RESULT_ABORTED_UNKNOWN = 0x8, + NVME_ST_RESULT_ABORTED_SANITIZE = 0x9, + NVME_ST_RESULT_NOT_USED = 0xf, +}; + +/** + * enum - + */ +enum { + NVME_ST_OPERATION_NONE = 0x0, + NVME_ST_OPERATION_SHORT = 0x1, + NVME_ST_OPERATION_EXTENDED = 0x2, + NVME_ST_OPERATION_VS = 0xe, +}; + +/** + * enum - + */ +enum { + NVME_ST_VALID_DIAG_INFO_NSID = 1 << 0, + NVME_ST_VALID_DIAG_INFO_FLBA = 1 << 1, + NVME_ST_VALID_DIAG_INFO_SCT = 1 << 2, + NVME_ST_VALID_DIAG_INFO_SC = 1 << 3, +}; + + +/** + * struct nvme_self_test_log - + */ +struct nvme_self_test_log { + __u8 current_operation; + __u8 completion; + __u8 rsvd[2]; + struct nvme_st_result result[NVME_LOG_ST_MAX_RESULTS]; +} __attribute__((packed)); + +/** + * struct nvme_telemetry_log - + */ +struct nvme_telemetry_log { + __u8 lpi; + __u8 rsvd[4]; + __u8 ieee[3]; + __le16 dalb1; + __le16 dalb2; + __le16 dalb3; + __u8 rsvd1[368]; + __u8 ctrlavail; + __u8 ctrldgn; + __u8 rsnident[128]; + __u8 telemetry_dataarea[]; +}; + +/** + * struct nvme_endurance_group_log - + */ +struct nvme_endurance_group_log { + __u8 critical_warning; + __u8 rsvd1[2]; + __u8 avl_spare; + __u8 avl_spare_threshold; + __u8 percent_used; + __u8 rsvd6[26]; + __u8 endurance_estimate[16]; + __u8 data_units_read[16]; + __u8 data_units_written[16]; + __u8 media_units_written[16]; + __u8 host_read_cmds[16]; + __u8 host_write_cmds[16]; + __u8 media_data_integrity_err[16]; + __u8 num_err_info_log_entries[16]; + __u8 rsvd160[352]; +}; + +/** + * enum - + */ +enum nvme_eg_critical_warning_flags { + NVME_EG_CRITICAL_WARNING_SPARE = 1 << 0, + NVME_EG_CRITICAL_WARNING_DEGRADED = 1 << 2, + NVME_EG_CRITICAL_WARNING_READ_ONLY = 1 << 3, +}; + +/** + * struct nvme_aggregate_endurance_group_event - + */ +struct nvme_aggregate_endurance_group_event { + __le64 num_entries; + __le16 entries[]; +}; + +/** + * struct nvme_nvmset_predictable_lat_log - + */ +struct nvme_nvmset_predictable_lat_log { + __u8 status; + __u8 rsvd1; + __le16 event_type; + __u8 rsvd4[28]; + __le64 dtwin_rt; + __le64 dtwin_wt; + __le64 dtwin_tmax; + __le64 dtwin_tmin_hi; + __le64 dtwin_tmin_lo; + __u8 rsvd72[56]; + __le64 dtwin_re; + __le64 dtwin_we; + __le64 dtwin_te; + __u8 rsvd152[360]; +}; + +/** + * enum - + */ +enum { + NVME_NVMSET_PL_STATUS_DISABLED = 0, + NVME_NVMSET_PL_STATUS_DTWIN = 1, + NVME_NVMSET_PL_STATUS_NDWIN = 2, +}; + +/** + * enum - + */ +enum { + NVME_NVMSET_PL_EVENT_DTWIN_READ_WARN = 1 << 0, + NVME_NVMSET_PL_EVENT_DTWIN_WRITE_WARN = 1 << 1, + NVME_NVMSET_PL_EVENT_DTWIN_TIME_WARN = 1 << 2, + NVME_NVMSET_PL_EVENT_DTWIN_EXCEEDED = 1 << 14, + NVME_NVMSET_PL_EVENT_DTWIN_EXCURSION = 1 << 15, +}; + +/** + * struct nvme_aggregate_predictable_lat_event - + */ +struct nvme_aggregate_predictable_lat_event { + __le64 num_entries; + __le16 entries[]; +}; + +/** + * struct nvme_ana_group_desc - + */ +struct nvme_ana_group_desc { + __le32 grpid; + __le32 nnsids; + __le64 chgcnt; + __u8 state; + __u8 rsvd17[15]; + __le32 nsids[]; +}; + +/** + * enum - + */ +enum { + NVME_ANA_STATE_OPTIMIZED = 0x1, + NVME_ANA_STATE_NONOPTIMIZED = 0x2, + NVME_ANA_STATE_INACCESSIBLE = 0x3, + NVME_ANA_STATE_PERSISTENT_LOSS = 0x4, + NVME_ANA_STATE_CHANGE = 0xf, +}; + +/** + * struct nvme_ana_log - + */ +struct nvme_ana_log { + __le64 chgcnt; + __le16 ngrps; + __u8 rsvd10[6]; + struct nvme_ana_group_desc descs[]; +}; + +/** + * struct nvme_persistent_event_log - + */ +struct nvme_persistent_event_log { + __u8 lid; + __u8 rsvd1[3]; + __le32 ttl; + __u8 rv; + __u8 rsvd17; + __le16 lht; + __le64 ts; + __u8 poh[16]; + __le64 pcc; + __le16 vid; + __le16 ssvid; + char sn[20]; + char mn[40]; + char subnqn[256]; + __u8 rsvd372; + __u8 seb[32]; +}; + +/** + * struct nvme_lba_rd - + */ +struct nvme_lba_rd { + __le64 rslba; + __le32 rnlb; + __u8 rsvd12[4]; +}; + +/** + * struct nvme_lbas_ns_element - + */ +struct nvme_lbas_ns_element { + __le32 neid; + __le32 nrld; + __u8 ratype; + __u8 rsvd8[7]; + struct nvme_lba_rd lba_rd[]; +}; + +/** + * enum nvme_lba_status_atype - + * @NVME_LBA_STATUS_ATYPE_SCAN_UNTRACKED: + * @NVME_LBA_STATUS_ATYPE_SCAN_TRACKED: + */ +enum nvme_lba_status_atype { + NVME_LBA_STATUS_ATYPE_SCAN_UNTRACKED = 0x10, + NVME_LBA_STATUS_ATYPE_SCAN_TRACKED = 0x11, +}; + +/** + * struct nvme_lba_status_log - + */ +struct nvme_lba_status_log { + __le32 lslplen; + __le32 nlslne; + __le32 estulb; + __u8 rsvd12[2]; + __le16 lsgc; + struct nvme_lbas_ns_element elements[]; +}; + +/** + * struct nvme_eg_event_aggregate_log - + */ +struct nvme_eg_event_aggregate_log { + __le64 nr_entries; + __le16 egids[]; +}; + +/** + * struct nvme_resv_notification_log - + */ +struct nvme_resv_notification_log { + __le64 lpc; + __u8 rnlpt; + __u8 nalp; + __u8 rsvd9[2]; + __le32 nsid; + __u8 rsvd16[48]; +}; + +/** + * enum - + */ +enum { + NVME_RESV_NOTIFY_RNLPT_EMPTY = 0, + NVME_RESV_NOTIFY_RNLPT_REGISTRATION_PREEMPTED = 1, + NVME_RESV_NOTIFY_RNLPT_RESERVATION_RELEASED = 2, + NVME_RESV_NOTIFY_RNLPT_RESERVATION_PREEMPTED = 3, +}; + +/** + * struct nvme_sanitize_log_page - + */ +struct nvme_sanitize_log_page { + __le16 sprog; + __le16 sstat; + __le32 scdw10; + __le32 eto; + __le32 etbe; + __le32 etce; + __le32 etond; + __le32 etbend; + __le32 etcend; + __u8 rsvd32[480]; +}; + +/** + * DOC: NVMe Directives + */ + +/** + * enum - + */ +enum { + NVME_SANITIZE_SSTAT_NEVER_SANITIZED = 0, + NVME_SANITIZE_SSTAT_COMPLETE_SUCCESS = 1, + NVME_SANITIZE_SSTAT_IN_PROGESS = 2, + NVME_SANITIZE_SSTAT_COMPLETED_FAILED = 3, + NVME_SANITIZE_SSTAT_ND_COMPLETE_SUCCESS = 4, +}; + +/** + * struct nvme_lba_status_desc - + */ +struct nvme_lba_status_desc { + __le64 dslba; + __le32 nlb; + __u8 rsvd12; + __u8 status; + __u8 rsvd14[2]; +}; + +/** + * struct nvme_lba_status - + */ +struct nvme_lba_status { + __le32 nlsd; + __u8 cmpc; + __u8 rsvd5[3]; + struct nvme_lba_status_desc descs[]; +}; + + +/** + * DOC: NVMe Management Interface + */ + +/** + * struct nvme_mi_read_nvm_ss_info - + */ +struct nvme_mi_read_nvm_ss_info { + __u8 nump; + __u8 mjr; + __u8 mnr; + __u8 rsvd3[29]; +}; + +/** + * struct nvme_mi_port_pcie - + */ +struct nvme_mi_port_pcie { + __u8 mps; + __u8 sls; + __u8 cls; + __u8 mlw; + __u8 nlw; + __u8 pn; + __u8 rsvd14[18]; +}; + +/** + * struct nvme_mi_port_smb - + */ +struct nvme_mi_port_smb { + __u8 vpd_addr; + __u8 mvpd_freq; + __u8 mme_addr; + __u8 mme_freq; + __u8 nvmebm; + __u8 rsvd13[19]; +}; + +/** + * struct nvme_mi_read_port_info - + */ +struct nvme_mi_read_port_info { + __u8 portt; + __u8 rsvd1; + __le16 mmctptus; + __le32 meb; + union { + struct nvme_mi_port_pcie pcie; + struct nvme_mi_port_smb smb; + }; +}; + +/** + * struct nvme_mi_read_ctrl_info - + */ +struct nvme_mi_read_ctrl_info { + __u8 portid; + __u8 rsvd1[4]; + __u8 prii; + __le16 pri; + __le16 vid; + __le16 did; + __le16 ssvid; + __le16 ssid; + __u8 rsvd16[16]; +}; + +/** + * struct nvme_mi_osc - + */ +struct nvme_mi_osc { + __u8 type; + __u8 opc; +}; + +/** + * struct nvme_mi_read_sc_list - + */ +struct nvme_mi_read_sc_list { + __le16 numcmd; + struct nvme_mi_osc cmds[]; +}; + +/** + * struct nvme_mi_nvm_ss_health_status - + */ +struct nvme_mi_nvm_ss_health_status { + __u8 nss; + __u8 sw; + __u8 ctemp; + __u8 pdlu; + __le16 ccs; + __u8 rsvd8[2]; +}; + +/** + * enum - + */ +enum { + 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_heal_status - + */ +struct nvme_mi_ctrl_heal_status { + __le16 ctlid; + __le16 csts; + __le16 ctemp; + __u8 pdlu; + __u8 spare; + __u8 cwarn; + __u8 rsvd9[7]; +}; + +/** + * enum - + */ +enum { + NVME_MI_CSTS_RDY = 1 << 0, + NVME_MI_CSTS_CFS = 1 << 1, + NVME_MI_CSTS_SHST = 1 << 2, + NVME_MI_CSTS_NSSRO = 1 << 4, + NVME_MI_CSTS_CECO = 1 << 5, + NVME_MI_CSTS_NAC = 1 << 6, + NVME_MI_CSTS_FA = 1 << 7, + NVME_MI_CWARN_ST = 1 << 0, + NVME_MI_CWARN_TAUT = 1 << 1, + NVME_MI_CWARN_RD = 1 << 2, + NVME_MI_CWARN_RO = 1 << 3, + NVME_MI_CWARN_VMBF = 1 << 4, +}; + +/** + * struct nvme_mi_vpd_mra - + */ +struct nvme_mi_vpd_mra { + __u8 nmravn; + __u8 ff; + __u8 rsvd7[6]; + __u8 i18vpwr; + __u8 m18vpwr; + __u8 i33vpwr; + __u8 m33vpwr; + __u8 rsvd17; + __u8 m33vapsr; + __u8 i5vapsr; + __u8 m5vapsr; + __u8 i12vapsr; + __u8 m12vapsr; + __u8 mtl; + __u8 tnvmcap[16]; + __u8 rsvd37[27]; +}; + +/** + * struct nvme_mi_vpd_ppmra - + */ +struct nvme_mi_vpd_ppmra { + __u8 nppmravn; + __u8 pn; + __u8 ppi; + __u8 ls; + __u8 mlw; + __u8 mctp; + __u8 refccap; + __u8 pi; + __u8 rsvd13[3]; +}; + +/** + * struct nvme_mi_vpd_telem - + */ +struct nvme_mi_vpd_telem { + __u8 type; + __u8 rev; + __u8 len; + __u8 data[0]; +}; + +/** + * enum - + */ +enum { + NVME_MI_ELEM_EED = 1, + NVME_MI_ELEM_USCE = 2, + NVME_MI_ELEM_ECED = 3, + NVME_MI_ELEM_LED = 4, + NVME_MI_ELEM_SMBMED = 5, + NVME_MI_ELEM_PCIESED = 6, + NVME_MI_ELEM_NVMED = 7, +}; + +/** + * struct nvme_mi_vpd_tra - + */ +struct nvme_mi_vpd_tra { + __u8 vn; + __u8 rsvd6; + __u8 ec; + struct nvme_mi_vpd_telem elems[0]; +}; + +/** + * struct nvme_mi_vpd_mr_common - + */ +struct nvme_mi_vpd_mr_common { + __u8 type; + __u8 rf; + __u8 rlen; + __u8 rchksum; + __u8 hchksum; + + union { + struct nvme_mi_vpd_mra nmra; + struct nvme_mi_vpd_ppmra ppmra; + struct nvme_mi_vpd_tra tmra; + }; +}; + +/** + * struct nvme_mi_vpd_hdr - + */ +struct nvme_mi_vpd_hdr { + __u8 ipmiver; + __u8 iuaoff; + __u8 ciaoff; + __u8 biaoff; + __u8 piaoff; + __u8 mrioff; + __u8 rsvd6; + __u8 chchk; + __u8 vpd[]; +}; + +/** + * DOC: NVMe Features + */ + +/** + * struct nvme_feat_auto_pst - + */ +struct nvme_feat_auto_pst { + __le64 apst_entry[32]; +}; + +/** + * struct nvme_timestamp - + */ +struct nvme_timestamp { + __u8 timestamp[6]; + __u8 attr; + __u8 rsvd; +}; + +/** + * struct nvme_lba_range_type_entry - + */ +struct nvme_lba_range_type_entry { + __u8 type; + __u8 attributes; + __u8 rsvd2[14]; + __u64 slba; + __u64 nlb; + __u8 guid[16]; + __u8 rsvd48[16]; +}; + +/** + * enum - + */ +enum { + NVME_LBART_TYPE_GP = 0, + NVME_LBART_TYPE_FS = 1, + NVME_LBART_TYPE_RAID = 2, + NVME_LBART_TYPE_CACHE = 3, + NVME_LBART_TYPE_SWAP = 4, + NVME_LBART_ATTRIB_TEMP = 1 << 0, + NVME_LBART_ATTRIB_HIDE = 1 << 1, +}; + +/** + * struct nvme_lba_range_type - + */ +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 { + __le16 ee; + __u8 rsvd2[30]; + __le64 dtwinrt; + __le64 dtwinwt; + __le64 dtwintt; + __u8 rsvd56[456]; +}; + +/** + * struct nvme_feat_host_behavior - + */ +struct nvme_feat_host_behavior { + __u8 acre; + __u8 resv1[511]; +}; + +/** + * enum - + */ +enum { + NVME_ENABLE_ACRE = 1 << 0, +}; + +/** + * struct nvme_dsm_range - + */ +struct nvme_dsm_range { + __le32 cattr; + __le32 nlb; + __le64 slba; +}; + +/** + * struct nvme_registered_ctrl - + */ +struct nvme_registered_ctrl { + __le16 cntlid; + __u8 rcsts; + __u8 rsvd3[5]; + __le64 hostid; + __le64 rkey; +}; + +/** + * struct nvme_registered_ctrl_ext - + */ +struct nvme_registered_ctrl_ext { + __le16 cntlid; + __u8 rcsts; + __u8 resv3[5]; + __le64 rkey; + __u8 hostid[16]; + __u8 resv32[32]; +}; + +/** + * struct nvme_reservation_status - + */ +struct nvme_reservation_status { + __le32 gen; + __u8 rtype; + __u8 regctl[2]; + __u8 rsvd7[2]; + __u8 ptpls; + __u8 rsvd10[14]; + union { + struct { + __u8 resv24[40]; + struct nvme_registered_ctrl_ext regctl_eds[0]; + }; + struct nvme_registered_ctrl regctl_ds[0]; + }; +}; + +enum { + NVME_FEAT_ARB_BURST_MASK = 0x00000007, + NVME_FEAT_ARB_LPW_MASK = 0x0000ff00, + NVME_FEAT_ARB_MPW_MASK = 0x00ff0000, + NVME_FEAT_ARB_HPW_MASK = 0xff000000, + NVME_FEAT_PM_PS_MASK = 0x0000001f, + NVME_FEAT_PM_WH_MASK = 0x000000e0, + NVME_FEAT_LBAR_NR_MASK = 0x0000003f, + NVME_FEAT_TT_TMPTH_MASK = 0x0000ffff, + NVME_FEAT_TT_TMPSEL_MASK = 0x000f0000, + NVME_FEAT_TT_THSEL_MASK = 0x00300000, + NVME_FEAT_ER_TLER_MASK = 0x0000ffff, + NVME_FEAT_ER_DULBE_MASK = 0x00010000, + NVME_FEAT_VWC_WCE_MASK = 0x00000001, + NVME_FEAT_NRQS_NSQR_MASK = 0x0000ffff, + NVME_FEAT_NRQS_NCQR_MASK = 0xffff0000, + NVME_FEAT_ICOAL_THR_MASK = 0x000000ff, + NVME_FEAT_ICOAL_TIME_MASK = 0x0000ff00, + NVME_FEAT_ICFG_IV_MASK = 0x0000ffff, + NVME_FEAT_ICFG_CD_MASK = 0x00010000, + NVME_FEAT_WA_DN_MASK = 0x00000001, + NVME_FEAT_AE_SMART_MASK = 0x000000ff, + NVME_FEAT_AE_NAN_MASK = 0x00000100, + NVME_FEAT_AE_FW_MASK = 0x00000200, + NVME_FEAT_AE_TELEM_MASK = 0x00000400, + NVME_FEAT_AE_ANA_MASK = 0x00000800, + NVME_FEAT_AE_PLA_MASK = 0x00001000, + NVME_FEAT_AE_LBAS_MASK = 0x00002000, + NVME_FEAT_AE_EGA_MASK = 0x00004000, + NVME_FEAT_APST_APSTE_MASK = 0x00000001, + NVME_FEAT_HMEM_EHM_MASK = 0x00000001, + NVME_FEAT_TS_SYNCH_MASK = 0x00000001, + NVME_FEAT_TS_ORIGIN_MASK = 0x0000000e, + NVME_FEAT_TS_ORIGIN_CLR = 0x00000001, + NVME_FEAT_TS_ORIGIN_SF = 0x00000002, + NVME_FEAT_HCTM_TMT2_MASK = 0x0000ffff, + NVME_FEAT_HCTM_TMT1_MASK = 0xffff0000, + NVME_FEAT_NOPS_NOPPME_MASK = 0x00000001, + NVME_FEAT_RRL_RRL_MASK = 0x000000ff, + NVME_FEAT_PLM_PLME_MASK = 0x00000001, + NVME_FEAT_PLMW_WS_MASK = 0x00000007, + NVME_FEAT_LBAS_LSIRI_MASK = 0x0000ffff, + NVME_FEAT_LBAS_LSIPI_MASK = 0xffff0000, + NVME_FEAT_SC_NODRM_MASK = 0x00000001, + NVME_FEAT_EG_ENDGID_MASK = 0x0000ffff, + NVME_FEAT_EG_EGCW_MASK = 0x00ff0000, + NVME_FEAT_SPM_PBSLC_MASK = 0x000000ff, + NVME_FEAT_HOSTID_EXHID_MASK = 0x00000001, + NVME_FEAT_RM_REGPRE_MASK = 0x00000002, + NVME_FEAT_RM_RESREL_MASK = 0x00000004, + NVME_FEAT_RM_RESPRE_MASK = 0x00000008, + NVME_FEAT_RP_PTPL_MASK = 0x00000001, + NVME_FEAT_WP_WPS_MASK = 0x00000007, +}; + +#define shift(v, s, m) ((v & m) >> s) + +#define NVME_FEAT_ARB_BURST(v) shift(v, 0, NVME_FEAT_ARB_BURST_MASK) +#define NVME_FEAT_ARB_LPW(v) shift(v, 8, NVME_FEAT_ARB_LPW_MASK) +#define NVME_FEAT_ARB_MPW(v) shift(v, 16, NVME_FEAT_ARB_MPW_MASK) +#define NVME_FEAT_ARB_HPW(v) shift(v, 24, NVME_FEAT_ARB_HPW_MASK) +#define NVME_FEAT_PM_PS(v) shift(v, 0, NVME_FEAT_PM_PS_MASK) +#define NVME_FEAT_PM_WH(v) shift(v, 5, NVME_FEAT_PM_WH_MASK) +#define NVME_FEAT_LBAR_NR(v) shift(v, 0, NVME_FEAT_LBAR_NR_MASK) +#define NVME_FEAT_TT_TMPTH(v) shift(v, 0, NVME_FEAT_TT_TMPTH_MASK) +#define NVME_FEAT_TT_TMPSEL(v) shift(v, 16, NVME_FEAT_TT_TMPSEL_MASK) +#define NVME_FEAT_TT_THSEL(v) shift(v, 20, NVME_FEAT_TT_THSEL_MASK) +#define NVME_FEAT_ER_TLER(v) shift(v, 0, NVME_FEAT_ER_TLER_MASK) +#define NVME_FEAT_ER_DULBE(v) shift(v, 16, NVME_FEAT_ER_DULBE_MASK) +#define NVME_FEAT_VWC_WCE(v) shift(v, 0, NVME_FEAT_VWC_WCE_MASK) +#define NVME_FEAT_NRQS_NSQR(v) shift(v, 0, NVME_FEAT_NRQS_NSQR_MASK) +#define NVME_FEAT_NRQS_NCQR(v) shift(v, 16, NVME_FEAT_NRQS_NCQR_MASK) +#define NVME_FEAT_ICOAL_THR(v) shift(v, 0, NVME_FEAT_ICOAL_THR_MASK) +#define NVME_FEAT_ICOAL_TIME(v) shift(v, 8, NVME_FEAT_ICOAL_TIME_MASK) +#define NVME_FEAT_ICFG_IV(v) shift(v, 0, NVME_FEAT_ICFG_IV_MASK) +#define NVME_FEAT_ICFG_CD(v) shift(v, 16, NVME_FEAT_ICFG_CD_MASK) +#define NVME_FEAT_WA_DN(v) shift(v, 0, NVME_FEAT_WA_DN_MASK) +#define NVME_FEAT_AE_SMART(v) shift(v, 0, NVME_FEAT_AE_SMART_MASK) +#define NVME_FEAT_AE_NAN(v) shift(v, 8, NVME_FEAT_AE_NAN_MASK) +#define NVME_FEAT_AE_FW(v) shift(v, 9, NVME_FEAT_AE_FW_MASK) +#define NVME_FEAT_AE_TELEM(v) shift(v, 10, NVME_FEAT_AE_TELEM_MASK) +#define NVME_FEAT_AE_ANA(v) shift(v, 11, NVME_FEAT_AE_ANA_MASK) +#define NVME_FEAT_AE_PLA(v) shift(v, 12, NVME_FEAT_AE_PLA_MASK) +#define NVME_FEAT_AE_LBAS(v) shift(v, 13, NVME_FEAT_AE_LBAS_MASK) +#define NVME_FEAT_AE_EGA(v) shift(v, 14, NVME_FEAT_AE_EGA_MASK) +#define NVME_FEAT_APST_APSTE(v) shift(v, 0, NVME_FEAT_APST_APSTE_MASK) +#define NVME_FEAT_HMEM_EHM(v) shift(v, 0, NVME_FEAT_HMEM_EHM_MASK) +#define NVME_FEAT_TS_SYNC(v) shift(v, 0, NVME_FEAT_TS_SYNCH_MASK) +#define NVME_FEAT_TS_ORIGIN(v) shift(v, 1, NVME_FEAT_TS_ORIGIN_MASK) +#define NVME_FEAT_HCTM_TMT2(v) shift(v, 0, NVME_FEAT_HCTM_TMT2_MASK) +#define NVME_FEAT_HCTM_TMT1(v) shift(v, 16, NVME_FEAT_HCTM_TMT1_MASK) +#define NVME_FEAT_NOPS_NOPPME(v) shift(v, 0, NVME_FEAT_NOPS_NOPPME_MASK) +#define NVME_FEAT_RRL_RRL(v) shift(v, 0, NVME_FEAT_RRL_RRL_MASK) +#define NVME_FEAT_PLM_PLME(v) shift(v, 0, NVME_FEAT_PLM_PLME_MASK) +#define NVME_FEAT_PLMW_WS(v) shift(v, 0, NVME_FEAT_PLMW_WS_MASK) +#define NVME_FEAT_LBAS_LSIRI(v) shift(v, 0, NVME_FEAT_LBAS_LSIRI_MASK) +#define NVME_FEAT_LBAS_LSIPI(v) shift(v, 16, NVME_FEAT_LBAS_LSIPI_MASK) +#define NVME_FEAT_SC_NODRM(v) shift(v, 0, NVME_FEAT_SC_NODRM_MASK) +#define NVME_FEAT_EG_ENDGID(v) shift(v, 0, NVME_FEAT_EG_ENDGID_MASK) +#define NVME_FEAT_EG_EGCW(v) shift(v, 16, NVME_FEAT_EG_EGCW_MASK) +#define NVME_FEAT_SPM_PBSLC(v) shift(v, 0, NVME_FEAT_SPM_PBSLC_MASK) +#define NVME_FEAT_HOSTID_EXHID(v) shift(v, 0, NVME_FEAT_HOSTID_EXHID_MASK) +#define NVME_FEAT_RM_REGPRE(v) shift(v, 1, NVME_FEAT_RM_REGPRE_MASK) +#define NVME_FEAT_RM_RESREL(v) shift(v, 2, NVME_FEAT_RM_RESREL_MASK) +#define NVME_FEAT_RM_RESPRE(v) shift(v, 3, NVME_FEAT_RM_RESPRE_MASK) +#define NVME_FEAT_RP_PTPL(v) shift(v, 0, NVME_FEAT_RP_PTPL_MASK) +#define NVME_FEAT_WP_WPS(v) shift(v, 0, NVME_FEAT_WP_WPS_MASK) + +/** + * struct nvme_streams_directive_params - + */ +struct nvme_streams_directive_params { + __le16 msl; + __le16 nssa; + __le16 nsso; + __u8 nssc; + __u8 rsvd[9]; + __le32 sws; + __le16 sgs; + __le16 nsa; + __le16 nso; + __u8 rsvd2[6]; +}; + +/** + * struct nvme_streams_directive_status - + */ +struct nvme_streams_directive_status { + __le16 osc; + __le16 sid[]; +}; + +/** + * struct nvme_id_directives - + */ +struct nvme_id_directives { + __u8 supported[32]; + __u8 enabled[32]; + __u8 rsvd64[4032]; +}; + +/** + * enum - + */ +enum { + NVME_ID_DIR_ID_BIT = 0, + NVME_ID_DIR_SD_BIT = 1, +}; + +/** + * struct nvme_host_mem_buf_desc - + */ +struct nvme_host_mem_buf_desc { + __le64 addr; + __le32 size; + __u32 rsvd; +}; + +/** + * enum - + */ +enum { + NVME_AER_ERROR = 0, + NVME_AER_SMART = 1, + NVME_AER_NOTICE = 2, + NVME_AER_CSS = 6, + NVME_AER_VS = 7, +}; + +/** + * enum - + */ +enum { + NVME_AER_NOTICE_NS_CHANGED = 0x00, + NVME_AER_NOTICE_FW_ACT_STARTING = 0x01, + NVME_AER_NOTICE_ANA = 0x03, + NVME_AER_NOTICE_DISC_CHANGED = 0xf0, +}; + +/** + * enum nvme_subsys_type - + * @NVME_NQN_DISC: Discovery type target subsystem + * @NVME_NQN_NVME: NVME type target subsystem + */ +enum nvme_subsys_type { + NVME_NQN_DISC = 1, + NVME_NQN_NVME = 2, +}; + +#define NVME_DISC_SUBSYS_NAME "nqn.2014-08.org.nvmexpress.discovery" +#define NVME_RDMA_IP_PORT 4420 + +/* NQN names in commands fields specified one size */ +#define NVMF_NQN_FIELD_LEN 256 + +/* However the max length of a qualified name is another size */ +#define NVMF_NQN_SIZE 223 +#define NVMF_TRSVCID_SIZE 32 +#define NVMF_TRADDR_SIZE 256 +#define NVMF_TSAS_SIZE 256 + +/** + * struct nvmf_disc_log_entry - + * + * Discovery log page entry + */ +struct nvmf_disc_log_entry { + __u8 trtype; + __u8 adrfam; + __u8 subtype; + __u8 treq; + __le16 portid; + __le16 cntlid; + __le16 asqsz; + __u8 resv10[22]; + char trsvcid[NVMF_TRSVCID_SIZE]; + __u8 resv64[192]; + char subnqn[NVMF_NQN_FIELD_LEN]; + char traddr[NVMF_TRADDR_SIZE]; + union tsas { + char common[NVMF_TSAS_SIZE]; + struct rdma { + __u8 qptype; + __u8 prtype; + __u8 cms; + __u8 resv3[5]; + __u16 pkey; + __u8 resv10[246]; + } rdma; + struct tcp { + __u8 sectype; + } tcp; + } tsas; +}; + +/** + * enum - + * @NVMF_TRTYPE_UNSPECIFIED: Not indicated + * @NVMF_TRTYPE_RDMA: RDMA + * @NVMF_TRTYPE_FC: Fibre Channel + * @NVMF_TRTYPE_TCP: TCP + * @NVMF_TRTYPE_LOOP: Reserved for host usage + * + * Transport Type codes for Discovery Log Page entry TRTYPE field + */ +enum { + NVMF_TRTYPE_UNSPECIFIED = 0, + NVMF_TRTYPE_RDMA = 1, + NVMF_TRTYPE_FC = 2, + NVMF_TRTYPE_TCP = 3, + NVMF_TRTYPE_LOOP = 254, + NVMF_TRTYPE_MAX, +}; + +/** + * enum - + * @NVMF_ADDR_FAMILY_PCI: PCIe + * @NVMF_ADDR_FAMILY_IP4: IPv4 + * @NVMF_ADDR_FAMILY_IP6: IPv6 + * @NVMF_ADDR_FAMILY_IB: InfiniBand + * @NVMF_ADDR_FAMILY_FC: Fibre Channel + * + * Address Family codes for Discovery Log Page entry ADRFAM field + */ +enum { + NVMF_ADDR_FAMILY_PCI = 0, + NVMF_ADDR_FAMILY_IP4 = 1, + NVMF_ADDR_FAMILY_IP6 = 2, + NVMF_ADDR_FAMILY_IB = 3, + NVMF_ADDR_FAMILY_FC = 4, +}; + +/** + * enum - + * @NVMF_TREQ_NOT_SPECIFIED: Not specified + * @NVMF_TREQ_REQUIRED: Required + * @NVMF_TREQ_NOT_REQUIRED: Not Required + * @NVMF_TREQ_DISABLE_SQFLOW: SQ flow control disable supported + * + * Transport Requirements codes for Discovery Log Page entry TREQ field + */ +enum { + NVMF_TREQ_NOT_SPECIFIED = 0, + NVMF_TREQ_REQUIRED = 1, + NVMF_TREQ_NOT_REQUIRED = 2, + NVMF_TREQ_DISABLE_SQFLOW = 4, +}; + +/** + * enum - + * @NVMF_RDMA_QPTYPE_CONNECTED: Reliable Connected + * @NVMF_RDMA_QPTYPE_DATAGRAM: Reliable Datagram + * + * RDMA QP Service Type codes for Discovery Log Page entry TSAS + * RDMA_QPTYPE field + */ +enum { + NVMF_RDMA_QPTYPE_CONNECTED = 1, + NVMF_RDMA_QPTYPE_DATAGRAM = 2, +}; + +/** + * enum - + * @NVMF_RDMA_PRTYPE_NOT_SPECIFIED: No Provider Specified + * @NVMF_RDMA_PRTYPE_IB: InfiniBand + * @NVMF_RDMA_PRTYPE_ROCE: InfiniBand RoCE + * @NVMF_RDMA_PRTYPE_ROCEV2: InfiniBand RoCEV2 + * @NVMF_RDMA_PRTYPE_IWARP: iWARP + * + * RDMA Provider Type codes for Discovery Log Page entry TSAS + * RDMA_PRTYPE field + */ +enum { + NVMF_RDMA_PRTYPE_NOT_SPECIFIED = 1, + NVMF_RDMA_PRTYPE_IB = 2, + NVMF_RDMA_PRTYPE_ROCE = 3, + NVMF_RDMA_PRTYPE_ROCEV2 = 4, + NVMF_RDMA_PRTYPE_IWARP = 5, +}; + +/** + * enum - + * @NVMF_RDMA_CMS_RDMA_CM: Sockets based endpoint addressing + * + * RDMA Connection Management Service Type codes for Discovery Log Page + * entry TSAS RDMA_CMS field + */ +enum { + NVMF_RDMA_CMS_RDMA_CM = 1, +}; + +/** + * enum - + * @NVMF_TCP_SECTYPE_NONE: No Security + * @NVMF_TCP_SECTYPE_TLS: Transport Layer Security + */ +enum { + NVMF_TCP_SECTYPE_NONE = 0, + NVMF_TCP_SECTYPE_TLS = 1, +}; + +/** + * struct nvmf_discovery_log - + */ +struct nvmf_discovery_log { + __le64 genctr; + __le64 numrec; + __le16 recfmt; + __u8 resv14[1006]; + struct nvmf_disc_log_entry entries[0]; +}; + +/** + * struct nvmf_connect_data - + */ +struct nvmf_connect_data { + __u8 hostid[16]; + __le16 cntlid; + char resv4[238]; + char subsysnqn[NVMF_NQN_FIELD_LEN]; + char hostnqn[NVMF_NQN_FIELD_LEN]; + char resv5[256]; +}; + +/** + * enum - + */ +enum { + /* + * Status code type + */ + NVME_SCT_GENERIC = 0x000, + NVME_SCT_CMD_SPECIFIC = 0x100, + NVME_SCT_MEDIA = 0x200, + NVME_SCT_PATH = 0x300, + NVME_SCT_VS = 0x700, + NVME_SCT_MASK = 0x700, + + /* + * Generic Command Status: + */ + NVME_SC_SUCCESS = 0x0, + NVME_SC_INVALID_OPCODE = 0x1, + NVME_SC_INVALID_FIELD = 0x2, + NVME_SC_CMDID_CONFLICT = 0x3, + NVME_SC_DATA_XFER_ERROR = 0x4, + NVME_SC_POWER_LOSS = 0x5, + NVME_SC_INTERNAL = 0x6, + NVME_SC_ABORT_REQ = 0x7, + NVME_SC_ABORT_QUEUE = 0x8, + NVME_SC_FUSED_FAIL = 0x9, + NVME_SC_FUSED_MISSING = 0xa, + NVME_SC_INVALID_NS = 0xb, + NVME_SC_CMD_SEQ_ERROR = 0xc, + NVME_SC_SGL_INVALID_LAST = 0xd, + NVME_SC_SGL_INVALID_COUNT = 0xe, + NVME_SC_SGL_INVALID_DATA = 0xf, + NVME_SC_SGL_INVALID_METADATA = 0x10, + NVME_SC_SGL_INVALID_TYPE = 0x11, + NVME_SC_CMB_INVALID_USE = 0x12, + NVME_SC_PRP_INVALID_OFFSET = 0x13, + NVME_SC_AWU_EXCEEDED = 0x14, + NVME_SC_OP_DENIED = 0x15, + NVME_SC_SGL_INVALID_OFFSET = 0x16, + + NVME_SC_HOSTID_FORMAT = 0x18, + NVME_SC_KAT_EXPIRED = 0x19, + NVME_SC_KAT_INVALID = 0x1a, + NVME_SC_CMD_ABORTED_PREMEPT = 0x1b, + NVME_SC_SANITIZE_FAILED = 0x1c, + NVME_SC_SANITIZE_IN_PROGRESS = 0x1d, + NVME_SC_SGL_INVALID_GRANULARITY = 0x1e, + NVME_SC_CMD_IN_CMBQ_NOT_SUPP = 0x1f, + NVME_SC_NS_WRITE_PROTECTED = 0x20, + NVME_SC_CMD_INTERRUPTED = 0x21, + NVME_SC_TRAN_TPORT_ERROR = 0x22, + + NVME_SC_LBA_RANGE = 0x80, + NVME_SC_CAP_EXCEEDED = 0x81, + NVME_SC_NS_NOT_READY = 0x82, + NVME_SC_RESERVATION_CONFLICT = 0x83, + NVME_SC_FORMAT_IN_PROGRESS = 0x84, + + /* + * Command Specific Status: + */ + NVME_SC_CQ_INVALID = 0x00, + NVME_SC_QID_INVALID = 0x01, + NVME_SC_QUEUE_SIZE = 0x02, + NVME_SC_ABORT_LIMIT = 0x03, + NVME_SC_ABORT_MISSING = 0x04, + NVME_SC_ASYNC_LIMIT = 0x05, + NVME_SC_FIRMWARE_SLOT = 0x06, + NVME_SC_FIRMWARE_IMAGE = 0x07, + NVME_SC_INVALID_VECTOR = 0x08, + NVME_SC_INVALID_LOG_PAGE = 0x09, + NVME_SC_INVALID_FORMAT = 0x0a, + NVME_SC_FW_NEEDS_CONV_RESET = 0x0b, + NVME_SC_INVALID_QUEUE = 0x0c, + NVME_SC_FEATURE_NOT_SAVEABLE = 0x0d, + NVME_SC_FEATURE_NOT_CHANGEABLE = 0x0e, + NVME_SC_FEATURE_NOT_PER_NS = 0x0f, + NVME_SC_FW_NEEDS_SUBSYS_RESET = 0x10, + NVME_SC_FW_NEEDS_RESET = 0x11, + NVME_SC_FW_NEEDS_MAX_TIME = 0x12, + NVME_SC_FW_ACTIVATE_PROHIBITED = 0x13, + NVME_SC_OVERLAPPING_RANGE = 0x14, + NVME_SC_NS_INSUFFICIENT_CAP = 0x15, + NVME_SC_NS_ID_UNAVAILABLE = 0x16, + NVME_SC_NS_ALREADY_ATTACHED = 0x18, + NVME_SC_NS_IS_PRIVATE = 0x19, + NVME_SC_NS_NOT_ATTACHED = 0x1a, + NVME_SC_THIN_PROV_NOT_SUPP = 0x1b, + NVME_SC_CTRL_LIST_INVALID = 0x1c, + NVME_SC_SELF_TEST_IN_PROGRESS = 0x1d, + NVME_SC_BP_WRITE_PROHIBITED = 0x1e, + NVME_SC_INVALID_CTRL_ID = 0x1f, + NVME_SC_INVALID_SEC_CTRL_STATE = 0x20, + NVME_SC_INVALID_CTRL_RESOURCES = 0x21, + NVME_SC_INVALID_RESOURCE_ID = 0x22, + NVME_SC_PMR_SAN_PROHIBITED = 0x23, + NVME_SC_ANA_GROUP_ID_INVALID = 0x24, + NVME_SC_ANA_ATTACH_FAILED = 0x25, + + /* + * I/O Command Set Specific - NVM commands: + */ + NVME_SC_BAD_ATTRIBUTES = 0x80, + NVME_SC_INVALID_PI = 0x81, + NVME_SC_READ_ONLY = 0x82, + + /* + * I/O Command Set Specific - Fabrics commands: + */ + NVME_SC_CONNECT_FORMAT = 0x80, + NVME_SC_CONNECT_CTRL_BUSY = 0x81, + NVME_SC_CONNECT_INVALID_PARAM = 0x82, + NVME_SC_CONNECT_RESTART_DISC = 0x83, + NVME_SC_CONNECT_INVALID_HOST = 0x84, + NVME_SC_DISCONNECT_INVALID_QTYPE= 0x85, + + NVME_SC_DISCOVERY_RESTART = 0x90, + NVME_SC_AUTH_REQUIRED = 0x91, + + /* + * Media and Data Integrity Errors: + */ + NVME_SC_WRITE_FAULT = 0x80, + NVME_SC_READ_ERROR = 0x81, + NVME_SC_GUARD_CHECK = 0x82, + NVME_SC_APPTAG_CHECK = 0x83, + NVME_SC_REFTAG_CHECK = 0x84, + NVME_SC_COMPARE_FAILED = 0x85, + NVME_SC_ACCESS_DENIED = 0x86, + NVME_SC_UNWRITTEN_BLOCK = 0x87, + + /* + * Path-related Errors: + */ + NVME_SC_ANA_INTERNAL_PATH_ERROR = 0x00, + NVME_SC_ANA_PERSISTENT_LOSS = 0x01, + NVME_SC_ANA_INACCESSIBLE = 0x02, + NVME_SC_ANA_TRANSITION = 0x03, + + NVME_SC_CTRL_PATH_ERROR = 0x60, + + NVME_SC_HOST_PATH_ERROR = 0x70, + NVME_SC_CMD_ABORTED_BY_HOST = 0x71, + + /* + * Status code mask + */ + NVME_SC_MASK = 0xff, + + /* + * Additional status info + */ + NVME_SC_CRD = 0x1800, + NVME_SC_MORE = 0x2000, + NVME_SC_DNR = 0x4000, +}; + +#define NVME_MAJOR(ver) ((ver) >> 16) +#define NVME_MINOR(ver) (((ver) >> 8) & 0xff) +#define NVME_TERTIARY(ver) ((ver) & 0xff) + +#endif /* _LIBNVME_TYPES_H */ diff --git a/lib/nvme/util.c b/lib/nvme/util.c new file mode 100644 index 0000000000..bd06328acc --- /dev/null +++ b/lib/nvme/util.c @@ -0,0 +1,579 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "filters.h" +#include "types.h" +#include "cmd.h" +#include "ioctl.h" +#include "util.h" +#include "tree.h" + +static inline __u8 nvme_generic_status_to_errno(__u16 status) +{ + switch (status) { + case NVME_SC_INVALID_OPCODE: + case NVME_SC_INVALID_FIELD: + case NVME_SC_INVALID_NS: + case NVME_SC_SGL_INVALID_LAST: + case NVME_SC_SGL_INVALID_COUNT: + case NVME_SC_SGL_INVALID_DATA: + case NVME_SC_SGL_INVALID_METADATA: + case NVME_SC_SGL_INVALID_TYPE: + case NVME_SC_SGL_INVALID_OFFSET: + return EINVAL; + case NVME_SC_CMDID_CONFLICT: + return EADDRINUSE; + case NVME_SC_DATA_XFER_ERROR: + case NVME_SC_INTERNAL: + case NVME_SC_SANITIZE_FAILED: + return EIO; + case NVME_SC_POWER_LOSS: + case NVME_SC_ABORT_REQ: + case NVME_SC_ABORT_QUEUE: + case NVME_SC_FUSED_FAIL: + case NVME_SC_FUSED_MISSING: + return EWOULDBLOCK; + case NVME_SC_CMD_SEQ_ERROR: + return EILSEQ; + case NVME_SC_SANITIZE_IN_PROGRESS: + return EINPROGRESS; + case NVME_SC_NS_WRITE_PROTECTED: + case NVME_SC_NS_NOT_READY: + case NVME_SC_RESERVATION_CONFLICT: + return EACCES; + case NVME_SC_LBA_RANGE: + return EREMOTEIO; + case NVME_SC_CAP_EXCEEDED: + return ENOSPC; + } + return EIO; +} + +static inline __u8 nvme_cmd_specific_status_to_errno(__u16 status) +{ + switch (status) { + case NVME_SC_CQ_INVALID: + case NVME_SC_QID_INVALID: + case NVME_SC_QUEUE_SIZE: + case NVME_SC_FIRMWARE_SLOT: + case NVME_SC_FIRMWARE_IMAGE: + case NVME_SC_INVALID_VECTOR: + case NVME_SC_INVALID_LOG_PAGE: + case NVME_SC_INVALID_FORMAT: + case NVME_SC_INVALID_QUEUE: + case NVME_SC_NS_INSUFFICIENT_CAP: + case NVME_SC_NS_ID_UNAVAILABLE: + case NVME_SC_CTRL_LIST_INVALID: + case NVME_SC_BAD_ATTRIBUTES: + case NVME_SC_INVALID_PI: + return EINVAL; + case NVME_SC_ABORT_LIMIT: + case NVME_SC_ASYNC_LIMIT: + return EDQUOT; + case NVME_SC_FW_NEEDS_CONV_RESET: + case NVME_SC_FW_NEEDS_SUBSYS_RESET: + case NVME_SC_FW_NEEDS_MAX_TIME: + return ERESTART; + case NVME_SC_FEATURE_NOT_SAVEABLE: + case NVME_SC_FEATURE_NOT_CHANGEABLE: + case NVME_SC_FEATURE_NOT_PER_NS: + case NVME_SC_FW_ACTIVATE_PROHIBITED: + case NVME_SC_NS_IS_PRIVATE: + case NVME_SC_BP_WRITE_PROHIBITED: + case NVME_SC_READ_ONLY: + case NVME_SC_PMR_SAN_PROHIBITED: + return EPERM; + case NVME_SC_OVERLAPPING_RANGE: + case NVME_SC_NS_NOT_ATTACHED: + return ENOSPC; + case NVME_SC_NS_ALREADY_ATTACHED: + return EALREADY; + case NVME_SC_THIN_PROV_NOT_SUPP: + return EOPNOTSUPP; + } + + return EIO; +} + +static inline __u8 nvme_fabrics_status_to_errno(__u16 status) +{ + switch (status) { + case NVME_SC_CONNECT_FORMAT: + case NVME_SC_CONNECT_INVALID_PARAM: + return EINVAL; + case NVME_SC_CONNECT_CTRL_BUSY: + return EBUSY; + case NVME_SC_CONNECT_RESTART_DISC: + return ERESTART; + case NVME_SC_CONNECT_INVALID_HOST: + return ECONNREFUSED; + case NVME_SC_DISCOVERY_RESTART: + return EAGAIN; + case NVME_SC_AUTH_REQUIRED: + return EPERM; + } + + return EIO; +} + +__u8 nvme_status_to_errno(int status, bool fabrics) +{ + __u16 sc, sct; + + if (!status) + return 0; + if (status < 0) + return errno; + + sc = status & NVME_SC_MASK; + sct = status & NVME_SCT_MASK; + + switch (sct) { + case NVME_SCT_GENERIC: + return nvme_generic_status_to_errno(sc); + case NVME_SCT_CMD_SPECIFIC: + if (fabrics) + return nvme_fabrics_status_to_errno(sc); + return nvme_cmd_specific_status_to_errno(sc); + default: + /* + * Media, integrity related status, and the others will be + * mapped to EIO. + */ + return EIO; + } +} + +static int __nvme_open(const char *name) +{ + char *path; + int fd, ret; + + ret = asprintf(&path, "%s/%s", "/dev", name); + if (ret < 0) { + errno = ENOMEM; + return -1; + } + + fd = open(path, O_RDONLY); + free(path); + return fd; +} + +int nvme_open(const char *name) +{ + int ret, fd, id, ns; + struct stat stat; + bool c; + + ret = sscanf(name, "nvme%dn%d", &id, &ns); + if (ret != 1 && ret != 2) { + errno = EINVAL; + return -1; + } + c = ret == 1; + + fd = __nvme_open(name); + if (fd < 0) + return fd; + + ret = fstat(fd, &stat); + if (ret < 0) + goto close_fd; + + if (c) { + if (!S_ISCHR(stat.st_mode)) { + errno = EINVAL; + goto close_fd; + } + } else if (!S_ISBLK(stat.st_mode)) { + errno = EINVAL; + goto close_fd; + } + + return fd; + +close_fd: + close(fd); + return -1; +} + +int nvme_fw_download_split(int fd, __u32 size, __u32 xfer, __u32 offset, + void *buf) +{ + int err = 0; + + while (size > 0) { + xfer = MIN(xfer, size); + err = nvme_fw_download(fd, offset, xfer, buf); + if (err) + break; + + buf += xfer; + size -= xfer; + offset += xfer; + } + + return err; +} + +int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, + __u32 data_len, void *data) +{ + __u64 offset = 0, xfer_len = data_len; + void *ptr = data; + int ret; + + /* + * 4k is the smallest possible transfer unit, so restricting to 4k + * avoids having to check the MDTS value of the controller. + */ + do { + xfer_len = data_len - offset; + if (xfer_len > 4096) + xfer_len = 4096; + + ret = nvme_get_log(fd, log_id, nsid, offset, NVME_LOG_LSP_NONE, + NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, + xfer_len, ptr); + if (ret) + return ret; + + offset += xfer_len; + ptr += xfer_len; + } while (offset < data_len); + + return 0; +} + +int nvme_get_telemetry_log(int fd, bool create, bool ctrl, int data_area, + void **buf, __u32 *log_size) +{ + struct nvme_telemetry_log *telem; + static const __u32 xfer = 512; + __u32 size, offset = xfer; + void *log; + int err; + + log = malloc(xfer); + if (!log) { + errno = ENOMEM; + return -1; + } + + if (ctrl) + err = nvme_get_log_telemetry_ctrl(fd, true, 0, xfer, log); + else if (create) + err = nvme_get_log_create_telemetry_host(fd, log); + else + err = nvme_get_log_telemetry_host(fd, 0, xfer, log); + + if (err) + goto free; + + telem = log; + if (!telem->ctrlavail) { + size = xfer; + goto done; + } + + switch (data_area) { + case 1: + size = (le16_to_cpu(telem->dalb1) * xfer) + xfer; + break; + case 2: + size = (le16_to_cpu(telem->dalb2) * xfer) + xfer; + break; + case 3: + size = (le16_to_cpu(telem->dalb3) * xfer) + xfer; + break; + default: + errno = EINVAL; + err = -1; + goto free; + } + + log = realloc(log, size); + if (!log) { + errno = ENOMEM; + err = -1; + goto free; + } + + while (offset != size) { + if (ctrl) + err = nvme_get_log_telemetry_ctrl(fd, true, offset, + xfer, log + offset); + else + err = nvme_get_log_telemetry_host(fd, offset, xfer, + log + offset); + if (err) + goto free; + offset += xfer; + } +done: + *log_size = size; + *buf = log; + return 0; +free: + free(log); + return err; +} + +void nvme_setup_dsm_range(struct nvme_dsm_range *dsm, __u32 *ctx_attrs, + __u32 *llbas, __u64 *slbas, __u16 nr_ranges) +{ + int i; + + for (i = 0; i < nr_ranges; i++) { + dsm[i].cattr = cpu_to_le32(ctx_attrs[i]); + dsm[i].nlb = cpu_to_le32(llbas[i]); + dsm[i].slba = cpu_to_le64(slbas[i]); + } +} + +void nvme_setup_id_ns(struct nvme_id_ns *ns, __u64 nsze, __u64 ncap, __u8 flbas, + __u8 dps, __u8 nmic, __u32 anagrpid, __u16 nvmsetid) +{ + memset(ns, 0, sizeof(*ns)); + ns->nsze = cpu_to_le64(nsze); + ns->ncap = cpu_to_le64(ncap); + ns->flbas = flbas; + ns->dps = dps; + ns->nmic = nmic; + ns->anagrpid = cpu_to_le32(anagrpid); + ns->nvmsetid = cpu_to_le16(nvmsetid); +} + +void nvme_setup_ctrl_list(struct nvme_ctrl_list *cntlist, __u16 num_ctrls, + __u16 *ctrlist) +{ + int i; + + cntlist->num = cpu_to_le16(num_ctrls); + for (i = 0; i < num_ctrls; i++) + cntlist->identifier[i] = cpu_to_le16(ctrlist[i]); +} + +static int nvme_ns_attachment(int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist, bool attach) +{ + struct nvme_ctrl_list cntlist = { 0 }; + enum nvme_ns_attach_sel sel; + + if (attach) + sel = NVME_NS_ATTACH_SEL_CTRL_ATTACH; + else + sel = NVME_NS_ATTACH_SEL_CTRL_DEATTACH; + + nvme_setup_ctrl_list(&cntlist, num_ctrls, ctrlist); + return nvme_ns_attach(fd, nsid, sel, &cntlist); +} + +int nvme_namespace_attach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist) +{ + return nvme_ns_attachment(fd, nsid, num_ctrls, ctrlist, true); +} + +int nvme_namespace_detach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist) +{ + return nvme_ns_attachment(fd, nsid, num_ctrls, ctrlist, false); +} + +int nvme_get_ana_log_len(int fd, size_t *analen) +{ + struct nvme_id_ctrl ctrl; + int ret; + + ret = nvme_identify_ctrl(fd, &ctrl); + if (ret) + return ret; + + *analen = sizeof(struct nvme_ana_log) + + le32_to_cpu(ctrl.nanagrpid) * sizeof(struct nvme_ana_group_desc) + + le32_to_cpu(ctrl.mnan) * sizeof(__le32); + return 0; +} + +int nvme_get_feature_length(int fid, __u32 cdw11, __u32 *len) +{ + switch (fid) { + case NVME_FEAT_FID_LBA_RANGE: + *len = sizeof(struct nvme_lba_range_type); + break; + case NVME_FEAT_FID_AUTO_PST: + *len = sizeof(struct nvme_feat_auto_pst); + break; + case NVME_FEAT_FID_PLM_CONFIG: + *len = sizeof(struct nvme_plm_config); + break; + case NVME_FEAT_FID_TIMESTAMP: + *len = sizeof(struct nvme_timestamp); + break; + case NVME_FEAT_FID_HOST_BEHAVIOR: + *len = sizeof(struct nvme_feat_host_behavior); + break; + case NVME_FEAT_FID_HOST_ID: + *len = (cdw11 & 0x1) ? 16 : 8; + break; + case NVME_FEAT_FID_ARBITRATION: + case NVME_FEAT_FID_POWER_MGMT: + case NVME_FEAT_FID_TEMP_THRESH: + case NVME_FEAT_FID_ERR_RECOVERY: + case NVME_FEAT_FID_VOLATILE_WC: + case NVME_FEAT_FID_NUM_QUEUES: + case NVME_FEAT_FID_IRQ_COALESCE: + 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: + case NVME_FEAT_FID_RRL: + case NVME_FEAT_FID_PLM_WINDOW: + case NVME_FEAT_FID_LBA_STS_INTERVAL: + case NVME_FEAT_FID_SANITIZE: + case NVME_FEAT_FID_ENDURANCE_EVT_CFG: + case NVME_FEAT_FID_SW_PROGRESS: + case NVME_FEAT_FID_RESV_MASK: + case NVME_FEAT_RESV_PERSIST: + case NVME_FEAT_FID_WRITE_PROTECT: + *len = 0; + break; + default: + return EINVAL; + } + return 0; +} + +int nvme_get_directive_receive_length(__u8 dtype, __u8 doper, __u32 *len) +{ + switch (dtype) { + case NVME_DIRECTIVE_DTYPE_IDENTIFY: + switch (doper) { + case NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM: + *len = sizeof(struct nvme_id_directives); + break; + default: + return -EINVAL; + } + break; + case NVME_DIRECTIVE_DTYPE_STREAMS: + switch (doper) { + case NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM: + *len = sizeof(struct nvme_streams_directive_params); + break; + case NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS: + *len = (128 * 1024) * sizeof(__le16); + break; + case NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE: + *len = 0; + break; + default: + return -EINVAL; + } + default: + return -EINVAL; + } + return 0; +} + +static int __nvme_set_attr(const char *path, const char *value) +{ + int ret, fd; + + fd = open(path, O_WRONLY); + if (fd < 0) + return -1; + + ret = write(fd, value, strlen(value)); + close(fd); + return ret; +} + +int nvme_set_attr(const char *dir, const char *attr, const char *value) +{ + char *path; + int ret; + + ret = asprintf(&path, "%s/%s", dir, attr); + if (ret < 0) + return -1; + + ret = __nvme_set_attr(path, value); + free(path); + return ret; +} + +static char *__nvme_get_attr(const char *path) +{ + char value[4096] = { 0 }; + int ret, fd; + + fd = open(path, O_RDONLY); + if (fd < 0) + return NULL; + + memset(value, 0, sizeof(value)); + ret = read(fd, value, sizeof(value) - 1); + if (ret < 0) { + close(fd); + return NULL; + } + + if (value[strlen(value) - 1] == '\n') + value[strlen(value) - 1] = '\0'; + while (strlen(value) > 0 && value[strlen(value) - 1] == ' ') + value[strlen(value) - 1] = '\0'; + + close(fd); + return strdup(value); +} + +static char *nvme_get_attr(const char *dir, const char *attr) +{ + char *path, *value; + int ret; + + ret = asprintf(&path, "%s/%s", dir, attr); + if (ret < 0) + return NULL; + + value = __nvme_get_attr(path); + free(path); + return value; +} + +char *nvme_get_subsys_attr(nvme_subsystem_t s, const char *attr) +{ + return nvme_get_attr(nvme_subsystem_get_sysfs_dir(s), attr); +} + +char *nvme_get_ctrl_attr(nvme_ctrl_t c, const char *attr) +{ + return nvme_get_attr(nvme_ctrl_get_sysfs_dir(c), attr); +} + +char *nvme_get_ns_attr(nvme_ns_t n, const char *attr) +{ + return nvme_get_attr(nvme_ns_get_sysfs_dir(n), attr); +} + +char *nvme_get_path_attr(nvme_path_t p, const char *attr) +{ + return nvme_get_attr(nvme_path_get_sysfs_dir(p), attr); +} diff --git a/lib/nvme/util.h b/lib/nvme/util.h new file mode 100644 index 0000000000..96f9421865 --- /dev/null +++ b/lib/nvme/util.h @@ -0,0 +1,133 @@ +#ifndef _LIBNVME_UTIL_H +#define _LIBNVME_UTIL_H + +#include +#include + +#include "types.h" + +/** + * nvme_status_type() - Returns SCT(Status Code Type) in status field of + * the completion queue entry. + * @status: return value from nvme passthrough commands, which is the nvme + * status field, located at DW3 in completion queue entry + */ +static inline __u8 nvme_status_type(__u16 status) +{ + return (status & NVME_SCT_MASK) >> 8; +} + +/** + * nvme_status_to_string() - + */ +const char *nvme_status_to_string(int status, bool fabrics); + +/* + * nvme_status_to_errno() - Converts nvme return status to errno + * @status: >= 0 for nvme status field in completion queue entry, + * < 0 for linux internal errors + * @fabrics: true if given status is for fabrics + * + * Notes: This function will convert a given status to an errno + */ +__u8 nvme_status_to_errno(int status, bool fabrics); + +/** + * nvme_fw_download_split() - + */ +int nvme_fw_download_split(int fd, __u32 size, __u32 xfer, __u32 offset, + void *buf); + +/** + * nvme_get_telemetry_log() - + */ +int nvme_get_telemetry_log(int fd, bool create, bool ctrl, int data_area, + void **buf, __u32 *log_size); + +/** + * nvme_setup_id_ns() - + */ +void nvme_setup_id_ns(struct nvme_id_ns *ns, __u64 nsze, __u64 ncap, __u8 flbas, + __u8 dps, __u8 nmic, __u32 anagrpid, __u16 nvmsetid); + +/** + * nvme_setup_ctrl_list() - + */ +void nvme_setup_ctrl_list(struct nvme_ctrl_list *cntlist, __u16 num_ctrls, + __u16 *ctrlist); + +/** + * nvme_dsm_range() - Constructs a data set range structure + * @dsm: DSM range array + * @ctx_attrs: Array of context attributes + * @llbas: Array of length in logical blocks + * @slbas: Array of starting logical blocks + * @nr_ranges: The size of the dsm arrays + * + * Each array must be the same size of size 'nr_ranges'. + * + * Return: The nvme command status if a response was received or -errno + * otherwise. + */ +void nvme_setup_dsm_range(struct nvme_dsm_range *dsm, __u32 *ctx_attrs, + __u32 *llbas, __u64 *slbas, __u16 nr_ranges); + +/** + * nvme_get_log_page() - + */ +int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, + __u32 data_len, void *data); + +/** + * nvme_get_ana_log_len() - + */ +int nvme_get_ana_log_len(int fd, size_t *analen); + +/** + * nvme_namespace_attach_ctrls() - Attach namespace to controller(s) + * @fd: File descriptor of nvme device + * @nsid: Namespace ID to attach + * @num_ctrls: Number of controllers in ctrlist + * @ctrlist: List of controller IDs to perform the attach action + * + * Return: The nvme command status if a response was received or -errno + * otherwise. + */ +int nvme_namespace_attach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist); + +/** + * nvme_namespace_detach_ctrls() - Detach namespace from controller(s) + * @fd: File descriptor of nvme device + * @nsid: Namespace ID to detach + * @num_ctrls: Number of controllers in ctrlist + * @ctrlist: List of controller IDs to perform the detach action + * + * Return: The nvme command status if a response was received or -errno + * otherwise. + */ +int nvme_namespace_detach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist); + +/** + * nvme_get_feature_length() - + */ +int nvme_get_feature_length(int fid, __u32 cdw11, __u32 *len); + +/** + * nvme_get_directive_receive_length() - + */ +int nvme_get_directive_receive_length(__u8 dtype, __u8 doper, __u32 *len); + +/** + * nvme_open() - Open an nvme controller or namespace device + * @name: The basename of the device to open + * + * This will look for the handle in /dev/ and validate the name and filetype + * match linux conventions. + * + * Return: A file descriptor for the device on a successful open, or -1 with + * errno set otherwise. + */ +int nvme_open(const char *name); + +int nvme_set_attr(const char *dir, const char *attr, const char *value); +#endif /* _LIBNVME_UTIL_H */ diff --git a/test/test.c b/test/test.c new file mode 100644 index 0000000000..0f1bf29c82 --- /dev/null +++ b/test/test.c @@ -0,0 +1,426 @@ +#include +#include +#include +#include + +static char *nqn_match; + +static bool nvme_match_subsysnqn_filter(nvme_subsystem_t s) +{ + return strcmp(nvme_subsystem_get_nqn(s), nqn_match) == 0; +} + +static int test_ctrl(nvme_ctrl_t c) +{ + static __u8 buf[0x1000]; + + enum nvme_get_features_sel sel = NVME_GET_FEATURES_SEL_CURRENT; + int ret, temp, fd = nvme_ctrl_get_fd(c); + struct nvme_error_log_page error[64]; + struct nvme_smart_log smart = { 0 }; + struct nvme_firmware_slot fw = { 0 }; + struct nvme_ns_list ns_list = { 0 }; + struct nvme_cmd_effects_log cfx = { 0 }; + struct nvme_self_test_log st = { 0 }; + struct nvme_telemetry_log *telem = (void *)buf; + struct nvme_endurance_group_log eglog = { 0 }; + struct nvme_ana_group_desc *analog = (void *)buf; + struct nvme_resv_notification_log resvnotify = { 0 }; + struct nvme_sanitize_log_page sanlog = { 0 }; + + struct nvme_id_uuid_list uuid = { 0 }; + struct nvme_id_ns_granularity_list gran = { 0 }; + struct nvme_secondary_ctrl_list sec = { 0 }; + struct nvme_primary_ctrl_cap prim = { 0 }; + struct nvme_ctrl_list ctrlist = { 0 }; + struct nvme_id_ctrl id = { 0 }; + + __u32 result; + + ret = nvme_ctrl_identify(c, &id); + if (ret) { + printf("ERROR: no identify for:%s\n", nvme_ctrl_get_name(c)); + return ret; + } + + ret = nvme_get_log_smart(fd, NVME_NSID_ALL, true, &smart); + if (ret) { + printf("ERROR: no smart log for:%s %x\n", nvme_ctrl_get_name(c), ret); + return ret; + } + + temp = ((smart.temperature[1] << 8) | smart.temperature[0]) - 273; + printf("Controller:%s\n", nvme_ctrl_get_name(c)); + printf("\nIdentify:\n"); + printf(" vid:%04x ssvid:%04x oacs:%x lpa%x\n", + le16_to_cpu(id.vid), le16_to_cpu(id.ssvid), + id.oacs, id.lpa); + printf(" sn:%-.20s model:%-.40s\n", id.sn, id.mn); + + ret = nvme_identify_allocated_ns_list(fd, 0, &ns_list); + if (!ret) + printf(" Allocated NS List:\n"); + else + printf(" ERROR: Allocated NS List:%x\n", ret); + ret = nvme_identify_active_ns_list(fd, 0, &ns_list); + if (!ret) + printf(" Active NS List:\n"); + else + printf(" ERROR: Active NS List:%x\n", ret); + ret = nvme_identify_ctrl_list(fd, 0, &ctrlist); + if (!ret) + printf(" Ctrl List:\n"); + else + printf(" ERROR: CtrlList:%x\n", ret); + ret = nvme_identify_nsid_ctrl_list(fd, 1, 0, &ctrlist); + if (!ret) + printf(" NSID Ctrl List:\n"); + else + printf(" ERROR: NSID CtrlList:%x\n", ret); + ret = nvme_identify_primary_ctrl(fd, 0, &prim); + if (!ret) + printf(" Identify Primary:\n"); + else + printf(" ERROR: Identify Primary:%x\n", ret); + ret = nvme_identify_secondary_ctrl_list(fd, 0, &sec); + if (!ret) + printf(" Identify Secondary:\n"); + else + printf(" ERROR: Identify Secondary:%x\n", ret); + ret = nvme_identify_ns_granularity(fd, &gran); + if (!ret) + printf(" Identify NS granularity:\n"); + else + printf(" ERROR: Identify NS granularity:%x\n", ret); + ret = nvme_identify_uuid(fd, &uuid); + if (!ret) + printf(" Identify UUID List:\n"); + else + printf(" ERROR: Identify UUID List:%x\n", ret); + + printf("\nLogs\n"); + printf(" SMART: Current temperature:%d percent used:%d%%\n", temp, + smart.percent_used); + ret = nvme_get_log_sanitize(fd, true, &sanlog); + if (!ret) + printf(" Sanitize Log:\n"); + else + printf(" ERROR: Sanitize Log:%x\n", ret); + ret = nvme_get_log_reservation(fd, true, &resvnotify); + if (!ret) + printf(" Reservation Log\n"); + else + printf(" ERROR: Reservation Log :%x\n", ret); + ret = nvme_get_log_ana_groups(fd, true, sizeof(buf), analog); + if (!ret) + printf(" ANA Groups\n"); + else + printf(" ERROR: ANA Groups :%x\n", ret); + ret = nvme_get_log_endurance_group(fd, 0, &eglog); + if (!ret) + printf(" Endurance Group\n"); + else + printf(" ERROR: Endurance Group :%x\n", ret); + ret = nvme_get_log_telemetry_ctrl(fd, true, 0, sizeof(buf), telem); + if (!ret) + printf(" Telemetry Controller\n"); + else + printf(" ERROR: Telemetry Controller :%x\n", ret); + ret = nvme_get_log_device_self_test(fd, &st); + if (!ret) + printf(" Device Self Test\n"); + else + printf(" ERROR: Device Self Test :%x\n", ret); + ret = nvme_get_log_cmd_effects(fd, &cfx); + if (!ret) + printf(" Command Effects\n"); + else + printf(" ERROR: Command Effects :%x\n", ret); + ret = nvme_get_log_changed_ns_list(fd, true, &ns_list); + if (!ret) + printf(" Change NS List\n"); + else + printf(" ERROR: Change NS List :%x\n", ret); + ret = nvme_get_log_fw_slot(fd, true, &fw); + if (ret) + printf(" FW Slot\n"); + else + printf(" ERROR: FW Slot :%x\n", ret); + ret = nvme_get_log_error(fd, 64, true, error); + if (!ret) + printf(" Error Log\n"); + else + printf(" ERROR: Error Log :%x\n", ret); + printf("\nFeatures\n"); + ret = nvme_get_features_arbitration(fd, sel, &result); + if (!ret) + printf(" Arbitration:%x\n", result); + else if (ret > 0) + printf(" ERROR: Arbitration:%x\n", ret); + ret = nvme_get_features_power_mgmt(fd, sel, &result); + if (!ret) + printf(" Power Management:%x\n", result); + else if (ret > 0) + printf(" ERROR: Power Management:%x\n", ret); + ret = nvme_get_features_temp_thresh(fd, sel, &result); + if (!ret) + printf(" Temperature Threshold:%x\n", result); + else if (ret > 0) + printf(" ERROR: Temperature Threshold:%x\n", ret); + ret = nvme_get_features_err_recovery(fd, sel, &result); + if (!ret) + printf(" Error Recovery:%x\n", result); + else if (ret > 0) + printf(" ERROR: Error Recovery:%x\n", ret); + ret = nvme_get_features_volatile_wc(fd, sel, &result); + if (!ret) + printf(" Volatile Write Cache:%x\n", result); + else if (ret > 0) + printf(" ERROR: Volatile Write Cache:%x\n", ret); + ret = nvme_get_features_num_queues(fd, sel, &result); + if (!ret) + printf(" Number of Queues:%x\n", result); + else if (ret > 0) + printf(" ERROR: Number of Queues:%x\n", ret); + ret = nvme_get_features_irq_coalesce(fd, sel, &result); + if (!ret) + printf(" IRQ Coalescing:%x\n", result); + else if (ret > 0) + printf(" ERROR: IRQ Coalescing:%x\n", ret); + ret = nvme_get_features_write_atomic(fd, sel, &result); + if (!ret) + printf(" Write Atomic:%x\n", result); + else if (ret > 0) + printf(" ERROR: Write Atomic:%x\n", ret); + ret = nvme_get_features_async_event(fd, sel, &result); + if (!ret) + printf(" Asycn Event Config:%x\n", result); + else if (ret > 0) + printf(" ERROR: Asycn Event Config:%x\n", ret); + ret = nvme_get_features_hctm(fd, sel, &result); + if (!ret) + printf(" HCTM:%x\n", result); + else if (ret > 0) + printf(" ERROR: HCTM:%x\n", ret); + ret = nvme_get_features_nopsc(fd, sel, &result); + if (!ret) + printf(" NOP Power State Config:%x\n", result); + else if (ret > 0) + printf(" ERROR: NOP Power State Configrbitration:%x\n", ret); + ret = nvme_get_features_rrl(fd, sel, &result); + if (!ret) + printf(" Read Recover Levels:%x\n", result); + else if (ret > 0) + printf(" ERROR: Read Recover Levels:%x\n", ret); + ret = nvme_get_features_lba_sts_interval(fd, sel, &result); + if (!ret) + printf(" LBA Status Interval:%x\n", result); + else if (ret > 0) + printf(" ERROR: LBA Status Interval:%x\n", ret); + ret = nvme_get_features_sanitize(fd, sel, &result); + if (!ret) + printf(" Sanitize:%x\n", result); + else if (ret > 0) + printf(" ERROR: SW Progress Marker:%x\n", ret); + ret = nvme_get_features_sw_progress(fd, sel, &result); + if (!ret) + printf(" SW Progress Marker:%x\n", result); + else if (ret > 0) + printf(" ERROR: Sanitize:%x\n", ret); + ret = nvme_get_features_resv_mask(fd, sel, &result); + if (!ret) + printf(" Reservation Mask:%x\n", result); + else if (ret > 0) + printf(" ERROR: Reservation Mask:%x\n", ret); + ret = nvme_get_features_resv_persist(fd, sel, &result); + if (!ret) + printf(" Reservation Persistence:%x\n", result); + else if (ret > 0) + printf(" ERROR: Reservation Persistence:%x\n", ret); + ret = nvme_get_features_write_protect(fd, 1, sel, &result); + if (!ret) + printf(" Write Protect:%x\n", result); + else if (ret > 0) + printf(" ERROR: Write Protect:%x\n", ret); + return 0; +} + +static int test_namespace(nvme_ns_t n) +{ + struct nvme_id_ns ns = { 0 }, allocated = { 0 }; + int nsid = nvme_ns_get_nsid(n); + int ret, fd = nvme_ns_get_fd(n); + struct nvme_ns_id_desc descs = { 0 }; + + ret = nvme_ns_identify(n, &ns); + if (ret) + return ret; + + printf("%s: nsze:%lx lba size:%d\n", nvme_ns_get_name(n), le64_to_cpu(ns.nsze), + 1 << ns.lbaf[ns.flbas & NVME_NS_FLBAS_LBA_MASK].ds); + + ret = nvme_identify_allocated_ns(fd, nsid, &allocated); + if (!ret) + printf(" Identify allocated ns\n"); + else + printf(" ERROR: Identify allocated ns:%x\n", ret); + ret = nvme_identify_ns_descs(fd, nsid, &descs); + if (!ret) + printf(" Identify NS Descriptorss\n"); + else + printf(" ERROR: Identify NS Descriptors:%x\n", ret); + return 0; +} + +int main() +{ + nvme_root_t r; + nvme_subsystem_t s; + nvme_ctrl_t c; + nvme_path_t p; + nvme_ns_t n; + + r = nvme_scan(); + if (!r) + return -1; + + printf("Test walking the topology\n"); + nvme_for_each_subsystem(r, s) { + printf("%s - NQN=%s\n", nvme_subsystem_get_name(s), + nvme_subsystem_get_nqn(s)); + nvme_subsystem_for_each_ctrl(s, c) { + printf(" +- %s %s %s %s\n", nvme_ctrl_get_name(c), + nvme_ctrl_get_transport(c), + nvme_ctrl_get_address(c), + nvme_ctrl_get_state(c)); + + nvme_ctrl_for_each_ns(c, n) + printf(" +- %s lba size:%d lba max:%lu\n", + nvme_ns_get_name(n), nvme_ns_get_lba_size(n), + nvme_ns_get_lba_count(n)); + + nvme_ctrl_for_each_path(c, p) + printf(" +- %s %s\n", nvme_path_get_name(p), + nvme_path_get_ana_state(p)); + } + + nvme_subsystem_for_each_ns(s, n) { + printf(" +- %s lba size:%d lba max:%lu\n", + nvme_ns_get_name(n), nvme_ns_get_lba_size(n), + nvme_ns_get_lba_count(n)); + } + } + printf("\n"); + + nvme_for_each_subsystem(r, s) { + bool first = true; + printf("%s %s ", nvme_subsystem_get_name(s), + nvme_subsystem_get_nqn(s)); + + nvme_subsystem_for_each_ctrl(s, c) { + printf("%s%s", first ? "": ", ", nvme_ctrl_get_name(c)); + first = false; + } + printf("\n"); + } + printf("\n"); + + nvme_for_each_subsystem(r, s) { + nvme_subsystem_for_each_ctrl(s, c) { + bool first = true; + + printf("%s %s %s %s %s %s %s ", nvme_ctrl_get_name(c), + nvme_ctrl_get_serial(c), nvme_ctrl_get_model(c), + nvme_ctrl_get_firmware(c), + nvme_ctrl_get_transport(c), + nvme_ctrl_get_address(c), + nvme_subsystem_get_name(s)); + + nvme_ctrl_for_each_ns(c, n) { + printf("%s%s", first ? "": ", ", + nvme_ns_get_name(n)); + first = false; + } + + nvme_ctrl_for_each_path(c, p) { + printf("%s%s", first ? "": ", ", + nvme_ns_get_name(nvme_path_get_ns(p))); + first = false; + } + printf("\n"); + } + } + printf("\n"); + + nvme_for_each_subsystem(r, s) { + nvme_subsystem_for_each_ctrl(s, c) + nvme_ctrl_for_each_ns(c, n) + printf("%s %d %lu/%lu %d %s\n", + nvme_ns_get_name(n), + nvme_ns_get_nsid(n), + nvme_ns_get_lba_count(n), + nvme_ns_get_lba_util(n), + nvme_ns_get_lba_size(n), + nvme_ctrl_get_name(c)); + + nvme_subsystem_for_each_ns(s, n) { + bool first = true; + + printf("%s %d %lu/%lu %d ", nvme_ns_get_name(n), + nvme_ns_get_nsid(n), + nvme_ns_get_lba_count(n), + nvme_ns_get_lba_util(n), + nvme_ns_get_lba_size(n)); + nvme_subsystem_for_each_ctrl(s, c) { + printf("%s%s", first ? "" : ", ", + nvme_ctrl_get_name(c)); + first = false; + } + printf("\n"); + } + } + printf("\n"); + + printf("Test identification, logs, and features\n"); + nvme_for_each_subsystem(r, s) { + nvme_subsystem_for_each_ctrl(s, c) { + test_ctrl(c); + nvme_ctrl_for_each_ns(c, n) + test_namespace(n); + printf("\n"); + } + nvme_subsystem_for_each_ns(s, n) + test_namespace(n); + } + printf("\n"); + + nvme_free_tree(r); + + printf("Test filter for common loop back target\n"); + nqn_match = "testnqn"; + r = nvme_scan_filter(nvme_match_subsysnqn_filter); + nvme_for_each_subsystem(r, s) { + printf("%s - NQN=%s\n", nvme_subsystem_get_name(s), + nvme_subsystem_get_nqn(s)); + nvme_subsystem_for_each_ctrl(s, c) { + printf(" `- %s %s %s %s\n", nvme_ctrl_get_name(c), + nvme_ctrl_get_transport(c), + nvme_ctrl_get_address(c), + nvme_ctrl_get_state(c)); + } + } + printf("\n"); + nvme_free_tree(r); + + printf("Test scan specific controller\n"); + c = nvme_scan_ctrl("nvme4"); + if (c) { + printf("%s %s %s %s\n", nvme_ctrl_get_name(c), + nvme_ctrl_get_transport(c), + nvme_ctrl_get_address(c), + nvme_ctrl_get_state(c)); + nvme_free_ctrl(c); + } + + return 0; +} From b4cd4f848e70f22682f1cb3de311f473981d278b Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 6 Feb 2020 12:53:30 -0800 Subject: [PATCH 0002/1564] Add a telemetry scan example Copy the liburing directory structure and start adding examples. The first example monitors all devices for telemetry events, and if available will write out the telemetry log to a file in /var/log/. While developing the example, some other misc fixes and updates were added to the library code. Signed-off-by: Keith Busch --- Makefile | 73 +++++- Makefile.quiet | 10 + configure | 191 +++++++++++++++ examples/Makefile | 22 ++ examples/nvme-telemetry.c | 158 ++++++++++++ lib/libnvme.pc.in => libnvme.pc.in | 2 +- lib/libnvme.spec => libnvme.spec | 24 +- {lib => src}/Makefile | 0 {lib => src}/libnvme.h | 0 {lib => src}/libnvme.map | 0 {lib => src}/nvme/cmd.h | 371 +++++++++++++++++++++++++++-- {lib => src}/nvme/fabrics.c | 2 +- {lib => src}/nvme/fabrics.h | 0 {lib => src}/nvme/filters.c | 0 {lib => src}/nvme/filters.h | 0 {lib => src}/nvme/ioctl.c | 2 +- {lib => src}/nvme/ioctl.h | 0 {lib => src}/nvme/private.h | 0 {lib => src}/nvme/tree.c | 0 {lib => src}/nvme/tree.h | 224 ++++++++++++++++- {lib => src}/nvme/types.h | 94 ++++++-- {lib => src}/nvme/util.c | 0 {lib => src}/nvme/util.h | 0 test/Makefile | 22 ++ 24 files changed, 1124 insertions(+), 71 deletions(-) create mode 100644 Makefile.quiet create mode 100755 configure create mode 100644 examples/Makefile create mode 100644 examples/nvme-telemetry.c rename lib/libnvme.pc.in => libnvme.pc.in (84%) rename lib/libnvme.spec => libnvme.spec (77%) rename {lib => src}/Makefile (100%) rename {lib => src}/libnvme.h (100%) rename {lib => src}/libnvme.map (100%) rename {lib => src}/nvme/cmd.h (82%) rename {lib => src}/nvme/fabrics.c (99%) rename {lib => src}/nvme/fabrics.h (100%) rename {lib => src}/nvme/filters.c (100%) rename {lib => src}/nvme/filters.h (100%) rename {lib => src}/nvme/ioctl.c (99%) rename {lib => src}/nvme/ioctl.h (100%) rename {lib => src}/nvme/private.h (100%) rename {lib => src}/nvme/tree.c (100%) rename {lib => src}/nvme/tree.h (77%) rename {lib => src}/nvme/types.h (95%) rename {lib => src}/nvme/util.c (100%) rename {lib => src}/nvme/util.h (100%) create mode 100644 test/Makefile diff --git a/Makefile b/Makefile index 800b9e8850..32bc5afca1 100644 --- a/Makefile +++ b/Makefile @@ -1,17 +1,70 @@ -CFLAGS = -O2 -g -Wall -Werror -std=gnu99 -D_GNU_SOURCE -LDFLAGS = -Ilib -Llib -lnvme +NAME=libnvme +SPECFILE=$(NAME).spec +VERSION=$(shell awk '/Version:/ { print $$2 }' $(SPECFILE)) +TAG = $(NAME)-$(VERSION) +RPMBUILD=$(shell `which rpmbuild >&/dev/null` && echo "rpmbuild" || echo "rpm") -QUIET_CC = @echo ' ' CC $@; +INSTALL=install -test: test/test.c libnvme - $(QUIET_CC)$(CC) $(CPPFLAGS) $(CFLAGS) $< -o test/test $(LDFLAGS) +default: all -libnvme: - @$(MAKE) -C lib/ +all: + @$(MAKE) -C src + @$(MAKE) -C test + @$(MAKE) -C examples + +runtests: all + @$(MAKE) -C test runtests +runtests-loop: + @$(MAKE) -C test runtests-loop + +config-host.mak: configure + @if [ ! -e "$@" ]; then \ + echo "Running configure ..."; \ + ./configure; \ + else \ + echo "$@ is out-of-date, running configure"; \ + sed -n "/.*Configured with/s/[^:]*: //p" "$@" | sh; \ + fi + +ifneq ($(MAKECMDGOALS),clean) +include config-host.mak +endif + +%.pc: %.pc.in config-host.mak $(SPECFILE) + sed -e "s%@prefix@%$(prefix)%g" \ + -e "s%@libdir@%$(libdir)%g" \ + -e "s%@includedir@%$(includedir)%g" \ + -e "s%@NAME@%$(NAME)%g" \ + -e "s%@VERSION@%$(VERSION)%g" \ + $< >$@ + +install: $(NAME).pc + @$(MAKE) -C src install prefix=$(DESTDIR)$(prefix) includedir=$(DESTDIR)$(includedir) libdir=$(DESTDIR)$(libdir) + $(INSTALL) -D -m 644 $(NAME).pc $(DESTDIR)$(libdir)/pkgconfig/$(NAME).pc + $(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man2 + $(INSTALL) -m 644 man/*.2 $(DESTDIR)$(mandir)/man2 + +install-tests: + @$(MAKE) -C test install prefix=$(DESTDIR)$(prefix) datadir=$(DESTDIR)$(datadir) clean: - rm -f test/test - $(MAKE) -C lib clean + @rm -f config-host.mak config-host.h cscope.out $(NAME).pc + @$(MAKE) -C src clean + @$(MAKE) -C test clean + @$(MAKE) -C examples clean + +cscope: + @cscope -b -R + +tag-archive: + @git tag $(TAG) + +create-archive: + @git archive --prefix=$(NAME)-$(VERSION)/ -o $(NAME)-$(VERSION).tar.gz $(TAG) + @echo "The final archive is ./$(NAME)-$(VERSION).tar.gz." +archive: clean tag-archive create-archive -.PHONY: libnvme test +srpm: create-archive + $(RPMBUILD) --define "_sourcedir `pwd`" --define "_srcrpmdir `pwd`" --nodeps -bs $(SPECFILE) diff --git a/Makefile.quiet b/Makefile.quiet new file mode 100644 index 0000000000..8eac349a84 --- /dev/null +++ b/Makefile.quiet @@ -0,0 +1,10 @@ +ifneq ($(findstring $(MAKEFLAGS),s),s) +ifndef V + QUIET_CC = @echo ' ' CC $@; + QUIET_LINK = @echo ' ' LINK $@; + QUIET_AR = @echo ' ' AR $@; + QUIET_RANLIB = @echo '' RANLIB $@; +endif +endif + + diff --git a/configure b/configure new file mode 100755 index 0000000000..63d26a50c9 --- /dev/null +++ b/configure @@ -0,0 +1,191 @@ +#!/bin/sh +# +# +if test ! -z "$TMPDIR" ; then + TMPDIR1="${TMPDIR}" +elif test ! -z "$TEMPDIR" ; then + TMPDIR1="${TEMPDIR}" +else + TMPDIR1="/tmp" +fi + +cc=gcc +ld=ld + +for opt do + optarg=$(expr "x$opt" : 'x[^=]*=\(.*\)') + case "$opt" in + --help|-h) show_help=yes + ;; + --prefix=*) prefix="$optarg" + ;; + --includedir=*) includedir="$optarg" + ;; + --libdir=*) libdir="$optarg" + ;; + --mandir=*) mandir="$optarg" + ;; + --datadir=*) datadir="$optarg" + ;; + *) + echo "ERROR: unkown option $opt" + echo "Try '$0 --help' for more information" + exit 1 + ;; + esac +done + +if test -z "$prefix"; then + prefix=/usr +fi +if test -z "$includedir"; then + includedir="$prefix/include" +fi +if test -z "$libdir"; then + libdir="$prefix/lib" +fi +if test -z "$mandir"; then + mandir="$prefix/man" +fi +if test -z "$datadir"; then + datadir="$prefix/share" +fi + +if test "$show_help" = "yes"; then +cat < $config_host_h +echo " * Automatically generated by configure - do not modify" >> $config_host_h +printf " * Configured with:" >> $config_host_h +printf " * '%s'" "$0" "$@" >> $config_host_h +echo "" >> $config_host_h +echo " */" >> $config_host_h + +echo "# Automatically generated by configure - do not modify" > $config_host_mak +printf "# Configured with:" >> $config_host_mak +printf " '%s'" "$0" "$@" >> $config_host_mak +echo >> $config_host_mak + +do_cc() { + # Run the compiler, capturing its output to the log. + echo $cc "$@" >> config.log + $cc "$@" >> config.log 2>&1 || return $? + # Test passed. If this is an --enable-werror build, rerun + # the test with -Werror and bail out if it fails. This + # makes warning-generating-errors in configure test code + # obvious to developers. + if test "$werror" != "yes"; then + return 0 + fi + # Don't bother rerunning the compile if we were already using -Werror + case "$*" in + *-Werror*) + return 0 + ;; + esac + echo $cc -Werror "$@" >> config.log + $cc -Werror "$@" >> config.log 2>&1 && return $? + echo "ERROR: configure test passed without -Werror but failed with -Werror." + echo "This is probably a bug in the configure script. The failing command" + echo "will be at the bottom of config.log." + fatal "You can run configure with --disable-werror to bypass this check." +} + +compile_object() { + do_cc $CFLAGS -c -o $TMPO $TMPC +} + +compile_prog() { + local_cflags="$1" + local_ldflags="$2 $LIBS" + echo "Compiling test case $3" >> config.log + do_cc $CFLAGS $local_cflags -o $TMPE $TMPC $LDFLAGS $local_ldflags +} + +has() { + type "$1" >/dev/null 2>&1 +} + +output_mak() { + echo "$1=$2" >> $config_host_mak +} + +output_sym() { + output_mak "$1" "y" + echo "#define $1" >> $config_host_h +} + +print_and_output_mak() { + print_config "$1" "$2" + output_mak "$1" "$2" +} + +print_and_output_mak "prefix" "$prefix" +print_and_output_mak "includedir" "$includedir" +print_and_output_mak "libdir" "$libdir" +print_and_output_mak "mandir" "$mandir" +print_and_output_mak "datadir" "$datadir" + +########################################## +# check for libuuid +libuuid="no" +${ld} -o /dev/null -luuid >/dev/null 2>&1 +if [ $? -eq 0 ]; then + libuuid="yes" +fi +print_config "libuuid" "${libuuid}" + +########################################## +# check for SystemD +havesystemd="no" +pkg-config --exists systemd --atleast-version=232 +if [ $? -eq 0 ]; then + havesystemd="yes" +fi +print_config "havesystemd" "${havesystemd}" + +if test "$libuuid" = "yes"; then + output_sym "LIBUUID" + echo "override LDFLAGS += -luuid" >> $config_host_mak + echo "override LIB_DEPENDS += uuid" >> $config_host_mak +fi +if test "$havesystemd" = "yes"; then + output_sym "HAVE_SYSTEMD" + echo "override LDFLAGS += -lsystemd" >> $config_host_mak +fi diff --git a/examples/Makefile b/examples/Makefile new file mode 100644 index 0000000000..baa7b08310 --- /dev/null +++ b/examples/Makefile @@ -0,0 +1,22 @@ +CFLAGS ?= -g -O2 +override CFLAGS += -Wall -D_GNU_SOURCE -L../src/ -I../src/ + +include ../Makefile.quiet + +ifneq ($(MAKECMDGOALS),clean) +include ../config-host.mak +endif + +all_targets += nvme-telemetry + +all: $(all_targets) + +test_srcs := nvme-telemetry + +test_objs := $(patsubst %.c,%.ol,$(test_srcs)) + +%: %.c + $(QUIET_CC)$(CC) $(CFLAGS) -o $@ $< -lnvme + +clean: + @rm -f $(all_targets) $(test_objs) diff --git a/examples/nvme-telemetry.c b/examples/nvme-telemetry.c new file mode 100644 index 0000000000..1705462a6c --- /dev/null +++ b/examples/nvme-telemetry.c @@ -0,0 +1,158 @@ +/** + * Open all nvme controller's uevent and listen for changes. If NVME_AEN event + * is observed with controller telemetry data, read the log and save it to a + * file in /var/log/ with the device's unique name and epoch timestamp. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +struct events { + nvme_ctrl_t c; + int uevent_fd; +}; + +static int open_uevent(nvme_ctrl_t c) +{ + char buf[0x1000]; + if (snprintf(buf, sizeof(buf), "%s/uevent", nvme_ctrl_get_sysfs_dir(c)) < 0) + return -1; + return open(buf, O_RDONLY); +} + +static void save_telemetry(nvme_ctrl_t c) +{ + char buf[0x1000]; + __u32 log_size; + int ret, fd; + void *log; + time_t s; + + ret = nvme_get_telemetry_log(nvme_ctrl_get_fd(c), false, true, 3, &log, + &log_size); + if (ret) + return; + + /* Clear the log (rae == false) to see new telemetry events later */ + nvme_get_log_telemetry_ctrl(nvme_ctrl_get_fd(c), false, 0, sizeof(buf), + buf); + memset(buf, 0, sizeof(buf)); + + s = time(NULL); + ret = snprintf(buf, sizeof(buf), "/var/log/%s-telemetry-%ld", + nvme_ctrl_get_subsysnqn(c), s); + if (ret < 0) { + free(log); + return; + } + + fd = open(buf, O_CREAT|O_WRONLY, S_IRUSR|S_IRGRP); + if (fd < 0) { + free(log); + return; + } + + ret = write(fd, log, log_size); + if (ret < 0) + printf("failed to write telemetry log\n"); + else + printf("telemetry log save as %s, wrote:%d size:%d\n", buf, + ret, log_size); + + close(fd); + free(log); +} + +static void check_telemetry(nvme_ctrl_t c, int ufd) +{ + char buf[0x1000] = { 0 }; + char *p, *ptr; + + if (read(ufd, buf, sizeof(buf)) < 0) + return; + + ptr = buf; + while ((p = strsep(&ptr, "\n")) != NULL) { + __u32 aen, type, info, lid; + + if (sscanf(p, "NVME_AEN=0x%08x", &aen) != 1) + break; + + type = aen & 0x07; + info = (aen >> 8) & 0xff; + lid = (aen >> 16) & 0xff; + + printf("%s: aen type:%x info:%x lid:%d\n", + nvme_ctrl_get_name(c), type, info, lid); + if (type == NVME_AER_NOTICE && + info == NVME_AER_NOTICE_TELEMETRY) + save_telemetry(c); + } +} + +static void wait_events(fd_set *fds, struct events *e, int nr) +{ + int ret, i; + + for (i = 0; i < nr; i++) + check_telemetry(e[i].c, e[i].uevent_fd); + + while (1) { + ret = select(nr, fds, NULL, NULL, NULL); + if (ret < 0) + return; + + for (i = 0; i < nr; i++) { + if (!FD_ISSET(e[i].uevent_fd, fds)) + continue; + check_telemetry(e[i].c, e[i].uevent_fd); + } + } +} + +int main() +{ + struct events *e; + fd_set fds; + int i = 0; + + nvme_subsystem_t s; + nvme_ctrl_t c; + nvme_root_t r; + + r = nvme_scan(); + if (!r) + return EXIT_FAILURE; + + nvme_for_each_subsystem(r, s) + nvme_subsystem_for_each_ctrl(s, c) + i++; + + e = calloc(i, sizeof(e)); + FD_ZERO(&fds); + i = 0; + + nvme_for_each_subsystem(r, s) { + nvme_subsystem_for_each_ctrl(s, c) { + int fd = open_uevent(c); + + if (fd < 0) + continue; + FD_SET(fd, &fds); + e[i].uevent_fd = fd; + e[i].c = c; + i++; + } + } + + wait_events(&fds, e, i); + nvme_free_tree(r); + free(e); + + return EXIT_SUCCESS; +} diff --git a/lib/libnvme.pc.in b/libnvme.pc.in similarity index 84% rename from lib/libnvme.pc.in rename to libnvme.pc.in index 224dd54f20..a1867aacf3 100644 --- a/lib/libnvme.pc.in +++ b/libnvme.pc.in @@ -6,7 +6,7 @@ includedir=@includedir@ Name: @NAME@ Version: @VERSION@ Description: Manage "libnvme" subsystem devices (Non-volatile Memory Express) -URL: http://github.com/linux-nvme/nvme-cli/ +URL: http://github.com/linux-nvme/libnvme/ Libs: -L${libdir} -lnvme Cflags: -I${includedir} diff --git a/lib/libnvme.spec b/libnvme.spec similarity index 77% rename from lib/libnvme.spec rename to libnvme.spec index d131af9fcc..f3407d88c7 100644 --- a/lib/libnvme.spec +++ b/libnvme.spec @@ -1,44 +1,36 @@ Name: libnvme Version: 0.1 -Release: 1 +Release: 0 Summary: Linux-native nvme device management library License: LGPLv2+ -Group: System Environment/Libraries Source: %{name}-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-root URL: http://github.com/linux-nvme/nvme-cli +BuildRequires: gcc %description -Provides library functions for accessing and managing nvme devices. +Provides library functions for accessing and managing nvme devices on a Linux +system. %package devel Summary: Development files for Linux-native nvme -Group: Development/System Requires: libnvme Provides: libnvme.so.1 %description devel This package provides header files to include and libraries to link with -for the Linux-native nvme. +for Linux-native nvme device maangement. %prep %setup %build ./configure --prefix=/usr --libdir=/%{_libdir} --mandir=/usr/share/man -make -%install -[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT - -make install DESTDIR=$RPM_BUILD_ROOT - -%clean -[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT +%make_build -%post -p /sbin/ldconfig - -%postun -p /sbin/ldconfig +%install +%make_install %files %defattr(-,root,root) diff --git a/lib/Makefile b/src/Makefile similarity index 100% rename from lib/Makefile rename to src/Makefile diff --git a/lib/libnvme.h b/src/libnvme.h similarity index 100% rename from lib/libnvme.h rename to src/libnvme.h diff --git a/lib/libnvme.map b/src/libnvme.map similarity index 100% rename from lib/libnvme.map rename to src/libnvme.map diff --git a/lib/nvme/cmd.h b/src/nvme/cmd.h similarity index 82% rename from lib/nvme/cmd.h rename to src/nvme/cmd.h index 1b34d74457..3c80f45d44 100644 --- a/lib/nvme/cmd.h +++ b/src/nvme/cmd.h @@ -118,29 +118,29 @@ enum nvme_identify_cns { * NVME_LOG_LID_PERSISTENT_EVENT: * NVME_LOG_LID_LBA_STATUS: * NVME_LOG_LID_ENDURANCE_GRP_EVT: - * NVME_LOG_LID_DISC: + * NVME_LOG_LID_DISCOVER: * NVME_LOG_LID_RESERVATION: * NVME_LOG_LID_SANITIZE: */ enum nvme_cmd_get_log_lid { NVME_LOG_LID_ERROR = 0x01, NVME_LOG_LID_SMART = 0x02, - NVME_LOG_LID_FW_SLOT = 0x03, - NVME_LOG_LID_CHANGED_NS = 0x04, + NVME_LOG_LID_FW_SLOT = 0x03, + NVME_LOG_LID_CHANGED_NS = 0x04, NVME_LOG_LID_CMD_EFFECTS = 0x05, - NVME_LOG_LID_DEVICE_SELF_TEST = 0x06, + NVME_LOG_LID_DEVICE_SELF_TEST = 0x06, NVME_LOG_LID_TELEMETRY_HOST = 0x07, NVME_LOG_LID_TELEMETRY_CTRL = 0x08, - NVME_LOG_LID_ENDURANCE_GROUP = 0x09, + NVME_LOG_LID_ENDURANCE_GROUP = 0x09, NVME_LOG_LID_PREDICTABLE_LAT_NVMSET = 0x0a, NVME_LOG_LID_PREDICTABLE_LAT_AGG = 0x0b, NVME_LOG_LID_ANA = 0x0c, - NVME_LOG_LID_PERSISTENT_EVENT = 0x0d, - NVME_LOG_LID_LBA_STATUS = 0x0e, - NVME_LOG_LID_ENDURANCE_GRP_EVT = 0x0f, - NVME_LOG_LID_DISC = 0x70, + NVME_LOG_LID_PERSISTENT_EVENT = 0x0d, + NVME_LOG_LID_LBA_STATUS = 0x0e, + NVME_LOG_LID_ENDURANCE_GRP_EVT = 0x0f, + NVME_LOG_LID_DISCOVER = 0x70, NVME_LOG_LID_RESERVATION = 0x80, - NVME_LOG_LID_SANITIZE = 0x81, + NVME_LOG_LID_SANITIZE = 0x81, }; /** @@ -503,7 +503,8 @@ int nvme_identify_active_ns_list(int fd, __u32 nsid, struct nvme_ns_list *list); * Return: The nvme command status if a response was received or -1 with errno * set otherwise. */ -int nvme_identify_allocated_ns_list(int fd, __u32 nsid, struct nvme_ns_list *list); +int nvme_identify_allocated_ns_list(int fd, __u32 nsid, + struct nvme_ns_list *list); /** * nvme_identify_ctrl_list() - Retrieves identify controller list @@ -576,7 +577,8 @@ int nvme_identify_ns_descs(int fd, __u32 nsid, struct nvme_ns_id_desc *descs); * Return: The nvme command status if a response was received or -1 with errno * set otherwise. */ -int nvme_identify_nvmset_list(int fd, __u16 nvmsetid, struct nvme_id_nvmset_list *nvmset); +int nvme_identify_nvmset_list(int fd, __u16 nvmsetid, + struct nvme_id_nvmset_list *nvmset); /** * nvme_identify_primary_ctrl() - Retrieve NVMe Primary Controller @@ -590,7 +592,8 @@ int nvme_identify_nvmset_list(int fd, __u16 nvmsetid, struct nvme_id_nvmset_list * Return: The nvme command status if a response was received or -1 * with errno set otherwise. */ -int nvme_identify_primary_ctrl(int fd, __u16 cntid, struct nvme_primary_ctrl_cap *cap); +int nvme_identify_primary_ctrl(int fd, __u16 cntid, + struct nvme_primary_ctrl_cap *cap); /** * nvme_identify_secondary_ctrl_list() - Retrieves secondary controller list @@ -609,7 +612,8 @@ int nvme_identify_primary_ctrl(int fd, __u16 cntid, struct nvme_primary_ctrl_cap * Return: The nvme command status if a response was received or -1 with errno * set otherwise. */ -int nvme_identify_secondary_ctrl_list(int fd, __u16 cntid, struct nvme_secondary_ctrl_list *list); +int nvme_identify_secondary_ctrl_list(int fd, __u16 cntid, + struct nvme_secondary_ctrl_list *list); /** * nvme_identify_ns_granularity() - Retrieves namespace granularity @@ -783,7 +787,8 @@ int nvme_get_log_telemetry_host(int fd, __u64 offset, __u32 len, void *log); * @len: Length of provided user buffer to hold the log data in bytes * @log: User address for log page data */ -int nvme_get_log_telemetry_ctrl(int fd, bool rae, __u64 offset, __u32 len, void *log); +int nvme_get_log_telemetry_ctrl(int fd, bool rae, __u64 offset, __u32 len, + void *log); /** * nvme_get_log_endurance_group() - @@ -801,7 +806,8 @@ int nvme_get_log_telemetry_ctrl(int fd, bool rae, __u64 offset, __u32 len, void * Return: The nvme command status if a response was received or -1 with errno * set otherwise. */ -int nvme_get_log_endurance_group(int fd, __u16 endgid, struct nvme_endurance_group_log *log); +int nvme_get_log_endurance_group(int fd, __u16 endgid, + struct nvme_endurance_group_log *log); /** * nvme_get_log_predictable_lat_nvmset() - @@ -938,18 +944,36 @@ int nvme_set_features(int fd, __u8 fid, __u32 nsid, __u32 cdw11, __u32 cdw12, /** * nvme_set_features_arbitration() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_arbitration(int fd, __u8 ab, __u8 lpw, __u8 mpw, __u8 hpw, bool save, __u32 *result); /** * nvme_set_features_power_mgmt() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_power_mgmt(int fd, __u8 ps, __u8 wh, bool save, __u32 *result); /** * nvme_set_features_lba_range() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_lba_range(int fd, __u32 nsid, __u32 nr_ranges, bool save, struct nvme_lba_range_type *data, __u32 *result); @@ -965,6 +989,12 @@ enum nvme_feat_tmpthresh_thsel { /** * nvme_set_features_temp_thresh() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_temp_thresh(int fd, __u16 tmpth, __u8 tmpsel, enum nvme_feat_tmpthresh_thsel thsel, @@ -972,6 +1002,12 @@ int nvme_set_features_temp_thresh(int fd, __u16 tmpth, __u8 tmpsel, /** * nvme_set_features_err_recovery() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_err_recovery(int fd, __u32 nsid, __u16 tler, bool dulbe, bool save, __u32 *result); @@ -979,18 +1015,36 @@ int nvme_set_features_err_recovery(int fd, __u32 nsid, __u16 tler, /** * nvme_set_features_volatile_wc() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_volatile_wc(int fd, bool wce, bool save, __u32 *result); /** * nvme_set_features_irq_coalesce() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_irq_coalesce(int fd, __u8 thr, __u8 time, bool save, __u32 *result); /** * nvme_set_features_irq_config() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_irq_config(int fd, __u16 iv, bool cd, bool save, __u32 *result); @@ -998,6 +1052,12 @@ int nvme_set_features_irq_config(int fd, __u16 iv, bool cd, bool save, /** * nvme_set_features_write_atomic() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_write_atomic(int fd, bool dn, bool save, __u32 *result); @@ -1024,6 +1084,12 @@ enum nvme_features_async_event_config_flags { /** * nvme_set_features_async_event() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_async_event(int fd, __u32 events, bool save, __u32 *result); @@ -1031,6 +1097,12 @@ int nvme_set_features_async_event(int fd, __u32 events, bool save, /** * nvme_set_features_auto_pst() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_auto_pst(int fd, bool apste, bool save, struct nvme_feat_auto_pst *apst, @@ -1038,12 +1110,24 @@ int nvme_set_features_auto_pst(int fd, bool apste, bool save, /** * nvme_set_features_timestamp() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @timestamp: The current timestamp value to assign to this this feature + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_timestamp(int fd, bool save, __u64 timestamp); /** * nvme_set_features_hctm() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_hctm(int fd, __u16 tmt2, __u16 tmt1, bool save, __u32 *result); @@ -1056,12 +1140,24 @@ int nvme_admin_set_features_nopsc(int fd, bool noppme, bool save, /** * nvme_set_features_rrl() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_rrl(int fd, __u8 rrl, __u16 nvmsetid, bool save, __u32 *result); /** * nvme_set_features_plm_config() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_plm_config(int fd, bool enable, __u16 nvmsetid, bool save, struct nvme_plm_config *data, @@ -1077,6 +1173,12 @@ enum nvme_feat_plm_window_select { /** * nvme_set_features_plm_window() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_plm_window(int fd, enum nvme_feat_plm_window_select sel, __u16 nvmsetid, bool save, __u32 *result); @@ -1084,6 +1186,12 @@ int nvme_set_features_plm_window(int fd, enum nvme_feat_plm_window_select sel, /** * nvme_set_features_lba_sts_interval() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_lba_sts_interval(int fd, __u16 lsiri, __u16 lsipi, bool save, __u32 *result); @@ -1091,26 +1199,48 @@ int nvme_set_features_lba_sts_interval(int fd, __u16 lsiri, __u16 lsipi, /** * nvme_set_features_host_behavior() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_host_behavior(int fd, bool save, struct nvme_feat_host_behavior *data); /** * nvme_set_features_sanitize() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_sanitize(int fd, bool nodrm, bool save, __u32 *result); /** * nvme_set_features_endurance_evt_cfg() - - * @fd: + * @fd: File descriptor of nvme device * @endgid: * @egwarn: Flags to enable warning, see &enum nvme_eg_critical_warning_flags + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_endurance_evt_cfg(int fd, __u16 endgid, __u8 egwarn, bool save, __u32 *result); /** * nvme_set_features_sw_progress() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_sw_progress(int fd, __u8 pbslc, bool save, __u32 *result); @@ -1118,6 +1248,12 @@ int nvme_set_features_sw_progress(int fd, __u8 pbslc, bool save, /** * nvme_set_features_host_id() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_host_id(int fd, bool exhid, bool save, __u8 *hostid); @@ -1132,11 +1268,23 @@ enum nvme_feat_resv_notify_flags { /** * nvme_set_features_resv_mask() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_resv_mask(int fd, __u32 mask, bool save, __u32 *result); /** * nvme_set_features_resv_persist() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_resv_persist(int fd, bool ptpl, bool save, __u32 *result); @@ -1156,6 +1304,12 @@ enum nvme_feat_nswpcfg_state { /** * nvme_set_features_write_protect() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_set_features_write_protect(int fd, enum nvme_feat_nswpcfg_state state, bool save, __u32 *result); @@ -1181,18 +1335,36 @@ int nvme_get_features(int fd, enum nvme_features_id fid, __u32 nsid, /** * nvme_get_features_arbitration() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_arbitration(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_power_mgmt() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_power_mgmt(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_lba_range() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_lba_range(int fd, enum nvme_get_features_sel sel, struct nvme_lba_range_type *data, @@ -1200,92 +1372,188 @@ int nvme_get_features_lba_range(int fd, enum nvme_get_features_sel sel, /** * nvme_get_features_temp_thresh() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_temp_thresh(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_err_recovery() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_err_recovery(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_volatile_wc() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_volatile_wc(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_num_queues() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_num_queues(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_irq_coalesce() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_irq_coalesce(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_irq_config() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_irq_config(int fd, enum nvme_get_features_sel sel, __u16 iv, __u32 *result); /** * nvme_get_features_write_atomic() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_write_atomic(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_async_event() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_async_event(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_auto_pst() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ 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() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_host_mem_buf(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_timestamp() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_timestamp(int fd, enum nvme_get_features_sel sel, struct nvme_timestamp *ts); /** * nvme_get_features_kato() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_kato(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_hctm() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_hctm(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_nopsc() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_nopsc(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_rrl() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_rrl(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_plm_config() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_plm_config(int fd, enum nvme_get_features_sel sel, __u16 nvmsetid, struct nvme_plm_config *data, @@ -1293,18 +1561,36 @@ int nvme_get_features_plm_config(int fd, enum nvme_get_features_sel sel, /** * nvme_get_features_plm_window() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_plm_window(int fd, enum nvme_get_features_sel sel, __u16 nvmsetid, __u32 *result); /** * nvme_get_features_lba_sts_interval() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_lba_sts_interval(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_host_behavior() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_host_behavior(int fd, enum nvme_get_features_sel sel, struct nvme_feat_host_behavior *data, @@ -1312,42 +1598,85 @@ int nvme_get_features_host_behavior(int fd, enum nvme_get_features_sel sel, /** * nvme_get_features_sanitize() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_sanitize(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_endurance_event_cfg() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_endurance_event_cfg(int fd, enum nvme_get_features_sel sel, __u16 endgid, __u32 *result); /** * nvme_get_features_sw_progress() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_sw_progress(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_host_id() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ 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() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_resv_mask(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_resv_persist() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_resv_persist(int fd, enum nvme_get_features_sel sel, __u32 *result); /** * nvme_get_features_write_protect() - + * @fd: File descriptor of nvme device + * @nsid: Namespace ID + * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. */ int nvme_get_features_write_protect(int fd, __u32 nsid, enum nvme_get_features_sel sel, @@ -1798,7 +2127,7 @@ int nvme_virtual_mgmt(int fd, enum nvme_virt_mgmt_act act, __u32 *result); /** - * DOC: NVMe IO command enums + * DOC: NVMe IO command */ /** @@ -1905,7 +2234,7 @@ enum nvme_io_dsm_flags { /** * nvme_read() - Submit an nvme user read command * @fd: File descriptor of nvme device - * @nsid: + * @nsid: Namespace ID * @slba: Starting logical block * @nblocks: Number of logical blocks to send (0's based value) * @control: Command control flags, see &enum nvme_io_control_flags. @@ -1936,7 +2265,7 @@ int nvme_read(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, /** * nvme_write() - Submit an nvme user write command * @fd: File descriptor of nvme device - * @nsid: + * @nsid: Namespace ID * @slba: Starting logical block * @nblocks: Number of logical blocks to send (0's based value) * @control: Command control flags, see &enum nvme_io_control_flags. @@ -1969,7 +2298,7 @@ int nvme_write(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, /** * nvme_compare() - Submit an nvme user compare command * @fd: File descriptor of nvme device - * @nsid: + * @nsid: Namespace ID * @slba: Starting logical block * @nblocks: Number of logical blocks to send (0's based value) * @control: Command control flags, see &enum nvme_io_control_flags. diff --git a/lib/nvme/fabrics.c b/src/nvme/fabrics.c similarity index 99% rename from lib/nvme/fabrics.c rename to src/nvme/fabrics.c index c1119df050..56e97fcad6 100644 --- a/lib/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -248,7 +248,7 @@ nvme_ctrl_t nvmf_connect_disc_entry(struct nvmf_disc_log_entry *e, static int nvme_discovery_log(int fd, __u32 len, struct nvmf_discovery_log *log) { - return nvme_get_log_page(fd, 0, NVME_LOG_LID_DISC, true, len, log); + return nvme_get_log_page(fd, 0, NVME_LOG_LID_DISCOVER, true, len, log); } int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, diff --git a/lib/nvme/fabrics.h b/src/nvme/fabrics.h similarity index 100% rename from lib/nvme/fabrics.h rename to src/nvme/fabrics.h diff --git a/lib/nvme/filters.c b/src/nvme/filters.c similarity index 100% rename from lib/nvme/filters.c rename to src/nvme/filters.c diff --git a/lib/nvme/filters.h b/src/nvme/filters.h similarity index 100% rename from lib/nvme/filters.h rename to src/nvme/filters.h diff --git a/lib/nvme/ioctl.c b/src/nvme/ioctl.c similarity index 99% rename from lib/nvme/ioctl.c rename to src/nvme/ioctl.c index ca59e096bc..1120438c6f 100644 --- a/lib/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -608,7 +608,7 @@ int nvme_get_log_endurance_grp_evt(int fd, bool rae, __u32 offset, __u32 len, int nvme_get_log_discovery(int fd, bool rae, __u32 offset, __u32 len, void *log) { - return nvme_get_log(fd, NVME_LOG_LID_DISC, NVME_NSID_NONE, offset, + return nvme_get_log(fd, NVME_LOG_LID_DISCOVER, NVME_NSID_NONE, offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, len, log); } diff --git a/lib/nvme/ioctl.h b/src/nvme/ioctl.h similarity index 100% rename from lib/nvme/ioctl.h rename to src/nvme/ioctl.h diff --git a/lib/nvme/private.h b/src/nvme/private.h similarity index 100% rename from lib/nvme/private.h rename to src/nvme/private.h diff --git a/lib/nvme/tree.c b/src/nvme/tree.c similarity index 100% rename from lib/nvme/tree.c rename to src/nvme/tree.c diff --git a/lib/nvme/tree.h b/src/nvme/tree.h similarity index 77% rename from lib/nvme/tree.h rename to src/nvme/tree.h index b5f53856b2..0156a07158 100644 --- a/lib/nvme/tree.h +++ b/src/nvme/tree.h @@ -9,88 +9,185 @@ #include "ioctl.h" #include "util.h" -extern const char *nvme_ctrl_sysfs_dir; -extern const char *nvme_subsys_sysfs_dir; - typedef struct nvme_ns *nvme_ns_t; typedef struct nvme_path *nvme_path_t; typedef struct nvme_ctrl *nvme_ctrl_t; typedef struct nvme_subsystem *nvme_subsystem_t; typedef struct nvme_root *nvme_root_t; +/** + * nvme_first_subsystem() - + */ nvme_subsystem_t nvme_first_subsystem(nvme_root_t r); + +/** + * nvme_next_subsystem() - + */ nvme_subsystem_t nvme_next_subsystem(nvme_root_t r, nvme_subsystem_t s); +/** + * nvme_ctrl_first_ns() - + */ nvme_ns_t nvme_ctrl_first_ns(nvme_ctrl_t c); + +/** + * nvme_ctrl_next_ns() - + */ nvme_ns_t nvme_ctrl_next_ns(nvme_ctrl_t c, nvme_ns_t n); +/** + * nvme_ctrl_first_path() - + */ nvme_path_t nvme_ctrl_first_path(nvme_ctrl_t c); + +/** + * nvme_ctrl_next_path() - + */ nvme_path_t nvme_ctrl_next_path(nvme_ctrl_t c, nvme_path_t p); +/** + * nvme_subsystem_first_ctrl() - + */ nvme_ctrl_t nvme_subsystem_first_ctrl(nvme_subsystem_t s); + +/** + * nvme_subsystem_next_ctrl() - + */ nvme_ctrl_t nvme_subsystem_next_ctrl(nvme_subsystem_t s, nvme_ctrl_t c); +/** + * nvme_subsystem_first_ns() - + */ nvme_ns_t nvme_subsystem_first_ns(nvme_subsystem_t s); + +/** + * nvme_subsystem_next_ns() - + */ nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n); +/** + * () + */ #define nvme_for_each_subsystem_safe(r, s, _s) \ for (s = nvme_first_subsystem(r), \ _s = nvme_next_subsystem(r, s); \ s != NULL; \ s = _s, _s = nvme_next_subsystem(r, s)) +/** + * () + */ #define nvme_for_each_subsystem(r, s) \ for (s = nvme_first_subsystem(r); s != NULL; \ s = nvme_next_subsystem(r, s)) +/** + * () + */ #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 = _c, _c = nvme_subsystem_next_ctrl(s, c)) +/** + * () + */ #define nvme_subsystem_for_each_ctrl(s, c) \ for (c = nvme_subsystem_first_ctrl(s); c != NULL; \ c = nvme_subsystem_next_ctrl(s, c)) +/** + * () + */ #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 = _n, _n = nvme_ctrl_next_ns(c, n)) +/** + * () + */ #define nvme_ctrl_for_each_ns(c, n) \ for (n = nvme_ctrl_first_ns(c); n != NULL; \ n = nvme_ctrl_next_ns(c, 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 = _p, _p = nvme_ctrl_next_path(c, p)) +/** + * () + */ #define nvme_ctrl_for_each_path(c, p) \ for (p = nvme_ctrl_first_path(c); p != NULL; \ p = nvme_ctrl_next_path(c, p)) +/** + * () + */ #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 = _n, _n = nvme_subsystem_next_ns(s, n)) +/** + * () + */ #define nvme_subsystem_for_each_ns(s, n) \ for (n = nvme_subsystem_first_ns(s); n != NULL; \ n = nvme_subsystem_next_ns(s, n)) +/** + * nvme_ns_get_fd() - + */ int nvme_ns_get_fd(nvme_ns_t n); + +/** + * nvme_ns_get_nsid() - + */ int nvme_ns_get_nsid(nvme_ns_t n); + +/** + * nvme_ns_get_lba_size() - + */ int nvme_ns_get_lba_size(nvme_ns_t n); + +/** + * nvme_ns_get_lba_count() - + */ uint64_t nvme_ns_get_lba_count(nvme_ns_t n); + +/** + * nvme_ns_get_lba_util() - + */ uint64_t nvme_ns_get_lba_util(nvme_ns_t n); + +/** + * char () - + */ const char *nvme_ns_get_sysfs_dir(nvme_ns_t n); + +/** + * char () - + */ const char *nvme_ns_get_name(nvme_ns_t n); + +/** + * nvme_ns_get_subsystem() - + */ nvme_subsystem_t nvme_ns_get_subsystem(nvme_ns_t n); + +/** + * nvme_ns_get_ctrl() - + */ nvme_ctrl_t nvme_ns_get_ctrl(nvme_ns_t n); /** @@ -133,50 +230,171 @@ int nvme_ns_flush(nvme_ns_t n); */ int nvme_ns_identify(nvme_ns_t n, struct nvme_id_ns *ns); +/** + * char () - + */ const char *nvme_path_get_name(nvme_path_t p); + +/** + * char () - + */ const char *nvme_path_get_sysfs_dir(nvme_path_t p); + +/** + * char () - + */ const char *nvme_path_get_ana_state(nvme_path_t p); + +/** + * nvme_path_get_subsystem() - + */ nvme_ctrl_t nvme_path_get_subsystem(nvme_path_t p); + +/** + * nvme_path_get_ns() - + */ nvme_ns_t nvme_path_get_ns(nvme_path_t p); int nvme_ctrl_get_fd(nvme_ctrl_t c); +/** + * char () - + */ const char *nvme_ctrl_get_name(nvme_ctrl_t c); +/** + * char () - + */ const char *nvme_ctrl_get_sysfs_dir(nvme_ctrl_t c); +/** + * char () - + */ const char *nvme_ctrl_get_address(nvme_ctrl_t c); +/** + * char () - + */ const char *nvme_ctrl_get_firmware(nvme_ctrl_t c); +/** + * char () - + */ const char *nvme_ctrl_get_model(nvme_ctrl_t c); +/** + * char () - + */ const char *nvme_ctrl_get_state(nvme_ctrl_t c); +/** + * char () - + */ const char *nvme_ctrl_get_numa_node(nvme_ctrl_t c); +/** + * char () - + */ const char *nvme_ctrl_get_queue_count(nvme_ctrl_t c); +/** + * char () - + */ const char *nvme_ctrl_get_serial(nvme_ctrl_t c); +/** + * char () - + */ const char *nvme_ctrl_get_sqsize(nvme_ctrl_t c); +/** + * char () - + */ const char *nvme_ctrl_get_transport(nvme_ctrl_t c); +/** + * char () - + */ const char *nvme_ctrl_get_nqn(nvme_ctrl_t c); +/** + * char () - + */ const char *nvme_ctrl_get_subsysnqn(nvme_ctrl_t c); +/** + * nvme_ctrl_get_subsystem() - + */ nvme_subsystem_t nvme_ctrl_get_subsystem(nvme_ctrl_t c); +/** + * nvme_ctrl_identify() - + */ int nvme_ctrl_identify(nvme_ctrl_t c, struct nvme_id_ctrl *id); +/** + * nvme_ctrl_disconnect() - + */ int nvme_ctrl_disconnect(nvme_ctrl_t c); +/** + * nvme_scan_ctrl() - + */ nvme_ctrl_t nvme_scan_ctrl(const char *name); +/** + * nvme_free_ctrl() - + */ void nvme_free_ctrl(struct nvme_ctrl *c); +/** + * nvme_unlink_ctrl() - + */ void nvme_unlink_ctrl(struct nvme_ctrl *c); +/** + * char () - + */ const char *nvme_subsystem_get_nqn(nvme_subsystem_t s); +/** + * char () - + */ const char *nvme_subsystem_get_sysfs_dir(nvme_subsystem_t s); +/** + * char () - + */ const char *nvme_subsystem_get_name(nvme_subsystem_t s); typedef bool (*nvme_scan_filter_t)(nvme_subsystem_t); + +/** + * nvme_scan_filter() - + */ nvme_root_t nvme_scan_filter(nvme_scan_filter_t f); +/** + * nvme_scan() - + */ nvme_root_t nvme_scan(); + +/** + * nvme_refresh_topology() - + */ void nvme_refresh_topology(nvme_root_t r); + +/** + * nvme_reset_topology() - + */ void nvme_reset_topology(nvme_root_t r); + +/** + * nvme_free_tree() - + */ void nvme_free_tree(nvme_root_t r); +/** + * *() - + */ char *nvme_get_subsys_attr(nvme_subsystem_t s, const char *attr); + +/** + * *() - + */ char *nvme_get_ctrl_attr(nvme_ctrl_t c, const char *attr); + +/** + * *() - + */ char *nvme_get_ns_attr(nvme_ns_t n, const char *attr); + +/** + * *() - + */ char *nvme_get_path_attr(nvme_path_t p, const char *attr); +extern const char *nvme_ctrl_sysfs_dir; +extern const char *nvme_subsys_sysfs_dir; #endif /* _LIBNVME_TREE_H */ diff --git a/lib/nvme/types.h b/src/nvme/types.h similarity index 95% rename from lib/nvme/types.h rename to src/nvme/types.h index 17d6851273..ebb01c7571 100644 --- a/lib/nvme/types.h +++ b/src/nvme/types.h @@ -2060,24 +2060,82 @@ struct nvme_host_mem_buf_desc { }; /** - * enum - - */ -enum { - NVME_AER_ERROR = 0, - NVME_AER_SMART = 1, - NVME_AER_NOTICE = 2, - NVME_AER_CSS = 6, - NVME_AER_VS = 7, -}; - -/** - * enum - - */ -enum { - NVME_AER_NOTICE_NS_CHANGED = 0x00, - NVME_AER_NOTICE_FW_ACT_STARTING = 0x01, - NVME_AER_NOTICE_ANA = 0x03, - NVME_AER_NOTICE_DISC_CHANGED = 0xf0, + * enum nvme_ae_type - + * @NVME_AER_ERROR: + * @NVME_AER_SMART: + * @NVME_AER_NOTICE: + * @NVME_AER_CSS: + * @NVME_AER_VS: + */ +enum nvme_ae_type { + 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 - + * @NVME_AER_ERROR_INVALID_DB_REG: + * @NVME_AER_ERROR_INVALID_DB_VAL: + * @NVME_AER_ERROR_DIAG_FAILURE: + * @NVME_AER_ERROR_PERSISTENT_INTERNAL_ERROR: + * @NVME_AER_ERROR_TRANSIENT_INTERNAL_ERROR: + * @NVME_AER_ERROR_FW_IMAGE_LOAD_ERROR: + */ +enum nvme_ae_info_error { + NVME_AER_ERROR_INVALID_DB_REG = 0x00, + NVME_AER_ERROR_INVALID_DB_VAL = 0x01, + NVME_AER_ERROR_DIAG_FAILURE = 0x02, + NVME_AER_ERROR_PERSISTENT_INTERNAL_ERROR = 0x03, + NVME_AER_ERROR_TRANSIENT_INTERNAL_ERROR = 0x04, + NVME_AER_ERROR_FW_IMAGE_LOAD_ERROR = 0x05, +}; + +/** + * enum nvme_ae_info_smart - + * @NVME_AER_SMART_SUBSYSTEM_RELIABILITY: + * @NVME_AER_SMART_TEMPERATURE_THRESHOLD: + * @NVME_AER_SMART_SPARE_THRESHOLD: + */ +enum nvme_ae_info_smart { + NVME_AER_SMART_SUBSYSTEM_RELIABILITY = 0x00, + NVME_AER_SMART_TEMPERATURE_THRESHOLD = 0x01, + NVME_AER_SMART_SPARE_THRESHOLD = 0x02, +}; + +/** + * enum nvme_ae_info_css_nvm - + * @NVME_AER_CSS_NVM_RESERVATION: + * @NVME_AER_CSS_NVM_SANITIZE_COMPLETED: + * @NVME_AER_CSS_NVM_UNEXPECTED_SANITIZE_DEALLOC: + */ +enum nvme_ae_info_css_nvm { + NVME_AER_CSS_NVM_RESERVATION = 0x00, + NVME_AER_CSS_NVM_SANITIZE_COMPLETED = 0x01, + NVME_AER_CSS_NVM_UNEXPECTED_SANITIZE_DEALLOC = 0x02, +}; + +/** + * enum nvme_ae_info_notice - + * @NVME_AER_NOTICE_NS_CHANGED: + * @NVME_AER_NOTICE_FW_ACT_STARTING: + * @NVME_AER_NOTICE_TELEMETRY: + * @NVME_AER_NOTICE_ANA: + * @NVME_AER_NOTICE_PL_EVENT: + * @NVME_AER_NOTICE_LBA_STATUS_ALERT: + * @NVME_AER_NOTICE_EG_EVENT: + * @NVME_AER_NOTICE_DISC_CHANGED: + */ +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, }; /** diff --git a/lib/nvme/util.c b/src/nvme/util.c similarity index 100% rename from lib/nvme/util.c rename to src/nvme/util.c diff --git a/lib/nvme/util.h b/src/nvme/util.h similarity index 100% rename from lib/nvme/util.h rename to src/nvme/util.h diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000000..b21e464320 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,22 @@ +CFLAGS ?= -g -O2 +override CFLAGS += -Wall -D_GNU_SOURCE -L../src/ -I../src/ + +include ../Makefile.quiet + +ifneq ($(MAKECMDGOALS),clean) +include ../config-host.mak +endif + +all_targets += test + +all: $(all_targets) + +%: %.c + $(QUIET_CC)$(CC) $(CFLAGS) -o $@ $< -lnvme + +test_srs := test.c + +test_objs := $(patsubst %.c,%.ol,$(test_srcs)) + +clean: + @rm -f $(all_targets) $(test_objs) From bdd5961496a557385bf749ae6c859380d38f11e7 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 6 Feb 2020 14:23:26 -0800 Subject: [PATCH 0003/1564] Add exported symbols to libnvme.map And add the kernel-doc style comments in all exported functions. This is just a capture of what currently exists and may change prior to tagging as a stable release. Signed-off-by: Keith Busch --- src/libnvme.map | 245 ++++++++++++++++++++++++++++++++++++++++++++- src/nvme/cmd.h | 15 +-- src/nvme/fabrics.h | 87 +++++++++++++++- src/nvme/filters.h | 35 ++++++- src/nvme/ioctl.c | 2 +- src/nvme/ioctl.h | 8 +- src/nvme/tree.h | 79 ++++++++------- src/nvme/util.c | 29 +++--- src/nvme/util.h | 6 +- 9 files changed, 431 insertions(+), 75 deletions(-) diff --git a/src/libnvme.map b/src/libnvme.map index 386dddbb96..fbb3355b4f 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -1,6 +1,249 @@ { global: - nvme_submit_passthru; + nvme_submit_admin_passthru64; + nvme_submit_admin_passthru; + nvme_submit_io_passthru64; + nvme_submit_io_passthru; + nvme_admin_passthru64; + nvme_admin_passthru; + nvme_io_passthru64; + nvme_io_passthru; + nvme_subsystem_reset; + nvme_ctrl_reset; + nvme_ns_rescan; + nvme_get_nsid; + nvme_identify; + nvme_identify_ctrl; + nvme_identify_ns; + nvme_identify_allocated_ns; + nvme_identify_active_ns_list; + nvme_identify_allocated_ns_list; + nvme_identify_nsid_ctrl_list; + nvme_identify_ns_descs; + nvme_identify_nvmset_list; + nvme_identify_primary_ctrl; + nvme_identify_secondary_ctrl_list; + nvme_identify_ns_granularity; + nvme_identify_uuid; + nvme_get_log; + nvme_get_log_error; + nvme_get_log_smart; + nvme_get_log_fw_slot; + nvme_get_log_changed_ns_list; + nvme_get_log_cmd_effects; + nvme_get_log_device_self_test; + nvme_get_log_create_telemetry_host; + nvme_get_log_telemetry_host; + nvme_get_log_telemetry_ctrl; + nvme_get_log_endurance_group; + nvme_get_log_predictable_lat_nvmset; + nvme_get_log_predictable_lat_event; + nvme_get_log_ana; + nvme_get_log_ana_groups; + nvme_get_log_lba_status; + nvme_get_log_endurance_grp_evt; + nvme_get_log_discovery; + nvme_get_log_reservation; + nvme_get_log_sanitize; + nvme_set_feature; + nvme_set_features_arbitration; + nvme_set_features_power_mgmt; + nvme_set_features_lba_range; + nvme_set_features_temp_thresh; + nvme_set_features_err_recovery; + nvme_set_features_volatile_wc; + nvme_set_features_irq_coalesce; + nvme_set_features_irq_config; + nvme_set_features_write_atomic; + nvme_set_features_async_event; + nvme_set_features_auto_pst; + nvme_set_features_timestamp; + nvme_set_features_hctm; + nvme_set_features_nopsc; + nvme_set_features_rrl; + nvme_set_features_plm_config; + nvme_set_features_plm_window; + nvme_set_features_lba_sts_interval; + nvme_set_features_host_behavior; + nvme_set_features_sanitize; + nvme_set_features_endurance_evt_cfg; + nvme_set_features_sw_progress; + nvme_set_features_host_id; + nvme_set_features_resv_mask; + nvme_set_features_resv_persist; + nvme_set_features_write_protect; + nvme_get_features; + nvme_get_features_arbitration; + nvme_get_features_power_mgmt; + nvme_get_features_lba_range; + nvme_get_features_temp_thresh; + nvme_get_features_err_recovery; + nvme_get_features_volatile_wc; + nvme_get_features_num_queues; + nvme_get_features_irq_coalesce; + nvme_get_features_irq_config; + nvme_get_features_write_atomic; + nvme_get_features_async_event; + nvme_get_features_auto_pst; + nvme_get_features_host_mem_buf; + nvme_get_features_timestamp; + nvme_get_features_kato; + nvme_get_features_hctm; + nvme_get_features_nopsc; + nvme_get_features_rrl; + nvme_get_features_plm_config; + nvme_get_features_plm_window; + nvme_get_features_lba_sts_interval; + nvme_get_features_host_behavior; + nvme_get_features_sanitize; + nvme_get_features_endurance_event_cfg; + nvme_get_features_sw_progress; + nvme_get_features_host_id; + nvme_get_features_resv_mask; + nvme_get_features_resv_persist; + nvme_get_features_write_protect; + nvme_format_nvm; + nvme_ns_mgmt; + nvme_ns_mgmt_create; + nvme_ns_mgmt_delete; + nvme_ns_attach; + nvme_ns_attach_ctrls; + nvme_ns_dettach_ctrls; + nvme_fw_download; + nvme_fw_commit; + nvme_security_receive; + nvme_security_receive; + nvme_get_lba_status; + nvme_directive_send; + nvme_directive_send_id_endir; + nvme_directive_send_stream_release_identifier; + nvme_directive_send_stream_release_resource; + nvme_directive_recv; + nvme_directive_recv_identify_parameters; + nvme_directive_recv_stream_parameters; + nvme_directive_recv_stream_status; + nvme_directive_recv_stream_allocate; + nvme_set_property; + nvme_get_property; + nvme_sanitize; + nvme_dev_self_test; + nvme_virtual_mgmt; + nvme_flush; + nvme_read; + nvme_write; + nvme_compare; + nvme_write_zeros; + nvme_write_uncorrectable; + nvme_verify; + nvme_dsm; + nvme_resv_acquire; + nvme_resv_register; + nvme_resv_release; + nvme_resv_report; + nvmf_add_ctrl_opts; + nvmf_add_ctrl; + nvme_first_subsystem; + nvme_next_subsystem; + nvme_ctrl_first_ns; + nvme_ctrl_next_ns; + nvme_ctrl_first_path; + nvme_ctrl_next_path; + nvme_subsystem_first_ctrl; + nvme_subsystem_next_ctrl; + nvme_subsystem_first_ns; + nvme_subsystem_next_ns; + nvme_ns_get_fd; + nvme_ns_get_nsid; + nvme_ns_get_lba_size; + nvme_ns_get_lba_count; + nvme_ns_get_lba_util; + nvme_ns_get_subsystem; + nvme_ns_get_ctrl; + nvme_ns_read; + nvme_ns_write; + nvme_ns_verify; + nvme_ns_compare; + nvme_ns_write_zeros; + nvme_ns_write_uncorrectable; + nvme_ns_flush; + nvme_ns_identify; + nvme_path_get_subsystem; + nvme_path_get_ns; + nvme_ctrl_get_subsystem; + nvme_ctrl_identify; + nvme_ctrl_disconnect; + nvme_scan_ctrl; + nvme_free_ctrl; + nvme_unlink_ctrl; + nvme_scan_filter; + nvme_scan; + nvme_refresh_topology; + nvme_reset_topology; + nvme_free_tree; + nvme_get_subsys_attr; + nvme_get_ctrl_attr; + nvme_get_ns_attr; + nvme_get_path_attr; + nvme_subsystem_get_nqn; + nvme_subsystem_get_sysfs_dir; + nvme_subsystem_get_name; + nvme_subsystem_get_nqn; + nvme_ctrl_get_fd; + nvme_ctrl_get_name; + nvme_ctrl_get_sysfs_dir; + nvme_ctrl_get_address; + nvme_ctrl_get_firmware; + nvme_ctrl_get_model; + nvme_ctrl_get_state; + nvme_ctrl_get_numa_node; + nvme_ctrl_get_queue_count; + nvme_ctrl_get_serial; + nvme_ctrl_get_sqsize; + nvme_ctrl_get_transport; + nvme_ctrl_get_nqn; + nvme_ctrl_get_subsysnqn; + nvme_path_get_name; + nvme_path_get_sysfs_dir; + nvme_path_get_ana_state; + nvme_ns_get_sysfs_dir; + nvme_ns_get_name; + nvme_status_type; + nvme_status_to_string; + nvme_status_to_errno; + nvme_fw_download_seq; + nvme_get_telemetry_log; + nvme_setup_id_ns; + nvme_setup_ctrl_list; + nvme_dsm_range; + nvme_get_log_page; + nvme_get_ana_log_len; + nvme_namespace_attach_ctrls; + nvme_namespace_detach_ctrls; + nvme_get_feature_length; + nvme_get_directive_receive_length; + nvme_open; + nvme_scan_ctrl_namespaces; + nvme_scan_ctrl_namespace_paths; + nvme_scan_subsystem_namespaces; + nvme_scan_subsystem_ctrls; + nvme_scan_subsystems; + nvme_subsys_filter; + nvme_ctrls_filter; + nvme_paths_filter; + nvme_namespace_filter; + nvmf_get_discovery_log; + nvmf_hostnqn_generate; + nvmf_hostnqn_from_file; + nvmf_hostid_from_file; + nvmf_trtype_str; + nvmf_adrfam_str; + nvmf_subtype_str; + nvmf_treq_str; + nvmf_sectype_str; + nvmf_prtype_str; + nvmf_qptype_str; + nvmf_cms_str; + nvmf_connect_disc_entry; local: *; }; diff --git a/src/nvme/cmd.h b/src/nvme/cmd.h index 3c80f45d44..90abc628be 100644 --- a/src/nvme/cmd.h +++ b/src/nvme/cmd.h @@ -765,7 +765,9 @@ int nvme_get_log_device_self_test(int fd, struct nvme_self_test_log *log); * nvme_get_log_create_telemetry_host() - */ int nvme_get_log_create_telemetry_host(int fd, struct nvme_telemetry_log *log); -/** * nvme_get_log_telemetry_host() - + +/** + * nvme_get_log_telemetry_host() - * @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 @@ -1133,10 +1135,9 @@ int nvme_set_features_hctm(int fd, __u16 tmt2, __u16 tmt1, bool save, __u32 *result); /** - * nvme_admin_set_features_nopsc() - + * nvme_set_features_nopsc() - */ -int nvme_admin_set_features_nopsc(int fd, bool noppme, bool save, - __u32 *result); +int nvme_set_features_nopsc(int fd, bool noppme, bool save, __u32 *result); /** * nvme_set_features_rrl() - @@ -2253,8 +2254,6 @@ enum nvme_io_dsm_flags { * metadata_len:Length of user buffer, @metadata, in bytes * @metadata: Pointer to user address of the metadata buffer * - * Calls nvme_io() with nvme_cmd_read for the opcode. - * * Return: The nvme command status if a response was received or -1 with errno * set otherwise. */ @@ -2285,8 +2284,6 @@ int nvme_read(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, * metadata_len:Length of user buffer, @metadata, in bytes * @metadata: Pointer to user address of the metadata buffer * - * Calls nvme_io() with nvme_cmd_write for the opcode. - * * Return: The nvme command status if a response was received or -1 with errno * set otherwise. */ @@ -2316,8 +2313,6 @@ int nvme_write(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, * metadata_len:Length of user buffer, @metadata, in bytes * @metadata: Pointer to user address of the metadata buffer * - * Calls nvme_io() with nvme_cmd_compare for the opcode. - * * Return: The nvme command status if a response was received or -1 with errno * set otherwise. */ diff --git a/src/nvme/fabrics.h b/src/nvme/fabrics.h index 0f5e82ec33..d794136224 100644 --- a/src/nvme/fabrics.h +++ b/src/nvme/fabrics.h @@ -3,9 +3,31 @@ #include #include - #include "tree.h" +/** + * struct nvme_fabrics_config - + * @transport: + * @traddr: + * @trsvcid: + * @nqn: + * @hostnqn: + * @host_traddr: + * @hostid: + * @queue_size: + * @nr_io_queues: + * @reconnect_delay: + * @ctrl_loss_tmo: + * @keep_alive_tmo: + * @nr_write_queues: + * @nr_poll_queues: + * @tos: + * @duplicate_connect: + * @disable_sqflow: + * @hdr_digest: + * @data_digest: + * @rsvd: + */ struct nvme_fabrics_config { const char *transport; const char *traddr; @@ -32,23 +54,82 @@ struct nvme_fabrics_config { uint8_t rsvd[0x200]; }; +/** + * nvmf_add_ctrl_opts() - + */ int nvmf_add_ctrl_opts(struct nvme_fabrics_config *cfg); + +/** + * nvmf_add_ctrl() - + */ nvme_ctrl_t nvmf_add_ctrl(struct nvme_fabrics_config *cfg); -int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, int max_retries); + +/** + * nvmf_get_discovery_log() - + */ +int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, + int max_retries); + +/** + * nvmf_hostnqn_generate() - + */ char *nvmf_hostnqn_generate(); + +/** + * nvmf_hostnqn_from_file() - + */ char *nvmf_hostnqn_from_file(); -char *nvmf_hostid_from_file(); +/** + * nvmf_hostid_from_file() - + */ +char *nvmf_hostid_from_file(); +/** + * nvmf_trtype_str() - + */ const char *nvmf_trtype_str(__u8 trtype); + +/** + * nvmf_adrfam_str() - + */ const char *nvmf_adrfam_str(__u8 adrfam); + +/** + * nvmf_subtype_str() - + */ const char *nvmf_subtype_str(__u8 subtype); + +/** + * nvmf_treq_str() - + */ const char *nvmf_treq_str(__u8 treq); + +/** + * nvmf_sectype_str() - + */ const char *nvmf_sectype_str(__u8 sectype); + +/** + * nvmf_prtype_str() - + */ const char *nvmf_prtype_str(__u8 prtype); + +/** + * nvmf_qptype_str() - + */ const char *nvmf_qptype_str(__u8 qptype); + +/** + * nvmf_cms_str() - + */ const char *nvmf_cms_str(__u8 cm); + +/** + * nvmf_connect_disc_entry() - + */ nvme_ctrl_t nvmf_connect_disc_entry(struct nvmf_disc_log_entry *e, const struct nvme_fabrics_config *defcfg, bool *discover); + #endif /* _LIBNVME_FABRICS_H */ diff --git a/src/nvme/filters.h b/src/nvme/filters.h index 9021c1bc7c..bc97cf8391 100644 --- a/src/nvme/filters.h +++ b/src/nvme/filters.h @@ -4,16 +4,49 @@ #include #include "tree.h" - +/** + * nvme_namespace_filter() - + */ int nvme_namespace_filter(const struct dirent *d); + +/** + * nvme_paths_filter() - + */ int nvme_paths_filter(const struct dirent *d); + +/** + * nvme_ctrls_filter() - + */ int nvme_ctrls_filter(const struct dirent *d); + +/** + * nvme_subsys_filter() - + */ int nvme_subsys_filter(const struct dirent *d); +/** + * nvme_scan_subsystems() - + */ int nvme_scan_subsystems(struct dirent ***subsys); + +/** + * nvme_scan_subsystem_ctrls() - + */ int nvme_scan_subsystem_ctrls(nvme_subsystem_t s, struct dirent ***ctrls); + +/** + * nvme_scan_subsystem_namespaces() - + */ int nvme_scan_subsystem_namespaces(nvme_subsystem_t s, struct dirent ***namespaces); + +/** + * nvme_scan_ctrl_namespace_paths() - + */ int nvme_scan_ctrl_namespace_paths(nvme_ctrl_t c, struct dirent ***namespaces); + +/** + * nvme_scan_ctrl_namespaces() - + */ int nvme_scan_ctrl_namespaces(nvme_ctrl_t c, struct dirent ***namespaces); #endif /* _LIBNVME_FILTERS_H */ diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 1120438c6f..ab7b022f01 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -39,7 +39,7 @@ int nvme_subsystem_reset(int fd) return ioctl(fd, NVME_IOCTL_SUBSYS_RESET); } -int nvme_reset_controller(int fd) +int nvme_ctrl_reset(int fd) { int ret; diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index e5477f0f80..38587453c2 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -210,7 +210,7 @@ int nvme_admin_passthru(int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 timeout_ms, __u32 *result); /** - * nvme_submit_passthru64() - Submit a 64-bit nvme passthrough command + * nvme_submit_io_passthru64() - Submit a 64-bit nvme passthrough command * @fd: File descriptor of nvme device * @cmd: The nvme io command to send * @result: Optional field to return the result from the CQE DW0-1 @@ -260,7 +260,7 @@ int nvme_io_passthru64(int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 timeout_ms, __u64 *result); /** - * nvme_submit_passthru() - Submit an nvme passthrough command + * nvme_submit_io_passthru() - Submit an nvme passthrough command * @fd: File descriptor of nvme device * @cmd: The nvme io command to send * @result: Optional field to return the result from the CQE dword 0 @@ -322,14 +322,14 @@ int nvme_io_passthru(int fd, __u8 opcode, __u8 flags, __u16 rsvd, int nvme_subsystem_reset(int fd); /** - * nvme_reset_ctrl() - Initiate a controller reset + * nvme_ctrl_reset() - Initiate a controller reset * @fd: File descriptor of nvme device * * This should only be sent to controller handles, not to namespaces. * * Return: Zero if a reset was initiated or -1 with errno set otherwise. */ -int nvme_reset_ctrl(int fd); +int nvme_ctrl_reset(int fd); /** * nvme_ns_rescan() - Initiate a controller rescan diff --git a/src/nvme/tree.h b/src/nvme/tree.h index 0156a07158..e751d7c666 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -66,7 +66,7 @@ nvme_ns_t nvme_subsystem_first_ns(nvme_subsystem_t s); nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n); /** - * () + * nvme_for_each_subsystem_safe() */ #define nvme_for_each_subsystem_safe(r, s, _s) \ for (s = nvme_first_subsystem(r), \ @@ -75,14 +75,14 @@ nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n); s = _s, _s = nvme_next_subsystem(r, s)) /** - * () + * nvme_for_each_subsystem() */ #define nvme_for_each_subsystem(r, s) \ for (s = nvme_first_subsystem(r); s != NULL; \ s = nvme_next_subsystem(r, s)) /** - * () + * nvme_subsystem_for_each_ctrl_safe() */ #define nvme_subsystem_for_each_ctrl_safe(s, c, _c) \ for (c = nvme_subsystem_first_ctrl(s), \ @@ -91,14 +91,14 @@ nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n); c = _c, _c = nvme_subsystem_next_ctrl(s, c)) /** - * () + * nvme_subsystem_for_each_ctrl() */ #define nvme_subsystem_for_each_ctrl(s, c) \ for (c = nvme_subsystem_first_ctrl(s); c != NULL; \ c = nvme_subsystem_next_ctrl(s, c)) /** - * () + * nvme_ctrl_for_each_ns_safe() */ #define nvme_ctrl_for_each_ns_safe(c, n, _n) \ for (n = nvme_ctrl_first_ns(c), \ @@ -107,14 +107,14 @@ nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n); n = _n, _n = nvme_ctrl_next_ns(c, n)) /** - * () + * nvme_ctrl_for_each_ns() */ #define nvme_ctrl_for_each_ns(c, n) \ for (n = nvme_ctrl_first_ns(c); n != NULL; \ n = nvme_ctrl_next_ns(c, n)) /** - * () + * nvme_ctrl_for_each_path_safe() */ #define nvme_ctrl_for_each_path_safe(c, p, _p) \ for (p = nvme_ctrl_first_path(c), \ @@ -123,14 +123,14 @@ nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n); p = _p, _p = nvme_ctrl_next_path(c, p)) /** - * () + * nvme_ctrl_for_each_path() */ #define nvme_ctrl_for_each_path(c, p) \ for (p = nvme_ctrl_first_path(c); p != NULL; \ p = nvme_ctrl_next_path(c, p)) /** - * () + * nvme_subsystem_for_each_ns_safe() */ #define nvme_subsystem_for_each_ns_safe(s, n, _n) \ for (n = nvme_subsystem_first_ns(s), \ @@ -139,7 +139,7 @@ nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n); n = _n, _n = nvme_subsystem_next_ns(s, n)) /** - * () + * nvme_subsystem_for_each_ns() */ #define nvme_subsystem_for_each_ns(s, n) \ for (n = nvme_subsystem_first_ns(s); n != NULL; \ @@ -171,12 +171,12 @@ uint64_t nvme_ns_get_lba_count(nvme_ns_t n); uint64_t nvme_ns_get_lba_util(nvme_ns_t n); /** - * char () - + * nvme_ns_get_sysfs_dir() - */ const char *nvme_ns_get_sysfs_dir(nvme_ns_t n); /** - * char () - + * nvme_ns_get_name() - */ const char *nvme_ns_get_name(nvme_ns_t n); @@ -231,17 +231,17 @@ int nvme_ns_flush(nvme_ns_t n); int nvme_ns_identify(nvme_ns_t n, struct nvme_id_ns *ns); /** - * char () - + * nvme_path_get_name() - */ const char *nvme_path_get_name(nvme_path_t p); /** - * char () - + * nvme_path_get_sysfs_dir() - */ const char *nvme_path_get_sysfs_dir(nvme_path_t p); /** - * char () - + * nvme_path_get_ana_state() - */ const char *nvme_path_get_ana_state(nvme_path_t p); @@ -255,59 +255,64 @@ nvme_ctrl_t nvme_path_get_subsystem(nvme_path_t p); */ nvme_ns_t nvme_path_get_ns(nvme_path_t p); +/** + * nvme_ctrl_get_fd() - + */ int nvme_ctrl_get_fd(nvme_ctrl_t c); + /** - * char () - + * nvme_ctrl_get_name() - */ const char *nvme_ctrl_get_name(nvme_ctrl_t c); /** - * char () - + * nvme_ctrl_get_sysfs_dir() - */ const char *nvme_ctrl_get_sysfs_dir(nvme_ctrl_t c); /** - * char () - + * nvme_ctrl_get_address() - */ const char *nvme_ctrl_get_address(nvme_ctrl_t c); /** - * char () - + * nvme_ctrl_get_firmware() - */ const char *nvme_ctrl_get_firmware(nvme_ctrl_t c); /** - * char () - + * nvme_ctrl_get_model() - */ const char *nvme_ctrl_get_model(nvme_ctrl_t c); /** - * char () - + * nvme_ctrl_get_state() - */ const char *nvme_ctrl_get_state(nvme_ctrl_t c); /** - * char () - + * nvme_ctrl_get_numa_node() - */ const char *nvme_ctrl_get_numa_node(nvme_ctrl_t c); /** - * char () - + * nvme_ctrl_get_queue_count() - */ const char *nvme_ctrl_get_queue_count(nvme_ctrl_t c); /** - * char () - + * nvme_ctrl_get_serial() - */ const char *nvme_ctrl_get_serial(nvme_ctrl_t c); /** - * char () - + * nvme_ctrl_get_sqsize() - */ const char *nvme_ctrl_get_sqsize(nvme_ctrl_t c); /** - * char () - + * nvme_ctrl_get_transport() - */ const char *nvme_ctrl_get_transport(nvme_ctrl_t c); /** - * char () - + * nvme_ctrl_get_nqn() - */ const char *nvme_ctrl_get_nqn(nvme_ctrl_t c); /** - * char () - + * nvme_ctrl_get_subsysnqn() - */ const char *nvme_ctrl_get_subsysnqn(nvme_ctrl_t c); + /** * nvme_ctrl_get_subsystem() - */ @@ -317,10 +322,12 @@ nvme_subsystem_t nvme_ctrl_get_subsystem(nvme_ctrl_t c); * nvme_ctrl_identify() - */ int nvme_ctrl_identify(nvme_ctrl_t c, struct nvme_id_ctrl *id); + /** * nvme_ctrl_disconnect() - */ int nvme_ctrl_disconnect(nvme_ctrl_t c); + /** * nvme_scan_ctrl() - */ @@ -336,15 +343,17 @@ void nvme_free_ctrl(struct nvme_ctrl *c); void nvme_unlink_ctrl(struct nvme_ctrl *c); /** - * char () - + * nvme_subsystem_get_nqn() - */ const char *nvme_subsystem_get_nqn(nvme_subsystem_t s); + /** - * char () - + * nvme_subsystem_get_sysfs_dir() - */ const char *nvme_subsystem_get_sysfs_dir(nvme_subsystem_t s); + /** - * char () - + * nvme_subsystem_get_name() - */ const char *nvme_subsystem_get_name(nvme_subsystem_t s); @@ -376,22 +385,22 @@ void nvme_reset_topology(nvme_root_t r); void nvme_free_tree(nvme_root_t r); /** - * *() - + * nvme_get_subsys_attr() - */ char *nvme_get_subsys_attr(nvme_subsystem_t s, const char *attr); /** - * *() - + * nvme_get_ctrl_attr() - */ char *nvme_get_ctrl_attr(nvme_ctrl_t c, const char *attr); /** - * *() - + * nvme_get_ns_attr() - */ char *nvme_get_ns_attr(nvme_ns_t n, const char *attr); /** - * *() - + * nvme_get_path_attr() - */ char *nvme_get_path_attr(nvme_path_t p, const char *attr); diff --git a/src/nvme/util.c b/src/nvme/util.c index bd06328acc..9b0c68be74 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -212,8 +212,8 @@ int nvme_open(const char *name) return -1; } -int nvme_fw_download_split(int fd, __u32 size, __u32 xfer, __u32 offset, - void *buf) +int nvme_fw_download_seq(int fd, __u32 size, __u32 xfer, __u32 offset, + void *buf) { int err = 0; @@ -263,9 +263,11 @@ int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, int nvme_get_telemetry_log(int fd, bool create, bool ctrl, int data_area, void **buf, __u32 *log_size) { - struct nvme_telemetry_log *telem; static const __u32 xfer = 512; - __u32 size, offset = xfer; + + __u8 lid = NVME_LOG_LID_TELEMETRY_HOST; + struct nvme_telemetry_log *telem; + __u32 size; void *log; int err; @@ -275,9 +277,10 @@ int nvme_get_telemetry_log(int fd, bool create, bool ctrl, int data_area, return -1; } - if (ctrl) + if (ctrl) { err = nvme_get_log_telemetry_ctrl(fd, true, 0, xfer, log); - else if (create) + lid = NVME_LOG_LID_TELEMETRY_CTRL; + } else if (create) err = nvme_get_log_create_telemetry_host(fd, log); else err = nvme_get_log_telemetry_host(fd, 0, xfer, log); @@ -314,17 +317,9 @@ int nvme_get_telemetry_log(int fd, bool create, bool ctrl, int data_area, goto free; } - while (offset != size) { - if (ctrl) - err = nvme_get_log_telemetry_ctrl(fd, true, offset, - xfer, log + offset); - else - err = nvme_get_log_telemetry_host(fd, offset, xfer, - log + offset); - if (err) - goto free; - offset += xfer; - } + err = nvme_get_log_page(fd, NVME_NSID_NONE, lid, true, size, (void *)log); + if (err) + goto free; done: *log_size = size; *buf = log; diff --git a/src/nvme/util.h b/src/nvme/util.h index 96f9421865..d608eef20c 100644 --- a/src/nvme/util.h +++ b/src/nvme/util.h @@ -33,10 +33,10 @@ const char *nvme_status_to_string(int status, bool fabrics); __u8 nvme_status_to_errno(int status, bool fabrics); /** - * nvme_fw_download_split() - + * nvme_fw_download_seq() - */ -int nvme_fw_download_split(int fd, __u32 size, __u32 xfer, __u32 offset, - void *buf); +int nvme_fw_download_seq(int fd, __u32 size, __u32 xfer, __u32 offset, + void *buf); /** * nvme_get_telemetry_log() - From 581642b1501db54f65315ab958e659ac65dab567 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 6 Feb 2020 14:49:40 -0800 Subject: [PATCH 0004/1564] Add nvme display tree example Simple visual demonstration of an nvme topology. Signed-off-by: Keith Busch --- .gitignore | 8 +++ Makefile | 2 +- examples/Makefile | 4 +- examples/display-tree.c | 59 +++++++++++++++++++ .../{nvme-telemetry.c => telemetry-listen.c} | 0 5 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 examples/display-tree.c rename examples/{nvme-telemetry.c => telemetry-listen.c} (100%) diff --git a/.gitignore b/.gitignore index c225675465..fa77022a8e 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,14 @@ a.out *.swp *.a *.so.* + test/test +examples/display-tree +examples/telemetry-listen + +config-host.h +config-host.mak +config.log + cscope.* diff --git a/Makefile b/Makefile index 32bc5afca1..f197496306 100644 --- a/Makefile +++ b/Makefile @@ -49,7 +49,7 @@ install-tests: @$(MAKE) -C test install prefix=$(DESTDIR)$(prefix) datadir=$(DESTDIR)$(datadir) clean: - @rm -f config-host.mak config-host.h cscope.out $(NAME).pc + @rm -f config-host.mak config-host.h cscope.out cscope.files $(NAME).pc @$(MAKE) -C src clean @$(MAKE) -C test clean @$(MAKE) -C examples clean diff --git a/examples/Makefile b/examples/Makefile index baa7b08310..877428a483 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -7,11 +7,11 @@ ifneq ($(MAKECMDGOALS),clean) include ../config-host.mak endif -all_targets += nvme-telemetry +all_targets += telemetry-listen display-tree all: $(all_targets) -test_srcs := nvme-telemetry +test_srcs := telemetry-listen.c display-tree.c test_objs := $(patsubst %.c,%.ol,$(test_srcs)) diff --git a/examples/display-tree.c b/examples/display-tree.c new file mode 100644 index 0000000000..9d00da2791 --- /dev/null +++ b/examples/display-tree.c @@ -0,0 +1,59 @@ +/** + * display-tree: Scans the nvme topology, prints as an ascii tree with some + * selected attributes for each component. + */ +#include +#include + +int main() +{ + nvme_root_t r; + nvme_subsystem_t s, _s; + nvme_ctrl_t c, _c; + nvme_path_t p, _p; + nvme_ns_t n, _n; + + r = nvme_scan(); + if (!r) + return -1; + + printf(".\n"); + nvme_for_each_subsystem_safe(r, s, _s) { + printf("%c-- %s - NQN=%s\n", _s ? '|' : '`', + nvme_subsystem_get_name(s), + nvme_subsystem_get_nqn(s)); + + nvme_subsystem_for_each_ns_safe(s, n, _n) { + printf("%c |-- %s lba size:%d lba max:%lu\n", + _s ? '|' : ' ', + nvme_ns_get_name(n), nvme_ns_get_lba_size(n), + nvme_ns_get_lba_count(n)); + } + + nvme_subsystem_for_each_ctrl_safe(s, c, _c) { + printf("%c %c-- %s %s %s %s\n", + _s ? '|' : ' ', _c ? '|' : '`', + nvme_ctrl_get_name(c), + nvme_ctrl_get_transport(c), + nvme_ctrl_get_address(c), + nvme_ctrl_get_state(c)); + + nvme_ctrl_for_each_ns_safe(c, n, _n) + printf("%c %c %c-- %s lba size:%d lba max:%lu\n", + _s ? '|' : ' ', _c ? '|' : ' ', + _n ? '|' : '`', + nvme_ns_get_name(n), + nvme_ns_get_lba_size(n), + nvme_ns_get_lba_count(n)); + + nvme_ctrl_for_each_path_safe(c, p, _p) + printf("%c %c %c-- %s %s\n", + _s ? '|' : ' ', _c ? '|' : ' ', + _p ? '|' : '`', + nvme_path_get_name(p), + nvme_path_get_ana_state(p)); + } + } + nvme_free_tree(r); + return 0; +} diff --git a/examples/nvme-telemetry.c b/examples/telemetry-listen.c similarity index 100% rename from examples/nvme-telemetry.c rename to examples/telemetry-listen.c From 54e5da06650d5b4a276182a82d26f18c7231abf3 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 6 Feb 2020 14:58:10 -0800 Subject: [PATCH 0005/1564] examples/telemetry: Fix scanning uevent file Continue to the next line if current one does not contain async event information. Signed-off-by: Keith Busch --- examples/telemetry-listen.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/telemetry-listen.c b/examples/telemetry-listen.c index 1705462a6c..1561a0c740 100644 --- a/examples/telemetry-listen.c +++ b/examples/telemetry-listen.c @@ -11,7 +11,7 @@ #include #include #include - + struct events { nvme_ctrl_t c; int uevent_fd; @@ -63,7 +63,6 @@ static void save_telemetry(nvme_ctrl_t c) else printf("telemetry log save as %s, wrote:%d size:%d\n", buf, ret, log_size); - close(fd); free(log); } @@ -81,7 +80,7 @@ static void check_telemetry(nvme_ctrl_t c, int ufd) __u32 aen, type, info, lid; if (sscanf(p, "NVME_AEN=0x%08x", &aen) != 1) - break; + continue; type = aen & 0x07; info = (aen >> 8) & 0xff; From 556949e5bbd8d6db748e863255f255cd463c9d61 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 6 Feb 2020 15:12:55 -0800 Subject: [PATCH 0006/1564] examples: Add column disaply of topology Pretty print nvme topology in detailed columns. Signed-off-by: Keith Busch --- .gitignore | 1 + examples/Makefile | 4 +- examples/display-columnar.c | 100 ++++++++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 examples/display-columnar.c diff --git a/.gitignore b/.gitignore index fa77022a8e..2cef1e0bc1 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ a.out test/test examples/display-tree +examples/display-columnar examples/telemetry-listen config-host.h diff --git a/examples/Makefile b/examples/Makefile index 877428a483..5c4a082e80 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -7,11 +7,11 @@ ifneq ($(MAKECMDGOALS),clean) include ../config-host.mak endif -all_targets += telemetry-listen display-tree +all_targets += telemetry-listen display-tree display-columnar all: $(all_targets) -test_srcs := telemetry-listen.c display-tree.c +test_srcs := telemetry-listen.c display-tree.c display-columnar.c test_objs := $(patsubst %.c,%.ol,$(test_srcs)) diff --git a/examples/display-columnar.c b/examples/display-columnar.c new file mode 100644 index 0000000000..b3dbc7ea86 --- /dev/null +++ b/examples/display-columnar.c @@ -0,0 +1,100 @@ +/** + * display-tree: Scans the nvme topology, prints as an ascii tree with some + * selected attributes for each component. + */ +#include +#include + +static const char dash[101] = {[0 ... 99] = '-'}; +int main() +{ + nvme_root_t r; + nvme_subsystem_t s; + nvme_ctrl_t c; + nvme_path_t p; + nvme_ns_t n; + + r = nvme_scan(); + if (!r) + return -1; + + + printf("%-16s %-96s %-.16s\n", "Subsystem", "Subsystem-NQN", "Controllers"); + printf("%-.16s %-.96s %-.16s\n", dash, dash, dash); + + nvme_for_each_subsystem(r, s) { + bool first = true; + printf("%-16s %-96s ", nvme_subsystem_get_name(s), nvme_subsystem_get_nqn(s)); + + nvme_subsystem_for_each_ctrl(s, c) { + printf("%s%s", first ? "": ", ", nvme_ctrl_get_name(c)); + first = false; + } + printf("\n"); + } + printf("\n"); + + printf("%-8s %-20s %-40s %-8s %-6s %-14s %-12s %-16s\n", "Device", + "SN", "MN", "FR", "TxPort", "Address", "Subsystem", "Namespaces"); + printf("%-.8s %-.20s %-.40s %-.8s %-.6s %-.14s %-.12s %-.16s\n", dash, dash, + dash, dash, dash, dash, dash, dash); + + nvme_for_each_subsystem(r, s) { + nvme_subsystem_for_each_ctrl(s, c) { + bool first = true; + + printf("%-8s %-20s %-40s %-8s %-6s %-14s %-12s ", + nvme_ctrl_get_name(c), nvme_ctrl_get_serial(c), + nvme_ctrl_get_model(c), nvme_ctrl_get_firmware(c), + nvme_ctrl_get_transport(c), nvme_ctrl_get_address(c), + nvme_subsystem_get_name(s)); + + nvme_ctrl_for_each_ns(c, n) { + printf("%s%s", first ? "": ", ", + nvme_ns_get_name(n)); + first = false; + } + + nvme_ctrl_for_each_path(c, p) { + printf("%s%s", first ? "": ", ", + nvme_ns_get_name(nvme_path_get_ns(p))); + first = false; + } + printf("\n"); + } + } + printf("\n"); + + printf("%-12s %-8s %-16s %-8s %-16s\n", "Device", "NSID", "Sectors", "Format", "Controllers"); + printf("%-.12s %-.8s %-.16s %-.8s %-.16s\n", dash, dash, dash, dash, dash); + + nvme_for_each_subsystem(r, s) { + nvme_subsystem_for_each_ctrl(s, c) + nvme_ctrl_for_each_ns(c, n) + printf("%-12s %-8d %-16lu %-8d %s\n", + nvme_ns_get_name(n), + nvme_ns_get_nsid(n), + nvme_ns_get_lba_count(n), + nvme_ns_get_lba_size(n), + nvme_ctrl_get_name(c)); + + nvme_subsystem_for_each_ns(s, n) { + bool first = true; + + printf("%-12s %-8d %-16lu %-8d ", + nvme_ns_get_name(n), + nvme_ns_get_nsid(n), + nvme_ns_get_lba_count(n), + nvme_ns_get_lba_size(n)); + + nvme_subsystem_for_each_ctrl(s, c) { + printf("%s%s", first ? "" : ", ", + nvme_ctrl_get_name(c)); + first = false; + } + printf("\n"); + } + } + return 0; +} + From 339364742b85f2d1944cff9bad53f64f7674a54e Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 6 Feb 2020 16:43:45 -0800 Subject: [PATCH 0007/1564] examples: Add loop discover example A basic fabrics example discoverying loop nvme fabric targets. Apply fixes and updates to lib code as needed from testing. Signed-off-by: Keith Busch --- .gitignore | 1 + examples/Makefile | 6 ++-- examples/discover-loop.c | 72 +++++++++++++++++++++++++++++++++++++ examples/display-columnar.c | 4 +-- src/Makefile | 2 +- src/libnvme.map | 1 + src/nvme/fabrics.c | 22 +++++++++--- src/nvme/ioctl.c | 5 ++- src/nvme/util.c | 24 ++++++++----- src/nvme/util.h | 21 +++++++++++ 10 files changed, 136 insertions(+), 22 deletions(-) create mode 100644 examples/discover-loop.c diff --git a/.gitignore b/.gitignore index 2cef1e0bc1..364c1d0e86 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ test/test examples/display-tree examples/display-columnar examples/telemetry-listen +examples/discover-loop config-host.h config-host.mak diff --git a/examples/Makefile b/examples/Makefile index 5c4a082e80..0a70e9b812 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -1,5 +1,5 @@ CFLAGS ?= -g -O2 -override CFLAGS += -Wall -D_GNU_SOURCE -L../src/ -I../src/ +override CFLAGS += -Wall -D_GNU_SOURCE -L../src/ -I../src/ -lsystemd include ../Makefile.quiet @@ -7,11 +7,11 @@ ifneq ($(MAKECMDGOALS),clean) include ../config-host.mak endif -all_targets += telemetry-listen display-tree display-columnar +all_targets += telemetry-listen display-tree display-columnar discover-loop all: $(all_targets) -test_srcs := telemetry-listen.c display-tree.c display-columnar.c +test_srcs := telemetry-listen.c display-tree.c display-columnar.c discover-loop.c test_objs := $(patsubst %.c,%.ol,$(test_srcs)) diff --git a/examples/discover-loop.c b/examples/discover-loop.c new file mode 100644 index 0000000000..6b9d01ff0a --- /dev/null +++ b/examples/discover-loop.c @@ -0,0 +1,72 @@ +/** + * discover-loop: Use fabrics commands to discover any loop targets and print + * those records. You must have at least one configured nvme loop target on the + * system (no existing connection required). The output will look more + * interesting with more targets. + */ +#include +#include +#include +#include +#include + +static void print_discover_log(struct nvmf_discovery_log *log) +{ + int i, numrec = le64_to_cpu(log->numrec); + + printf(".\n"); + printf("|-- genctr:%llx\n", log->genctr); + printf("|-- numrec:%x\n", numrec); + printf("`-- recfmt:%x\n", log->recfmt); + + for (i = 0; i < numrec; i++) { + struct nvmf_disc_log_entry *e = &log->entries[i]; + + printf(" %c-- Entry:%d\n", (i < numrec - 1) ? '|' : '`', i); + printf(" %c |-- trtype:%x\n", (i < numrec - 1) ? '|' : ' ', e->trtype); + printf(" %c |-- adrfam:%x\n", (i < numrec - 1) ? '|' : ' ', e->adrfam); + printf(" %c |-- subtype:%x\n", (i < numrec - 1) ? '|' : ' ', e->subtype); + printf(" %c |-- treq:%x\n", (i < numrec - 1) ? '|' : ' ', e->treq); + printf(" %c |-- portid:%x\n", (i < numrec - 1) ? '|' : ' ', e->portid); + printf(" %c |-- cntlid:%x\n", (i < numrec - 1) ? '|' : ' ', e->cntlid); + printf(" %c |-- asqsz:%x\n", (i < numrec - 1) ? '|' : ' ', e->asqsz); + printf(" %c |-- trsvcid:%s\n", (i < numrec - 1) ? '|' : ' ', e->trsvcid); + printf(" %c |-- subnqn:%s\n", (i < numrec - 1) ? '|' : ' ', e->subnqn); + printf(" %c `-- traddr:%s\n", (i < numrec - 1) ? '|' : ' ', e->traddr); + } +} + +int main() +{ + struct nvmf_discovery_log *log = NULL; + nvme_ctrl_t c; + char *hnqn; + int ret; + + struct nvme_fabrics_config cfg = { + .nqn = NVME_DISC_SUBSYS_NAME, + .transport = "loop", + .tos = -1, + }; + + hnqn = nvmf_hostnqn_from_file(), + cfg.hostnqn = hnqn; + + c = nvmf_add_ctrl(&cfg); + if (!c) { + fprintf(stderr, "no controller found\n"); + return errno; + } + + ret = nvmf_get_discovery_log(c, &log, 4); + nvme_ctrl_disconnect(c); + nvme_free_ctrl(c); + + if (ret) + fprintf(stderr, "nvmf-discover-log:%x\n", ret); + else + print_discover_log(log); + + free(hnqn); + return 0; +} diff --git a/examples/display-columnar.c b/examples/display-columnar.c index b3dbc7ea86..014c8dc44d 100644 --- a/examples/display-columnar.c +++ b/examples/display-columnar.c @@ -1,6 +1,6 @@ /** - * display-tree: Scans the nvme topology, prints as an ascii tree with some - * selected attributes for each component. + * display-columnar: Scans the nvme topology, prints each record type in a + * column format for easy visual scanning. */ #include #include diff --git a/src/Makefile b/src/Makefile index 396e8caf8e..6b5847480e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -10,7 +10,7 @@ CFLAGS ?= -g -fomit-frame-pointer -O2 -I/usr/include -Invme/ override CFLAGS += -Wall -fPIC SO_CFLAGS=-shared $(CFLAGS) L_CFLAGS=$(CFLAGS) -LINK_FLAGS= -L /usr/lib64 +LINK_FLAGS= -L /usr/lib64 -lsystemd LINK_FLAGS+=$(LDFLAGS) ENABLE_SHARED ?= 1 SED ?= sed diff --git a/src/libnvme.map b/src/libnvme.map index fbb3355b4f..6fb0c9e2c9 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -216,6 +216,7 @@ nvme_setup_ctrl_list; nvme_dsm_range; nvme_get_log_page; + __nvme_get_log_page; nvme_get_ana_log_len; nvme_namespace_attach_ctrls; nvme_namespace_detach_ctrls; diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 56e97fcad6..2e232ddf70 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -154,8 +154,6 @@ int nvmf_add_ctrl_opts(struct nvme_fabrics_config *cfg) return ret; ret = __nvmf_add_ctrl(argstr); - printf("ctrl:%s ret:%d\n", argstr, ret); - free(argstr); return ret; } @@ -229,7 +227,23 @@ nvme_ctrl_t nvmf_connect_disc_entry(struct nvmf_disc_log_entry *e, errno = EINVAL; return NULL; } - cfg.transport = nvmf_trtype_str(e->trtype); + + switch (e->trtype) { + case NVMF_TRTYPE_RDMA: + cfg.transport = "rdma"; + break; + case NVMF_TRTYPE_FC: + cfg.transport = "fc"; + break; + case NVMF_TRTYPE_TCP: + cfg.transport = "tcp"; + break; + case NVMF_TRTYPE_LOOP: + cfg.transport = "loop"; + break; + default: + break; + } cfg.nqn = e->subnqn; if (e->treq & NVMF_TREQ_DISABLE_SQFLOW) @@ -248,7 +262,7 @@ nvme_ctrl_t nvmf_connect_disc_entry(struct nvmf_disc_log_entry *e, static int nvme_discovery_log(int fd, __u32 len, struct nvmf_discovery_log *log) { - return nvme_get_log_page(fd, 0, NVME_LOG_LID_DISCOVER, true, len, log); + return __nvme_get_log_page(fd, 0, NVME_LOG_LID_DISCOVER, true, 512, len, log); } int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index ab7b022f01..a0d22f7716 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -18,10 +18,9 @@ static int nvme_verify_chr(int fd) static struct stat nvme_stat; int err = fstat(fd, &nvme_stat); - if (err < 0) { - perror("fstat"); + if (err < 0) return errno; - } + if (!S_ISCHR(nvme_stat.st_mode)) { errno = ENOTBLK; return -1; diff --git a/src/nvme/util.c b/src/nvme/util.c index 9b0c68be74..6234ea0e65 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -231,10 +231,10 @@ int nvme_fw_download_seq(int fd, __u32 size, __u32 xfer, __u32 offset, return err; } -int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, - __u32 data_len, void *data) +int __nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, + __u32 xfer_len, __u32 data_len, void *data) { - __u64 offset = 0, xfer_len = data_len; + __u64 offset = 0, xfer; void *ptr = data; int ret; @@ -243,23 +243,29 @@ int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, * avoids having to check the MDTS value of the controller. */ do { - xfer_len = data_len - offset; - if (xfer_len > 4096) - xfer_len = 4096; + xfer = data_len - offset; + if (xfer > xfer_len) + xfer = xfer_len; ret = nvme_get_log(fd, log_id, nsid, offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, - xfer_len, ptr); + xfer, ptr); if (ret) return ret; - offset += xfer_len; - ptr += xfer_len; + offset += xfer; + ptr += xfer; } while (offset < data_len); return 0; } +int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, + __u32 data_len, void *data) +{ + return __nvme_get_log_page(fd, nsid, log_id, rae, 4086, data_len, data); +} + int nvme_get_telemetry_log(int fd, bool create, bool ctrl, int data_area, void **buf, __u32 *log_size) { diff --git a/src/nvme/util.h b/src/nvme/util.h index d608eef20c..04bd88d4b5 100644 --- a/src/nvme/util.h +++ b/src/nvme/util.h @@ -72,8 +72,29 @@ void nvme_setup_ctrl_list(struct nvme_ctrl_list *cntlist, __u16 num_ctrls, void nvme_setup_dsm_range(struct nvme_dsm_range *dsm, __u32 *ctx_attrs, __u32 *llbas, __u64 *slbas, __u16 nr_ranges); +/** + * __nvme_get_log_page() - + * @fd: + * @nsid: + * @log_id: + * @rae: + * @xfer_len: Max partial log transfer size to request while splitting + * @data_len: + * @data: + */ +int __nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, + __u32 xfer_len, __u32 data_len, void *data); + /** * nvme_get_log_page() - + * @fd: + * @nsid: + * @log_id: + * @rae: + * @data_len: + * @data: + * + * Calls __nvme_get_log_page() with a default 4k transfer length. */ int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, __u32 data_len, void *data); From 0f0c956ac03f74c675270509f55b0a7197239041 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 6 Feb 2020 18:04:07 -0800 Subject: [PATCH 0008/1564] Add documentation Experimenting with documentation generation: Initialize sphinx documentation building. Use linux's 'scripts/kernel-doc' to extract documentation comments from source and format as .rst file. Signed-off-by: Keith Busch --- doc/Makefile | 20 + doc/conf.py | 55 + doc/index.rst | 20 + doc/libnvme.rst | 10456 ++++++++++++++++++++++++++++++++++++++++++++++ doc/make.bat | 35 + src/nvme/cmd.h | 36 +- 6 files changed, 10604 insertions(+), 18 deletions(-) create mode 100644 doc/Makefile create mode 100644 doc/conf.py create mode 100644 doc/index.rst create mode 100644 doc/libnvme.rst create mode 100644 doc/make.bat diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 0000000000..d4bb2cbb9e --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/doc/conf.py b/doc/conf.py new file mode 100644 index 0000000000..745075b25c --- /dev/null +++ b/doc/conf.py @@ -0,0 +1,55 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + + +# -- Project information ----------------------------------------------------- + +project = 'libnvme' +copyright = '2020, Keith Busch' +author = 'Keith Busch ' + +# The full version, including alpha/beta/rc tags +release = '0.1' + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'alabaster' + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] diff --git a/doc/index.rst b/doc/index.rst new file mode 100644 index 0000000000..f435859465 --- /dev/null +++ b/doc/index.rst @@ -0,0 +1,20 @@ +.. libnvme documentation master file, created by + sphinx-quickstart on Thu Feb 6 17:59:42 2020. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to libnvme's documentation! +=================================== + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/doc/libnvme.rst b/doc/libnvme.rst new file mode 100644 index 0000000000..39c23592aa --- /dev/null +++ b/doc/libnvme.rst @@ -0,0 +1,10456 @@ +**NVMe Admin command enums** + + + + +.. c:type:: enum nvme_admin_opcode + + Known NVMe admin opcodes + +**Constants** + +``nvme_admin_delete_sq`` + *undescribed* + +``nvme_admin_create_sq`` + *undescribed* + +``nvme_admin_get_log_page`` + *undescribed* + +``nvme_admin_delete_cq`` + *undescribed* + +``nvme_admin_create_cq`` + *undescribed* + +``nvme_admin_identify`` + *undescribed* + +``nvme_admin_abort_cmd`` + *undescribed* + +``nvme_admin_set_features`` + *undescribed* + +``nvme_admin_get_features`` + *undescribed* + +``nvme_admin_async_event`` + *undescribed* + +``nvme_admin_ns_mgmt`` + *undescribed* + +``nvme_admin_fw_commit`` + *undescribed* + +``nvme_admin_fw_download`` + *undescribed* + +``nvme_admin_dev_self_test`` + *undescribed* + +``nvme_admin_ns_attach`` + *undescribed* + +``nvme_admin_keep_alive`` + *undescribed* + +``nvme_admin_directive_send`` + *undescribed* + +``nvme_admin_directive_recv`` + *undescribed* + +``nvme_admin_virtual_mgmt`` + *undescribed* + +``nvme_admin_nvme_mi_send`` + *undescribed* + +``nvme_admin_nvme_mi_recv`` + *undescribed* + +``nvme_admin_dbbuf`` + *undescribed* + +``nvme_admin_fabrics`` + *undescribed* + +``nvme_admin_format_nvm`` + *undescribed* + +``nvme_admin_security_send`` + *undescribed* + +``nvme_admin_security_recv`` + *undescribed* + +``nvme_admin_sanitize_nvm`` + *undescribed* + +``nvme_admin_get_lba_status`` + *undescribed* + + + + +.. c:type:: enum nvme_identify_cns + + +**Constants** + +``NVME_IDENTIFY_CNS_NS`` + *undescribed* + +``NVME_IDENTIFY_CNS_CTRL`` + *undescribed* + +``NVME_IDENTIFY_CNS_NS_ACTIVE_LIST`` + *undescribed* + +``NVME_IDENTIFY_CNS_NS_DESC_LIST`` + *undescribed* + +``NVME_IDENTIFY_CNS_NVMSET_LIST`` + *undescribed* + +``NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST`` + *undescribed* + +``NVME_IDENTIFY_CNS_ALLOCATED_NS`` + *undescribed* + +``NVME_IDENTIFY_CNS_NS_CTRL_LIST`` + *undescribed* + +``NVME_IDENTIFY_CNS_CTRL_LIST`` + *undescribed* + +``NVME_IDENTIFY_CNS_PRIMARY_CTRL_CAP`` + *undescribed* + +``NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST`` + *undescribed* + +``NVME_IDENTIFY_CNS_NS_GRANULARITY`` + *undescribed* + +``NVME_IDENTIFY_CNS_UUID_LIST`` + *undescribed* + + + + +.. c:type:: enum nvme_cmd_get_log_lid + + +**Constants** + +``NVME_LOG_LID_ERROR`` + *undescribed* + +``NVME_LOG_LID_SMART`` + *undescribed* + +``NVME_LOG_LID_FW_SLOT`` + *undescribed* + +``NVME_LOG_LID_CHANGED_NS`` + *undescribed* + +``NVME_LOG_LID_CMD_EFFECTS`` + *undescribed* + +``NVME_LOG_LID_DEVICE_SELF_TEST`` + *undescribed* + +``NVME_LOG_LID_TELEMETRY_HOST`` + *undescribed* + +``NVME_LOG_LID_TELEMETRY_CTRL`` + *undescribed* + +``NVME_LOG_LID_ENDURANCE_GROUP`` + *undescribed* + +``NVME_LOG_LID_PREDICTABLE_LAT_NVMSET`` + *undescribed* + +``NVME_LOG_LID_PREDICTABLE_LAT_AGG`` + *undescribed* + +``NVME_LOG_LID_ANA`` + *undescribed* + +``NVME_LOG_LID_PERSISTENT_EVENT`` + *undescribed* + +``NVME_LOG_LID_LBA_STATUS`` + *undescribed* + +``NVME_LOG_LID_ENDURANCE_GRP_EVT`` + *undescribed* + +``NVME_LOG_LID_DISCOVER`` + *undescribed* + +``NVME_LOG_LID_RESERVATION`` + *undescribed* + +``NVME_LOG_LID_SANITIZE`` + *undescribed* + + + + +.. c:type:: enum nvme_features_id + + +**Constants** + +``NVME_FEAT_FID_ARBITRATION`` + *undescribed* + +``NVME_FEAT_FID_POWER_MGMT`` + *undescribed* + +``NVME_FEAT_FID_LBA_RANGE`` + *undescribed* + +``NVME_FEAT_FID_TEMP_THRESH`` + *undescribed* + +``NVME_FEAT_FID_ERR_RECOVERY`` + *undescribed* + +``NVME_FEAT_FID_VOLATILE_WC`` + *undescribed* + +``NVME_FEAT_FID_NUM_QUEUES`` + *undescribed* + +``NVME_FEAT_FID_IRQ_COALESCE`` + *undescribed* + +``NVME_FEAT_FID_IRQ_CONFIG`` + *undescribed* + +``NVME_FEAT_FID_WRITE_ATOMIC`` + *undescribed* + +``NVME_FEAT_FID_ASYNC_EVENT`` + *undescribed* + +``NVME_FEAT_FID_AUTO_PST`` + *undescribed* + +``NVME_FEAT_FID_HOST_MEM_BUF`` + *undescribed* + +``NVME_FEAT_FID_TIMESTAMP`` + *undescribed* + +``NVME_FEAT_FID_KATO`` + *undescribed* + +``NVME_FEAT_FID_HCTM`` + *undescribed* + +``NVME_FEAT_FID_NOPSC`` + *undescribed* + +``NVME_FEAT_FID_RRL`` + *undescribed* + +``NVME_FEAT_FID_PLM_CONFIG`` + *undescribed* + +``NVME_FEAT_FID_PLM_WINDOW`` + *undescribed* + +``NVME_FEAT_FID_LBA_STS_INTERVAL`` + *undescribed* + +``NVME_FEAT_FID_HOST_BEHAVIOR`` + *undescribed* + +``NVME_FEAT_FID_SANITIZE`` + *undescribed* + +``NVME_FEAT_FID_ENDURANCE_EVT_CFG`` + *undescribed* + +``NVME_FEAT_FID_SW_PROGRESS`` + *undescribed* + +``NVME_FEAT_FID_HOST_ID`` + *undescribed* + +``NVME_FEAT_FID_RESV_MASK`` + *undescribed* + +``NVME_FEAT_RESV_PERSIST`` + *undescribed* + +``NVME_FEAT_FID_WRITE_PROTECT`` + *undescribed* + + + + +.. c:type:: enum nvme_get_features_sel + + +**Constants** + +``NVME_GET_FEATURES_SEL_CURRENT`` + *undescribed* + +``NVME_GET_FEATURES_SEL_DEFAULT`` + *undescribed* + +``NVME_GET_FEATURES_SEL_SAVED`` + *undescribed* + + + + +.. c:type:: enum nvme_cmd_format_mset + + +**Constants** + +``NVME_FORMAT_MSET_SEPARATE`` + *undescribed* + +``NVME_FORMAT_MSET_EXTENEDED`` + *undescribed* + + + + +.. c:type:: enum nvme_cmd_format_pi + + +**Constants** + +``NVME_FORMAT_PI_DISABLE`` + *undescribed* + +``NVME_FORMAT_PI_TYPE1`` + *undescribed* + +``NVME_FORMAT_PI_TYPE2`` + *undescribed* + +``NVME_FORMAT_PI_TYPE3`` + *undescribed* + + + + +.. c:type:: enum nvme_cmd_format_ses + + +**Constants** + +``NVME_FORMAT_SES_NONE`` + *undescribed* + +``NVME_FORMAT_SES_USER_DATA_ERASE`` + *undescribed* + +``NVME_FORMAT_SES_CRYPTO_ERASE`` + *undescribed* + + + + +.. c:type:: enum nvme_ns_mgmt_sel + + +**Constants** + +``NVME_NS_MGMT_SEL_CREATE`` + *undescribed* + +``NVME_NS_MGMT_SEL_DELETE`` + *undescribed* + + + + +.. c:type:: enum nvme_ns_attach_sel + + NVME_NS_ATTACH_SEL_CTRL_ATTACH: NVME_NP_ATTACH_SEL_CTRL_DEATTACH: + +**Constants** + +``NVME_NS_ATTACH_SEL_CTRL_ATTACH`` + *undescribed* + +``NVME_NS_ATTACH_SEL_CTRL_DEATTACH`` + *undescribed* + + + + +.. c:type:: enum nvme_fw_commit_ca + + +**Constants** + +``NVME_FW_COMMIT_CA_REPLACE`` + *undescribed* + +``NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE`` + *undescribed* + +``NVME_FW_COMMIT_CA_SET_ACTIVE`` + *undescribed* + +``NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE_IMMEDIATE`` + *undescribed* + +``NVME_FW_COMMIT_CA_REPLACE_BOOT_PARTITION`` + *undescribed* + +``NVME_FW_COMMIT_CA_ACTIVATE_BOOT_PARTITION`` + *undescribed* + + + + +.. c:type:: enum nvme_directive_dtype + + +**Constants** + +``NVME_DIRECTIVE_DTYPE_IDENTIFY`` + *undescribed* + +``NVME_DIRECTIVE_DTYPE_STREAMS`` + *undescribed* + + + + +.. c:type:: enum nvme_cmd_directive_receive_identify_doper + + +**Constants** + +``NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM`` + *undescribed* + + + + +.. c:type:: enum nvme_cmd_directive_receive_streams_doper + + +**Constants** + +``NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM`` + *undescribed* + +``NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS`` + *undescribed* + +``NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE`` + *undescribed* + + + + +.. c:type:: enum nvme_cmd_directive_send_identify_doper + + +**Constants** + +``NVME_DIRECTIVE_SEND_IDENTIFY_DOPER_ENDIR`` + *undescribed* + + + + +.. c:type:: enum nvme_cmd_directive_send_identify_endir + + +**Constants** + +``NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_DISABLE`` + *undescribed* + +``NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_ENABLE`` + *undescribed* + + + + +.. c:type:: enum nvme_cmd_directive_send_streams_doper + + +**Constants** + +``NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_IDENTIFIER`` + *undescribed* + +``NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE`` + *undescribed* + + + + +.. c:type:: enum nvme_sanitize_sanact + + +**Constants** + +``NVME_SANITIZE_SANACT_EXIT_FAILURE`` + *undescribed* + +``NVME_SANITIZE_SANACT_START_BLOCK_ERASE`` + *undescribed* + +``NVME_SANITIZE_SANACT_START_OVERWRITE`` + *undescribed* + +``NVME_SANITIZE_SANACT_START_CRYPTO_ERASE`` + *undescribed* + + + + +.. c:type:: enum nvme_dst_stc + + +**Constants** + +``NVME_DST_STC_SHORT`` + *undescribed* + +``NVME_DST_STC_LONG`` + *undescribed* + +``NVME_DST_STC_VS`` + *undescribed* + +``NVME_DST_STC_ABORT`` + *undescribed* + + + + +.. c:type:: enum nvme_virt_mgmt_act + + +**Constants** + +``NVME_VIRT_MGMT_ACT_PRIM_CTRL_FLEX_ALLOC`` + *undescribed* + +``NVME_VIRT_MGMT_ACT_OFFLINE_SEC_CTRL`` + *undescribed* + +``NVME_VIRT_MGMT_ACT_ASSIGN_SEC_CTRL`` + *undescribed* + +``NVME_VIRT_MGMT_ACT_ONLINE_SEC_CTRL`` + *undescribed* + + + + +.. c:type:: enum nvme_virt_mgmt_rt + + +**Constants** + +``NVME_VIRT_MGMT_RT_VQ_RESOURCE`` + *undescribed* + +``NVME_VIRT_MGMT_RT_VI_RESOURCE`` + *undescribed* + + +.. c:function:: int nvme_identify (int fd, enum nvme_identify_cns cns, __u32 nsid, __u16 cntid, __u16 nvmsetid, __u8 uuidx, void * data) + + Send the NVMe Identify command + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_identify_cns cns`` + The Controller or Namespace structure, see **enum** nvme_identify_cns + +``__u32 nsid`` + Namespace identifier, if applicable + +``__u16 cntid`` + The Controller Identifier, if applicable + +``__u16 nvmsetid`` + The NVMe Set ID if CNS is 04h + +``__u8 uuidx`` + UUID Index if controller supports this id selection method + +``void * data`` + User space destination address to transfer the data + +**Description** + +The Identify command returns a data buffer that describes information about +the NVM subsystem, the controller or the namespace(s). + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_identify_ctrl (int fd, struct nvme_id_ctrl * id) + + Retrieves nvme identify controller + +**Parameters** + +``int fd`` + File descriptor of nvme device + id: User space destination address to transfer the data, + +``struct nvme_id_ctrl * id`` + *undescribed* + +**Description** + +Sends nvme identify with CNS value ``NVME_IDENTIFY_CNS_CTRL``. + +See :c:type:`struct nvme_id_ctrl ` for details on the data returned. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_identify_ns (int fd, __u32 nsid, struct nvme_id_ns * ns) + + Retrieves nvme identify namespace + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace to identify + +``struct nvme_id_ns * ns`` + User space destination address to transfer the data + +**Description** + +If the Namespace Identifier (NSID) field specifies an active NSID, then the +Identify Namespace data structure is returned to the host for that specified +namespace. + +If the controller supports the Namespace Management capability and the NSID +field is set to ``NVME_NSID_ALL``, then the controller returns an Identify Namespace +data structure that specifies capabilities that are common across namespaces +for this controller. + +See :c:type:`struct nvme_id_ns ` for details on the structure returned. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_identify_allocated_ns (int fd, __u32 nsid, struct nvme_id_ns * ns) + + Same as nvme_identify_ns, but only for allocated namespaces + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace to identify + +``struct nvme_id_ns * ns`` + User space destination address to transfer the data + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_identify_active_ns_list (int fd, __u32 nsid, struct nvme_ns_list * list) + + Retrieves active namespaces id list + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Return namespaces greater than this identifer + +``struct nvme_ns_list * list`` + *undescribed* + +**Description** + +A list of 1024 namespace IDs is returned to the host containing NSIDs in +increasing order that are greater than the value specified in the Namespace +Identifier (nsid) field of the command. + +See :c:type:`struct nvme_ns_list ` for the definition of the returned structure. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_identify_allocated_ns_list (int fd, __u32 nsid, struct nvme_ns_list * list) + + Retrieves allocated namespace id list + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Return namespaces greater than this identifer + +``struct nvme_ns_list * list`` + *undescribed* + +**Description** + +A list of 1024 namespace IDs is returned to the host containing NSIDs in +increasing order that are greater than the value specified in the Namespace +Identifier (nsid) field of the command. + +See :c:type:`struct nvme_ns_list ` for the definition of the returned structure. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_identify_ctrl_list (int fd, __u16 cntid, struct nvme_ctrl_list * ctrlist) + + Retrieves identify controller list + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u16 cntid`` + *undescribed* + +``struct nvme_ctrl_list * ctrlist`` + *undescribed* + +**Description** + +Up to 2047 controller identifiers is returned containing a controller +identifier greater than or equal to the controller identifier specified in +**cntid**. + +See :c:type:`struct nvme_ctrl_list ` for a definition of the structure returned. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_identify_nsid_ctrl_list (int fd, __u32 nsid, __u16 cntid, struct nvme_ctrl_list * ctrlist) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Return controllers that are attached to this nsid + +``__u16 cntid`` + *undescribed* + +``struct nvme_ctrl_list * ctrlist`` + *undescribed* + +**Description** + +Up to 2047 controller identifiers is returned containing a controller +identifier greater than or equal to the controller identifier specified in +**cntid**. + +See :c:type:`struct nvme_ctrl_list ` for a definition of the structure returned. + +**Return** + +The nvme command status if a response was received or -1 + + +.. c:function:: int nvme_identify_ns_descs (int fd, __u32 nsid, struct nvme_ns_id_desc * descs) + + Retrieves namespace descriptor list + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + The namespace id to retrieve destriptors + +``struct nvme_ns_id_desc * descs`` + User space destination address to transfer the data + +**Description** + +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'. + +See :c:type:`struct nvme_ns_id_desc ` for the definition of the returned structure. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_identify_nvmset_list (int fd, __u16 nvmsetid, struct nvme_id_nvmset_list * nvmset) + + Retrieves NVM Set List + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u16 nvmsetid`` + *undescribed* + +``struct nvme_id_nvmset_list * nvmset`` + User space destination address to transfer the data + +**Description** + +Retrieves an NVM Set List, struct nvme_id_nvmset. The data structure is an +ordered list by NVM Set Identifier, starting with the first NVM Set +Identifier supported by the NVM subsystem that is equal to or greater than +the NVM Set Identifier. + +See :c:type:`struct nvme_id_nvmset_list ` for the defintion of the returned structure. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_identify_primary_ctrl (int fd, __u16 cntid, struct nvme_primary_ctrl_cap * cap) + + Retrieve NVMe Primary Controller identification :c:type:`fd`: + +**Parameters** + +``int fd`` + *undescribed* + +``__u16 cntid`` + *undescribed* + +``struct nvme_primary_ctrl_cap * cap`` + +**Description** + +See :c:type:`struct nvme_primary_ctrl_cap ` for the defintion of the returned structure, **cap**. + +**Return** + +The nvme command status if a response was received or -1 + with errno set otherwise. + + +.. c:function:: int nvme_identify_secondary_ctrl_list (int fd, __u16 cntid, struct nvme_secondary_ctrl_list * list) + + Retrieves secondary controller list + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u16 cntid`` + Return controllers starting at this identifier + +``struct nvme_secondary_ctrl_list * list`` + *undescribed* + +**Description** + +A Secondary Controller List is returned to the host for up to 127 secondary +controllers associated with the primary controller processing this command. +The list contains entries for controller identifiers greater than or equal +to the value specified in the Controller Identifier (cntid). + +See :c:type:`struct nvme_secondary_ctrls_list ` for a defintion of the returned +structure. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_identify_ns_granularity (int fd, struct nvme_id_ns_granularity_list * list) + + Retrieves namespace granularity identification + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``struct nvme_id_ns_granularity_list * list`` + *undescribed* + +**Description** + +If the controller supports reporting of Namespace Granularity, then a +Namespace Granularity List is returned to the host for up to sixteen +namespace granularity descriptors + +See :c:type:`struct nvme_id_ns_granularity_list ` for the definition of the returned +structure. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_identify_uuid (int fd, struct nvme_id_uuid_list * list) + + Retrieves device's UUIDs + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``struct nvme_id_uuid_list * list`` + *undescribed* + +**Description** + +Each UUID List entry is either 0h, the NVMe Invalid UUID, or a valid UUID. +Valid UUIDs are those which are non-zero and are not the NVMe Invalid UUID. + +See :c:type:`struct nvme_id_uuid_list ` for the definition of the returned structure. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_log (int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, __u8 lsp, __u16 lsi, bool rae, __u8 uuidx, __u32 len, void * log) + + NVMe Admin Get Log command + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_cmd_get_log_lid lid`` + Log page identifier, see :c:type:`enum nvme_cmd_get_log_lid ` for known values + +``__u32 nsid`` + Namespace identifier, if applicable + +``__u64 lpo`` + Log page offset for partial log transfers + +``__u8 lsp`` + Log specific field + +``__u16 lsi`` + Endurance group information + +``bool rae`` + Retain asynchronous events + +``__u8 uuidx`` + UUID selection, if supported + +``__u32 len`` + Length of provided user buffer to hold the log data in bytes + +``void * log`` + User space destination address to transfer the data + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_log_error (int fd, unsigned nr_entries, bool rae, struct nvme_error_log_page * log) + + Retrieve nvme error log + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``unsigned nr_entries`` + *undescribed* + +``bool rae`` + Retain asynchronous events + +``struct nvme_error_log_page * log`` + *undescribed* + +**Description** + +This log page is used to describe extended error information for a command +that completed with error, or may report an error that is not specific to a +particular command. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_log_smart (int fd, __u32 nsid, bool rae, struct nvme_smart_log * log) + + Retrieve nvme smart log + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Optional namespace identifier + +``bool rae`` + Retain asynchronous events + +``struct nvme_smart_log * log`` + *undescribed* + +**Description** + +This log page is used to provide SMART and general health information. The +information provided is over the life of the controller and is retained +across power cycles. To request the controller log page, the namespace +identifier specified is FFFFFFFFh. The controller may also support +requesting the log page on a per namespace basis, as indicated by bit 0 of +the LPA field in the Identify Controller data structure. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_log_fw_slot (int fd, bool rae, struct nvme_firmware_slot * log) + + Retrieves the controller firmware log + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``bool rae`` + Retain asynchronous events + +``struct nvme_firmware_slot * log`` + *undescribed* + +**Description** + +This log page is used to describe the firmware revision stored in each +firmware slot supported. The firmware revision is indicated as an ASCII +string. The log page also indicates the active slot number. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_log_changed_ns_list (int fd, bool rae, struct nvme_ns_list * log) + + Retrieve namespace changed list + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``bool rae`` + Retain asynchronous events + +``struct nvme_ns_list * log`` + *undescribed* + +**Description** + +This log page is used to describe namespaces attached to this controller +that have changed since the last time the namespace was identified, been +added, or deleted. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_log_cmd_effects (int fd, struct nvme_cmd_effects_log * log) + + Retrieve nvme command effects log + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``struct nvme_cmd_effects_log * log`` + *undescribed* + +**Description** + +This log page is used to describe the commands that the controller supports +and the effects of those commands on the state of the NVM subsystem. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_log_device_self_test (int fd, struct nvme_self_test_log * log) + + Retrieve the device self test log + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``struct nvme_self_test_log * log`` + Userspace address of the log payload + +**Description** + +The log page is used to indicate the status of an in progress self test and +the percent complete of that operation, and the results of the previous 20 +self-test operations. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_log_create_telemetry_host (int fd, struct nvme_telemetry_log * log) + + +**Parameters** + +``int fd`` + *undescribed* + +``struct nvme_telemetry_log * log`` + *undescribed* + + +.. c:function:: int nvme_get_log_telemetry_host (int fd, __u64 offset, __u32 len, void * log) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u64 offset`` + Offset into the telemetry data + +``__u32 len`` + Length of provided user buffer to hold the log data in bytes + +``void * log`` + User address for log page data + +**Description** + +Retreives 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 or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_log_telemetry_ctrl (int fd, bool rae, __u64 offset, __u32 len, void * log) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``bool rae`` + Retain asynchronous events + +``__u64 offset`` + Offset into the telemetry data + +``__u32 len`` + Length of provided user buffer to hold the log data in bytes + +``void * log`` + User address for log page data + + +.. c:function:: int nvme_get_log_endurance_group (int fd, __u16 endgid, struct nvme_endurance_group_log * log) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u16 endgid`` + Starting group identifier to return in the list + +``struct nvme_endurance_group_log * log`` + User address to store the endurance log + +**Description** + +This log page indicates if an Endurance Group Event has occurred for a +particular Endurance Group. If an Endurance Group Event has occurred, the +details of the particular event are included in the Endurance Group +Information log page for that Endurance Group. An asynchronous event is +generated when an entry for an Endurance Group is newly added to this log +page. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_log_predictable_lat_nvmset (int fd, __u16 nvmsetid, struct nvme_nvmset_predictable_lat_log * log) + + +**Parameters** + +``int fd`` + *undescribed* + +``__u16 nvmsetid`` + +``struct nvme_nvmset_predictable_lat_log * log`` + *undescribed* + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_log_predictable_lat_event (int fd, bool rae, __u32 offset, __u32 len, void * log) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``bool rae`` + Retain asynchronous events + +``__u32 offset`` + *undescribed* + +``__u32 len`` + *undescribed* + +``void * log`` + *undescribed* + + +.. c:function:: int nvme_get_log_ana (int fd, enum nvme_log_ana_lsp lsp, bool rae, __u64 offset, __u32 len, void * log) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_log_ana_lsp lsp`` + Log specific, see :c:type:`enum nvme_get_log_ana_lsp ` + +``bool rae`` + Retain asynchronous events + +``__u64 offset`` + *undescribed* + +``__u32 len`` + The allocated length of the log page + +``void * log`` + User address to store the ana log + +**Description** + +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 :c:type:`struct nvme_ana_rsp_hdr ` for the defintion of the returned structure. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_log_ana_groups (int fd, bool rae, __u32 len, struct nvme_ana_group_desc * log) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``bool rae`` + Retain asynchronous events + +``__u32 len`` + *undescribed* + +``struct nvme_ana_group_desc * log`` + *undescribed* + +**Description** + +See :c:type:`struct nvme_ana_group_desc ` for the defintion of the returned structure. + + +.. c:function:: int nvme_get_log_lba_status (int fd, bool rae, __u64 offset, __u32 len, void * log) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``bool rae`` + Retain asynchronous events + +``__u64 offset`` + *undescribed* + +``__u32 len`` + *undescribed* + +``void * log`` + *undescribed* + + +.. c:function:: int nvme_get_log_endurance_grp_evt (int fd, bool rae, __u32 offset, __u32 len, void * log) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``bool rae`` + Retain asynchronous events + +``__u32 offset`` + *undescribed* + +``__u32 len`` + *undescribed* + +``void * log`` + *undescribed* + + +.. c:function:: int nvme_get_log_discovery (int fd, bool rae, __u32 offset, __u32 len, void * log) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``bool rae`` + Retain asynchronous events + +``__u32 offset`` + Offset of this log to retrieve + +``__u32 len`` + The allocated size for this portion of the log + +``void * log`` + User address to store the discovery log + +**Description** + +Supported only by fabrics discovery controllers, returning discovery +records. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_log_reservation (int fd, bool rae, struct nvme_resv_notification_log * log) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``bool rae`` + Retain asynchronous events + +``struct nvme_resv_notification_log * log`` + *undescribed* + + +.. c:function:: int nvme_get_log_sanitize (int fd, bool rae, struct nvme_sanitize_log_page * log) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``bool rae`` + Retain asynchronous events + +``struct nvme_sanitize_log_page * log`` + User address to store the sanitize log + +**Description** + +The Sanitize Status log page is used to report sanitize operation time +estimates and information about the most recent sanitize operation. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_set_features (int fd, __u8 fid, __u32 nsid, __u32 cdw11, __u32 cdw12, bool save, __u8 uuidx, __u32 cdw15, __u32 data_len, void * data, __u32 * result) + + Set a feature attribute + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u8 fid`` + Feature identifier + +``__u32 nsid`` + Namespace ID, if applicable + +``__u32 cdw11`` + Value to set the feature to + +``__u32 cdw12`` + Feature specific command dword12 field + +``bool save`` + Save value across power states + +``__u8 uuidx`` + UUID Index for differentiating vendor specific encoding + +``__u32 cdw15`` + *undescribed* + +``__u32 data_len`` + Length of feature data, if applicable, in bytes + +``void * data`` + User address of feature data, if applicable + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_set_features_arbitration (int fd, __u8 ab, __u8 lpw, __u8 mpw, __u8 hpw, bool save, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u8 ab`` + *undescribed* + +``__u8 lpw`` + *undescribed* + +``__u8 mpw`` + *undescribed* + +``__u8 hpw`` + *undescribed* + +``bool save`` + Save value across power states + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_set_features_power_mgmt (int fd, __u8 ps, __u8 wh, bool save, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u8 ps`` + *undescribed* + +``__u8 wh`` + *undescribed* + +``bool save`` + Save value across power states + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_set_features_lba_range (int fd, __u32 nsid, __u32 nr_ranges, bool save, struct nvme_lba_range_type * data, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + *undescribed* + +``__u32 nr_ranges`` + *undescribed* + +``bool save`` + Save value across power states + +``struct nvme_lba_range_type * data`` + *undescribed* + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + + + +.. c:type:: enum nvme_feat_tmpthresh_thsel + + +**Constants** + +``NVME_FEATURE_TEMPTHRESH_THSEL_OVER`` + *undescribed* + +``NVME_FEATURETEMPTHRESH__THSEL_UNDER`` + *undescribed* + + +.. c:function:: int nvme_set_features_temp_thresh (int fd, __u16 tmpth, __u8 tmpsel, enum nvme_feat_tmpthresh_thsel thsel, bool save, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u16 tmpth`` + *undescribed* + +``__u8 tmpsel`` + *undescribed* + +``enum nvme_feat_tmpthresh_thsel thsel`` + *undescribed* + +``bool save`` + Save value across power states + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_set_features_err_recovery (int fd, __u32 nsid, __u16 tler, bool dulbe, bool save, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + *undescribed* + +``__u16 tler`` + *undescribed* + +``bool dulbe`` + *undescribed* + +``bool save`` + Save value across power states + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_set_features_volatile_wc (int fd, bool wce, bool save, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``bool wce`` + *undescribed* + +``bool save`` + Save value across power states + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_set_features_irq_coalesce (int fd, __u8 thr, __u8 time, bool save, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u8 thr`` + *undescribed* + +``__u8 time`` + *undescribed* + +``bool save`` + Save value across power states + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_set_features_irq_config (int fd, __u16 iv, bool cd, bool save, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u16 iv`` + *undescribed* + +``bool cd`` + *undescribed* + +``bool save`` + Save value across power states + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_set_features_write_atomic (int fd, bool dn, bool save, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``bool dn`` + *undescribed* + +``bool save`` + Save value across power states + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + + + +.. c:type:: enum nvme_features_async_event_config_flags + + +**Constants** + +``NVME_FEATURE_AENCFG_SMART_CRIT_SPARE`` + *undescribed* + +``NVME_FEATURE_AENCFG_SMART_CRIT_TEMPERATURE`` + *undescribed* + +``NVME_FEATURE_AENCFG_SMART_CRIT_DEGRADED`` + *undescribed* + +``NVME_FEATURE_AENCFG_SMART_CRIT_READ_ONLY`` + *undescribed* + +``NVME_FEATURE_AENCFG_SMART_CRIT_VOLATILE_BACKUP`` + *undescribed* + +``NVME_FEATURE_AENCFG_SMART_CRIT_READ_ONLY_PMR`` + *undescribed* + +``NVME_FEATURE_AENCFG_NOTICE_NAMESPACE_ATTRIBUTES`` + *undescribed* + +``NVME_FEATURE_AENCFG_NOTICE_FIRMWARE_ACTIVATION`` + *undescribed* + +``NVME_FEATURE_AENCFG_NOTICE_TELEMETRY_LOG`` + *undescribed* + +``NVME_FEATURE_AENCFG_NOTICE_ANA_CHANGE`` + *undescribed* + +``NVME_FEATURE_AENCFG_NOTICE_PL_EVENT`` + *undescribed* + +``NVME_FEATURE_AENCFG_NOTICE_LBA_STATUS`` + *undescribed* + +``NVME_FEATURE_AENCFG_NOTICE_EG_EVENT`` + *undescribed* + +``NVME_FEATURE_AENCFG_NOTICE_DISCOVERY_CHANGE`` + *undescribed* + + +.. c:function:: int nvme_set_features_async_event (int fd, __u32 events, bool save, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 events`` + *undescribed* + +``bool save`` + Save value across power states + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_set_features_auto_pst (int fd, bool apste, bool save, struct nvme_feat_auto_pst * apst, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``bool apste`` + *undescribed* + +``bool save`` + Save value across power states + +``struct nvme_feat_auto_pst * apst`` + *undescribed* + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_set_features_timestamp (int fd, bool save, __u64 timestamp) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``bool save`` + Save value across power states + +``__u64 timestamp`` + The current timestamp value to assign to this this feature + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_set_features_hctm (int fd, __u16 tmt2, __u16 tmt1, bool save, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u16 tmt2`` + *undescribed* + +``__u16 tmt1`` + *undescribed* + +``bool save`` + Save value across power states + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_set_features_nopsc (int fd, bool noppme, bool save, __u32 * result) + + +**Parameters** + +``int fd`` + *undescribed* + +``bool noppme`` + *undescribed* + +``bool save`` + *undescribed* + +``__u32 * result`` + *undescribed* + + +.. c:function:: int nvme_set_features_rrl (int fd, __u8 rrl, __u16 nvmsetid, bool save, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u8 rrl`` + *undescribed* + +``__u16 nvmsetid`` + *undescribed* + +``bool save`` + Save value across power states + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_set_features_plm_config (int fd, bool enable, __u16 nvmsetid, bool save, struct nvme_plm_config * data, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``bool enable`` + *undescribed* + +``__u16 nvmsetid`` + *undescribed* + +``bool save`` + Save value across power states + +``struct nvme_plm_config * data`` + *undescribed* + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + + + +.. c:type:: enum nvme_feat_plm_window_select + + +**Constants** + +``NVME_FEATURE_PLM_DTWIN`` + *undescribed* + +``NVME_FEATURE_PLM_NDWIN`` + *undescribed* + + +.. c:function:: int nvme_set_features_plm_window (int fd, enum nvme_feat_plm_window_select sel, __u16 nvmsetid, bool save, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_feat_plm_window_select sel`` + *undescribed* + +``__u16 nvmsetid`` + *undescribed* + +``bool save`` + Save value across power states + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_set_features_lba_sts_interval (int fd, __u16 lsiri, __u16 lsipi, bool save, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u16 lsiri`` + *undescribed* + +``__u16 lsipi`` + *undescribed* + +``bool save`` + Save value across power states + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_set_features_host_behavior (int fd, bool save, struct nvme_feat_host_behavior * data) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``bool save`` + Save value across power states + +``struct nvme_feat_host_behavior * data`` + *undescribed* + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_set_features_sanitize (int fd, bool nodrm, bool save, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``bool nodrm`` + *undescribed* + +``bool save`` + Save value across power states + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_set_features_endurance_evt_cfg (int fd, __u16 endgid, __u8 egwarn, bool save, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u16 endgid`` + *undescribed* + +``__u8 egwarn`` + Flags to enable warning, see :c:type:`enum nvme_eg_critical_warning_flags ` + +``bool save`` + Save value across power states + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_set_features_sw_progress (int fd, __u8 pbslc, bool save, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u8 pbslc`` + *undescribed* + +``bool save`` + Save value across power states + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_set_features_host_id (int fd, bool exhid, bool save, __u8 * hostid) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``bool exhid`` + *undescribed* + +``bool save`` + Save value across power states + +``__u8 * hostid`` + *undescribed* + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_set_features_resv_mask (int fd, __u32 mask, bool save, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 mask`` + *undescribed* + +``bool save`` + Save value across power states + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_set_features_resv_persist (int fd, bool ptpl, bool save, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``bool ptpl`` + *undescribed* + +``bool save`` + Save value across power states + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + + + +.. c:type:: enum nvme_feat_nswpcfg_state + + +**Constants** + +``NVME_FEAT_NS_NO_WRITE_PROTECT`` + *undescribed* + +``NVME_FEAT_NS_WRITE_PROTECT`` + *undescribed* + +``NVME_FEAT_NS_WRITE_PROTECT_PWR_CYCLE`` + *undescribed* + +``NVME_FEAT_NS_WRITE_PROTECT_PERMANENT`` + *undescribed* + + +.. c:function:: int nvme_set_features_write_protect (int fd, enum nvme_feat_nswpcfg_state state, bool save, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_feat_nswpcfg_state state`` + *undescribed* + +``bool save`` + Save value across power states + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_features (int fd, enum nvme_features_id fid, __u32 nsid, enum nvme_get_features_sel sel, __u32 cdw11, __u8 uuidx, __u32 data_len, void * data, __u32 * result) + + Retrieve a feature attribute + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_features_id fid`` + Feature identifier + +``__u32 nsid`` + Namespace ID, if applicable + +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` + +``__u32 cdw11`` + Feature specific command dword11 field + +``__u8 uuidx`` + UUID Index for differentiating vendor specific encoding + +``__u32 data_len`` + Length of feature data, if applicable, in bytes + +``void * data`` + User address of feature data, if applicable + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_features_arbitration (int fd, enum nvme_get_features_sel sel, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_features_power_mgmt (int fd, enum nvme_get_features_sel sel, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_features_lba_range (int fd, enum nvme_get_features_sel sel, struct nvme_lba_range_type * data, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` + +``struct nvme_lba_range_type * data`` + *undescribed* + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_features_temp_thresh (int fd, enum nvme_get_features_sel sel, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_features_err_recovery (int fd, enum nvme_get_features_sel sel, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_features_volatile_wc (int fd, enum nvme_get_features_sel sel, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_features_num_queues (int fd, enum nvme_get_features_sel sel, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_features_irq_coalesce (int fd, enum nvme_get_features_sel sel, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_features_irq_config (int fd, enum nvme_get_features_sel sel, __u16 iv, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` + +``__u16 iv`` + *undescribed* + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_features_write_atomic (int fd, enum nvme_get_features_sel sel, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_features_async_event (int fd, enum nvme_get_features_sel sel, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_features_auto_pst (int fd, enum nvme_get_features_sel sel, struct nvme_feat_auto_pst * apst, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` + +``struct nvme_feat_auto_pst * apst`` + *undescribed* + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_features_host_mem_buf (int fd, enum nvme_get_features_sel sel, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_features_timestamp (int fd, enum nvme_get_features_sel sel, struct nvme_timestamp * ts) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` + +``struct nvme_timestamp * ts`` + *undescribed* + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_features_kato (int fd, enum nvme_get_features_sel sel, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_features_hctm (int fd, enum nvme_get_features_sel sel, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_features_nopsc (int fd, enum nvme_get_features_sel sel, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_features_rrl (int fd, enum nvme_get_features_sel sel, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_features_plm_config (int fd, enum nvme_get_features_sel sel, __u16 nvmsetid, struct nvme_plm_config * data, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` + +``__u16 nvmsetid`` + *undescribed* + +``struct nvme_plm_config * data`` + *undescribed* + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_features_plm_window (int fd, enum nvme_get_features_sel sel, __u16 nvmsetid, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` + +``__u16 nvmsetid`` + *undescribed* + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_features_lba_sts_interval (int fd, enum nvme_get_features_sel sel, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_features_host_behavior (int fd, enum nvme_get_features_sel sel, struct nvme_feat_host_behavior * data, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` + +``struct nvme_feat_host_behavior * data`` + *undescribed* + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_features_sanitize (int fd, enum nvme_get_features_sel sel, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_features_endurance_event_cfg (int fd, enum nvme_get_features_sel sel, __u16 endgid, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` + +``__u16 endgid`` + *undescribed* + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_features_sw_progress (int fd, enum nvme_get_features_sel sel, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_features_host_id (int fd, enum nvme_get_features_sel sel, bool exhid, __u32 len, __u8 * hostid) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` + +``bool exhid`` + *undescribed* + +``__u32 len`` + *undescribed* + +``__u8 * hostid`` + *undescribed* + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_features_resv_mask (int fd, enum nvme_get_features_sel sel, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_features_resv_persist (int fd, enum nvme_get_features_sel sel, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_features_write_protect (int fd, __u32 nsid, enum nvme_get_features_sel sel, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace ID + +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_format_nvm (int fd, __u32 nsid, __u8 lbaf, enum nvme_cmd_format_mset mset, enum nvme_cmd_format_pi pi, enum nvme_cmd_format_pil pil, enum nvme_cmd_format_ses ses, __u32 timeout) + + Format nvme namespace(s) + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace ID to format + +``__u8 lbaf`` + Logical block address format + +``enum nvme_cmd_format_mset mset`` + Metadata settings (extended or separated), true if extended + +``enum nvme_cmd_format_pi pi`` + Protection information type + +``enum nvme_cmd_format_pil pil`` + Protection information location (beginning or end), true if end + +``enum nvme_cmd_format_ses ses`` + Secure erase settings + +``__u32 timeout`` + Set to override default timeout to this value in milliseconds; + useful for long running formats. 0 will use system default. + +**Description** + +The Format NVM command is used to low level format the NVM media. This +command is used by the host to change the LBA data size and/or metadata +size. A low level format may destroy all data and metadata associated with +all namespaces or only the specific namespace associated with the command + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_ns_mgmt (int fd, __u32 nsid, enum nvme_ns_mgmt_sel sel, struct nvme_id_ns * ns, __u32 * result, __u32 timeout) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + *undescribed* + +``enum nvme_ns_mgmt_sel sel`` + *undescribed* + +``struct nvme_id_ns * ns`` + *undescribed* + +``__u32 * result`` + *undescribed* + +``__u32 timeout`` + *undescribed* + + +.. c:function:: int nvme_ns_mgmt_create (int fd, struct nvme_id_ns * ns, __u32 * nsid, __u32 timeout) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``struct nvme_id_ns * ns`` + Namespace identifiaction that defines creation parameters + +``__u32 * nsid`` + On success, set to the namespace id that was created + +``__u32 timeout`` + Overide the default timeout to this value in milliseconds; + set to 0 to use the system default. + +**Description** + +On successful creation, the namespace exists in the subsystem, but is not +attached to any controller. Use the nvme_ns_attach_ctrls() to assign the +namespace to one or more controllers. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_ns_mgmt_delete (int fd, __u32 nsid) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace identifier to delete + +**Description** + +It is recommended that a namespace being deleted is not attached to any +controller. Use the nvme_ns_detach_ctrls() first if the namespace is still +attached. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_ns_attach (int fd, __u32 nsid, enum nvme_ns_attach_sel sel, struct nvme_ctrl_list * ctrlist) + + Attach or detach namespace to controller(s) + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace ID to execute attach selection + +``enum nvme_ns_attach_sel sel`` + Attachment selection, see :c:type:`enum nvme_ns_attach_sel ` + +``struct nvme_ctrl_list * ctrlist`` + Controller list to modify attachment state of nsid + + +.. c:function:: int nvme_ns_attach_ctrls (int fd, __u32 nsid, struct nvme_ctrl_list * ctrlist) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace ID to attach + +``struct nvme_ctrl_list * ctrlist`` + Controller list to modify attachment state of nsid + + +.. c:function:: int nvme_ns_dettach_ctrls (int fd, __u32 nsid, struct nvme_ctrl_list * ctrlist) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace ID to dettach + +``struct nvme_ctrl_list * ctrlist`` + Controller list to modify attachment state of nsid + + +.. c:function:: int nvme_fw_download (int fd, __u32 offset, __u32 data_len, void * data) + + Download part or all of a firmware image to the controller + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 offset`` + Offset in the firmware data + +``__u32 data_len`` + Length of data in this command in bytes + +``void * data`` + Userspace address of the firmware data + +**Description** + +The Firmware Image Download command is used to download all or a portion of +an image for a future update to the controller. The Firmware Image Download +command downloads a new image (in whole or in part) to the controller. + +The image may be constructed of multiple pieces that are individually +downloaded with separate Firmware Image Download commands. Each Firmware +Image Download command includes a Dword Offset and Number of Dwords that +specify a dword range. + +The new firmware image is not activated as part of the Firmware Image +Download command. Use the nvme_fw_commit() to activate a newly downloaded +image. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_fw_commit (int fd, __u8 slot, enum nvme_fw_commit_ca action, bool bpid) + + Commit firmware using the specified action + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u8 slot`` + Firmware slot to commit the downloaded image + +``enum nvme_fw_commit_ca action`` + Action to use for the firmware image, see :c:type:`enum nvme_fw_commit_ca ` + +``bool bpid`` + Set to true to select the boot partition id + +**Description** + +The Firmware Commit command is used to modify the firmware image or Boot +Partitions. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. The command status response may specify additional + reset actions required to complete the commit process. + + +.. c:function:: int nvme_security_send (int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, __u8 secp, __u32 tl, __u32 data_len, void * data, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace ID to issue security command on + +``__u8 nssf`` + NVMe Security Specific field + +``__u8 spsp0`` + Security Protocol Specific field + +``__u8 spsp1`` + Security Protocol Specific field + +``__u8 secp`` + Security Protocol + +``__u32 tl`` + Protocol specific transfer length + +``__u32 data_len`` + Data length of the payload in bytes + +``void * data`` + Security data payload to send + +``__u32 * result`` + The command completion result from CQE dword0 + +**Description** + +The Security Send command is used to transfer security protocol data to the +controller. The data structure transferred to the controller as part of this +command contains security protocol specific commands to be performed by the +controller. The data structure transferred may also contain data or +parameters associated with the security protocol commands. + +The security data is protocol specific and is not defined by the NVMe +specification. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_security_receive (int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, __u8 secp, __u32 al, __u32 data_len, void * data, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace ID to issue security command on + +``__u8 nssf`` + NVMe Security Specific field + +``__u8 spsp0`` + Security Protocol Specific field + +``__u8 spsp1`` + Security Protocol Specific field + +``__u8 secp`` + Security Protocol + +``__u32 al`` + Protocol specific allocation length + +``__u32 data_len`` + Data length of the payload in bytes + +``void * data`` + Security data payload to send + +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_lba_status (int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl, enum nvme_lba_status_atype atype, struct nvme_lba_status * lbas) + + Retrieve information on possibly unrecoverable LBAs + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace ID to retrieve LBA status + +``__u64 slba`` + Starting logical block address to check statuses + +``__u32 mndw`` + Maximum number of dwords to return + +``__u16 rl`` + Range length from slba to perform the action + +``enum nvme_lba_status_atype atype`` + Action type mechanism to determine LBA status desctriptors to + return, see :c:type:`enum nvme_lba_status_atype ` + +``struct nvme_lba_status * lbas`` + Data payload to return status descriptors + +**Description** + +The Get LBA Status command requests information about Potentially +Unrecoverable LBAs. Refer to the specification for action type descriptions. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_directive_send (int fd, __u32 nsid, __u16 dspec, __u8 doper, enum nvme_directive_dtype dtype, __u32 cdw12, __u32 data_len, void * data, __u32 * result) + + Send directive command + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace ID, if applicable + +``__u16 dspec`` + Directive specific field + +``__u8 doper`` + Directive operation + +``enum nvme_directive_dtype dtype`` + Directive type, see :c:type:`enum nvme_directive_dtype ` + +``__u32 cdw12`` + *undescribed* + +``__u32 data_len`` + Length of data payload in bytes + +``void * data`` + Usespace address of data payload + +``__u32 * result`` + If successful, the CQE dword0 value + +**Description** + +Directives is a mechanism to enable host and NVM subsystem or controller +information exchange. The Directive Send command is used to transfer data +related to a specific Directive Type from the host to the controller. + +See the NVMe specification for more information. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_directive_send_id_endir (int fd, __u32 nsid, bool endir, enum nvme_directive_dtype dtype, struct nvme_id_directives * id) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace ID + +``bool endir`` + *undescribed* + +``enum nvme_directive_dtype dtype`` + *undescribed* + +``struct nvme_id_directives * id`` + *undescribed* + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_directive_send_stream_release_identifier (int fd, __u32 nsid, __u16 stream_id) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace ID + +``__u16 stream_id`` + *undescribed* + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_directive_send_stream_release_resource (int fd, __u32 nsid) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace ID + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_directive_recv (int fd, __u32 nsid, __u16 dspec, __u8 doper, enum nvme_directive_dtype dtype, __u32 cdw12, __u32 data_len, void * data, __u32 * result) + + Receive directive specific data + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace ID, if applicable + +``__u16 dspec`` + Directive specific field + +``__u8 doper`` + Directive operation + +``enum nvme_directive_dtype dtype`` + Directive type, see :c:type:`enum nvme_directive_dtype ` + +``__u32 cdw12`` + *undescribed* + +``__u32 data_len`` + Length of data payload + +``void * data`` + Usespace address of data payload in bytes + +``__u32 * result`` + If successful, the CQE dword0 value + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_directive_recv_identify_parameters (int fd, __u32 nsid, struct nvme_id_directives * id) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace ID + +``struct nvme_id_directives * id`` + *undescribed* + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_directive_recv_stream_parameters (int fd, __u32 nsid, struct nvme_streams_directive_params * parms) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace ID + +``struct nvme_streams_directive_params * parms`` + *undescribed* + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_directive_recv_stream_status (int fd, __u32 nsid, unsigned nr_entries, struct nvme_streams_directive_status * id) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace ID + +``unsigned nr_entries`` + *undescribed* + +``struct nvme_streams_directive_status * id`` + *undescribed* + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_directive_recv_stream_allocate (int fd, __u32 nsid, __u16 nsr, __u32 * result) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace ID + +``__u16 nsr`` + *undescribed* + +``__u32 * result`` + *undescribed* + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + + + +.. c:type:: enum nvme_fctype + + +**Constants** + +``nvme_fabrics_type_property_set`` + *undescribed* + +``nvme_fabrics_type_connect`` + *undescribed* + +``nvme_fabrics_type_property_get`` + *undescribed* + +``nvme_fabrics_type_auth_send`` + *undescribed* + +``nvme_fabrics_type_auth_receive`` + *undescribed* + +``nvme_fabrics_type_disconnect`` + *undescribed* + + +.. c:function:: int nvme_set_property (int fd, int offset, __u64 value) + + Set controller property + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``int offset`` + Property offset from the base to set + +``__u64 value`` + The value to set the property + +**Description** + +This is an NVMe-over-Fabrics specific command, not applicable to PCIe. These +properties align to the PCI MMIO controller registers. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_property (int fd, int offset, __u64 * value) + + Get a controller property + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``int offset`` + Property offset from the base to retrieve + +``__u64 * value`` + Where the property's value will be stored on success + +**Description** + +This is an NVMe-over-Fabrics specific command, not applicable to PCIe. These +properties align to the PCI MMIO controller registers. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_sanitize_nvm (int fd, enum nvme_sanitize_sanact sanact, bool ause, __u8 owpass, bool oipbp, bool nodas, __u32 ovrpat) + + Start a sanitize operation + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_sanitize_sanact sanact`` + Sanitize action, see :c:type:`enum nvme_sanitize_sanact ` + +``bool ause`` + Set to allow unrestriced sanitize exit + +``__u8 owpass`` + Overwrite pass count + +``bool oipbp`` + Set to overwrite invert pattern between passes + +``bool nodas`` + Set to not deallocate blocks after sanitizing + +``__u32 ovrpat`` + Overwrite pattern + +**Description** + +A sanitize operation alters all user data in the NVM subsystem such that +recovery of any previous user data from any cache, the non-volatile media, +or any Controller Memory Buffer is not possible. + +The Sanitize command is used to start a sanitize operation or to recover +from a previously failed sanitize operation. The sanitize operation types +that may be supported are Block Erase, Crypto Erase, and Overwrite. All +sanitize operations are processed in the background, i.e., completion of the +sanitize command does not indicate completion of the sanitize operation. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_dev_self_test (int fd, __u32 nsid, enum nvme_dst_stc stc) + + Start or abort a self test + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace ID to test + +``enum nvme_dst_stc stc`` + Self test code, see :c:type:`enum nvme_dst_stc ` + +**Description** + +The Device Self-test command is used to start a device self-test operation +or abort a device self-test operation. A device self-test operation is a +diagnostic testing sequence that tests the integrity and functionality of +the controller and may include testing of the media associated with +namespaces. The controller may return a response to this command immediately +while running the self-test in the background. + +Set the 'nsid' field to 0 to not include namepsaces in the test. Set to +0xffffffff to test all namespaces. All other values tests a specific +namespace, if present. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_virtual_mgmt (int fd, enum nvme_virt_mgmt_act act, enum nvme_virt_mgmt_rt rt, __u16 cntlid, __u16 nr, __u32 * result) + + Virtualization resource management + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_virt_mgmt_act act`` + Virtual resource action, see :c:type:`enum nvme_virt_mgmt_act ` + +``enum nvme_virt_mgmt_rt rt`` + Resource type to modify, see :c:type:`enum nvme_virt_mgmt_rt ` + +``__u16 cntlid`` + Controller id for which resources are bing modified + +``__u16 nr`` + Number of resources being allocated or assigned + +``__u32 * result`` + If successful, the CQE dword0 + +**Description** + +The Virtualization Management command is supported by primary controllers +that support the Virtualization Enhancements capability. This command is +used for several functions: + + - Modifying Flexible Resource allocation for the primary controller + - Assigning Flexible Resources for secondary controllers + - Setting the Online and Offline state for secondary controllers + +**Return** + +The nvme command status if a response was received or -1 + with errno set otherwise. + + +**NVMe IO command** + + + + +.. c:type:: enum nvme_io_opcode + + +**Constants** + +``nvme_cmd_flush`` + *undescribed* + +``nvme_cmd_write`` + *undescribed* + +``nvme_cmd_read`` + *undescribed* + +``nvme_cmd_write_uncor`` + *undescribed* + +``nvme_cmd_compare`` + *undescribed* + +``nvme_cmd_write_zeroes`` + *undescribed* + +``nvme_cmd_dsm`` + *undescribed* + +``nvme_cmd_verify`` + *undescribed* + +``nvme_cmd_resv_register`` + *undescribed* + +``nvme_cmd_resv_report`` + *undescribed* + +``nvme_cmd_resv_acquire`` + *undescribed* + +``nvme_cmd_resv_release`` + *undescribed* + + +.. c:function:: int nvme_flush (int fd, __u32 nsid) + + Send an nvme flush command + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace identifier + +**Description** + +The Flush command is used to request that the contents of volatile write +cache be made non-volatile. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + + + +.. c:type:: enum nvme_io_control_flags + + +**Constants** + +``NVME_IO_DTYPE_STREAMS`` + *undescribed* + +``NVME_IO_DEAC`` + *undescribed* + +``NVME_IO_PRINFO_PRCHK_REF`` + *undescribed* + +``NVME_IO_PRINFO_PRCHK_APP`` + *undescribed* + +``NVME_IO_PRINFO_PRCHK_GUARD`` + *undescribed* + +``NVME_IO_PRINFO_PRACT`` + *undescribed* + +``NVME_IO_FUA`` + *undescribed* + +``NVME_IO_LR`` + *undescribed* + + + + +.. c:type:: enum nvme_io_dsm_flags + + +**Constants** + +``NVME_IO_DSM_FREQ_UNSPEC`` + *undescribed* + +``NVME_IO_DSM_FREQ_TYPICAL`` + *undescribed* + +``NVME_IO_DSM_FREQ_RARE`` + *undescribed* + +``NVME_IO_DSM_FREQ_READS`` + *undescribed* + +``NVME_IO_DSM_FREQ_WRITES`` + *undescribed* + +``NVME_IO_DSM_FREQ_RW`` + *undescribed* + +``NVME_IO_DSM_FREQ_ONCE`` + *undescribed* + +``NVME_IO_DSM_FREQ_PREFETCH`` + *undescribed* + +``NVME_IO_DSM_FREQ_TEMP`` + *undescribed* + +``NVME_IO_DSM_LATENCY_NONE`` + *undescribed* + +``NVME_IO_DSM_LATENCY_IDLE`` + *undescribed* + +``NVME_IO_DSM_LATENCY_NORM`` + *undescribed* + +``NVME_IO_DSM_LATENCY_LOW`` + *undescribed* + +``NVME_IO_DSM_SEQ_REQ`` + *undescribed* + +``NVME_IO_DSM_COMPRESSED`` + *undescribed* + + +.. c:function:: int nvme_read (int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u8 dsm, __u32 reftag, __u16 apptag, __u16 appmask, __u32 data_len, void * data, __u32 metadata_len, void * metadata) + + Submit an nvme user read command + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace ID + +``__u64 slba`` + Starting logical block + +``__u16 nlb`` + *undescribed* + +``__u16 control`` + Command control flags, see :c:type:`enum nvme_io_control_flags `. + +``__u8 dsm`` + Data set management attributes, see :c:type:`enum nvme_io_dsm_flags ` + +``__u32 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. + +``__u16 apptag`` + This field specifies the Application Tag Mask expected value. + Used only if the namespace is formatted to use end-to-end + protection information. + +``__u16 appmask`` + This field specifies the Application Tag expected value. Used + only if the namespace is formatted to use end-to-end protection + information. + +``__u32 data_len`` + Length of user buffer, **data**, in bytes + +``void * data`` + Pointer to user address of the data buffer + metadata_len:Length of user buffer, **metadata**, in bytes + +``__u32 metadata_len`` + *undescribed* + +``void * metadata`` + Pointer to user address of the metadata buffer + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_write (int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u8 dsm, __u16 dspec, __u32 reftag, __u16 apptag, __u16 appmask, __u32 data_len, void * data, __u32 metadata_len, void * metadata) + + Submit an nvme user write command + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace ID + +``__u64 slba`` + Starting logical block + +``__u16 nlb`` + *undescribed* + +``__u16 control`` + Command control flags, see :c:type:`enum nvme_io_control_flags `. + +``__u8 dsm`` + Data set management attributes, see :c:type:`enum nvme_io_dsm_flags ` + +``__u16 dspec`` + Directive specific command, eg: stream identifier + +``__u32 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. + +``__u16 apptag`` + This field specifies the Application Tag Mask expected value. + Used only if the namespace is formatted to use end-to-end + protection information. + +``__u16 appmask`` + This field specifies the Application Tag expected value. Used + only if the namespace is formatted to use end-to-end protection + information. + +``__u32 data_len`` + Length of user buffer, **data**, in bytes + +``void * data`` + Pointer to user address of the data buffer + metadata_len:Length of user buffer, **metadata**, in bytes + +``__u32 metadata_len`` + *undescribed* + +``void * metadata`` + Pointer to user address of the metadata buffer + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_compare (int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 reftag, __u16 apptag, __u16 appmask, __u32 data_len, void * data, __u32 metadata_len, void * metadata) + + Submit an nvme user compare command + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace ID + +``__u64 slba`` + Starting logical block + +``__u16 nlb`` + *undescribed* + +``__u16 control`` + Command control flags, see :c:type:`enum nvme_io_control_flags `. + +``__u32 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. + +``__u16 apptag`` + This field specifies the Application Tag Mask expected value. + Used only if the namespace is formatted to use end-to-end + protection information. + +``__u16 appmask`` + This field specifies the Application Tag expected value. Used + only if the namespace is formatted to use end-to-end protection + information. + +``__u32 data_len`` + Length of user buffer, **data**, in bytes + +``void * data`` + Pointer to user address of the data buffer + metadata_len:Length of user buffer, **metadata**, in bytes + +``__u32 metadata_len`` + *undescribed* + +``void * metadata`` + Pointer to user address of the metadata buffer + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_write_zeros (int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 reftag, __u16 apptag, __u16 appmask) + + Submit an nvme write zeroes command + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace identifier + +``__u64 slba`` + Starting logical block + +``__u16 nlb`` + Number of logical blocks to clear (0's based value) + +``__u16 control`` + Command control flags, see :c:type:`enum nvme_io_control_flags `. + +``__u32 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. + +``__u16 apptag`` + This field specifies the Application Tag Mask expected value. + Used only if the namespace is formatted to use end-to-end + protection information. + +``__u16 appmask`` + This field specifies the Application Tag expected value. Used + only if the namespace is formatted to use end-to-end protection + information. + +**Description** + +The Write Zeroes command is used to set a range of logical blocks to zero. +After successful completion of this command, the value returned by +subsequent reads of logical blocks in this range shall be all bytes cleared +to 0h until a write occurs to this LBA range. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_write_uncorrectable (int fd, __u32 nsid, __u64 slba, __u16 nlb) + + Submit an nvme write uncorrectable command + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace identifier + +``__u64 slba`` + Starting logical block + +``__u16 nlb`` + Number of logical blocks to invalidate (0's based value) + +**Description** + +The Write Uncorrectable command is used to mark a range of logical blocks as +invalid. When the specified logical block(s) are read after this operation, +a failure is returned with Unrecovered Read Error status. To clear the +invalid logical block status, a write operation on those logical blocks is +required. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_verify (int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 reftag, __u16 apptag, __u16 appmask) + + Send an nvme verify command + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace identifier + +``__u64 slba`` + Starting logical block + +``__u16 nlb`` + Number of logical blocks to verify (0's based value) + +``__u16 control`` + Command control flags, see :c:type:`enum nvme_io_control_flags `. + +``__u32 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. + +``__u16 apptag`` + This field specifies the Application Tag Mask expected value. + Used only if the namespace is formatted to use end-to-end + protection information. + +``__u16 appmask`` + This field specifies the Application Tag expected value. Used + only if the namespace is formatted to use end-to-end protection + information. + +**Description** + +The Verify command verifies integrity of stored information by reading data +and metadata, if applicable, for the LBAs indicated without transferring any +data or metadata to the host. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + + + +.. c:type:: enum nvme_dsm_attributes + + +**Constants** + +``NVME_DSMGMT_IDR`` + *undescribed* + +``NVME_DSMGMT_IDW`` + *undescribed* + +``NVME_DSMGMT_AD`` + *undescribed* + + +.. c:function:: int nvme_dsm (int fd, __u32 nsid, __u32 attrs, __u16 nr_ranges, struct nvme_dsm_range * dsm) + + Send an nvme data set management command + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace identifier + +``__u32 attrs`` + DSM attributes, see :c:type:`enum nvme_dsm_attributes ` + :c:type:`nr_ranges`: Number of block ranges in the data set management attributes + +``__u16 nr_ranges`` + *undescribed* + +``struct nvme_dsm_range * dsm`` + The data set management attributes + +**Description** + +The Dataset Management command is used by the host to indicate attributes +for ranges of logical blocks. This includes attributes like frequency that +data is read or written, access size, and other information that may be used +to optimize performance and reliability, and may be used to +deallocate/unmap/trim those logical blocks. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + + + +.. c:type:: enum nvme_reservation_rtype + + +**Constants** + +``NVME_RESERVATION_RTYPE_WE`` + *undescribed* + +``NVME_RESERVATION_RTYPE_EA`` + *undescribed* + +``NVME_RESERVATION_RTYPE_WERO`` + *undescribed* + +``NVME_RESERVATION_RTYPE_EARO`` + *undescribed* + +``NVME_RESERVATION_RTYPE_WEAR`` + *undescribed* + +``NVME_RESERVATION_RTYPE_EAAR`` + *undescribed* + + + + +.. c:type:: enum nvme_reservation_racqa + + +**Constants** + +``NVME_RESERVATION_RACQA_ACQUIRE`` + *undescribed* + +``NVME_RESERVATION_RACQA_PREEMPT`` + *undescribed* + +``NVME_RESERVATION_RACQA_PREEMPT_AND_ABORT`` + *undescribed* + + +.. c:function:: int nvme_resv_acquire (int fd, __u32 nsid, enum nvme_reservation_rtype rtype, enum nvme_reservation_racqa racqa, bool iekey, __u64 crkey, __u64 nrkey) + + Send an nvme reservation acquire + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace identifier + +``enum nvme_reservation_rtype rtype`` + The type of reservation to be create, see :c:type:`enum nvme_reservation_rtype ` + +``enum nvme_reservation_racqa racqa`` + The action that is performed by the command, see :c:type:`enum nvme_reservation_racqa ` + +``bool iekey`` + Set to ignore the existing key + +``__u64 crkey`` + The current reservation key associated with the host + +``__u64 nrkey`` + The reservation key to be unregistered from the namespace if + the action is preempt + +**Description** + +The Reservation Acquire command is used to acquire a reservation on a +namespace, preempt a reservation held on a namespace, and abort a +reservation held on a namespace. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + + + +.. c:type:: enum nvme_reservation_rrega + + +**Constants** + +``NVME_RESERVATION_RREGA_REGISTER_KEY`` + *undescribed* + +``NVME_RESERVATION_RREGA_UNREGISTER_KEY`` + *undescribed* + +``NVME_RESERVATION_RREGA_REPLACE_KEY`` + *undescribed* + + + + +.. c:type:: enum nvme_reservation_cptpl + + +**Constants** + +``NVME_RESERVATION_CPTPL_NO_CHANGE`` + *undescribed* + +``NVME_RESERVATION_CPTPL_CLEAR`` + *undescribed* + +``NVME_RESERVATION_CPTPL_PERSIST`` + *undescribed* + + +.. c:function:: int nvme_resv_register (int fd, __u32 nsid, enum nvme_reservation_rrega rrega, enum nvme_reservation_cptpl cptpl, bool iekey, __u64 crkey, __u64 nrkey) + + Send an nvme reservation register + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace identifier + +``enum nvme_reservation_rrega rrega`` + The registration action, see :c:type:`enum nvme_reservation_rrega ` + +``enum nvme_reservation_cptpl cptpl`` + Change persist through power loss, see :c:type:`enum nvme_reservation_cptpl ` + +``bool iekey`` + Set to ignore the existing key + +``__u64 crkey`` + The current reservation key associated with the host + +``__u64 nrkey`` + The new reservation key to be register if action is register or + replace + +**Description** + +The Reservation Register command is used to register, unregister, or replace +a reservation key. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + + + +.. c:type:: enum nvme_reservation_rrela + + +**Constants** + +``NVME_RESERVATION_RRELA_RELEASE`` + *undescribed* + +``NVME_RESERVATION_RRELA_CLEAR`` + *undescribed* + + +.. c:function:: int nvme_resv_release (int fd, __u32 nsid, enum nvme_reservation_rtype rtype, enum nvme_reservation_rrela rrela, bool iekey, __u64 crkey) + + Send an nvme reservation release + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace identifier + +``enum nvme_reservation_rtype rtype`` + The type of reservation to be create, see :c:type:`enum nvme_reservation_rtype ` + +``enum nvme_reservation_rrela rrela`` + Reservation releast action, see :c:type:`enum nvme_reservation_rrela ` + +``bool iekey`` + Set to ignore the existing key + +``__u64 crkey`` + The current reservation key to release + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_resv_report (int fd, __u32 nsid, bool eds, __u32 len, struct nvme_reservation_status * report) + + Send an nvme reservation report + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace identifier + +``bool eds`` + Request extended Data Structure + +``__u32 len`` + Number of bytes to request transfered with this command + +``struct nvme_reservation_status * report`` + The user space destination address to store the reservation report + +**Description** + +Returns a Reservation Status data structure to memory that describes the +registration and reservation status of a namespace. See the defintion for +the returned structure, :c:type:`struct nvme_reservation_status `, for more details. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + + + +.. c:type:: struct nvme_fabrics_config + + +**Definition** + +:: + + struct nvme_fabrics_config { + const char *transport; + const char *traddr; + const char *trsvcid; + const char *nqn; + const char *hostnqn; + const char *host_traddr; + const char *hostid; + int queue_size; + int nr_io_queues; + int reconnect_delay; + int ctrl_loss_tmo; + int keep_alive_tmo; + int nr_write_queues; + int nr_poll_queues; + int tos; + bool duplicate_connect; + bool disable_sqflow; + bool hdr_digest; + bool data_digest; + uint8_t rsvd[0x200]; + }; + +**Members** + + + +.. c:function:: int nvmf_add_ctrl_opts (struct nvme_fabrics_config * cfg) + + +**Parameters** + +``struct nvme_fabrics_config * cfg`` + *undescribed* + + +.. c:function:: nvme_ctrl_t nvmf_add_ctrl (struct nvme_fabrics_config * cfg) + + +**Parameters** + +``struct nvme_fabrics_config * cfg`` + *undescribed* + + +.. c:function:: int nvmf_get_discovery_log (nvme_ctrl_t c, struct nvmf_discovery_log ** logp, int max_retries) + + +**Parameters** + +``nvme_ctrl_t c`` + *undescribed* + +``struct nvmf_discovery_log ** logp`` + *undescribed* + +``int max_retries`` + *undescribed* + + +.. c:function:: char * nvmf_hostnqn_generate () + + +**Parameters** + + +.. c:function:: char * nvmf_hostnqn_from_file () + + +**Parameters** + + +.. c:function:: char * nvmf_hostid_from_file () + + +**Parameters** + + +.. c:function:: const char * nvmf_trtype_str (__u8 trtype) + + +**Parameters** + +``__u8 trtype`` + *undescribed* + + +.. c:function:: const char * nvmf_adrfam_str (__u8 adrfam) + + +**Parameters** + +``__u8 adrfam`` + *undescribed* + + +.. c:function:: const char * nvmf_subtype_str (__u8 subtype) + + +**Parameters** + +``__u8 subtype`` + *undescribed* + + +.. c:function:: const char * nvmf_treq_str (__u8 treq) + + +**Parameters** + +``__u8 treq`` + *undescribed* + + +.. c:function:: const char * nvmf_sectype_str (__u8 sectype) + + +**Parameters** + +``__u8 sectype`` + *undescribed* + + +.. c:function:: const char * nvmf_prtype_str (__u8 prtype) + + +**Parameters** + +``__u8 prtype`` + *undescribed* + + +.. c:function:: const char * nvmf_qptype_str (__u8 qptype) + + +**Parameters** + +``__u8 qptype`` + *undescribed* + + +.. c:function:: const char * nvmf_cms_str (__u8 cm) + + +**Parameters** + +``__u8 cm`` + *undescribed* + + +.. c:function:: nvme_ctrl_t nvmf_connect_disc_entry (struct nvmf_disc_log_entry * e, const struct nvme_fabrics_config * defcfg, bool * discover) + + +**Parameters** + +``struct nvmf_disc_log_entry * e`` + *undescribed* + +``const struct nvme_fabrics_config * defcfg`` + *undescribed* + +``bool * discover`` + *undescribed* + + +.. c:function:: int nvme_namespace_filter (const struct dirent * d) + + +**Parameters** + +``const struct dirent * d`` + *undescribed* + + +.. c:function:: int nvme_paths_filter (const struct dirent * d) + + +**Parameters** + +``const struct dirent * d`` + *undescribed* + + +.. c:function:: int nvme_ctrls_filter (const struct dirent * d) + + +**Parameters** + +``const struct dirent * d`` + *undescribed* + + +.. c:function:: int nvme_subsys_filter (const struct dirent * d) + + +**Parameters** + +``const struct dirent * d`` + *undescribed* + + +.. c:function:: int nvme_scan_subsystems (struct dirent *** subsys) + + +**Parameters** + +``struct dirent *** subsys`` + *undescribed* + + +.. c:function:: int nvme_scan_subsystem_ctrls (nvme_subsystem_t s, struct dirent *** ctrls) + + +**Parameters** + +``nvme_subsystem_t s`` + *undescribed* + +``struct dirent *** ctrls`` + *undescribed* + + +.. c:function:: int nvme_scan_subsystem_namespaces (nvme_subsystem_t s, struct dirent *** namespaces) + + +**Parameters** + +``nvme_subsystem_t s`` + *undescribed* + +``struct dirent *** namespaces`` + *undescribed* + + +.. c:function:: int nvme_scan_ctrl_namespace_paths (nvme_ctrl_t c, struct dirent *** namespaces) + + +**Parameters** + +``nvme_ctrl_t c`` + *undescribed* + +``struct dirent *** namespaces`` + *undescribed* + + +.. c:function:: int nvme_scan_ctrl_namespaces (nvme_ctrl_t c, struct dirent *** namespaces) + + +**Parameters** + +``nvme_ctrl_t c`` + *undescribed* + +``struct dirent *** namespaces`` + *undescribed* + + + + +.. c:type:: struct nvme_passthru_cmd + + +**Definition** + +:: + + struct nvme_passthru_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 result; + }; + +**Members** + +``opcode`` + Operation code, see :c:type:`enum nvme_io_opcodes ` and :c:type:`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 + +``result`` + Set on completion to the command's CQE DWORD 0 controller response + + + + + +.. c:type:: struct nvme_passthru_cmd64 + + +**Definition** + +:: + + 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; + }; + +**Members** + +``opcode`` + Operation code, see :c:type:`enum nvme_io_opcodes ` and :c:type:`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 impicit struct pad + +``result`` + Set on completion to the command's CQE DWORD 0-1 controller response + + + +.. c:function:: int nvme_submit_admin_passthru64 (int fd, struct nvme_passthru_cmd64 * cmd, __u64 * result) + + Submit a 64-bit nvme passthrough admin command + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``struct nvme_passthru_cmd64 * cmd`` + The nvme admin command to send + +``__u64 * result`` + Optional field to return the result from the CQE DW0-1 + +**Description** + +Uses NVME_IOCTL_ADMIN64_CMD for the ioctl request. + +**Return** + +The nvme command status if a response was received or -1 + with errno set otherwise. + + +.. c:function:: int nvme_admin_passthru64 (int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, __u32 data_len, void * data, __u32 metadata_len, void * metadata, __u32 timeout_ms, __u64 * result) + + Submit an nvme passthrough command + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u8 opcode`` + The nvme io command to send + +``__u8 flags`` + NVMe command flags (not used) + +``__u16 rsvd`` + Reserevd for future use + +``__u32 nsid`` + Namespace identifier + +``__u32 cdw2`` + Command dword 2 + +``__u32 cdw3`` + Command dword 3 + +``__u32 cdw10`` + Command dword 10 + +``__u32 cdw11`` + Command dword 11 + +``__u32 cdw12`` + Command dword 12 + +``__u32 cdw13`` + Command dword 13 + +``__u32 cdw14`` + Command dword 14 + +``__u32 cdw15`` + Command dword 15 + +``__u32 data_len`` + Length of the data transfered in this command in bytes + +``void * data`` + Pointer to user address of the data buffer + +``__u32 metadata_len`` + Length of metadata transfered in this command + +``void * metadata`` + Pointer to user address of the metadata buffer + +``__u32 timeout_ms`` + How long the kernel waits for the command to complete + +``__u64 * result`` + Optional field to return the result from the CQE dword 0 + +**Description** + +Parameterized form of nvme_submit_admin_passthru64(). This sets up and +submits a :c:type:`struct nvme_passthru_cmd64 `. + +Known values for **opcode** are defined in :c:type:`enum nvme_admin_opcode `. + +**Return** + +The nvme command status if a response was received or -1 + with errno set otherwise. + + +.. c:function:: int nvme_submit_admin_passthru (int fd, struct nvme_passthru_cmd * cmd, __u32 * result) + + Submit an nvme passthrough admin command + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``struct nvme_passthru_cmd * cmd`` + The nvme admin command to send + +``__u32 * result`` + Optional field to return the result from the CQE DW0 + +**Description** + +Uses NVME_IOCTL_ADMIN_CMD for the ioctl request. + +**Return** + +The nvme command status if a response was received or -1 + with errno set otherwise. + + +.. c:function:: int nvme_admin_passthru (int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, __u32 data_len, void * data, __u32 metadata_len, void * metadata, __u32 timeout_ms, __u32 * result) + + Submit an nvme passthrough command + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u8 opcode`` + The nvme io command to send + +``__u8 flags`` + NVMe command flags (not used) + +``__u16 rsvd`` + Reserevd for future use + +``__u32 nsid`` + Namespace identifier + +``__u32 cdw2`` + Command dword 2 + +``__u32 cdw3`` + Command dword 3 + +``__u32 cdw10`` + Command dword 10 + +``__u32 cdw11`` + Command dword 11 + +``__u32 cdw12`` + Command dword 12 + +``__u32 cdw13`` + Command dword 13 + +``__u32 cdw14`` + Command dword 14 + +``__u32 cdw15`` + Command dword 15 + +``__u32 data_len`` + Length of the data transfered in this command in bytes + +``void * data`` + Pointer to user address of the data buffer + +``__u32 metadata_len`` + Length of metadata transfered in this command + +``void * metadata`` + Pointer to user address of the metadata buffer + +``__u32 timeout_ms`` + How long the kernel waits for the command to complete + +``__u32 * result`` + Optional field to return the result from the CQE dword 0 + +**Description** + +Parameterized form of nvme_submit_admin_passthru(). This sets up and +submits a :c:type:`struct nvme_passthru_cmd `. + +Known values for **opcode** are defined in :c:type:`enum nvme_admin_opcode `. + +**Return** + +The nvme command status if a response was received or -1 + with errno set otherwise. + + +.. c:function:: int nvme_submit_io_passthru64 (int fd, struct nvme_passthru_cmd64 * cmd, __u64 * result) + + Submit a 64-bit nvme passthrough command + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``struct nvme_passthru_cmd64 * cmd`` + The nvme io command to send + +``__u64 * result`` + Optional field to return the result from the CQE DW0-1 + +**Description** + +Uses NVME_IOCTL_IO64_CMD for the ioctl request. + +**Return** + +The nvme command status if a response was received or -1 + with errno set otherwise. + + +.. c:function:: int nvme_io_passthru64 (int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, __u32 data_len, void * data, __u32 metadata_len, void * metadata, __u32 timeout_ms, __u64 * result) + + Submit an nvme io passthrough command + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u8 opcode`` + The nvme io command to send + +``__u8 flags`` + NVMe command flags (not used) + +``__u16 rsvd`` + Reserevd for future use + +``__u32 nsid`` + Namespace identifier + +``__u32 cdw2`` + Command dword 2 + +``__u32 cdw3`` + Command dword 3 + +``__u32 cdw10`` + Command dword 10 + +``__u32 cdw11`` + Command dword 11 + +``__u32 cdw12`` + Command dword 12 + +``__u32 cdw13`` + Command dword 13 + +``__u32 cdw14`` + Command dword 14 + +``__u32 cdw15`` + Command dword 15 + +``__u32 data_len`` + Length of the data transfered in this command in bytes + +``void * data`` + Pointer to user address of the data buffer + +``__u32 metadata_len`` + Length of metadata transfered in this command + +``void * metadata`` + Pointer to user address of the metadata buffer + +``__u32 timeout_ms`` + How long the kernel waits for the command to complete + +``__u64 * result`` + Optional field to return the result from the CQE dword 0 + +**Description** + +Parameterized form of nvme_submit_io_passthru64(). This sets up and submits +a :c:type:`struct nvme_passthru_cmd64 `. + +Known values for **opcode** are defined in :c:type:`enum nvme_io_opcode `. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_submit_io_passthru (int fd, struct nvme_passthru_cmd * cmd, __u32 * result) + + Submit an nvme passthrough command + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``struct nvme_passthru_cmd * cmd`` + The nvme io command to send + +``__u32 * result`` + Optional field to return the result from the CQE DW0 + +**Description** + +Uses NVME_IOCTL_IO_CMD for the ioctl request. + +**Return** + +The nvme command status if a response was received or -1 + with errno set otherwise. + + +.. c:function:: int nvme_io_passthru (int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, __u32 data_len, void * data, __u32 metadata_len, void * metadata, __u32 timeout_ms, __u32 * result) + + Submit an nvme io passthrough command + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u8 opcode`` + The nvme io command to send + +``__u8 flags`` + NVMe command flags (not used) + +``__u16 rsvd`` + Reserevd for future use + +``__u32 nsid`` + Namespace identifier + +``__u32 cdw2`` + Command dword 2 + +``__u32 cdw3`` + Command dword 3 + +``__u32 cdw10`` + Command dword 10 + +``__u32 cdw11`` + Command dword 11 + +``__u32 cdw12`` + Command dword 12 + +``__u32 cdw13`` + Command dword 13 + +``__u32 cdw14`` + Command dword 14 + +``__u32 cdw15`` + Command dword 15 + +``__u32 data_len`` + Length of the data transfered in this command in bytes + +``void * data`` + Pointer to user address of the data buffer + +``__u32 metadata_len`` + Length of metadata transfered in this command + +``void * metadata`` + Pointer to user address of the metadata buffer + +``__u32 timeout_ms`` + How long the kernel waits for the command to complete + +``__u32 * result`` + Optional field to return the result from the CQE dword 0 + +**Description** + +Parameterized form of nvme_submit_io_passthru(). This sets up and submits +a :c:type:`struct nvme_passthru_cmd `. + +Known values for **opcode** are defined in :c:type:`enum nvme_io_opcode `. + +**Return** + +The nvme command status if a response was received or -1 + with errno set otherwise. + + +.. c:function:: int nvme_subsystem_reset (int fd) + + Initiate a subsystem reset + +**Parameters** + +``int fd`` + File descriptor of nvme device + +**Description** + +This should only be sent to controller handles, not to namespaces. + +**Return** + +Zero if a subsystem reset was initiated or -1 with errno set + otherwise. + + +.. c:function:: int nvme_ctrl_reset (int fd) + + Initiate a controller reset + +**Parameters** + +``int fd`` + File descriptor of nvme device + +**Description** + +This should only be sent to controller handles, not to namespaces. + +**Return** + +Zero if a reset was initiated or -1 with errno set otherwise. + + +.. c:function:: int nvme_ns_rescan (int fd) + + Initiate a controller rescan + +**Parameters** + +``int fd`` + File descriptor of nvme device + +**Description** + +This should only be sent to controller handles, not to namespaces. + +**Return** + +Zero if a rescan was initiated or -1 with errno set otherwise. + + +.. c:function:: int nvme_get_nsid (int fd) + + Retrieve the NSID from a namespace file descriptor + +**Parameters** + +``int fd`` + File descriptor of nvme namespace + +**Description** + +This should only be sent to namespace handles, not to controllers. + +**Return** + +The namespace identifier if a succecssful or -1 with errno set + otherwise. + + +.. c:function:: nvme_subsystem_t nvme_first_subsystem (nvme_root_t r) + + +**Parameters** + +``nvme_root_t r`` + *undescribed* + + +.. c:function:: nvme_subsystem_t nvme_next_subsystem (nvme_root_t r, nvme_subsystem_t s) + + +**Parameters** + +``nvme_root_t r`` + *undescribed* + +``nvme_subsystem_t s`` + *undescribed* + + +.. c:function:: nvme_ns_t nvme_ctrl_first_ns (nvme_ctrl_t c) + + +**Parameters** + +``nvme_ctrl_t c`` + *undescribed* + + +.. c:function:: nvme_ns_t nvme_ctrl_next_ns (nvme_ctrl_t c, nvme_ns_t n) + + +**Parameters** + +``nvme_ctrl_t c`` + *undescribed* + +``nvme_ns_t n`` + *undescribed* + + +.. c:function:: nvme_path_t nvme_ctrl_first_path (nvme_ctrl_t c) + + +**Parameters** + +``nvme_ctrl_t c`` + *undescribed* + + +.. c:function:: nvme_path_t nvme_ctrl_next_path (nvme_ctrl_t c, nvme_path_t p) + + +**Parameters** + +``nvme_ctrl_t c`` + *undescribed* + +``nvme_path_t p`` + *undescribed* + + +.. c:function:: nvme_ctrl_t nvme_subsystem_first_ctrl (nvme_subsystem_t s) + + +**Parameters** + +``nvme_subsystem_t s`` + *undescribed* + + +.. c:function:: nvme_ctrl_t nvme_subsystem_next_ctrl (nvme_subsystem_t s, nvme_ctrl_t c) + + +**Parameters** + +``nvme_subsystem_t s`` + *undescribed* + +``nvme_ctrl_t c`` + *undescribed* + + +.. c:function:: nvme_ns_t nvme_subsystem_first_ns (nvme_subsystem_t s) + + +**Parameters** + +``nvme_subsystem_t s`` + *undescribed* + + +.. c:function:: nvme_ns_t nvme_subsystem_next_ns (nvme_subsystem_t s, nvme_ns_t n) + + +**Parameters** + +``nvme_subsystem_t s`` + *undescribed* + +``nvme_ns_t n`` + *undescribed* + + +.. c:function:: nvme_for_each_subsystem_safe ( r, s, _s) + + +**Parameters** + +``r`` + *undescribed* + +``s`` + *undescribed* + +``_s`` + *undescribed* + + +.. c:function:: nvme_for_each_subsystem ( r, s) + + +**Parameters** + +``r`` + *undescribed* + +``s`` + *undescribed* + + +.. c:function:: nvme_subsystem_for_each_ctrl_safe ( s, c, _c) + + +**Parameters** + +``s`` + *undescribed* + +``c`` + *undescribed* + +``_c`` + *undescribed* + + +.. c:function:: nvme_subsystem_for_each_ctrl ( s, c) + + +**Parameters** + +``s`` + *undescribed* + +``c`` + *undescribed* + + +.. c:function:: nvme_ctrl_for_each_ns_safe ( c, n, _n) + + +**Parameters** + +``c`` + *undescribed* + +``n`` + *undescribed* + +``_n`` + *undescribed* + + +.. c:function:: nvme_ctrl_for_each_ns ( c, n) + + +**Parameters** + +``c`` + *undescribed* + +``n`` + *undescribed* + + +.. c:function:: nvme_ctrl_for_each_path_safe ( c, p, _p) + + +**Parameters** + +``c`` + *undescribed* + +``p`` + *undescribed* + +``_p`` + *undescribed* + + +.. c:function:: nvme_ctrl_for_each_path ( c, p) + + +**Parameters** + +``c`` + *undescribed* + +``p`` + *undescribed* + + +.. c:function:: nvme_subsystem_for_each_ns_safe ( s, n, _n) + + +**Parameters** + +``s`` + *undescribed* + +``n`` + *undescribed* + +``_n`` + *undescribed* + + +.. c:function:: nvme_subsystem_for_each_ns ( s, n) + + +**Parameters** + +``s`` + *undescribed* + +``n`` + *undescribed* + + +.. c:function:: int nvme_ns_get_fd (nvme_ns_t n) + + +**Parameters** + +``nvme_ns_t n`` + *undescribed* + + +.. c:function:: int nvme_ns_get_nsid (nvme_ns_t n) + + +**Parameters** + +``nvme_ns_t n`` + *undescribed* + + +.. c:function:: int nvme_ns_get_lba_size (nvme_ns_t n) + + +**Parameters** + +``nvme_ns_t n`` + *undescribed* + + +.. c:function:: uint64_t nvme_ns_get_lba_count (nvme_ns_t n) + + +**Parameters** + +``nvme_ns_t n`` + *undescribed* + + +.. c:function:: uint64_t nvme_ns_get_lba_util (nvme_ns_t n) + + +**Parameters** + +``nvme_ns_t n`` + *undescribed* + + +.. c:function:: const char * nvme_ns_get_sysfs_dir (nvme_ns_t n) + + +**Parameters** + +``nvme_ns_t n`` + *undescribed* + + +.. c:function:: const char * nvme_ns_get_name (nvme_ns_t n) + + +**Parameters** + +``nvme_ns_t n`` + *undescribed* + + +.. c:function:: nvme_subsystem_t nvme_ns_get_subsystem (nvme_ns_t n) + + +**Parameters** + +``nvme_ns_t n`` + *undescribed* + + +.. c:function:: nvme_ctrl_t nvme_ns_get_ctrl (nvme_ns_t n) + + +**Parameters** + +``nvme_ns_t n`` + *undescribed* + + +.. c:function:: int nvme_ns_read (nvme_ns_t n, void * buf, off_t offset, size_t count) + + +**Parameters** + +``nvme_ns_t n`` + *undescribed* + +``void * buf`` + *undescribed* + +``off_t offset`` + *undescribed* + +``size_t count`` + *undescribed* + + +.. c:function:: int nvme_ns_write (nvme_ns_t n, void * buf, off_t offset, size_t count) + + +**Parameters** + +``nvme_ns_t n`` + *undescribed* + +``void * buf`` + *undescribed* + +``off_t offset`` + *undescribed* + +``size_t count`` + *undescribed* + + +.. c:function:: int nvme_ns_verify (nvme_ns_t n, off_t offset, size_t count) + + +**Parameters** + +``nvme_ns_t n`` + *undescribed* + +``off_t offset`` + *undescribed* + +``size_t count`` + *undescribed* + + +.. c:function:: int nvme_ns_compare (nvme_ns_t n, void * buf, off_t offset, size_t count) + + +**Parameters** + +``nvme_ns_t n`` + *undescribed* + +``void * buf`` + *undescribed* + +``off_t offset`` + *undescribed* + +``size_t count`` + *undescribed* + + +.. c:function:: int nvme_ns_write_zeros (nvme_ns_t n, off_t offset, size_t count) + + +**Parameters** + +``nvme_ns_t n`` + *undescribed* + +``off_t offset`` + *undescribed* + +``size_t count`` + *undescribed* + + +.. c:function:: int nvme_ns_write_uncorrectable (nvme_ns_t n, off_t offset, size_t count) + + +**Parameters** + +``nvme_ns_t n`` + *undescribed* + +``off_t offset`` + *undescribed* + +``size_t count`` + *undescribed* + + +.. c:function:: int nvme_ns_flush (nvme_ns_t n) + + +**Parameters** + +``nvme_ns_t n`` + *undescribed* + + +.. c:function:: int nvme_ns_identify (nvme_ns_t n, struct nvme_id_ns * ns) + + +**Parameters** + +``nvme_ns_t n`` + *undescribed* + +``struct nvme_id_ns * ns`` + *undescribed* + + +.. c:function:: const char * nvme_path_get_name (nvme_path_t p) + + +**Parameters** + +``nvme_path_t p`` + *undescribed* + + +.. c:function:: const char * nvme_path_get_sysfs_dir (nvme_path_t p) + + +**Parameters** + +``nvme_path_t p`` + *undescribed* + + +.. c:function:: const char * nvme_path_get_ana_state (nvme_path_t p) + + +**Parameters** + +``nvme_path_t p`` + *undescribed* + + +.. c:function:: nvme_ctrl_t nvme_path_get_subsystem (nvme_path_t p) + + +**Parameters** + +``nvme_path_t p`` + *undescribed* + + +.. c:function:: nvme_ns_t nvme_path_get_ns (nvme_path_t p) + + +**Parameters** + +``nvme_path_t p`` + *undescribed* + + +.. c:function:: int nvme_ctrl_get_fd (nvme_ctrl_t c) + + +**Parameters** + +``nvme_ctrl_t c`` + *undescribed* + + +.. c:function:: const char * nvme_ctrl_get_name (nvme_ctrl_t c) + + +**Parameters** + +``nvme_ctrl_t c`` + *undescribed* + + +.. c:function:: const char * nvme_ctrl_get_sysfs_dir (nvme_ctrl_t c) + + +**Parameters** + +``nvme_ctrl_t c`` + *undescribed* + + +.. c:function:: const char * nvme_ctrl_get_address (nvme_ctrl_t c) + + +**Parameters** + +``nvme_ctrl_t c`` + *undescribed* + + +.. c:function:: const char * nvme_ctrl_get_firmware (nvme_ctrl_t c) + + +**Parameters** + +``nvme_ctrl_t c`` + *undescribed* + + +.. c:function:: const char * nvme_ctrl_get_model (nvme_ctrl_t c) + + +**Parameters** + +``nvme_ctrl_t c`` + *undescribed* + + +.. c:function:: const char * nvme_ctrl_get_state (nvme_ctrl_t c) + + +**Parameters** + +``nvme_ctrl_t c`` + *undescribed* + + +.. c:function:: const char * nvme_ctrl_get_numa_node (nvme_ctrl_t c) + + +**Parameters** + +``nvme_ctrl_t c`` + *undescribed* + + +.. c:function:: const char * nvme_ctrl_get_queue_count (nvme_ctrl_t c) + + +**Parameters** + +``nvme_ctrl_t c`` + *undescribed* + + +.. c:function:: const char * nvme_ctrl_get_serial (nvme_ctrl_t c) + + +**Parameters** + +``nvme_ctrl_t c`` + *undescribed* + + +.. c:function:: const char * nvme_ctrl_get_sqsize (nvme_ctrl_t c) + + +**Parameters** + +``nvme_ctrl_t c`` + *undescribed* + + +.. c:function:: const char * nvme_ctrl_get_transport (nvme_ctrl_t c) + + +**Parameters** + +``nvme_ctrl_t c`` + *undescribed* + + +.. c:function:: const char * nvme_ctrl_get_nqn (nvme_ctrl_t c) + + +**Parameters** + +``nvme_ctrl_t c`` + *undescribed* + + +.. c:function:: const char * nvme_ctrl_get_subsysnqn (nvme_ctrl_t c) + + +**Parameters** + +``nvme_ctrl_t c`` + *undescribed* + + +.. c:function:: nvme_subsystem_t nvme_ctrl_get_subsystem (nvme_ctrl_t c) + + +**Parameters** + +``nvme_ctrl_t c`` + *undescribed* + + +.. c:function:: int nvme_ctrl_identify (nvme_ctrl_t c, struct nvme_id_ctrl * id) + + +**Parameters** + +``nvme_ctrl_t c`` + *undescribed* + +``struct nvme_id_ctrl * id`` + *undescribed* + + +.. c:function:: int nvme_ctrl_disconnect (nvme_ctrl_t c) + + +**Parameters** + +``nvme_ctrl_t c`` + *undescribed* + + +.. c:function:: nvme_ctrl_t nvme_scan_ctrl (const char * name) + + +**Parameters** + +``const char * name`` + *undescribed* + + +.. c:function:: void nvme_free_ctrl (struct nvme_ctrl * c) + + +**Parameters** + +``struct nvme_ctrl * c`` + *undescribed* + + +.. c:function:: void nvme_unlink_ctrl (struct nvme_ctrl * c) + + +**Parameters** + +``struct nvme_ctrl * c`` + *undescribed* + + +.. c:function:: const char * nvme_subsystem_get_nqn (nvme_subsystem_t s) + + +**Parameters** + +``nvme_subsystem_t s`` + *undescribed* + + +.. c:function:: const char * nvme_subsystem_get_sysfs_dir (nvme_subsystem_t s) + + +**Parameters** + +``nvme_subsystem_t s`` + *undescribed* + + +.. c:function:: const char * nvme_subsystem_get_name (nvme_subsystem_t s) + + +**Parameters** + +``nvme_subsystem_t s`` + *undescribed* + + +.. c:function:: nvme_root_t nvme_scan_filter (nvme_scan_filter_t f) + + +**Parameters** + +``nvme_scan_filter_t f`` + *undescribed* + + +.. c:function:: nvme_root_t nvme_scan () + + +**Parameters** + + +.. c:function:: void nvme_refresh_topology (nvme_root_t r) + + +**Parameters** + +``nvme_root_t r`` + *undescribed* + + +.. c:function:: void nvme_reset_topology (nvme_root_t r) + + +**Parameters** + +``nvme_root_t r`` + *undescribed* + + +.. c:function:: void nvme_free_tree (nvme_root_t r) + + +**Parameters** + +``nvme_root_t r`` + *undescribed* + + +.. c:function:: char * nvme_get_subsys_attr (nvme_subsystem_t s, const char * attr) + + +**Parameters** + +``nvme_subsystem_t s`` + *undescribed* + +``const char * attr`` + *undescribed* + + +.. c:function:: char * nvme_get_ctrl_attr (nvme_ctrl_t c, const char * attr) + + +**Parameters** + +``nvme_ctrl_t c`` + *undescribed* + +``const char * attr`` + *undescribed* + + +.. c:function:: char * nvme_get_ns_attr (nvme_ns_t n, const char * attr) + + +**Parameters** + +``nvme_ns_t n`` + *undescribed* + +``const char * attr`` + *undescribed* + + +.. c:function:: char * nvme_get_path_attr (nvme_path_t p, const char * attr) + + +**Parameters** + +``nvme_path_t p`` + *undescribed* + +``const char * attr`` + *undescribed* + + + + +.. c:type:: enum nvme_constants + + +**Constants** + +``NVME_NSID_ALL`` + *undescribed* + +``NVME_NSID_NONE`` + *undescribed* + +``NVME_UUID_NONE`` + *undescribed* + +``NVME_CNTLID_NONE`` + *undescribed* + +``NVME_NVMSETID_NONE`` + *undescribed* + +``NVME_LOG_LSP_NONE`` + *undescribed* + +``NVME_LOG_LSI_NONE`` + *undescribed* + +``NVME_IDENTIFY_DATA_SIZE`` + *undescribed* + +``NVME_ID_NVMSET_LIST_MAX`` + *undescribed* + +``NVME_ID_UUID_LIST_MAX`` + *undescribed* + +``NVME_ID_CTRL_LIST_MAX`` + *undescribed* + +``NVME_ID_NS_LIST_MAX`` + *undescribed* + +``NVME_ID_SECONDARY_CTRL_MAX`` + *undescribed* + +``NVME_FEAT_LBA_RANGE_MAX`` + *undescribed* + +``NVME_LOG_ST_MAX_RESULTS`` + *undescribed* + +``NVME_DSM_MAX_RANGES`` + *undescribed* + + +**NVMe controller registers/properties** + + + + +.. c:type:: enum nvme_registers + + +**Constants** + +``NVME_REG_CAP`` + Controller Capabilities + +``NVME_REG_VS`` + Version + +``NVME_REG_INTMS`` + Interrupt Mask Set + +``NVME_REG_INTMC`` + Interrupt Mask Clear + +``NVME_REG_CC`` + Controller Configuration + +``NVME_REG_CSTS`` + Controller Status + +``NVME_REG_NSSR`` + NVM Subsystem Reset + +``NVME_REG_AQA`` + Admin Queue Attributes + +``NVME_REG_ASQ`` + Admin SQ Base Address + +``NVME_REG_ACQ`` + Admin CQ Base Address + +``NVME_REG_CMBLOC`` + Controller Memory Buffer Location + +``NVME_REG_CMBSZ`` + Controller Memory Buffer Size + +``NVME_REG_BPINFO`` + Boot Partition Information + +``NVME_REG_BPRSEL`` + Boot Partition Read Select + +``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_PMRCAP`` + Persistent Memory Capabilities + +``NVME_REG_PMRCTL`` + Persistent Memory Region Control + +``NVME_REG_PMRSTS`` + Persistent Memory Region Status + +``NVME_REG_PMREBS`` + Persistent Memory Region Elasticity Buffer Size + +``NVME_REG_PMRSWTP`` + Memory Region Sustained Write Throughput + +``NVME_REG_PMRMSC`` + Persistent Memory Region Controller Memory Space Control + +``NVME_REG_DBS`` + SQ 0 Tail Doorbell + + + + +.. c:type:: enum + + +**Constants** + +``NVME_CC_ENABLE`` + *undescribed* + +``NVME_CC_CSS_NVM`` + *undescribed* + +``NVME_CC_EN_SHIFT`` + *undescribed* + +``NVME_CC_CSS_SHIFT`` + *undescribed* + +``NVME_CC_MPS_SHIFT`` + *undescribed* + +``NVME_CC_AMS_SHIFT`` + *undescribed* + +``NVME_CC_SHN_SHIFT`` + *undescribed* + +``NVME_CC_IOSQES_SHIFT`` + *undescribed* + +``NVME_CC_IOCQES_SHIFT`` + *undescribed* + +``NVME_CC_AMS_RR`` + *undescribed* + +``NVME_CC_AMS_WRRU`` + *undescribed* + +``NVME_CC_AMS_VS`` + *undescribed* + +``NVME_CC_SHN_NONE`` + *undescribed* + +``NVME_CC_SHN_NORMAL`` + *undescribed* + +``NVME_CC_SHN_ABRUPT`` + *undescribed* + +``NVME_CC_SHN_MASK`` + *undescribed* + +``NVME_CSTS_RDY`` + *undescribed* + +``NVME_CSTS_CFS`` + *undescribed* + +``NVME_CSTS_NSSRO`` + *undescribed* + +``NVME_CSTS_PP`` + *undescribed* + +``NVME_CSTS_SHST_NORMAL`` + *undescribed* + +``NVME_CSTS_SHST_OCCUR`` + *undescribed* + +``NVME_CSTS_SHST_CMPLT`` + *undescribed* + +``NVME_CSTS_SHST_MASK`` + *undescribed* + + +**NVMe Identify** + + + + +.. c:type:: struct nvme_id_psd + + +**Definition** + +:: + + struct nvme_id_psd { + __le16 mp; + __u8 rsvd2; + __u8 flags; + __le32 enlat; + __le32 exlat; + __u8 rrt; + __u8 rrl; + __u8 rwt; + __u8 rwl; + __le16 idlp; + __u8 ips; + __u8 rsvd19; + __le16 actp; + __u8 apw; + __u8 aps; + __u8 rsvd23[8]; + }; + +**Members** + + + +.. c:function:: unsigned nvme_psd_power_scale (__u8 ps) + + power scale occupies the upper 3 bits + +**Parameters** + +``__u8 ps`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_PSD_FLAGS_MAX_POWER_SCALE`` + *undescribed* + +``NVME_PSD_FLAGS_NON_OP_STATE`` + *undescribed* + +``NVME_PSD_RELATIVE_MASK`` + *undescribed* + +``NVME_PSD_APW_MASK`` + *undescribed* + + + + +.. c:type:: struct nvme_id_ctrl + + Identify Controller data structure + +**Definition** + +:: + + struct nvme_id_ctrl { + __le16 vid; + __le16 ssvid; + char sn[20]; + char mn[40]; + char fr[8]; + __u8 rab; + __u8 ieee[3]; + __u8 cmic; + __u8 mdts; + __le16 cntlid; + __le32 ver; + __le32 rtd3r; + __le32 rtd3e; + __le32 oaes; + __le32 ctratt; + __le16 rrls; + __u8 rsvd102[9]; + __u8 cntrltype; + __u8 fguid[16]; + __le16 crdt1; + __le16 crdt2; + __le16 crdt3; + __u8 rsvd134[119]; + __u8 nvmsr; + __u8 vwci; + __u8 mec; + __le16 oacs; + __u8 acl; + __u8 aerl; + __u8 frmw; + __u8 lpa; + __u8 elpe; + __u8 npss; + __u8 avscc; + __u8 apsta; + __le16 wctemp; + __le16 cctemp; + __le16 mtfa; + __le32 hmpre; + __le32 hmmin; + __u8 tnvmcap[16]; + __u8 unvmcap[16]; + __le32 rpmbs; + __le16 edstt; + __u8 dsto; + __u8 fwug; + __le16 kas; + __le16 hctma; + __le16 mntmt; + __le16 mxtmt; + __le32 sanicap; + __le32 hmminds; + __le16 hmmaxd; + __le16 nsetidmax; + __le16 endgidmax; + __u8 anatt; + __u8 anacap; + __le32 anagrpmax; + __le32 nanagrpid; + __le32 pels; + __u8 rsvd356[156]; + __u8 sqes; + __u8 cqes; + __le16 maxcmd; + __le32 nn; + __le16 oncs; + __le16 fuses; + __u8 fna; + __u8 vwc; + __le16 awun; + __le16 awupf; + __u8 nvscc; + __u8 nwpc; + __le16 acwu; + __u8 rsvd534[2]; + __le32 sgls; + __le32 mnan; + __u8 rsvd544[224]; + char subnqn[256]; + __u8 rsvd1024[768]; + __le32 ioccsz; + __le32 iorcsz; + __le16 icdoff; + __u8 fcatt; + __u8 msdbd; + __le16 ofcs; + __u8 rsvd1806[242]; + struct nvme_id_psd psd[32]; + __u8 vs[1024]; + }; + +**Members** + +``vid`` + Vendor ID + +``ssvid`` + Subsystem Vendor Id + +``sn`` + Serial Number + +``mn`` + Model Number + +``fr`` + Firmware Revision + +``rab`` + Recommended Arbitration Burst + +``ieee`` + IEEE + +``cmic`` + Controller Mulitpathing Capabilities + +``mdts`` + Max Data Transfer Size + +``cntlid`` + Controller Identifier + +``ver`` + Version + +``rtd3r`` + Runtime D3 Resume + +``rtd3e`` + Runtime D3 Exit + +``oaes`` + Optional Async Events Supported + +``ctratt`` + Controller Attributes + +``rrls`` + Read Recovery Levels + +``cntrltype`` + Controller Type + +``fguid`` + FRU GUID + +``crdt1`` + Controller Retry Delay 1 + +``crdt2`` + Controller Retry Delay 2 + +``crdt3`` + Controller Retry Delay 3 + +``oacs`` + Optional Admin Commands Supported + +``acl`` + Abort Command Limit + +``aerl`` + Async Event Request Limit + +``lpa`` + Log Page Attributes + +``npss`` + Number of Power States Supported + + + + + +.. c:type:: enum + + +**Constants** + +``NVME_CTRL_CMIC_MULTI_PORT`` + *undescribed* + +``NVME_CTRL_CMIC_MULTI_CTRL`` + *undescribed* + +``NVME_CTRL_CMIC_MULTI_SRIOV`` + *undescribed* + +``NVME_CTRL_CMIC_MULTI_ANA_REPORTING`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_CTRL_OAES_NA`` + *undescribed* + +``NVME_CTRL_OAES_FA`` + *undescribed* + +``NVME_CTRL_OAES_ANA`` + *undescribed* + +``NVME_CTRL_OAES_PLEA`` + *undescribed* + +``NVME_CTRL_OAES_LBAS`` + *undescribed* + +``NVME_CTRL_OAES_EGE`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_CTRL_CTRATT_128_ID`` + *undescribed* + +``NVME_CTRL_CTRATT_NON_OP_PSP`` + *undescribed* + +``NVME_CTRL_CTRATT_NVM_SETS`` + *undescribed* + +``NVME_CTRL_CTRATT_READ_RECV_LVLS`` + *undescribed* + +``NVME_CTRL_CTRATT_ENDURANCE_GROUPS`` + *undescribed* + +``NVME_CTRL_CTRATT_PREDICTABLE_LAT`` + *undescribed* + +``NVME_CTRL_CTRATT_TBKAS`` + *undescribed* + +``NVME_CTRL_CTRATT_NAMESPACE_GRANULARITY`` + *undescribed* + +``NVME_CTRL_CTRATT_SQ_ASSOCIATIONS`` + *undescribed* + +``NVME_CTRL_CTRATT_UUID_LIST`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_CTRL_CNTRLTYPE_RESERVED`` + *undescribed* + +``NVME_CTRL_CNTRLTYPE_IO`` + *undescribed* + +``NVME_CTRL_CNTRLTYPE_DISCOVERY`` + *undescribed* + +``NVME_CTRL_CNTRLTYPE_ADMIN`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_CTRL_NVMSR_NVMESD`` + *undescribed* + +``NVME_CTRL_NVMSR_NVMEE`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_CTRL_VWCI_VWCR`` + *undescribed* + +``NVME_CTRL_VWCI_VWCRV`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_CTRL_MEC_SMBUSME`` + *undescribed* + +``NVME_CTRL_MEC_PCIEME`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_CTRL_OACS_SECURITY`` + *undescribed* + +``NVME_CTRL_OACS_FORMAT`` + *undescribed* + +``NVME_CTRL_OACS_FW`` + *undescribed* + +``NVME_CTRL_OACS_NS_MGMT`` + *undescribed* + +``NVME_CTRL_OACS_SELF_TEST`` + *undescribed* + +``NVME_CTRL_OACS_DIRECTIVES`` + *undescribed* + +``NVME_CTRL_OACS_NVME_MI`` + *undescribed* + +``NVME_CTRL_OACS_VIRT_MGMT`` + *undescribed* + +``NVME_CTRL_OACS_DBBUF_CFG`` + *undescribed* + +``NVME_CTRL_OACS_LBA_STATUS`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_CTRL_FRMW_1ST_RO`` + *undescribed* + +``NVME_CTRL_FRMW_NR_SLOTS`` + *undescribed* + +``NVME_CTRL_FRMW_FW_ACT_NO_RESET`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_CTRL_LPA_SMART_PER_NS`` + *undescribed* + +``NVME_CTRL_LPA_CMD_EFFECTS`` + *undescribed* + +``NVME_CTRL_LPA_EXTENDED`` + *undescribed* + +``NVME_CTRL_LPA_TELEMETRY`` + *undescribed* + +``NVME_CTRL_LPA_PERSETENT_EVENT`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_CTRL_AVSCC_AVS`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_CTRL_APSTA_APST`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_CTRL_RPMBS_NR_UNITS`` + *undescribed* + +``NVME_CTRL_RPMBS_AUTH_METHOD`` + *undescribed* + +``NVME_CTRL_RPMBS_TOTAL_SIZE`` + *undescribed* + +``NVME_CTRL_RPMBS_ACCESS_SIZE`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_CTRL_DSTO_ONE_DST`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_CTRL_HCTMA_HCTM`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_CTRL_SANICAP_CES`` + *undescribed* + +``NVME_CTRL_SANICAP_BES`` + *undescribed* + +``NVME_CTRL_SANICAP_OWS`` + *undescribed* + +``NVME_CTRL_SANICAP_NDI`` + *undescribed* + +``NVME_CTRL_SANICAP_NODMMAS`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_CTRL_ANACAP_OPT`` + *undescribed* + +``NVME_CTRL_ANACAP_NON_OPT`` + *undescribed* + +``NVME_CTRL_ANACAP_INACCESSIBLE`` + *undescribed* + +``NVME_CTRL_ANACAP_PERSISTENT_LOSS`` + *undescribed* + +``NVME_CTRL_ANACAP_CHANGE`` + *undescribed* + +``NVME_CTRL_ANACAP_GRPID_NO_CHG`` + *undescribed* + +``NVME_CTRL_ANACAP_GRPID_MGMT`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_CTRL_SQES_MIN`` + *undescribed* + +``NVME_CTRL_SQES_MAX`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_CTRL_CQES_MIN`` + *undescribed* + +``NVME_CTRL_CQES_MAX`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_CTRL_ONCS_COMPARE`` + *undescribed* + +``NVME_CTRL_ONCS_WRITE_UNCORRECTABLE`` + *undescribed* + +``NVME_CTRL_ONCS_DSM`` + *undescribed* + +``NVME_CTRL_ONCS_WRITE_ZEROES`` + *undescribed* + +``NVME_CTRL_ONCS_SAVE_FEATURES`` + *undescribed* + +``NVME_CTRL_ONCS_RESERVATIONS`` + *undescribed* + +``NVME_CTRL_ONCS_TIMESTAMP`` + *undescribed* + +``NVME_CTRL_ONCS_VERIFY`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_CTRL_FUSES_COMPARE_AND_WRITE`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_CTRL_FNA_FMT_ALL_NAMESPACES`` + *undescribed* + +``NVME_CTRL_FNA_SEC_ALL_NAMESPACES`` + *undescribed* + +``NVME_CTRL_FNA_CRYPTO_ERASE`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_CTRL_VWC_PRESENT`` + *undescribed* + +``NVME_CTRL_VWC_FLUSH`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_CTRL_NVSCC_FMT`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_CTRL_NWPC_WRITE_PROTECT`` + *undescribed* + +``NVME_CTRL_NWPC_WRITE_PROTECT_POWER_CYCLE`` + *undescribed* + +``NVME_CTRL_NWPC_WRITE_PROTECT_PERMANENT`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_CTRL_SGLS_SUPPORTED`` + *undescribed* + +``NVME_CTRL_SGLS_KEYED`` + *undescribed* + +``NVME_CTRL_SGLS_BIT_BUCKET`` + *undescribed* + +``NVME_CTRL_SGLS_MPTR_BYTE_ALIGNED`` + *undescribed* + +``NVME_CTRL_SGLS_OVERSIZE`` + *undescribed* + +``NVME_CTRL_SGLS_MPTR_SGL`` + *undescribed* + +``NVME_CTRL_SGLS_OFFSET`` + *undescribed* + +``NVME_CTRL_SGLS_TPORT`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_CTRL_FCATT_DYNAMIC`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_CTRL_OFCS_DISCONNECT`` + *undescribed* + + + + +.. c:type:: struct nvme_lbaf + + +**Definition** + +:: + + struct nvme_lbaf { + __le16 ms; + __u8 ds; + __u8 rp; + }; + +**Members** + + + + + +.. c:type:: enum + + +**Constants** + +``NVME_LBAF_RP_BEST`` + *undescribed* + +``NVME_LBAF_RP_BETTER`` + *undescribed* + +``NVME_LBAF_RP_GOOD`` + *undescribed* + +``NVME_LBAF_RP_DEGRADED`` + *undescribed* + +``NVME_LBAF_RP_MASK`` + *undescribed* + + + + +.. c:type:: struct nvme_id_ns + + +**Definition** + +:: + + struct nvme_id_ns { + __le64 nsze; + __le64 ncap; + __le64 nuse; + __u8 nsfeat; + __u8 nlbaf; + __u8 flbas; + __u8 mc; + __u8 dpc; + __u8 dps; + __u8 nmic; + __u8 rescap; + __u8 fpi; + __u8 dlfeat; + __le16 nawun; + __le16 nawupf; + __le16 nacwu; + __le16 nabsn; + __le16 nabo; + __le16 nabspf; + __le16 noiob; + __u8 nvmcap[16]; + __le16 npwg; + __le16 npwa; + __le16 npdg; + __le16 npda; + __le16 nows; + __u8 rsvd74[18]; + __le32 anagrpid; + __u8 rsvd96[3]; + __u8 nsattr; + __le16 nvmsetid; + __le16 endgid; + __u8 nguid[16]; + __u8 eui64[8]; + struct nvme_lbaf lbaf[16]; + __u8 rsvd192[192]; + __u8 vs[3712]; + }; + +**Members** + + + + + +.. c:type:: enum + + +**Constants** + +``NVME_NS_FEAT_THIN`` + *undescribed* + +``NVME_NS_FEAT_NATOMIC`` + *undescribed* + +``NVME_NS_FEAT_DULBE`` + *undescribed* + +``NVME_NS_FEAT_ID_REUSE`` + *undescribed* + +``NVME_NS_FEAT_IO_OPT`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_NS_FLBAS_LBA_MASK`` + *undescribed* + +``NVME_NS_FLBAS_META_EXT`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_NS_MC_EXTENDED`` + *undescribed* + +``NVME_NS_MC_SEPARATE`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_NS_DPC_PI_TYPE1`` + *undescribed* + +``NVME_NS_DPC_PI_TYPE2`` + *undescribed* + +``NVME_NS_DPC_PI_TYPE3`` + *undescribed* + +``NVME_NS_DPC_PI_FIRST`` + *undescribed* + +``NVME_NS_DPC_PI_LAST`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_NS_DPS_PI_NONE`` + *undescribed* + +``NVME_NS_DPS_PI_TYPE1`` + *undescribed* + +``NVME_NS_DPS_PI_TYPE2`` + *undescribed* + +``NVME_NS_DPS_PI_TYPE3`` + *undescribed* + +``NVME_NS_DPS_PI_MASK`` + *undescribed* + +``NVME_NS_DPS_PI_FIRST`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_NS_NMIC_SHARED`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_NS_RESCAP_PTPL`` + *undescribed* + +``NVME_NS_RESCAP_WE`` + *undescribed* + +``NVME_NS_RESCAP_EA`` + *undescribed* + +``NVME_NS_RESCAP_WERO`` + *undescribed* + +``NVME_NS_RESCAP_EARO`` + *undescribed* + +``NVME_NS_RESCAP_WEAR`` + *undescribed* + +``NVME_NS_RESCAP_EAAR`` + *undescribed* + +``NVME_NS_RESCAP_IEK_13`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_NS_FPI_REMAINING`` + *undescribed* + +``NVME_NS_FPI_SUPPORTED`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_NS_DLFEAT_RB`` + *undescribed* + +``NVME_NS_DLFEAT_RB_NR`` + *undescribed* + +``NVME_NS_DLFEAT_RB_ALL_0S`` + *undescribed* + +``NVME_NS_DLFEAT_RB_ALL_FS`` + *undescribed* + +``NVME_NS_DLFEAT_WRITE_ZEROES`` + *undescribed* + +``NVME_NS_DLFEAT_CRC_GUARD`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_NS_NSATTR_WRITE_PROTECTED`` + *undescribed* + + + + +.. c:type:: struct nvme_ns_id_desc + + +**Definition** + +:: + + struct nvme_ns_id_desc { + __u8 nidt; + __u8 nidl; + __le16 reserved; + __u8 nid[]; + }; + +**Members** + + + + + +.. c:type:: enum + + +**Constants** + +``NVME_NIDT_EUI64`` + *undescribed* + +``NVME_NIDT_NGUID`` + *undescribed* + +``NVME_NIDT_UUID`` + *undescribed* + + + + +.. c:type:: struct nvme_nvmset_attr + + +**Definition** + +:: + + struct nvme_nvmset_attr { + __le16 id; + __le16 endurance_group_id; + __u8 rsvd4[4]; + __le32 random_4k_read_typical; + __le32 opt_write_size; + __u8 total_nvmset_cap[16]; + __u8 unalloc_nvmset_cap[16]; + __u8 rsvd48[80]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_id_nvmset_list + + +**Definition** + +:: + + struct nvme_id_nvmset_list { + __u8 nid; + __u8 rsvd1[127]; + struct nvme_nvmset_attr ent[NVME_ID_NVMSET_LIST_MAX]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_id_ns_granularity_list_entry + + +**Definition** + +:: + + struct nvme_id_ns_granularity_list_entry { + __le64 namespace_size_granularity; + __le64 namespace_capacity_granularity; + }; + +**Members** + + + + + +.. c:type:: struct nvme_id_ns_granularity_list + + +**Definition** + +:: + + struct nvme_id_ns_granularity_list { + __le32 attributes; + __u8 num_descriptors; + __u8 rsvd[27]; + struct nvme_id_ns_granularity_list_entry entry[16]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_id_uuid_list_entry + + +**Definition** + +:: + + struct nvme_id_uuid_list_entry { + __u8 header; + __u8 rsvd1[15]; + __u8 uuid[16]; + }; + +**Members** + + + + + +.. c:type:: enum + + +**Constants** + +``NVME_ID_UUID_HDR_ASSOCIATION_MASK`` + *undescribed* + +``NVME_ID_UUID_ASSOCIATION_NONE`` + *undescribed* + +``NVME_ID_UUID_ASSOCIATION_VENDOR`` + *undescribed* + +``NVME_ID_UUID_ASSOCIATION_SUBSYSTEM_VENDOR`` + *undescribed* + + + + +.. c:type:: struct nvme_id_uuid_list + + +**Definition** + +:: + + struct nvme_id_uuid_list { + __u8 rsvd0[32]; + struct nvme_id_uuid_list_entry entry[NVME_ID_UUID_LIST_MAX]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_ctrl_list + + +**Definition** + +:: + + struct nvme_ctrl_list { + __le16 num; + __le16 identifier[NVME_ID_CTRL_LIST_MAX]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_ns_list + + +**Definition** + +:: + + struct nvme_ns_list { + __le32 ns[NVME_ID_NS_LIST_MAX]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_primary_ctrl_cap + + +**Definition** + +:: + + struct nvme_primary_ctrl_cap { + __le16 cntlid; + __le16 portid; + __u8 crt; + __u8 rsvd5[27]; + __le32 vqfrt; + __le32 vqrfa; + __le16 vqrfap; + __le16 vqprt; + __le16 vqfrsm; + __le16 vqgran; + __u8 rsvd48[16]; + __le32 vifrt; + __le32 virfa; + __le16 virfap; + __le16 viprt; + __le16 vifrsm; + __le16 vigran; + __u8 rsvd80[4016]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_secondary_ctrl + + +**Definition** + +:: + + struct nvme_secondary_ctrl { + __le16 scid; + __le16 pcid; + __u8 scs; + __u8 rsvd5[3]; + __le16 vfn; + __le16 nvq; + __le16 nvi; + __u8 rsvd14[18]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_secondary_ctrl_list + + +**Definition** + +:: + + struct nvme_secondary_ctrl_list { + __u8 num; + __u8 rsvd[31]; + struct nvme_secondary_ctrl sc_entry[NVME_ID_SECONDARY_CTRL_MAX]; + }; + +**Members** + + + +**NVMe Logs** + + + + +.. c:type:: struct nvme_error_log_page + + +**Definition** + +:: + + struct nvme_error_log_page { + __le64 error_count; + __le16 sqid; + __le16 cmdid; + __le16 status_field; + __le16 parm_error_location; + __le64 lba; + __le32 nsid; + __u8 vs; + __u8 trtype; + __u8 resv[2]; + __le64 cs; + __le16 trtype_spec_info; + __u8 resv2[22]; + }; + +**Members** + + + + + +.. c:type:: enum + + +**Constants** + +``NVME_ERR_PEL_BYTE_MASK`` + *undescribed* + +``NVME_ERR_PEL_BIT_MASK`` + *undescribed* + + + + +.. c:type:: struct nvme_smart_log + + +**Definition** + +:: + + struct nvme_smart_log { + __u8 critical_warning; + __u8 temperature[2]; + __u8 avail_spare; + __u8 spare_thresh; + __u8 percent_used; + __u8 endu_grp_crit_warn_sumry; + __u8 rsvd7[25]; + __u8 data_units_read[16]; + __u8 data_units_written[16]; + __u8 host_reads[16]; + __u8 host_writes[16]; + __u8 ctrl_busy_time[16]; + __u8 power_cycles[16]; + __u8 power_on_hours[16]; + __u8 unsafe_shutdowns[16]; + __u8 media_errors[16]; + __u8 num_err_log_entries[16]; + __le32 warning_temp_time; + __le32 critical_comp_time; + __le16 temp_sensor[8]; + __le32 thm_temp1_trans_count; + __le32 thm_temp2_trans_count; + __le32 thm_temp1_total_time; + __le32 thm_temp2_total_time; + __u8 rsvd232[280]; + }; + +**Members** + + + + + +.. c:type:: enum + + +**Constants** + +``NVME_SMART_CRIT_SPARE`` + *undescribed* + +``NVME_SMART_CRIT_TEMPERATURE`` + *undescribed* + +``NVME_SMART_CRIT_DEGRADED`` + *undescribed* + +``NVME_SMART_CRIT_MEDIA`` + *undescribed* + +``NVME_SMART_CRIT_VOLATILE_MEMORY`` + *undescribed* + +``NVME_SMART_CRIT_PMR_RO`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_SMART_EGCW_SPARE`` + *undescribed* + +``NVME_SMART_EGCW_DEGRADED`` + *undescribed* + +``NVME_SMART_EGCW_RO`` + *undescribed* + + + + +.. c:type:: struct nvme_frs + + +**Definition** + +:: + + struct nvme_frs { + char frs[8]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_firmware_slot + + +**Definition** + +:: + + struct nvme_firmware_slot { + __u8 afi; + __u8 resv[7]; + struct nvme_frs frs[7]; + __u8 resv2[448]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_cmd_effects_log + + +**Definition** + +:: + + struct nvme_cmd_effects_log { + __le32 acs[256]; + __le32 iocs[256]; + __u8 resv[2048]; + }; + +**Members** + + + + + +.. c:type:: enum + + +**Constants** + +``NVME_CMD_EFFECTS_CSUPP`` + *undescribed* + +``NVME_CMD_EFFECTS_LBCC`` + *undescribed* + +``NVME_CMD_EFFECTS_NCC`` + *undescribed* + +``NVME_CMD_EFFECTS_NIC`` + *undescribed* + +``NVME_CMD_EFFECTS_CCC`` + *undescribed* + +``NVME_CMD_EFFECTS_CSE_MASK`` + *undescribed* + +``NVME_CMD_EFFECTS_UUID_SEL`` + *undescribed* + + + + +.. c:type:: struct nvme_st_result + + +**Definition** + +:: + + struct nvme_st_result { + __u8 dsts; + __u8 seg; + __u8 vdi; + __u8 rsvd; + __le64 poh; + __le32 nsid; + __le64 flba; + __u8 sct; + __u8 sc; + __u8 vs[2]; + }; + +**Members** + + + + + +.. c:type:: enum + + +**Constants** + +``NVME_ST_RESULT_NO_ERR`` + *undescribed* + +``NVME_ST_RESULT_ABORTED`` + *undescribed* + +``NVME_ST_RESULT_CLR`` + *undescribed* + +``NVME_ST_RESULT_NS_REMOVED`` + *undescribed* + +``NVME_ST_RESULT_ABORTED_FORMAT`` + *undescribed* + +``NVME_ST_RESULT_FATAL_ERR`` + *undescribed* + +``NVME_ST_RESULT_UNKNOWN_SEG_FAIL`` + *undescribed* + +``NVME_ST_RESULT_KNOWN_SEG_FAIL`` + *undescribed* + +``NVME_ST_RESULT_ABORTED_UNKNOWN`` + *undescribed* + +``NVME_ST_RESULT_ABORTED_SANITIZE`` + *undescribed* + +``NVME_ST_RESULT_NOT_USED`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_ST_OPERATION_NONE`` + *undescribed* + +``NVME_ST_OPERATION_SHORT`` + *undescribed* + +``NVME_ST_OPERATION_EXTENDED`` + *undescribed* + +``NVME_ST_OPERATION_VS`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_ST_VALID_DIAG_INFO_NSID`` + *undescribed* + +``NVME_ST_VALID_DIAG_INFO_FLBA`` + *undescribed* + +``NVME_ST_VALID_DIAG_INFO_SCT`` + *undescribed* + +``NVME_ST_VALID_DIAG_INFO_SC`` + *undescribed* + + + + +.. c:type:: struct nvme_self_test_log + + +**Definition** + +:: + + struct nvme_self_test_log { + __u8 current_operation; + __u8 completion; + __u8 rsvd[2]; + struct nvme_st_result result[NVME_LOG_ST_MAX_RESULTS]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_telemetry_log + + +**Definition** + +:: + + struct nvme_telemetry_log { + __u8 lpi; + __u8 rsvd[4]; + __u8 ieee[3]; + __le16 dalb1; + __le16 dalb2; + __le16 dalb3; + __u8 rsvd1[368]; + __u8 ctrlavail; + __u8 ctrldgn; + __u8 rsnident[128]; + __u8 telemetry_dataarea[]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_endurance_group_log + + +**Definition** + +:: + + struct nvme_endurance_group_log { + __u8 critical_warning; + __u8 rsvd1[2]; + __u8 avl_spare; + __u8 avl_spare_threshold; + __u8 percent_used; + __u8 rsvd6[26]; + __u8 endurance_estimate[16]; + __u8 data_units_read[16]; + __u8 data_units_written[16]; + __u8 media_units_written[16]; + __u8 host_read_cmds[16]; + __u8 host_write_cmds[16]; + __u8 media_data_integrity_err[16]; + __u8 num_err_info_log_entries[16]; + __u8 rsvd160[352]; + }; + +**Members** + + + + + +.. c:type:: enum nvme_eg_critical_warning_flags + + +**Constants** + +``NVME_EG_CRITICAL_WARNING_SPARE`` + *undescribed* + +``NVME_EG_CRITICAL_WARNING_DEGRADED`` + *undescribed* + +``NVME_EG_CRITICAL_WARNING_READ_ONLY`` + *undescribed* + + + + +.. c:type:: struct nvme_aggregate_endurance_group_event + + +**Definition** + +:: + + struct nvme_aggregate_endurance_group_event { + __le64 num_entries; + __le16 entries[]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_nvmset_predictable_lat_log + + +**Definition** + +:: + + struct nvme_nvmset_predictable_lat_log { + __u8 status; + __u8 rsvd1; + __le16 event_type; + __u8 rsvd4[28]; + __le64 dtwin_rt; + __le64 dtwin_wt; + __le64 dtwin_tmax; + __le64 dtwin_tmin_hi; + __le64 dtwin_tmin_lo; + __u8 rsvd72[56]; + __le64 dtwin_re; + __le64 dtwin_we; + __le64 dtwin_te; + __u8 rsvd152[360]; + }; + +**Members** + + + + + +.. c:type:: enum + + +**Constants** + +``NVME_NVMSET_PL_STATUS_DISABLED`` + *undescribed* + +``NVME_NVMSET_PL_STATUS_DTWIN`` + *undescribed* + +``NVME_NVMSET_PL_STATUS_NDWIN`` + *undescribed* + + + + +.. c:type:: enum + + +**Constants** + +``NVME_NVMSET_PL_EVENT_DTWIN_READ_WARN`` + *undescribed* + +``NVME_NVMSET_PL_EVENT_DTWIN_WRITE_WARN`` + *undescribed* + +``NVME_NVMSET_PL_EVENT_DTWIN_TIME_WARN`` + *undescribed* + +``NVME_NVMSET_PL_EVENT_DTWIN_EXCEEDED`` + *undescribed* + +``NVME_NVMSET_PL_EVENT_DTWIN_EXCURSION`` + *undescribed* + + + + +.. c:type:: struct nvme_aggregate_predictable_lat_event + + +**Definition** + +:: + + struct nvme_aggregate_predictable_lat_event { + __le64 num_entries; + __le16 entries[]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_ana_group_desc + + +**Definition** + +:: + + struct nvme_ana_group_desc { + __le32 grpid; + __le32 nnsids; + __le64 chgcnt; + __u8 state; + __u8 rsvd17[15]; + __le32 nsids[]; + }; + +**Members** + + + + + +.. c:type:: enum + + +**Constants** + +``NVME_ANA_STATE_OPTIMIZED`` + *undescribed* + +``NVME_ANA_STATE_NONOPTIMIZED`` + *undescribed* + +``NVME_ANA_STATE_INACCESSIBLE`` + *undescribed* + +``NVME_ANA_STATE_PERSISTENT_LOSS`` + *undescribed* + +``NVME_ANA_STATE_CHANGE`` + *undescribed* + + + + +.. c:type:: struct nvme_ana_log + + +**Definition** + +:: + + struct nvme_ana_log { + __le64 chgcnt; + __le16 ngrps; + __u8 rsvd10[6]; + struct nvme_ana_group_desc descs[]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_persistent_event_log + + +**Definition** + +:: + + struct nvme_persistent_event_log { + __u8 lid; + __u8 rsvd1[3]; + __le32 ttl; + __u8 rv; + __u8 rsvd17; + __le16 lht; + __le64 ts; + __u8 poh[16]; + __le64 pcc; + __le16 vid; + __le16 ssvid; + char sn[20]; + char mn[40]; + char subnqn[256]; + __u8 rsvd372; + __u8 seb[32]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_lba_rd + + +**Definition** + +:: + + struct nvme_lba_rd { + __le64 rslba; + __le32 rnlb; + __u8 rsvd12[4]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_lbas_ns_element + + +**Definition** + +:: + + struct nvme_lbas_ns_element { + __le32 neid; + __le32 nrld; + __u8 ratype; + __u8 rsvd8[7]; + struct nvme_lba_rd lba_rd[]; + }; + +**Members** + + + + + +.. c:type:: enum nvme_lba_status_atype + + +**Constants** + +``NVME_LBA_STATUS_ATYPE_SCAN_UNTRACKED`` + *undescribed* + +``NVME_LBA_STATUS_ATYPE_SCAN_TRACKED`` + *undescribed* + + + + +.. c:type:: struct nvme_lba_status_log + + +**Definition** + +:: + + struct nvme_lba_status_log { + __le32 lslplen; + __le32 nlslne; + __le32 estulb; + __u8 rsvd12[2]; + __le16 lsgc; + struct nvme_lbas_ns_element elements[]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_eg_event_aggregate_log + + +**Definition** + +:: + + struct nvme_eg_event_aggregate_log { + __le64 nr_entries; + __le16 egids[]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_resv_notification_log + + +**Definition** + +:: + + struct nvme_resv_notification_log { + __le64 lpc; + __u8 rnlpt; + __u8 nalp; + __u8 rsvd9[2]; + __le32 nsid; + __u8 rsvd16[48]; + }; + +**Members** + + + + + +.. c:type:: enum + + +**Constants** + +``NVME_RESV_NOTIFY_RNLPT_EMPTY`` + *undescribed* + +``NVME_RESV_NOTIFY_RNLPT_REGISTRATION_PREEMPTED`` + *undescribed* + +``NVME_RESV_NOTIFY_RNLPT_RESERVATION_RELEASED`` + *undescribed* + +``NVME_RESV_NOTIFY_RNLPT_RESERVATION_PREEMPTED`` + *undescribed* + + + + +.. c:type:: struct nvme_sanitize_log_page + + +**Definition** + +:: + + struct nvme_sanitize_log_page { + __le16 sprog; + __le16 sstat; + __le32 scdw10; + __le32 eto; + __le32 etbe; + __le32 etce; + __le32 etond; + __le32 etbend; + __le32 etcend; + __u8 rsvd32[480]; + }; + +**Members** + + + +**NVMe Directives** + + + + +.. c:type:: enum + + +**Constants** + +``NVME_SANITIZE_SSTAT_NEVER_SANITIZED`` + *undescribed* + +``NVME_SANITIZE_SSTAT_COMPLETE_SUCCESS`` + *undescribed* + +``NVME_SANITIZE_SSTAT_IN_PROGESS`` + *undescribed* + +``NVME_SANITIZE_SSTAT_COMPLETED_FAILED`` + *undescribed* + +``NVME_SANITIZE_SSTAT_ND_COMPLETE_SUCCESS`` + *undescribed* + + + + +.. c:type:: struct nvme_lba_status_desc + + +**Definition** + +:: + + struct nvme_lba_status_desc { + __le64 dslba; + __le32 nlb; + __u8 rsvd12; + __u8 status; + __u8 rsvd14[2]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_lba_status + + +**Definition** + +:: + + struct nvme_lba_status { + __le32 nlsd; + __u8 cmpc; + __u8 rsvd5[3]; + struct nvme_lba_status_desc descs[]; + }; + +**Members** + + + +**NVMe Management Interface** + + + + +.. c:type:: struct nvme_mi_read_nvm_ss_info + + +**Definition** + +:: + + struct nvme_mi_read_nvm_ss_info { + __u8 nump; + __u8 mjr; + __u8 mnr; + __u8 rsvd3[29]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_mi_port_pcie + + +**Definition** + +:: + + struct nvme_mi_port_pcie { + __u8 mps; + __u8 sls; + __u8 cls; + __u8 mlw; + __u8 nlw; + __u8 pn; + __u8 rsvd14[18]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_mi_port_smb + + +**Definition** + +:: + + struct nvme_mi_port_smb { + __u8 vpd_addr; + __u8 mvpd_freq; + __u8 mme_addr; + __u8 mme_freq; + __u8 nvmebm; + __u8 rsvd13[19]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_mi_read_port_info + + +**Definition** + +:: + + struct nvme_mi_read_port_info { + __u8 portt; + __u8 rsvd1; + __le16 mmctptus; + __le32 meb; + union { + struct nvme_mi_port_pcie pcie; + struct nvme_mi_port_smb smb; + }; + }; + +**Members** + +``{unnamed_union}`` + anonymous + + + + + +.. c:type:: struct nvme_mi_read_ctrl_info + + +**Definition** + +:: + + struct nvme_mi_read_ctrl_info { + __u8 portid; + __u8 rsvd1[4]; + __u8 prii; + __le16 pri; + __le16 vid; + __le16 did; + __le16 ssvid; + __le16 ssid; + __u8 rsvd16[16]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_mi_osc + + +**Definition** + +:: + + struct nvme_mi_osc { + __u8 type; + __u8 opc; + }; + +**Members** + + + + + +.. c:type:: struct nvme_mi_read_sc_list + + +**Definition** + +:: + + struct nvme_mi_read_sc_list { + __le16 numcmd; + struct nvme_mi_osc cmds[]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_mi_nvm_ss_health_status + + +**Definition** + +:: + + struct nvme_mi_nvm_ss_health_status { + __u8 nss; + __u8 sw; + __u8 ctemp; + __u8 pdlu; + __le16 ccs; + __u8 rsvd8[2]; + }; + +**Members** + + + + + +.. c:type:: enum + + +**Constants** + +``NVME_MI_CCS_RDY`` + *undescribed* + +``NVME_MI_CSS_CFS`` + *undescribed* + +``NVME_MI_CSS_SHST`` + *undescribed* + +``NVME_MI_CSS_NSSRO`` + *undescribed* + +``NVME_MI_CSS_CECO`` + *undescribed* + +``NVME_MI_CSS_NAC`` + *undescribed* + +``NVME_MI_CSS_FA`` + *undescribed* + +``NVME_MI_CSS_CSTS`` + *undescribed* + +``NVME_MI_CSS_CTEMP`` + *undescribed* + +``NVME_MI_CSS_PDLU`` + *undescribed* + +``NVME_MI_CSS_SPARE`` + *undescribed* + +``NVME_MI_CSS_CCWARN`` + *undescribed* + + + + +.. c:type:: struct nvme_mi_ctrl_heal_status + + +**Definition** + +:: + + struct nvme_mi_ctrl_heal_status { + __le16 ctlid; + __le16 csts; + __le16 ctemp; + __u8 pdlu; + __u8 spare; + __u8 cwarn; + __u8 rsvd9[7]; + }; + +**Members** + + + + + +.. c:type:: enum + + +**Constants** + +``NVME_MI_CSTS_RDY`` + *undescribed* + +``NVME_MI_CSTS_CFS`` + *undescribed* + +``NVME_MI_CSTS_SHST`` + *undescribed* + +``NVME_MI_CSTS_NSSRO`` + *undescribed* + +``NVME_MI_CSTS_CECO`` + *undescribed* + +``NVME_MI_CSTS_NAC`` + *undescribed* + +``NVME_MI_CSTS_FA`` + *undescribed* + +``NVME_MI_CWARN_ST`` + *undescribed* + +``NVME_MI_CWARN_TAUT`` + *undescribed* + +``NVME_MI_CWARN_RD`` + *undescribed* + +``NVME_MI_CWARN_RO`` + *undescribed* + +``NVME_MI_CWARN_VMBF`` + *undescribed* + + + + +.. c:type:: struct nvme_mi_vpd_mra + + +**Definition** + +:: + + struct nvme_mi_vpd_mra { + __u8 nmravn; + __u8 ff; + __u8 rsvd7[6]; + __u8 i18vpwr; + __u8 m18vpwr; + __u8 i33vpwr; + __u8 m33vpwr; + __u8 rsvd17; + __u8 m33vapsr; + __u8 i5vapsr; + __u8 m5vapsr; + __u8 i12vapsr; + __u8 m12vapsr; + __u8 mtl; + __u8 tnvmcap[16]; + __u8 rsvd37[27]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_mi_vpd_ppmra + + +**Definition** + +:: + + struct nvme_mi_vpd_ppmra { + __u8 nppmravn; + __u8 pn; + __u8 ppi; + __u8 ls; + __u8 mlw; + __u8 mctp; + __u8 refccap; + __u8 pi; + __u8 rsvd13[3]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_mi_vpd_telem + + +**Definition** + +:: + + struct nvme_mi_vpd_telem { + __u8 type; + __u8 rev; + __u8 len; + __u8 data[0]; + }; + +**Members** + + + + + +.. c:type:: enum + + +**Constants** + +``NVME_MI_ELEM_EED`` + *undescribed* + +``NVME_MI_ELEM_USCE`` + *undescribed* + +``NVME_MI_ELEM_ECED`` + *undescribed* + +``NVME_MI_ELEM_LED`` + *undescribed* + +``NVME_MI_ELEM_SMBMED`` + *undescribed* + +``NVME_MI_ELEM_PCIESED`` + *undescribed* + +``NVME_MI_ELEM_NVMED`` + *undescribed* + + + + +.. c:type:: struct nvme_mi_vpd_tra + + +**Definition** + +:: + + struct nvme_mi_vpd_tra { + __u8 vn; + __u8 rsvd6; + __u8 ec; + struct nvme_mi_vpd_telem elems[0]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_mi_vpd_mr_common + + +**Definition** + +:: + + struct nvme_mi_vpd_mr_common { + __u8 type; + __u8 rf; + __u8 rlen; + __u8 rchksum; + __u8 hchksum; + union { + struct nvme_mi_vpd_mra nmra; + struct nvme_mi_vpd_ppmra ppmra; + struct nvme_mi_vpd_tra tmra; + }; + }; + +**Members** + +``{unnamed_union}`` + anonymous + + + + + +.. c:type:: struct nvme_mi_vpd_hdr + + +**Definition** + +:: + + struct nvme_mi_vpd_hdr { + __u8 ipmiver; + __u8 iuaoff; + __u8 ciaoff; + __u8 biaoff; + __u8 piaoff; + __u8 mrioff; + __u8 rsvd6; + __u8 chchk; + __u8 vpd[]; + }; + +**Members** + + + +**NVMe Features** + + + + +.. c:type:: struct nvme_feat_auto_pst + + +**Definition** + +:: + + struct nvme_feat_auto_pst { + __le64 apst_entry[32]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_timestamp + + +**Definition** + +:: + + struct nvme_timestamp { + __u8 timestamp[6]; + __u8 attr; + __u8 rsvd; + }; + +**Members** + + + + + +.. c:type:: struct nvme_lba_range_type_entry + + +**Definition** + +:: + + struct nvme_lba_range_type_entry { + __u8 type; + __u8 attributes; + __u8 rsvd2[14]; + __u64 slba; + __u64 nlb; + __u8 guid[16]; + __u8 rsvd48[16]; + }; + +**Members** + + + + + +.. c:type:: enum + + +**Constants** + +``NVME_LBART_TYPE_GP`` + *undescribed* + +``NVME_LBART_TYPE_FS`` + *undescribed* + +``NVME_LBART_TYPE_RAID`` + *undescribed* + +``NVME_LBART_TYPE_CACHE`` + *undescribed* + +``NVME_LBART_TYPE_SWAP`` + *undescribed* + +``NVME_LBART_ATTRIB_TEMP`` + *undescribed* + +``NVME_LBART_ATTRIB_HIDE`` + *undescribed* + + + + +.. c:type:: struct nvme_lba_range_type + + +**Definition** + +:: + + struct nvme_lba_range_type { + struct nvme_lba_range_type_entry entry[NVME_FEAT_LBA_RANGE_MAX]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_plm_config + + +**Definition** + +:: + + struct nvme_plm_config { + __le16 ee; + __u8 rsvd2[30]; + __le64 dtwinrt; + __le64 dtwinwt; + __le64 dtwintt; + __u8 rsvd56[456]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_feat_host_behavior + + +**Definition** + +:: + + struct nvme_feat_host_behavior { + __u8 acre; + __u8 resv1[511]; + }; + +**Members** + + + + + +.. c:type:: enum + + +**Constants** + +``NVME_ENABLE_ACRE`` + *undescribed* + + + + +.. c:type:: struct nvme_dsm_range + + +**Definition** + +:: + + struct nvme_dsm_range { + __le32 cattr; + __le32 nlb; + __le64 slba; + }; + +**Members** + + + + + +.. c:type:: struct nvme_registered_ctrl + + +**Definition** + +:: + + struct nvme_registered_ctrl { + __le16 cntlid; + __u8 rcsts; + __u8 rsvd3[5]; + __le64 hostid; + __le64 rkey; + }; + +**Members** + + + + + +.. c:type:: struct nvme_registered_ctrl_ext + + +**Definition** + +:: + + struct nvme_registered_ctrl_ext { + __le16 cntlid; + __u8 rcsts; + __u8 resv3[5]; + __le64 rkey; + __u8 hostid[16]; + __u8 resv32[32]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_reservation_status + + +**Definition** + +:: + + struct nvme_reservation_status { + __le32 gen; + __u8 rtype; + __u8 regctl[2]; + __u8 rsvd7[2]; + __u8 ptpls; + __u8 rsvd10[14]; + union { + struct { + __u8 resv24[40]; + struct nvme_registered_ctrl_ext regctl_eds[0]; + }; + struct nvme_registered_ctrl regctl_ds[0]; + }; + }; + +**Members** + +``{unnamed_union}`` + anonymous + +``{unnamed_struct}`` + anonymous + + + + + +.. c:type:: struct nvme_streams_directive_params + + +**Definition** + +:: + + struct nvme_streams_directive_params { + __le16 msl; + __le16 nssa; + __le16 nsso; + __u8 nssc; + __u8 rsvd[9]; + __le32 sws; + __le16 sgs; + __le16 nsa; + __le16 nso; + __u8 rsvd2[6]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_streams_directive_status + + +**Definition** + +:: + + struct nvme_streams_directive_status { + __le16 osc; + __le16 sid[]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_id_directives + + +**Definition** + +:: + + struct nvme_id_directives { + __u8 supported[32]; + __u8 enabled[32]; + __u8 rsvd64[4032]; + }; + +**Members** + + + + + +.. c:type:: enum + + +**Constants** + +``NVME_ID_DIR_ID_BIT`` + *undescribed* + +``NVME_ID_DIR_SD_BIT`` + *undescribed* + + + + +.. c:type:: struct nvme_host_mem_buf_desc + + +**Definition** + +:: + + struct nvme_host_mem_buf_desc { + __le64 addr; + __le32 size; + __u32 rsvd; + }; + +**Members** + + + + + +.. c:type:: enum nvme_ae_type + + +**Constants** + +``NVME_AER_ERROR`` + *undescribed* + +``NVME_AER_SMART`` + *undescribed* + +``NVME_AER_NOTICE`` + *undescribed* + +``NVME_AER_CSS`` + *undescribed* + +``NVME_AER_VS`` + *undescribed* + + + + +.. c:type:: enum nvme_ae_info_error + + +**Constants** + +``NVME_AER_ERROR_INVALID_DB_REG`` + *undescribed* + +``NVME_AER_ERROR_INVALID_DB_VAL`` + *undescribed* + +``NVME_AER_ERROR_DIAG_FAILURE`` + *undescribed* + +``NVME_AER_ERROR_PERSISTENT_INTERNAL_ERROR`` + *undescribed* + +``NVME_AER_ERROR_TRANSIENT_INTERNAL_ERROR`` + *undescribed* + +``NVME_AER_ERROR_FW_IMAGE_LOAD_ERROR`` + *undescribed* + + + + +.. c:type:: enum nvme_ae_info_smart + + +**Constants** + +``NVME_AER_SMART_SUBSYSTEM_RELIABILITY`` + *undescribed* + +``NVME_AER_SMART_TEMPERATURE_THRESHOLD`` + *undescribed* + +``NVME_AER_SMART_SPARE_THRESHOLD`` + *undescribed* + + + + +.. c:type:: enum nvme_ae_info_css_nvm + + +**Constants** + +``NVME_AER_CSS_NVM_RESERVATION`` + *undescribed* + +``NVME_AER_CSS_NVM_SANITIZE_COMPLETED`` + *undescribed* + +``NVME_AER_CSS_NVM_UNEXPECTED_SANITIZE_DEALLOC`` + *undescribed* + + + + +.. c:type:: enum nvme_ae_info_notice + + +**Constants** + +``NVME_AER_NOTICE_NS_CHANGED`` + *undescribed* + +``NVME_AER_NOTICE_FW_ACT_STARTING`` + *undescribed* + +``NVME_AER_NOTICE_TELEMETRY`` + *undescribed* + +``NVME_AER_NOTICE_ANA`` + *undescribed* + +``NVME_AER_NOTICE_PL_EVENT`` + *undescribed* + +``NVME_AER_NOTICE_LBA_STATUS_ALERT`` + *undescribed* + +``NVME_AER_NOTICE_EG_EVENT`` + *undescribed* + +``NVME_AER_NOTICE_DISC_CHANGED`` + *undescribed* + + + + +.. c:type:: enum nvme_subsys_type + + +**Constants** + +``NVME_NQN_DISC`` + Discovery type target subsystem + +``NVME_NQN_NVME`` + NVME type target subsystem + + + + +.. c:type:: struct nvmf_disc_log_entry + + +**Definition** + +:: + + struct nvmf_disc_log_entry { + __u8 trtype; + __u8 adrfam; + __u8 subtype; + __u8 treq; + __le16 portid; + __le16 cntlid; + __le16 asqsz; + __u8 resv10[22]; + char trsvcid[NVMF_TRSVCID_SIZE]; + __u8 resv64[192]; + char subnqn[NVMF_NQN_FIELD_LEN]; + char traddr[NVMF_TRADDR_SIZE]; + union tsas { + char common[NVMF_TSAS_SIZE]; + struct rdma { + __u8 qptype; + __u8 prtype; + __u8 cms; + __u8 resv3[5]; + __u16 pkey; + __u8 resv10[246]; + } rdma; + struct tcp { + __u8 sectype; + } tcp; + } tsas; + }; + +**Members** + + +**Description** + + +Discovery log page entry + + + + +.. c:type:: enum + + +**Constants** + +``NVMF_TRTYPE_UNSPECIFIED`` + Not indicated + +``NVMF_TRTYPE_RDMA`` + RDMA + +``NVMF_TRTYPE_FC`` + Fibre Channel + +``NVMF_TRTYPE_TCP`` + TCP + +``NVMF_TRTYPE_LOOP`` + Reserved for host usage + +``NVMF_TRTYPE_MAX`` + *undescribed* + +**Description** + +Transport Type codes for Discovery Log Page entry TRTYPE field + + + + +.. c:type:: enum + + +**Constants** + +``NVMF_ADDR_FAMILY_PCI`` + PCIe + +``NVMF_ADDR_FAMILY_IP4`` + IPv4 + +``NVMF_ADDR_FAMILY_IP6`` + IPv6 + +``NVMF_ADDR_FAMILY_IB`` + InfiniBand + +``NVMF_ADDR_FAMILY_FC`` + Fibre Channel + +**Description** + +Address Family codes for Discovery Log Page entry ADRFAM field + + + + +.. c:type:: enum + + +**Constants** + +``NVMF_TREQ_NOT_SPECIFIED`` + Not specified + +``NVMF_TREQ_REQUIRED`` + Required + +``NVMF_TREQ_NOT_REQUIRED`` + Not Required + +``NVMF_TREQ_DISABLE_SQFLOW`` + SQ flow control disable supported + +**Description** + +Transport Requirements codes for Discovery Log Page entry TREQ field + + + + +.. c:type:: enum + + +**Constants** + +``NVMF_RDMA_QPTYPE_CONNECTED`` + Reliable Connected + +``NVMF_RDMA_QPTYPE_DATAGRAM`` + Reliable Datagram + +**Description** + +RDMA QP Service Type codes for Discovery Log Page entry TSAS +RDMA_QPTYPE field + + + + +.. c:type:: enum + + +**Constants** + +``NVMF_RDMA_PRTYPE_NOT_SPECIFIED`` + No Provider Specified + +``NVMF_RDMA_PRTYPE_IB`` + InfiniBand + +``NVMF_RDMA_PRTYPE_ROCE`` + InfiniBand RoCE + +``NVMF_RDMA_PRTYPE_ROCEV2`` + InfiniBand RoCEV2 + +``NVMF_RDMA_PRTYPE_IWARP`` + iWARP + +**Description** + +RDMA Provider Type codes for Discovery Log Page entry TSAS +RDMA_PRTYPE field + + + + +.. c:type:: enum + + +**Constants** + +``NVMF_RDMA_CMS_RDMA_CM`` + Sockets based endpoint addressing + +**Description** + +RDMA Connection Management Service Type codes for Discovery Log Page +entry TSAS RDMA_CMS field + + + + +.. c:type:: enum + + +**Constants** + +``NVMF_TCP_SECTYPE_NONE`` + No Security + +``NVMF_TCP_SECTYPE_TLS`` + Transport Layer Security + + + + +.. c:type:: struct nvmf_discovery_log + + +**Definition** + +:: + + struct nvmf_discovery_log { + __le64 genctr; + __le64 numrec; + __le16 recfmt; + __u8 resv14[1006]; + struct nvmf_disc_log_entry entries[0]; + }; + +**Members** + + + + + +.. c:type:: struct nvmf_connect_data + + +**Definition** + +:: + + struct nvmf_connect_data { + __u8 hostid[16]; + __le16 cntlid; + char resv4[238]; + char subsysnqn[NVMF_NQN_FIELD_LEN]; + char hostnqn[NVMF_NQN_FIELD_LEN]; + char resv5[256]; + }; + +**Members** + + + + + +.. c:type:: enum + + +**Constants** + +``NVME_SCT_GENERIC`` + *undescribed* + +``NVME_SCT_CMD_SPECIFIC`` + *undescribed* + +``NVME_SCT_MEDIA`` + *undescribed* + +``NVME_SCT_PATH`` + *undescribed* + +``NVME_SCT_VS`` + *undescribed* + +``NVME_SCT_MASK`` + *undescribed* + +``NVME_SC_SUCCESS`` + *undescribed* + +``NVME_SC_INVALID_OPCODE`` + *undescribed* + +``NVME_SC_INVALID_FIELD`` + *undescribed* + +``NVME_SC_CMDID_CONFLICT`` + *undescribed* + +``NVME_SC_DATA_XFER_ERROR`` + *undescribed* + +``NVME_SC_POWER_LOSS`` + *undescribed* + +``NVME_SC_INTERNAL`` + *undescribed* + +``NVME_SC_ABORT_REQ`` + *undescribed* + +``NVME_SC_ABORT_QUEUE`` + *undescribed* + +``NVME_SC_FUSED_FAIL`` + *undescribed* + +``NVME_SC_FUSED_MISSING`` + *undescribed* + +``NVME_SC_INVALID_NS`` + *undescribed* + +``NVME_SC_CMD_SEQ_ERROR`` + *undescribed* + +``NVME_SC_SGL_INVALID_LAST`` + *undescribed* + +``NVME_SC_SGL_INVALID_COUNT`` + *undescribed* + +``NVME_SC_SGL_INVALID_DATA`` + *undescribed* + +``NVME_SC_SGL_INVALID_METADATA`` + *undescribed* + +``NVME_SC_SGL_INVALID_TYPE`` + *undescribed* + +``NVME_SC_CMB_INVALID_USE`` + *undescribed* + +``NVME_SC_PRP_INVALID_OFFSET`` + *undescribed* + +``NVME_SC_AWU_EXCEEDED`` + *undescribed* + +``NVME_SC_OP_DENIED`` + *undescribed* + +``NVME_SC_SGL_INVALID_OFFSET`` + *undescribed* + +``NVME_SC_HOSTID_FORMAT`` + *undescribed* + +``NVME_SC_KAT_EXPIRED`` + *undescribed* + +``NVME_SC_KAT_INVALID`` + *undescribed* + +``NVME_SC_CMD_ABORTED_PREMEPT`` + *undescribed* + +``NVME_SC_SANITIZE_FAILED`` + *undescribed* + +``NVME_SC_SANITIZE_IN_PROGRESS`` + *undescribed* + +``NVME_SC_SGL_INVALID_GRANULARITY`` + *undescribed* + +``NVME_SC_CMD_IN_CMBQ_NOT_SUPP`` + *undescribed* + +``NVME_SC_NS_WRITE_PROTECTED`` + *undescribed* + +``NVME_SC_CMD_INTERRUPTED`` + *undescribed* + +``NVME_SC_TRAN_TPORT_ERROR`` + *undescribed* + +``NVME_SC_LBA_RANGE`` + *undescribed* + +``NVME_SC_CAP_EXCEEDED`` + *undescribed* + +``NVME_SC_NS_NOT_READY`` + *undescribed* + +``NVME_SC_RESERVATION_CONFLICT`` + *undescribed* + +``NVME_SC_FORMAT_IN_PROGRESS`` + *undescribed* + +``NVME_SC_CQ_INVALID`` + *undescribed* + +``NVME_SC_QID_INVALID`` + *undescribed* + +``NVME_SC_QUEUE_SIZE`` + *undescribed* + +``NVME_SC_ABORT_LIMIT`` + *undescribed* + +``NVME_SC_ABORT_MISSING`` + *undescribed* + +``NVME_SC_ASYNC_LIMIT`` + *undescribed* + +``NVME_SC_FIRMWARE_SLOT`` + *undescribed* + +``NVME_SC_FIRMWARE_IMAGE`` + *undescribed* + +``NVME_SC_INVALID_VECTOR`` + *undescribed* + +``NVME_SC_INVALID_LOG_PAGE`` + *undescribed* + +``NVME_SC_INVALID_FORMAT`` + *undescribed* + +``NVME_SC_FW_NEEDS_CONV_RESET`` + *undescribed* + +``NVME_SC_INVALID_QUEUE`` + *undescribed* + +``NVME_SC_FEATURE_NOT_SAVEABLE`` + *undescribed* + +``NVME_SC_FEATURE_NOT_CHANGEABLE`` + *undescribed* + +``NVME_SC_FEATURE_NOT_PER_NS`` + *undescribed* + +``NVME_SC_FW_NEEDS_SUBSYS_RESET`` + *undescribed* + +``NVME_SC_FW_NEEDS_RESET`` + *undescribed* + +``NVME_SC_FW_NEEDS_MAX_TIME`` + *undescribed* + +``NVME_SC_FW_ACTIVATE_PROHIBITED`` + *undescribed* + +``NVME_SC_OVERLAPPING_RANGE`` + *undescribed* + +``NVME_SC_NS_INSUFFICIENT_CAP`` + *undescribed* + +``NVME_SC_NS_ID_UNAVAILABLE`` + *undescribed* + +``NVME_SC_NS_ALREADY_ATTACHED`` + *undescribed* + +``NVME_SC_NS_IS_PRIVATE`` + *undescribed* + +``NVME_SC_NS_NOT_ATTACHED`` + *undescribed* + +``NVME_SC_THIN_PROV_NOT_SUPP`` + *undescribed* + +``NVME_SC_CTRL_LIST_INVALID`` + *undescribed* + +``NVME_SC_SELF_TEST_IN_PROGRESS`` + *undescribed* + +``NVME_SC_BP_WRITE_PROHIBITED`` + *undescribed* + +``NVME_SC_INVALID_CTRL_ID`` + *undescribed* + +``NVME_SC_INVALID_SEC_CTRL_STATE`` + *undescribed* + +``NVME_SC_INVALID_CTRL_RESOURCES`` + *undescribed* + +``NVME_SC_INVALID_RESOURCE_ID`` + *undescribed* + +``NVME_SC_PMR_SAN_PROHIBITED`` + *undescribed* + +``NVME_SC_ANA_GROUP_ID_INVALID`` + *undescribed* + +``NVME_SC_ANA_ATTACH_FAILED`` + *undescribed* + +``NVME_SC_BAD_ATTRIBUTES`` + *undescribed* + +``NVME_SC_INVALID_PI`` + *undescribed* + +``NVME_SC_READ_ONLY`` + *undescribed* + +``NVME_SC_CONNECT_FORMAT`` + *undescribed* + +``NVME_SC_CONNECT_CTRL_BUSY`` + *undescribed* + +``NVME_SC_CONNECT_INVALID_PARAM`` + *undescribed* + +``NVME_SC_CONNECT_RESTART_DISC`` + *undescribed* + +``NVME_SC_CONNECT_INVALID_HOST`` + *undescribed* + +``NVME_SC_DISCONNECT_INVALID_QTYPE`` + *undescribed* + +``NVME_SC_DISCOVERY_RESTART`` + *undescribed* + +``NVME_SC_AUTH_REQUIRED`` + *undescribed* + +``NVME_SC_WRITE_FAULT`` + *undescribed* + +``NVME_SC_READ_ERROR`` + *undescribed* + +``NVME_SC_GUARD_CHECK`` + *undescribed* + +``NVME_SC_APPTAG_CHECK`` + *undescribed* + +``NVME_SC_REFTAG_CHECK`` + *undescribed* + +``NVME_SC_COMPARE_FAILED`` + *undescribed* + +``NVME_SC_ACCESS_DENIED`` + *undescribed* + +``NVME_SC_UNWRITTEN_BLOCK`` + *undescribed* + +``NVME_SC_ANA_INTERNAL_PATH_ERROR`` + *undescribed* + +``NVME_SC_ANA_PERSISTENT_LOSS`` + *undescribed* + +``NVME_SC_ANA_INACCESSIBLE`` + *undescribed* + +``NVME_SC_ANA_TRANSITION`` + *undescribed* + +``NVME_SC_CTRL_PATH_ERROR`` + *undescribed* + +``NVME_SC_HOST_PATH_ERROR`` + *undescribed* + +``NVME_SC_CMD_ABORTED_BY_HOST`` + *undescribed* + +``NVME_SC_MASK`` + *undescribed* + +``NVME_SC_CRD`` + *undescribed* + +``NVME_SC_MORE`` + *undescribed* + +``NVME_SC_DNR`` + *undescribed* + + +.. c:function:: __u8 nvme_status_type (__u16 status) + + Returns SCT(Status Code Type) in status field of the completion queue entry. + +**Parameters** + +``__u16 status`` + return value from nvme passthrough commands, which is the nvme + status field, located at DW3 in completion queue entry + + +.. c:function:: const char * nvme_status_to_string (int status, bool fabrics) + + +**Parameters** + +``int status`` + *undescribed* + +``bool fabrics`` + *undescribed* + + +.. c:function:: int nvme_fw_download_seq (int fd, __u32 size, __u32 xfer, __u32 offset, void * buf) + + +**Parameters** + +``int fd`` + *undescribed* + +``__u32 size`` + *undescribed* + +``__u32 xfer`` + *undescribed* + +``__u32 offset`` + *undescribed* + +``void * buf`` + *undescribed* + + +.. c:function:: int nvme_get_telemetry_log (int fd, bool create, bool ctrl, int data_area, void ** buf, __u32 * log_size) + + +**Parameters** + +``int fd`` + *undescribed* + +``bool create`` + *undescribed* + +``bool ctrl`` + *undescribed* + +``int data_area`` + *undescribed* + +``void ** buf`` + *undescribed* + +``__u32 * log_size`` + *undescribed* + + +.. c:function:: void nvme_setup_id_ns (struct nvme_id_ns * ns, __u64 nsze, __u64 ncap, __u8 flbas, __u8 dps, __u8 nmic, __u32 anagrpid, __u16 nvmsetid) + + +**Parameters** + +``struct nvme_id_ns * ns`` + *undescribed* + +``__u64 nsze`` + *undescribed* + +``__u64 ncap`` + *undescribed* + +``__u8 flbas`` + *undescribed* + +``__u8 dps`` + *undescribed* + +``__u8 nmic`` + *undescribed* + +``__u32 anagrpid`` + *undescribed* + +``__u16 nvmsetid`` + *undescribed* + + +.. c:function:: void nvme_setup_ctrl_list (struct nvme_ctrl_list * cntlist, __u16 num_ctrls, __u16 * ctrlist) + + +**Parameters** + +``struct nvme_ctrl_list * cntlist`` + *undescribed* + +``__u16 num_ctrls`` + *undescribed* + +``__u16 * ctrlist`` + *undescribed* + + +.. c:function:: void nvme_setup_dsm_range (struct nvme_dsm_range * dsm, __u32 * ctx_attrs, __u32 * llbas, __u64 * slbas, __u16 nr_ranges) + + Constructs a data set range structure + +**Parameters** + +``struct nvme_dsm_range * dsm`` + DSM range array + +``__u32 * ctx_attrs`` + Array of context attributes + +``__u32 * llbas`` + Array of length in logical blocks + +``__u64 * slbas`` + Array of starting logical blocks + +``__u16 nr_ranges`` + The size of the dsm arrays + +**Description** + +Each array must be the same size of size 'nr_ranges'. + +**Return** + +The nvme command status if a response was received or -errno + otherwise. + + +.. c:function:: int __nvme_get_log_page (int fd, __u32 nsid, __u8 log_id, bool rae, __u32 xfer_len, __u32 data_len, void * data) + + +**Parameters** + +``int fd`` + *undescribed* + +``__u32 nsid`` + *undescribed* + +``__u8 log_id`` + *undescribed* + +``bool rae`` + *undescribed* + +``__u32 xfer_len`` + Max partial log transfer size to request while splitting + +``__u32 data_len`` + *undescribed* + +``void * data`` + *undescribed* + + +.. c:function:: int nvme_get_log_page (int fd, __u32 nsid, __u8 log_id, bool rae, __u32 data_len, void * data) + + +**Parameters** + +``int fd`` + *undescribed* + +``__u32 nsid`` + *undescribed* + +``__u8 log_id`` + *undescribed* + +``bool rae`` + *undescribed* + +``__u32 data_len`` + *undescribed* + +``void * data`` + +**Description** + +Calls __nvme_get_log_page() with a default 4k transfer length. + + +.. c:function:: int nvme_get_ana_log_len (int fd, size_t * analen) + + +**Parameters** + +``int fd`` + *undescribed* + +``size_t * analen`` + *undescribed* + + +.. c:function:: int nvme_namespace_attach_ctrls (int fd, __u32 nsid, __u16 num_ctrls, __u16 * ctrlist) + + Attach namespace to controller(s) + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace ID to attach + +``__u16 num_ctrls`` + Number of controllers in ctrlist + +``__u16 * ctrlist`` + List of controller IDs to perform the attach action + +**Return** + +The nvme command status if a response was received or -errno + otherwise. + + +.. c:function:: int nvme_namespace_detach_ctrls (int fd, __u32 nsid, __u16 num_ctrls, __u16 * ctrlist) + + Detach namespace from controller(s) + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace ID to detach + +``__u16 num_ctrls`` + Number of controllers in ctrlist + +``__u16 * ctrlist`` + List of controller IDs to perform the detach action + +**Return** + +The nvme command status if a response was received or -errno + otherwise. + + +.. c:function:: int nvme_get_feature_length (int fid, __u32 cdw11, __u32 * len) + + +**Parameters** + +``int fid`` + *undescribed* + +``__u32 cdw11`` + *undescribed* + +``__u32 * len`` + *undescribed* + + +.. c:function:: int nvme_get_directive_receive_length (__u8 dtype, __u8 doper, __u32 * len) + + +**Parameters** + +``__u8 dtype`` + *undescribed* + +``__u8 doper`` + *undescribed* + +``__u32 * len`` + *undescribed* + + +.. c:function:: int nvme_open (const char * name) + + Open an nvme controller or namespace device + +**Parameters** + +``const char * name`` + The basename of the device to open + +**Description** + +This will look for the handle in /dev/ and validate the name and filetype +match linux conventions. + +**Return** + +A file descriptor for the device on a successful open, or -1 with + errno set otherwise. + + diff --git a/doc/make.bat b/doc/make.bat new file mode 100644 index 0000000000..2119f51099 --- /dev/null +++ b/doc/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/src/nvme/cmd.h b/src/nvme/cmd.h index 90abc628be..bdbff39140 100644 --- a/src/nvme/cmd.h +++ b/src/nvme/cmd.h @@ -103,24 +103,24 @@ enum nvme_identify_cns { /** * enum nvme_cmd_get_log_lid - - * NVME_LOG_LID_ERROR: - * NVME_LOG_LID_SMART: - * NVME_LOG_LID_FW_SLOT: - * NVME_LOG_LID_CHANGED_NS: - * NVME_LOG_LID_CMD_EFFECTS: - * NVME_LOG_LID_DEVICE_SELF_TEST: - * NVME_LOG_LID_TELEMETRY_HOST: - * NVME_LOG_LID_TELEMETRY_CTRL: - * NVME_LOG_LID_ENDURANCE_GROUP: - * NVME_LOG_LID_PREDICTABLE_LAT_NVMSET: - * NVME_LOG_LID_PREDICTABLE_LAT_AGG: - * NVME_LOG_LID_ANA: - * NVME_LOG_LID_PERSISTENT_EVENT: - * NVME_LOG_LID_LBA_STATUS: - * NVME_LOG_LID_ENDURANCE_GRP_EVT: - * NVME_LOG_LID_DISCOVER: - * NVME_LOG_LID_RESERVATION: - * NVME_LOG_LID_SANITIZE: + * @NVME_LOG_LID_ERROR: + * @NVME_LOG_LID_SMART: + * @NVME_LOG_LID_FW_SLOT: + * @NVME_LOG_LID_CHANGED_NS: + * @NVME_LOG_LID_CMD_EFFECTS: + * @NVME_LOG_LID_DEVICE_SELF_TEST: + * @NVME_LOG_LID_TELEMETRY_HOST: + * @NVME_LOG_LID_TELEMETRY_CTRL: + * @NVME_LOG_LID_ENDURANCE_GROUP: + * @NVME_LOG_LID_PREDICTABLE_LAT_NVMSET: + * @NVME_LOG_LID_PREDICTABLE_LAT_AGG: + * @NVME_LOG_LID_ANA: + * @NVME_LOG_LID_PERSISTENT_EVENT: + * @NVME_LOG_LID_LBA_STATUS: + * @NVME_LOG_LID_ENDURANCE_GRP_EVT: + * @NVME_LOG_LID_DISCOVER: + * @NVME_LOG_LID_RESERVATION: + * @NVME_LOG_LID_SANITIZE: */ enum nvme_cmd_get_log_lid { NVME_LOG_LID_ERROR = 0x01, From e4552860c82a6e415a185a22b0b4a62fdd72bd94 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 6 Feb 2020 18:37:51 -0800 Subject: [PATCH 0009/1564] tests: Remove some of the output Remove parts made redundant with the examples/display programs. Signed-off-by: Keith Busch --- test/test.c | 165 +++++++++++++++++----------------------------------- 1 file changed, 54 insertions(+), 111 deletions(-) diff --git a/test/test.c b/test/test.c index 0f1bf29c82..efe4885b2a 100644 --- a/test/test.c +++ b/test/test.c @@ -1,3 +1,12 @@ +/** + * Basic libnvme test: uses scan filters, single controllers, and many admin + * command APIs for identifications, logs, and features. No verification for + * specific values are performed: the test will only report which commands + * executed were completed successfully or with an error. User inspection of + * the output woould be required to know if everything is working when the + * program exists successfully; an ungraceful exit means a bug exists + * somewhere. + */ #include #include #include @@ -27,7 +36,6 @@ static int test_ctrl(nvme_ctrl_t c) struct nvme_ana_group_desc *analog = (void *)buf; struct nvme_resv_notification_log resvnotify = { 0 }; struct nvme_sanitize_log_page sanlog = { 0 }; - struct nvme_id_uuid_list uuid = { 0 }; struct nvme_id_ns_granularity_list gran = { 0 }; struct nvme_secondary_ctrl_list sec = { 0 }; @@ -237,20 +245,15 @@ static int test_ctrl(nvme_ctrl_t c) printf(" Reservation Persistence:%x\n", result); else if (ret > 0) printf(" ERROR: Reservation Persistence:%x\n", ret); - ret = nvme_get_features_write_protect(fd, 1, sel, &result); - if (!ret) - printf(" Write Protect:%x\n", result); - else if (ret > 0) - printf(" ERROR: Write Protect:%x\n", ret); return 0; } static int test_namespace(nvme_ns_t n) { + int ret, nsid = nvme_ns_get_nsid(n), fd = nvme_ns_get_fd(n); struct nvme_id_ns ns = { 0 }, allocated = { 0 }; - int nsid = nvme_ns_get_nsid(n); - int ret, fd = nvme_ns_get_fd(n); struct nvme_ns_id_desc descs = { 0 }; + __u32 result = 0; ret = nvme_ns_identify(n, &ns); if (ret) @@ -269,6 +272,12 @@ static int test_namespace(nvme_ns_t n) printf(" Identify NS Descriptorss\n"); else printf(" ERROR: Identify NS Descriptors:%x\n", ret); + ret = nvme_get_features_write_protect(fd, nsid, + NVME_GET_FEATURES_SEL_CURRENT, &result); + if (!ret) + printf(" Write Protect:%x\n", result); + else if (ret > 0) + printf(" ERROR: Write Protect:%x\n", ret); return 0; } @@ -280,6 +289,33 @@ int main() nvme_path_t p; nvme_ns_t n; + printf("Test filter for common loop back target\n"); + nqn_match = "testnqn"; + r = nvme_scan_filter(nvme_match_subsysnqn_filter); + nvme_for_each_subsystem(r, s) { + printf("%s - NQN=%s\n", nvme_subsystem_get_name(s), + nvme_subsystem_get_nqn(s)); + nvme_subsystem_for_each_ctrl(s, c) { + printf(" %s %s %s %s\n", nvme_ctrl_get_name(c), + nvme_ctrl_get_transport(c), + nvme_ctrl_get_address(c), + nvme_ctrl_get_state(c)); + } + } + printf("\n"); + nvme_free_tree(r); + + printf("Test scan specific controller\n"); + c = nvme_scan_ctrl("nvme4"); + if (c) { + printf("%s %s %s %s\n", nvme_ctrl_get_name(c), + nvme_ctrl_get_transport(c), + nvme_ctrl_get_address(c), + nvme_ctrl_get_state(c)); + nvme_free_ctrl(c); + } + printf("\n"); + r = nvme_scan(); if (!r) return -1; @@ -289,138 +325,45 @@ int main() printf("%s - NQN=%s\n", nvme_subsystem_get_name(s), nvme_subsystem_get_nqn(s)); nvme_subsystem_for_each_ctrl(s, c) { - printf(" +- %s %s %s %s\n", nvme_ctrl_get_name(c), + printf(" `- %s %s %s %s\n", nvme_ctrl_get_name(c), nvme_ctrl_get_transport(c), nvme_ctrl_get_address(c), nvme_ctrl_get_state(c)); nvme_ctrl_for_each_ns(c, n) - printf(" +- %s lba size:%d lba max:%lu\n", + printf(" `- %s lba size:%d lba max:%lu\n", nvme_ns_get_name(n), nvme_ns_get_lba_size(n), nvme_ns_get_lba_count(n)); nvme_ctrl_for_each_path(c, p) - printf(" +- %s %s\n", nvme_path_get_name(p), + printf(" `- %s %s\n", nvme_path_get_name(p), nvme_path_get_ana_state(p)); } nvme_subsystem_for_each_ns(s, n) { - printf(" +- %s lba size:%d lba max:%lu\n", + printf(" `- %s lba size:%d lba max:%lu\n", nvme_ns_get_name(n), nvme_ns_get_lba_size(n), nvme_ns_get_lba_count(n)); } } printf("\n"); - nvme_for_each_subsystem(r, s) { - bool first = true; - printf("%s %s ", nvme_subsystem_get_name(s), - nvme_subsystem_get_nqn(s)); - - nvme_subsystem_for_each_ctrl(s, c) { - printf("%s%s", first ? "": ", ", nvme_ctrl_get_name(c)); - first = false; - } - printf("\n"); - } - printf("\n"); - - nvme_for_each_subsystem(r, s) { - nvme_subsystem_for_each_ctrl(s, c) { - bool first = true; - - printf("%s %s %s %s %s %s %s ", nvme_ctrl_get_name(c), - nvme_ctrl_get_serial(c), nvme_ctrl_get_model(c), - nvme_ctrl_get_firmware(c), - nvme_ctrl_get_transport(c), - nvme_ctrl_get_address(c), - nvme_subsystem_get_name(s)); - - nvme_ctrl_for_each_ns(c, n) { - printf("%s%s", first ? "": ", ", - nvme_ns_get_name(n)); - first = false; - } - - nvme_ctrl_for_each_path(c, p) { - printf("%s%s", first ? "": ", ", - nvme_ns_get_name(nvme_path_get_ns(p))); - first = false; - } - printf("\n"); - } - } - printf("\n"); - - nvme_for_each_subsystem(r, s) { - nvme_subsystem_for_each_ctrl(s, c) - nvme_ctrl_for_each_ns(c, n) - printf("%s %d %lu/%lu %d %s\n", - nvme_ns_get_name(n), - nvme_ns_get_nsid(n), - nvme_ns_get_lba_count(n), - nvme_ns_get_lba_util(n), - nvme_ns_get_lba_size(n), - nvme_ctrl_get_name(c)); - - nvme_subsystem_for_each_ns(s, n) { - bool first = true; - - printf("%s %d %lu/%lu %d ", nvme_ns_get_name(n), - nvme_ns_get_nsid(n), - nvme_ns_get_lba_count(n), - nvme_ns_get_lba_util(n), - nvme_ns_get_lba_size(n)); - nvme_subsystem_for_each_ctrl(s, c) { - printf("%s%s", first ? "" : ", ", - nvme_ctrl_get_name(c)); - first = false; - } - printf("\n"); - } - } - printf("\n"); - printf("Test identification, logs, and features\n"); nvme_for_each_subsystem(r, s) { nvme_subsystem_for_each_ctrl(s, c) { test_ctrl(c); - nvme_ctrl_for_each_ns(c, n) - test_namespace(n); printf("\n"); + nvme_ctrl_for_each_ns(c, n) { + test_namespace(n); + printf("\n"); + } } - nvme_subsystem_for_each_ns(s, n) + nvme_subsystem_for_each_ns(s, n) { test_namespace(n); - } - printf("\n"); - - nvme_free_tree(r); - - printf("Test filter for common loop back target\n"); - nqn_match = "testnqn"; - r = nvme_scan_filter(nvme_match_subsysnqn_filter); - nvme_for_each_subsystem(r, s) { - printf("%s - NQN=%s\n", nvme_subsystem_get_name(s), - nvme_subsystem_get_nqn(s)); - nvme_subsystem_for_each_ctrl(s, c) { - printf(" `- %s %s %s %s\n", nvme_ctrl_get_name(c), - nvme_ctrl_get_transport(c), - nvme_ctrl_get_address(c), - nvme_ctrl_get_state(c)); + printf("\n"); } } - printf("\n"); nvme_free_tree(r); - printf("Test scan specific controller\n"); - c = nvme_scan_ctrl("nvme4"); - if (c) { - printf("%s %s %s %s\n", nvme_ctrl_get_name(c), - nvme_ctrl_get_transport(c), - nvme_ctrl_get_address(c), - nvme_ctrl_get_state(c)); - nvme_free_ctrl(c); - } - return 0; } From 6edf30814b91118ca45b73ec97c6bb1e35ebe1a6 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 6 Feb 2020 19:55:01 -0800 Subject: [PATCH 0010/1564] Add license information Added LGPL licence via: wget https://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt -O COPYING Signed-off-by: Keith Busch --- COPYING | 502 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 502 insertions(+) create mode 100644 COPYING diff --git a/COPYING b/COPYING new file mode 100644 index 0000000000..4362b49151 --- /dev/null +++ b/COPYING @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! From e6b0b6cceba2d431290e2e99c5c7e69eccbf8cdd Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 6 Feb 2020 20:08:39 -0800 Subject: [PATCH 0011/1564] Add README Signed-off-by: Keith Busch --- README | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 README diff --git a/README b/README new file mode 100644 index 0000000000..e54c8e8bd8 --- /dev/null +++ b/README @@ -0,0 +1,26 @@ +libnvme +------- + +This is the libnvme development C library. libnvme provides type +defintions for NVMe specification structures, enumerations, and bit +fields, helper functions to construct, dispatch, and decode commands +and payloads, and utilities to connect, scan, and manage nvme devices +on a Linux system. + +The public specification is the authority to resolve any protocol +discrepencies with this library. For more info on NVM Express, please see: + + http://nvmexpress.org + +Subscribe to linux-nvme@lists.infradead.org for linux-nvme related discussions +and development for both kernel and userspace. The list is archived here: + + http://lists.infradead.org/mailman/listinfo/linux-nvme + +License +------- + +All software contained within this repo is currently licensed LGPL, see +COPYING for more information. + +Keith Busch 2020-02-06 From e6d40ab68109481a918f3bec6b83cd7e1fa70b53 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 6 Feb 2020 20:26:06 -0800 Subject: [PATCH 0012/1564] util: Fix default log transfer length typo Transfer lengths are 4k, not 4086 bytes. Signed-off-by: Keith Busch --- src/nvme/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nvme/util.c b/src/nvme/util.c index 6234ea0e65..da70c9aa3a 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -263,7 +263,7 @@ int __nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, __u32 data_len, void *data) { - return __nvme_get_log_page(fd, nsid, log_id, rae, 4086, data_len, data); + return __nvme_get_log_page(fd, nsid, log_id, rae, 4096, data_len, data); } int nvme_get_telemetry_log(int fd, bool create, bool ctrl, int data_area, From bb769b52be9a2496230d4d64a798090ac74d622c Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 6 Feb 2020 20:30:03 -0800 Subject: [PATCH 0013/1564] tests: Fix fw log check Had the return check inverted (0 is success). Signed-off-by: Keith Busch --- test/test.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/test/test.c b/test/test.c index efe4885b2a..64a7febe28 100644 --- a/test/test.c +++ b/test/test.c @@ -118,47 +118,47 @@ static int test_ctrl(nvme_ctrl_t c) if (!ret) printf(" Reservation Log\n"); else - printf(" ERROR: Reservation Log :%x\n", ret); + printf(" ERROR: Reservation Log:%x\n", ret); ret = nvme_get_log_ana_groups(fd, true, sizeof(buf), analog); if (!ret) printf(" ANA Groups\n"); else - printf(" ERROR: ANA Groups :%x\n", ret); + printf(" ERROR: ANA Groups:%x\n", ret); ret = nvme_get_log_endurance_group(fd, 0, &eglog); if (!ret) printf(" Endurance Group\n"); else - printf(" ERROR: Endurance Group :%x\n", ret); + printf(" ERROR: Endurance Group:%x\n", ret); ret = nvme_get_log_telemetry_ctrl(fd, true, 0, sizeof(buf), telem); if (!ret) printf(" Telemetry Controller\n"); else - printf(" ERROR: Telemetry Controller :%x\n", ret); + printf(" ERROR: Telemetry Controller:%x\n", ret); ret = nvme_get_log_device_self_test(fd, &st); if (!ret) printf(" Device Self Test\n"); else - printf(" ERROR: Device Self Test :%x\n", ret); + printf(" ERROR: Device Self Test:%x\n", ret); ret = nvme_get_log_cmd_effects(fd, &cfx); if (!ret) printf(" Command Effects\n"); else - printf(" ERROR: Command Effects :%x\n", ret); + printf(" ERROR: Command Effects:%x\n", ret); ret = nvme_get_log_changed_ns_list(fd, true, &ns_list); if (!ret) printf(" Change NS List\n"); else - printf(" ERROR: Change NS List :%x\n", ret); + printf(" ERROR: Change NS List:%x\n", ret); ret = nvme_get_log_fw_slot(fd, true, &fw); - if (ret) + if (!ret) printf(" FW Slot\n"); else - printf(" ERROR: FW Slot :%x\n", ret); + printf(" ERROR: FW Slot%x\n", ret); ret = nvme_get_log_error(fd, 64, true, error); if (!ret) printf(" Error Log\n"); else - printf(" ERROR: Error Log :%x\n", ret); + printf(" ERROR: Error Log:%x\n", ret); printf("\nFeatures\n"); ret = nvme_get_features_arbitration(fd, sel, &result); if (!ret) From ec3b136123110dbb5663aaa940b5bdbac7de1c5a Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Fri, 7 Feb 2020 16:32:35 -0800 Subject: [PATCH 0014/1564] Import ccan modules Replace list implementation with the superior ccan list. This is a more pleasant C implementation to work with, and since we the structures using this are not exported through the API, we can freely change these kinds of implementation details. And while we're at it, include a few other useful modules to provide useful macros and compile time checks on spec defined structs. Signed-off-by: Keith Busch --- src/Makefile | 48 +- src/ccan/ccan/array_size/LICENSE | 1 + src/ccan/ccan/array_size/_info | 46 ++ src/ccan/ccan/array_size/array_size.h | 26 + src/ccan/ccan/build_assert/LICENSE | 1 + src/ccan/ccan/build_assert/_info | 49 ++ src/ccan/ccan/build_assert/build_assert.h | 40 + src/ccan/ccan/check_type/LICENSE | 1 + src/ccan/ccan/check_type/_info | 33 + src/ccan/ccan/check_type/check_type.h | 64 ++ src/ccan/ccan/container_of/LICENSE | 1 + src/ccan/ccan/container_of/_info | 65 ++ src/ccan/ccan/container_of/container_of.h | 145 ++++ src/ccan/ccan/endian/LICENSE | 1 + src/ccan/ccan/endian/_info | 55 ++ src/ccan/ccan/endian/endian.h | 363 +++++++++ src/ccan/ccan/list/LICENSE | 1 + src/ccan/ccan/list/_info | 72 ++ src/ccan/ccan/list/list.c | 43 ++ src/ccan/ccan/list/list.h | 842 +++++++++++++++++++++ src/ccan/ccan/minmax/LICENSE | 1 + src/ccan/ccan/minmax/_info | 48 ++ src/ccan/ccan/minmax/minmax.h | 65 ++ src/ccan/ccan/short_types/LICENSE | 1 + src/ccan/ccan/short_types/short_types.h | 35 + src/ccan/ccan/str/LICENSE | 1 + src/ccan/ccan/str/_info | 52 ++ src/ccan/ccan/str/debug.c | 108 +++ src/ccan/ccan/str/str.c | 13 + src/ccan/ccan/str/str.h | 228 ++++++ src/ccan/ccan/str/str_debug.h | 30 + src/ccan/licenses/BSD-MIT | 17 + src/ccan/licenses/CC0 | 28 + src/ccan/tools/configurator/configurator.c | 563 ++++++++++++++ src/licenses/BSD-MIT | 17 + src/licenses/CC0 | 28 + src/nvme/fabrics.c | 3 +- src/nvme/filters.c | 2 - src/nvme/filters.h | 31 + src/nvme/ioctl.c | 21 + src/nvme/ioctl.h | 3 +- src/nvme/private.h | 28 +- src/nvme/tree.c | 89 +-- src/nvme/tree.h | 229 +++++- src/nvme/types.h | 42 +- src/nvme/util.c | 12 +- src/nvme/util.h | 85 ++- 47 files changed, 3548 insertions(+), 129 deletions(-) create mode 120000 src/ccan/ccan/array_size/LICENSE create mode 100644 src/ccan/ccan/array_size/_info create mode 100644 src/ccan/ccan/array_size/array_size.h create mode 120000 src/ccan/ccan/build_assert/LICENSE create mode 100644 src/ccan/ccan/build_assert/_info create mode 100644 src/ccan/ccan/build_assert/build_assert.h create mode 120000 src/ccan/ccan/check_type/LICENSE create mode 100644 src/ccan/ccan/check_type/_info create mode 100644 src/ccan/ccan/check_type/check_type.h create mode 120000 src/ccan/ccan/container_of/LICENSE create mode 100644 src/ccan/ccan/container_of/_info create mode 100644 src/ccan/ccan/container_of/container_of.h create mode 120000 src/ccan/ccan/endian/LICENSE create mode 100644 src/ccan/ccan/endian/_info create mode 100644 src/ccan/ccan/endian/endian.h create mode 120000 src/ccan/ccan/list/LICENSE create mode 100644 src/ccan/ccan/list/_info create mode 100644 src/ccan/ccan/list/list.c create mode 100644 src/ccan/ccan/list/list.h create mode 120000 src/ccan/ccan/minmax/LICENSE create mode 100644 src/ccan/ccan/minmax/_info create mode 100644 src/ccan/ccan/minmax/minmax.h create mode 120000 src/ccan/ccan/short_types/LICENSE create mode 100644 src/ccan/ccan/short_types/short_types.h create mode 120000 src/ccan/ccan/str/LICENSE create mode 100644 src/ccan/ccan/str/_info create mode 100644 src/ccan/ccan/str/debug.c create mode 100644 src/ccan/ccan/str/str.c create mode 100644 src/ccan/ccan/str/str.h create mode 100644 src/ccan/ccan/str/str_debug.h create mode 100644 src/ccan/licenses/BSD-MIT create mode 100644 src/ccan/licenses/CC0 create mode 100644 src/ccan/tools/configurator/configurator.c create mode 100644 src/licenses/BSD-MIT create mode 100644 src/licenses/CC0 diff --git a/src/Makefile b/src/Makefile index 6b5847480e..35fa88555b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -6,7 +6,9 @@ prefix ?= /usr includedir ?= $(prefix)/include libdir ?= $(prefix)/lib -CFLAGS ?= -g -fomit-frame-pointer -O2 -I/usr/include -Invme/ +CCANDIR=ccan/ + +CFLAGS ?= -g -fomit-frame-pointer -O2 -I/usr/include -Invme/ -I$(CCANDIR) override CFLAGS += -Wall -fPIC SO_CFLAGS=-shared $(CFLAGS) L_CFLAGS=$(CFLAGS) @@ -37,22 +39,27 @@ ifeq ($(ENABLE_SHARED),1) all_targets += $(libname) endif -ifneq ($(findstring $(MAKEFLAGS),s),s) -ifndef V - QUIET_CC = @echo ' ' CC $@; - QUIET_LINK = @echo ' ' LINK $@; - QUIET_AR = @echo ' ' AR $@; - QUIET_RANLIB = @echo '' RANLIB $@; -endif -endif +include ../Makefile.quiet all: $(all_targets) +$(CCANDIR)config.h: $(CCANDIR)tools/configurator/configurator + $< > $@ + +libccan_headers := $(wildcard $(CCANDIR)ccan/*/*.h) +libccan_srcs := $(wildcard $(CCANDIR)ccan/*/*.c) +libccan_objs := $(patsubst %.c,%.ol,$(libccan_srcs)) +libccan_sobjs := $(patsubst %.c,%.os,$(libccan_srcs)) + +$(libccan_objs) $(libccan_sobjs): $(libccan_headers) + +libnvme_priv := nvme/private.h +libnvme_api := libnvme.h nvme/types.h nvme/ioctl.h nvme/filters.h nvme/tree.h nvme/util.h nvme/cmd.h libnvme_srcs := nvme/ioctl.c nvme/filters.c nvme/fabrics.c nvme/util.c nvme/tree.c libnvme_objs := $(patsubst %.c,%.ol,$(libnvme_srcs)) libnvme_sobjs := $(patsubst %.c,%.os,$(libnvme_srcs)) -$(libnvme_objs) $(libnvme_sobjs): libnvme.h nvme/types.h nvme/ioctl.h nvme/filters.h nvme/tree.h nvme/util.h nvme/cmd.h +$(libnvme_objs) $(libnvme_sobjs): $(libnvme_api) $(libnvme_private) $(libccan_objs) %.os: %.c $(QUIET_CC)$(CC) $(SO_CFLAGS) -c -o $@ $< @@ -62,20 +69,18 @@ $(libnvme_objs) $(libnvme_sobjs): libnvme.h nvme/types.h nvme/ioctl.h nvme/filte AR ?= ar RANLIB ?= ranlib -libnvme.a: $(libnvme_objs) +libnvme.a: $(libnvme_objs) $(libccan_objs) @rm -f libnvme.a $(QUIET_AR)$(AR) r libnvme.a $^ $(QUIET_RANLIB)$(RANLIB) libnvme.a -$(libname): $(libnvme_sobjs) libnvme.map - $(QUIET_CC)$(CC) $(SO_CFLAGS) -Wl,--version-script=libnvme.map -Wl,-soname=$(soname) -o $@ $(libnvme_sobjs) $(LINK_FLAGS) +$(libname): $(libnvme_sobjs) $(libccan_sobjs) libnvme.map + $(QUIET_CC)$(CC) $(SO_CFLAGS) -Wl,--version-script=libnvme.map -Wl,-soname=$(soname) -o $@ $(libnvme_sobjs) $(libccan_sobjs) $(LINK_FLAGS) install: $(all_targets) $(NAME).pc - $(INSTALL) -D -m 644 nvme/types.h $(includedir)/nvme/types.h - $(INSTALL) -D -m 644 nvme/ioctl.h $(includedir)/nvme/ioctl.h - $(INSTALL) -D -m 644 nvme/fabrics.h $(includedir)/nvme/fabrics.h - $(INSTALL) -D -m 644 nvme/filters.h $(includedir)/nvme/filters.h - $(INSTALL) -D -m 644 libnvme.h $(includedir)/libnvme.h + for i in $(libnvme_api); do \ + $(INSTALL) -D -m 644 ${i} $(includedir)/${i} + done $(INSTALL) -D -m 644 libnvme.a $(libdir)/libnvme.a $(INSTALL) -D -m 644 $(NAME).pc $(DESTDIR)$(libdir)/pkgconfig/$(NAME).pc ifeq ($(ENABLE_SHARED),1) @@ -84,8 +89,11 @@ ifeq ($(ENABLE_SHARED),1) ln -sf $(libname) $(libdir)/libnvme.so endif -$(libnvme_objs): libnvme.h +$(libnvme_objs): $(libnvme_api) $(libnvme_private) +$(libccan_objs): $(libccan_headers) $(CCANDIR)config.h clean: - rm -f $(all_targets) $(libnvme_objs) $(libnvme_sobjs) $(soname).new $(NAME).pc + rm -f $(all_targets) $(libnvme_objs) $(libnvme_sobjs) $(libccan_objs) $(libccan_sobjs) $(soname).new $(NAME).pc + rm -f $(CCANDIR)config.h + rm -f $(CCANDIR)tools/configurator/configurator rm -f *.so* *.a *.o diff --git a/src/ccan/ccan/array_size/LICENSE b/src/ccan/ccan/array_size/LICENSE new file mode 120000 index 0000000000..b7951dabdc --- /dev/null +++ b/src/ccan/ccan/array_size/LICENSE @@ -0,0 +1 @@ +../../licenses/CC0 \ No newline at end of file diff --git a/src/ccan/ccan/array_size/_info b/src/ccan/ccan/array_size/_info new file mode 100644 index 0000000000..69570f34c8 --- /dev/null +++ b/src/ccan/ccan/array_size/_info @@ -0,0 +1,46 @@ +#include "config.h" +#include +#include + +/** + * array_size - routine for safely deriving the size of a visible array. + * + * This provides a simple ARRAY_SIZE() macro, which (given a good compiler) + * will also break compile if you try to use it on a pointer. + * + * This can ensure your code is robust to changes, without needing a gratuitous + * macro or constant. + * + * Example: + * // Outputs "Initialized 32 values\n" + * #include + * #include + * #include + * + * // We currently use 32 random values. + * static unsigned int vals[32]; + * + * int main(void) + * { + * unsigned int i; + * for (i = 0; i < ARRAY_SIZE(vals); i++) + * vals[i] = random(); + * printf("Initialized %u values\n", i); + * return 0; + * } + * + * License: CC0 (Public domain) + * Author: Rusty Russell + */ +int main(int argc, char *argv[]) +{ + if (argc != 2) + return 1; + + if (strcmp(argv[1], "depends") == 0) { + printf("ccan/build_assert\n"); + return 0; + } + + return 1; +} diff --git a/src/ccan/ccan/array_size/array_size.h b/src/ccan/ccan/array_size/array_size.h new file mode 100644 index 0000000000..0ca422a291 --- /dev/null +++ b/src/ccan/ccan/array_size/array_size.h @@ -0,0 +1,26 @@ +/* CC0 (Public domain) - see LICENSE file for details */ +#ifndef CCAN_ARRAY_SIZE_H +#define CCAN_ARRAY_SIZE_H +#include "config.h" +#include + +/** + * ARRAY_SIZE - get the number of elements in a visible array + * @arr: the array whose size you want. + * + * This does not work on pointers, or arrays declared as [], or + * function parameters. With correct compiler support, such usage + * will cause a build error (see build_assert). + */ +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + _array_size_chk(arr)) + +#if HAVE_BUILTIN_TYPES_COMPATIBLE_P && HAVE_TYPEOF +/* Two gcc extensions. + * &a[0] degrades to a pointer: a different type from an array */ +#define _array_size_chk(arr) \ + BUILD_ASSERT_OR_ZERO(!__builtin_types_compatible_p(typeof(arr), \ + typeof(&(arr)[0]))) +#else +#define _array_size_chk(arr) 0 +#endif +#endif /* CCAN_ALIGNOF_H */ diff --git a/src/ccan/ccan/build_assert/LICENSE b/src/ccan/ccan/build_assert/LICENSE new file mode 120000 index 0000000000..b7951dabdc --- /dev/null +++ b/src/ccan/ccan/build_assert/LICENSE @@ -0,0 +1 @@ +../../licenses/CC0 \ No newline at end of file diff --git a/src/ccan/ccan/build_assert/_info b/src/ccan/ccan/build_assert/_info new file mode 100644 index 0000000000..97ebe6c966 --- /dev/null +++ b/src/ccan/ccan/build_assert/_info @@ -0,0 +1,49 @@ +#include "config.h" +#include +#include + +/** + * build_assert - routines for build-time assertions + * + * This code provides routines which will cause compilation to fail should some + * assertion be untrue: such failures are preferable to run-time assertions, + * but much more limited since they can only depends on compile-time constants. + * + * These assertions are most useful when two parts of the code must be kept in + * sync: it is better to avoid such cases if possible, but seconds best is to + * detect invalid changes at build time. + * + * For example, a tricky piece of code might rely on a certain element being at + * the start of the structure. To ensure that future changes don't break it, + * you would catch such changes in your code like so: + * + * Example: + * #include + * #include + * + * struct foo { + * char string[5]; + * int x; + * }; + * + * static char *foo_string(struct foo *foo) + * { + * // This trick requires that the string be first in the structure + * BUILD_ASSERT(offsetof(struct foo, string) == 0); + * return (char *)foo; + * } + * + * License: CC0 (Public domain) + * Author: Rusty Russell + */ +int main(int argc, char *argv[]) +{ + if (argc != 2) + return 1; + + if (strcmp(argv[1], "depends") == 0) + /* Nothing. */ + return 0; + + return 1; +} diff --git a/src/ccan/ccan/build_assert/build_assert.h b/src/ccan/ccan/build_assert/build_assert.h new file mode 100644 index 0000000000..b9ecd84028 --- /dev/null +++ b/src/ccan/ccan/build_assert/build_assert.h @@ -0,0 +1,40 @@ +/* CC0 (Public domain) - see LICENSE file for details */ +#ifndef CCAN_BUILD_ASSERT_H +#define CCAN_BUILD_ASSERT_H + +/** + * BUILD_ASSERT - assert a build-time dependency. + * @cond: the compile-time condition which must be true. + * + * Your compile will fail if the condition isn't true, or can't be evaluated + * by the compiler. This can only be used within a function. + * + * Example: + * #include + * ... + * static char *foo_to_char(struct foo *foo) + * { + * // This code needs string to be at start of foo. + * BUILD_ASSERT(offsetof(struct foo, string) == 0); + * return (char *)foo; + * } + */ +#define BUILD_ASSERT(cond) \ + do { (void) sizeof(char [1 - 2*!(cond)]); } while(0) + +/** + * BUILD_ASSERT_OR_ZERO - assert a build-time dependency, as an expression. + * @cond: the compile-time condition which must be true. + * + * Your compile will fail if the condition isn't true, or can't be evaluated + * by the compiler. This can be used in an expression: its value is "0". + * + * Example: + * #define foo_to_char(foo) \ + * ((char *)(foo) \ + * + BUILD_ASSERT_OR_ZERO(offsetof(struct foo, string) == 0)) + */ +#define BUILD_ASSERT_OR_ZERO(cond) \ + (sizeof(char [1 - 2*!(cond)]) - 1) + +#endif /* CCAN_BUILD_ASSERT_H */ diff --git a/src/ccan/ccan/check_type/LICENSE b/src/ccan/ccan/check_type/LICENSE new file mode 120000 index 0000000000..b7951dabdc --- /dev/null +++ b/src/ccan/ccan/check_type/LICENSE @@ -0,0 +1 @@ +../../licenses/CC0 \ No newline at end of file diff --git a/src/ccan/ccan/check_type/_info b/src/ccan/ccan/check_type/_info new file mode 100644 index 0000000000..cc42673492 --- /dev/null +++ b/src/ccan/ccan/check_type/_info @@ -0,0 +1,33 @@ +#include "config.h" +#include +#include + +/** + * check_type - routines for compile time type checking + * + * C has fairly weak typing: ints get automatically converted to longs, signed + * to unsigned, etc. There are some cases where this is best avoided, and + * these macros provide methods for evoking warnings (or build errors) when + * a precise type isn't used. + * + * On compilers which don't support typeof() these routines are less effective, + * since they have to use sizeof() which can only distiguish between types of + * different size. + * + * License: CC0 (Public domain) + * Author: Rusty Russell + */ +int main(int argc, char *argv[]) +{ + if (argc != 2) + return 1; + + if (strcmp(argv[1], "depends") == 0) { +#if !HAVE_TYPEOF + printf("ccan/build_assert\n"); +#endif + return 0; + } + + return 1; +} diff --git a/src/ccan/ccan/check_type/check_type.h b/src/ccan/ccan/check_type/check_type.h new file mode 100644 index 0000000000..837aef7b1a --- /dev/null +++ b/src/ccan/ccan/check_type/check_type.h @@ -0,0 +1,64 @@ +/* CC0 (Public domain) - see LICENSE file for details */ +#ifndef CCAN_CHECK_TYPE_H +#define CCAN_CHECK_TYPE_H +#include "config.h" + +/** + * check_type - issue a warning or build failure if type is not correct. + * @expr: the expression whose type we should check (not evaluated). + * @type: the exact type we expect the expression to be. + * + * This macro is usually used within other macros to try to ensure that a macro + * argument is of the expected type. No type promotion of the expression is + * done: an unsigned int is not the same as an int! + * + * check_type() always evaluates to 0. + * + * If your compiler does not support typeof, then the best we can do is fail + * to compile if the sizes of the types are unequal (a less complete check). + * + * Example: + * // They should always pass a 64-bit value to _set_some_value! + * #define set_some_value(expr) \ + * _set_some_value((check_type((expr), uint64_t), (expr))) + */ + +/** + * check_types_match - issue a warning or build failure if types are not same. + * @expr1: the first expression (not evaluated). + * @expr2: the second expression (not evaluated). + * + * This macro is usually used within other macros to try to ensure that + * arguments are of identical types. No type promotion of the expressions is + * done: an unsigned int is not the same as an int! + * + * check_types_match() always evaluates to 0. + * + * If your compiler does not support typeof, then the best we can do is fail + * to compile if the sizes of the types are unequal (a less complete check). + * + * Example: + * // Do subtraction to get to enclosing type, but make sure that + * // pointer is of correct type for that member. + * #define container_of(mbr_ptr, encl_type, mbr) \ + * (check_types_match((mbr_ptr), &((encl_type *)0)->mbr), \ + * ((encl_type *) \ + * ((char *)(mbr_ptr) - offsetof(encl_type, mbr)))) + */ +#if HAVE_TYPEOF +#define check_type(expr, type) \ + ((typeof(expr) *)0 != (type *)0) + +#define check_types_match(expr1, expr2) \ + ((typeof(expr1) *)0 != (typeof(expr2) *)0) +#else +#include +/* Without typeof, we can only test the sizes. */ +#define check_type(expr, type) \ + BUILD_ASSERT_OR_ZERO(sizeof(expr) == sizeof(type)) + +#define check_types_match(expr1, expr2) \ + BUILD_ASSERT_OR_ZERO(sizeof(expr1) == sizeof(expr2)) +#endif /* HAVE_TYPEOF */ + +#endif /* CCAN_CHECK_TYPE_H */ diff --git a/src/ccan/ccan/container_of/LICENSE b/src/ccan/ccan/container_of/LICENSE new file mode 120000 index 0000000000..b7951dabdc --- /dev/null +++ b/src/ccan/ccan/container_of/LICENSE @@ -0,0 +1 @@ +../../licenses/CC0 \ No newline at end of file diff --git a/src/ccan/ccan/container_of/_info b/src/ccan/ccan/container_of/_info new file mode 100644 index 0000000000..b1160522ed --- /dev/null +++ b/src/ccan/ccan/container_of/_info @@ -0,0 +1,65 @@ +#include "config.h" +#include +#include + +/** + * container_of - routine for upcasting + * + * It is often convenient to create code where the caller registers a pointer + * to a generic structure and a callback. The callback might know that the + * pointer points to within a larger structure, and container_of gives a + * convenient and fairly type-safe way of returning to the enclosing structure. + * + * This idiom is an alternative to providing a void * pointer for every + * callback. + * + * Example: + * #include + * #include + * + * struct timer { + * void *members; + * }; + * + * struct info { + * int my_stuff; + * struct timer timer; + * }; + * + * static void my_timer_callback(struct timer *timer) + * { + * struct info *info = container_of(timer, struct info, timer); + * printf("my_stuff is %u\n", info->my_stuff); + * } + * + * static void register_timer(struct timer *timer) + * { + * (void)timer; + * (void)my_timer_callback; + * //... + * } + * + * int main(void) + * { + * struct info info = { .my_stuff = 1 }; + * + * register_timer(&info.timer); + * // ... + * return 0; + * } + * + * License: CC0 (Public domain) + * Author: Rusty Russell + */ +int main(int argc, char *argv[]) +{ + if (argc != 2) + return 1; + + if (strcmp(argv[1], "depends") == 0) { + printf("ccan/check_type\n"); + return 0; + } + + return 1; +} diff --git a/src/ccan/ccan/container_of/container_of.h b/src/ccan/ccan/container_of/container_of.h new file mode 100644 index 0000000000..47a34d853b --- /dev/null +++ b/src/ccan/ccan/container_of/container_of.h @@ -0,0 +1,145 @@ +/* CC0 (Public domain) - see LICENSE file for details */ +#ifndef CCAN_CONTAINER_OF_H +#define CCAN_CONTAINER_OF_H +#include + +#include "config.h" +#include + +/** + * container_of - get pointer to enclosing structure + * @member_ptr: pointer to the structure member + * @containing_type: the type this member is within + * @member: the name of this member within the structure. + * + * Given a pointer to a member of a structure, this macro does pointer + * subtraction to return the pointer to the enclosing type. + * + * Example: + * struct foo { + * int fielda, fieldb; + * // ... + * }; + * struct info { + * int some_other_field; + * struct foo my_foo; + * }; + * + * static struct info *foo_to_info(struct foo *foo) + * { + * return container_of(foo, struct info, my_foo); + * } + */ +#define container_of(member_ptr, containing_type, member) \ + ((containing_type *) \ + ((char *)(member_ptr) \ + - container_off(containing_type, member)) \ + + check_types_match(*(member_ptr), ((containing_type *)0)->member)) + + +/** + * container_of_or_null - get pointer to enclosing structure, or NULL + * @member_ptr: pointer to the structure member + * @containing_type: the type this member is within + * @member: the name of this member within the structure. + * + * Given a pointer to a member of a structure, this macro does pointer + * subtraction to return the pointer to the enclosing type, unless it + * is given NULL, in which case it also returns NULL. + * + * Example: + * struct foo { + * int fielda, fieldb; + * // ... + * }; + * struct info { + * int some_other_field; + * struct foo my_foo; + * }; + * + * static struct info *foo_to_info_allowing_null(struct foo *foo) + * { + * return container_of_or_null(foo, struct info, my_foo); + * } + */ +static inline char *container_of_or_null_(void *member_ptr, size_t offset) +{ + return member_ptr ? (char *)member_ptr - offset : NULL; +} +#define container_of_or_null(member_ptr, containing_type, member) \ + ((containing_type *) \ + container_of_or_null_(member_ptr, \ + container_off(containing_type, member)) \ + + check_types_match(*(member_ptr), ((containing_type *)0)->member)) + +/** + * container_off - get offset to enclosing structure + * @containing_type: the type this member is within + * @member: the name of this member within the structure. + * + * Given a pointer to a member of a structure, this macro does + * typechecking and figures out the offset to the enclosing type. + * + * Example: + * struct foo { + * int fielda, fieldb; + * // ... + * }; + * struct info { + * int some_other_field; + * struct foo my_foo; + * }; + * + * static struct info *foo_to_info(struct foo *foo) + * { + * size_t off = container_off(struct info, my_foo); + * return (void *)((char *)foo - off); + * } + */ +#define container_off(containing_type, member) \ + offsetof(containing_type, member) + +/** + * container_of_var - get pointer to enclosing structure using a variable + * @member_ptr: pointer to the structure member + * @container_var: a pointer of same type as this member's container + * @member: the name of this member within the structure. + * + * Given a pointer to a member of a structure, this macro does pointer + * subtraction to return the pointer to the enclosing type. + * + * Example: + * static struct info *foo_to_i(struct foo *foo) + * { + * struct info *i = container_of_var(foo, i, my_foo); + * return i; + * } + */ +#if HAVE_TYPEOF +#define container_of_var(member_ptr, container_var, member) \ + container_of(member_ptr, typeof(*container_var), member) +#else +#define container_of_var(member_ptr, container_var, member) \ + ((void *)((char *)(member_ptr) - \ + container_off_var(container_var, member))) +#endif + +/** + * container_off_var - get offset of a field in enclosing structure + * @container_var: a pointer to a container structure + * @member: the name of a member within the structure. + * + * Given (any) pointer to a structure and a its member name, this + * macro does pointer subtraction to return offset of member in a + * structure memory layout. + * + */ +#if HAVE_TYPEOF +#define container_off_var(var, member) \ + container_off(typeof(*var), member) +#else +#define container_off_var(var, member) \ + ((const char *)&(var)->member - (const char *)(var)) +#endif + +#endif /* CCAN_CONTAINER_OF_H */ diff --git a/src/ccan/ccan/endian/LICENSE b/src/ccan/ccan/endian/LICENSE new file mode 120000 index 0000000000..b7951dabdc --- /dev/null +++ b/src/ccan/ccan/endian/LICENSE @@ -0,0 +1 @@ +../../licenses/CC0 \ No newline at end of file diff --git a/src/ccan/ccan/endian/_info b/src/ccan/ccan/endian/_info new file mode 100644 index 0000000000..efe5a8bbde --- /dev/null +++ b/src/ccan/ccan/endian/_info @@ -0,0 +1,55 @@ +#include "config.h" +#include +#include + +/** + * endian - endian conversion macros for simple types + * + * Portable protocols (such as on-disk formats, or network protocols) + * are often defined to be a particular endian: little-endian (least + * significant bytes first) or big-endian (most significant bytes + * first). + * + * Similarly, some CPUs lay out values in memory in little-endian + * order (most commonly, Intel's 8086 and derivatives), or big-endian + * order (almost everyone else). + * + * This module provides conversion routines, inspired by the linux kernel. + * It also provides leint32_t, beint32_t etc typedefs, which are annotated for + * the sparse checker. + * + * Example: + * #include + * #include + * #include + * + * // + * int main(int argc, char *argv[]) + * { + * uint32_t value; + * + * if (argc != 2) + * errx(1, "Usage: %s ", argv[0]); + * + * value = atoi(argv[1]); + * printf("native: %08x\n", value); + * printf("little-endian: %08x\n", cpu_to_le32(value)); + * printf("big-endian: %08x\n", cpu_to_be32(value)); + * printf("byte-reversed: %08x\n", bswap_32(value)); + * exit(0); + * } + * + * License: License: CC0 (Public domain) + * Author: Rusty Russell + */ +int main(int argc, char *argv[]) +{ + if (argc != 2) + return 1; + + if (strcmp(argv[1], "depends") == 0) + /* Nothing */ + return 0; + + return 1; +} diff --git a/src/ccan/ccan/endian/endian.h b/src/ccan/ccan/endian/endian.h new file mode 100644 index 0000000000..3753f49003 --- /dev/null +++ b/src/ccan/ccan/endian/endian.h @@ -0,0 +1,363 @@ +/* CC0 (Public domain) - see LICENSE file for details */ +#ifndef CCAN_ENDIAN_H +#define CCAN_ENDIAN_H +#include +#include "config.h" + +/** + * BSWAP_16 - reverse bytes in a constant uint16_t value. + * @val: constant value whose bytes to swap. + * + * Designed to be usable in constant-requiring initializers. + * + * Example: + * struct mystruct { + * char buf[BSWAP_16(0x1234)]; + * }; + */ +#define BSWAP_16(val) \ + ((((uint16_t)(val) & 0x00ff) << 8) \ + | (((uint16_t)(val) & 0xff00) >> 8)) + +/** + * BSWAP_32 - reverse bytes in a constant uint32_t value. + * @val: constant value whose bytes to swap. + * + * Designed to be usable in constant-requiring initializers. + * + * Example: + * struct mystruct { + * char buf[BSWAP_32(0xff000000)]; + * }; + */ +#define BSWAP_32(val) \ + ((((uint32_t)(val) & 0x000000ff) << 24) \ + | (((uint32_t)(val) & 0x0000ff00) << 8) \ + | (((uint32_t)(val) & 0x00ff0000) >> 8) \ + | (((uint32_t)(val) & 0xff000000) >> 24)) + +/** + * BSWAP_64 - reverse bytes in a constant uint64_t value. + * @val: constantvalue whose bytes to swap. + * + * Designed to be usable in constant-requiring initializers. + * + * Example: + * struct mystruct { + * char buf[BSWAP_64(0xff00000000000000ULL)]; + * }; + */ +#define BSWAP_64(val) \ + ((((uint64_t)(val) & 0x00000000000000ffULL) << 56) \ + | (((uint64_t)(val) & 0x000000000000ff00ULL) << 40) \ + | (((uint64_t)(val) & 0x0000000000ff0000ULL) << 24) \ + | (((uint64_t)(val) & 0x00000000ff000000ULL) << 8) \ + | (((uint64_t)(val) & 0x000000ff00000000ULL) >> 8) \ + | (((uint64_t)(val) & 0x0000ff0000000000ULL) >> 24) \ + | (((uint64_t)(val) & 0x00ff000000000000ULL) >> 40) \ + | (((uint64_t)(val) & 0xff00000000000000ULL) >> 56)) + +#if HAVE_BYTESWAP_H +#include +#else +/** + * bswap_16 - reverse bytes in a uint16_t value. + * @val: value whose bytes to swap. + * + * Example: + * // Output contains "1024 is 4 as two bytes reversed" + * printf("1024 is %u as two bytes reversed\n", bswap_16(1024)); + */ +static inline uint16_t bswap_16(uint16_t val) +{ + return BSWAP_16(val); +} + +/** + * bswap_32 - reverse bytes in a uint32_t value. + * @val: value whose bytes to swap. + * + * Example: + * // Output contains "1024 is 262144 as four bytes reversed" + * printf("1024 is %u as four bytes reversed\n", bswap_32(1024)); + */ +static inline uint32_t bswap_32(uint32_t val) +{ + return BSWAP_32(val); +} +#endif /* !HAVE_BYTESWAP_H */ + +#if !HAVE_BSWAP_64 +/** + * bswap_64 - reverse bytes in a uint64_t value. + * @val: value whose bytes to swap. + * + * Example: + * // Output contains "1024 is 1125899906842624 as eight bytes reversed" + * printf("1024 is %llu as eight bytes reversed\n", + * (unsigned long long)bswap_64(1024)); + */ +static inline uint64_t bswap_64(uint64_t val) +{ + return BSWAP_64(val); +} +#endif + +/* Needed for Glibc like endiness check */ +#define __LITTLE_ENDIAN 1234 +#define __BIG_ENDIAN 4321 + +/* Sanity check the defines. We don't handle weird endianness. */ +#if !HAVE_LITTLE_ENDIAN && !HAVE_BIG_ENDIAN +#error "Unknown endian" +#elif HAVE_LITTLE_ENDIAN && HAVE_BIG_ENDIAN +#error "Can't compile for both big and little endian." +#elif HAVE_LITTLE_ENDIAN +#ifndef __BYTE_ORDER +#define __BYTE_ORDER __LITTLE_ENDIAN +#elif __BYTE_ORDER != __LITTLE_ENDIAN +#error "__BYTE_ORDER already defined, but not equal to __LITTLE_ENDIAN" +#endif +#elif HAVE_BIG_ENDIAN +#ifndef __BYTE_ORDER +#define __BYTE_ORDER __BIG_ENDIAN +#elif __BYTE_ORDER != __BIG_ENDIAN +#error "__BYTE_ORDER already defined, but not equal to __BIG_ENDIAN" +#endif +#endif + + +#ifdef __CHECKER__ +/* sparse needs forcing to remove bitwise attribute from ccan/short_types */ +#define ENDIAN_CAST __attribute__((force)) +#define ENDIAN_TYPE __attribute__((bitwise)) +#else +#define ENDIAN_CAST +#define ENDIAN_TYPE +#endif + +typedef uint64_t ENDIAN_TYPE leint64_t; +typedef uint64_t ENDIAN_TYPE beint64_t; +typedef uint32_t ENDIAN_TYPE leint32_t; +typedef uint32_t ENDIAN_TYPE beint32_t; +typedef uint16_t ENDIAN_TYPE leint16_t; +typedef uint16_t ENDIAN_TYPE beint16_t; + +#if HAVE_LITTLE_ENDIAN +/** + * CPU_TO_LE64 - convert a constant uint64_t value to little-endian + * @native: constant to convert + */ +#define CPU_TO_LE64(native) ((ENDIAN_CAST leint64_t)(native)) + +/** + * CPU_TO_LE32 - convert a constant uint32_t value to little-endian + * @native: constant to convert + */ +#define CPU_TO_LE32(native) ((ENDIAN_CAST leint32_t)(native)) + +/** + * CPU_TO_LE16 - convert a constant uint16_t value to little-endian + * @native: constant to convert + */ +#define CPU_TO_LE16(native) ((ENDIAN_CAST leint16_t)(native)) + +/** + * LE64_TO_CPU - convert a little-endian uint64_t constant + * @le_val: little-endian constant to convert + */ +#define LE64_TO_CPU(le_val) ((ENDIAN_CAST uint64_t)(le_val)) + +/** + * LE32_TO_CPU - convert a little-endian uint32_t constant + * @le_val: little-endian constant to convert + */ +#define LE32_TO_CPU(le_val) ((ENDIAN_CAST uint32_t)(le_val)) + +/** + * LE16_TO_CPU - convert a little-endian uint16_t constant + * @le_val: little-endian constant to convert + */ +#define LE16_TO_CPU(le_val) ((ENDIAN_CAST uint16_t)(le_val)) + +#else /* ... HAVE_BIG_ENDIAN */ +#define CPU_TO_LE64(native) ((ENDIAN_CAST leint64_t)BSWAP_64(native)) +#define CPU_TO_LE32(native) ((ENDIAN_CAST leint32_t)BSWAP_32(native)) +#define CPU_TO_LE16(native) ((ENDIAN_CAST leint16_t)BSWAP_16(native)) +#define LE64_TO_CPU(le_val) BSWAP_64((ENDIAN_CAST uint64_t)le_val) +#define LE32_TO_CPU(le_val) BSWAP_32((ENDIAN_CAST uint32_t)le_val) +#define LE16_TO_CPU(le_val) BSWAP_16((ENDIAN_CAST uint16_t)le_val) +#endif /* HAVE_BIG_ENDIAN */ + +#if HAVE_BIG_ENDIAN +/** + * CPU_TO_BE64 - convert a constant uint64_t value to big-endian + * @native: constant to convert + */ +#define CPU_TO_BE64(native) ((ENDIAN_CAST beint64_t)(native)) + +/** + * CPU_TO_BE32 - convert a constant uint32_t value to big-endian + * @native: constant to convert + */ +#define CPU_TO_BE32(native) ((ENDIAN_CAST beint32_t)(native)) + +/** + * CPU_TO_BE16 - convert a constant uint16_t value to big-endian + * @native: constant to convert + */ +#define CPU_TO_BE16(native) ((ENDIAN_CAST beint16_t)(native)) + +/** + * BE64_TO_CPU - convert a big-endian uint64_t constant + * @le_val: big-endian constant to convert + */ +#define BE64_TO_CPU(le_val) ((ENDIAN_CAST uint64_t)(le_val)) + +/** + * BE32_TO_CPU - convert a big-endian uint32_t constant + * @le_val: big-endian constant to convert + */ +#define BE32_TO_CPU(le_val) ((ENDIAN_CAST uint32_t)(le_val)) + +/** + * BE16_TO_CPU - convert a big-endian uint16_t constant + * @le_val: big-endian constant to convert + */ +#define BE16_TO_CPU(le_val) ((ENDIAN_CAST uint16_t)(le_val)) + +#else /* ... HAVE_LITTLE_ENDIAN */ +#define CPU_TO_BE64(native) ((ENDIAN_CAST beint64_t)BSWAP_64(native)) +#define CPU_TO_BE32(native) ((ENDIAN_CAST beint32_t)BSWAP_32(native)) +#define CPU_TO_BE16(native) ((ENDIAN_CAST beint16_t)BSWAP_16(native)) +#define BE64_TO_CPU(le_val) BSWAP_64((ENDIAN_CAST uint64_t)le_val) +#define BE32_TO_CPU(le_val) BSWAP_32((ENDIAN_CAST uint32_t)le_val) +#define BE16_TO_CPU(le_val) BSWAP_16((ENDIAN_CAST uint16_t)le_val) +#endif /* HAVE_LITTE_ENDIAN */ + + +/** + * cpu_to_le64 - convert a uint64_t value to little-endian + * @native: value to convert + */ +static inline leint64_t cpu_to_le64(uint64_t native) +{ + return CPU_TO_LE64(native); +} + +/** + * cpu_to_le32 - convert a uint32_t value to little-endian + * @native: value to convert + */ +static inline leint32_t cpu_to_le32(uint32_t native) +{ + return CPU_TO_LE32(native); +} + +/** + * cpu_to_le16 - convert a uint16_t value to little-endian + * @native: value to convert + */ +static inline leint16_t cpu_to_le16(uint16_t native) +{ + return CPU_TO_LE16(native); +} + +/** + * le64_to_cpu - convert a little-endian uint64_t value + * @le_val: little-endian value to convert + */ +static inline uint64_t le64_to_cpu(leint64_t le_val) +{ + return LE64_TO_CPU(le_val); +} + +/** + * le32_to_cpu - convert a little-endian uint32_t value + * @le_val: little-endian value to convert + */ +static inline uint32_t le32_to_cpu(leint32_t le_val) +{ + return LE32_TO_CPU(le_val); +} + +/** + * le16_to_cpu - convert a little-endian uint16_t value + * @le_val: little-endian value to convert + */ +static inline uint16_t le16_to_cpu(leint16_t le_val) +{ + return LE16_TO_CPU(le_val); +} + +/** + * cpu_to_be64 - convert a uint64_t value to big endian. + * @native: value to convert + */ +static inline beint64_t cpu_to_be64(uint64_t native) +{ + return CPU_TO_BE64(native); +} + +/** + * cpu_to_be32 - convert a uint32_t value to big endian. + * @native: value to convert + */ +static inline beint32_t cpu_to_be32(uint32_t native) +{ + return CPU_TO_BE32(native); +} + +/** + * cpu_to_be16 - convert a uint16_t value to big endian. + * @native: value to convert + */ +static inline beint16_t cpu_to_be16(uint16_t native) +{ + return CPU_TO_BE16(native); +} + +/** + * be64_to_cpu - convert a big-endian uint64_t value + * @be_val: big-endian value to convert + */ +static inline uint64_t be64_to_cpu(beint64_t be_val) +{ + return BE64_TO_CPU(be_val); +} + +/** + * be32_to_cpu - convert a big-endian uint32_t value + * @be_val: big-endian value to convert + */ +static inline uint32_t be32_to_cpu(beint32_t be_val) +{ + return BE32_TO_CPU(be_val); +} + +/** + * be16_to_cpu - convert a big-endian uint16_t value + * @be_val: big-endian value to convert + */ +static inline uint16_t be16_to_cpu(beint16_t be_val) +{ + return BE16_TO_CPU(be_val); +} + +/* Whichever they include first, they get these definitions. */ +#ifdef CCAN_SHORT_TYPES_H +/** + * be64/be32/be16 - 64/32/16 bit big-endian representation. + */ +typedef beint64_t be64; +typedef beint32_t be32; +typedef beint16_t be16; + +/** + * le64/le32/le16 - 64/32/16 bit little-endian representation. + */ +typedef leint64_t le64; +typedef leint32_t le32; +typedef leint16_t le16; +#endif +#endif /* CCAN_ENDIAN_H */ diff --git a/src/ccan/ccan/list/LICENSE b/src/ccan/ccan/list/LICENSE new file mode 120000 index 0000000000..2354d12945 --- /dev/null +++ b/src/ccan/ccan/list/LICENSE @@ -0,0 +1 @@ +../../licenses/BSD-MIT \ No newline at end of file diff --git a/src/ccan/ccan/list/_info b/src/ccan/ccan/list/_info new file mode 100644 index 0000000000..c4f3e2a0ac --- /dev/null +++ b/src/ccan/ccan/list/_info @@ -0,0 +1,72 @@ +#include "config.h" +#include +#include + +/** + * list - double linked list routines + * + * The list header contains routines for manipulating double linked lists. + * It defines two types: struct list_head used for anchoring lists, and + * struct list_node which is usually embedded in the structure which is placed + * in the list. + * + * Example: + * #include + * #include + * #include + * #include + * + * struct parent { + * const char *name; + * struct list_head children; + * unsigned int num_children; + * }; + * + * struct child { + * const char *name; + * struct list_node list; + * }; + * + * int main(int argc, char *argv[]) + * { + * struct parent p; + * struct child *c; + * int i; + * + * if (argc < 2) + * errx(1, "Usage: %s parent children...", argv[0]); + * + * p.name = argv[1]; + * list_head_init(&p.children); + * p.num_children = 0; + * for (i = 2; i < argc; i++) { + * c = malloc(sizeof(*c)); + * c->name = argv[i]; + * list_add(&p.children, &c->list); + * p.num_children++; + * } + * + * printf("%s has %u children:", p.name, p.num_children); + * list_for_each(&p.children, c, list) + * printf("%s ", c->name); + * printf("\n"); + * return 0; + * } + * + * License: BSD-MIT + * Author: Rusty Russell + */ +int main(int argc, char *argv[]) +{ + if (argc != 2) + return 1; + + if (strcmp(argv[1], "depends") == 0) { + printf("ccan/str\n"); + printf("ccan/container_of\n"); + printf("ccan/check_type\n"); + return 0; + } + + return 1; +} diff --git a/src/ccan/ccan/list/list.c b/src/ccan/ccan/list/list.c new file mode 100644 index 0000000000..2717fa3f17 --- /dev/null +++ b/src/ccan/ccan/list/list.c @@ -0,0 +1,43 @@ +/* Licensed under BSD-MIT - see LICENSE file for details */ +#include +#include +#include "list.h" + +static void *corrupt(const char *abortstr, + const struct list_node *head, + const struct list_node *node, + unsigned int count) +{ + if (abortstr) { + fprintf(stderr, + "%s: prev corrupt in node %p (%u) of %p\n", + abortstr, node, count, head); + abort(); + } + return NULL; +} + +struct list_node *list_check_node(const struct list_node *node, + const char *abortstr) +{ + const struct list_node *p, *n; + int count = 0; + + for (p = node, n = node->next; n != node; p = n, n = n->next) { + count++; + if (n->prev != p) + return corrupt(abortstr, node, n, count); + } + /* Check prev on head node. */ + if (node->prev != p) + return corrupt(abortstr, node, node, 0); + + return (struct list_node *)node; +} + +struct list_head *list_check(const struct list_head *h, const char *abortstr) +{ + if (!list_check_node(&h->n, abortstr)) + return NULL; + return (struct list_head *)h; +} diff --git a/src/ccan/ccan/list/list.h b/src/ccan/ccan/list/list.h new file mode 100644 index 0000000000..a15321c590 --- /dev/null +++ b/src/ccan/ccan/list/list.h @@ -0,0 +1,842 @@ +/* Licensed under BSD-MIT - see LICENSE file for details */ +#ifndef CCAN_LIST_H +#define CCAN_LIST_H +//#define CCAN_LIST_DEBUG 1 +#include +#include +#include +#include +#include + +/** + * struct list_node - an entry in a doubly-linked list + * @next: next entry (self if empty) + * @prev: previous entry (self if empty) + * + * This is used as an entry in a linked list. + * Example: + * struct child { + * const char *name; + * // Linked list of all us children. + * struct list_node list; + * }; + */ +struct list_node +{ + struct list_node *next, *prev; +}; + +/** + * struct list_head - the head of a doubly-linked list + * @h: the list_head (containing next and prev pointers) + * + * This is used as the head of a linked list. + * Example: + * struct parent { + * const char *name; + * struct list_head children; + * unsigned int num_children; + * }; + */ +struct list_head +{ + struct list_node n; +}; + +/** + * list_check - check head of a list for consistency + * @h: the list_head + * @abortstr: the location to print on aborting, or NULL. + * + * Because list_nodes have redundant information, consistency checking between + * the back and forward links can be done. This is useful as a debugging check. + * If @abortstr is non-NULL, that will be printed in a diagnostic if the list + * is inconsistent, and the function will abort. + * + * Returns the list head if the list is consistent, NULL if not (it + * can never return NULL if @abortstr is set). + * + * See also: list_check_node() + * + * Example: + * static void dump_parent(struct parent *p) + * { + * struct child *c; + * + * printf("%s (%u children):\n", p->name, p->num_children); + * list_check(&p->children, "bad child list"); + * list_for_each(&p->children, c, list) + * printf(" -> %s\n", c->name); + * } + */ +struct list_head *list_check(const struct list_head *h, const char *abortstr); + +/** + * list_check_node - check node of a list for consistency + * @n: the list_node + * @abortstr: the location to print on aborting, or NULL. + * + * Check consistency of the list node is in (it must be in one). + * + * See also: list_check() + * + * Example: + * static void dump_child(const struct child *c) + * { + * list_check_node(&c->list, "bad child list"); + * printf("%s\n", c->name); + * } + */ +struct list_node *list_check_node(const struct list_node *n, + const char *abortstr); + +#define LIST_LOC __FILE__ ":" stringify(__LINE__) +#ifdef CCAN_LIST_DEBUG +#define list_debug(h, loc) list_check((h), loc) +#define list_debug_node(n, loc) list_check_node((n), loc) +#else +#define list_debug(h, loc) ((void)loc, h) +#define list_debug_node(n, loc) ((void)loc, n) +#endif + +/** + * LIST_HEAD_INIT - initializer for an empty list_head + * @name: the name of the list. + * + * Explicit initializer for an empty list. + * + * See also: + * LIST_HEAD, list_head_init() + * + * Example: + * static struct list_head my_list = LIST_HEAD_INIT(my_list); + */ +#define LIST_HEAD_INIT(name) { { &(name).n, &(name).n } } + +/** + * LIST_HEAD - define and initialize an empty list_head + * @name: the name of the list. + * + * The LIST_HEAD macro defines a list_head and initializes it to an empty + * list. It can be prepended by "static" to define a static list_head. + * + * See also: + * LIST_HEAD_INIT, list_head_init() + * + * Example: + * static LIST_HEAD(my_global_list); + */ +#define LIST_HEAD(name) \ + struct list_head name = LIST_HEAD_INIT(name) + +/** + * list_head_init - initialize a list_head + * @h: the list_head to set to the empty list + * + * Example: + * ... + * struct parent *parent = malloc(sizeof(*parent)); + * + * list_head_init(&parent->children); + * parent->num_children = 0; + */ +static inline void list_head_init(struct list_head *h) +{ + h->n.next = h->n.prev = &h->n; +} + +/** + * list_node_init - initialize a list_node + * @n: the list_node to link to itself. + * + * You don't need to use this normally! But it lets you list_del(@n) + * safely. + */ +static inline void list_node_init(struct list_node *n) +{ + n->next = n->prev = n; +} + +/** + * list_add_after - add an entry after an existing node in a linked list + * @h: the list_head to add the node to (for debugging) + * @p: the existing list_node to add the node after + * @n: the new list_node to add to the list. + * + * The existing list_node must already be a member of the list. + * The new list_node does not need to be initialized; it will be overwritten. + * + * Example: + * struct child c1, c2, c3; + * LIST_HEAD(h); + * + * list_add_tail(&h, &c1.list); + * list_add_tail(&h, &c3.list); + * list_add_after(&h, &c1.list, &c2.list); + */ +#define list_add_after(h, p, n) list_add_after_(h, p, n, LIST_LOC) +static inline void list_add_after_(struct list_head *h, + struct list_node *p, + struct list_node *n, + const char *abortstr) +{ + n->next = p->next; + n->prev = p; + p->next->prev = n; + p->next = n; + (void)list_debug(h, abortstr); +} + +/** + * list_add - add an entry at the start of a linked list. + * @h: the list_head to add the node to + * @n: the list_node to add to the list. + * + * The list_node does not need to be initialized; it will be overwritten. + * Example: + * struct child *child = malloc(sizeof(*child)); + * + * child->name = "marvin"; + * list_add(&parent->children, &child->list); + * parent->num_children++; + */ +#define list_add(h, n) list_add_(h, n, LIST_LOC) +static inline void list_add_(struct list_head *h, + struct list_node *n, + const char *abortstr) +{ + list_add_after_(h, &h->n, n, abortstr); +} + +/** + * list_add_before - add an entry before an existing node in a linked list + * @h: the list_head to add the node to (for debugging) + * @p: the existing list_node to add the node before + * @n: the new list_node to add to the list. + * + * The existing list_node must already be a member of the list. + * The new list_node does not need to be initialized; it will be overwritten. + * + * Example: + * list_head_init(&h); + * list_add_tail(&h, &c1.list); + * list_add_tail(&h, &c3.list); + * list_add_before(&h, &c3.list, &c2.list); + */ +#define list_add_before(h, p, n) list_add_before_(h, p, n, LIST_LOC) +static inline void list_add_before_(struct list_head *h, + struct list_node *p, + struct list_node *n, + const char *abortstr) +{ + n->next = p; + n->prev = p->prev; + p->prev->next = n; + p->prev = n; + (void)list_debug(h, abortstr); +} + +/** + * list_add_tail - add an entry at the end of a linked list. + * @h: the list_head to add the node to + * @n: the list_node to add to the list. + * + * The list_node does not need to be initialized; it will be overwritten. + * Example: + * list_add_tail(&parent->children, &child->list); + * parent->num_children++; + */ +#define list_add_tail(h, n) list_add_tail_(h, n, LIST_LOC) +static inline void list_add_tail_(struct list_head *h, + struct list_node *n, + const char *abortstr) +{ + list_add_before_(h, &h->n, n, abortstr); +} + +/** + * list_empty - is a list empty? + * @h: the list_head + * + * If the list is empty, returns true. + * + * Example: + * assert(list_empty(&parent->children) == (parent->num_children == 0)); + */ +#define list_empty(h) list_empty_(h, LIST_LOC) +static inline bool list_empty_(const struct list_head *h, const char* abortstr) +{ + (void)list_debug(h, abortstr); + return h->n.next == &h->n; +} + +/** + * list_empty_nodebug - is a list empty (and don't perform debug checks)? + * @h: the list_head + * + * If the list is empty, returns true. + * This differs from list_empty() in that if CCAN_LIST_DEBUG is set it + * will NOT perform debug checks. Only use this function if you REALLY + * know what you're doing. + * + * Example: + * assert(list_empty_nodebug(&parent->children) == (parent->num_children == 0)); + */ +#ifndef CCAN_LIST_DEBUG +#define list_empty_nodebug(h) list_empty(h) +#else +static inline bool list_empty_nodebug(const struct list_head *h) +{ + return h->n.next == &h->n; +} +#endif + +/** + * list_empty_nocheck - is a list empty? + * @h: the list_head + * + * If the list is empty, returns true. This doesn't perform any + * debug check for list consistency, so it can be called without + * locks, racing with the list being modified. This is ok for + * checks where an incorrect result is not an issue (optimized + * bail out path for example). + */ +static inline bool list_empty_nocheck(const struct list_head *h) +{ + return h->n.next == &h->n; +} + +/** + * list_del - delete an entry from an (unknown) linked list. + * @n: the list_node to delete from the list. + * + * Note that this leaves @n in an undefined state; it can be added to + * another list, but not deleted again. + * + * See also: + * list_del_from(), list_del_init() + * + * Example: + * list_del(&child->list); + * parent->num_children--; + */ +#define list_del(n) list_del_(n, LIST_LOC) +static inline void list_del_(struct list_node *n, const char* abortstr) +{ + (void)list_debug_node(n, abortstr); + n->next->prev = n->prev; + n->prev->next = n->next; +#ifdef CCAN_LIST_DEBUG + /* Catch use-after-del. */ + n->next = n->prev = NULL; +#endif +} + +/** + * list_del_init - delete a node, and reset it so it can be deleted again. + * @n: the list_node to be deleted. + * + * list_del(@n) or list_del_init() again after this will be safe, + * which can be useful in some cases. + * + * See also: + * list_del_from(), list_del() + * + * Example: + * list_del_init(&child->list); + * parent->num_children--; + */ +#define list_del_init(n) list_del_init_(n, LIST_LOC) +static inline void list_del_init_(struct list_node *n, const char *abortstr) +{ + list_del_(n, abortstr); + list_node_init(n); +} + +/** + * list_del_from - delete an entry from a known linked list. + * @h: the list_head the node is in. + * @n: the list_node to delete from the list. + * + * This explicitly indicates which list a node is expected to be in, + * which is better documentation and can catch more bugs. + * + * See also: list_del() + * + * Example: + * list_del_from(&parent->children, &child->list); + * parent->num_children--; + */ +static inline void list_del_from(struct list_head *h, struct list_node *n) +{ +#ifdef CCAN_LIST_DEBUG + { + /* Thorough check: make sure it was in list! */ + struct list_node *i; + for (i = h->n.next; i != n; i = i->next) + assert(i != &h->n); + } +#endif /* CCAN_LIST_DEBUG */ + + /* Quick test that catches a surprising number of bugs. */ + assert(!list_empty(h)); + list_del(n); +} + +/** + * list_swap - swap out an entry from an (unknown) linked list for a new one. + * @o: the list_node to replace from the list. + * @n: the list_node to insert in place of the old one. + * + * Note that this leaves @o in an undefined state; it can be added to + * another list, but not deleted/swapped again. + * + * See also: + * list_del() + * + * Example: + * struct child x1, x2; + * LIST_HEAD(xh); + * + * list_add(&xh, &x1.list); + * list_swap(&x1.list, &x2.list); + */ +#define list_swap(o, n) list_swap_(o, n, LIST_LOC) +static inline void list_swap_(struct list_node *o, + struct list_node *n, + const char* abortstr) +{ + (void)list_debug_node(o, abortstr); + *n = *o; + n->next->prev = n; + n->prev->next = n; +#ifdef CCAN_LIST_DEBUG + /* Catch use-after-del. */ + o->next = o->prev = NULL; +#endif +} + +/** + * list_entry - convert a list_node back into the structure containing it. + * @n: the list_node + * @type: the type of the entry + * @member: the list_node member of the type + * + * Example: + * // First list entry is children.next; convert back to child. + * child = list_entry(parent->children.n.next, struct child, list); + * + * See Also: + * list_top(), list_for_each() + */ +#define list_entry(n, type, member) container_of(n, type, member) + +/** + * list_top - get the first entry in a list + * @h: the list_head + * @type: the type of the entry + * @member: the list_node member of the type + * + * If the list is empty, returns NULL. + * + * Example: + * struct child *first; + * first = list_top(&parent->children, struct child, list); + * if (!first) + * printf("Empty list!\n"); + */ +#define list_top(h, type, member) \ + ((type *)list_top_((h), list_off_(type, member))) + +static inline const void *list_top_(const struct list_head *h, size_t off) +{ + if (list_empty(h)) + return NULL; + return (const char *)h->n.next - off; +} + +/** + * list_pop - remove the first entry in a list + * @h: the list_head + * @type: the type of the entry + * @member: the list_node member of the type + * + * If the list is empty, returns NULL. + * + * Example: + * struct child *one; + * one = list_pop(&parent->children, struct child, list); + * if (!one) + * printf("Empty list!\n"); + */ +#define list_pop(h, type, member) \ + ((type *)list_pop_((h), list_off_(type, member))) + +static inline const void *list_pop_(const struct list_head *h, size_t off) +{ + struct list_node *n; + + if (list_empty(h)) + return NULL; + n = h->n.next; + list_del(n); + return (const char *)n - off; +} + +/** + * list_tail - get the last entry in a list + * @h: the list_head + * @type: the type of the entry + * @member: the list_node member of the type + * + * If the list is empty, returns NULL. + * + * Example: + * struct child *last; + * last = list_tail(&parent->children, struct child, list); + * if (!last) + * printf("Empty list!\n"); + */ +#define list_tail(h, type, member) \ + ((type *)list_tail_((h), list_off_(type, member))) + +static inline const void *list_tail_(const struct list_head *h, size_t off) +{ + if (list_empty(h)) + return NULL; + return (const char *)h->n.prev - off; +} + +/** + * list_for_each - iterate through a list. + * @h: the list_head (warning: evaluated multiple times!) + * @i: the structure containing the list_node + * @member: the list_node member of the structure + * + * This is a convenient wrapper to iterate @i over the entire list. It's + * a for loop, so you can break and continue as normal. + * + * Example: + * list_for_each(&parent->children, child, list) + * printf("Name: %s\n", child->name); + */ +#define list_for_each(h, i, member) \ + list_for_each_off(h, i, list_off_var_(i, member)) + +/** + * list_for_each_rev - iterate through a list backwards. + * @h: the list_head + * @i: the structure containing the list_node + * @member: the list_node member of the structure + * + * This is a convenient wrapper to iterate @i over the entire list. It's + * a for loop, so you can break and continue as normal. + * + * Example: + * list_for_each_rev(&parent->children, child, list) + * printf("Name: %s\n", child->name); + */ +#define list_for_each_rev(h, i, member) \ + list_for_each_rev_off(h, i, list_off_var_(i, member)) + +/** + * list_for_each_rev_safe - iterate through a list backwards, + * maybe during deletion + * @h: the list_head + * @i: the structure containing the list_node + * @nxt: the structure containing the list_node + * @member: the list_node member of the structure + * + * This is a convenient wrapper to iterate @i over the entire list backwards. + * It's a for loop, so you can break and continue as normal. The extra + * variable * @nxt is used to hold the next element, so you can delete @i + * from the list. + * + * Example: + * struct child *next; + * list_for_each_rev_safe(&parent->children, child, next, list) { + * printf("Name: %s\n", child->name); + * } + */ +#define list_for_each_rev_safe(h, i, nxt, member) \ + list_for_each_rev_safe_off(h, i, nxt, list_off_var_(i, member)) + +/** + * list_for_each_safe - iterate through a list, maybe during deletion + * @h: the list_head + * @i: the structure containing the list_node + * @nxt: the structure containing the list_node + * @member: the list_node member of the structure + * + * This is a convenient wrapper to iterate @i over the entire list. It's + * a for loop, so you can break and continue as normal. The extra variable + * @nxt is used to hold the next element, so you can delete @i from the list. + * + * Example: + * list_for_each_safe(&parent->children, child, next, list) { + * list_del(&child->list); + * parent->num_children--; + * } + */ +#define list_for_each_safe(h, i, nxt, member) \ + list_for_each_safe_off(h, i, nxt, list_off_var_(i, member)) + +/** + * list_next - get the next entry in a list + * @h: the list_head + * @i: a pointer to an entry in the list. + * @member: the list_node member of the structure + * + * If @i was the last entry in the list, returns NULL. + * + * Example: + * struct child *second; + * second = list_next(&parent->children, first, list); + * if (!second) + * printf("No second child!\n"); + */ +#define list_next(h, i, member) \ + ((list_typeof(i))list_entry_or_null(list_debug(h, \ + __FILE__ ":" stringify(__LINE__)), \ + (i)->member.next, \ + list_off_var_((i), member))) + +/** + * list_prev - get the previous entry in a list + * @h: the list_head + * @i: a pointer to an entry in the list. + * @member: the list_node member of the structure + * + * If @i was the first entry in the list, returns NULL. + * + * Example: + * first = list_prev(&parent->children, second, list); + * if (!first) + * printf("Can't go back to first child?!\n"); + */ +#define list_prev(h, i, member) \ + ((list_typeof(i))list_entry_or_null(list_debug(h, \ + __FILE__ ":" stringify(__LINE__)), \ + (i)->member.prev, \ + list_off_var_((i), member))) + +/** + * list_append_list - empty one list onto the end of another. + * @to: the list to append into + * @from: the list to empty. + * + * This takes the entire contents of @from and moves it to the end of + * @to. After this @from will be empty. + * + * Example: + * struct list_head adopter; + * + * list_append_list(&adopter, &parent->children); + * assert(list_empty(&parent->children)); + * parent->num_children = 0; + */ +#define list_append_list(t, f) list_append_list_(t, f, \ + __FILE__ ":" stringify(__LINE__)) +static inline void list_append_list_(struct list_head *to, + struct list_head *from, + const char *abortstr) +{ + struct list_node *from_tail = list_debug(from, abortstr)->n.prev; + struct list_node *to_tail = list_debug(to, abortstr)->n.prev; + + /* Sew in head and entire list. */ + to->n.prev = from_tail; + from_tail->next = &to->n; + to_tail->next = &from->n; + from->n.prev = to_tail; + + /* Now remove head. */ + list_del(&from->n); + list_head_init(from); +} + +/** + * list_prepend_list - empty one list into the start of another. + * @to: the list to prepend into + * @from: the list to empty. + * + * This takes the entire contents of @from and moves it to the start + * of @to. After this @from will be empty. + * + * Example: + * list_prepend_list(&adopter, &parent->children); + * assert(list_empty(&parent->children)); + * parent->num_children = 0; + */ +#define list_prepend_list(t, f) list_prepend_list_(t, f, LIST_LOC) +static inline void list_prepend_list_(struct list_head *to, + struct list_head *from, + const char *abortstr) +{ + struct list_node *from_tail = list_debug(from, abortstr)->n.prev; + struct list_node *to_head = list_debug(to, abortstr)->n.next; + + /* Sew in head and entire list. */ + to->n.next = &from->n; + from->n.prev = &to->n; + to_head->prev = from_tail; + from_tail->next = to_head; + + /* Now remove head. */ + list_del(&from->n); + list_head_init(from); +} + +/* internal macros, do not use directly */ +#define list_for_each_off_dir_(h, i, off, dir) \ + for (i = list_node_to_off_(list_debug(h, LIST_LOC)->n.dir, \ + (off)); \ + list_node_from_off_((void *)i, (off)) != &(h)->n; \ + i = list_node_to_off_(list_node_from_off_((void *)i, (off))->dir, \ + (off))) + +#define list_for_each_safe_off_dir_(h, i, nxt, off, dir) \ + for (i = list_node_to_off_(list_debug(h, LIST_LOC)->n.dir, \ + (off)), \ + nxt = list_node_to_off_(list_node_from_off_(i, (off))->dir, \ + (off)); \ + list_node_from_off_(i, (off)) != &(h)->n; \ + i = nxt, \ + nxt = list_node_to_off_(list_node_from_off_(i, (off))->dir, \ + (off))) + +/** + * list_for_each_off - iterate through a list of memory regions. + * @h: the list_head + * @i: the pointer to a memory region which contains list node data. + * @off: offset(relative to @i) at which list node data resides. + * + * This is a low-level wrapper to iterate @i over the entire list, used to + * implement all oher, more high-level, for-each constructs. It's a for loop, + * so you can break and continue as normal. + * + * WARNING! Being the low-level macro that it is, this wrapper doesn't know + * nor care about the type of @i. The only assumption made is that @i points + * to a chunk of memory that at some @offset, relative to @i, contains a + * properly filled `struct list_node' which in turn contains pointers to + * memory chunks and it's turtles all the way down. With all that in mind + * remember that given the wrong pointer/offset couple this macro will + * happily churn all you memory until SEGFAULT stops it, in other words + * caveat emptor. + * + * It is worth mentioning that one of legitimate use-cases for that wrapper + * is operation on opaque types with known offset for `struct list_node' + * member(preferably 0), because it allows you not to disclose the type of + * @i. + * + * Example: + * list_for_each_off(&parent->children, child, + * offsetof(struct child, list)) + * printf("Name: %s\n", child->name); + */ +#define list_for_each_off(h, i, off) \ + list_for_each_off_dir_((h),(i),(off),next) + +/** + * list_for_each_rev_off - iterate through a list of memory regions backwards + * @h: the list_head + * @i: the pointer to a memory region which contains list node data. + * @off: offset(relative to @i) at which list node data resides. + * + * See list_for_each_off for details + */ +#define list_for_each_rev_off(h, i, off) \ + list_for_each_off_dir_((h),(i),(off),prev) + +/** + * list_for_each_safe_off - iterate through a list of memory regions, maybe + * during deletion + * @h: the list_head + * @i: the pointer to a memory region which contains list node data. + * @nxt: the structure containing the list_node + * @off: offset(relative to @i) at which list node data resides. + * + * For details see `list_for_each_off' and `list_for_each_safe' + * descriptions. + * + * Example: + * list_for_each_safe_off(&parent->children, child, + * next, offsetof(struct child, list)) + * printf("Name: %s\n", child->name); + */ +#define list_for_each_safe_off(h, i, nxt, off) \ + list_for_each_safe_off_dir_((h),(i),(nxt),(off),next) + +/** + * list_for_each_rev_safe_off - iterate backwards through a list of + * memory regions, maybe during deletion + * @h: the list_head + * @i: the pointer to a memory region which contains list node data. + * @nxt: the structure containing the list_node + * @off: offset(relative to @i) at which list node data resides. + * + * For details see `list_for_each_rev_off' and `list_for_each_rev_safe' + * descriptions. + * + * Example: + * list_for_each_rev_safe_off(&parent->children, child, + * next, offsetof(struct child, list)) + * printf("Name: %s\n", child->name); + */ +#define list_for_each_rev_safe_off(h, i, nxt, off) \ + list_for_each_safe_off_dir_((h),(i),(nxt),(off),prev) + +/* Other -off variants. */ +#define list_entry_off(n, type, off) \ + ((type *)list_node_from_off_((n), (off))) + +#define list_head_off(h, type, off) \ + ((type *)list_head_off((h), (off))) + +#define list_tail_off(h, type, off) \ + ((type *)list_tail_((h), (off))) + +#define list_add_off(h, n, off) \ + list_add((h), list_node_from_off_((n), (off))) + +#define list_del_off(n, off) \ + list_del(list_node_from_off_((n), (off))) + +#define list_del_from_off(h, n, off) \ + list_del_from(h, list_node_from_off_((n), (off))) + +/* Offset helper functions so we only single-evaluate. */ +static inline void *list_node_to_off_(struct list_node *node, size_t off) +{ + return (void *)((char *)node - off); +} +static inline struct list_node *list_node_from_off_(void *ptr, size_t off) +{ + return (struct list_node *)((char *)ptr + off); +} + +/* Get the offset of the member, but make sure it's a list_node. */ +#define list_off_(type, member) \ + (container_off(type, member) + \ + check_type(((type *)0)->member, struct list_node)) + +#define list_off_var_(var, member) \ + (container_off_var(var, member) + \ + check_type(var->member, struct list_node)) + +#if HAVE_TYPEOF +#define list_typeof(var) typeof(var) +#else +#define list_typeof(var) void * +#endif + +/* Returns member, or NULL if at end of list. */ +static inline void *list_entry_or_null(const struct list_head *h, + const struct list_node *n, + size_t off) +{ + if (n == &h->n) + return NULL; + return (char *)n - off; +} +#endif /* CCAN_LIST_H */ diff --git a/src/ccan/ccan/minmax/LICENSE b/src/ccan/ccan/minmax/LICENSE new file mode 120000 index 0000000000..b7951dabdc --- /dev/null +++ b/src/ccan/ccan/minmax/LICENSE @@ -0,0 +1 @@ +../../licenses/CC0 \ No newline at end of file diff --git a/src/ccan/ccan/minmax/_info b/src/ccan/ccan/minmax/_info new file mode 100644 index 0000000000..2f6437e610 --- /dev/null +++ b/src/ccan/ccan/minmax/_info @@ -0,0 +1,48 @@ +#include "config.h" +#include +#include + +/** + * minmax - typesafe minimum and maximum functions + * + * The classic implementation of minimum / maximum macros in C can be + * very dangerous. If the two arguments have different sizes, or + * different signedness, type promotion rules can lead to very + * surprising results. + * + * This module implements typesafe versions, which will generate a + * compile time error, if the arguments have different types. + * + * Example: + * #include + * #include + * + * int main(int argc, char *argv[]) + * { + * printf("Signed max: %d\n", max(1, -1)); + * printf("Unsigned max: %u\n", max(1U, -1U)); + * return 0; + * } + * + * Author: David Gibson + * License: CC0 (Public domain) + */ +int main(int argc, char *argv[]) +{ + /* Expect exactly one argument */ + if (argc != 2) + return 1; + + if (strcmp(argv[1], "depends") == 0) { + printf("ccan/build_assert\n"); + return 0; + } + + if (strcmp(argv[1], "ccanlint") == 0) { + /* We need several gcc extensions */ + printf("tests_compile_without_features FAIL\n"); + return 0; + } + + return 1; +} diff --git a/src/ccan/ccan/minmax/minmax.h b/src/ccan/ccan/minmax/minmax.h new file mode 100644 index 0000000000..d111d1bc38 --- /dev/null +++ b/src/ccan/ccan/minmax/minmax.h @@ -0,0 +1,65 @@ +/* CC0 (Public domain) - see LICENSE file for details */ +#ifndef CCAN_MINMAX_H +#define CCAN_MINMAX_H + +#include "config.h" + +#include + +#if !HAVE_STATEMENT_EXPR || !HAVE_TYPEOF +/* + * Without these, there's no way to avoid unsafe double evaluation of + * the arguments + */ +#error Sorry, minmax module requires statement expressions and typeof +#endif + +#if HAVE_BUILTIN_TYPES_COMPATIBLE_P +#define MINMAX_ASSERT_COMPATIBLE(a, b) \ + BUILD_ASSERT(__builtin_types_compatible_p(a, b)) +#else +#define MINMAX_ASSERT_COMPATIBLE(a, b) \ + do { } while (0) +#endif + +#define min(a, b) \ + ({ \ + typeof(a) _a = (a); \ + typeof(b) _b = (b); \ + MINMAX_ASSERT_COMPATIBLE(typeof(_a), typeof(_b)); \ + _a < _b ? _a : _b; \ + }) + +#define max(a, b) \ + ({ \ + typeof(a) _a = (a); \ + typeof(b) _b = (b); \ + MINMAX_ASSERT_COMPATIBLE(typeof(_a), typeof(_b)); \ + _a > _b ? _a : _b; \ + }) + +#define clamp(v, f, c) (max(min((v), (c)), (f))) + + +#define min_t(t, a, b) \ + ({ \ + t _ta = (a); \ + t _tb = (b); \ + min(_ta, _tb); \ + }) +#define max_t(t, a, b) \ + ({ \ + t _ta = (a); \ + t _tb = (b); \ + max(_ta, _tb); \ + }) + +#define clamp_t(t, v, f, c) \ + ({ \ + t _tv = (v); \ + t _tf = (f); \ + t _tc = (c); \ + clamp(_tv, _tf, _tc); \ + }) + +#endif /* CCAN_MINMAX_H */ diff --git a/src/ccan/ccan/short_types/LICENSE b/src/ccan/ccan/short_types/LICENSE new file mode 120000 index 0000000000..b7951dabdc --- /dev/null +++ b/src/ccan/ccan/short_types/LICENSE @@ -0,0 +1 @@ +../../licenses/CC0 \ No newline at end of file diff --git a/src/ccan/ccan/short_types/short_types.h b/src/ccan/ccan/short_types/short_types.h new file mode 100644 index 0000000000..175377e9ba --- /dev/null +++ b/src/ccan/ccan/short_types/short_types.h @@ -0,0 +1,35 @@ +/* CC0 (Public domain) - see LICENSE file for details */ +#ifndef CCAN_SHORT_TYPES_H +#define CCAN_SHORT_TYPES_H +#include + +/** + * u64/s64/u32/s32/u16/s16/u8/s8 - short names for explicitly-sized types. + */ +typedef uint64_t u64; +typedef int64_t s64; +typedef uint32_t u32; +typedef int32_t s32; +typedef uint16_t u16; +typedef int16_t s16; +typedef uint8_t u8; +typedef int8_t s8; + +/* Whichever they include first, they get these definitions. */ +#ifdef CCAN_ENDIAN_H +/** + * be64/be32/be16 - 64/32/16 bit big-endian representation. + */ +typedef beint64_t be64; +typedef beint32_t be32; +typedef beint16_t be16; + +/** + * le64/le32/le16 - 64/32/16 bit little-endian representation. + */ +typedef leint64_t le64; +typedef leint32_t le32; +typedef leint16_t le16; +#endif + +#endif /* CCAN_SHORT_TYPES_H */ diff --git a/src/ccan/ccan/str/LICENSE b/src/ccan/ccan/str/LICENSE new file mode 120000 index 0000000000..b7951dabdc --- /dev/null +++ b/src/ccan/ccan/str/LICENSE @@ -0,0 +1 @@ +../../licenses/CC0 \ No newline at end of file diff --git a/src/ccan/ccan/str/_info b/src/ccan/ccan/str/_info new file mode 100644 index 0000000000..b579525faa --- /dev/null +++ b/src/ccan/ccan/str/_info @@ -0,0 +1,52 @@ +#include "config.h" +#include +#include + +/** + * str - string helper routines + * + * This is a grab bag of functions for string operations, designed to enhance + * the standard string.h. + * + * Note that if you define CCAN_STR_DEBUG, you will get extra compile + * checks on common misuses of the following functions (they will now + * be out-of-line, so there is a runtime penalty!). + * + * strstr, strchr, strrchr: + * Return const char * if first argument is const (gcc only). + * + * isalnum, isalpha, isascii, isblank, iscntrl, isdigit, isgraph, + * islower, isprint, ispunct, isspace, isupper, isxdigit: + * Static and runtime check that input is EOF or an *unsigned* + * char, as per C standard (really!). + * + * Example: + * #include + * #include + * + * int main(int argc, char *argv[]) + * { + * if (argc > 1 && streq(argv[1], "--verbose")) + * printf("verbose set\n"); + * if (argc > 1 && strstarts(argv[1], "--")) + * printf("Some option set\n"); + * if (argc > 1 && strends(argv[1], "cow-powers")) + * printf("Magic option set\n"); + * return 0; + * } + * + * License: CC0 (Public domain) + * Author: Rusty Russell + */ +int main(int argc, char *argv[]) +{ + if (argc != 2) + return 1; + + if (strcmp(argv[1], "depends") == 0) { + printf("ccan/build_assert\n"); + return 0; + } + + return 1; +} diff --git a/src/ccan/ccan/str/debug.c b/src/ccan/ccan/str/debug.c new file mode 100644 index 0000000000..8c519442d7 --- /dev/null +++ b/src/ccan/ccan/str/debug.c @@ -0,0 +1,108 @@ +/* CC0 (Public domain) - see LICENSE file for details */ +#include "config.h" +#include +#include +#include +#include + +#ifdef CCAN_STR_DEBUG +/* Because we mug the real ones with macros, we need our own wrappers. */ +int str_isalnum(int i) +{ + assert(i >= -1 && i < 256); + return isalnum(i); +} + +int str_isalpha(int i) +{ + assert(i >= -1 && i < 256); + return isalpha(i); +} + +int str_isascii(int i) +{ + assert(i >= -1 && i < 256); + return isascii(i); +} + +#if HAVE_ISBLANK +int str_isblank(int i) +{ + assert(i >= -1 && i < 256); + return isblank(i); +} +#endif + +int str_iscntrl(int i) +{ + assert(i >= -1 && i < 256); + return iscntrl(i); +} + +int str_isdigit(int i) +{ + assert(i >= -1 && i < 256); + return isdigit(i); +} + +int str_isgraph(int i) +{ + assert(i >= -1 && i < 256); + return isgraph(i); +} + +int str_islower(int i) +{ + assert(i >= -1 && i < 256); + return islower(i); +} + +int str_isprint(int i) +{ + assert(i >= -1 && i < 256); + return isprint(i); +} + +int str_ispunct(int i) +{ + assert(i >= -1 && i < 256); + return ispunct(i); +} + +int str_isspace(int i) +{ + assert(i >= -1 && i < 256); + return isspace(i); +} + +int str_isupper(int i) +{ + assert(i >= -1 && i < 256); + return isupper(i); +} + +int str_isxdigit(int i) +{ + assert(i >= -1 && i < 256); + return isxdigit(i); +} + +#undef strstr +#undef strchr +#undef strrchr + +char *str_strstr(const char *haystack, const char *needle) +{ + return strstr(haystack, needle); +} + +char *str_strchr(const char *haystack, int c) +{ + return strchr(haystack, c); +} + +char *str_strrchr(const char *haystack, int c) +{ + return strrchr(haystack, c); +} +#endif diff --git a/src/ccan/ccan/str/str.c b/src/ccan/ccan/str/str.c new file mode 100644 index 0000000000..a9245c1742 --- /dev/null +++ b/src/ccan/ccan/str/str.c @@ -0,0 +1,13 @@ +/* CC0 (Public domain) - see LICENSE file for details */ +#include + +size_t strcount(const char *haystack, const char *needle) +{ + size_t i = 0, nlen = strlen(needle); + + while ((haystack = strstr(haystack, needle)) != NULL) { + i++; + haystack += nlen; + } + return i; +} diff --git a/src/ccan/ccan/str/str.h b/src/ccan/ccan/str/str.h new file mode 100644 index 0000000000..d919b84d49 --- /dev/null +++ b/src/ccan/ccan/str/str.h @@ -0,0 +1,228 @@ +/* CC0 (Public domain) - see LICENSE file for details */ +#ifndef CCAN_STR_H +#define CCAN_STR_H +#include "config.h" +#include +#include +#include +#include + +/** + * streq - Are two strings equal? + * @a: first string + * @b: first string + * + * This macro is arguably more readable than "!strcmp(a, b)". + * + * Example: + * if (streq(somestring, "")) + * printf("String is empty!\n"); + */ +#define streq(a,b) (strcmp((a),(b)) == 0) + +/** + * strstarts - Does this string start with this prefix? + * @str: string to test + * @prefix: prefix to look for at start of str + * + * Example: + * if (strstarts(somestring, "foo")) + * printf("String %s begins with 'foo'!\n", somestring); + */ +#define strstarts(str,prefix) (strncmp((str),(prefix),strlen(prefix)) == 0) + +/** + * strends - Does this string end with this postfix? + * @str: string to test + * @postfix: postfix to look for at end of str + * + * Example: + * if (strends(somestring, "foo")) + * printf("String %s end with 'foo'!\n", somestring); + */ +static inline bool strends(const char *str, const char *postfix) +{ + if (strlen(str) < strlen(postfix)) + return false; + + return streq(str + strlen(str) - strlen(postfix), postfix); +} + +/** + * stringify - Turn expression into a string literal + * @expr: any C expression + * + * Example: + * #define PRINT_COND_IF_FALSE(cond) \ + * ((cond) || printf("%s is false!", stringify(cond))) + */ +#define stringify(expr) stringify_1(expr) +/* Double-indirection required to stringify expansions */ +#define stringify_1(expr) #expr + +/** + * strcount - Count number of (non-overlapping) occurrences of a substring. + * @haystack: a C string + * @needle: a substring + * + * Example: + * assert(strcount("aaa aaa", "a") == 6); + * assert(strcount("aaa aaa", "ab") == 0); + * assert(strcount("aaa aaa", "aa") == 2); + */ +size_t strcount(const char *haystack, const char *needle); + +/** + * STR_MAX_CHARS - Maximum possible size of numeric string for this type. + * @type_or_expr: a pointer or integer type or expression. + * + * This provides enough space for a nul-terminated string which represents the + * largest possible value for the type or expression. + * + * Note: The implementation adds extra space so hex values or negative + * values will fit (eg. sprintf(... "%p"). ) + * + * Example: + * char str[STR_MAX_CHARS(int)]; + * + * sprintf(str, "%i", 7); + */ +#define STR_MAX_CHARS(type_or_expr) \ + ((sizeof(type_or_expr) * CHAR_BIT + 8) / 9 * 3 + 2 \ + + STR_MAX_CHARS_TCHECK_(type_or_expr)) + +#if HAVE_TYPEOF +/* Only a simple type can have 0 assigned, so test that. */ +#define STR_MAX_CHARS_TCHECK_(type_or_expr) \ + (sizeof(({ typeof(type_or_expr) x = 0; x; }))*0) +#else +#define STR_MAX_CHARS_TCHECK_(type_or_expr) 0 +#endif + +/** + * cisalnum - isalnum() which takes a char (and doesn't accept EOF) + * @c: a character + * + * Surprisingly, the standard ctype.h isalnum() takes an int, which + * must have the value of EOF (-1) or an unsigned char. This variant + * takes a real char, and doesn't accept EOF. + */ +static inline bool cisalnum(char c) +{ + return isalnum((unsigned char)c); +} +static inline bool cisalpha(char c) +{ + return isalpha((unsigned char)c); +} +static inline bool cisascii(char c) +{ + return isascii((unsigned char)c); +} +#if HAVE_ISBLANK +static inline bool cisblank(char c) +{ + return isblank((unsigned char)c); +} +#endif +static inline bool ciscntrl(char c) +{ + return iscntrl((unsigned char)c); +} +static inline bool cisdigit(char c) +{ + return isdigit((unsigned char)c); +} +static inline bool cisgraph(char c) +{ + return isgraph((unsigned char)c); +} +static inline bool cislower(char c) +{ + return islower((unsigned char)c); +} +static inline bool cisprint(char c) +{ + return isprint((unsigned char)c); +} +static inline bool cispunct(char c) +{ + return ispunct((unsigned char)c); +} +static inline bool cisspace(char c) +{ + return isspace((unsigned char)c); +} +static inline bool cisupper(char c) +{ + return isupper((unsigned char)c); +} +static inline bool cisxdigit(char c) +{ + return isxdigit((unsigned char)c); +} + +#include + +/* These checks force things out of line, hence they are under DEBUG. */ +#ifdef CCAN_STR_DEBUG +#include + +/* These are commonly misused: they take -1 or an *unsigned* char value. */ +#undef isalnum +#undef isalpha +#undef isascii +#undef isblank +#undef iscntrl +#undef isdigit +#undef isgraph +#undef islower +#undef isprint +#undef ispunct +#undef isspace +#undef isupper +#undef isxdigit + +/* You can use a char if char is unsigned. */ +#if HAVE_BUILTIN_TYPES_COMPATIBLE_P && HAVE_TYPEOF +#define str_check_arg_(i) \ + ((i) + BUILD_ASSERT_OR_ZERO(!__builtin_types_compatible_p(typeof(i), \ + char) \ + || (char)255 > 0)) +#else +#define str_check_arg_(i) (i) +#endif + +#define isalnum(i) str_isalnum(str_check_arg_(i)) +#define isalpha(i) str_isalpha(str_check_arg_(i)) +#define isascii(i) str_isascii(str_check_arg_(i)) +#if HAVE_ISBLANK +#define isblank(i) str_isblank(str_check_arg_(i)) +#endif +#define iscntrl(i) str_iscntrl(str_check_arg_(i)) +#define isdigit(i) str_isdigit(str_check_arg_(i)) +#define isgraph(i) str_isgraph(str_check_arg_(i)) +#define islower(i) str_islower(str_check_arg_(i)) +#define isprint(i) str_isprint(str_check_arg_(i)) +#define ispunct(i) str_ispunct(str_check_arg_(i)) +#define isspace(i) str_isspace(str_check_arg_(i)) +#define isupper(i) str_isupper(str_check_arg_(i)) +#define isxdigit(i) str_isxdigit(str_check_arg_(i)) + +#if HAVE_TYPEOF +/* With GNU magic, we can make const-respecting standard string functions. */ +#undef strstr +#undef strchr +#undef strrchr + +/* + 0 is needed to decay array into pointer. */ +#define strstr(haystack, needle) \ + ((typeof((haystack) + 0))str_strstr((haystack), (needle))) +#define strchr(haystack, c) \ + ((typeof((haystack) + 0))str_strchr((haystack), (c))) +#define strrchr(haystack, c) \ + ((typeof((haystack) + 0))str_strrchr((haystack), (c))) +#endif +#endif /* CCAN_STR_DEBUG */ + +#endif /* CCAN_STR_H */ diff --git a/src/ccan/ccan/str/str_debug.h b/src/ccan/ccan/str/str_debug.h new file mode 100644 index 0000000000..92c10c41cc --- /dev/null +++ b/src/ccan/ccan/str/str_debug.h @@ -0,0 +1,30 @@ +/* CC0 (Public domain) - see LICENSE file for details */ +#ifndef CCAN_STR_DEBUG_H +#define CCAN_STR_DEBUG_H + +/* #define CCAN_STR_DEBUG 1 */ + +#ifdef CCAN_STR_DEBUG +/* Because we mug the real ones with macros, we need our own wrappers. */ +int str_isalnum(int i); +int str_isalpha(int i); +int str_isascii(int i); +#if HAVE_ISBLANK +int str_isblank(int i); +#endif +int str_iscntrl(int i); +int str_isdigit(int i); +int str_isgraph(int i); +int str_islower(int i); +int str_isprint(int i); +int str_ispunct(int i); +int str_isspace(int i); +int str_isupper(int i); +int str_isxdigit(int i); + +char *str_strstr(const char *haystack, const char *needle); +char *str_strchr(const char *s, int c); +char *str_strrchr(const char *s, int c); +#endif /* CCAN_STR_DEBUG */ + +#endif /* CCAN_STR_DEBUG_H */ diff --git a/src/ccan/licenses/BSD-MIT b/src/ccan/licenses/BSD-MIT new file mode 100644 index 0000000000..89de354795 --- /dev/null +++ b/src/ccan/licenses/BSD-MIT @@ -0,0 +1,17 @@ +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/src/ccan/licenses/CC0 b/src/ccan/licenses/CC0 new file mode 100644 index 0000000000..feb9b118e6 --- /dev/null +++ b/src/ccan/licenses/CC0 @@ -0,0 +1,28 @@ +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer exclusive Copyright and Related Rights (defined below) upon the creator and subsequent owner(s) (each and all, an "owner") of an original work of authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for the purpose of contributing to a commons of creative, cultural and scientific works ("Commons") that the public can reliably and without fear of later claims of infringement build upon, modify, incorporate in other works, reuse and redistribute as freely as possible in any form whatsoever and for any purposes, including without limitation commercial purposes. These owners may contribute to the Commons to promote the ideal of a free culture and the further production of creative, cultural and scientific works, or to gain reputation or greater distribution for their Work in part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any expectation of additional consideration or compensation, the person associating CC0 with a Work (the "Affirmer"), to the extent that he or she is an owner of Copyright and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and publicly distribute the Work under its terms, with knowledge of his or her Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be protected by copyright and related or neighboring rights ("Copyright and Related Rights"). Copyright and Related Rights include, but are not limited to, the following: + + the right to reproduce, adapt, distribute, perform, display, communicate, and translate a Work; + moral rights retained by the original author(s) and/or performer(s); + publicity and privacy rights pertaining to a person's image or likeness depicted in a Work; + rights protecting against unfair competition in regards to a Work, subject to the limitations in paragraph 4(a), below; + rights protecting the extraction, dissemination, use and reuse of data in a Work; + database rights (such as those arising under Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, and under any national implementation thereof, including any amended or successor version of such directive); and + other similar, equivalent or corresponding rights throughout the world based on applicable law or treaty, and any national implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention of, applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and unconditionally waives, abandons, and surrenders all of Affirmer's Copyright and Related Rights and associated claims and causes of action, whether now known or unknown (including existing as well as future claims and causes of action), in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each member of the public at large and to the detriment of Affirmer's heirs and successors, fully intending that such Waiver shall not be subject to revocation, rescission, cancellation, termination, or any other legal or equitable action to disrupt the quiet enjoyment of the Work by the public as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason be judged legally invalid or ineffective under applicable law, then the Waiver shall be preserved to the maximum extent permitted taking into account Affirmer's express Statement of Purpose. In addition, to the extent the Waiver is so judged Affirmer hereby grants to each affected person a royalty-free, non transferable, non sublicensable, non exclusive, irrevocable and unconditional license to exercise Affirmer's Copyright and Related Rights in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "License"). The License shall be deemed effective as of the date CC0 was applied by Affirmer to the Work. Should any part of the License for any reason be judged legally invalid or ineffective under applicable law, such partial invalidity or ineffectiveness shall not invalidate the remainder of the License, and in such case Affirmer hereby affirms that he or she will not (i) exercise any of his or her remaining Copyright and Related Rights in the Work or (ii) assert any associated claims and causes of action with respect to the Work, in either case contrary to Affirmer's express Statement of Purpose. + +4. Limitations and Disclaimers. + + No trademark or patent rights held by Affirmer are waived, abandoned, surrendered, licensed or otherwise affected by this document. + Affirmer offers the Work as-is and makes no representations or warranties of any kind concerning the Work, express, implied, statutory or otherwise, including without limitation warranties of title, merchantability, fitness for a particular purpose, non infringement, or the absence of latent or other defects, accuracy, or the present or absence of errors, whether or not discoverable, all to the greatest extent permissible under applicable law. + Affirmer disclaims responsibility for clearing rights of other persons that may apply to the Work or any use thereof, including without limitation any person's Copyright and Related Rights in the Work. Further, Affirmer disclaims responsibility for obtaining any necessary consents, permissions or other rights required for any use of the Work. + Affirmer understands and acknowledges that Creative Commons is not a party to this document and has no duty or obligation with respect to this CC0 or use of the Work. diff --git a/src/ccan/tools/configurator/configurator.c b/src/ccan/tools/configurator/configurator.c new file mode 100644 index 0000000000..dd5587c3b5 --- /dev/null +++ b/src/ccan/tools/configurator/configurator.c @@ -0,0 +1,563 @@ +/* Simple tool to create config.h. + * Would be much easier with ccan modules, but deliberately standalone. + * + * Copyright 2011 Rusty Russell . MIT license. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEFAULT_COMPILER "cc" +#define DEFAULT_FLAGS "-g3 -ggdb -Wall -Wundef -Wmissing-prototypes -Wmissing-declarations -Wstrict-prototypes -Wold-style-definition" + +#define OUTPUT_FILE "configurator.out" +#define INPUT_FILE "configuratortest.c" + +static int verbose; + +enum test_style { + OUTSIDE_MAIN = 0x1, + DEFINES_FUNC = 0x2, + INSIDE_MAIN = 0x4, + DEFINES_EVERYTHING = 0x8, + MAY_NOT_COMPILE = 0x10, + EXECUTE = 0x8000 +}; + +struct test { + const char *name; + enum test_style style; + const char *depends; + const char *link; + const char *fragment; + const char *overrides; /* On success, force this to '1' */ + bool done; + bool answer; +}; + +static struct test tests[] = { + { "HAVE_32BIT_OFF_T", DEFINES_EVERYTHING|EXECUTE, NULL, NULL, + "#include \n" + "int main(int argc, char *argv[]) {\n" + " return sizeof(off_t) == 4 ? 0 : 1;\n" + "}\n" }, + { "HAVE_ALIGNOF", INSIDE_MAIN, NULL, NULL, + "return __alignof__(double) > 0 ? 0 : 1;" }, + { "HAVE_ASPRINTF", DEFINES_FUNC, NULL, NULL, + "#define _GNU_SOURCE\n" + "#include \n" + "static char *func(int x) {" + " char *p;\n" + " if (asprintf(&p, \"%u\", x) == -1) p = NULL;" + " return p;\n" + "}" }, + { "HAVE_ATTRIBUTE_COLD", DEFINES_FUNC, NULL, NULL, + "static int __attribute__((cold)) func(int x) { return x; }" }, + { "HAVE_ATTRIBUTE_CONST", DEFINES_FUNC, NULL, NULL, + "static int __attribute__((const)) func(int x) { return x; }" }, + { "HAVE_ATTRIBUTE_PURE", DEFINES_FUNC, NULL, NULL, + "static int __attribute__((pure)) func(int x) { return x; }" }, + { "HAVE_ATTRIBUTE_MAY_ALIAS", OUTSIDE_MAIN, NULL, NULL, + "typedef short __attribute__((__may_alias__)) short_a;" }, + { "HAVE_ATTRIBUTE_NORETURN", DEFINES_FUNC, NULL, NULL, + "#include \n" + "static void __attribute__((noreturn)) func(int x) { exit(x); }" }, + { "HAVE_ATTRIBUTE_PRINTF", DEFINES_FUNC, NULL, NULL, + "static void __attribute__((format(__printf__, 1, 2))) func(const char *fmt, ...) { }" }, + { "HAVE_ATTRIBUTE_UNUSED", OUTSIDE_MAIN, NULL, NULL, + "static int __attribute__((unused)) func(int x) { return x; }" }, + { "HAVE_ATTRIBUTE_USED", OUTSIDE_MAIN, NULL, NULL, + "static int __attribute__((used)) func(int x) { return x; }" }, + { "HAVE_BACKTRACE", DEFINES_FUNC, NULL, NULL, + "#include \n" + "static int func(int x) {" + " void *bt[10];\n" + " return backtrace(bt, 10) < x;\n" + "}" }, + { "HAVE_BIG_ENDIAN", INSIDE_MAIN|EXECUTE, NULL, NULL, + "union { int i; char c[sizeof(int)]; } u;\n" + "u.i = 0x01020304;\n" + "return u.c[0] == 0x01 && u.c[1] == 0x02 && u.c[2] == 0x03 && u.c[3] == 0x04 ? 0 : 1;" }, + { "HAVE_BSWAP_64", DEFINES_FUNC, "HAVE_BYTESWAP_H", NULL, + "#include \n" + "static int func(int x) { return bswap_64(x); }" }, + { "HAVE_BUILTIN_CHOOSE_EXPR", INSIDE_MAIN, NULL, NULL, + "return __builtin_choose_expr(1, 0, \"garbage\");" }, + { "HAVE_BUILTIN_CLZ", INSIDE_MAIN, NULL, NULL, + "return __builtin_clz(1) == (sizeof(int)*8 - 1) ? 0 : 1;" }, + { "HAVE_BUILTIN_CLZL", INSIDE_MAIN, NULL, NULL, + "return __builtin_clzl(1) == (sizeof(long)*8 - 1) ? 0 : 1;" }, + { "HAVE_BUILTIN_CLZLL", INSIDE_MAIN, NULL, NULL, + "return __builtin_clzll(1) == (sizeof(long long)*8 - 1) ? 0 : 1;" }, + { "HAVE_BUILTIN_CTZ", INSIDE_MAIN, NULL, NULL, + "return __builtin_ctz(1 << (sizeof(int)*8 - 1)) == (sizeof(int)*8 - 1) ? 0 : 1;" }, + { "HAVE_BUILTIN_CTZL", INSIDE_MAIN, NULL, NULL, + "return __builtin_ctzl(1UL << (sizeof(long)*8 - 1)) == (sizeof(long)*8 - 1) ? 0 : 1;" }, + { "HAVE_BUILTIN_CTZLL", INSIDE_MAIN, NULL, NULL, + "return __builtin_ctzll(1ULL << (sizeof(long long)*8 - 1)) == (sizeof(long long)*8 - 1) ? 0 : 1;" }, + { "HAVE_BUILTIN_CONSTANT_P", INSIDE_MAIN, NULL, NULL, + "return __builtin_constant_p(1) ? 0 : 1;" }, + { "HAVE_BUILTIN_EXPECT", INSIDE_MAIN, NULL, NULL, + "return __builtin_expect(argc == 1, 1) ? 0 : 1;" }, + { "HAVE_BUILTIN_FFS", INSIDE_MAIN, NULL, NULL, + "return __builtin_ffs(0) == 0 ? 0 : 1;" }, + { "HAVE_BUILTIN_FFSL", INSIDE_MAIN, NULL, NULL, + "return __builtin_ffsl(0L) == 0 ? 0 : 1;" }, + { "HAVE_BUILTIN_FFSLL", INSIDE_MAIN, NULL, NULL, + "return __builtin_ffsll(0LL) == 0 ? 0 : 1;" }, + { "HAVE_BUILTIN_POPCOUNTL", INSIDE_MAIN, NULL, NULL, + "return __builtin_popcountl(255L) == 8 ? 0 : 1;" }, + { "HAVE_BUILTIN_TYPES_COMPATIBLE_P", INSIDE_MAIN, NULL, NULL, + "return __builtin_types_compatible_p(char *, int) ? 1 : 0;" }, + { "HAVE_ICCARM_INTRINSICS", DEFINES_FUNC, NULL, NULL, + "#include \n" + "int func(int v) {\n" + " return __CLZ(__RBIT(v));\n" + "}" }, + { "HAVE_BYTESWAP_H", OUTSIDE_MAIN, NULL, NULL, + "#include \n" }, + { "HAVE_CLOCK_GETTIME", + DEFINES_FUNC, "HAVE_STRUCT_TIMESPEC", NULL, + "#include \n" + "static struct timespec func(void) {\n" + " struct timespec ts;\n" + " clock_gettime(CLOCK_REALTIME, &ts);\n" + " return ts;\n" + "}\n" }, + { "HAVE_CLOCK_GETTIME_IN_LIBRT", + DEFINES_FUNC, + "HAVE_STRUCT_TIMESPEC !HAVE_CLOCK_GETTIME", + "-lrt", + "#include \n" + "static struct timespec func(void) {\n" + " struct timespec ts;\n" + " clock_gettime(CLOCK_REALTIME, &ts);\n" + " return ts;\n" + "}\n", + /* This means HAVE_CLOCK_GETTIME, too */ + "HAVE_CLOCK_GETTIME" }, + { "HAVE_COMPOUND_LITERALS", INSIDE_MAIN, NULL, NULL, + "int *foo = (int[]) { 1, 2, 3, 4 };\n" + "return foo[0] ? 0 : 1;" }, + { "HAVE_FCHDIR", DEFINES_EVERYTHING|EXECUTE, NULL, NULL, + "#include \n" + "#include \n" + "#include \n" + "#include \n" + "int main(void) {\n" + " int fd = open(\"..\", O_RDONLY);\n" + " return fchdir(fd) == 0 ? 0 : 1;\n" + "}\n" }, + { "HAVE_ERR_H", DEFINES_FUNC, NULL, NULL, + "#include \n" + "static void func(int arg) {\n" + " if (arg == 0)\n" + " err(1, \"err %u\", arg);\n" + " if (arg == 1)\n" + " errx(1, \"err %u\", arg);\n" + " if (arg == 3)\n" + " warn(\"warn %u\", arg);\n" + " if (arg == 4)\n" + " warnx(\"warn %u\", arg);\n" + "}\n" }, + { "HAVE_FILE_OFFSET_BITS", DEFINES_EVERYTHING|EXECUTE, + "HAVE_32BIT_OFF_T", NULL, + "#define _FILE_OFFSET_BITS 64\n" + "#include \n" + "int main(int argc, char *argv[]) {\n" + " return sizeof(off_t) == 8 ? 0 : 1;\n" + "}\n" }, + { "HAVE_FOR_LOOP_DECLARATION", INSIDE_MAIN, NULL, NULL, + "for (int i = 0; i < argc; i++) { return 0; };\n" + "return 1;" }, + { "HAVE_FLEXIBLE_ARRAY_MEMBER", OUTSIDE_MAIN, NULL, NULL, + "struct foo { unsigned int x; int arr[]; };" }, + { "HAVE_GETPAGESIZE", DEFINES_FUNC, NULL, NULL, + "#include \n" + "static int func(void) { return getpagesize(); }" }, + { "HAVE_ISBLANK", DEFINES_FUNC, NULL, NULL, + "#define _GNU_SOURCE\n" + "#include \n" + "static int func(void) { return isblank(' '); }" }, + { "HAVE_LITTLE_ENDIAN", INSIDE_MAIN|EXECUTE, NULL, NULL, + "union { int i; char c[sizeof(int)]; } u;\n" + "u.i = 0x01020304;\n" + "return u.c[0] == 0x04 && u.c[1] == 0x03 && u.c[2] == 0x02 && u.c[3] == 0x01 ? 0 : 1;" }, + { "HAVE_MEMMEM", DEFINES_FUNC, NULL, NULL, + "#define _GNU_SOURCE\n" + "#include \n" + "static void *func(void *h, size_t hl, void *n, size_t nl) {\n" + "return memmem(h, hl, n, nl);" + "}\n", }, + { "HAVE_MEMRCHR", DEFINES_FUNC, NULL, NULL, + "#define _GNU_SOURCE\n" + "#include \n" + "static void *func(void *s, int c, size_t n) {\n" + "return memrchr(s, c, n);" + "}\n", }, + { "HAVE_MMAP", DEFINES_FUNC, NULL, NULL, + "#include \n" + "static void *func(int fd) {\n" + " return mmap(0, 65536, PROT_READ, MAP_SHARED, fd, 0);\n" + "}" }, + { "HAVE_PROC_SELF_MAPS", DEFINES_EVERYTHING|EXECUTE, NULL, NULL, + "#include \n" + "#include \n" + "#include \n" + "int main(void) {\n" + " return open(\"/proc/self/maps\", O_RDONLY) != -1 ? 0 : 1;\n" + "}\n" }, + { "HAVE_QSORT_R_PRIVATE_LAST", + DEFINES_EVERYTHING|EXECUTE|MAY_NOT_COMPILE, NULL, NULL, + "#define _GNU_SOURCE 1\n" + "#include \n" + "static int cmp(const void *lp, const void *rp, void *priv) {\n" + " *(unsigned int *)priv = 1;\n" + " return *(const int *)lp - *(const int *)rp; }\n" + "int main(void) {\n" + " int array[] = { 9, 2, 5 };\n" + " unsigned int called = 0;\n" + " qsort_r(array, 3, sizeof(int), cmp, &called);\n" + " return called && array[0] == 2 && array[1] == 5 && array[2] == 9 ? 0 : 1;\n" + "}\n" }, + { "HAVE_STRUCT_TIMESPEC", + DEFINES_FUNC, NULL, NULL, + "#include \n" + "static void func(void) {\n" + " struct timespec ts;\n" + " ts.tv_sec = ts.tv_nsec = 1;\n" + "}\n" }, + { "HAVE_SECTION_START_STOP", + DEFINES_FUNC, NULL, NULL, + "static void *__attribute__((__section__(\"mysec\"))) p = &p;\n" + "static int func(void) {\n" + " extern void *__start_mysec[], *__stop_mysec[];\n" + " return __stop_mysec - __start_mysec;\n" + "}\n" }, + { "HAVE_STACK_GROWS_UPWARDS", DEFINES_EVERYTHING|EXECUTE, NULL, NULL, + "static long nest(const void *base, unsigned int i)\n" + "{\n" + " if (i == 0)\n" + " return (const char *)&i - (const char *)base;\n" + " return nest(base, i-1);\n" + "}\n" + "int main(int argc, char *argv[]) {\n" + " return (nest(&argc, argc) > 0) ? 0 : 1\n;" + "}\n" }, + { "HAVE_STATEMENT_EXPR", INSIDE_MAIN, NULL, NULL, + "return ({ int x = argc; x == argc ? 0 : 1; });" }, + { "HAVE_SYS_FILIO_H", OUTSIDE_MAIN, NULL, NULL, /* Solaris needs this for FIONREAD */ + "#include \n" }, + { "HAVE_SYS_TERMIOS_H", OUTSIDE_MAIN, NULL, NULL, + "#include \n" }, + { "HAVE_TYPEOF", INSIDE_MAIN, NULL, NULL, + "__typeof__(argc) i; i = argc; return i == argc ? 0 : 1;" }, + { "HAVE_UTIME", DEFINES_FUNC, NULL, NULL, + "#include \n" + "#include \n" + "static int func(const char *filename) {\n" + " struct utimbuf times = { 0 };\n" + " return utime(filename, ×);\n" + "}" }, + { "HAVE_WARN_UNUSED_RESULT", DEFINES_FUNC, NULL, NULL, + "#include \n" + "#include \n" + "static __attribute__((warn_unused_result)) int func(int i) {\n" + " return i + 1;\n" + "}" }, +}; + +static char *grab_fd(int fd) +{ + int ret; + size_t max, size = 0; + char *buffer; + + max = 16384; + buffer = malloc(max+1); + while ((ret = read(fd, buffer + size, max - size)) > 0) { + size += ret; + if (size == max) + buffer = realloc(buffer, max *= 2); + } + if (ret < 0) + err(1, "reading from command"); + buffer[size] = '\0'; + return buffer; +} + +static char *run(const char *cmd, int *exitstatus) +{ + pid_t pid; + int p[2]; + char *ret; + int status; + + if (pipe(p) != 0) + err(1, "creating pipe"); + + pid = fork(); + if (pid == -1) + err(1, "forking"); + + if (pid == 0) { + if (dup2(p[1], STDOUT_FILENO) != STDOUT_FILENO + || dup2(p[1], STDERR_FILENO) != STDERR_FILENO + || close(p[0]) != 0 + || close(STDIN_FILENO) != 0 + || open("/dev/null", O_RDONLY) != STDIN_FILENO) + exit(128); + + status = system(cmd); + if (WIFEXITED(status)) + exit(WEXITSTATUS(status)); + /* Here's a hint... */ + exit(128 + WTERMSIG(status)); + } + + close(p[1]); + ret = grab_fd(p[0]); + /* This shouldn't fail... */ + if (waitpid(pid, &status, 0) != pid) + err(1, "Failed to wait for child"); + close(p[0]); + if (WIFEXITED(status)) + *exitstatus = WEXITSTATUS(status); + else + *exitstatus = -WTERMSIG(status); + return ret; +} + +static char *connect_args(const char *argv[], const char *extra) +{ + unsigned int i, len = strlen(extra) + 1; + char *ret; + + for (i = 1; argv[i]; i++) + len += 1 + strlen(argv[i]); + + ret = malloc(len); + len = 0; + for (i = 1; argv[i]; i++) { + strcpy(ret + len, argv[i]); + len += strlen(argv[i]); + if (argv[i+1]) + ret[len++] = ' '; + } + strcpy(ret + len, extra); + return ret; +} + +static struct test *find_test(const char *name) +{ + unsigned int i; + + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + if (strcmp(tests[i].name, name) == 0) + return &tests[i]; + } + abort(); +} + +#define PRE_BOILERPLATE "/* Test program generated by configurator. */\n" +#define MAIN_START_BOILERPLATE "int main(int argc, char *argv[]) {\n" +#define USE_FUNC_BOILERPLATE "(void)func;\n" +#define MAIN_BODY_BOILERPLATE "return 0;\n" +#define MAIN_END_BOILERPLATE "}\n" + +static bool run_test(const char *cmd, struct test *test) +{ + char *output; + FILE *outf; + int status; + + if (test->done) + return test->answer; + + if (test->depends) { + size_t len; + const char *deps = test->depends; + char *dep; + + /* Space-separated dependencies, could be ! for inverse. */ + while ((len = strcspn(deps, " "))) { + bool positive = true; + if (deps[len]) { + dep = strdup(deps); + dep[len] = '\0'; + } else { + dep = (char *)deps; + } + + if (dep[0] == '!') { + dep++; + positive = false; + } + if (run_test(cmd, find_test(dep)) != positive) { + test->answer = false; + test->done = true; + return test->answer; + } + deps += len; + deps += strspn(deps, " "); + } + } + + outf = fopen(INPUT_FILE, "w"); + if (!outf) + err(1, "creating %s", INPUT_FILE); + + fprintf(outf, "%s", PRE_BOILERPLATE); + switch (test->style & ~(EXECUTE|MAY_NOT_COMPILE)) { + case INSIDE_MAIN: + fprintf(outf, "%s", MAIN_START_BOILERPLATE); + fprintf(outf, "%s", test->fragment); + fprintf(outf, "%s", MAIN_END_BOILERPLATE); + break; + case OUTSIDE_MAIN: + fprintf(outf, "%s", test->fragment); + fprintf(outf, "%s", MAIN_START_BOILERPLATE); + fprintf(outf, "%s", MAIN_BODY_BOILERPLATE); + fprintf(outf, "%s", MAIN_END_BOILERPLATE); + break; + case DEFINES_FUNC: + fprintf(outf, "%s", test->fragment); + fprintf(outf, "%s", MAIN_START_BOILERPLATE); + fprintf(outf, "%s", USE_FUNC_BOILERPLATE); + fprintf(outf, "%s", MAIN_BODY_BOILERPLATE); + fprintf(outf, "%s", MAIN_END_BOILERPLATE); + break; + case DEFINES_EVERYTHING: + fprintf(outf, "%s", test->fragment); + break; + default: + abort(); + + } + fclose(outf); + + if (verbose > 1) + if (system("cat " INPUT_FILE) == -1); + + if (test->link) { + char *newcmd; + newcmd = malloc(strlen(cmd) + strlen(" ") + + strlen(test->link) + 1); + sprintf(newcmd, "%s %s", cmd, test->link); + if (verbose > 1) + printf("Extra link line: %s", newcmd); + cmd = newcmd; + } + + output = run(cmd, &status); + if (status != 0 || strstr(output, "warning")) { + if (verbose) + printf("Compile %s for %s, status %i: %s\n", + status ? "fail" : "warning", + test->name, status, output); + if ((test->style & EXECUTE) && !(test->style & MAY_NOT_COMPILE)) + errx(1, "Test for %s did not compile:\n%s", + test->name, output); + test->answer = false; + free(output); + } else { + /* Compile succeeded. */ + free(output); + /* We run INSIDE_MAIN tests for sanity checking. */ + if ((test->style & EXECUTE) || (test->style & INSIDE_MAIN)) { + output = run("./" OUTPUT_FILE, &status); + if (!(test->style & EXECUTE) && status != 0) + errx(1, "Test for %s failed with %i:\n%s", + test->name, status, output); + if (verbose && status) + printf("%s exited %i\n", test->name, status); + free(output); + } + test->answer = (status == 0); + } + test->done = true; + + if (test->answer && test->overrides) { + struct test *override = find_test(test->overrides); + override->done = true; + override->answer = true; + } + return test->answer; +} + +int main(int argc, const char *argv[]) +{ + char *cmd; + unsigned int i; + const char *default_args[] + = { "", DEFAULT_COMPILER, DEFAULT_FLAGS, NULL }; + + if (argc > 1) { + if (strcmp(argv[1], "--help") == 0) { + printf("Usage: configurator [-v] [ ...]\n" + " will have \"-o \" appended\n" + "Default: %s %s\n", + DEFAULT_COMPILER, DEFAULT_FLAGS); + exit(0); + } + if (strcmp(argv[1], "-v") == 0) { + argc--; + argv++; + verbose = 1; + } else if (strcmp(argv[1], "-vv") == 0) { + argc--; + argv++; + verbose = 2; + } + } + + if (argc == 1) + argv = default_args; + + cmd = connect_args(argv, " -o " OUTPUT_FILE " " INPUT_FILE); + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) + run_test(cmd, &tests[i]); + + unlink(OUTPUT_FILE); + unlink(INPUT_FILE); + + printf("/* Generated by CCAN configurator */\n" + "#ifndef CCAN_CONFIG_H\n" + "#define CCAN_CONFIG_H\n"); + printf("#ifndef _GNU_SOURCE\n"); + printf("#define _GNU_SOURCE /* Always use GNU extensions. */\n"); + printf("#endif\n"); + printf("#define CCAN_COMPILER \"%s\"\n", argv[1]); + printf("#define CCAN_CFLAGS \"%s\"\n\n", connect_args(argv+1, "")); + /* This one implies "#include +#include + #include "fabrics.h" #include "types.h" #include "cmd.h" @@ -22,7 +24,6 @@ #define NVMF_HOSTID_SIZE 36 #define NVME_HOSTNQN_ID SD_ID128_MAKE(c7,f4,61,81,12,be,49,32,8c,83,10,6f,9d,dd,d8,6b) -#define ARRAY_SIZE(x) (sizeof(x) / sizeof (*x)) const char *nvmf_dev = "/dev/nvme-fabrics"; const char *nvmf_hostnqn_file = "/etc/nvme/hostnqn"; diff --git a/src/nvme/filters.c b/src/nvme/filters.c index ed0d402f50..44e31fb607 100644 --- a/src/nvme/filters.c +++ b/src/nvme/filters.c @@ -5,9 +5,7 @@ #include #include -#include #include -#include #include #include #include diff --git a/src/nvme/filters.h b/src/nvme/filters.h index bc97cf8391..0c6df91667 100644 --- a/src/nvme/filters.h +++ b/src/nvme/filters.h @@ -6,46 +6,77 @@ /** * nvme_namespace_filter() - + * @d: + * + * Return: */ int nvme_namespace_filter(const struct dirent *d); /** * nvme_paths_filter() - + * @d: + * + * Return: */ int nvme_paths_filter(const struct dirent *d); /** * nvme_ctrls_filter() - + * @d: + * + * Return: */ int nvme_ctrls_filter(const struct dirent *d); /** * nvme_subsys_filter() - + * @d: + * + * Return: */ int nvme_subsys_filter(const struct dirent *d); /** * nvme_scan_subsystems() - + * @subsys: + * + * Return: */ int nvme_scan_subsystems(struct dirent ***subsys); /** * nvme_scan_subsystem_ctrls() - + * @s: + * @ctrls: + * + * Return: */ int nvme_scan_subsystem_ctrls(nvme_subsystem_t s, struct dirent ***ctrls); /** * nvme_scan_subsystem_namespaces() - + * @s: + * @namespaces: + * + * Return: */ int nvme_scan_subsystem_namespaces(nvme_subsystem_t s, struct dirent ***namespaces); /** * nvme_scan_ctrl_namespace_paths() - + * @c: + * @namespaces: + * + * Return: */ int nvme_scan_ctrl_namespace_paths(nvme_ctrl_t c, struct dirent ***namespaces); /** * nvme_scan_ctrl_namespaces() - + * @c: + * @namespaces: + * + * Return: */ int nvme_scan_ctrl_namespaces(nvme_ctrl_t c, struct dirent ***namespaces); diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index a0d22f7716..c2d219cc7a 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -9,6 +9,8 @@ #include #include +#include + #include "ioctl.h" #include "cmd.h" #include "types.h" @@ -365,11 +367,13 @@ static int __nvme_identify(int fd, __u8 cns, __u32 nsid, void *data) int nvme_identify_ctrl(int fd, struct nvme_id_ctrl *id) { + BUILD_ASSERT(sizeof(struct nvme_id_ctrl) == 4096); return __nvme_identify(fd, NVME_IDENTIFY_CNS_CTRL, NVME_NSID_NONE, id); } int nvme_identify_ns(int fd, __u32 nsid, struct nvme_id_ns *ns) { + BUILD_ASSERT(sizeof(struct nvme_id_ns) == 4096); return __nvme_identify(fd, NVME_IDENTIFY_CNS_NS, nsid, ns); } @@ -380,6 +384,7 @@ int nvme_identify_allocated_ns(int fd, __u32 nsid, struct nvme_id_ns *ns) int nvme_identify_active_ns_list(int fd, __u32 nsid, struct nvme_ns_list *list) { + BUILD_ASSERT(sizeof(struct nvme_ns_list) == 4096); return __nvme_identify(fd, NVME_IDENTIFY_CNS_NS_ACTIVE_LIST, nsid, list); } @@ -394,6 +399,7 @@ int nvme_identify_allocated_ns_list(int fd, __u32 nsid, int nvme_identify_ctrl_list(int fd, __u16 cntid, struct nvme_ctrl_list *ctrlist) { + BUILD_ASSERT(sizeof(struct nvme_ctrl_list) == 4096); return nvme_identify(fd, NVME_IDENTIFY_CNS_CTRL_LIST, NVME_NSID_NONE, cntid, NVME_NVMSETID_NONE, NVME_UUID_NONE, ctrlist); @@ -414,6 +420,7 @@ int nvme_identify_ns_descs(int fd, __u32 nsid, struct nvme_ns_id_desc *descs) int nvme_identify_nvmset_list(int fd, __u16 nvmsetid, struct nvme_id_nvmset_list *nvmset) { + BUILD_ASSERT(sizeof(struct nvme_id_nvmset_list) == 4096); return nvme_identify(fd, NVME_IDENTIFY_CNS_NVMSET_LIST, NVME_NSID_NONE, NVME_CNTLID_NONE, nvmsetid, NVME_UUID_NONE, nvmset); @@ -422,6 +429,7 @@ int nvme_identify_nvmset_list(int fd, __u16 nvmsetid, int nvme_identify_primary_ctrl(int fd, __u16 cntid, struct nvme_primary_ctrl_cap *cap) { + BUILD_ASSERT(sizeof(struct nvme_primary_ctrl_cap) == 4096); return nvme_identify(fd, NVME_IDENTIFY_CNS_PRIMARY_CTRL_CAP, NVME_NSID_NONE, cntid, NVME_NVMSETID_NONE, NVME_UUID_NONE, cap); @@ -430,6 +438,7 @@ int nvme_identify_primary_ctrl(int fd, __u16 cntid, int nvme_identify_secondary_ctrl_list(int fd, __u16 cntid, struct nvme_secondary_ctrl_list *list) { + BUILD_ASSERT(sizeof(struct nvme_secondary_ctrl_list) == 4096); return nvme_identify(fd, NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST, NVME_NSID_NONE, cntid, NVME_NVMSETID_NONE, NVME_UUID_NONE, list); @@ -438,12 +447,14 @@ int nvme_identify_secondary_ctrl_list(int fd, __u16 cntid, int nvme_identify_ns_granularity(int fd, struct nvme_id_ns_granularity_list *list) { + BUILD_ASSERT(sizeof(struct nvme_id_ns_granularity_list) == 4096); return __nvme_identify(fd, NVME_IDENTIFY_CNS_NS_GRANULARITY, NVME_NSID_NONE, list); } int nvme_identify_uuid(int fd, struct nvme_id_uuid_list *list) { + BUILD_ASSERT(sizeof(struct nvme_id_uuid_list) == 4096); return __nvme_identify(fd, NVME_IDENTIFY_CNS_UUID_LIST, NVME_NSID_NONE, list); } @@ -489,12 +500,14 @@ static int __nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, bool rae, int nvme_get_log_error(int fd, unsigned nr_entries, bool rae, struct nvme_error_log_page *log) { + BUILD_ASSERT(sizeof(struct nvme_error_log_page) == 64); return __nvme_get_log(fd, NVME_LOG_LID_ERROR, rae, sizeof(*log) * nr_entries, log); } int nvme_get_log_smart(int fd, __u32 nsid, bool rae, struct nvme_smart_log *log) { + BUILD_ASSERT(sizeof(struct nvme_smart_log) == 512); return nvme_get_log(fd, NVME_LOG_LID_SMART, nsid, 0, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, sizeof(*log), log); @@ -502,6 +515,7 @@ int nvme_get_log_smart(int fd, __u32 nsid, bool rae, struct nvme_smart_log *log) int nvme_get_log_fw_slot(int fd, bool rae, struct nvme_firmware_slot *log) { + BUILD_ASSERT(sizeof(struct nvme_firmware_slot) == 512); return __nvme_get_log(fd, NVME_LOG_LID_FW_SLOT, rae, sizeof(*log), log); } @@ -514,12 +528,14 @@ int nvme_get_log_changed_ns_list(int fd, bool rae, struct nvme_ns_list *log) int nvme_get_log_cmd_effects(int fd, struct nvme_cmd_effects_log *log) { + BUILD_ASSERT(sizeof(struct nvme_cmd_effects_log) == 4096); return __nvme_get_log(fd, NVME_LOG_LID_CMD_EFFECTS, false, sizeof(*log), log); } int nvme_get_log_device_self_test(int fd, struct nvme_self_test_log *log) { + BUILD_ASSERT(sizeof(struct nvme_self_test_log) == 564); return __nvme_get_log(fd, NVME_LOG_LID_DEVICE_SELF_TEST, false, sizeof(*log), log); } @@ -531,6 +547,7 @@ enum nvme_cmd_get_log_telemetry_host_lsp { int nvme_get_log_create_telemetry_host(int fd, struct nvme_telemetry_log *log) { + BUILD_ASSERT(sizeof(struct nvme_telemetry_log) == 512); return nvme_get_log(fd, NVME_LOG_LID_TELEMETRY_HOST, NVME_NSID_NONE, 0, NVME_LOG_TELEM_HOST_LSP_CREATE, NVME_LOG_LSI_NONE, false, NVME_UUID_NONE, sizeof(*log), log); @@ -554,6 +571,7 @@ int nvme_get_log_telemetry_ctrl(int fd, bool rae, __u64 offset, __u32 len, int nvme_get_log_endurance_group(int fd, __u16 endgid, struct nvme_endurance_group_log *log) { + BUILD_ASSERT(sizeof(struct nvme_endurance_group_log) == 512); return nvme_get_log(fd, NVME_LOG_LID_ENDURANCE_GROUP, NVME_NSID_NONE, 0, NVME_LOG_LSP_NONE, endgid, false, NVME_UUID_NONE, sizeof(*log), log); @@ -562,6 +580,7 @@ int nvme_get_log_endurance_group(int fd, __u16 endgid, int nvme_get_log_predictable_lat_nvmset(int fd, __u16 nvmsetid, struct nvme_nvmset_predictable_lat_log *log) { + BUILD_ASSERT(sizeof(struct nvme_nvmset_predictable_lat_log) == 512); return nvme_get_log(fd, NVME_LOG_LID_PREDICTABLE_LAT_NVMSET, NVME_NSID_NONE, 0, NVME_LOG_LSP_NONE, nvmsetid, false, NVME_UUID_NONE, sizeof(*log), log); @@ -615,6 +634,7 @@ int nvme_get_log_discovery(int fd, bool rae, __u32 offset, __u32 len, void *log) int nvme_get_log_reservation(int fd, bool rae, struct nvme_resv_notification_log *log) { + BUILD_ASSERT(sizeof(struct nvme_resv_notification_log) == 64); return __nvme_get_log(fd, NVME_LOG_LID_RESERVATION, rae, sizeof(*log), log); } @@ -622,6 +642,7 @@ int nvme_get_log_reservation(int fd, bool rae, int nvme_get_log_sanitize(int fd, bool rae, struct nvme_sanitize_log_page *log) { + BUILD_ASSERT(sizeof(struct nvme_sanitize_log_page) == 512); return __nvme_get_log(fd, NVME_LOG_LID_SANITIZE, rae, sizeof(*log), log); } diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 38587453c2..a713dc8976 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -1,9 +1,10 @@ #ifndef _LIBNVME_IOCTL_H #define _LIBNVME_IOCTL_H -#include #include +#include "types.h" + /* * We can not always count on the kernel UAPI being installed. Use the same * 'ifdef' guard to avoid double definitions just in case. diff --git a/src/nvme/private.h b/src/nvme/private.h index 939aba7401..e49a1b1f99 100644 --- a/src/nvme/private.h +++ b/src/nvme/private.h @@ -2,15 +2,17 @@ #define _LIBNVME_PRIVATE_H #include -#include #include #include +#include + #include "tree.h" struct nvme_path { - TAILQ_ENTRY(nvme_path) entry; - TAILQ_ENTRY(nvme_path) nentry; + struct list_node entry; + struct list_node nentry; + struct nvme_ctrl *c; struct nvme_ns *n; @@ -21,8 +23,9 @@ struct nvme_path { }; struct nvme_ns { - TAILQ_ENTRY(nvme_ns) entry; - TAILQ_HEAD(, nvme_path) paths; + struct list_node entry; + struct list_head paths; + struct nvme_subsystem *s; struct nvme_ctrl *c; @@ -38,9 +41,10 @@ struct nvme_ns { }; struct nvme_ctrl { - TAILQ_ENTRY(nvme_ctrl) entry; - TAILQ_HEAD(, nvme_ns) namespaces; - TAILQ_HEAD(, nvme_path) paths; + struct list_node entry; + struct list_head paths; + struct list_head namespaces; + struct nvme_subsystem *s; int fd; @@ -59,9 +63,9 @@ struct nvme_ctrl { }; struct nvme_subsystem { - TAILQ_ENTRY(nvme_subsystem) entry; - TAILQ_HEAD(, nvme_ctrl) ctrls; - TAILQ_HEAD(, nvme_ns) namespaces; + struct list_node entry; + struct list_head ctrls; + struct list_head namespaces; struct nvme_root *r; char *name; @@ -70,7 +74,7 @@ struct nvme_subsystem { }; struct nvme_root { - TAILQ_HEAD(, nvme_subsystem) subsystems; + struct list_head subsystems; }; void nvme_free_ctrl(struct nvme_ctrl *c); diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 9de7d49301..881dfe5921 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -39,7 +39,7 @@ nvme_root_t nvme_scan_filter(nvme_scan_filter_t f) } memset(r, 0, sizeof(*r)); - TAILQ_INIT(&r->subsystems); + list_head_init(&r->subsystems); nvme_scan_topology(r, f); return r; } @@ -51,14 +51,14 @@ nvme_root_t nvme_scan() nvme_subsystem_t nvme_first_subsystem(nvme_root_t r) { - return TAILQ_FIRST(&r->subsystems); + return list_top(&r->subsystems, struct nvme_subsystem, entry); } nvme_subsystem_t nvme_next_subsystem(nvme_root_t r, nvme_subsystem_t s) { if (!s) return NULL; - return TAILQ_NEXT(s, entry); + return list_next(&r->subsystems, s, entry); } void nvme_refresh_topology(nvme_root_t r) @@ -105,26 +105,35 @@ const char *nvme_subsystem_get_name(nvme_subsystem_t s) nvme_ctrl_t nvme_subsystem_first_ctrl(nvme_subsystem_t s) { - return TAILQ_FIRST(&s->ctrls); + return list_top(&s->ctrls, struct nvme_ctrl, entry); } nvme_ctrl_t nvme_subsystem_next_ctrl(nvme_subsystem_t s, nvme_ctrl_t c) { if (!c) return NULL; - return TAILQ_NEXT(c, entry); + return list_next(&s->ctrls, c, entry); } nvme_ns_t nvme_subsystem_first_ns(nvme_subsystem_t s) { - return TAILQ_FIRST(&s->namespaces); + return list_top(&s->namespaces, struct nvme_ns, entry); } nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n) { if (!n) return NULL; - return TAILQ_NEXT(n, entry); + return list_next(&s->namespaces, n, entry); +} + +static void nvme_free_ns(struct nvme_ns *n) +{ + list_del_init(&n->entry); + close(n->fd); + free(n->name); + free(n->sysfs_dir); + free(n); } void nvme_free_subsystem(struct nvme_subsystem *s) @@ -132,14 +141,12 @@ void nvme_free_subsystem(struct nvme_subsystem *s) struct nvme_ctrl *c, *_c; struct nvme_ns *n, *_n; - if (s->r) - TAILQ_REMOVE(&s->r->subsystems, s, entry); - + list_del_init(&s->entry); nvme_subsystem_for_each_ctrl_safe(s, c, _c) nvme_free_ctrl(c); nvme_subsystem_for_each_ns_safe(s, n, _n) - nvme_subsystem_free_ns(n); + nvme_free_ns(n); free(s->name); free(s->sysfs_dir); @@ -200,12 +207,12 @@ int nvme_scan_subsystem(struct nvme_root *r, char *name, nvme_scan_filter_t f) s->name = strdup(name);; s->sysfs_dir = path; s->subsysnqn = nvme_get_subsys_attr(s, "subsysnqn"); - TAILQ_INIT(&s->ctrls); - TAILQ_INIT(&s->namespaces); + list_head_init(&s->ctrls); + list_head_init(&s->namespaces); nvme_subsystem_scan_namespaces(s); nvme_subsystem_scan_ctrls(s); - TAILQ_INSERT_TAIL(&r->subsystems, s, entry); + list_add(&r->subsystems, &s->entry); if (f && !f(s)) { nvme_free_subsystem(s); @@ -245,8 +252,8 @@ const char *nvme_path_get_ana_state(nvme_path_t p) void nvme_free_path(struct nvme_path *p) { - TAILQ_REMOVE(&p->c->paths, p, entry); - TAILQ_REMOVE(&p->n->paths, p, nentry); + list_del_init(&p->entry); + list_del_init(&p->nentry); free(p->name); free(p->sysfs_dir); free(p->ana_state); @@ -266,7 +273,7 @@ static void nvme_subsystem_set_path_ns(nvme_subsystem_t s, nvme_path_t p) sprintf(n_name, "nvme%dn%d", i, nsid); nvme_subsystem_for_each_ns(s, n) { if (!strcmp(n_name, nvme_ns_get_name(n))) { - TAILQ_INSERT_TAIL(&n->paths, p, nentry); + list_add(&n->paths, &p->nentry); p->n = n; } } @@ -303,7 +310,7 @@ int nvme_ctrl_scan_path(struct nvme_ctrl *c, char *name) free(grpid); } - TAILQ_INSERT_TAIL(&c->paths, p, entry); + list_add(&c->paths, &p->entry); return 0; free_path: @@ -388,26 +395,26 @@ int nvme_ctrl_identify(nvme_ctrl_t c, struct nvme_id_ctrl *id) nvme_ns_t nvme_ctrl_first_ns(nvme_ctrl_t c) { - return TAILQ_FIRST(&c->namespaces); + return list_top(&c->namespaces, struct nvme_ns, entry); } nvme_ns_t nvme_ctrl_next_ns(nvme_ctrl_t c, nvme_ns_t n) { if (!n) return NULL; - return TAILQ_NEXT(n, entry); + return list_next(&c->namespaces, n, entry); } nvme_path_t nvme_ctrl_first_path(nvme_ctrl_t c) { - return TAILQ_FIRST(&c->paths); + return list_top(&c->paths, struct nvme_path, entry); } nvme_path_t nvme_ctrl_next_path(nvme_ctrl_t c, nvme_path_t p) { if (!p) return NULL; - return TAILQ_NEXT(p, entry); + return list_next(&c->paths, p, entry); } int nvme_ctrl_disconnect(nvme_ctrl_t c) @@ -417,8 +424,7 @@ int nvme_ctrl_disconnect(nvme_ctrl_t c) void nvme_unlink_ctrl(nvme_ctrl_t c) { - if (c->s) - TAILQ_REMOVE(&c->s->ctrls, c, entry); + list_del_init(&c->entry); c->s = NULL; } @@ -433,7 +439,7 @@ void nvme_free_ctrl(nvme_ctrl_t c) nvme_free_path(p); nvme_ctrl_for_each_ns_safe(c, n, _n) - nvme_ctrl_free_ns(n); + nvme_free_ns(n); close(c->fd); free(c->name); @@ -501,8 +507,9 @@ static nvme_ctrl_t __nvme_ctrl_alloc(const char *path, const char *name) if (c->fd < 0) goto free_ctrl; - TAILQ_INIT(&c->namespaces); - TAILQ_INIT(&c->paths); + list_head_init(&c->namespaces); + list_head_init(&c->paths); + list_node_init(&c->entry); c->name = strdup(name); c->sysfs_dir = (char *)path; c->subsysnqn = nvme_get_ctrl_attr(c, "subsysnqn"); @@ -557,7 +564,7 @@ int nvme_subsystem_scan_ctrl(struct nvme_subsystem *s, char *name) c->s = s; nvme_ctrl_scan_namespaces(c); nvme_ctrl_scan_paths(c); - TAILQ_INSERT_TAIL(&s->ctrls, c, entry); + list_add(&s->ctrls, &c->entry); return 0; } @@ -705,26 +712,6 @@ int nvme_ns_flush(nvme_ns_t n) return nvme_flush(nvme_ns_get_fd(n), nvme_ns_get_nsid(n)); } -static void nvme_free_ns(struct nvme_ns *n) -{ - close(n->fd); - free(n->name); - free(n->sysfs_dir); - free(n); -} - -void nvme_ctrl_free_ns(struct nvme_ns *n) -{ - TAILQ_REMOVE(&n->s->namespaces, n, entry); - nvme_free_ns(n); -} - -void nvme_subsystem_free_ns(struct nvme_ns *n) -{ - TAILQ_REMOVE(&n->s->namespaces, n, entry); - nvme_free_ns(n); -} - static void nvme_ns_init(struct nvme_ns *n) { struct nvme_id_ns ns = { 0 }; @@ -766,7 +753,7 @@ static struct nvme_ns *__nvme_scan_namespace(const char *sysfs_dir, char *name) if (n->nsid < 0) goto close_fd; - TAILQ_INIT(&n->paths); + list_head_init(&n->paths); nvme_ns_init(n); return n; @@ -790,7 +777,7 @@ int nvme_ctrl_scan_namespace(struct nvme_ctrl *c, char *name) n->s = c->s; n->c = c; - TAILQ_INSERT_TAIL(&c->namespaces, n, entry); + list_add(&c->namespaces, &n->entry); return 0; } @@ -803,6 +790,6 @@ int nvme_subsystem_scan_namespace(struct nvme_subsystem *s, char *name) return -1; n->s = s; - TAILQ_INSERT_TAIL(&s->namespaces, n, entry); + list_add(&s->namespaces, &n->entry); return 0; } diff --git a/src/nvme/tree.h b/src/nvme/tree.h index e751d7c666..a37541ab89 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -9,59 +9,99 @@ #include "ioctl.h" #include "util.h" +extern const char *nvme_ctrl_sysfs_dir; +extern const char *nvme_subsys_sysfs_dir; + typedef struct nvme_ns *nvme_ns_t; typedef struct nvme_path *nvme_path_t; typedef struct nvme_ctrl *nvme_ctrl_t; typedef struct nvme_subsystem *nvme_subsystem_t; typedef struct nvme_root *nvme_root_t; +typedef bool (*nvme_scan_filter_t)(nvme_subsystem_t); + /** * nvme_first_subsystem() - + * @r: + * + * Return: */ nvme_subsystem_t nvme_first_subsystem(nvme_root_t r); /** * nvme_next_subsystem() - + * @r: + * @s: + * + * Return: */ nvme_subsystem_t nvme_next_subsystem(nvme_root_t r, nvme_subsystem_t s); /** * nvme_ctrl_first_ns() - + * @c: + * + * Return: */ nvme_ns_t nvme_ctrl_first_ns(nvme_ctrl_t c); /** * nvme_ctrl_next_ns() - + * @c: + * @n: + * + * Return: */ nvme_ns_t nvme_ctrl_next_ns(nvme_ctrl_t c, nvme_ns_t n); /** * nvme_ctrl_first_path() - + * @c: + * + * Return: */ nvme_path_t nvme_ctrl_first_path(nvme_ctrl_t c); /** * nvme_ctrl_next_path() - + * @c: + * @p: + * + * Return: */ nvme_path_t nvme_ctrl_next_path(nvme_ctrl_t c, nvme_path_t p); /** * nvme_subsystem_first_ctrl() - + * @s: + * + * Return: */ nvme_ctrl_t nvme_subsystem_first_ctrl(nvme_subsystem_t s); /** * nvme_subsystem_next_ctrl() - + * @s: + * @c: + * + * Return: */ nvme_ctrl_t nvme_subsystem_next_ctrl(nvme_subsystem_t s, nvme_ctrl_t c); /** * nvme_subsystem_first_ns() - + * @s: + * + * Return: */ nvme_ns_t nvme_subsystem_first_ns(nvme_subsystem_t s); /** * nvme_subsystem_next_ns() - + * @s: + * @n: + * + * Return: */ nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n); @@ -147,263 +187,444 @@ nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n); /** * nvme_ns_get_fd() - + * @n: + * + * Return: */ int nvme_ns_get_fd(nvme_ns_t n); /** * nvme_ns_get_nsid() - + * @n: + * + * Return: */ int nvme_ns_get_nsid(nvme_ns_t n); /** * nvme_ns_get_lba_size() - + * @n: + * + * Return: */ int nvme_ns_get_lba_size(nvme_ns_t n); /** * nvme_ns_get_lba_count() - + * @n: + * + * Return: */ uint64_t nvme_ns_get_lba_count(nvme_ns_t n); /** * nvme_ns_get_lba_util() - + * @n: + * + * Return: */ uint64_t nvme_ns_get_lba_util(nvme_ns_t n); /** * nvme_ns_get_sysfs_dir() - + * @n: + * + * Return: */ const char *nvme_ns_get_sysfs_dir(nvme_ns_t n); /** * nvme_ns_get_name() - + * @n: + * + * Return: */ const char *nvme_ns_get_name(nvme_ns_t n); /** * nvme_ns_get_subsystem() - + * @n: + * + * Return: */ nvme_subsystem_t nvme_ns_get_subsystem(nvme_ns_t n); /** * nvme_ns_get_ctrl() - + * @n: + * + * Return: */ nvme_ctrl_t nvme_ns_get_ctrl(nvme_ns_t n); /** * nvme_ns_read() - + * @n: + * @buf: + * @offset: + * @count: + * + * Return: */ int nvme_ns_read(nvme_ns_t n, void *buf, off_t offset, size_t count); /** * nvme_ns_write() - + * @n: + * @buf: + * @offset: + * @count: + * + * Return: */ int nvme_ns_write(nvme_ns_t n, void *buf, off_t offset, size_t count); /** * nvme_ns_verify() - + * @n: + * @offset: + * @count: + * + * Return: */ int nvme_ns_verify(nvme_ns_t n, off_t offset, size_t count); /** * nvme_ns_compare() - + * @n: + * @buf: + * @offset: + * @count: + * + * Return: */ int nvme_ns_compare(nvme_ns_t n, void *buf, off_t offset, size_t count); /** * nvme_ns_write_zeros() - + * @n: + * @offset: + * @count: + * + * Return: */ int nvme_ns_write_zeros(nvme_ns_t n, off_t offset, size_t count); /** * nvme_ns_write_uncorrectable() - + * @n: + * @offset: + * @count: + * + * Return: */ int nvme_ns_write_uncorrectable(nvme_ns_t n, off_t offset, size_t count); /** * nvme_ns_flush() - + * @n: + * + * Return: */ int nvme_ns_flush(nvme_ns_t n); /** * nvme_ns_identify() - + * @n: + * @ns: + * + * Return: */ int nvme_ns_identify(nvme_ns_t n, struct nvme_id_ns *ns); /** * nvme_path_get_name() - + * @p: + * + * Return: */ const char *nvme_path_get_name(nvme_path_t p); /** * nvme_path_get_sysfs_dir() - + * @p: + * + * Return: */ const char *nvme_path_get_sysfs_dir(nvme_path_t p); /** * nvme_path_get_ana_state() - + * @p: + * + * Return: */ const char *nvme_path_get_ana_state(nvme_path_t p); /** * nvme_path_get_subsystem() - + * @p: + * + * Return: */ nvme_ctrl_t nvme_path_get_subsystem(nvme_path_t p); /** * nvme_path_get_ns() - + * @p: + * + * Return: */ nvme_ns_t nvme_path_get_ns(nvme_path_t p); /** * nvme_ctrl_get_fd() - + * @c: + * + * Return: */ int nvme_ctrl_get_fd(nvme_ctrl_t c); /** * nvme_ctrl_get_name() - + * @c: + * + * Return: */ const char *nvme_ctrl_get_name(nvme_ctrl_t c); + /** * nvme_ctrl_get_sysfs_dir() - + * @c: + * + * Return: */ const char *nvme_ctrl_get_sysfs_dir(nvme_ctrl_t c); + /** * nvme_ctrl_get_address() - + * @c: + * + * Return: */ const char *nvme_ctrl_get_address(nvme_ctrl_t c); + /** * nvme_ctrl_get_firmware() - + * @c: + * + * Return: */ const char *nvme_ctrl_get_firmware(nvme_ctrl_t c); + /** * nvme_ctrl_get_model() - + * @c: + * + * Return: */ const char *nvme_ctrl_get_model(nvme_ctrl_t c); + /** * nvme_ctrl_get_state() - + * @c: + * + * Return: */ const char *nvme_ctrl_get_state(nvme_ctrl_t c); + /** * nvme_ctrl_get_numa_node() - + * @c: + * + * Return: */ const char *nvme_ctrl_get_numa_node(nvme_ctrl_t c); + /** * nvme_ctrl_get_queue_count() - + * @c: + * + * Return: */ const char *nvme_ctrl_get_queue_count(nvme_ctrl_t c); + /** * nvme_ctrl_get_serial() - + * @c: + * + * Return: */ const char *nvme_ctrl_get_serial(nvme_ctrl_t c); + /** * nvme_ctrl_get_sqsize() - + * @c: + * + * Return: */ const char *nvme_ctrl_get_sqsize(nvme_ctrl_t c); + /** * nvme_ctrl_get_transport() - + * @c: + * + * Return: */ const char *nvme_ctrl_get_transport(nvme_ctrl_t c); + /** * nvme_ctrl_get_nqn() - + * @c: + * + * Return: */ const char *nvme_ctrl_get_nqn(nvme_ctrl_t c); + /** * nvme_ctrl_get_subsysnqn() - + * @c: + * + * Return: */ const char *nvme_ctrl_get_subsysnqn(nvme_ctrl_t c); /** * nvme_ctrl_get_subsystem() - + * @c: + * + * Return: */ nvme_subsystem_t nvme_ctrl_get_subsystem(nvme_ctrl_t c); /** * nvme_ctrl_identify() - + * @c: + * @id: + * + * Return: */ int nvme_ctrl_identify(nvme_ctrl_t c, struct nvme_id_ctrl *id); /** * nvme_ctrl_disconnect() - + * @c: + * + * Return: */ int nvme_ctrl_disconnect(nvme_ctrl_t c); /** * nvme_scan_ctrl() - + * @name: + * + * Return: */ nvme_ctrl_t nvme_scan_ctrl(const char *name); /** * nvme_free_ctrl() - + * @c: */ void nvme_free_ctrl(struct nvme_ctrl *c); + /** * nvme_unlink_ctrl() - + * @c: */ void nvme_unlink_ctrl(struct nvme_ctrl *c); /** * nvme_subsystem_get_nqn() - + * @s: + * + * Return: */ const char *nvme_subsystem_get_nqn(nvme_subsystem_t s); /** * nvme_subsystem_get_sysfs_dir() - + * @s: + * + * Return: */ const char *nvme_subsystem_get_sysfs_dir(nvme_subsystem_t s); /** * nvme_subsystem_get_name() - + * @s: + * + * Return: */ const char *nvme_subsystem_get_name(nvme_subsystem_t s); -typedef bool (*nvme_scan_filter_t)(nvme_subsystem_t); - /** * nvme_scan_filter() - + * @f: + * + * Return: */ nvme_root_t nvme_scan_filter(nvme_scan_filter_t f); /** * nvme_scan() - + * + * Return: */ nvme_root_t nvme_scan(); /** * nvme_refresh_topology() - + * @r: */ void nvme_refresh_topology(nvme_root_t r); /** * nvme_reset_topology() - + * @r: */ void nvme_reset_topology(nvme_root_t r); /** * nvme_free_tree() - + * @r: */ void nvme_free_tree(nvme_root_t r); /** * nvme_get_subsys_attr() - + * @s: + * @attr: + * + * Return: */ char *nvme_get_subsys_attr(nvme_subsystem_t s, const char *attr); /** * nvme_get_ctrl_attr() - + * @c: + * @attr: + * + * Return: */ char *nvme_get_ctrl_attr(nvme_ctrl_t c, const char *attr); /** * nvme_get_ns_attr() - + * @n: + * @attr: + * + * Return: */ char *nvme_get_ns_attr(nvme_ns_t n, const char *attr); /** * nvme_get_path_attr() - + * @p: + * @attr: + * + * Return: */ char *nvme_get_path_attr(nvme_path_t p, const char *attr); -extern const char *nvme_ctrl_sysfs_dir; -extern const char *nvme_subsys_sysfs_dir; #endif /* _LIBNVME_TREE_H */ diff --git a/src/nvme/types.h b/src/nvme/types.h index ebb01c7571..179510de8a 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -13,12 +13,34 @@ #define __force #endif -static inline __le16 cpu_to_le16(uint16_t x) { return (__force __le16)htole16(x); } -static inline __le32 cpu_to_le32(uint32_t x) { return (__force __le32)htole32(x); } -static inline __le64 cpu_to_le64(uint64_t x) { return (__force __le64)htole64(x); } -static inline uint16_t le16_to_cpu(__le16 x) { return le16toh((__force __u16)x); } -static inline uint32_t le32_to_cpu(__le32 x) { return le32toh((__force __u32)x); } -static inline uint64_t le64_to_cpu(__le64 x) { return le64toh((__force __u64)x); } +static inline __le16 cpu_to_le16(uint16_t x) +{ + return (__force __le16)htole16(x); +} + +static inline __le32 cpu_to_le32(uint32_t x) +{ + return (__force __le32)htole32(x); +} + +static inline __le64 cpu_to_le64(uint64_t x) +{ + return (__force __le64)htole64(x); +} + +static inline uint16_t le16_to_cpu(__le16 x) +{ + return le16toh((__force __u16)x); +} + +static inline uint32_t le32_to_cpu(__le32 x) +{ + return le32toh((__force __u32)x); } + +static inline uint64_t le64_to_cpu(__le64 x) +{ + return le64toh((__force __u64)x); +} /** * enum nvme_constants - @@ -53,6 +75,7 @@ enum nvme_constants { NVME_ID_CTRL_LIST_MAX = 2047, NVME_ID_NS_LIST_MAX = 1024, NVME_ID_SECONDARY_CTRL_MAX = 127, + NVME_ID_ND_DESCRIPTOR_MAX = 16, NVME_FEAT_LBA_RANGE_MAX = 64, NVME_LOG_ST_MAX_RESULTS = 20, NVME_DSM_MAX_RANGES = 256, @@ -948,9 +971,9 @@ struct nvme_id_nvmset_list { }; /** - * struct nvme_id_ns_granularity_list_entry - + * struct nvme_id_ns_granularity_desc - */ -struct nvme_id_ns_granularity_list_entry { +struct nvme_id_ns_granularity_desc { __le64 namespace_size_granularity; __le64 namespace_capacity_granularity; }; @@ -962,7 +985,8 @@ struct nvme_id_ns_granularity_list { __le32 attributes; __u8 num_descriptors; __u8 rsvd[27]; - struct nvme_id_ns_granularity_list_entry entry[16]; + struct nvme_id_ns_granularity_desc entry[NVME_ID_ND_DESCRIPTOR_MAX]; + __u8 rsvd288[3808]; }; /** diff --git a/src/nvme/util.c b/src/nvme/util.c index da70c9aa3a..73099afe6d 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -400,8 +400,10 @@ int nvme_get_ana_log_len(int fd, size_t *analen) int ret; ret = nvme_identify_ctrl(fd, &ctrl); - if (ret) - return ret; + if (ret) { + errno = nvme_status_to_errno(ret, false); + return -1; + } *analen = sizeof(struct nvme_ana_log) + le32_to_cpu(ctrl.nanagrpid) * sizeof(struct nvme_ana_group_desc) + @@ -456,7 +458,8 @@ int nvme_get_feature_length(int fid, __u32 cdw11, __u32 *len) *len = 0; break; default: - return EINVAL; + errno = EINVAL; + return -1; } return 0; } @@ -470,7 +473,8 @@ int nvme_get_directive_receive_length(__u8 dtype, __u8 doper, __u32 *len) *len = sizeof(struct nvme_id_directives); break; default: - return -EINVAL; + errno = EINVAL; + return -1; } break; case NVME_DIRECTIVE_DTYPE_STREAMS: diff --git a/src/nvme/util.h b/src/nvme/util.h index 04bd88d4b5..96824d5f4a 100644 --- a/src/nvme/util.h +++ b/src/nvme/util.h @@ -7,51 +7,62 @@ #include "types.h" /** - * nvme_status_type() - Returns SCT(Status Code Type) in status field of - * the completion queue entry. - * @status: return value from nvme passthrough commands, which is the nvme - * status field, located at DW3 in completion queue entry - */ -static inline __u8 nvme_status_type(__u16 status) -{ - return (status & NVME_SCT_MASK) >> 8; -} - -/** - * nvme_status_to_string() - - */ -const char *nvme_status_to_string(int status, bool fabrics); - -/* * nvme_status_to_errno() - Converts nvme return status to errno - * @status: >= 0 for nvme status field in completion queue entry, - * < 0 for linux internal errors + * @status: Return status from an nvme passthrough commmand * @fabrics: true if given status is for fabrics * - * Notes: This function will convert a given status to an errno + * If status < 0, errno is already set. + * + * Return: Appropriate errno for the given nvme status */ __u8 nvme_status_to_errno(int status, bool fabrics); /** * nvme_fw_download_seq() - + * @fd: + * @size: + * @xfer: + * @offset: + * @buf: + * + * Return: */ int nvme_fw_download_seq(int fd, __u32 size, __u32 xfer, __u32 offset, void *buf); /** * nvme_get_telemetry_log() - + * @fd: + * @create: + * @ctrl: + * @data_area: + * @buf: + * @log_size: + * + * Return: */ int nvme_get_telemetry_log(int fd, bool create, bool ctrl, int data_area, void **buf, __u32 *log_size); /** * nvme_setup_id_ns() - + * @ns: + * @nsze: + * @ncap: + * @flbas: + * @dps: + * @nmic: + * @anagrpid: + * @nvmsetid: */ void nvme_setup_id_ns(struct nvme_id_ns *ns, __u64 nsze, __u64 ncap, __u8 flbas, __u8 dps, __u8 nmic, __u32 anagrpid, __u16 nvmsetid); /** * nvme_setup_ctrl_list() - + * @cntlist: + * @num_ctrls: + * @ctrlist: */ void nvme_setup_ctrl_list(struct nvme_ctrl_list *cntlist, __u16 num_ctrls, __u16 *ctrlist); @@ -100,7 +111,11 @@ int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, __u32 data_len, void *data); /** - * nvme_get_ana_log_len() - + * nvme_get_ana_log_len() - Retreive size of the current ANA log + * @fd: File descriptor of nvme device + * @analen: Pointer to where the length will be set on success + * + * Return: 0 on success, -1 otherwise with errno set */ int nvme_get_ana_log_len(int fd, size_t *analen); @@ -111,8 +126,8 @@ int nvme_get_ana_log_len(int fd, size_t *analen); * @num_ctrls: Number of controllers in ctrlist * @ctrlist: List of controller IDs to perform the attach action * - * Return: The nvme command status if a response was received or -errno - * otherwise. + * Return: The nvme command status if a response was received or -1 + * with errno set otherwise. */ int nvme_namespace_attach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist); @@ -123,18 +138,29 @@ int nvme_namespace_attach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrl * @num_ctrls: Number of controllers in ctrlist * @ctrlist: List of controller IDs to perform the detach action * - * Return: The nvme command status if a response was received or -errno - * otherwise. + * Return: The nvme command status if a response was received or -1 + * with errno set otherwise. */ int nvme_namespace_detach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist); /** - * nvme_get_feature_length() - + * nvme_get_feature_length() - Retreive the command payload length for a + * specific feature identifier + * @fid: + * @cdw11: + * @len: + * + * Return: 0 on success, -1 with errno set otherwise */ int nvme_get_feature_length(int fid, __u32 cdw11, __u32 *len); /** * nvme_get_directive_receive_length() - + * @dtype: + * @doper: + * @len: + * + * Return: */ int nvme_get_directive_receive_length(__u8 dtype, __u8 doper, __u32 *len); @@ -150,5 +176,14 @@ int nvme_get_directive_receive_length(__u8 dtype, __u8 doper, __u32 *len); */ int nvme_open(const char *name); +/** + * nvme_set_attr() - + * @dir: + * @attr: + * @value: + * + * Return + */ int nvme_set_attr(const char *dir, const char *attr, const char *value); + #endif /* _LIBNVME_UTIL_H */ From 2f6a96925cef5828ce2cba27709252b21ab8c3af Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Mon, 10 Feb 2020 11:04:51 -0800 Subject: [PATCH 0015/1564] Split host and controller telemetry log API While similar, these are logs are not obtained the same way. Signed-off-by: Keith Busch --- examples/telemetry-listen.c | 9 +---- src/nvme/cmd.h | 43 ++++++++++----------- src/nvme/ioctl.c | 6 ++- src/nvme/util.c | 77 +++++++++++++++++++++---------------- src/nvme/util.h | 45 +++++++++++++++------- 5 files changed, 102 insertions(+), 78 deletions(-) diff --git a/examples/telemetry-listen.c b/examples/telemetry-listen.c index 1561a0c740..00c43f7bef 100644 --- a/examples/telemetry-listen.c +++ b/examples/telemetry-listen.c @@ -33,16 +33,11 @@ static void save_telemetry(nvme_ctrl_t c) void *log; time_t s; - ret = nvme_get_telemetry_log(nvme_ctrl_get_fd(c), false, true, 3, &log, - &log_size); + /* Clear the log (rae == false) at the end to see new telemetry events later */ + ret = nvme_get_ctrl_telemetry(nvme_ctrl_get_fd(c), false, &log, &log_size); if (ret) return; - /* Clear the log (rae == false) to see new telemetry events later */ - nvme_get_log_telemetry_ctrl(nvme_ctrl_get_fd(c), false, 0, sizeof(buf), - buf); - memset(buf, 0, sizeof(buf)); - s = time(NULL); ret = snprintf(buf, sizeof(buf), "/var/log/%s-telemetry-%ld", nvme_ctrl_get_subsysnqn(c), s); diff --git a/src/nvme/cmd.h b/src/nvme/cmd.h index bdbff39140..80b7b96eb2 100644 --- a/src/nvme/cmd.h +++ b/src/nvme/cmd.h @@ -314,44 +314,39 @@ enum nvme_directive_dtype { }; /** - * enum - + * enum nvme_directive_receive_doper - + * @NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM: + * @NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM: + * @NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS: + * @NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE: */ -enum nvme_cmd_directive_receive_identify_doper { +enum nvme_directive_receive_doper { NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM = 0x01, -}; - -/** - * enum - - */ -enum nvme_cmd_directive_receive_streams_doper { NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM = 0x01, NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS = 0x02, NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE = 0x03, }; /** - * enum - + * enum nvme_directive_send_doper - + * @NVME_DIRECTIVE_SEND_IDENTIFY_DOPER_ENDIR: + * @NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_IDENTIFIER: + * @NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE: */ -enum nvme_cmd_directive_send_identify_doper { +enum nvme_directive_send_doper { NVME_DIRECTIVE_SEND_IDENTIFY_DOPER_ENDIR = 0x01, + NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_IDENTIFIER = 0x01, + NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE = 0x02, }; /** * enum - */ -enum nvme_cmd_directive_send_identify_endir { +enum nvme_directive_send_identify_endir { NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_DISABLE = 0, NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_ENABLE = 1, }; -/** - * enum - - */ -enum nvme_cmd_directive_send_streams_doper { - NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_IDENTIFIER = 0x01, - NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE = 0x02, -}; - /** * enum nvme_sanitize_sanact - * @NVME_SANITIZE_SANACT_EXIT_FAILURE: @@ -1893,7 +1888,7 @@ int nvme_get_lba_status(int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl, * @fd: File descriptor of nvme device * @nsid: Namespace ID, if applicable * @dspec: Directive specific field - * @doper: Directive operation + * @doper: Directive send operation, see &enum nvme_directive_send_doper * @dtype: Directive type, see &enum nvme_directive_dtype * @dw12: Directive specific command dword12 * @data_len: Length of data payload in bytes @@ -1909,7 +1904,8 @@ int nvme_get_lba_status(int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl, * Return: The nvme command status if a response was received or -1 with errno * set otherwise. */ -int nvme_directive_send(int fd, __u32 nsid, __u16 dspec, __u8 doper, +int nvme_directive_send(int fd, __u32 nsid, __u16 dspec, + enum nvme_directive_send_doper doper, enum nvme_directive_dtype dtype, __u32 cdw12, __u32 data_len, void *data, __u32 *result); @@ -1951,7 +1947,7 @@ int nvme_directive_send_stream_release_resource(int fd, __u32 nsid); * @fd: File descriptor of nvme device * @nsid: Namespace ID, if applicable * @dspec: Directive specific field - * @doper: Directive operation + * @doper: Directive receive operation, see &enum nvme_directive_receive_doper * @dtype: Directive type, see &enum nvme_directive_dtype * @dw12: Directive specific command dword12 * @data_len: Length of data payload @@ -1961,7 +1957,8 @@ int nvme_directive_send_stream_release_resource(int fd, __u32 nsid); * Return: The nvme command status if a response was received or -1 with errno * set otherwise. */ -int nvme_directive_recv(int fd, __u32 nsid, __u16 dspec, __u8 doper, +int nvme_directive_recv(int fd, __u32 nsid, __u16 dspec, + enum nvme_directive_receive_doper doper, enum nvme_directive_dtype dtype, __u32 cdw12, __u32 data_len, void *data, __u32 *result); diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index c2d219cc7a..0298c8b9ed 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -1281,7 +1281,8 @@ int nvme_get_lba_status(int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl, return nvme_submit_admin_passthru(fd, &cmd, NULL); } -int nvme_directive_send(int fd, __u32 nsid, __u16 dspec, __u8 doper, +int nvme_directive_send(int fd, __u32 nsid, __u16 dspec, + enum nvme_directive_send_doper doper, enum nvme_directive_dtype dtype, __u32 cdw12, __u32 data_len, void *data, __u32 *result) { @@ -1331,7 +1332,8 @@ int nvme_directive_send_stream_release_resource(int fd, __u32 nsid) NULL); } -int nvme_directive_recv(int fd, __u32 nsid, __u16 dspec, __u8 doper, +int nvme_directive_recv(int fd, __u32 nsid, __u16 dspec, + enum nvme_directive_receive_doper doper, enum nvme_directive_dtype dtype, __u32 cdw12, __u32 data_len, void *data, __u32 *result) { diff --git a/src/nvme/util.c b/src/nvme/util.c index 73099afe6d..7ce5b63c0e 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -235,6 +235,7 @@ int __nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, __u32 xfer_len, __u32 data_len, void *data) { __u64 offset = 0, xfer; + bool retain = true; void *ptr = data; int ret; @@ -247,8 +248,16 @@ int __nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, if (xfer > xfer_len) xfer = xfer_len; + /* + * Always retain regardless of the RAE parameter until the very + * last portion of this log page so the data remains latched + * during the fetch sequence. + */ + if (offset + xfer == data_len) + retain = rae; + ret = nvme_get_log(fd, log_id, nsid, offset, NVME_LOG_LSP_NONE, - NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, + NVME_LOG_LSI_NONE, retain, NVME_UUID_NONE, xfer, ptr); if (ret) return ret; @@ -266,14 +275,14 @@ int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, return __nvme_get_log_page(fd, nsid, log_id, rae, 4096, data_len, data); } -int nvme_get_telemetry_log(int fd, bool create, bool ctrl, int data_area, - void **buf, __u32 *log_size) +static int nvme_get_telemetry_log(int fd, bool create, bool ctrl, bool rae, void **buf, + __u32 *log_size) { static const __u32 xfer = 512; - __u8 lid = NVME_LOG_LID_TELEMETRY_HOST; struct nvme_telemetry_log *telem; __u32 size; + __u8 lid; void *log; int err; @@ -286,36 +295,24 @@ int nvme_get_telemetry_log(int fd, bool create, bool ctrl, int data_area, if (ctrl) { err = nvme_get_log_telemetry_ctrl(fd, true, 0, xfer, log); lid = NVME_LOG_LID_TELEMETRY_CTRL; - } else if (create) - err = nvme_get_log_create_telemetry_host(fd, log); - else - err = nvme_get_log_telemetry_host(fd, 0, xfer, log); + } else { + lid = NVME_LOG_LID_TELEMETRY_HOST; + if (create) + err = nvme_get_log_create_telemetry_host(fd, log); + else + err = nvme_get_log_telemetry_host(fd, 0, xfer, log); + } if (err) goto free; telem = log; - if (!telem->ctrlavail) { + if (ctrl && !telem->ctrlavail) { size = xfer; goto done; } - switch (data_area) { - case 1: - size = (le16_to_cpu(telem->dalb1) * xfer) + xfer; - break; - case 2: - size = (le16_to_cpu(telem->dalb2) * xfer) + xfer; - break; - case 3: - size = (le16_to_cpu(telem->dalb3) * xfer) + xfer; - break; - default: - errno = EINVAL; - err = -1; - goto free; - } - + size = (le16_to_cpu(telem->dalb3) * xfer) + xfer; log = realloc(log, size); if (!log) { errno = ENOMEM; @@ -323,7 +320,7 @@ int nvme_get_telemetry_log(int fd, bool create, bool ctrl, int data_area, goto free; } - err = nvme_get_log_page(fd, NVME_NSID_NONE, lid, true, size, (void *)log); + err = nvme_get_log_page(fd, NVME_NSID_NONE, lid, rae, size, (void *)log); if (err) goto free; done: @@ -335,6 +332,21 @@ int nvme_get_telemetry_log(int fd, bool create, bool ctrl, int data_area, return err; } +int nvme_get_ctrl_telemetry(int fd, bool rae, void **buf, __u32 *log_size) +{ + return nvme_get_telemetry_log(fd, false, true, rae, buf, log_size); +} + +int nvme_get_host_telemetry(int fd, void **buf, __u32 *log_size) +{ + return nvme_get_telemetry_log(fd, false, false, false, buf, log_size); +} + +int nvme_get_new_host_telemetry(int fd, void **buf, __u32 *log_size) +{ + return nvme_get_telemetry_log(fd, true, false, false, buf, log_size); +} + void nvme_setup_dsm_range(struct nvme_dsm_range *dsm, __u32 *ctx_attrs, __u32 *llbas, __u64 *slbas, __u16 nr_ranges) { @@ -464,37 +476,36 @@ int nvme_get_feature_length(int fid, __u32 cdw11, __u32 *len) return 0; } -int nvme_get_directive_receive_length(__u8 dtype, __u8 doper, __u32 *len) +int nvme_get_directive_receive_length(enum nvme_directive_dtype dtype, + enum nvme_directive_receive_doper doper, __u32 *len) { switch (dtype) { case NVME_DIRECTIVE_DTYPE_IDENTIFY: switch (doper) { case NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM: *len = sizeof(struct nvme_id_directives); - break; + return 0; default: errno = EINVAL; return -1; } - break; case NVME_DIRECTIVE_DTYPE_STREAMS: switch (doper) { case NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM: *len = sizeof(struct nvme_streams_directive_params); - break; + return 0; case NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS: *len = (128 * 1024) * sizeof(__le16); - break; + return 0; case NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE: *len = 0; - break; + return 0; default: return -EINVAL; } default: return -EINVAL; } - return 0; } static int __nvme_set_attr(const char *path, const char *value) diff --git a/src/nvme/util.h b/src/nvme/util.h index 96824d5f4a..82588dd144 100644 --- a/src/nvme/util.h +++ b/src/nvme/util.h @@ -4,7 +4,7 @@ #include #include -#include "types.h" +#include "cmd.h" /** * nvme_status_to_errno() - Converts nvme return status to errno @@ -31,18 +31,35 @@ int nvme_fw_download_seq(int fd, __u32 size, __u32 xfer, __u32 offset, void *buf); /** - * nvme_get_telemetry_log() - + * nvme_get_ctrl_telemetry() - * @fd: - * @create: - * @ctrl: - * @data_area: + * @rae: * @buf: * @log_size: * - * Return: + * Returns: + */ +int nvme_get_ctrl_telemetry(int fd, bool rae, void **buf, __u32 *log_size); + +/** + * nvme_get_host_telemetry() - + * @fd: + * @buf: + * @log_size: + * + * Returns: */ -int nvme_get_telemetry_log(int fd, bool create, bool ctrl, int data_area, - void **buf, __u32 *log_size); +int nvme_get_host_telemetry(int fd, void **buf, __u32 *log_size); + +/** + * nvme_get_new_host_telemetry() - + * @fd: + * @buf: + * @log_size: + * + * Returns: + */ +int nvme_get_new_host_telemetry(int fd, void **buf, __u32 *log_size); /** * nvme_setup_id_ns() - @@ -156,13 +173,15 @@ int nvme_get_feature_length(int fid, __u32 cdw11, __u32 *len); /** * nvme_get_directive_receive_length() - - * @dtype: - * @doper: - * @len: + * @dtype: Directive type, see &enum nvme_directive_dtype + * @doper: Directive receive operation, see &enum nvme_directive_receive_doper + * @len: Address to save the payload length of the directive in bytes on + * a successful decode * - * Return: + * Return: 0 on success, -1 with errno set to EINVAL. */ -int nvme_get_directive_receive_length(__u8 dtype, __u8 doper, __u32 *len); +int nvme_get_directive_receive_length(enum nvme_directive_dtype dtype, + enum nvme_directive_receive_doper doper, __u32 *len); /** * nvme_open() - Open an nvme controller or namespace device From 178db95f1bebea7db9ba709006d395a2fb044051 Mon Sep 17 00:00:00 2001 From: Chaitanya Kulkarni Date: Mon, 10 Feb 2020 11:37:45 -0800 Subject: [PATCH 0016/1564] libnvme: code cleanup src/nvme/fabrics.c This patch has following style fixes :- Add a new line after function. Adjust function arguments. Init array remove memset. Return early in the function. Signed-off-by: Chaitanya Kulkarni Signed-off-by: Keith Busch --- src/nvme/fabrics.c | 46 +++++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 5d1b68847c..0b39fb35f4 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -33,19 +33,21 @@ static int add_bool_argument(char **argstr, char *tok, bool arg) { char *nstr; - if (arg) { - if (asprintf(&nstr, "%s,%s", *argstr, tok) < 0) { - errno = ENOMEM; - return -1; - } - free(*argstr); - *argstr = nstr; + if (!arg) + return 0; + + if (asprintf(&nstr, "%s,%s", *argstr, tok) < 0) { + errno = ENOMEM; + return -1; } + free(*argstr); + *argstr = nstr; + return 0; } static int add_int_argument(char **argstr, char *tok, int arg, - bool allow_zero) + bool allow_zero) { char *nstr; @@ -64,14 +66,14 @@ static int add_argument(char **argstr, const char *tok, const char *arg) { char *nstr; - if (arg && strcmp(arg, "none")) { - if (asprintf(&nstr, "%s,%s=%s", *argstr, tok, arg) < 0) { - errno = ENOMEM; - return -1; - } - free(*argstr); - *argstr = nstr; + if (!(arg && strcmp(arg, "none"))) + return 0; + if (asprintf(&nstr, "%s,%s=%s", *argstr, tok, arg) < 0) { + errno = ENOMEM; + return -1; } + free(*argstr); + *argstr = nstr; return 0; } @@ -108,6 +110,7 @@ static int build_options(char **argstr, struct nvme_fabrics_config *cfg) return 0; } + static int __nvmf_add_ctrl(const char *argstr) { int ret, fd, len = strlen(argstr); @@ -161,14 +164,13 @@ int nvmf_add_ctrl_opts(struct nvme_fabrics_config *cfg) nvme_ctrl_t nvmf_add_ctrl(struct nvme_fabrics_config *cfg) { - char d[32]; + char d[32] = { 0 }; int ret; ret = nvmf_add_ctrl_opts(cfg); if (ret < 0) return NULL; - memset(d, 0, sizeof(d)); if (snprintf(d, sizeof(d), "nvme%d", ret) < 0) return NULL; @@ -182,7 +184,8 @@ static void chomp(char *s, int l) } nvme_ctrl_t nvmf_connect_disc_entry(struct nvmf_disc_log_entry *e, - const struct nvme_fabrics_config *defcfg, bool *discover) + const struct nvme_fabrics_config *defcfg, + bool *discover) { struct nvme_fabrics_config cfg = { 0 }; nvme_ctrl_t c; @@ -263,11 +266,12 @@ nvme_ctrl_t nvmf_connect_disc_entry(struct nvmf_disc_log_entry *e, static int nvme_discovery_log(int fd, __u32 len, struct nvmf_discovery_log *log) { - return __nvme_get_log_page(fd, 0, NVME_LOG_LID_DISCOVER, true, 512, len, log); + return __nvme_get_log_page(fd, 0, NVME_LOG_LID_DISCOVER, true, 512, + len, log); } int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, - int max_retries) + int max_retries) { struct nvmf_discovery_log *log; int hdr, ret, retries = 0; @@ -335,8 +339,8 @@ int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, char *nvmf_hostnqn_generate() { - sd_id128_t id; char *ret = NULL; + sd_id128_t id; if (sd_id128_get_machine_app_specific(NVME_HOSTNQN_ID, &id) < 0) return NULL; From d00cf430d9953f0043d583aebe48704f2e3a63c2 Mon Sep 17 00:00:00 2001 From: Chaitanya Kulkarni Date: Mon, 10 Feb 2020 11:37:46 -0800 Subject: [PATCH 0017/1564] libnvme: code cleanup src/nvme/filters.c Make sure lines length stays <= 80 character. Signed-off-by: Chaitanya Kulkarni Signed-off-by: Keith Busch --- src/nvme/filters.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/nvme/filters.c b/src/nvme/filters.c index 44e31fb607..2579403b6b 100644 --- a/src/nvme/filters.c +++ b/src/nvme/filters.c @@ -81,25 +81,30 @@ int nvme_subsys_filter(const struct dirent *d) int nvme_scan_subsystems(struct dirent ***subsys) { - return scandir(nvme_subsys_sysfs_dir, subsys, nvme_subsys_filter, alphasort); + return scandir(nvme_subsys_sysfs_dir, subsys, nvme_subsys_filter, + alphasort); } int nvme_scan_subsystem_ctrls(nvme_subsystem_t s, struct dirent ***ctrls) { - return scandir(nvme_subsystem_get_sysfs_dir(s), ctrls, nvme_ctrls_filter, alphasort); + return scandir(nvme_subsystem_get_sysfs_dir(s), ctrls, + nvme_ctrls_filter, alphasort); } int nvme_scan_subsystem_namespaces(nvme_subsystem_t s, struct dirent ***namespaces) { - return scandir(nvme_subsystem_get_sysfs_dir(s), namespaces, nvme_namespace_filter, alphasort); + return scandir(nvme_subsystem_get_sysfs_dir(s), namespaces, + nvme_namespace_filter, alphasort); } int nvme_scan_ctrl_namespace_paths(nvme_ctrl_t c, struct dirent ***namespaces) { - return scandir(nvme_ctrl_get_sysfs_dir(c), namespaces, nvme_paths_filter, alphasort); + return scandir(nvme_ctrl_get_sysfs_dir(c), namespaces, + nvme_paths_filter, alphasort); } int nvme_scan_ctrl_namespaces(nvme_ctrl_t c, struct dirent ***namespaces) { - return scandir(nvme_ctrl_get_sysfs_dir(c), namespaces, nvme_namespace_filter, alphasort); + return scandir(nvme_ctrl_get_sysfs_dir(c), namespaces, + nvme_namespace_filter, alphasort); } From 71195039d254b3ccabb98a4eb86e5d152c75fca8 Mon Sep 17 00:00:00 2001 From: Chaitanya Kulkarni Date: Mon, 10 Feb 2020 11:37:47 -0800 Subject: [PATCH 0018/1564] libnvme: code cleanup src/nvme/ioctl.c Various coding style fixes. Signed-off-by: Chaitanya Kulkarni Signed-off-by: Keith Busch --- src/nvme/ioctl.c | 375 ++++++++++++++++++++++++++--------------------- 1 file changed, 204 insertions(+), 171 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 0298c8b9ed..364465bad2 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -76,7 +76,8 @@ int nvme_get_nsid(int fd) } static int nvme_submit_passthru64(int fd, unsigned long ioctl_cmd, - struct nvme_passthru_cmd64 *cmd, __u64 *result) + struct nvme_passthru_cmd64 *cmd, + __u64 *result) { int err = ioctl(fd, ioctl_cmd, cmd); @@ -86,7 +87,7 @@ static int nvme_submit_passthru64(int fd, unsigned long ioctl_cmd, } static int nvme_submit_passthru(int fd, unsigned long ioctl_cmd, - struct nvme_passthru_cmd *cmd, __u32 *result) + struct nvme_passthru_cmd *cmd, __u32 *result) { int err = ioctl(fd, ioctl_cmd, cmd); @@ -96,11 +97,11 @@ static int nvme_submit_passthru(int fd, unsigned long ioctl_cmd, } static int nvme_passthru64(int fd, unsigned long ioctl_cmd, __u8 opcode, - __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, - __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, - __u32 cdw14, __u32 cdw15, __u32 data_len, void *data, - __u32 metadata_len, void *metadata, __u32 timeout_ms, - __u64 *result) + __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, + __u32 cdw3, __u32 cdw10, __u32 cdw11, __u32 cdw12, + __u32 cdw13, __u32 cdw14, __u32 cdw15, + __u32 data_len, void *data, __u32 metadata_len, + void *metadata, __u32 timeout_ms, __u64 *result) { struct nvme_passthru_cmd64 cmd = { .opcode = opcode, @@ -126,11 +127,11 @@ static int nvme_passthru64(int fd, unsigned long ioctl_cmd, __u8 opcode, } static int nvme_passthru(int fd, unsigned long ioctl_cmd, __u8 opcode, - __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, - __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, - __u32 cdw14, __u32 cdw15, __u32 data_len, void *data, - __u32 metadata_len, void *metadata, __u32 timeout_ms, - __u32 *result) + __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, + __u32 cdw3, __u32 cdw10, __u32 cdw11, __u32 cdw12, + __u32 cdw13, __u32 cdw14, __u32 cdw15, __u32 data_len, + void *data, __u32 metadata_len, void *metadata, + __u32 timeout_ms, __u32 *result) { struct nvme_passthru_cmd cmd = { .opcode = opcode, @@ -162,14 +163,16 @@ int nvme_submit_admin_passthru64(int fd, struct nvme_passthru_cmd64 *cmd, } int nvme_admin_passthru64(int fd, __u8 opcode, __u8 flags, __u16 rsvd, - __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, - __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, - __u32 data_len, void *data, __u32 metadata_len, void *metadata, - __u32 timeout_ms, __u64 *result) + __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, + __u32 cdw11, __u32 cdw12, __u32 cdw13, __u32 cdw14, + __u32 cdw15, __u32 data_len, void *data, + __u32 metadata_len, void *metadata, __u32 timeout_ms, + __u64 *result) { return nvme_passthru64(fd, NVME_IOCTL_ADMIN64_CMD, opcode, flags, rsvd, - nsid, cdw2, cdw3, cdw10, cdw11, cdw12, cdw13, cdw14, cdw15, - data_len, data, metadata_len, metadata, timeout_ms, result); + nsid, cdw2, cdw3, cdw10, cdw11, cdw12, cdw13, + cdw14, cdw15, data_len, data, metadata_len, + metadata, timeout_ms, result); } int nvme_submit_admin_passthru(int fd, struct nvme_passthru_cmd *cmd, __u32 *result) @@ -178,14 +181,16 @@ int nvme_submit_admin_passthru(int fd, struct nvme_passthru_cmd *cmd, __u32 *res } int nvme_admin_passthru(int fd, __u8 opcode, __u8 flags, __u16 rsvd, - __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, - __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, - __u32 data_len, void *data, __u32 metadata_len, void *metadata, - __u32 timeout_ms, __u32 *result) + __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, + __u32 cdw11, __u32 cdw12, __u32 cdw13, __u32 cdw14, + __u32 cdw15, __u32 data_len, void *data, + __u32 metadata_len, void *metadata, __u32 timeout_ms, + __u32 *result) { - return nvme_passthru(fd, NVME_IOCTL_ADMIN_CMD, opcode, flags, rsvd, nsid, - cdw2, cdw3, cdw10, cdw11, cdw12, cdw13, cdw14, cdw15, data_len, - data, metadata_len, metadata, timeout_ms, result); + return nvme_passthru(fd, NVME_IOCTL_ADMIN_CMD, opcode, flags, rsvd, + nsid, cdw2, cdw3, cdw10, cdw11, cdw12, cdw13, + cdw14, cdw15, data_len, data, metadata_len, + metadata, timeout_ms, result); } enum nvme_cmd_dword_fields { @@ -362,7 +367,7 @@ int nvme_identify(int fd, enum nvme_identify_cns cns, __u32 nsid, __u16 cntid, static int __nvme_identify(int fd, __u8 cns, __u32 nsid, void *data) { return nvme_identify(fd, cns, nsid, NVME_CNTLID_NONE, - NVME_NVMSETID_NONE, NVME_UUID_NONE, data); + NVME_NVMSETID_NONE, NVME_UUID_NONE, data); } int nvme_identify_ctrl(int fd, struct nvme_id_ctrl *id) @@ -386,14 +391,14 @@ int nvme_identify_active_ns_list(int fd, __u32 nsid, struct nvme_ns_list *list) { BUILD_ASSERT(sizeof(struct nvme_ns_list) == 4096); return __nvme_identify(fd, NVME_IDENTIFY_CNS_NS_ACTIVE_LIST, nsid, - list); + list); } int nvme_identify_allocated_ns_list(int fd, __u32 nsid, struct nvme_ns_list *list) { return __nvme_identify(fd, NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST, nsid, - list); + list); } int nvme_identify_ctrl_list(int fd, __u16 cntid, @@ -401,15 +406,16 @@ int nvme_identify_ctrl_list(int fd, __u16 cntid, { BUILD_ASSERT(sizeof(struct nvme_ctrl_list) == 4096); return nvme_identify(fd, NVME_IDENTIFY_CNS_CTRL_LIST, - NVME_NSID_NONE, cntid, NVME_NVMSETID_NONE, - NVME_UUID_NONE, ctrlist); + NVME_NSID_NONE, cntid, NVME_NVMSETID_NONE, + NVME_UUID_NONE, ctrlist); } int nvme_identify_nsid_ctrl_list(int fd, __u32 nsid, __u16 cntid, struct nvme_ctrl_list *ctrlist) { return nvme_identify(fd, NVME_IDENTIFY_CNS_NS_CTRL_LIST, nsid, - cntid, NVME_NVMSETID_NONE, NVME_UUID_NONE, ctrlist); + cntid, NVME_NVMSETID_NONE, NVME_UUID_NONE, + ctrlist); } int nvme_identify_ns_descs(int fd, __u32 nsid, struct nvme_ns_id_desc *descs) @@ -422,8 +428,8 @@ int nvme_identify_nvmset_list(int fd, __u16 nvmsetid, { BUILD_ASSERT(sizeof(struct nvme_id_nvmset_list) == 4096); return nvme_identify(fd, NVME_IDENTIFY_CNS_NVMSET_LIST, - NVME_NSID_NONE, NVME_CNTLID_NONE, nvmsetid, NVME_UUID_NONE, - nvmset); + NVME_NSID_NONE, NVME_CNTLID_NONE, nvmsetid, + NVME_UUID_NONE, nvmset); } int nvme_identify_primary_ctrl(int fd, __u16 cntid, @@ -431,8 +437,8 @@ int nvme_identify_primary_ctrl(int fd, __u16 cntid, { BUILD_ASSERT(sizeof(struct nvme_primary_ctrl_cap) == 4096); return nvme_identify(fd, NVME_IDENTIFY_CNS_PRIMARY_CTRL_CAP, - NVME_NSID_NONE, cntid, NVME_NVMSETID_NONE, NVME_UUID_NONE, - cap); + NVME_NSID_NONE, cntid, NVME_NVMSETID_NONE, + NVME_UUID_NONE, cap); } int nvme_identify_secondary_ctrl_list(int fd, __u16 cntid, @@ -440,8 +446,8 @@ int nvme_identify_secondary_ctrl_list(int fd, __u16 cntid, { BUILD_ASSERT(sizeof(struct nvme_secondary_ctrl_list) == 4096); return nvme_identify(fd, NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST, - NVME_NSID_NONE, cntid, NVME_NVMSETID_NONE, NVME_UUID_NONE, - list); + NVME_NSID_NONE, cntid, NVME_NVMSETID_NONE, + NVME_UUID_NONE, list); } int nvme_identify_ns_granularity(int fd, @@ -449,14 +455,14 @@ int nvme_identify_ns_granularity(int fd, { BUILD_ASSERT(sizeof(struct nvme_id_ns_granularity_list) == 4096); return __nvme_identify(fd, NVME_IDENTIFY_CNS_NS_GRANULARITY, - NVME_NSID_NONE, list); + NVME_NSID_NONE, list); } int nvme_identify_uuid(int fd, struct nvme_id_uuid_list *list) { BUILD_ASSERT(sizeof(struct nvme_id_uuid_list) == 4096); return __nvme_identify(fd, NVME_IDENTIFY_CNS_UUID_LIST, NVME_NSID_NONE, - list); + list); } int nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, @@ -490,11 +496,11 @@ int nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, return nvme_submit_admin_passthru(fd, &cmd, NULL); } -static int __nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, bool rae, - __u32 len, void *log) +static int __nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, bool rae, + __u32 len, void *log) { return nvme_get_log(fd, lid, NVME_NSID_ALL, 0, NVME_LOG_LSP_NONE, - NVME_LOG_LSI_NONE, NVME_UUID_NONE, rae, len, log); + NVME_LOG_LSI_NONE, NVME_UUID_NONE, rae, len, log); } int nvme_get_log_error(int fd, unsigned nr_entries, bool rae, @@ -502,42 +508,42 @@ int nvme_get_log_error(int fd, unsigned nr_entries, bool rae, { BUILD_ASSERT(sizeof(struct nvme_error_log_page) == 64); return __nvme_get_log(fd, NVME_LOG_LID_ERROR, rae, - sizeof(*log) * nr_entries, log); + sizeof(*log) * nr_entries, log); } int nvme_get_log_smart(int fd, __u32 nsid, bool rae, struct nvme_smart_log *log) { BUILD_ASSERT(sizeof(struct nvme_smart_log) == 512); return nvme_get_log(fd, NVME_LOG_LID_SMART, nsid, 0, - NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, - sizeof(*log), log); + NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, + NVME_UUID_NONE, sizeof(*log), log); } int nvme_get_log_fw_slot(int fd, bool rae, struct nvme_firmware_slot *log) { BUILD_ASSERT(sizeof(struct nvme_firmware_slot) == 512); return __nvme_get_log(fd, NVME_LOG_LID_FW_SLOT, rae, sizeof(*log), - log); + log); } int nvme_get_log_changed_ns_list(int fd, bool rae, struct nvme_ns_list *log) { return __nvme_get_log(fd, NVME_LOG_LID_CHANGED_NS, rae, - sizeof(*log), log); + sizeof(*log), log); } int nvme_get_log_cmd_effects(int fd, struct nvme_cmd_effects_log *log) { BUILD_ASSERT(sizeof(struct nvme_cmd_effects_log) == 4096); return __nvme_get_log(fd, NVME_LOG_LID_CMD_EFFECTS, false, - sizeof(*log), log); + sizeof(*log), log); } int nvme_get_log_device_self_test(int fd, struct nvme_self_test_log *log) { BUILD_ASSERT(sizeof(struct nvme_self_test_log) == 564); return __nvme_get_log(fd, NVME_LOG_LID_DEVICE_SELF_TEST, false, - sizeof(*log), log); + sizeof(*log), log); } enum nvme_cmd_get_log_telemetry_host_lsp { @@ -549,32 +555,33 @@ int nvme_get_log_create_telemetry_host(int fd, struct nvme_telemetry_log *log) { BUILD_ASSERT(sizeof(struct nvme_telemetry_log) == 512); return nvme_get_log(fd, NVME_LOG_LID_TELEMETRY_HOST, NVME_NSID_NONE, 0, - NVME_LOG_TELEM_HOST_LSP_CREATE, NVME_LOG_LSI_NONE, false, - NVME_UUID_NONE, sizeof(*log), log); + NVME_LOG_TELEM_HOST_LSP_CREATE, NVME_LOG_LSI_NONE, + false, NVME_UUID_NONE, sizeof(*log), log); } int nvme_get_log_telemetry_host(int fd, __u64 offset, __u32 len, void *log) { return nvme_get_log(fd, NVME_LOG_LID_TELEMETRY_HOST, NVME_NSID_NONE, - offset, NVME_LOG_TELEM_HOST_LSP_RETAIN, NVME_LOG_LSI_NONE, - false, NVME_UUID_NONE, len, log); + offset, NVME_LOG_TELEM_HOST_LSP_RETAIN, + NVME_LOG_LSI_NONE, + false, NVME_UUID_NONE, len, log); } int nvme_get_log_telemetry_ctrl(int fd, bool rae, __u64 offset, __u32 len, - void *log) + void *log) { return nvme_get_log(fd, NVME_LOG_LID_TELEMETRY_CTRL, NVME_NSID_NONE, - offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, - NVME_UUID_NONE, len, log); + offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, + NVME_UUID_NONE, len, log); } int nvme_get_log_endurance_group(int fd, __u16 endgid, - struct nvme_endurance_group_log *log) + struct nvme_endurance_group_log *log) { BUILD_ASSERT(sizeof(struct nvme_endurance_group_log) == 512); return nvme_get_log(fd, NVME_LOG_LID_ENDURANCE_GROUP, NVME_NSID_NONE, - 0, NVME_LOG_LSP_NONE, endgid, false, NVME_UUID_NONE, - sizeof(*log), log); + 0, NVME_LOG_LSP_NONE, endgid, false, NVME_UUID_NONE, + sizeof(*log), log); } int nvme_get_log_predictable_lat_nvmset(int fd, __u16 nvmsetid, @@ -582,8 +589,8 @@ int nvme_get_log_predictable_lat_nvmset(int fd, __u16 nvmsetid, { BUILD_ASSERT(sizeof(struct nvme_nvmset_predictable_lat_log) == 512); return nvme_get_log(fd, NVME_LOG_LID_PREDICTABLE_LAT_NVMSET, - NVME_NSID_NONE, 0, NVME_LOG_LSP_NONE, nvmsetid, false, - NVME_UUID_NONE, sizeof(*log), log); + NVME_NSID_NONE, 0, NVME_LOG_LSP_NONE, nvmsetid, + false, NVME_UUID_NONE, sizeof(*log), log); } int nvme_get_log_predictable_lat_event(int fd, bool rae, __u32 offset, @@ -597,38 +604,39 @@ int nvme_get_log_predictable_lat_event(int fd, bool rae, __u32 offset, int nvme_get_log_ana(int fd, enum nvme_log_ana_lsp lsp, bool rae, __u64 offset, __u32 len, void *log) { - return nvme_get_log(fd, NVME_LOG_LID_ANA, NVME_NSID_NONE, offset, lsp, - NVME_LOG_LSI_NONE, false, NVME_UUID_NONE, len, log); + return nvme_get_log(fd, NVME_LOG_LID_ANA, NVME_NSID_NONE, offset, + lsp,NVME_LOG_LSI_NONE, false, NVME_UUID_NONE, + len, log); } int nvme_get_log_ana_groups(int fd, bool rae, __u32 len, struct nvme_ana_group_desc *log) { return nvme_get_log_ana(fd, NVME_LOG_ANA_LSP_RGO_GROUPS_ONLY, rae, 0, - len, log); + len, log); } int nvme_get_log_lba_status(int fd, bool rae, __u64 offset, __u32 len, void *log) { return nvme_get_log(fd, NVME_LOG_LID_LBA_STATUS, NVME_NSID_NONE, - offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, - NVME_UUID_NONE, len, log); + offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, + NVME_UUID_NONE, len, log); } int nvme_get_log_endurance_grp_evt(int fd, bool rae, __u32 offset, __u32 len, void *log) { return nvme_get_log(fd, NVME_LOG_LID_ENDURANCE_GRP_EVT, - NVME_NSID_NONE, offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, - rae, NVME_UUID_NONE, len, log); + NVME_NSID_NONE, offset, NVME_LOG_LSP_NONE, + NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, len, log); } int nvme_get_log_discovery(int fd, bool rae, __u32 offset, __u32 len, void *log) { return nvme_get_log(fd, NVME_LOG_LID_DISCOVER, NVME_NSID_NONE, offset, - NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, - len, log); + NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, + NVME_UUID_NONE, len, log); } int nvme_get_log_reservation(int fd, bool rae, @@ -636,7 +644,7 @@ int nvme_get_log_reservation(int fd, bool rae, { BUILD_ASSERT(sizeof(struct nvme_resv_notification_log) == 64); return __nvme_get_log(fd, NVME_LOG_LID_RESERVATION, rae, - sizeof(*log), log); + sizeof(*log), log); } int nvme_get_log_sanitize(int fd, bool rae, @@ -644,7 +652,7 @@ int nvme_get_log_sanitize(int fd, bool rae, { BUILD_ASSERT(sizeof(struct nvme_sanitize_log_page) == 512); return __nvme_get_log(fd, NVME_LOG_LID_SANITIZE, rae, sizeof(*log), - log); + log); } int nvme_set_features(int fd, __u8 fid, __u32 nsid, __u32 cdw11, __u32 cdw12, @@ -686,7 +694,7 @@ int nvme_set_features_arbitration(int fd, __u8 ab, __u8 lpw, __u8 mpw, DW(hpw, NVME_FEATURES_ARBITRATION_HPW); return __nvme_set_features(fd, NVME_FEAT_FID_ARBITRATION, value, save, - result); + result); } int nvme_set_features_power_mgmt(int fd, __u8 ps, __u8 wh, bool save, @@ -696,7 +704,7 @@ int nvme_set_features_power_mgmt(int fd, __u8 ps, __u8 wh, bool save, DW(wh, NVME_FEATURES_PWRMGMT_PS); return __nvme_set_features(fd, NVME_FEAT_FID_POWER_MGMT, value, save, - result); + result); } int nvme_set_features_lba_range(int fd, __u32 nsid, __u32 nr_ranges, bool save, @@ -713,7 +721,7 @@ int nvme_set_features_temp_thresh(int fd, __u16 tmpth, __u8 tmpsel, DW(thsel, NVME_FEATURES_THSEL); return __nvme_set_features(fd, NVME_FEAT_FID_TEMP_THRESH, value, save, - result); + result); } int nvme_set_features_err_recovery(int fd, __u32 nsid, __u16 tler, bool dulbe, @@ -723,7 +731,7 @@ int nvme_set_features_err_recovery(int fd, __u32 nsid, __u16 tler, bool dulbe, DW(!!dulbe, NVME_FEATURES_ERROR_RECOVERY_DULBE); return __nvme_set_features(fd, NVME_FEAT_FID_ERR_RECOVERY, value, save, - result); + result); } int nvme_set_features_volatile_wc(int fd, bool wce, bool save, __u32 *result) @@ -731,7 +739,7 @@ int nvme_set_features_volatile_wc(int fd, bool wce, bool save, __u32 *result) __u32 value = DW(!!wce, NVME_FEATURES_VWC_WCE); return __nvme_set_features(fd, NVME_FEAT_FID_VOLATILE_WC, value, save, - result); + result); } int nvme_set_features_irq_coalesce(int fd, __u8 thr, __u8 time, bool save, @@ -741,7 +749,7 @@ int nvme_set_features_irq_coalesce(int fd, __u8 thr, __u8 time, bool save, DW(time, NVME_FEATURES_IRQC_THR); return __nvme_set_features(fd, NVME_FEAT_FID_IRQ_COALESCE, value, save, - result); + result); } int nvme_set_features_irq_config(int fd, __u16 iv, bool cd, bool save, @@ -751,7 +759,7 @@ int nvme_set_features_irq_config(int fd, __u16 iv, bool cd, bool save, DW(!!cd, NVME_FEATURES_IVC_CD); return __nvme_set_features(fd, NVME_FEAT_FID_IRQ_CONFIG, value, save, - result); + result); } int nvme_set_features_write_atomic(int fd, bool dn, bool save, __u32 *result) @@ -759,14 +767,14 @@ int nvme_set_features_write_atomic(int fd, bool dn, bool save, __u32 *result) __u32 value = DW(!!dn, NVME_FEATURES_WAN_DN); return __nvme_set_features(fd, NVME_FEAT_FID_WRITE_ATOMIC, value, save, - result); + result); } int nvme_set_features_async_event(int fd, __u32 events, bool save, __u32 *result) { return __nvme_set_features(fd, NVME_FEAT_FID_ASYNC_EVENT, events, save, - result); + result); } int nvme_set_features_auto_pst(int fd, bool apste, bool save, @@ -775,7 +783,7 @@ int nvme_set_features_auto_pst(int fd, bool apste, bool save, __u32 value = DW(!!apste, NVME_FEATURES_APST_APSTE); return __nvme_set_features(fd, NVME_FEAT_FID_AUTO_PST, value, save, - result); + result); } int nvme_set_features_timestamp(int fd, bool save, __u64 timestamp) @@ -785,8 +793,8 @@ int nvme_set_features_timestamp(int fd, bool save, __u64 timestamp) memcpy(&t, ts.timestamp, sizeof(ts.timestamp)); return nvme_set_features(fd, NVME_FEAT_FID_TIMESTAMP, - NVME_NSID_NONE, 0, 0, save, NVME_UUID_NONE, 0, - sizeof(ts), &ts, NULL); + NVME_NSID_NONE, 0, 0, save, NVME_UUID_NONE, 0, + sizeof(ts), &ts, NULL); } int nvme_set_features_hctm(int fd, __u16 tmt2, __u16 tmt1, @@ -796,7 +804,7 @@ int nvme_set_features_hctm(int fd, __u16 tmt2, __u16 tmt1, DW(tmt1, NVME_FEATURES_HCTM_TMT1); return __nvme_set_features(fd, NVME_FEAT_FID_HCTM, value, save, - result); + result); } int nvme_set_features_nopsc(int fd, bool noppme, bool save, __u32 *result) @@ -804,22 +812,23 @@ int nvme_set_features_nopsc(int fd, bool noppme, bool save, __u32 *result) __u32 value = DW(noppme, NVME_FEATURES_NOPS_NOPPME); return __nvme_set_features(fd, NVME_FEAT_FID_NOPSC, value, save, - result); + result); } int nvme_set_features_rrl(int fd, __u8 rrl, __u16 nvmsetid, bool save, __u32 *result) { return nvme_set_features(fd, NVME_FEAT_FID_RRL, NVME_NSID_NONE, - nvmsetid, rrl, save, NVME_UUID_NONE, 0, 0, NULL, result); + nvmsetid, rrl, save, NVME_UUID_NONE, 0, 0, + NULL, result); } int nvme_set_features_plm_config(int fd, bool plm, __u16 nvmsetid, bool save, struct nvme_plm_config *data, __u32 *result) { return nvme_set_features(fd, NVME_FEAT_FID_PLM_CONFIG, - NVME_NSID_NONE, nvmsetid, !!plm, save, NVME_UUID_NONE, 0, 0, - NULL, result); + NVME_NSID_NONE, nvmsetid, !!plm, save, + NVME_UUID_NONE, 0, 0, NULL, result); } int nvme_set_features_plm_window(int fd, enum nvme_feat_plm_window_select sel, @@ -828,7 +837,8 @@ int nvme_set_features_plm_window(int fd, enum nvme_feat_plm_window_select sel, __u32 cdw12 = DW(sel, NVME_FEATURES_PLM_WINDOW_SELECT); return nvme_set_features(fd, NVME_FEAT_FID_PLM_WINDOW, NVME_NSID_NONE, - nvmsetid, cdw12, save, NVME_UUID_NONE, 0, 0, NULL, result); + nvmsetid, cdw12, save, NVME_UUID_NONE, 0, 0, + NULL, result); } int nvme_set_features_lba_sts_interval(int fd, __u16 lsiri, __u16 lsipi, @@ -838,36 +848,37 @@ int nvme_set_features_lba_sts_interval(int fd, __u16 lsiri, __u16 lsipi, DW(lsipi, NVME_FEATURES_LBAS_LSIPI); return __nvme_set_features(fd, NVME_FEAT_FID_LBA_STS_INTERVAL, value, - save, result); + save, result); } int nvme_set_features_host_behavior(int fd, bool save, struct nvme_feat_host_behavior *data) { return nvme_set_features(fd, NVME_FEAT_FID_HOST_BEHAVIOR, - NVME_NSID_NONE, save, 0, 0, NVME_UUID_NONE, 0, sizeof(*data), - data, NULL); + NVME_NSID_NONE, save, 0, 0, NVME_UUID_NONE, 0, + sizeof(*data), data, NULL); } int nvme_set_features_sanitize(int fd, bool nodrm, bool save, __u32 *result) { return __nvme_set_features(fd, NVME_FEAT_FID_SANITIZE, !!nodrm, save, - result); + result); } int nvme_set_features_endurance_evt_cfg(int fd, __u16 endgid, __u8 egwarn, bool save, __u32 *result) { __u32 value = endgid | egwarn << 16; + return __nvme_set_features(fd, NVME_FEAT_FID_ENDURANCE_EVT_CFG, value, - save, result); + save, result); } int nvme_set_features_sw_progress(int fd, __u8 pbslc, bool save, __u32 *result) { return __nvme_set_features(fd, NVME_FEAT_FID_SW_PROGRESS, pbslc, save, - result); + result); } int nvme_set_features_host_id(int fd, bool save, bool exhid, __u8 *hostid) @@ -882,20 +893,20 @@ int nvme_set_features_host_id(int fd, bool save, bool exhid, __u8 *hostid) int nvme_set_features_resv_mask(int fd, __u32 mask, bool save, __u32 *result) { return __nvme_set_features(fd, NVME_FEAT_FID_RESV_MASK, mask, save, - result); + result); } int nvme_set_features_resv_persist(int fd, bool ptpl, bool save, __u32 *result) { return __nvme_set_features(fd, NVME_FEAT_RESV_PERSIST, !!ptpl, save, - result); + result); } int nvme_set_features_write_protect(int fd, enum nvme_feat_nswpcfg_state state, bool save, __u32 *result) { return __nvme_set_features(fd, NVME_FEAT_FID_WRITE_PROTECT, state, - save, result); + save, result); } int nvme_get_features(int fd, enum nvme_features_id fid, __u32 nsid, @@ -920,20 +931,20 @@ int nvme_get_features(int fd, enum nvme_features_id fid, __u32 nsid, } static int __nvme_get_features(int fd, enum nvme_features_id fid, - enum nvme_get_features_sel sel, __u32 *result) + enum nvme_get_features_sel sel, __u32 *result) { return nvme_get_features(fd, fid, NVME_NSID_NONE, sel, 0, - NVME_UUID_NONE, 0, NULL, result); + NVME_UUID_NONE, 0, NULL, result); } int nvme_get_features_arbitration(int fd, enum nvme_get_features_sel sel, - __u32 *result) + __u32 *result) { return __nvme_get_features(fd, NVME_FEAT_FID_ARBITRATION, sel, result); } int nvme_get_features_power_mgmt(int fd, enum nvme_get_features_sel sel, - __u32 *result) + __u32 *result) { return __nvme_get_features(fd, NVME_FEAT_FID_POWER_MGMT, sel, result); } @@ -942,71 +953,71 @@ int nvme_get_features_lba_range(int fd, enum nvme_get_features_sel sel, struct nvme_lba_range_type *data, __u32 *result) { - return nvme_get_features(fd, NVME_FEAT_FID_LBA_RANGE, NVME_NSID_NONE, sel, 0, - NVME_UUID_NONE, 0, NULL, result); + return nvme_get_features(fd, NVME_FEAT_FID_LBA_RANGE, NVME_NSID_NONE, + sel, 0, NVME_UUID_NONE, 0, NULL, result); } int nvme_get_features_temp_thresh(int fd, enum nvme_get_features_sel sel, - __u32 *result) + __u32 *result) { return __nvme_get_features(fd, NVME_FEAT_FID_TEMP_THRESH, sel, result); } int nvme_get_features_err_recovery(int fd, enum nvme_get_features_sel sel, - __u32 *result) + __u32 *result) { return __nvme_get_features(fd, NVME_FEAT_FID_ERR_RECOVERY, sel, - result); + result); } int nvme_get_features_volatile_wc(int fd, enum nvme_get_features_sel sel, - __u32 *result) + __u32 *result) { return __nvme_get_features(fd, NVME_FEAT_FID_VOLATILE_WC, sel, result); } int nvme_get_features_num_queues(int fd, enum nvme_get_features_sel sel, - __u32 *result) + __u32 *result) { return __nvme_get_features(fd, NVME_FEAT_FID_NUM_QUEUES, sel, result); } int nvme_get_features_irq_coalesce(int fd, enum nvme_get_features_sel sel, - __u32 *result) + __u32 *result) { return __nvme_get_features(fd, NVME_FEAT_FID_IRQ_COALESCE, sel, - result); + result); } int nvme_get_features_irq_config(int fd, enum nvme_get_features_sel sel, - __u16 iv, __u32 *result) + __u16 iv, __u32 *result) { - return nvme_get_features(fd, NVME_FEAT_FID_IRQ_CONFIG, NVME_NSID_NONE, sel, iv, - NVME_UUID_NONE, 0, NULL, result); + return nvme_get_features(fd, NVME_FEAT_FID_IRQ_CONFIG, NVME_NSID_NONE, + sel, iv, NVME_UUID_NONE, 0, NULL, result); } int nvme_get_features_write_atomic(int fd, enum nvme_get_features_sel sel, - __u32 *result) + __u32 *result) { return __nvme_get_features(fd, NVME_FEAT_FID_WRITE_ATOMIC, sel, - result); + result); } int nvme_get_features_async_event(int fd, enum nvme_get_features_sel sel, - __u32 *result) + __u32 *result) { return __nvme_get_features(fd, NVME_FEAT_FID_ASYNC_EVENT, sel, result); } int nvme_get_features_auto_pst(int fd, enum nvme_get_features_sel sel, - struct nvme_feat_auto_pst *apst, __u32 *result) + struct nvme_feat_auto_pst *apst, __u32 *result) { - return nvme_get_features(fd, NVME_FEAT_FID_AUTO_PST, NVME_NSID_NONE, sel, 0, - NVME_UUID_NONE, 0, NULL, result); + return nvme_get_features(fd, NVME_FEAT_FID_AUTO_PST, NVME_NSID_NONE, + sel, 0, NVME_UUID_NONE, 0, NULL, result); } int nvme_get_features_host_mem_buf(int fd, enum nvme_get_features_sel sel, - __u32 *result) + __u32 *result) { return __nvme_get_features(fd, NVME_FEAT_FID_HOST_MEM_BUF, sel, result); } @@ -1014,8 +1025,8 @@ int nvme_get_features_host_mem_buf(int fd, enum nvme_get_features_sel sel, int nvme_get_features_timestamp(int fd, enum nvme_get_features_sel sel, struct nvme_timestamp *ts) { - return nvme_get_features(fd, NVME_FEAT_FID_TIMESTAMP, NVME_NSID_NONE, sel, 0, - NVME_UUID_NONE, 0, NULL, NULL); + return nvme_get_features(fd, NVME_FEAT_FID_TIMESTAMP, NVME_NSID_NONE, + sel, 0, NVME_UUID_NONE, 0, NULL, NULL); } int nvme_get_features_kato(int fd, enum nvme_get_features_sel sel, __u32 *result) @@ -1042,74 +1053,84 @@ int nvme_get_features_plm_config(int fd, enum nvme_get_features_sel sel, __u16 nvmsetid, struct nvme_plm_config *data, __u32 *result) { return nvme_get_features(fd, NVME_FEAT_FID_PLM_CONFIG, NVME_NSID_NONE, - sel, nvmsetid, NVME_UUID_NONE, 0, NULL, result); + sel, nvmsetid, NVME_UUID_NONE, 0, NULL, + result); } int nvme_get_features_plm_window(int fd, enum nvme_get_features_sel sel, __u16 nvmsetid, __u32 *result) { return nvme_get_features(fd, NVME_FEAT_FID_PLM_WINDOW, NVME_NSID_NONE, - sel, nvmsetid, NVME_UUID_NONE, 0, NULL, result); + sel, nvmsetid, NVME_UUID_NONE, 0, NULL, + result); } -int nvme_get_features_lba_sts_interval(int fd, enum nvme_get_features_sel sel, __u32 *result) +int nvme_get_features_lba_sts_interval(int fd, enum nvme_get_features_sel sel, + __u32 *result) { - return __nvme_get_features(fd, NVME_FEAT_FID_LBA_STS_INTERVAL, sel, result); + return __nvme_get_features(fd, NVME_FEAT_FID_LBA_STS_INTERVAL, sel, + result); } int nvme_get_features_host_behavior(int fd, enum nvme_get_features_sel sel, - struct nvme_feat_host_behavior *data, __u32 *result) + struct nvme_feat_host_behavior *data, + __u32 *result) { return nvme_get_features(fd, NVME_FEAT_FID_HOST_BEHAVIOR, NVME_NSID_NONE, sel, 0, NVME_UUID_NONE, 0, NULL, result); } -int nvme_get_features_sanitize(int fd, enum nvme_get_features_sel sel, __u32 *result) +int nvme_get_features_sanitize(int fd, enum nvme_get_features_sel sel, + __u32 *result) { return __nvme_get_features(fd, NVME_FEAT_FID_SANITIZE, sel, result); } -int nvme_get_features_endurance_event_cfg(int fd, enum nvme_get_features_sel sel, __u16 endgid, __u32 *result) +int nvme_get_features_endurance_event_cfg(int fd, enum nvme_get_features_sel sel, + __u16 endgid, __u32 *result) { return nvme_get_features(fd, NVME_FEAT_FID_ENDURANCE_EVT_CFG, - NVME_NSID_NONE, sel, 0, NVME_UUID_NONE, 0, NULL, result); + NVME_NSID_NONE, sel, 0, NVME_UUID_NONE, 0, + NULL, result); } -int nvme_get_features_sw_progress(int fd, enum nvme_get_features_sel sel, __u32 *result) +int nvme_get_features_sw_progress(int fd, enum nvme_get_features_sel sel, + __u32 *result) { return __nvme_get_features(fd, NVME_FEAT_FID_SW_PROGRESS, sel, result); } int nvme_get_features_host_id(int fd, enum nvme_get_features_sel sel, - bool exhid, __u32 len, __u8 *hostid) + bool exhid, __u32 len, __u8 *hostid) { - return nvme_get_features(fd, NVME_FEAT_FID_HOST_ID, NVME_NSID_NONE, - sel, !!exhid, NVME_UUID_NONE, len, hostid, NULL); + return nvme_get_features(fd, NVME_FEAT_FID_HOST_ID, NVME_NSID_NONE, sel, + !!exhid, NVME_UUID_NONE, len, hostid, NULL); } -int nvme_get_features_resv_mask(int fd, - enum nvme_get_features_sel sel, __u32 *result) +int nvme_get_features_resv_mask(int fd, enum nvme_get_features_sel sel, + __u32 *result) { return __nvme_get_features(fd, NVME_FEAT_FID_RESV_MASK, sel, result); } -int nvme_get_features_resv_persist(int fd, - enum nvme_get_features_sel sel, __u32 *result) +int nvme_get_features_resv_persist(int fd, enum nvme_get_features_sel sel, + __u32 *result) { return __nvme_get_features(fd, NVME_FEAT_RESV_PERSIST, sel, result); } int nvme_get_features_write_protect(int fd, __u32 nsid, - enum nvme_get_features_sel sel, __u32 *result) + enum nvme_get_features_sel sel, + __u32 *result) { return nvme_get_features(fd, NVME_FEAT_FID_WRITE_PROTECT, nsid, sel, 0, - NVME_UUID_NONE, 0, NULL, result); + NVME_UUID_NONE, 0, NULL, result); } int nvme_format_nvm(int fd, __u32 nsid, __u8 lbaf, - enum nvme_cmd_format_mset mset, enum nvme_cmd_format_pi pi, - enum nvme_cmd_format_pil pil, enum nvme_cmd_format_ses ses, - __u32 timeout) + enum nvme_cmd_format_mset mset, enum nvme_cmd_format_pi pi, + enum nvme_cmd_format_pil pil, enum nvme_cmd_format_ses ses, + __u32 timeout) { __u32 cdw10 = DW(lbaf, NVME_FORMAT_CDW10_LBAF) | DW(mset, NVME_FORMAT_CDW10_MSET) | @@ -1149,7 +1170,7 @@ int nvme_ns_mgmt_create(int fd, struct nvme_id_ns *ns, __u32 *nsid, __u32 timeout) { return nvme_ns_mgmt(fd, NVME_NSID_NONE, NVME_NS_MGMT_SEL_CREATE, ns, nsid, - timeout); + timeout); } int nvme_ns_mgmt_delete(int fd, __u32 nsid) @@ -1181,7 +1202,7 @@ int nvme_ns_attach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist) int nvme_ns_dettach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist) { return nvme_ns_attach(fd, nsid, NVME_NS_ATTACH_SEL_CTRL_DEATTACH, - ctrlist); + ctrlist); } int nvme_fw_download(int fd, __u32 offset, __u32 data_len, void *data) @@ -1312,24 +1333,28 @@ int nvme_directive_send_id_endir(int fd, __u32 nsid, bool endir, DW(endir, NVME_DIRECTIVE_SEND_IDENTIFY_CDW12_ENDIR); return nvme_directive_send(fd, nsid, 0, NVME_DIRECTIVE_DTYPE_IDENTIFY, - NVME_DIRECTIVE_SEND_IDENTIFY_DOPER_ENDIR, cdw12, sizeof(*id), - id, NULL); + NVME_DIRECTIVE_SEND_IDENTIFY_DOPER_ENDIR, + cdw12, sizeof(*id), id, NULL); } int nvme_directive_send_stream_release_identifier(int fd, __u32 nsid, __u16 stream_id) { + enum nvme_directive_dtype dtype = + NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_IDENTIFIER; + return nvme_directive_send(fd, nsid, stream_id, - NVME_DIRECTIVE_DTYPE_STREAMS, - NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_IDENTIFIER, 0, 0, - NULL, NULL); + NVME_DIRECTIVE_DTYPE_STREAMS, + dtype, 0, 0, NULL, NULL); } int nvme_directive_send_stream_release_resource(int fd, __u32 nsid) { + enum nvme_directive_dtype dtype = + NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE; + return nvme_directive_send(fd, nsid, 0, NVME_DIRECTIVE_DTYPE_STREAMS, - NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE, 0, 0, NULL, - NULL); + dtype, 0, 0, NULL, NULL); } int nvme_directive_recv(int fd, __u32 nsid, __u16 dspec, @@ -1358,33 +1383,41 @@ int nvme_directive_recv(int fd, __u32 nsid, __u16 dspec, int nvme_directive_recv_identify_parameters(int fd, __u32 nsid, struct nvme_id_directives *id) { + enum nvme_directive_dtype dtype = + NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM; + return nvme_directive_recv(fd, nsid, 0, NVME_DIRECTIVE_DTYPE_IDENTIFY, - NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM, 0, sizeof(*id), - id, NULL); + dtype, 0, sizeof(*id), id, NULL); } int nvme_directive_recv_stream_parameters(int fd, __u32 nsid, struct nvme_streams_directive_params *parms) { + enum nvme_directive_dtype dtype = + NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM; + return nvme_directive_recv(fd, nsid, 0, NVME_DIRECTIVE_DTYPE_STREAMS, - NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM, 0, sizeof(*parms), - parms, NULL); + dtype, 0, sizeof(*parms), parms, NULL); } int nvme_directive_recv_stream_status(int fd, __u32 nsid, unsigned nr_entries, struct nvme_streams_directive_status *id) { + enum nvme_directive_dtype dtype = + NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS; + return nvme_directive_recv(fd, nsid, 0, NVME_DIRECTIVE_DTYPE_STREAMS, - NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS, 0, sizeof(*id), - id, NULL); + dtype, 0, sizeof(*id), id, NULL); } int nvme_directive_recv_stream_allocate(int fd, __u32 nsid, __u16 nsr, __u32 *result) { + enum nvme_directive_dtype dtype = + NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE; + return nvme_directive_recv(fd, nsid, 0, NVME_DIRECTIVE_DTYPE_STREAMS, - NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE, nsr, 0, NULL, - result); + dtype, nsr, 0, NULL, result); } int nvme_set_property(int fd, int offset, __u64 value) @@ -1544,8 +1577,8 @@ int nvme_read(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 data_len, void *data, __u32 metadata_len, void *metadata) { return nvme_io(fd, nvme_cmd_read, nsid, slba, nlb, control, dsm, - reftag, apptag, appmask, data_len, data, metadata_len, - metadata); + reftag, apptag, appmask, data_len, data, metadata_len, + metadata); } int nvme_write(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, @@ -1556,8 +1589,8 @@ int nvme_write(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 flags = dsm | dspec << 16; return nvme_io(fd, nvme_cmd_write, nsid, slba, nlb, control, flags, - reftag, apptag, appmask, data_len, data, metadata_len, - metadata); + reftag, apptag, appmask, data_len, data, metadata_len, + metadata); } int nvme_compare(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, @@ -1565,28 +1598,28 @@ int nvme_compare(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, void *data, __u32 metadata_len, void *metadata) { return nvme_io(fd, nvme_cmd_compare, nsid, slba, nlb, control, 0, - reftag, apptag, appmask, data_len, data, metadata_len, - metadata); + reftag, apptag, appmask, data_len, data, metadata_len, + metadata); } int nvme_write_zeros(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 reftag, __u16 apptag, __u16 appmask) { return nvme_io(fd, nvme_cmd_write_zeroes, nsid, slba, nlb, control, 0, - reftag, apptag, appmask, 0, NULL, 0, NULL); + reftag, apptag, appmask, 0, NULL, 0, NULL); } int nvme_verify(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 reftag, __u16 apptag, __u16 appmask) { return nvme_io(fd, nvme_cmd_verify, nsid, slba, nlb, control, 0, - reftag, apptag, appmask, 0, NULL, 0, NULL); + reftag, apptag, appmask, 0, NULL, 0, NULL); } int nvme_write_uncorrectable(int fd, __u32 nsid, __u64 slba, __u16 nlb) { return nvme_io(fd, nvme_cmd_write_uncor, nsid, slba, nlb, 0, 0, 0, 0, - 0, 0, NULL, 0, NULL); + 0, 0, NULL, 0, NULL); } int nvme_dsm(int fd, __u32 nsid, __u32 attrs, __u16 nr_ranges, From ce04c5c27e2f3333a5c2995ce43aa0e71faaa45a Mon Sep 17 00:00:00 2001 From: Chaitanya Kulkarni Date: Mon, 10 Feb 2020 11:37:48 -0800 Subject: [PATCH 0019/1564] libnvme: code cleanup src/nvme/tree.c Various coding style fixes. Signed-off-by: Chaitanya Kulkarni Signed-off-by: Keith Busch --- src/nvme/tree.c | 54 ++++++++++++++++++------------------------------- 1 file changed, 20 insertions(+), 34 deletions(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 881dfe5921..a2f3bca834 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -31,14 +31,13 @@ static int nvme_scan_topology(struct nvme_root *r, nvme_scan_filter_t f) nvme_root_t nvme_scan_filter(nvme_scan_filter_t f) { - struct nvme_root *r = malloc(sizeof(*r)); + struct nvme_root *r = calloc(1, sizeof(*r)); if (!r) { errno = ENOMEM; return NULL; } - memset(r, 0, sizeof(*r)); list_head_init(&r->subsystems); nvme_scan_topology(r, f); return r; @@ -56,9 +55,7 @@ nvme_subsystem_t nvme_first_subsystem(nvme_root_t r) nvme_subsystem_t nvme_next_subsystem(nvme_root_t r, nvme_subsystem_t s) { - if (!s) - return NULL; - return list_next(&r->subsystems, s, entry); + return s ? list_next(&r->subsystems, s, entry) : NULL; } void nvme_refresh_topology(nvme_root_t r) @@ -110,9 +107,7 @@ nvme_ctrl_t nvme_subsystem_first_ctrl(nvme_subsystem_t s) nvme_ctrl_t nvme_subsystem_next_ctrl(nvme_subsystem_t s, nvme_ctrl_t c) { - if (!c) - return NULL; - return list_next(&s->ctrls, c, entry); + return c ? list_next(&s->ctrls, c, entry) : NULL; } nvme_ns_t nvme_subsystem_first_ns(nvme_subsystem_t s) @@ -122,9 +117,7 @@ nvme_ns_t nvme_subsystem_first_ns(nvme_subsystem_t s) nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n) { - if (!n) - return NULL; - return list_next(&s->namespaces, n, entry); + return n ? list_next(&s->namespaces, n, entry) : NULL; } static void nvme_free_ns(struct nvme_ns *n) @@ -196,12 +189,11 @@ int nvme_scan_subsystem(struct nvme_root *r, char *name, nvme_scan_filter_t f) if (ret < 0) return ret; - s = malloc(sizeof(*s)); + s = calloc(1, sizeof(*s)); if (!s) { errno = ENOMEM; goto free_path; } - memset(s, 0, sizeof(*s)); s->r = r; s->name = strdup(name);; @@ -291,12 +283,11 @@ int nvme_ctrl_scan_path(struct nvme_ctrl *c, char *name) return -1; } - p = malloc(sizeof(*p)); + p = calloc(1, sizeof(*p)); if (!p) { errno = ENOMEM; goto free_path; } - memset(p, 0, sizeof(*p)); p->c = c; p->name = strdup(name); @@ -400,9 +391,7 @@ nvme_ns_t nvme_ctrl_first_ns(nvme_ctrl_t c) nvme_ns_t nvme_ctrl_next_ns(nvme_ctrl_t c, nvme_ns_t n) { - if (!n) - return NULL; - return list_next(&c->namespaces, n, entry); + return n ? list_next(&c->namespaces, n, entry) : NULL; } nvme_path_t nvme_ctrl_first_path(nvme_ctrl_t c) @@ -412,14 +401,13 @@ nvme_path_t nvme_ctrl_first_path(nvme_ctrl_t c) nvme_path_t nvme_ctrl_next_path(nvme_ctrl_t c, nvme_path_t p) { - if (!p) - return NULL; - return list_next(&c->paths, p, entry); + return p ? list_next(&c->paths, p, entry) : NULL; } int nvme_ctrl_disconnect(nvme_ctrl_t c) { - return nvme_set_attr(nvme_ctrl_get_sysfs_dir(c), "delete_controller", "1"); + return nvme_set_attr(nvme_ctrl_get_sysfs_dir(c), + "delete_controller", "1"); } void nvme_unlink_ctrl(nvme_ctrl_t c) @@ -496,12 +484,11 @@ static nvme_ctrl_t __nvme_ctrl_alloc(const char *path, const char *name) return NULL; closedir(d); - c = malloc(sizeof(*c)); + c = calloc(1, sizeof(*c)); if (!c) { errno = ENOMEM; return NULL; } - memset(c, 0, sizeof(*c)); c->fd = nvme_open(name); if (c->fd < 0) @@ -569,8 +556,8 @@ int nvme_subsystem_scan_ctrl(struct nvme_subsystem *s, char *name) return 0; } -static int nvme_bytes_to_lba(nvme_ns_t n, off_t offset, size_t count, __u64 *lba, - __u16 *nlb) +static int nvme_bytes_to_lba(nvme_ns_t n, off_t offset, size_t count, + __u64 *lba, __u16 *nlb) { int bs; @@ -644,7 +631,7 @@ int nvme_ns_verify(nvme_ns_t n, off_t offset, size_t count) return -1; return nvme_verify(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), slba, nlb, - 0, 0, 0, 0); + 0, 0, 0, 0); } int nvme_ns_write_uncorrectable(nvme_ns_t n, off_t offset, size_t count) @@ -656,7 +643,7 @@ int nvme_ns_write_uncorrectable(nvme_ns_t n, off_t offset, size_t count) return -1; return nvme_write_uncorrectable(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), - slba, nlb); + slba, nlb); } int nvme_ns_write_zeros(nvme_ns_t n, off_t offset, size_t count) @@ -668,7 +655,7 @@ int nvme_ns_write_zeros(nvme_ns_t n, off_t offset, size_t count) return -1; return nvme_write_zeros(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), slba, - nlb, 0, 0, 0, 0); + nlb, 0, 0, 0, 0); } int nvme_ns_write(nvme_ns_t n, void *buf, off_t offset, size_t count) @@ -680,7 +667,7 @@ int nvme_ns_write(nvme_ns_t n, void *buf, off_t offset, size_t count) return -1; return nvme_write(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), slba, nlb, 0, - 0, 0, 0, 0, 0, count, buf, 0, NULL); + 0, 0, 0, 0, 0, count, buf, 0, NULL); } int nvme_ns_read(nvme_ns_t n, void *buf, off_t offset, size_t count) @@ -692,7 +679,7 @@ int nvme_ns_read(nvme_ns_t n, void *buf, off_t offset, size_t count) return -1; return nvme_read(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), slba, nlb, 0, - 0, 0, 0, 0, count, buf, 0, NULL); + 0, 0, 0, 0, count, buf, 0, NULL); } int nvme_ns_compare(nvme_ns_t n, void *buf, off_t offset, size_t count) @@ -704,7 +691,7 @@ int nvme_ns_compare(nvme_ns_t n, void *buf, off_t offset, size_t count) return -1; return nvme_compare(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), slba, nlb, - 0, 0, 0, 0, count, buf, 0, NULL); + 0, 0, 0, 0, count, buf, 0, NULL); } int nvme_ns_flush(nvme_ns_t n) @@ -736,12 +723,11 @@ static struct nvme_ns *__nvme_scan_namespace(const char *sysfs_dir, char *name) return NULL; } - n = malloc(sizeof(*n)); + n = calloc(1, sizeof(*n)); if (!n) { errno = ENOMEM; goto free_path; } - memset(n, 0, sizeof(*n)); n->name = strdup(name); n->sysfs_dir = path; From a6530a6f5b14dd2129056a13dd77127b81fdbdf6 Mon Sep 17 00:00:00 2001 From: Chaitanya Kulkarni Date: Mon, 10 Feb 2020 11:37:49 -0800 Subject: [PATCH 0020/1564] libnvme: code cleanup src/nvme/util.c Various coding style fixes. Signed-off-by: Chaitanya Kulkarni Signed-off-by: Keith Busch --- src/nvme/util.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/nvme/util.c b/src/nvme/util.c index 7ce5b63c0e..11760263f7 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -232,7 +232,7 @@ int nvme_fw_download_seq(int fd, __u32 size, __u32 xfer, __u32 offset, } int __nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, - __u32 xfer_len, __u32 data_len, void *data) + __u32 xfer_len, __u32 data_len, void *data) { __u64 offset = 0, xfer; bool retain = true; @@ -270,13 +270,13 @@ int __nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, } int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, - __u32 data_len, void *data) + __u32 data_len, void *data) { return __nvme_get_log_page(fd, nsid, log_id, rae, 4096, data_len, data); } -static int nvme_get_telemetry_log(int fd, bool create, bool ctrl, bool rae, void **buf, - __u32 *log_size) +static int nvme_get_telemetry_log(int fd, bool create, bool ctrl, bool rae, + void **buf, __u32 *log_size) { static const __u32 xfer = 512; @@ -382,26 +382,27 @@ void nvme_setup_ctrl_list(struct nvme_ctrl_list *cntlist, __u16 num_ctrls, cntlist->identifier[i] = cpu_to_le16(ctrlist[i]); } -static int nvme_ns_attachment(int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist, bool attach) +static int nvme_ns_attachment(int fd, __u32 nsid, __u16 num_ctrls, + __u16 *ctrlist, bool attach) { + enum nvme_ns_attach_sel sel = NVME_NS_ATTACH_SEL_CTRL_DEATTACH; struct nvme_ctrl_list cntlist = { 0 }; - enum nvme_ns_attach_sel sel; if (attach) sel = NVME_NS_ATTACH_SEL_CTRL_ATTACH; - else - sel = NVME_NS_ATTACH_SEL_CTRL_DEATTACH; nvme_setup_ctrl_list(&cntlist, num_ctrls, ctrlist); return nvme_ns_attach(fd, nsid, sel, &cntlist); } -int nvme_namespace_attach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist) +int nvme_namespace_attach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, + __u16 *ctrlist) { return nvme_ns_attachment(fd, nsid, num_ctrls, ctrlist, true); } -int nvme_namespace_detach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist) +int nvme_namespace_detach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, + __u16 *ctrlist) { return nvme_ns_attachment(fd, nsid, num_ctrls, ctrlist, false); } @@ -544,7 +545,6 @@ static char *__nvme_get_attr(const char *path) if (fd < 0) return NULL; - memset(value, 0, sizeof(value)); ret = read(fd, value, sizeof(value) - 1); if (ret < 0) { close(fd); From 0049b2e5fab6d927f684715ba405ff0933904902 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Mon, 10 Feb 2020 13:03:38 -0800 Subject: [PATCH 0021/1564] Consolodate features into common header Locate all command submission helper declarations into common ioctl.h header rather than split these. Remove the private.h file as only one .c was using it. Signed-off-by: Keith Busch --- src/Makefile | 2 +- src/libnvme.h | 1 - src/nvme/cmd.h | 2566 -------------------------------------------- src/nvme/fabrics.c | 3 +- src/nvme/ioctl.c | 2 - src/nvme/ioctl.h | 2559 +++++++++++++++++++++++++++++++++++++++++++ src/nvme/private.h | 101 -- src/nvme/tree.c | 95 +- src/nvme/util.c | 2 - src/nvme/util.h | 2 +- 10 files changed, 2655 insertions(+), 2678 deletions(-) delete mode 100644 src/nvme/cmd.h delete mode 100644 src/nvme/private.h diff --git a/src/Makefile b/src/Makefile index 35fa88555b..5f42219cb8 100644 --- a/src/Makefile +++ b/src/Makefile @@ -54,7 +54,7 @@ libccan_sobjs := $(patsubst %.c,%.os,$(libccan_srcs)) $(libccan_objs) $(libccan_sobjs): $(libccan_headers) libnvme_priv := nvme/private.h -libnvme_api := libnvme.h nvme/types.h nvme/ioctl.h nvme/filters.h nvme/tree.h nvme/util.h nvme/cmd.h +libnvme_api := libnvme.h nvme/types.h nvme/ioctl.h nvme/filters.h nvme/tree.h nvme/util.h libnvme_srcs := nvme/ioctl.c nvme/filters.c nvme/fabrics.c nvme/util.c nvme/tree.c libnvme_objs := $(patsubst %.c,%.ol,$(libnvme_srcs)) libnvme_sobjs := $(patsubst %.c,%.os,$(libnvme_srcs)) diff --git a/src/libnvme.h b/src/libnvme.h index c4921cbfce..66e17d0c15 100644 --- a/src/libnvme.h +++ b/src/libnvme.h @@ -2,7 +2,6 @@ #define _LIBNVME_H #include "nvme/types.h" -#include "nvme/cmd.h" #include "nvme/ioctl.h" #include "nvme/fabrics.h" #include "nvme/filters.h" diff --git a/src/nvme/cmd.h b/src/nvme/cmd.h deleted file mode 100644 index 80b7b96eb2..0000000000 --- a/src/nvme/cmd.h +++ /dev/null @@ -1,2566 +0,0 @@ -#ifndef _LIBNVME_CMD_H -#define _LIBNVME_CMD_H - -#include "types.h" - -/** - * DOC: NVMe Admin command enums - */ - -/** - * enum nvme_admin_opcode - Known NVMe admin opcodes - * @nvme_admin_delete_sq: - * @nvme_admin_create_sq: - * @nvme_admin_get_log_page: - * @nvme_admin_delete_cq: - * @nvme_admin_create_cq: - * @nvme_admin_identify: - * @nvme_admin_abort_cmd: - * @nvme_admin_set_features: - * @nvme_admin_get_features: - * @nvme_admin_async_event: - * @nvme_admin_ns_mgmt: - * @nvme_admin_fw_commit: - * @nvme_admin_fw_download: - * @nvme_admin_dev_self_test: - * @nvme_admin_ns_attach: - * @nvme_admin_keep_alive: - * @nvme_admin_directive_send: - * @nvme_admin_directive_recv: - * @nvme_admin_virtual_mgmt: - * @nvme_admin_nvme_mi_send: - * @nvme_admin_nvme_mi_recv: - * @nvme_admin_dbbuf: - * @nvme_admin_fabrics: - * @nvme_admin_format_nvm: - * @nvme_admin_security_send: - * @nvme_admin_security_recv: - * @nvme_admin_sanitize_nvm: - * @nvme_admin_get_lba_status: - */ -enum nvme_admin_opcode { - nvme_admin_delete_sq = 0x00, - nvme_admin_create_sq = 0x01, - nvme_admin_get_log_page = 0x02, - nvme_admin_delete_cq = 0x04, - nvme_admin_create_cq = 0x05, - nvme_admin_identify = 0x06, - nvme_admin_abort_cmd = 0x08, - nvme_admin_set_features = 0x09, - nvme_admin_get_features = 0x0a, - nvme_admin_async_event = 0x0c, - nvme_admin_ns_mgmt = 0x0d, - nvme_admin_fw_commit = 0x10, - nvme_admin_fw_download = 0x11, - nvme_admin_dev_self_test = 0x14, - nvme_admin_ns_attach = 0x15, - nvme_admin_keep_alive = 0x18, - nvme_admin_directive_send = 0x19, - nvme_admin_directive_recv = 0x1a, - nvme_admin_virtual_mgmt = 0x1c, - nvme_admin_nvme_mi_send = 0x1d, - nvme_admin_nvme_mi_recv = 0x1e, - nvme_admin_dbbuf = 0x7c, - nvme_admin_fabrics = 0x7f, - nvme_admin_format_nvm = 0x80, - nvme_admin_security_send = 0x81, - nvme_admin_security_recv = 0x82, - nvme_admin_sanitize_nvm = 0x84, - nvme_admin_get_lba_status = 0x86, -}; - -/** - * enum nvme_identify_cns - - * @NVME_IDENTIFY_CNS_NS: - * @NVME_IDENTIFY_CNS_CTRL: - * @NVME_IDENTIFY_CNS_NS_ACTIVE_LIST: - * @NVME_IDENTIFY_CNS_NS_DESC_LIST: - * @NVME_IDENTIFY_CNS_NVMSET_LIST: - * @NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST: - * @NVME_IDENTIFY_CNS_ALLOCATED_NS: - * @NVME_IDENTIFY_CNS_NS_CTRL_LIST: - * @NVME_IDENTIFY_CNS_CTRL_LIST: - * @NVME_IDENTIFY_CNS_PRIMARY_CTRL_CAP: - * @NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST: - * @NVME_IDENTIFY_CNS_NS_GRANULARITY: - * @NVME_IDENTIFY_CNS_UUID_LIST: - */ -enum nvme_identify_cns { - NVME_IDENTIFY_CNS_NS = 0x00, - NVME_IDENTIFY_CNS_CTRL = 0x01, - NVME_IDENTIFY_CNS_NS_ACTIVE_LIST = 0x02, - NVME_IDENTIFY_CNS_NS_DESC_LIST = 0x03, - NVME_IDENTIFY_CNS_NVMSET_LIST = 0x04, - NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST = 0x10, - NVME_IDENTIFY_CNS_ALLOCATED_NS = 0x11, - NVME_IDENTIFY_CNS_NS_CTRL_LIST = 0x12, - NVME_IDENTIFY_CNS_CTRL_LIST = 0x13, - NVME_IDENTIFY_CNS_PRIMARY_CTRL_CAP = 0x14, - NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST = 0x15, - NVME_IDENTIFY_CNS_NS_GRANULARITY = 0x16, - NVME_IDENTIFY_CNS_UUID_LIST = 0x17, -}; - -/** - * enum nvme_cmd_get_log_lid - - * @NVME_LOG_LID_ERROR: - * @NVME_LOG_LID_SMART: - * @NVME_LOG_LID_FW_SLOT: - * @NVME_LOG_LID_CHANGED_NS: - * @NVME_LOG_LID_CMD_EFFECTS: - * @NVME_LOG_LID_DEVICE_SELF_TEST: - * @NVME_LOG_LID_TELEMETRY_HOST: - * @NVME_LOG_LID_TELEMETRY_CTRL: - * @NVME_LOG_LID_ENDURANCE_GROUP: - * @NVME_LOG_LID_PREDICTABLE_LAT_NVMSET: - * @NVME_LOG_LID_PREDICTABLE_LAT_AGG: - * @NVME_LOG_LID_ANA: - * @NVME_LOG_LID_PERSISTENT_EVENT: - * @NVME_LOG_LID_LBA_STATUS: - * @NVME_LOG_LID_ENDURANCE_GRP_EVT: - * @NVME_LOG_LID_DISCOVER: - * @NVME_LOG_LID_RESERVATION: - * @NVME_LOG_LID_SANITIZE: - */ -enum nvme_cmd_get_log_lid { - NVME_LOG_LID_ERROR = 0x01, - NVME_LOG_LID_SMART = 0x02, - NVME_LOG_LID_FW_SLOT = 0x03, - NVME_LOG_LID_CHANGED_NS = 0x04, - NVME_LOG_LID_CMD_EFFECTS = 0x05, - NVME_LOG_LID_DEVICE_SELF_TEST = 0x06, - NVME_LOG_LID_TELEMETRY_HOST = 0x07, - NVME_LOG_LID_TELEMETRY_CTRL = 0x08, - NVME_LOG_LID_ENDURANCE_GROUP = 0x09, - NVME_LOG_LID_PREDICTABLE_LAT_NVMSET = 0x0a, - NVME_LOG_LID_PREDICTABLE_LAT_AGG = 0x0b, - NVME_LOG_LID_ANA = 0x0c, - NVME_LOG_LID_PERSISTENT_EVENT = 0x0d, - NVME_LOG_LID_LBA_STATUS = 0x0e, - NVME_LOG_LID_ENDURANCE_GRP_EVT = 0x0f, - NVME_LOG_LID_DISCOVER = 0x70, - NVME_LOG_LID_RESERVATION = 0x80, - NVME_LOG_LID_SANITIZE = 0x81, -}; - -/** - * enum nvme_features_id - - * @NVME_FEAT_FID_ARBITRATION: - * @NVME_FEAT_FID_POWER_MGMT: - * @NVME_FEAT_FID_LBA_RANGE: - * @NVME_FEAT_FID_TEMP_THRESH: - * @NVME_FEAT_FID_ERR_RECOVERY: - * @NVME_FEAT_FID_VOLATILE_WC: - * @NVME_FEAT_FID_NUM_QUEUES: - * @NVME_FEAT_FID_IRQ_COALESCE: - * @NVME_FEAT_FID_IRQ_CONFIG: - * @NVME_FEAT_FID_WRITE_ATOMIC: - * @NVME_FEAT_FID_ASYNC_EVENT: - * @NVME_FEAT_FID_AUTO_PST: - * @NVME_FEAT_FID_HOST_MEM_BUF: - * @NVME_FEAT_FID_TIMESTAMP: - * @NVME_FEAT_FID_KATO: - * @NVME_FEAT_FID_HCTM: - * @NVME_FEAT_FID_NOPSC: - * @NVME_FEAT_FID_RRL: - * @NVME_FEAT_FID_PLM_CONFIG: - * @NVME_FEAT_FID_PLM_WINDOW: - * @NVME_FEAT_FID_LBA_STS_INTERVAL: - * @NVME_FEAT_FID_HOST_BEHAVIOR: - * @NVME_FEAT_FID_SANITIZE: - * @NVME_FEAT_FID_ENDURANCE_EVT_CFG: - * @NVME_FEAT_FID_SW_PROGRESS: - * @NVME_FEAT_FID_HOST_ID: - * @NVME_FEAT_FID_RESV_MASK: - * @NVME_FEAT_RESV_PERSIST: - * @NVME_FEAT_FID_WRITE_PROTECT: - */ -enum nvme_features_id { - NVME_FEAT_FID_ARBITRATION = 0x01, - NVME_FEAT_FID_POWER_MGMT = 0x02, - NVME_FEAT_FID_LBA_RANGE = 0x03, - NVME_FEAT_FID_TEMP_THRESH = 0x04, - NVME_FEAT_FID_ERR_RECOVERY = 0x05, - NVME_FEAT_FID_VOLATILE_WC = 0x06, - NVME_FEAT_FID_NUM_QUEUES = 0x07, - NVME_FEAT_FID_IRQ_COALESCE = 0x08, - NVME_FEAT_FID_IRQ_CONFIG = 0x09, - NVME_FEAT_FID_WRITE_ATOMIC = 0x0a, - NVME_FEAT_FID_ASYNC_EVENT = 0x0b, - NVME_FEAT_FID_AUTO_PST = 0x0c, - NVME_FEAT_FID_HOST_MEM_BUF = 0x0d, - NVME_FEAT_FID_TIMESTAMP = 0x0e, - NVME_FEAT_FID_KATO = 0x0f, - NVME_FEAT_FID_HCTM = 0X10, - NVME_FEAT_FID_NOPSC = 0X11, - NVME_FEAT_FID_RRL = 0x12, - NVME_FEAT_FID_PLM_CONFIG = 0x13, - NVME_FEAT_FID_PLM_WINDOW = 0x14, - NVME_FEAT_FID_LBA_STS_INTERVAL = 0x15, - NVME_FEAT_FID_HOST_BEHAVIOR = 0x16, - NVME_FEAT_FID_SANITIZE = 0x17, - NVME_FEAT_FID_ENDURANCE_EVT_CFG = 0x18, - NVME_FEAT_FID_SW_PROGRESS = 0x80, - NVME_FEAT_FID_HOST_ID = 0x81, - NVME_FEAT_FID_RESV_MASK = 0x82, - NVME_FEAT_RESV_PERSIST = 0x83, - NVME_FEAT_FID_WRITE_PROTECT = 0x84, -}; - -/** - * enum nvme_get_features_sel - - * @NVME_GET_FEATURES_SEL_CURRENT: - * @NVME_GET_FEATURES_SEL_DEFAULT: - * @NVME_GET_FEATURES_SEL_SAVED: - */ -enum nvme_get_features_sel { - NVME_GET_FEATURES_SEL_CURRENT = 0, - NVME_GET_FEATURES_SEL_DEFAULT = 1, - NVME_GET_FEATURES_SEL_SAVED = 2, -}; - -/** - * enum nvme_cmd_format_mset - - * @NVME_FORMAT_MSET_SEPARATE: - * @NVME_FORMAT_MSET_EXTENEDED: - */ -enum nvme_cmd_format_mset { - NVME_FORMAT_MSET_SEPARATE = 0, - NVME_FORMAT_MSET_EXTENEDED = 1, -}; - -/** - * enum nvme_cmd_format_pi - - * @NVME_FORMAT_PI_DISABLE: - * @NVME_FORMAT_PI_TYPE1: - * @NVME_FORMAT_PI_TYPE2: - * @NVME_FORMAT_PI_TYPE3: - */ -enum nvme_cmd_format_pi { - NVME_FORMAT_PI_DISABLE = 0, - NVME_FORMAT_PI_TYPE1 = 1, - NVME_FORMAT_PI_TYPE2 = 2, - NVME_FORMAT_PI_TYPE3 = 3, -}; - -/** - * @enum nvme_cmd_format_pil - - * @NVME_FORMAT_PIL_LAST: - * @NVME_FORMAT_PIL_FIRST: - */ -enum nvme_cmd_format_pil { - NVME_FORMAT_PIL_LAST = 0, - NVME_FORMAT_PIL_FIRST = 1, -}; - -/** - * enum nvme_cmd_format_ses - - * @NVME_FORMAT_SES_NONE: - * @NVME_FORMAT_SES_USER_DATA_ERASE: - * @NVME_FORMAT_SES_CRYPTO_ERASE: - */ -enum nvme_cmd_format_ses { - NVME_FORMAT_SES_NONE = 0, - NVME_FORMAT_SES_USER_DATA_ERASE = 1, - NVME_FORMAT_SES_CRYPTO_ERASE = 2, -}; - -/** - * enum nvme_ns_mgmt_sel - - * @NVME_NAMESPACE_MGMT_SEL_CREATE: - * @NVME_NAMESPACE_MGMT_SEL_DELETE: - */ -enum nvme_ns_mgmt_sel { - NVME_NS_MGMT_SEL_CREATE = 0, - NVME_NS_MGMT_SEL_DELETE = 1, -}; - -/** - * enum nvme_ns_attach_sel - - * NVME_NS_ATTACH_SEL_CTRL_ATTACH: - * NVME_NP_ATTACH_SEL_CTRL_DEATTACH: - */ -enum nvme_ns_attach_sel { - NVME_NS_ATTACH_SEL_CTRL_ATTACH = 0, - NVME_NS_ATTACH_SEL_CTRL_DEATTACH = 1, -}; - -/** - * enum nvme_fw_commit_ca - - * @NVME_FW_COMMIT_CA_REPLACE: - * @NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE: - * @NVME_FW_COMMIT_CA_SET_ACTIVE: - * @NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE_IMMEDIATE: - * @NVME_FW_COMMIT_CA_REPLACE_BOOT_PARTITION: - * @NVME_FW_COMMIT_CA_ACTIVATE_BOOT_PARTITION: - */ -enum nvme_fw_commit_ca { - NVME_FW_COMMIT_CA_REPLACE = 0, - NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE = 1, - NVME_FW_COMMIT_CA_SET_ACTIVE = 2, - NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE_IMMEDIATE = 3, - NVME_FW_COMMIT_CA_REPLACE_BOOT_PARTITION = 6, - NVME_FW_COMMIT_CA_ACTIVATE_BOOT_PARTITION = 7, -}; - -/** - * enum nvme_directive_dtype - - * @NVME_DIRECTIVE_DTYPE_IDENTIFY: - * @NVME_DIRECTIVE_DTYPE_STREAMS: - */ -enum nvme_directive_dtype { - NVME_DIRECTIVE_DTYPE_IDENTIFY = 0, - NVME_DIRECTIVE_DTYPE_STREAMS = 1, -}; - -/** - * enum nvme_directive_receive_doper - - * @NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM: - * @NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM: - * @NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS: - * @NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE: - */ -enum nvme_directive_receive_doper { - NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM = 0x01, - NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM = 0x01, - NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS = 0x02, - NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE = 0x03, -}; - -/** - * enum nvme_directive_send_doper - - * @NVME_DIRECTIVE_SEND_IDENTIFY_DOPER_ENDIR: - * @NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_IDENTIFIER: - * @NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE: - */ -enum nvme_directive_send_doper { - NVME_DIRECTIVE_SEND_IDENTIFY_DOPER_ENDIR = 0x01, - NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_IDENTIFIER = 0x01, - NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE = 0x02, -}; - -/** - * enum - - */ -enum nvme_directive_send_identify_endir { - NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_DISABLE = 0, - NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_ENABLE = 1, -}; - -/** - * enum nvme_sanitize_sanact - - * @NVME_SANITIZE_SANACT_EXIT_FAILURE: - * @NVME_SANITIZE_SANACT_START_BLOCK_ERASE: - * @NVME_SANITIZE_SANACT_START_OVERWRITE: - * @NVME_SANITIZE_SANACT_START_CRYPTO_ERASE: - */ -enum nvme_sanitize_sanact { - NVME_SANITIZE_SANACT_EXIT_FAILURE = 1, - NVME_SANITIZE_SANACT_START_BLOCK_ERASE = 2, - NVME_SANITIZE_SANACT_START_OVERWRITE = 3, - NVME_SANITIZE_SANACT_START_CRYPTO_ERASE = 4, -}; - -/** - * enum nvme_dst_stc - - * @NVME_DST_STC_SHORT: - * @NVME_DST_STC_LONG: - * @NVME_DST_STC_VS: - * @NVME_DST_STC_ABORT: - */ -enum nvme_dst_stc { - NVME_DST_STC_SHORT = 0x1, - NVME_DST_STC_LONG = 0x2, - NVME_DST_STC_VS = 0xe, - NVME_DST_STC_ABORT = 0xf, -}; - -/** - * enum nvme_virt_mgmt_act - - * @NVME_VIRT_MGMT_ACT_PRIM_CTRL_FLEX_ALLOC: - * @NVME_VIRT_MGMT_ACT_OFFLINE_SEC_CTRL: - * @NVME_VIRT_MGMT_ACT_ASSIGN_SEC_CTRL: - * @NVME_VIRT_MGMT_ACT_ONLINE_SEC_CTRL: - */ -enum nvme_virt_mgmt_act { - NVME_VIRT_MGMT_ACT_PRIM_CTRL_FLEX_ALLOC = 1, - NVME_VIRT_MGMT_ACT_OFFLINE_SEC_CTRL = 7, - NVME_VIRT_MGMT_ACT_ASSIGN_SEC_CTRL = 8, - NVME_VIRT_MGMT_ACT_ONLINE_SEC_CTRL = 9, -}; - -/** - * enum nvme_virt_mgmt_rt - - * @NVME_VIRT_MGMT_RT_VQ_RESOURCE: - * @NVME_VIRT_MGMT_RT_VI_RESOURCE: - */ -enum nvme_virt_mgmt_rt { - NVME_VIRT_MGMT_RT_VQ_RESOURCE = 0, - NVME_VIRT_MGMT_RT_VI_RESOURCE = 1, -}; - -/** - * nvme_identify() - Send the NVMe Identify command - * @fd: File descriptor of nvme device - * @cns: The Controller or Namespace structure, see @enum nvme_identify_cns - * @nsid: Namespace identifier, if applicable - * @cntid: The Controller Identifier, if applicable - * @nvmsetid: The NVMe Set ID if CNS is 04h - * @uuidx: UUID Index if controller supports this id selection method - * @data: User space destination address to transfer the data - * - * The Identify command returns a data buffer that describes information about - * the NVM subsystem, the controller or the namespace(s). - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_identify(int fd, enum nvme_identify_cns cns, __u32 nsid, - __u16 cntid, __u16 nvmsetid, __u8 uuidx, void *data); - -/** - * nvme_identify_ctrl() - Retrieves nvme identify controller - * @fd: File descriptor of nvme device - * id: User space destination address to transfer the data, - * - * Sends nvme identify with CNS value %NVME_IDENTIFY_CNS_CTRL. - * - * See &struct nvme_id_ctrl for details on the data returned. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_identify_ctrl(int fd, struct nvme_id_ctrl *id); - -/** - * nvme_identify_ns() - Retrieves nvme identify namespace - * @fd: File descriptor of nvme device - * @nsid: Namespace to identify - * @ns: User space destination address to transfer the data - * - * If the Namespace Identifier (NSID) field specifies an active NSID, then the - * Identify Namespace data structure is returned to the host for that specified - * namespace. - * - * If the controller supports the Namespace Management capability and the NSID - * field is set to %NVME_NSID_ALL, then the controller returns an Identify Namespace - * data structure that specifies capabilities that are common across namespaces - * for this controller. - * - * See &struct nvme_id_ns for details on the structure returned. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -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 - * @fd: File descriptor of nvme device - * @nsid: Namespace to identify - * @ns: User space destination address to transfer the data - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_identify_allocated_ns(int fd, __u32 nsid, struct nvme_id_ns *ns); - -/** - * nvme_identify_active_ns_list() - Retrieves active namespaces id list - * @fd: File descriptor of nvme device - * @nsid: Return namespaces greater than this identifer - * @ns_list: User space destination address to transfer the data - * - * A list of 1024 namespace IDs is returned to the host containing NSIDs in - * increasing order that are greater than the value specified in the Namespace - * Identifier (nsid) field of the command. - * - * See &struct nvme_ns_list for the definition of the returned structure. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_identify_active_ns_list(int fd, __u32 nsid, struct nvme_ns_list *list); - -/** - * nvme_identify_allocated_ns_list() - Retrieves allocated namespace id list - * @fd: File descriptor of nvme device - * @nsid: Return namespaces greater than this identifer - * @ns_list: User space destination address to transfer the data - * - * A list of 1024 namespace IDs is returned to the host containing NSIDs in - * increasing order that are greater than the value specified in the Namespace - * Identifier (nsid) field of the command. - * - * See &struct nvme_ns_list for the definition of the returned structure. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_identify_allocated_ns_list(int fd, __u32 nsid, - struct nvme_ns_list *list); - -/** - * nvme_identify_ctrl_list() - Retrieves identify controller list - * @fd: File descriptor of nvme device - * @cntlid: Starting CNTLID to return in the list - * @cntlist: User space destination address to transfer the data - * - * Up to 2047 controller identifiers is returned containing a controller - * identifier greater than or equal to the controller identifier specified in - * @cntid. - * - * See &struct nvme_ctrl_list for a definition of the structure returned. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_identify_ctrl_list(int fd, __u16 cntid, - struct nvme_ctrl_list *ctrlist); - -/** - * nvme_identify_nsid_ctrl_list() - - * @fd: File descriptor of nvme device - * @nsid: Return controllers that are attached to this nsid - * @cntlid: Starting CNTLID to return in the list - * @cntlist: User space destination address to transfer the data - * - * Up to 2047 controller identifiers is returned containing a controller - * identifier greater than or equal to the controller identifier specified in - * @cntid. - * - * See &struct nvme_ctrl_list for a definition of the structure returned. - * - * Return: The nvme command status if a response was received or -1 - */ -int nvme_identify_nsid_ctrl_list(int fd, __u32 nsid, __u16 cntid, - struct nvme_ctrl_list *ctrlist); - -/** - * nvme_identify_ns_descs() - Retrieves namespace descriptor list - * @fd: File descriptor of nvme device - * @nsid: The namespace id to retrieve destriptors - * @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'. - * - * See &struct nvme_ns_id_desc for the definition of the returned structure. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_identify_ns_descs(int fd, __u32 nsid, struct nvme_ns_id_desc *descs); - -/** - * nvme_identify_nvmset_list() - Retrieves NVM Set List - * @fd: File descriptor of nvme device - * @nvmeset_id: NVM Set Identifier - * @nvmset: User space destination address to transfer the data - * - * Retrieves an NVM Set List, struct nvme_id_nvmset. The data structure is an - * ordered list by NVM Set Identifier, starting with the first NVM Set - * 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. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_identify_nvmset_list(int fd, __u16 nvmsetid, - struct nvme_id_nvmset_list *nvmset); - -/** - * nvme_identify_primary_ctrl() - Retrieve NVMe Primary Controller - * identification - * &fd: - * @cntid: - * @cap: - * - * See &struct nvme_primary_ctrl_cap for the defintion of the returned structure, @cap. - * - * Return: The nvme command status if a response was received or -1 - * with errno set otherwise. - */ -int nvme_identify_primary_ctrl(int fd, __u16 cntid, - struct nvme_primary_ctrl_cap *cap); - -/** - * nvme_identify_secondary_ctrl_list() - Retrieves secondary controller list - * @fd: File descriptor of nvme device - * @cntid: Return controllers starting at this identifier - * @sc_list: User space destination address to transfer the data - * - * A Secondary Controller List is returned to the host for up to 127 secondary - * controllers associated with the primary controller processing this command. - * 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 - * structure. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_identify_secondary_ctrl_list(int fd, __u16 cntid, - struct nvme_secondary_ctrl_list *list); - -/** - * nvme_identify_ns_granularity() - Retrieves namespace granularity - * identification - * @fd: File descriptor of nvme device - * @gr_list: User space destination address to transfer the data - * - * If the controller supports reporting of Namespace Granularity, then a - * Namespace Granularity List is returned to the host for up to sixteen - * namespace granularity descriptors - * - * See &struct nvme_id_ns_granularity_list for the definition of the returned - * structure. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_identify_ns_granularity(int fd, struct nvme_id_ns_granularity_list *list); - -/** - * nvme_identify_uuid() - Retrieves device's UUIDs - * @fd: File descriptor of nvme device - * @uuid_list: User space destination address to transfer the data - * - * Each UUID List entry is either 0h, the NVMe Invalid UUID, or a valid UUID. - * Valid UUIDs are those which are non-zero and are not the NVMe Invalid UUID. - * - * See &struct nvme_id_uuid_list for the definition of the returned structure. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_identify_uuid(int fd, struct nvme_id_uuid_list *list); - -/** - * nvme_get_log() - NVMe Admin Get Log command - * @fd: File descriptor of nvme device - * @lid: Log page identifier, see &enum nvme_cmd_get_log_lid for known values - * @nsid: Namespace identifier, if applicable - * @lpo: Log page offset for partial log transfers - * @lsp: Log specific field - * @lsi: Endurance group information - * @rae: Retain asynchronous events - * @uuidx: UUID selection, if supported - * @len: Length of provided user buffer to hold the log data in bytes - * @log: User space destination address to transfer the data - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, - __u8 lsp, __u16 lsi, bool rae, __u8 uuidx, __u32 len, void *log); - -/** - * nvme_get_log_error() - Retrieve nvme error log - * @fd: File descriptor of nvme device - * @entries: Number of error log entries allocated - * @rae: Retain asynchronous events - * @err_log: Array of error logs of size 'entries' - * - * This log page is used to describe extended error information for a command - * that completed with error, or may report an error that is not specific to a - * particular command. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_log_error(int fd, unsigned nr_entries, bool rae, - struct nvme_error_log_page *log); - -/** - * nvme_get_log_smart() - Retrieve nvme smart log - * @fd: File descriptor of nvme device - * @nsid: Optional namespace identifier - * @rae: Retain asynchronous events - * @smart_log: User address to store the smart log - * - * This log page is used to provide SMART and general health information. The - * information provided is over the life of the controller and is retained - * across power cycles. To request the controller log page, the namespace - * identifier specified is FFFFFFFFh. The controller may also support - * requesting the log page on a per namespace basis, as indicated by bit 0 of - * the LPA field in the Identify Controller data structure. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_log_smart(int fd, __u32 nsid, bool rae, struct nvme_smart_log *log); - -/** - * nvme_get_log_fw_slot() - Retrieves the controller firmware log - * @fd: File descriptor of nvme device - * @rae: Retain asynchronous events - * @fw_log: User address to store the log page - * - * This log page is used to describe the firmware revision stored in each - * firmware slot supported. The firmware revision is indicated as an ASCII - * string. The log page also indicates the active slot number. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_log_fw_slot(int fd, bool rae, struct nvme_firmware_slot *log); - -/** - * nvme_get_log_changed_ns_list() - Retrieve namespace changed list - * @fd: File descriptor of nvme device - * @rae: Retain asynchronous events - * @ns_list: User address to store the log page - * - * This log page is used to describe namespaces attached to this controller - * that have changed since the last time the namespace was identified, been - * added, or deleted. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_log_changed_ns_list(int fd, bool rae, struct nvme_ns_list *log); - -/** - * nvme_get_log_cmd_effects() - Retrieve nvme command effects log - * @fd: File descriptor of nvme device - * @effects_log:User address to store the effects log - * - * This log page is used to describe the commands that the controller supports - * and the effects of those commands on the state of the NVM subsystem. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_log_cmd_effects(int fd, struct nvme_cmd_effects_log *log); - -/** - * nvme_get_log_device_self_test() - Retrieve the device self test log - * @fd: File descriptor of nvme device - * @nsid: Namespace ID being tested - * @log: Userspace address of the log payload - * - * The log page is used to indicate the status of an in progress self test and - * the percent complete of that operation, and the results of the previous 20 - * self-test operations. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_log_device_self_test(int fd, struct nvme_self_test_log *log); - -/** - * nvme_get_log_create_telemetry_host() - - */ -int nvme_get_log_create_telemetry_host(int fd, struct nvme_telemetry_log *log); - -/** - * nvme_get_log_telemetry_host() - - * @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 - * using the previously existing capture. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_log_telemetry_host(int fd, __u64 offset, __u32 len, void *log); - -/** - * nvme_get_log_telemetry_ctrl() - - * @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 - */ -int nvme_get_log_telemetry_ctrl(int fd, bool rae, __u64 offset, __u32 len, - void *log); - -/** - * nvme_get_log_endurance_group() - - * @fd: File descriptor of nvme device - * @endgid: Starting group identifier to return in the list - * @log: User address to store the endurance log - * - * This log page indicates if an Endurance Group Event has occurred for a - * particular Endurance Group. If an Endurance Group Event has occurred, the - * details of the particular event are included in the Endurance Group - * Information log page for that Endurance Group. An asynchronous event is - * generated when an entry for an Endurance Group is newly added to this log - * page. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_log_endurance_group(int fd, __u16 endgid, - struct nvme_endurance_group_log *log); - -/** - * nvme_get_log_predictable_lat_nvmset() - - * @fd: - * @nvmsetid: - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_log_predictable_lat_nvmset(int fd, __u16 nvmsetid, - struct nvme_nvmset_predictable_lat_log *log); - -/** - * nvme_get_log_predictable_lat_event() - - * @fd: File descriptor of nvme device - * @rae: Retain asynchronous events - */ -int nvme_get_log_predictable_lat_event(int fd, bool rae, __u32 offset, - __u32 len, void *log); - -/** - * - */ -enum nvme_log_ana_lsp { - NVME_LOG_ANA_LSP_RGO_NAMESPACES = 0, - NVME_LOG_ANA_LSP_RGO_GROUPS_ONLY = 1, -}; - -/** - * nvme_get_log_ana() - - * @fd: File descriptor of nvme device - * @lsp: Log specific, see &enum nvme_get_log_ana_lsp - * @rae: Retain asynchronous events - * @len: The allocated length of the log page - * @log: User address to store the ana log - * - * This log consists of a header describing the log and descriptors containing - * the asymmetric namespace access information for ANA Groups that contain - * namespaces that are attached to the controller processing the command. - * - * See &struct nvme_ana_rsp_hdr for the defintion of the returned structure. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_log_ana(int fd, enum nvme_log_ana_lsp lsp, bool rae, __u64 offset, - __u32 len, void *log); - -/** - * nvme_get_log_ana_groups() - - * @fd: File descriptor of nvme device - * @rae: Retain asynchronous events - * - * See &struct nvme_ana_group_desc for the defintion of the returned structure. - */ -int nvme_get_log_ana_groups(int fd, bool rae, __u32 len, - struct nvme_ana_group_desc *log); - -/** - * nvme_get_log_lba_status() - - * @fd: File descriptor of nvme device - * @rae: Retain asynchronous events - */ -int nvme_get_log_lba_status(int fd, bool rae, __u64 offset, __u32 len, - void *log); - -/** - * nvme_get_log_endurance_grp_evt() - - * @fd: File descriptor of nvme device - * @rae: Retain asynchronous events - */ -int nvme_get_log_endurance_grp_evt(int fd, bool rae, __u32 offset, __u32 len, - void *log); - -/** - * nvme_get_log_discovery() - - * @fd: File descriptor of nvme device - * @rae: Retain asynchronous events - * @offset: Offset of this log to retrieve - * @len: The allocated size for this portion of the log - * @log: User address to store the discovery log - * - * Supported only by fabrics discovery controllers, returning discovery - * records. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_log_discovery(int fd, bool rae, __u32 offset, __u32 len, void *log); - -/** - * nvme_get_log_reservation() - - * @fd: File descriptor of nvme device - * @rae: Retain asynchronous events - */ -int nvme_get_log_reservation(int fd, bool rae, - struct nvme_resv_notification_log *log); - -/** - * nvme_get_log_sanitize() - - * @fd: File descriptor of nvme device - * @rae: Retain asynchronous events - * @log: User address to store the sanitize log - * - * The Sanitize Status log page is used to report sanitize operation time - * estimates and information about the most recent sanitize operation. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_log_sanitize(int fd, bool rae, - struct nvme_sanitize_log_page *log); - -/** - * nvme_set_feature() - Set a feature attribute - * @fd: File descriptor of nvme device - * @fid: Feature identifier - * @nsid: Namespace ID, if applicable - * @cdw11: Value to set the feature to - * @cdw12: Feature specific command dword12 field - * @save: Save value across power states - * @uuidx: UUID Index for differentiating vendor specific encoding - * @cdw14: Feature specific command dword15 field - * @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 or -1 with errno - * set otherwise. - */ -int nvme_set_features(int fd, __u8 fid, __u32 nsid, __u32 cdw11, __u32 cdw12, - bool save, __u8 uuidx, __u32 cdw15, __u32 data_len, - void *data, __u32 *result); - -/** - * nvme_set_features_arbitration() - - * @fd: File descriptor of nvme device - * @save: Save value across power states - * @result: The command completion result from CQE dword0 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_set_features_arbitration(int fd, __u8 ab, __u8 lpw, __u8 mpw, - __u8 hpw, bool save, __u32 *result); - -/** - * nvme_set_features_power_mgmt() - - * @fd: File descriptor of nvme device - * @save: Save value across power states - * @result: The command completion result from CQE dword0 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_set_features_power_mgmt(int fd, __u8 ps, __u8 wh, bool save, - __u32 *result); - -/** - * nvme_set_features_lba_range() - - * @fd: File descriptor of nvme device - * @save: Save value across power states - * @result: The command completion result from CQE dword0 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_set_features_lba_range(int fd, __u32 nsid, __u32 nr_ranges, bool save, - struct nvme_lba_range_type *data, __u32 *result); - - -/** - * enum nvme_feat_tmpthresh_thsel - - */ -enum nvme_feat_tmpthresh_thsel { - NVME_FEATURE_TEMPTHRESH_THSEL_OVER = 0, - NVME_FEATURETEMPTHRESH__THSEL_UNDER = 1, -}; - -/** - * nvme_set_features_temp_thresh() - - * @fd: File descriptor of nvme device - * @save: Save value across power states - * @result: The command completion result from CQE dword0 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_set_features_temp_thresh(int fd, __u16 tmpth, __u8 tmpsel, - enum nvme_feat_tmpthresh_thsel thsel, - bool save, __u32 *result); - -/** - * nvme_set_features_err_recovery() - - * @fd: File descriptor of nvme device - * @save: Save value across power states - * @result: The command completion result from CQE dword0 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_set_features_err_recovery(int fd, __u32 nsid, __u16 tler, - bool dulbe, bool save, __u32 *result); - - -/** - * nvme_set_features_volatile_wc() - - * @fd: File descriptor of nvme device - * @save: Save value across power states - * @result: The command completion result from CQE dword0 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_set_features_volatile_wc(int fd, bool wce, bool save, - __u32 *result); - -/** - * nvme_set_features_irq_coalesce() - - * @fd: File descriptor of nvme device - * @save: Save value across power states - * @result: The command completion result from CQE dword0 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_set_features_irq_coalesce(int fd, __u8 thr, __u8 time, - bool save, __u32 *result); - -/** - * nvme_set_features_irq_config() - - * @fd: File descriptor of nvme device - * @save: Save value across power states - * @result: The command completion result from CQE dword0 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_set_features_irq_config(int fd, __u16 iv, bool cd, bool save, - __u32 *result); - - -/** - * nvme_set_features_write_atomic() - - * @fd: File descriptor of nvme device - * @save: Save value across power states - * @result: The command completion result from CQE dword0 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_set_features_write_atomic(int fd, bool dn, bool save, - __u32 *result); - -/** - * enum nvme_features_async_event_config_flags - - */ -enum nvme_features_async_event_config_flags { - NVME_FEATURE_AENCFG_SMART_CRIT_SPARE = 1 << 0, - NVME_FEATURE_AENCFG_SMART_CRIT_TEMPERATURE = 1 << 1, - NVME_FEATURE_AENCFG_SMART_CRIT_DEGRADED = 1 << 2, - NVME_FEATURE_AENCFG_SMART_CRIT_READ_ONLY = 1 << 3, - NVME_FEATURE_AENCFG_SMART_CRIT_VOLATILE_BACKUP = 1 << 4, - NVME_FEATURE_AENCFG_SMART_CRIT_READ_ONLY_PMR = 1 << 5, - NVME_FEATURE_AENCFG_NOTICE_NAMESPACE_ATTRIBUTES = 1 << 8, - NVME_FEATURE_AENCFG_NOTICE_FIRMWARE_ACTIVATION = 1 << 9, - NVME_FEATURE_AENCFG_NOTICE_TELEMETRY_LOG = 1 << 10, - NVME_FEATURE_AENCFG_NOTICE_ANA_CHANGE = 1 << 11, - NVME_FEATURE_AENCFG_NOTICE_PL_EVENT = 1 << 12, - NVME_FEATURE_AENCFG_NOTICE_LBA_STATUS = 1 << 13, - NVME_FEATURE_AENCFG_NOTICE_EG_EVENT = 1 << 14, - NVME_FEATURE_AENCFG_NOTICE_DISCOVERY_CHANGE = 1 << 31, -}; - -/** - * nvme_set_features_async_event() - - * @fd: File descriptor of nvme device - * @save: Save value across power states - * @result: The command completion result from CQE dword0 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_set_features_async_event(int fd, __u32 events, bool save, - __u32 *result); - - -/** - * nvme_set_features_auto_pst() - - * @fd: File descriptor of nvme device - * @save: Save value across power states - * @result: The command completion result from CQE dword0 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_set_features_auto_pst(int fd, bool apste, bool save, - struct nvme_feat_auto_pst *apst, - __u32 *result); - -/** - * nvme_set_features_timestamp() - - * @fd: File descriptor of nvme device - * @save: Save value across power states - * @timestamp: The current timestamp value to assign to this this feature - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_set_features_timestamp(int fd, bool save, __u64 timestamp); - - -/** - * nvme_set_features_hctm() - - * @fd: File descriptor of nvme device - * @save: Save value across power states - * @result: The command completion result from CQE dword0 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_set_features_hctm(int fd, __u16 tmt2, __u16 tmt1, bool save, - __u32 *result); - -/** - * nvme_set_features_nopsc() - - */ -int nvme_set_features_nopsc(int fd, bool noppme, bool save, __u32 *result); - -/** - * nvme_set_features_rrl() - - * @fd: File descriptor of nvme device - * @save: Save value across power states - * @result: The command completion result from CQE dword0 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_set_features_rrl(int fd, __u8 rrl, __u16 nvmsetid, bool save, - __u32 *result); - -/** - * nvme_set_features_plm_config() - - * @fd: File descriptor of nvme device - * @save: Save value across power states - * @result: The command completion result from CQE dword0 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_set_features_plm_config(int fd, bool enable, __u16 nvmsetid, - bool save, struct nvme_plm_config *data, - __u32*result); - -/** - * enum nvme_feat_plm_window_select - - */ -enum nvme_feat_plm_window_select { - NVME_FEATURE_PLM_DTWIN = 1, - NVME_FEATURE_PLM_NDWIN = 2, -}; - -/** - * nvme_set_features_plm_window() - - * @fd: File descriptor of nvme device - * @save: Save value across power states - * @result: The command completion result from CQE dword0 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -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() - - * @fd: File descriptor of nvme device - * @save: Save value across power states - * @result: The command completion result from CQE dword0 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_set_features_lba_sts_interval(int fd, __u16 lsiri, __u16 lsipi, - bool save, __u32 *result); - - -/** - * nvme_set_features_host_behavior() - - * @fd: File descriptor of nvme device - * @save: Save value across power states - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_set_features_host_behavior(int fd, bool save, - struct nvme_feat_host_behavior *data); - -/** - * nvme_set_features_sanitize() - - * @fd: File descriptor of nvme device - * @save: Save value across power states - * @result: The command completion result from CQE dword0 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_set_features_sanitize(int fd, bool nodrm, bool save, __u32 *result); - -/** - * nvme_set_features_endurance_evt_cfg() - - * @fd: File descriptor of nvme device - * @endgid: - * @egwarn: Flags to enable warning, see &enum nvme_eg_critical_warning_flags - * @save: Save value across power states - * @result: The command completion result from CQE dword0 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_set_features_endurance_evt_cfg(int fd, __u16 endgid, __u8 egwarn, - bool save, __u32 *result); - -/** - * nvme_set_features_sw_progress() - - * @fd: File descriptor of nvme device - * @save: Save value across power states - * @result: The command completion result from CQE dword0 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_set_features_sw_progress(int fd, __u8 pbslc, bool save, - __u32 *result); - - -/** - * nvme_set_features_host_id() - - * @fd: File descriptor of nvme device - * @save: Save value across power states - * @result: The command completion result from CQE dword0 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_set_features_host_id(int fd, bool exhid, bool save, __u8 *hostid); - -/** - * - */ -enum nvme_feat_resv_notify_flags { - NVME_FEAT_RESV_NOTIFY_REGPRE = 1 << 1, - NVME_FEAT_RESV_NOTIFY_RESREL = 1 << 2, - NVME_FEAT_RESV_NOTIFY_RESPRE = 1 << 3, -}; - -/** - * nvme_set_features_resv_mask() - - * @fd: File descriptor of nvme device - * @save: Save value across power states - * @result: The command completion result from CQE dword0 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_set_features_resv_mask(int fd, __u32 mask, bool save, __u32 *result); - -/** - * nvme_set_features_resv_persist() - - * @fd: File descriptor of nvme device - * @save: Save value across power states - * @result: The command completion result from CQE dword0 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_set_features_resv_persist(int fd, bool ptpl, bool save, __u32 *result); - -/** - * enum nvme_feat_ns_wp_cfg_state - - * @NVME_FEAT_NS_NO_WRITE_PROTECT: - * @NVME_FEAT_NS_WRITE_PROTECT: - * @NVME_FEAT_NS_WRITE_PROTECT_PWR_CYCLE: - * @NVME_FEAT_NS_WRITE_PROTECT_PERMANENT: - */ -enum nvme_feat_nswpcfg_state { - 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, -}; - -/** - * nvme_set_features_write_protect() - - * @fd: File descriptor of nvme device - * @save: Save value across power states - * @result: The command completion result from CQE dword0 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_set_features_write_protect(int fd, enum nvme_feat_nswpcfg_state state, - bool save, __u32 *result); - -/** - * nvme_get_features() - Retrieve a feature attribute - * @fd: File descriptor of nvme device - * @fid: Feature identifier - * @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 - * @uuidx: UUID Index for differentiating vendor specific encoding - * @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 or -1 with errno - * set otherwise. - */ -int nvme_get_features(int fd, enum nvme_features_id fid, __u32 nsid, - enum nvme_get_features_sel sel, __u32 cdw11, __u8 uuidx, - __u32 data_len, void *data, __u32 *result); - -/** - * nvme_get_features_arbitration() - - * @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 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_features_arbitration(int fd, enum nvme_get_features_sel sel, - __u32 *result); - -/** - * nvme_get_features_power_mgmt() - - * @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 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_features_power_mgmt(int fd, enum nvme_get_features_sel sel, - __u32 *result); - -/** - * nvme_get_features_lba_range() - - * @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 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_features_lba_range(int fd, enum nvme_get_features_sel sel, - struct nvme_lba_range_type *data, - __u32 *result); - -/** - * nvme_get_features_temp_thresh() - - * @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 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_features_temp_thresh(int fd, enum nvme_get_features_sel sel, - __u32 *result); - -/** - * nvme_get_features_err_recovery() - - * @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 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_features_err_recovery(int fd, enum nvme_get_features_sel sel, - __u32 *result); - -/** - * nvme_get_features_volatile_wc() - - * @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 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_features_volatile_wc(int fd, enum nvme_get_features_sel sel, - __u32 *result); - -/** - * nvme_get_features_num_queues() - - * @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 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_features_num_queues(int fd, enum nvme_get_features_sel sel, - __u32 *result); - -/** - * nvme_get_features_irq_coalesce() - - * @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 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_features_irq_coalesce(int fd, enum nvme_get_features_sel sel, - __u32 *result); - -/** - * nvme_get_features_irq_config() - - * @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 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_features_irq_config(int fd, enum nvme_get_features_sel sel, - __u16 iv, __u32 *result); - -/** - * nvme_get_features_write_atomic() - - * @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 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_features_write_atomic(int fd, enum nvme_get_features_sel sel, - __u32 *result); - -/** - * nvme_get_features_async_event() - - * @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 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_features_async_event(int fd, enum nvme_get_features_sel sel, - __u32 *result); - -/** - * nvme_get_features_auto_pst() - - * @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 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -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() - - * @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 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_features_host_mem_buf(int fd, enum nvme_get_features_sel sel, - __u32 *result); - -/** - * nvme_get_features_timestamp() - - * @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 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_features_timestamp(int fd, enum nvme_get_features_sel sel, - struct nvme_timestamp *ts); - -/** - * nvme_get_features_kato() - - * @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 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_features_kato(int fd, enum nvme_get_features_sel sel, __u32 *result); - -/** - * nvme_get_features_hctm() - - * @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 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_features_hctm(int fd, enum nvme_get_features_sel sel, __u32 *result); - -/** - * nvme_get_features_nopsc() - - * @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 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_features_nopsc(int fd, enum nvme_get_features_sel sel, __u32 *result); - -/** - * nvme_get_features_rrl() - - * @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 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_features_rrl(int fd, enum nvme_get_features_sel sel, __u32 *result); - -/** - * nvme_get_features_plm_config() - - * @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 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_features_plm_config(int fd, enum nvme_get_features_sel sel, - __u16 nvmsetid, struct nvme_plm_config *data, - __u32 *result); - -/** - * nvme_get_features_plm_window() - - * @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 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_features_plm_window(int fd, enum nvme_get_features_sel sel, - __u16 nvmsetid, __u32 *result); - -/** - * nvme_get_features_lba_sts_interval() - - * @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 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_features_lba_sts_interval(int fd, enum nvme_get_features_sel sel, - __u32 *result); - -/** - * nvme_get_features_host_behavior() - - * @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 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_features_host_behavior(int fd, enum nvme_get_features_sel sel, - struct nvme_feat_host_behavior *data, - __u32 *result); - -/** - * nvme_get_features_sanitize() - - * @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 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_features_sanitize(int fd, enum nvme_get_features_sel sel, - __u32 *result); - -/** - * nvme_get_features_endurance_event_cfg() - - * @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 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_features_endurance_event_cfg(int fd, enum nvme_get_features_sel sel, - __u16 endgid, __u32 *result); - -/** - * nvme_get_features_sw_progress() - - * @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 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_features_sw_progress(int fd, enum nvme_get_features_sel sel, - __u32 *result); - -/** - * nvme_get_features_host_id() - - * @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 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -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() - - * @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 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_features_resv_mask(int fd, enum nvme_get_features_sel sel, - __u32 *result); - -/** - * nvme_get_features_resv_persist() - - * @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 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_features_resv_persist(int fd, enum nvme_get_features_sel sel, - __u32 *result); - -/** - * nvme_get_features_write_protect() - - * @fd: File descriptor of nvme device - * @nsid: Namespace ID - * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel - * @result: The command completion result from CQE dword0 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_features_write_protect(int fd, __u32 nsid, - enum nvme_get_features_sel sel, - __u32 *result); - - -/** - * nvme_format_nvm() - Format nvme namespace(s) - * @fd: File descriptor of nvme device - * @nsid: Namespace ID to format - * @lbaf: Logical block address 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 - * @timeout: Set to override default timeout to this value in milliseconds; - * useful for long running formats. 0 will use system default. - * - * The Format NVM command is used to low level format the NVM media. This - * command is used by the host to change the LBA data size and/or metadata - * size. A low level format may destroy all data and metadata associated with - * all namespaces or only the specific namespace associated with the command - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_format_nvm(int fd, __u32 nsid, __u8 lbaf, - enum nvme_cmd_format_mset mset, - enum nvme_cmd_format_pi pi, - enum nvme_cmd_format_pil pil, - enum nvme_cmd_format_ses ses, - __u32 timeout); - -/** - * nvme_ns_mgmt() - - * @fd: File descriptor of nvme device - */ -int nvme_ns_mgmt(int fd, __u32 nsid, enum nvme_ns_mgmt_sel sel, - struct nvme_id_ns *ns, __u32 *result, __u32 timeout); - -/** - * nvme_ns_mgmt_create() - - * @fd: File descriptor of nvme device - * @ns: Namespace identifiaction that defines 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. - * - * On successful creation, the namespace exists in the subsystem, but is not - * attached to any controller. Use the nvme_ns_attach_ctrls() to assign the - * namespace to one or more controllers. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_ns_mgmt_create(int fd, struct nvme_id_ns *ns, __u32 *nsid, - __u32 timeout); - -/** - * nvme_ns_mgmt_delete() - - * @fd: File descriptor of nvme device - * @nsid: Namespace identifier to delete - * - * It is recommended that a namespace being deleted is not attached to any - * controller. Use the nvme_ns_detach_ctrls() first if the namespace is still - * attached. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_ns_mgmt_delete(int fd, __u32 nsid); - -/** - * nvme_ns_attach() - Attach or detach namespace to controller(s) - * @fd: File descriptor of nvme device - * @nsid: Namespace ID to execute attach selection - * @sel: Attachment selection, see &enum nvme_ns_attach_sel - * @ctrlist: Controller list to modify attachment state of nsid - */ -int nvme_ns_attach(int fd, __u32 nsid, enum nvme_ns_attach_sel sel, - struct nvme_ctrl_list *ctrlist); - -/** - * nvme_ns_attach_ctrls() - - * @fd: File descriptor of nvme device - * @nsid: Namespace ID to attach - * @ctrlist: Controller list to modify attachment state of nsid - */ -int nvme_ns_attach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist); - -/** - * nvme_ns_dettach_ctrls() - - * @fd: File descriptor of nvme device - * @nsid: Namespace ID to dettach - * @ctrlist: Controller list to modify attachment state of nsid - */ -int nvme_ns_dettach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist); - -/** - * nvme_fw_download() - Download part or all of a firmware image to the - * controller - * @fd: File descriptor of nvme device - * @offset: Offset in the firmware data - * @data_len: Length of data in this command in bytes - * @data: Userspace address of the firmware data - * - * The Firmware Image Download command is used to download all or a portion of - * an image for a future update to the controller. The Firmware Image Download - * command downloads a new image (in whole or in part) to the controller. - * - * The image may be constructed of multiple pieces that are individually - * downloaded with separate Firmware Image Download commands. Each Firmware - * Image Download command includes a Dword Offset and Number of Dwords that - * specify a dword range. - * - * The new firmware image is not activated as part of the Firmware Image - * Download command. Use the nvme_fw_commit() to activate a newly downloaded - * image. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_fw_download(int fd, __u32 offset, __u32 data_len, void *data); - -/** - * nvme_fw_commit() - Commit firmware using the specified action - * @fd: File descriptor of nvme device - * @slot: Firmware slot to commit the downloaded image - * @action: Action to use for the firmware image, see &enum nvme_fw_commit_ca - * @bpid: Set to true to select the boot partition id - * - * The Firmware Commit command is used to modify the firmware image or Boot - * Partitions. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. The command status response may specify additional - * reset actions required to complete the commit process. - */ -int nvme_fw_commit(int fd, __u8 slot, enum nvme_fw_commit_ca action, bool bpid); - -/** - * nvme_security_receive() - - * @fd: File descriptor of nvme device - * @nsid: Namespace ID to issue security command on - * @nssf: NVMe Security Specific field - * @spsp0: Security Protocol Specific field - * @spsp1: Security Protocol Specific field - * @secp: Security Protocol - * @tl: Protocol specific transfer length - * @data_len: Data length of the payload in bytes - * @data: Security data payload to send - * @result: The command completion result from CQE dword0 - * - * The Security Send command is used to transfer security protocol data to the - * controller. The data structure transferred to the controller as part of this - * command contains security protocol specific commands to be performed by the - * controller. The data structure transferred may also contain data or - * parameters associated with the security protocol commands. - * - * The security data is protocol specific and is not defined by the NVMe - * specification. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_security_send(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, - __u8 secp, __u32 tl, __u32 data_len, void *data, - __u32 *result); - -/** - * nvme_security_receive() - - * @fd: File descriptor of nvme device - * @nsid: Namespace ID to issue security command on - * @nssf: NVMe Security Specific field - * @spsp0: Security Protocol Specific field - * @spsp1: Security Protocol Specific field - * @secp: Security Protocol - * @al: Protocol specific allocation length - * @data_len: Data length of the payload in bytes - * @data: Security data payload to send - * @result: The command completion result from CQE dword0 - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_security_receive(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, - __u8 spsp1, __u8 secp, __u32 al, __u32 data_len, - void *data, __u32 *result); - -/** - * nvme_get_lba_status() - Retrieve information on possibly unrecoverable LBAs - * @fd: File descriptor of nvme device - * @nsid: Namespace ID to retrieve LBA status - * @slba: Starting logical block address to check statuses - * @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 - * @lbas: Data payload to return status descriptors - * - * The Get LBA Status command requests information about Potentially - * Unrecoverable LBAs. Refer to the specification for action type descriptions. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_lba_status(int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl, - enum nvme_lba_status_atype atype, - struct nvme_lba_status *lbas); - -/** - * nvme_directive_send() - Send directive command - * @fd: File descriptor of nvme device - * @nsid: Namespace ID, if applicable - * @dspec: Directive specific field - * @doper: Directive send operation, see &enum nvme_directive_send_doper - * @dtype: Directive type, see &enum nvme_directive_dtype - * @dw12: Directive specific command dword12 - * @data_len: Length of data payload in bytes - * @data: Usespace address of data payload - * @result: If successful, the CQE dword0 value - * - * Directives is a mechanism to enable host and NVM subsystem or controller - * information exchange. The Directive Send command is used to transfer data - * related to a specific Directive Type from the host to the controller. - * - * See the NVMe specification for more information. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_directive_send(int fd, __u32 nsid, __u16 dspec, - enum nvme_directive_send_doper doper, - enum nvme_directive_dtype dtype, __u32 cdw12, - __u32 data_len, void *data, __u32 *result); - -/** - * nvme_directive_send_id_endir() - - * @fd: File descriptor of nvme device - * @nsid: Namespace ID - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_directive_send_id_endir(int fd, __u32 nsid, bool endir, - enum nvme_directive_dtype dtype, - struct nvme_id_directives *id); - -/** - * nvme_directive_send_stream_release_identifier() - - * @fd: File descriptor of nvme device - * @nsid: Namespace ID - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_directive_send_stream_release_identifier(int fd, __u32 nsid, - __u16 stream_id); - -/** - * nvme_directive_send_stream_release_resource() - - * @fd: File descriptor of nvme device - * @nsid: Namespace ID - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_directive_send_stream_release_resource(int fd, __u32 nsid); - -/** - * nvme_directive_recv() - Receive directive specific data - * @fd: File descriptor of nvme device - * @nsid: Namespace ID, if applicable - * @dspec: Directive specific field - * @doper: Directive receive operation, see &enum nvme_directive_receive_doper - * @dtype: Directive type, see &enum nvme_directive_dtype - * @dw12: Directive specific command dword12 - * @data_len: Length of data payload - * @data: Usespace address of data payload in bytes - * @result: If successful, the CQE dword0 value - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_directive_recv(int fd, __u32 nsid, __u16 dspec, - enum nvme_directive_receive_doper doper, - enum nvme_directive_dtype dtype, __u32 cdw12, - __u32 data_len, void *data, __u32 *result); - -/** - * nvme_directive_recv_identify_parameters() - - * @fd: File descriptor of nvme device - * @nsid: Namespace ID - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_directive_recv_identify_parameters(int fd, __u32 nsid, - struct nvme_id_directives *id); - -/** - * nvme_directive_recv_stream_parameters() - - * @fd: File descriptor of nvme device - * @nsid: Namespace ID - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_directive_recv_stream_parameters(int fd, __u32 nsid, - struct nvme_streams_directive_params *parms); - -/** - * nvme_directive_recv_stream_status() - - * @fd: File descriptor of nvme device - * @nsid: Namespace ID - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_directive_recv_stream_status(int fd, __u32 nsid, unsigned nr_entries, - struct nvme_streams_directive_status *id); - -/** - * nvme_directive_recv_stream_allocate() - - * @fd: File descriptor of nvme device - * @nsid: Namespace ID - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_directive_recv_stream_allocate(int fd, __u32 nsid, __u16 nsr, - __u32 *result); - -/** - * enum nvme_fctype - - * @nvme_fabrics_type_property_set: - * @nvme_fabrics_type_connect: - * @nvme_fabrics_type_property_get: - * @nvme_fabrics_type_auth_send: - * @nvme_fabrics_type_auth_receive: - * @nvme_fabrics_type_disconnect: - */ -enum nvme_fctype { - nvme_fabrics_type_property_set = 0x00, - nvme_fabrics_type_connect = 0x01, - nvme_fabrics_type_property_get = 0x04, - nvme_fabrics_type_auth_send = 0x05, - nvme_fabrics_type_auth_receive = 0x06, - nvme_fabrics_type_disconnect = 0x08, -}; - -/** - * nvme_set_property() - Set controller property - * @fd: File descriptor of nvme device - * @offset: Property offset from the base to set - * @value: The value to set the property - * - * This is an NVMe-over-Fabrics specific command, not applicable to PCIe. These - * properties align to the PCI MMIO controller registers. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_set_property(int fd, int offset, __u64 value); - -/** - * nvme_get_property() - Get a controller property - * @fd: File descriptor of nvme device - * @offset: Property offset from the base to retrieve - * @value: Where the property's value will be stored on success - * - * This is an NVMe-over-Fabrics specific command, not applicable to PCIe. These - * properties align to the PCI MMIO controller registers. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_get_property(int fd, int offset, __u64 *value); - -/** - * nvme_sanitize() - Start a sanitize operation - * @fd: File descriptor of nvme device - * @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 - * @ovrpat: Overwrite pattern - * - * A sanitize operation alters all user data in the NVM subsystem such that - * recovery of any previous user data from any cache, the non-volatile media, - * or any Controller Memory Buffer is not possible. - * - * The Sanitize command is used to start a sanitize operation or to recover - * from a previously failed sanitize operation. The sanitize operation types - * that may be supported are Block Erase, Crypto Erase, and Overwrite. All - * sanitize operations are processed in the background, i.e., completion of the - * sanitize command does not indicate completion of the sanitize operation. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_sanitize_nvm(int fd, enum nvme_sanitize_sanact sanact, bool ause, - __u8 owpass, bool oipbp, bool nodas, __u32 ovrpat); - -/** - * nvme_dev_self_test() - Start or abort a self test - * @fd: File descriptor of nvme device - * @nsid: Namespace ID to test - * @stc: Self test code, see &enum nvme_dst_stc - * - * The Device Self-test command is used to start a device self-test operation - * or abort a device self-test operation. A device self-test operation is a - * diagnostic testing sequence that tests the integrity and functionality of - * the controller and may include testing of the media associated with - * namespaces. The controller may return a response to this command immediately - * while running the self-test in the background. - * - * Set the 'nsid' field to 0 to not include namepsaces in the test. Set to - * 0xffffffff to test all namespaces. All other values tests a specific - * namespace, if present. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_dev_self_test(int fd, __u32 nsid, enum nvme_dst_stc stc); - -/** - * nvme_virtual_mgmt() - Virtualization resource management - * @fd: File descriptor of nvme device - * @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 - * @result: If successful, the CQE dword0 - * - * The Virtualization Management command is supported by primary controllers - * that support the Virtualization Enhancements capability. This command is - * used for several functions: - * - * - Modifying Flexible Resource allocation for the primary controller - * - Assigning Flexible Resources for secondary controllers - * - Setting the Online and Offline state for secondary controllers - * - * Return: The nvme command status if a response was received or -1 - * with errno set otherwise. - */ -int nvme_virtual_mgmt(int fd, enum nvme_virt_mgmt_act act, - enum nvme_virt_mgmt_rt rt, __u16 cntlid, __u16 nr, - __u32 *result); - -/** - * DOC: NVMe IO command - */ - -/** - * enum nvme_io_opcode - - * @nvme_cmd_flush: - * @nvme_cmd_write: - * @nvme_cmd_read: - * @nvme_cmd_write_uncor: - * @nvme_cmd_compare: - * @nvme_cmd_write_zeroes: - * @nvme_cmd_dsm: - * @nvme_cmd_verify: - * @nvme_cmd_resv_register: - * @nvme_cmd_resv_report: - * @nvme_cmd_resv_acquire: - * @nvme_cmd_resv_release: - */ -enum nvme_io_opcode { - nvme_cmd_flush = 0x00, - nvme_cmd_write = 0x01, - nvme_cmd_read = 0x02, - nvme_cmd_write_uncor = 0x04, - nvme_cmd_compare = 0x05, - nvme_cmd_write_zeroes = 0x08, - nvme_cmd_dsm = 0x09, - nvme_cmd_verify = 0x0c, - nvme_cmd_resv_register = 0x0d, - nvme_cmd_resv_report = 0x0e, - nvme_cmd_resv_acquire = 0x11, - nvme_cmd_resv_release = 0x15, -}; - -/** - * nvme_flush() - Send an nvme flush command - * @fd: File descriptor of nvme device - * @nsid: Namespace identifier - * - * The Flush command is used to request that the contents of volatile write - * cache be made non-volatile. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_flush(int fd, __u32 nsid); - -/** - * enum nvme_io_control_flags - - * @NVME_IO_DTYPE_STREAMS: - * @NVME_IO_DEAC: - * @NVME_IO_PRINFO_PRCHK_REF: - * @NVME_IO_PRINFO_PRCHK_APP: - * @NVME_IO_PRINFO_PRCHK_GUARD: - * @NVME_IO_PRINFO_PRACT: - * @NVME_IO_FUA: - * @NVME_IO_LR: - */ -enum nvme_io_control_flags { - NVME_IO_DTYPE_STREAMS = 1 << 4, - NVME_IO_DEAC = 1 << 9, - NVME_IO_PRINFO_PRCHK_REF = 1 << 10, - NVME_IO_PRINFO_PRCHK_APP = 1 << 11, - NVME_IO_PRINFO_PRCHK_GUARD = 1 << 12, - NVME_IO_PRINFO_PRACT = 1 << 13, - NVME_IO_FUA = 1 << 14, - NVME_IO_LR = 1 << 15, -}; - -/** - * enum nvme_io_dsm_flag - - * @NVME_IO_DSM_FREQ_UNSPEC: - * @NVME_IO_DSM_FREQ_TYPICAL: - * @NVME_IO_DSM_FREQ_RARE: - * @NVME_IO_DSM_FREQ_READS: - * @NVME_IO_DSM_FREQ_WRITES: - * @NVME_IO_DSM_FREQ_RW: - * @NVME_IO_DSM_FREQ_ONCE: - * @NVME_IO_DSM_FREQ_PREFETCH: - * @NVME_IO_DSM_FREQ_TEMP: - * @NVME_IO_DSM_LATENCY_NONE: - * @NVME_IO_DSM_LATENCY_IDLE: - * @NVME_IO_DSM_LATENCY_NORM: - * @NVME_IO_DSM_LATENCY_LOW: - * @NVME_IO_DSM_SEQ_REQ: - * @NVME_IO_DSM_COMPRESSED: - */ -enum nvme_io_dsm_flags { - NVME_IO_DSM_FREQ_UNSPEC = 0, - NVME_IO_DSM_FREQ_TYPICAL = 1, - NVME_IO_DSM_FREQ_RARE = 2, - NVME_IO_DSM_FREQ_READS = 3, - NVME_IO_DSM_FREQ_WRITES = 4, - NVME_IO_DSM_FREQ_RW = 5, - NVME_IO_DSM_FREQ_ONCE = 6, - NVME_IO_DSM_FREQ_PREFETCH = 7, - NVME_IO_DSM_FREQ_TEMP = 8, - NVME_IO_DSM_LATENCY_NONE = 0 << 4, - NVME_IO_DSM_LATENCY_IDLE = 1 << 4, - NVME_IO_DSM_LATENCY_NORM = 2 << 4, - NVME_IO_DSM_LATENCY_LOW = 3 << 4, - NVME_IO_DSM_SEQ_REQ = 1 << 6, - NVME_IO_DSM_COMPRESSED = 1 << 7, -}; - -/** - * nvme_read() - Submit an nvme user read command - * @fd: File descriptor of nvme device - * @nsid: Namespace ID - * @slba: Starting logical block - * @nblocks: Number of logical blocks to send (0's based value) - * @control: Command control flags, see &enum nvme_io_control_flags. - * @dsm: Data set management attributes, see &enum nvme_io_dsm_flags - * @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. - * @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. - * @data_len: Length of user buffer, @data, in bytes - * @data: Pointer to user address of the data buffer - * metadata_len:Length of user buffer, @metadata, in bytes - * @metadata: Pointer to user address of the metadata buffer - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_read(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, - __u8 dsm, __u32 reftag, __u16 apptag, __u16 appmask, - __u32 data_len, void *data, __u32 metadata_len, void *metadata); - -/** - * nvme_write() - Submit an nvme user write command - * @fd: File descriptor of nvme device - * @nsid: Namespace ID - * @slba: Starting logical block - * @nblocks: Number of logical blocks to send (0's based value) - * @control: Command control flags, see &enum nvme_io_control_flags. - * @dsm: Data set management attributes, see &enum nvme_io_dsm_flags - * @dspec: Directive specific command, eg: stream identifier - * @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. - * @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. - * @data_len: Length of user buffer, @data, in bytes - * @data: Pointer to user address of the data buffer - * metadata_len:Length of user buffer, @metadata, in bytes - * @metadata: Pointer to user address of the metadata buffer - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_write(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, - __u8 dsm, __u16 dspec, __u32 reftag, __u16 apptag, - __u16 appmask, __u32 data_len, void *data, __u32 metadata_len, - void *metadata); - -/** - * nvme_compare() - Submit an nvme user compare command - * @fd: File descriptor of nvme device - * @nsid: Namespace ID - * @slba: Starting logical block - * @nblocks: Number of logical blocks to send (0's based value) - * @control: Command control flags, see &enum nvme_io_control_flags. - * @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. - * @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. - * @data_len: Length of user buffer, @data, in bytes - * @data: Pointer to user address of the data buffer - * metadata_len:Length of user buffer, @metadata, in bytes - * @metadata: Pointer to user address of the metadata buffer - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_compare(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, - __u32 reftag, __u16 apptag, __u16 appmask, __u32 data_len, - void *data, __u32 metadata_len, void *metadata); - -/** - * nvme_write_zeros() - Submit an nvme write zeroes command - * @fd: File descriptor of nvme device - * @nsid: Namespace identifier - * @slba: Starting logical block - * @nlb: Number of logical blocks to clear (0's based value) - * @control: Command control flags, see &enum nvme_io_control_flags. - * @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. - * @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. - * - * The Write Zeroes command is used to set a range of logical blocks to zero. - * After successful completion of this command, the value returned by - * subsequent reads of logical blocks in this range shall be all bytes cleared - * to 0h until a write occurs to this LBA range. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_write_zeros(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, - __u32 reftag, __u16 apptag, __u16 appmask); - -/** - * nvme_write_uncorrectable() - Submit an nvme write uncorrectable command - * @fd: File descriptor of nvme device - * @nsid: Namespace identifier - * @slba: Starting logical block - * @nlb: Number of logical blocks to invalidate (0's based value) - * - * The Write Uncorrectable command is used to mark a range of logical blocks as - * invalid. When the specified logical block(s) are read after this operation, - * a failure is returned with Unrecovered Read Error status. To clear the - * invalid logical block status, a write operation on those logical blocks is - * required. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_write_uncorrectable(int fd, __u32 nsid, __u64 slba, __u16 nlb); - -/** - * nvme_verify() - Send an nvme verify command - * @fd: File descriptor of nvme device - * @nsid: Namespace identifier - * @slba: Starting logical block - * @nlb: Number of logical blocks to verify (0's based value) - * @control: Command control flags, see &enum nvme_io_control_flags. - * @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. - * @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. - * - * The Verify command verifies integrity of stored information by reading data - * and metadata, if applicable, for the LBAs indicated without transferring any - * data or metadata to the host. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_verify(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, - __u32 reftag, __u16 apptag, __u16 appmask); - -/** - * enum nvme_dsm_attributes - - * @NVME_DSMGMT_IDR: - * @NVME_DSMGMT_IDW: - * @NVME_DSMGMT_AD: - */ -enum nvme_dsm_attributes { - NVME_DSMGMT_IDR = 1 << 0, - NVME_DSMGMT_IDW = 1 << 1, - NVME_DSMGMT_AD = 1 << 2, -}; - -/** - * nvme_dsm() - Send an nvme data set management command - * @fd: File descriptor of nvme device - * @nsid: Namespace identifier - * @attrs: DSM attributes, see &enum nvme_dsm_attributes - * &nr_ranges: Number of block ranges in the data set management attributes - * @dsm: The data set management attributes - * - * The Dataset Management command is used by the host to indicate attributes - * for ranges of logical blocks. This includes attributes like frequency that - * data is read or written, access size, and other information that may be used - * to optimize performance and reliability, and may be used to - * deallocate/unmap/trim those logical blocks. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_dsm(int fd, __u32 nsid, __u32 attrs, __u16 nr_ranges, - struct nvme_dsm_range *dsm); - -/** - * enum nvme_reservation_rtype - - * @NVME_RESERVATION_RTYPE_WE: - * @NVME_RESERVATION_RTYPE_EA: - * @NVME_RESERVATION_RTYPE_WERO: - * @NVME_RESERVATION_RTYPE_EARO: - * @NVME_RESERVATION_RTYPE_WEAR: - * @NVME_RESERVATION_RTYPE_EAAR: - */ -enum nvme_reservation_rtype { - NVME_RESERVATION_RTYPE_WE = 1, - NVME_RESERVATION_RTYPE_EA = 2, - NVME_RESERVATION_RTYPE_WERO = 3, - NVME_RESERVATION_RTYPE_EARO = 4, - NVME_RESERVATION_RTYPE_WEAR = 5, - NVME_RESERVATION_RTYPE_EAAR = 6, -}; - -/** - * enum nvme_reservation_racqa - - * @NVME_RESERVATION_RACQA_ACQUIRE: - * @NVME_RESERVATION_RACQA_PREEMPT: - * @NVME_RESERVATION_RACQA_PREEMPT_AND_ABORT: - */ -enum nvme_reservation_racqa { - NVME_RESERVATION_RACQA_ACQUIRE = 0, - NVME_RESERVATION_RACQA_PREEMPT = 1, - NVME_RESERVATION_RACQA_PREEMPT_AND_ABORT = 2, -}; - -/** - * nvme_resv_acquire() - Send an nvme reservation acquire - * @fd: File descriptor of nvme device - * @nsid: Namespace identifier - * @rtype: The type of reservation to be create, see &enum nvme_reservation_rtype - * @racqa: The action that is performed by the command, see &enum nvme_reservation_racqa - * @iekey: Set to ignore the existing key - * @crkey: The current reservation key associated with the host - * @nrkey: The reservation key to be unregistered from the namespace if - * the action is preempt - * - * The Reservation Acquire command is used to acquire a reservation on a - * namespace, preempt a reservation held on a namespace, and abort a - * reservation held on a namespace. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_resv_acquire(int fd, __u32 nsid, enum nvme_reservation_rtype rtype, - enum nvme_reservation_racqa racqa, bool iekey, - __u64 crkey, __u64 nrkey); - -/** - * enum nvme_reservation_rrega - - * @NVME_RESERVATION_RREGA_REGISTER_KEY: - * @NVME_RESERVATION_RREGA_UNREGISTER_KEY: - * @NVME_RESERVATION_RREGA_REPLACE_KEY: - */ -enum nvme_reservation_rrega { - NVME_RESERVATION_RREGA_REGISTER_KEY = 0, - NVME_RESERVATION_RREGA_UNREGISTER_KEY = 1, - NVME_RESERVATION_RREGA_REPLACE_KEY = 2, -}; - -/** - * enum nvme_reservation_cptpl - - * @NVME_RESERVATION_CPTPL_NO_CHANGE: - * @NVME_RESERVATION_CPTPL_CLEAR: - * @NVME_RESERVATION_CPTPL_PERSIST: - */ -enum nvme_reservation_cptpl { - NVME_RESERVATION_CPTPL_NO_CHANGE = 0, - NVME_RESERVATION_CPTPL_CLEAR = 2, - NVME_RESERVATION_CPTPL_PERSIST = 3, -}; - -/** - * nvme_resv_register() - Send an nvme reservation register - * @fd: File descriptor of nvme device - * @nsid: Namespace identifier - * @rrega: The registration action, see &enum nvme_reservation_rrega - * @cptpl: Change persist through power loss, see &enum nvme_reservation_cptpl - * @iekey: Set to ignore the existing key - * @crkey: The current reservation key associated with the host - * @nrkey: The new reservation key to be register if action is register or - * replace - * - * The Reservation Register command is used to register, unregister, or replace - * a reservation key. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_resv_register(int fd, __u32 nsid, enum nvme_reservation_rrega rrega, - enum nvme_reservation_cptpl cptpl, bool iekey, - __u64 crkey, __u64 nrkey); - -/** - * enum nvme_reservation_rrela - - * @NVME_RESERVATION_RRELA_RELEASE: - * @NVME_RESERVATION_RRELA_CLEAR: - */ -enum nvme_reservation_rrela { - NVME_RESERVATION_RRELA_RELEASE = 0, - NVME_RESERVATION_RRELA_CLEAR = 1 -}; - -/** - * nvme_resv_release() - Send an nvme reservation release - * @fd: File descriptor of nvme device - * @nsid: Namespace identifier - * @rtype: The type of reservation to be create, see &enum nvme_reservation_rtype - * @rrela: Reservation releast action, see &enum nvme_reservation_rrela - * @iekey: Set to ignore the existing key - * @crkey: The current reservation key to release - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_resv_release(int fd, __u32 nsid, enum nvme_reservation_rtype rtype, - enum nvme_reservation_rrela rrela, bool iekey, - __u64 crkey); - -/** - * nvme_resv_report() - Send an nvme reservation report - * @fd: File descriptor of nvme device - * @nsid: Namespace identifier - * @eds: Request extended Data Structure - * @len: Number of bytes to request transfered with this command - * @report: The user space destination address to store the reservation report - * - * Returns a Reservation Status data structure to memory that describes the - * registration and reservation status of a namespace. See the defintion for - * the returned structure, &struct nvme_reservation_status, for more details. - * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. - */ -int nvme_resv_report(int fd, __u32 nsid, bool eds, __u32 len, - struct nvme_reservation_status *report); - -#endif /* _LIBNVME_CMD_H */ diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 0b39fb35f4..795a060adf 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -18,8 +18,7 @@ #include #include "fabrics.h" -#include "types.h" -#include "cmd.h" +#include "ioctl.h" #include "util.h" #define NVMF_HOSTID_SIZE 36 diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 364465bad2..6105f443cf 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -12,8 +12,6 @@ #include #include "ioctl.h" -#include "cmd.h" -#include "types.h" static int nvme_verify_chr(int fd) { diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index a713dc8976..167162164e 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -353,4 +353,2563 @@ int nvme_ns_rescan(int fd); */ int nvme_get_nsid(int fd); +/** + * DOC: NVMe Admin command enums + */ + +/** + * enum nvme_admin_opcode - Known NVMe admin opcodes + * @nvme_admin_delete_sq: + * @nvme_admin_create_sq: + * @nvme_admin_get_log_page: + * @nvme_admin_delete_cq: + * @nvme_admin_create_cq: + * @nvme_admin_identify: + * @nvme_admin_abort_cmd: + * @nvme_admin_set_features: + * @nvme_admin_get_features: + * @nvme_admin_async_event: + * @nvme_admin_ns_mgmt: + * @nvme_admin_fw_commit: + * @nvme_admin_fw_download: + * @nvme_admin_dev_self_test: + * @nvme_admin_ns_attach: + * @nvme_admin_keep_alive: + * @nvme_admin_directive_send: + * @nvme_admin_directive_recv: + * @nvme_admin_virtual_mgmt: + * @nvme_admin_nvme_mi_send: + * @nvme_admin_nvme_mi_recv: + * @nvme_admin_dbbuf: + * @nvme_admin_fabrics: + * @nvme_admin_format_nvm: + * @nvme_admin_security_send: + * @nvme_admin_security_recv: + * @nvme_admin_sanitize_nvm: + * @nvme_admin_get_lba_status: + */ +enum nvme_admin_opcode { + nvme_admin_delete_sq = 0x00, + nvme_admin_create_sq = 0x01, + nvme_admin_get_log_page = 0x02, + nvme_admin_delete_cq = 0x04, + nvme_admin_create_cq = 0x05, + nvme_admin_identify = 0x06, + nvme_admin_abort_cmd = 0x08, + nvme_admin_set_features = 0x09, + nvme_admin_get_features = 0x0a, + nvme_admin_async_event = 0x0c, + nvme_admin_ns_mgmt = 0x0d, + nvme_admin_fw_commit = 0x10, + nvme_admin_fw_download = 0x11, + nvme_admin_dev_self_test = 0x14, + nvme_admin_ns_attach = 0x15, + nvme_admin_keep_alive = 0x18, + nvme_admin_directive_send = 0x19, + nvme_admin_directive_recv = 0x1a, + nvme_admin_virtual_mgmt = 0x1c, + nvme_admin_nvme_mi_send = 0x1d, + nvme_admin_nvme_mi_recv = 0x1e, + nvme_admin_dbbuf = 0x7c, + nvme_admin_fabrics = 0x7f, + nvme_admin_format_nvm = 0x80, + nvme_admin_security_send = 0x81, + nvme_admin_security_recv = 0x82, + nvme_admin_sanitize_nvm = 0x84, + nvme_admin_get_lba_status = 0x86, +}; + +/** + * enum nvme_identify_cns - + * @NVME_IDENTIFY_CNS_NS: + * @NVME_IDENTIFY_CNS_CTRL: + * @NVME_IDENTIFY_CNS_NS_ACTIVE_LIST: + * @NVME_IDENTIFY_CNS_NS_DESC_LIST: + * @NVME_IDENTIFY_CNS_NVMSET_LIST: + * @NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST: + * @NVME_IDENTIFY_CNS_ALLOCATED_NS: + * @NVME_IDENTIFY_CNS_NS_CTRL_LIST: + * @NVME_IDENTIFY_CNS_CTRL_LIST: + * @NVME_IDENTIFY_CNS_PRIMARY_CTRL_CAP: + * @NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST: + * @NVME_IDENTIFY_CNS_NS_GRANULARITY: + * @NVME_IDENTIFY_CNS_UUID_LIST: + */ +enum nvme_identify_cns { + NVME_IDENTIFY_CNS_NS = 0x00, + NVME_IDENTIFY_CNS_CTRL = 0x01, + NVME_IDENTIFY_CNS_NS_ACTIVE_LIST = 0x02, + NVME_IDENTIFY_CNS_NS_DESC_LIST = 0x03, + NVME_IDENTIFY_CNS_NVMSET_LIST = 0x04, + NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST = 0x10, + NVME_IDENTIFY_CNS_ALLOCATED_NS = 0x11, + NVME_IDENTIFY_CNS_NS_CTRL_LIST = 0x12, + NVME_IDENTIFY_CNS_CTRL_LIST = 0x13, + NVME_IDENTIFY_CNS_PRIMARY_CTRL_CAP = 0x14, + NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST = 0x15, + NVME_IDENTIFY_CNS_NS_GRANULARITY = 0x16, + NVME_IDENTIFY_CNS_UUID_LIST = 0x17, +}; + +/** + * enum nvme_cmd_get_log_lid - + * @NVME_LOG_LID_ERROR: + * @NVME_LOG_LID_SMART: + * @NVME_LOG_LID_FW_SLOT: + * @NVME_LOG_LID_CHANGED_NS: + * @NVME_LOG_LID_CMD_EFFECTS: + * @NVME_LOG_LID_DEVICE_SELF_TEST: + * @NVME_LOG_LID_TELEMETRY_HOST: + * @NVME_LOG_LID_TELEMETRY_CTRL: + * @NVME_LOG_LID_ENDURANCE_GROUP: + * @NVME_LOG_LID_PREDICTABLE_LAT_NVMSET: + * @NVME_LOG_LID_PREDICTABLE_LAT_AGG: + * @NVME_LOG_LID_ANA: + * @NVME_LOG_LID_PERSISTENT_EVENT: + * @NVME_LOG_LID_LBA_STATUS: + * @NVME_LOG_LID_ENDURANCE_GRP_EVT: + * @NVME_LOG_LID_DISCOVER: + * @NVME_LOG_LID_RESERVATION: + * @NVME_LOG_LID_SANITIZE: + */ +enum nvme_cmd_get_log_lid { + NVME_LOG_LID_ERROR = 0x01, + NVME_LOG_LID_SMART = 0x02, + NVME_LOG_LID_FW_SLOT = 0x03, + NVME_LOG_LID_CHANGED_NS = 0x04, + NVME_LOG_LID_CMD_EFFECTS = 0x05, + NVME_LOG_LID_DEVICE_SELF_TEST = 0x06, + NVME_LOG_LID_TELEMETRY_HOST = 0x07, + NVME_LOG_LID_TELEMETRY_CTRL = 0x08, + NVME_LOG_LID_ENDURANCE_GROUP = 0x09, + NVME_LOG_LID_PREDICTABLE_LAT_NVMSET = 0x0a, + NVME_LOG_LID_PREDICTABLE_LAT_AGG = 0x0b, + NVME_LOG_LID_ANA = 0x0c, + NVME_LOG_LID_PERSISTENT_EVENT = 0x0d, + NVME_LOG_LID_LBA_STATUS = 0x0e, + NVME_LOG_LID_ENDURANCE_GRP_EVT = 0x0f, + NVME_LOG_LID_DISCOVER = 0x70, + NVME_LOG_LID_RESERVATION = 0x80, + NVME_LOG_LID_SANITIZE = 0x81, +}; + +/** + * enum nvme_features_id - + * @NVME_FEAT_FID_ARBITRATION: + * @NVME_FEAT_FID_POWER_MGMT: + * @NVME_FEAT_FID_LBA_RANGE: + * @NVME_FEAT_FID_TEMP_THRESH: + * @NVME_FEAT_FID_ERR_RECOVERY: + * @NVME_FEAT_FID_VOLATILE_WC: + * @NVME_FEAT_FID_NUM_QUEUES: + * @NVME_FEAT_FID_IRQ_COALESCE: + * @NVME_FEAT_FID_IRQ_CONFIG: + * @NVME_FEAT_FID_WRITE_ATOMIC: + * @NVME_FEAT_FID_ASYNC_EVENT: + * @NVME_FEAT_FID_AUTO_PST: + * @NVME_FEAT_FID_HOST_MEM_BUF: + * @NVME_FEAT_FID_TIMESTAMP: + * @NVME_FEAT_FID_KATO: + * @NVME_FEAT_FID_HCTM: + * @NVME_FEAT_FID_NOPSC: + * @NVME_FEAT_FID_RRL: + * @NVME_FEAT_FID_PLM_CONFIG: + * @NVME_FEAT_FID_PLM_WINDOW: + * @NVME_FEAT_FID_LBA_STS_INTERVAL: + * @NVME_FEAT_FID_HOST_BEHAVIOR: + * @NVME_FEAT_FID_SANITIZE: + * @NVME_FEAT_FID_ENDURANCE_EVT_CFG: + * @NVME_FEAT_FID_SW_PROGRESS: + * @NVME_FEAT_FID_HOST_ID: + * @NVME_FEAT_FID_RESV_MASK: + * @NVME_FEAT_RESV_PERSIST: + * @NVME_FEAT_FID_WRITE_PROTECT: + */ +enum nvme_features_id { + NVME_FEAT_FID_ARBITRATION = 0x01, + NVME_FEAT_FID_POWER_MGMT = 0x02, + NVME_FEAT_FID_LBA_RANGE = 0x03, + NVME_FEAT_FID_TEMP_THRESH = 0x04, + NVME_FEAT_FID_ERR_RECOVERY = 0x05, + NVME_FEAT_FID_VOLATILE_WC = 0x06, + NVME_FEAT_FID_NUM_QUEUES = 0x07, + NVME_FEAT_FID_IRQ_COALESCE = 0x08, + NVME_FEAT_FID_IRQ_CONFIG = 0x09, + NVME_FEAT_FID_WRITE_ATOMIC = 0x0a, + NVME_FEAT_FID_ASYNC_EVENT = 0x0b, + NVME_FEAT_FID_AUTO_PST = 0x0c, + NVME_FEAT_FID_HOST_MEM_BUF = 0x0d, + NVME_FEAT_FID_TIMESTAMP = 0x0e, + NVME_FEAT_FID_KATO = 0x0f, + NVME_FEAT_FID_HCTM = 0X10, + NVME_FEAT_FID_NOPSC = 0X11, + NVME_FEAT_FID_RRL = 0x12, + NVME_FEAT_FID_PLM_CONFIG = 0x13, + NVME_FEAT_FID_PLM_WINDOW = 0x14, + NVME_FEAT_FID_LBA_STS_INTERVAL = 0x15, + NVME_FEAT_FID_HOST_BEHAVIOR = 0x16, + NVME_FEAT_FID_SANITIZE = 0x17, + NVME_FEAT_FID_ENDURANCE_EVT_CFG = 0x18, + NVME_FEAT_FID_SW_PROGRESS = 0x80, + NVME_FEAT_FID_HOST_ID = 0x81, + NVME_FEAT_FID_RESV_MASK = 0x82, + NVME_FEAT_RESV_PERSIST = 0x83, + NVME_FEAT_FID_WRITE_PROTECT = 0x84, +}; + +/** + * enum nvme_get_features_sel - + * @NVME_GET_FEATURES_SEL_CURRENT: + * @NVME_GET_FEATURES_SEL_DEFAULT: + * @NVME_GET_FEATURES_SEL_SAVED: + */ +enum nvme_get_features_sel { + NVME_GET_FEATURES_SEL_CURRENT = 0, + NVME_GET_FEATURES_SEL_DEFAULT = 1, + NVME_GET_FEATURES_SEL_SAVED = 2, +}; + +/** + * enum nvme_cmd_format_mset - + * @NVME_FORMAT_MSET_SEPARATE: + * @NVME_FORMAT_MSET_EXTENEDED: + */ +enum nvme_cmd_format_mset { + NVME_FORMAT_MSET_SEPARATE = 0, + NVME_FORMAT_MSET_EXTENEDED = 1, +}; + +/** + * enum nvme_cmd_format_pi - + * @NVME_FORMAT_PI_DISABLE: + * @NVME_FORMAT_PI_TYPE1: + * @NVME_FORMAT_PI_TYPE2: + * @NVME_FORMAT_PI_TYPE3: + */ +enum nvme_cmd_format_pi { + NVME_FORMAT_PI_DISABLE = 0, + NVME_FORMAT_PI_TYPE1 = 1, + NVME_FORMAT_PI_TYPE2 = 2, + NVME_FORMAT_PI_TYPE3 = 3, +}; + +/** + * @enum nvme_cmd_format_pil - + * @NVME_FORMAT_PIL_LAST: + * @NVME_FORMAT_PIL_FIRST: + */ +enum nvme_cmd_format_pil { + NVME_FORMAT_PIL_LAST = 0, + NVME_FORMAT_PIL_FIRST = 1, +}; + +/** + * enum nvme_cmd_format_ses - + * @NVME_FORMAT_SES_NONE: + * @NVME_FORMAT_SES_USER_DATA_ERASE: + * @NVME_FORMAT_SES_CRYPTO_ERASE: + */ +enum nvme_cmd_format_ses { + NVME_FORMAT_SES_NONE = 0, + NVME_FORMAT_SES_USER_DATA_ERASE = 1, + NVME_FORMAT_SES_CRYPTO_ERASE = 2, +}; + +/** + * enum nvme_ns_mgmt_sel - + * @NVME_NAMESPACE_MGMT_SEL_CREATE: + * @NVME_NAMESPACE_MGMT_SEL_DELETE: + */ +enum nvme_ns_mgmt_sel { + NVME_NS_MGMT_SEL_CREATE = 0, + NVME_NS_MGMT_SEL_DELETE = 1, +}; + +/** + * enum nvme_ns_attach_sel - + * NVME_NS_ATTACH_SEL_CTRL_ATTACH: + * NVME_NP_ATTACH_SEL_CTRL_DEATTACH: + */ +enum nvme_ns_attach_sel { + NVME_NS_ATTACH_SEL_CTRL_ATTACH = 0, + NVME_NS_ATTACH_SEL_CTRL_DEATTACH = 1, +}; + +/** + * enum nvme_fw_commit_ca - + * @NVME_FW_COMMIT_CA_REPLACE: + * @NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE: + * @NVME_FW_COMMIT_CA_SET_ACTIVE: + * @NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE_IMMEDIATE: + * @NVME_FW_COMMIT_CA_REPLACE_BOOT_PARTITION: + * @NVME_FW_COMMIT_CA_ACTIVATE_BOOT_PARTITION: + */ +enum nvme_fw_commit_ca { + NVME_FW_COMMIT_CA_REPLACE = 0, + NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE = 1, + NVME_FW_COMMIT_CA_SET_ACTIVE = 2, + NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE_IMMEDIATE = 3, + NVME_FW_COMMIT_CA_REPLACE_BOOT_PARTITION = 6, + NVME_FW_COMMIT_CA_ACTIVATE_BOOT_PARTITION = 7, +}; + +/** + * enum nvme_directive_dtype - + * @NVME_DIRECTIVE_DTYPE_IDENTIFY: + * @NVME_DIRECTIVE_DTYPE_STREAMS: + */ +enum nvme_directive_dtype { + NVME_DIRECTIVE_DTYPE_IDENTIFY = 0, + NVME_DIRECTIVE_DTYPE_STREAMS = 1, +}; + +/** + * enum nvme_directive_receive_doper - + * @NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM: + * @NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM: + * @NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS: + * @NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE: + */ +enum nvme_directive_receive_doper { + NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM = 0x01, + NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM = 0x01, + NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS = 0x02, + NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE = 0x03, +}; + +/** + * enum nvme_directive_send_doper - + * @NVME_DIRECTIVE_SEND_IDENTIFY_DOPER_ENDIR: + * @NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_IDENTIFIER: + * @NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE: + */ +enum nvme_directive_send_doper { + NVME_DIRECTIVE_SEND_IDENTIFY_DOPER_ENDIR = 0x01, + NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_IDENTIFIER = 0x01, + NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE = 0x02, +}; + +/** + * enum - + */ +enum nvme_directive_send_identify_endir { + NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_DISABLE = 0, + NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_ENABLE = 1, +}; + +/** + * enum nvme_sanitize_sanact - + * @NVME_SANITIZE_SANACT_EXIT_FAILURE: + * @NVME_SANITIZE_SANACT_START_BLOCK_ERASE: + * @NVME_SANITIZE_SANACT_START_OVERWRITE: + * @NVME_SANITIZE_SANACT_START_CRYPTO_ERASE: + */ +enum nvme_sanitize_sanact { + NVME_SANITIZE_SANACT_EXIT_FAILURE = 1, + NVME_SANITIZE_SANACT_START_BLOCK_ERASE = 2, + NVME_SANITIZE_SANACT_START_OVERWRITE = 3, + NVME_SANITIZE_SANACT_START_CRYPTO_ERASE = 4, +}; + +/** + * enum nvme_dst_stc - + * @NVME_DST_STC_SHORT: + * @NVME_DST_STC_LONG: + * @NVME_DST_STC_VS: + * @NVME_DST_STC_ABORT: + */ +enum nvme_dst_stc { + NVME_DST_STC_SHORT = 0x1, + NVME_DST_STC_LONG = 0x2, + NVME_DST_STC_VS = 0xe, + NVME_DST_STC_ABORT = 0xf, +}; + +/** + * enum nvme_virt_mgmt_act - + * @NVME_VIRT_MGMT_ACT_PRIM_CTRL_FLEX_ALLOC: + * @NVME_VIRT_MGMT_ACT_OFFLINE_SEC_CTRL: + * @NVME_VIRT_MGMT_ACT_ASSIGN_SEC_CTRL: + * @NVME_VIRT_MGMT_ACT_ONLINE_SEC_CTRL: + */ +enum nvme_virt_mgmt_act { + NVME_VIRT_MGMT_ACT_PRIM_CTRL_FLEX_ALLOC = 1, + NVME_VIRT_MGMT_ACT_OFFLINE_SEC_CTRL = 7, + NVME_VIRT_MGMT_ACT_ASSIGN_SEC_CTRL = 8, + NVME_VIRT_MGMT_ACT_ONLINE_SEC_CTRL = 9, +}; + +/** + * enum nvme_virt_mgmt_rt - + * @NVME_VIRT_MGMT_RT_VQ_RESOURCE: + * @NVME_VIRT_MGMT_RT_VI_RESOURCE: + */ +enum nvme_virt_mgmt_rt { + NVME_VIRT_MGMT_RT_VQ_RESOURCE = 0, + NVME_VIRT_MGMT_RT_VI_RESOURCE = 1, +}; + +/** + * nvme_identify() - Send the NVMe Identify command + * @fd: File descriptor of nvme device + * @cns: The Controller or Namespace structure, see @enum nvme_identify_cns + * @nsid: Namespace identifier, if applicable + * @cntid: The Controller Identifier, if applicable + * @nvmsetid: The NVMe Set ID if CNS is 04h + * @uuidx: UUID Index if controller supports this id selection method + * @data: User space destination address to transfer the data + * + * The Identify command returns a data buffer that describes information about + * the NVM subsystem, the controller or the namespace(s). + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_identify(int fd, enum nvme_identify_cns cns, __u32 nsid, + __u16 cntid, __u16 nvmsetid, __u8 uuidx, void *data); + +/** + * nvme_identify_ctrl() - Retrieves nvme identify controller + * @fd: File descriptor of nvme device + * id: User space destination address to transfer the data, + * + * Sends nvme identify with CNS value %NVME_IDENTIFY_CNS_CTRL. + * + * See &struct nvme_id_ctrl for details on the data returned. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_identify_ctrl(int fd, struct nvme_id_ctrl *id); + +/** + * nvme_identify_ns() - Retrieves nvme identify namespace + * @fd: File descriptor of nvme device + * @nsid: Namespace to identify + * @ns: User space destination address to transfer the data + * + * If the Namespace Identifier (NSID) field specifies an active NSID, then the + * Identify Namespace data structure is returned to the host for that specified + * namespace. + * + * If the controller supports the Namespace Management capability and the NSID + * field is set to %NVME_NSID_ALL, then the controller returns an Identify Namespace + * data structure that specifies capabilities that are common across namespaces + * for this controller. + * + * See &struct nvme_id_ns for details on the structure returned. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +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 + * @fd: File descriptor of nvme device + * @nsid: Namespace to identify + * @ns: User space destination address to transfer the data + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_identify_allocated_ns(int fd, __u32 nsid, struct nvme_id_ns *ns); + +/** + * nvme_identify_active_ns_list() - Retrieves active namespaces id list + * @fd: File descriptor of nvme device + * @nsid: Return namespaces greater than this identifer + * @ns_list: User space destination address to transfer the data + * + * A list of 1024 namespace IDs is returned to the host containing NSIDs in + * increasing order that are greater than the value specified in the Namespace + * Identifier (nsid) field of the command. + * + * See &struct nvme_ns_list for the definition of the returned structure. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_identify_active_ns_list(int fd, __u32 nsid, struct nvme_ns_list *list); + +/** + * nvme_identify_allocated_ns_list() - Retrieves allocated namespace id list + * @fd: File descriptor of nvme device + * @nsid: Return namespaces greater than this identifer + * @ns_list: User space destination address to transfer the data + * + * A list of 1024 namespace IDs is returned to the host containing NSIDs in + * increasing order that are greater than the value specified in the Namespace + * Identifier (nsid) field of the command. + * + * See &struct nvme_ns_list for the definition of the returned structure. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_identify_allocated_ns_list(int fd, __u32 nsid, + struct nvme_ns_list *list); + +/** + * nvme_identify_ctrl_list() - Retrieves identify controller list + * @fd: File descriptor of nvme device + * @cntlid: Starting CNTLID to return in the list + * @cntlist: User space destination address to transfer the data + * + * Up to 2047 controller identifiers is returned containing a controller + * identifier greater than or equal to the controller identifier specified in + * @cntid. + * + * See &struct nvme_ctrl_list for a definition of the structure returned. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_identify_ctrl_list(int fd, __u16 cntid, + struct nvme_ctrl_list *ctrlist); + +/** + * nvme_identify_nsid_ctrl_list() - + * @fd: File descriptor of nvme device + * @nsid: Return controllers that are attached to this nsid + * @cntlid: Starting CNTLID to return in the list + * @cntlist: User space destination address to transfer the data + * + * Up to 2047 controller identifiers is returned containing a controller + * identifier greater than or equal to the controller identifier specified in + * @cntid. + * + * See &struct nvme_ctrl_list for a definition of the structure returned. + * + * Return: The nvme command status if a response was received or -1 + */ +int nvme_identify_nsid_ctrl_list(int fd, __u32 nsid, __u16 cntid, + struct nvme_ctrl_list *ctrlist); + +/** + * nvme_identify_ns_descs() - Retrieves namespace descriptor list + * @fd: File descriptor of nvme device + * @nsid: The namespace id to retrieve destriptors + * @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'. + * + * See &struct nvme_ns_id_desc for the definition of the returned structure. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_identify_ns_descs(int fd, __u32 nsid, struct nvme_ns_id_desc *descs); + +/** + * nvme_identify_nvmset_list() - Retrieves NVM Set List + * @fd: File descriptor of nvme device + * @nvmeset_id: NVM Set Identifier + * @nvmset: User space destination address to transfer the data + * + * Retrieves an NVM Set List, struct nvme_id_nvmset. The data structure is an + * ordered list by NVM Set Identifier, starting with the first NVM Set + * 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. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_identify_nvmset_list(int fd, __u16 nvmsetid, + struct nvme_id_nvmset_list *nvmset); + +/** + * nvme_identify_primary_ctrl() - Retrieve NVMe Primary Controller + * identification + * &fd: + * @cntid: + * @cap: + * + * See &struct nvme_primary_ctrl_cap for the defintion of the returned structure, @cap. + * + * Return: The nvme command status if a response was received or -1 + * with errno set otherwise. + */ +int nvme_identify_primary_ctrl(int fd, __u16 cntid, + struct nvme_primary_ctrl_cap *cap); + +/** + * nvme_identify_secondary_ctrl_list() - Retrieves secondary controller list + * @fd: File descriptor of nvme device + * @cntid: Return controllers starting at this identifier + * @sc_list: User space destination address to transfer the data + * + * A Secondary Controller List is returned to the host for up to 127 secondary + * controllers associated with the primary controller processing this command. + * 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 + * structure. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_identify_secondary_ctrl_list(int fd, __u16 cntid, + struct nvme_secondary_ctrl_list *list); + +/** + * nvme_identify_ns_granularity() - Retrieves namespace granularity + * identification + * @fd: File descriptor of nvme device + * @gr_list: User space destination address to transfer the data + * + * If the controller supports reporting of Namespace Granularity, then a + * Namespace Granularity List is returned to the host for up to sixteen + * namespace granularity descriptors + * + * See &struct nvme_id_ns_granularity_list for the definition of the returned + * structure. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_identify_ns_granularity(int fd, struct nvme_id_ns_granularity_list *list); + +/** + * nvme_identify_uuid() - Retrieves device's UUIDs + * @fd: File descriptor of nvme device + * @uuid_list: User space destination address to transfer the data + * + * Each UUID List entry is either 0h, the NVMe Invalid UUID, or a valid UUID. + * Valid UUIDs are those which are non-zero and are not the NVMe Invalid UUID. + * + * See &struct nvme_id_uuid_list for the definition of the returned structure. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_identify_uuid(int fd, struct nvme_id_uuid_list *list); + +/** + * nvme_get_log() - NVMe Admin Get Log command + * @fd: File descriptor of nvme device + * @lid: Log page identifier, see &enum nvme_cmd_get_log_lid for known values + * @nsid: Namespace identifier, if applicable + * @lpo: Log page offset for partial log transfers + * @lsp: Log specific field + * @lsi: Endurance group information + * @rae: Retain asynchronous events + * @uuidx: UUID selection, if supported + * @len: Length of provided user buffer to hold the log data in bytes + * @log: User space destination address to transfer the data + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, + __u8 lsp, __u16 lsi, bool rae, __u8 uuidx, __u32 len, void *log); + +/** + * nvme_get_log_error() - Retrieve nvme error log + * @fd: File descriptor of nvme device + * @entries: Number of error log entries allocated + * @rae: Retain asynchronous events + * @err_log: Array of error logs of size 'entries' + * + * This log page is used to describe extended error information for a command + * that completed with error, or may report an error that is not specific to a + * particular command. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_log_error(int fd, unsigned nr_entries, bool rae, + struct nvme_error_log_page *log); + +/** + * nvme_get_log_smart() - Retrieve nvme smart log + * @fd: File descriptor of nvme device + * @nsid: Optional namespace identifier + * @rae: Retain asynchronous events + * @smart_log: User address to store the smart log + * + * This log page is used to provide SMART and general health information. The + * information provided is over the life of the controller and is retained + * across power cycles. To request the controller log page, the namespace + * identifier specified is FFFFFFFFh. The controller may also support + * requesting the log page on a per namespace basis, as indicated by bit 0 of + * the LPA field in the Identify Controller data structure. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_log_smart(int fd, __u32 nsid, bool rae, struct nvme_smart_log *log); + +/** + * nvme_get_log_fw_slot() - Retrieves the controller firmware log + * @fd: File descriptor of nvme device + * @rae: Retain asynchronous events + * @fw_log: User address to store the log page + * + * This log page is used to describe the firmware revision stored in each + * firmware slot supported. The firmware revision is indicated as an ASCII + * string. The log page also indicates the active slot number. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_log_fw_slot(int fd, bool rae, struct nvme_firmware_slot *log); + +/** + * nvme_get_log_changed_ns_list() - Retrieve namespace changed list + * @fd: File descriptor of nvme device + * @rae: Retain asynchronous events + * @ns_list: User address to store the log page + * + * This log page is used to describe namespaces attached to this controller + * that have changed since the last time the namespace was identified, been + * added, or deleted. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_log_changed_ns_list(int fd, bool rae, struct nvme_ns_list *log); + +/** + * nvme_get_log_cmd_effects() - Retrieve nvme command effects log + * @fd: File descriptor of nvme device + * @effects_log:User address to store the effects log + * + * This log page is used to describe the commands that the controller supports + * and the effects of those commands on the state of the NVM subsystem. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_log_cmd_effects(int fd, struct nvme_cmd_effects_log *log); + +/** + * nvme_get_log_device_self_test() - Retrieve the device self test log + * @fd: File descriptor of nvme device + * @nsid: Namespace ID being tested + * @log: Userspace address of the log payload + * + * The log page is used to indicate the status of an in progress self test and + * the percent complete of that operation, and the results of the previous 20 + * self-test operations. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_log_device_self_test(int fd, struct nvme_self_test_log *log); + +/** + * nvme_get_log_create_telemetry_host() - + */ +int nvme_get_log_create_telemetry_host(int fd, struct nvme_telemetry_log *log); + +/** + * nvme_get_log_telemetry_host() - + * @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 + * using the previously existing capture. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_log_telemetry_host(int fd, __u64 offset, __u32 len, void *log); + +/** + * nvme_get_log_telemetry_ctrl() - + * @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 + */ +int nvme_get_log_telemetry_ctrl(int fd, bool rae, __u64 offset, __u32 len, + void *log); + +/** + * nvme_get_log_endurance_group() - + * @fd: File descriptor of nvme device + * @endgid: Starting group identifier to return in the list + * @log: User address to store the endurance log + * + * This log page indicates if an Endurance Group Event has occurred for a + * particular Endurance Group. If an Endurance Group Event has occurred, the + * details of the particular event are included in the Endurance Group + * Information log page for that Endurance Group. An asynchronous event is + * generated when an entry for an Endurance Group is newly added to this log + * page. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_log_endurance_group(int fd, __u16 endgid, + struct nvme_endurance_group_log *log); + +/** + * nvme_get_log_predictable_lat_nvmset() - + * @fd: + * @nvmsetid: + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_log_predictable_lat_nvmset(int fd, __u16 nvmsetid, + struct nvme_nvmset_predictable_lat_log *log); + +/** + * nvme_get_log_predictable_lat_event() - + * @fd: File descriptor of nvme device + * @rae: Retain asynchronous events + */ +int nvme_get_log_predictable_lat_event(int fd, bool rae, __u32 offset, + __u32 len, void *log); + +/** + * + */ +enum nvme_log_ana_lsp { + NVME_LOG_ANA_LSP_RGO_NAMESPACES = 0, + NVME_LOG_ANA_LSP_RGO_GROUPS_ONLY = 1, +}; + +/** + * nvme_get_log_ana() - + * @fd: File descriptor of nvme device + * @lsp: Log specific, see &enum nvme_get_log_ana_lsp + * @rae: Retain asynchronous events + * @len: The allocated length of the log page + * @log: User address to store the ana log + * + * This log consists of a header describing the log and descriptors containing + * the asymmetric namespace access information for ANA Groups that contain + * namespaces that are attached to the controller processing the command. + * + * See &struct nvme_ana_rsp_hdr for the defintion of the returned structure. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_log_ana(int fd, enum nvme_log_ana_lsp lsp, bool rae, __u64 offset, + __u32 len, void *log); + +/** + * nvme_get_log_ana_groups() - + * @fd: File descriptor of nvme device + * @rae: Retain asynchronous events + * + * See &struct nvme_ana_group_desc for the defintion of the returned structure. + */ +int nvme_get_log_ana_groups(int fd, bool rae, __u32 len, + struct nvme_ana_group_desc *log); + +/** + * nvme_get_log_lba_status() - + * @fd: File descriptor of nvme device + * @rae: Retain asynchronous events + */ +int nvme_get_log_lba_status(int fd, bool rae, __u64 offset, __u32 len, + void *log); + +/** + * nvme_get_log_endurance_grp_evt() - + * @fd: File descriptor of nvme device + * @rae: Retain asynchronous events + */ +int nvme_get_log_endurance_grp_evt(int fd, bool rae, __u32 offset, __u32 len, + void *log); + +/** + * nvme_get_log_discovery() - + * @fd: File descriptor of nvme device + * @rae: Retain asynchronous events + * @offset: Offset of this log to retrieve + * @len: The allocated size for this portion of the log + * @log: User address to store the discovery log + * + * Supported only by fabrics discovery controllers, returning discovery + * records. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_log_discovery(int fd, bool rae, __u32 offset, __u32 len, void *log); + +/** + * nvme_get_log_reservation() - + * @fd: File descriptor of nvme device + * @rae: Retain asynchronous events + */ +int nvme_get_log_reservation(int fd, bool rae, + struct nvme_resv_notification_log *log); + +/** + * nvme_get_log_sanitize() - + * @fd: File descriptor of nvme device + * @rae: Retain asynchronous events + * @log: User address to store the sanitize log + * + * The Sanitize Status log page is used to report sanitize operation time + * estimates and information about the most recent sanitize operation. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_log_sanitize(int fd, bool rae, + struct nvme_sanitize_log_page *log); + +/** + * nvme_set_feature() - Set a feature attribute + * @fd: File descriptor of nvme device + * @fid: Feature identifier + * @nsid: Namespace ID, if applicable + * @cdw11: Value to set the feature to + * @cdw12: Feature specific command dword12 field + * @save: Save value across power states + * @uuidx: UUID Index for differentiating vendor specific encoding + * @cdw14: Feature specific command dword15 field + * @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 or -1 with errno + * set otherwise. + */ +int nvme_set_features(int fd, __u8 fid, __u32 nsid, __u32 cdw11, __u32 cdw12, + bool save, __u8 uuidx, __u32 cdw15, __u32 data_len, + void *data, __u32 *result); + +/** + * nvme_set_features_arbitration() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_set_features_arbitration(int fd, __u8 ab, __u8 lpw, __u8 mpw, + __u8 hpw, bool save, __u32 *result); + +/** + * nvme_set_features_power_mgmt() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_set_features_power_mgmt(int fd, __u8 ps, __u8 wh, bool save, + __u32 *result); + +/** + * nvme_set_features_lba_range() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_set_features_lba_range(int fd, __u32 nsid, __u32 nr_ranges, bool save, + struct nvme_lba_range_type *data, __u32 *result); + + +/** + * enum nvme_feat_tmpthresh_thsel - + */ +enum nvme_feat_tmpthresh_thsel { + NVME_FEATURE_TEMPTHRESH_THSEL_OVER = 0, + NVME_FEATURETEMPTHRESH__THSEL_UNDER = 1, +}; + +/** + * nvme_set_features_temp_thresh() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_set_features_temp_thresh(int fd, __u16 tmpth, __u8 tmpsel, + enum nvme_feat_tmpthresh_thsel thsel, + bool save, __u32 *result); + +/** + * nvme_set_features_err_recovery() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_set_features_err_recovery(int fd, __u32 nsid, __u16 tler, + bool dulbe, bool save, __u32 *result); + + +/** + * nvme_set_features_volatile_wc() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_set_features_volatile_wc(int fd, bool wce, bool save, + __u32 *result); + +/** + * nvme_set_features_irq_coalesce() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_set_features_irq_coalesce(int fd, __u8 thr, __u8 time, + bool save, __u32 *result); + +/** + * nvme_set_features_irq_config() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_set_features_irq_config(int fd, __u16 iv, bool cd, bool save, + __u32 *result); + + +/** + * nvme_set_features_write_atomic() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_set_features_write_atomic(int fd, bool dn, bool save, + __u32 *result); + +/** + * enum nvme_features_async_event_config_flags - + */ +enum nvme_features_async_event_config_flags { + NVME_FEATURE_AENCFG_SMART_CRIT_SPARE = 1 << 0, + NVME_FEATURE_AENCFG_SMART_CRIT_TEMPERATURE = 1 << 1, + NVME_FEATURE_AENCFG_SMART_CRIT_DEGRADED = 1 << 2, + NVME_FEATURE_AENCFG_SMART_CRIT_READ_ONLY = 1 << 3, + NVME_FEATURE_AENCFG_SMART_CRIT_VOLATILE_BACKUP = 1 << 4, + NVME_FEATURE_AENCFG_SMART_CRIT_READ_ONLY_PMR = 1 << 5, + NVME_FEATURE_AENCFG_NOTICE_NAMESPACE_ATTRIBUTES = 1 << 8, + NVME_FEATURE_AENCFG_NOTICE_FIRMWARE_ACTIVATION = 1 << 9, + NVME_FEATURE_AENCFG_NOTICE_TELEMETRY_LOG = 1 << 10, + NVME_FEATURE_AENCFG_NOTICE_ANA_CHANGE = 1 << 11, + NVME_FEATURE_AENCFG_NOTICE_PL_EVENT = 1 << 12, + NVME_FEATURE_AENCFG_NOTICE_LBA_STATUS = 1 << 13, + NVME_FEATURE_AENCFG_NOTICE_EG_EVENT = 1 << 14, + NVME_FEATURE_AENCFG_NOTICE_DISCOVERY_CHANGE = 1 << 31, +}; + +/** + * nvme_set_features_async_event() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_set_features_async_event(int fd, __u32 events, bool save, + __u32 *result); + + +/** + * nvme_set_features_auto_pst() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_set_features_auto_pst(int fd, bool apste, bool save, + struct nvme_feat_auto_pst *apst, + __u32 *result); + +/** + * nvme_set_features_timestamp() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @timestamp: The current timestamp value to assign to this this feature + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_set_features_timestamp(int fd, bool save, __u64 timestamp); + + +/** + * nvme_set_features_hctm() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_set_features_hctm(int fd, __u16 tmt2, __u16 tmt1, bool save, + __u32 *result); + +/** + * nvme_set_features_nopsc() - + */ +int nvme_set_features_nopsc(int fd, bool noppme, bool save, __u32 *result); + +/** + * nvme_set_features_rrl() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_set_features_rrl(int fd, __u8 rrl, __u16 nvmsetid, bool save, + __u32 *result); + +/** + * nvme_set_features_plm_config() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_set_features_plm_config(int fd, bool enable, __u16 nvmsetid, + bool save, struct nvme_plm_config *data, + __u32*result); + +/** + * enum nvme_feat_plm_window_select - + */ +enum nvme_feat_plm_window_select { + NVME_FEATURE_PLM_DTWIN = 1, + NVME_FEATURE_PLM_NDWIN = 2, +}; + +/** + * nvme_set_features_plm_window() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +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() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_set_features_lba_sts_interval(int fd, __u16 lsiri, __u16 lsipi, + bool save, __u32 *result); + + +/** + * nvme_set_features_host_behavior() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_set_features_host_behavior(int fd, bool save, + struct nvme_feat_host_behavior *data); + +/** + * nvme_set_features_sanitize() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_set_features_sanitize(int fd, bool nodrm, bool save, __u32 *result); + +/** + * nvme_set_features_endurance_evt_cfg() - + * @fd: File descriptor of nvme device + * @endgid: + * @egwarn: Flags to enable warning, see &enum nvme_eg_critical_warning_flags + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_set_features_endurance_evt_cfg(int fd, __u16 endgid, __u8 egwarn, + bool save, __u32 *result); + +/** + * nvme_set_features_sw_progress() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_set_features_sw_progress(int fd, __u8 pbslc, bool save, + __u32 *result); + + +/** + * nvme_set_features_host_id() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_set_features_host_id(int fd, bool exhid, bool save, __u8 *hostid); + +/** + * + */ +enum nvme_feat_resv_notify_flags { + NVME_FEAT_RESV_NOTIFY_REGPRE = 1 << 1, + NVME_FEAT_RESV_NOTIFY_RESREL = 1 << 2, + NVME_FEAT_RESV_NOTIFY_RESPRE = 1 << 3, +}; + +/** + * nvme_set_features_resv_mask() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_set_features_resv_mask(int fd, __u32 mask, bool save, __u32 *result); + +/** + * nvme_set_features_resv_persist() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_set_features_resv_persist(int fd, bool ptpl, bool save, __u32 *result); + +/** + * enum nvme_feat_ns_wp_cfg_state - + * @NVME_FEAT_NS_NO_WRITE_PROTECT: + * @NVME_FEAT_NS_WRITE_PROTECT: + * @NVME_FEAT_NS_WRITE_PROTECT_PWR_CYCLE: + * @NVME_FEAT_NS_WRITE_PROTECT_PERMANENT: + */ +enum nvme_feat_nswpcfg_state { + 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, +}; + +/** + * nvme_set_features_write_protect() - + * @fd: File descriptor of nvme device + * @save: Save value across power states + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_set_features_write_protect(int fd, enum nvme_feat_nswpcfg_state state, + bool save, __u32 *result); + +/** + * nvme_get_features() - Retrieve a feature attribute + * @fd: File descriptor of nvme device + * @fid: Feature identifier + * @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 + * @uuidx: UUID Index for differentiating vendor specific encoding + * @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 or -1 with errno + * set otherwise. + */ +int nvme_get_features(int fd, enum nvme_features_id fid, __u32 nsid, + enum nvme_get_features_sel sel, __u32 cdw11, __u8 uuidx, + __u32 data_len, void *data, __u32 *result); + +/** + * nvme_get_features_arbitration() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_features_arbitration(int fd, enum nvme_get_features_sel sel, + __u32 *result); + +/** + * nvme_get_features_power_mgmt() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_features_power_mgmt(int fd, enum nvme_get_features_sel sel, + __u32 *result); + +/** + * nvme_get_features_lba_range() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_features_lba_range(int fd, enum nvme_get_features_sel sel, + struct nvme_lba_range_type *data, + __u32 *result); + +/** + * nvme_get_features_temp_thresh() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_features_temp_thresh(int fd, enum nvme_get_features_sel sel, + __u32 *result); + +/** + * nvme_get_features_err_recovery() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_features_err_recovery(int fd, enum nvme_get_features_sel sel, + __u32 *result); + +/** + * nvme_get_features_volatile_wc() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_features_volatile_wc(int fd, enum nvme_get_features_sel sel, + __u32 *result); + +/** + * nvme_get_features_num_queues() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_features_num_queues(int fd, enum nvme_get_features_sel sel, + __u32 *result); + +/** + * nvme_get_features_irq_coalesce() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_features_irq_coalesce(int fd, enum nvme_get_features_sel sel, + __u32 *result); + +/** + * nvme_get_features_irq_config() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_features_irq_config(int fd, enum nvme_get_features_sel sel, + __u16 iv, __u32 *result); + +/** + * nvme_get_features_write_atomic() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_features_write_atomic(int fd, enum nvme_get_features_sel sel, + __u32 *result); + +/** + * nvme_get_features_async_event() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_features_async_event(int fd, enum nvme_get_features_sel sel, + __u32 *result); + +/** + * nvme_get_features_auto_pst() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +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() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_features_host_mem_buf(int fd, enum nvme_get_features_sel sel, + __u32 *result); + +/** + * nvme_get_features_timestamp() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_features_timestamp(int fd, enum nvme_get_features_sel sel, + struct nvme_timestamp *ts); + +/** + * nvme_get_features_kato() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_features_kato(int fd, enum nvme_get_features_sel sel, __u32 *result); + +/** + * nvme_get_features_hctm() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_features_hctm(int fd, enum nvme_get_features_sel sel, __u32 *result); + +/** + * nvme_get_features_nopsc() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_features_nopsc(int fd, enum nvme_get_features_sel sel, __u32 *result); + +/** + * nvme_get_features_rrl() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_features_rrl(int fd, enum nvme_get_features_sel sel, __u32 *result); + +/** + * nvme_get_features_plm_config() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_features_plm_config(int fd, enum nvme_get_features_sel sel, + __u16 nvmsetid, struct nvme_plm_config *data, + __u32 *result); + +/** + * nvme_get_features_plm_window() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_features_plm_window(int fd, enum nvme_get_features_sel sel, + __u16 nvmsetid, __u32 *result); + +/** + * nvme_get_features_lba_sts_interval() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_features_lba_sts_interval(int fd, enum nvme_get_features_sel sel, + __u32 *result); + +/** + * nvme_get_features_host_behavior() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_features_host_behavior(int fd, enum nvme_get_features_sel sel, + struct nvme_feat_host_behavior *data, + __u32 *result); + +/** + * nvme_get_features_sanitize() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_features_sanitize(int fd, enum nvme_get_features_sel sel, + __u32 *result); + +/** + * nvme_get_features_endurance_event_cfg() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_features_endurance_event_cfg(int fd, enum nvme_get_features_sel sel, + __u16 endgid, __u32 *result); + +/** + * nvme_get_features_sw_progress() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_features_sw_progress(int fd, enum nvme_get_features_sel sel, + __u32 *result); + +/** + * nvme_get_features_host_id() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +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() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_features_resv_mask(int fd, enum nvme_get_features_sel sel, + __u32 *result); + +/** + * nvme_get_features_resv_persist() - + * @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 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_features_resv_persist(int fd, enum nvme_get_features_sel sel, + __u32 *result); + +/** + * nvme_get_features_write_protect() - + * @fd: File descriptor of nvme device + * @nsid: Namespace ID + * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_features_write_protect(int fd, __u32 nsid, + enum nvme_get_features_sel sel, + __u32 *result); + + +/** + * nvme_format_nvm() - Format nvme namespace(s) + * @fd: File descriptor of nvme device + * @nsid: Namespace ID to format + * @lbaf: Logical block address 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 + * @timeout: Set to override default timeout to this value in milliseconds; + * useful for long running formats. 0 will use system default. + * + * The Format NVM command is used to low level format the NVM media. This + * command is used by the host to change the LBA data size and/or metadata + * size. A low level format may destroy all data and metadata associated with + * all namespaces or only the specific namespace associated with the command + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_format_nvm(int fd, __u32 nsid, __u8 lbaf, + enum nvme_cmd_format_mset mset, + enum nvme_cmd_format_pi pi, + enum nvme_cmd_format_pil pil, + enum nvme_cmd_format_ses ses, + __u32 timeout); + +/** + * nvme_ns_mgmt() - + * @fd: File descriptor of nvme device + */ +int nvme_ns_mgmt(int fd, __u32 nsid, enum nvme_ns_mgmt_sel sel, + struct nvme_id_ns *ns, __u32 *result, __u32 timeout); + +/** + * nvme_ns_mgmt_create() - + * @fd: File descriptor of nvme device + * @ns: Namespace identifiaction that defines 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. + * + * On successful creation, the namespace exists in the subsystem, but is not + * attached to any controller. Use the nvme_ns_attach_ctrls() to assign the + * namespace to one or more controllers. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_ns_mgmt_create(int fd, struct nvme_id_ns *ns, __u32 *nsid, + __u32 timeout); + +/** + * nvme_ns_mgmt_delete() - + * @fd: File descriptor of nvme device + * @nsid: Namespace identifier to delete + * + * It is recommended that a namespace being deleted is not attached to any + * controller. Use the nvme_ns_detach_ctrls() first if the namespace is still + * attached. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_ns_mgmt_delete(int fd, __u32 nsid); + +/** + * nvme_ns_attach() - Attach or detach namespace to controller(s) + * @fd: File descriptor of nvme device + * @nsid: Namespace ID to execute attach selection + * @sel: Attachment selection, see &enum nvme_ns_attach_sel + * @ctrlist: Controller list to modify attachment state of nsid + */ +int nvme_ns_attach(int fd, __u32 nsid, enum nvme_ns_attach_sel sel, + struct nvme_ctrl_list *ctrlist); + +/** + * nvme_ns_attach_ctrls() - + * @fd: File descriptor of nvme device + * @nsid: Namespace ID to attach + * @ctrlist: Controller list to modify attachment state of nsid + */ +int nvme_ns_attach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist); + +/** + * nvme_ns_dettach_ctrls() - + * @fd: File descriptor of nvme device + * @nsid: Namespace ID to dettach + * @ctrlist: Controller list to modify attachment state of nsid + */ +int nvme_ns_dettach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist); + +/** + * nvme_fw_download() - Download part or all of a firmware image to the + * controller + * @fd: File descriptor of nvme device + * @offset: Offset in the firmware data + * @data_len: Length of data in this command in bytes + * @data: Userspace address of the firmware data + * + * The Firmware Image Download command is used to download all or a portion of + * an image for a future update to the controller. The Firmware Image Download + * command downloads a new image (in whole or in part) to the controller. + * + * The image may be constructed of multiple pieces that are individually + * downloaded with separate Firmware Image Download commands. Each Firmware + * Image Download command includes a Dword Offset and Number of Dwords that + * specify a dword range. + * + * The new firmware image is not activated as part of the Firmware Image + * Download command. Use the nvme_fw_commit() to activate a newly downloaded + * image. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_fw_download(int fd, __u32 offset, __u32 data_len, void *data); + +/** + * nvme_fw_commit() - Commit firmware using the specified action + * @fd: File descriptor of nvme device + * @slot: Firmware slot to commit the downloaded image + * @action: Action to use for the firmware image, see &enum nvme_fw_commit_ca + * @bpid: Set to true to select the boot partition id + * + * The Firmware Commit command is used to modify the firmware image or Boot + * Partitions. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. The command status response may specify additional + * reset actions required to complete the commit process. + */ +int nvme_fw_commit(int fd, __u8 slot, enum nvme_fw_commit_ca action, bool bpid); + +/** + * nvme_security_receive() - + * @fd: File descriptor of nvme device + * @nsid: Namespace ID to issue security command on + * @nssf: NVMe Security Specific field + * @spsp0: Security Protocol Specific field + * @spsp1: Security Protocol Specific field + * @secp: Security Protocol + * @tl: Protocol specific transfer length + * @data_len: Data length of the payload in bytes + * @data: Security data payload to send + * @result: The command completion result from CQE dword0 + * + * The Security Send command is used to transfer security protocol data to the + * controller. The data structure transferred to the controller as part of this + * command contains security protocol specific commands to be performed by the + * controller. The data structure transferred may also contain data or + * parameters associated with the security protocol commands. + * + * The security data is protocol specific and is not defined by the NVMe + * specification. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_security_send(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, + __u8 secp, __u32 tl, __u32 data_len, void *data, + __u32 *result); + +/** + * nvme_security_receive() - + * @fd: File descriptor of nvme device + * @nsid: Namespace ID to issue security command on + * @nssf: NVMe Security Specific field + * @spsp0: Security Protocol Specific field + * @spsp1: Security Protocol Specific field + * @secp: Security Protocol + * @al: Protocol specific allocation length + * @data_len: Data length of the payload in bytes + * @data: Security data payload to send + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_security_receive(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, + __u8 spsp1, __u8 secp, __u32 al, __u32 data_len, + void *data, __u32 *result); + +/** + * nvme_get_lba_status() - Retrieve information on possibly unrecoverable LBAs + * @fd: File descriptor of nvme device + * @nsid: Namespace ID to retrieve LBA status + * @slba: Starting logical block address to check statuses + * @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 + * @lbas: Data payload to return status descriptors + * + * The Get LBA Status command requests information about Potentially + * Unrecoverable LBAs. Refer to the specification for action type descriptions. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_lba_status(int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl, + enum nvme_lba_status_atype atype, + struct nvme_lba_status *lbas); + +/** + * nvme_directive_send() - Send directive command + * @fd: File descriptor of nvme device + * @nsid: Namespace ID, if applicable + * @dspec: Directive specific field + * @doper: Directive send operation, see &enum nvme_directive_send_doper + * @dtype: Directive type, see &enum nvme_directive_dtype + * @dw12: Directive specific command dword12 + * @data_len: Length of data payload in bytes + * @data: Usespace address of data payload + * @result: If successful, the CQE dword0 value + * + * Directives is a mechanism to enable host and NVM subsystem or controller + * information exchange. The Directive Send command is used to transfer data + * related to a specific Directive Type from the host to the controller. + * + * See the NVMe specification for more information. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_directive_send(int fd, __u32 nsid, __u16 dspec, + enum nvme_directive_send_doper doper, + enum nvme_directive_dtype dtype, __u32 cdw12, + __u32 data_len, void *data, __u32 *result); + +/** + * nvme_directive_send_id_endir() - + * @fd: File descriptor of nvme device + * @nsid: Namespace ID + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_directive_send_id_endir(int fd, __u32 nsid, bool endir, + enum nvme_directive_dtype dtype, + struct nvme_id_directives *id); + +/** + * nvme_directive_send_stream_release_identifier() - + * @fd: File descriptor of nvme device + * @nsid: Namespace ID + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_directive_send_stream_release_identifier(int fd, __u32 nsid, + __u16 stream_id); + +/** + * nvme_directive_send_stream_release_resource() - + * @fd: File descriptor of nvme device + * @nsid: Namespace ID + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_directive_send_stream_release_resource(int fd, __u32 nsid); + +/** + * nvme_directive_recv() - Receive directive specific data + * @fd: File descriptor of nvme device + * @nsid: Namespace ID, if applicable + * @dspec: Directive specific field + * @doper: Directive receive operation, see &enum nvme_directive_receive_doper + * @dtype: Directive type, see &enum nvme_directive_dtype + * @dw12: Directive specific command dword12 + * @data_len: Length of data payload + * @data: Usespace address of data payload in bytes + * @result: If successful, the CQE dword0 value + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_directive_recv(int fd, __u32 nsid, __u16 dspec, + enum nvme_directive_receive_doper doper, + enum nvme_directive_dtype dtype, __u32 cdw12, + __u32 data_len, void *data, __u32 *result); + +/** + * nvme_directive_recv_identify_parameters() - + * @fd: File descriptor of nvme device + * @nsid: Namespace ID + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_directive_recv_identify_parameters(int fd, __u32 nsid, + struct nvme_id_directives *id); + +/** + * nvme_directive_recv_stream_parameters() - + * @fd: File descriptor of nvme device + * @nsid: Namespace ID + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_directive_recv_stream_parameters(int fd, __u32 nsid, + struct nvme_streams_directive_params *parms); + +/** + * nvme_directive_recv_stream_status() - + * @fd: File descriptor of nvme device + * @nsid: Namespace ID + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_directive_recv_stream_status(int fd, __u32 nsid, unsigned nr_entries, + struct nvme_streams_directive_status *id); + +/** + * nvme_directive_recv_stream_allocate() - + * @fd: File descriptor of nvme device + * @nsid: Namespace ID + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_directive_recv_stream_allocate(int fd, __u32 nsid, __u16 nsr, + __u32 *result); + +/** + * enum nvme_fctype - + * @nvme_fabrics_type_property_set: + * @nvme_fabrics_type_connect: + * @nvme_fabrics_type_property_get: + * @nvme_fabrics_type_auth_send: + * @nvme_fabrics_type_auth_receive: + * @nvme_fabrics_type_disconnect: + */ +enum nvme_fctype { + nvme_fabrics_type_property_set = 0x00, + nvme_fabrics_type_connect = 0x01, + nvme_fabrics_type_property_get = 0x04, + nvme_fabrics_type_auth_send = 0x05, + nvme_fabrics_type_auth_receive = 0x06, + nvme_fabrics_type_disconnect = 0x08, +}; + +/** + * nvme_set_property() - Set controller property + * @fd: File descriptor of nvme device + * @offset: Property offset from the base to set + * @value: The value to set the property + * + * This is an NVMe-over-Fabrics specific command, not applicable to PCIe. These + * properties align to the PCI MMIO controller registers. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_set_property(int fd, int offset, __u64 value); + +/** + * nvme_get_property() - Get a controller property + * @fd: File descriptor of nvme device + * @offset: Property offset from the base to retrieve + * @value: Where the property's value will be stored on success + * + * This is an NVMe-over-Fabrics specific command, not applicable to PCIe. These + * properties align to the PCI MMIO controller registers. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_get_property(int fd, int offset, __u64 *value); + +/** + * nvme_sanitize() - Start a sanitize operation + * @fd: File descriptor of nvme device + * @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 + * @ovrpat: Overwrite pattern + * + * A sanitize operation alters all user data in the NVM subsystem such that + * recovery of any previous user data from any cache, the non-volatile media, + * or any Controller Memory Buffer is not possible. + * + * The Sanitize command is used to start a sanitize operation or to recover + * from a previously failed sanitize operation. The sanitize operation types + * that may be supported are Block Erase, Crypto Erase, and Overwrite. All + * sanitize operations are processed in the background, i.e., completion of the + * sanitize command does not indicate completion of the sanitize operation. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_sanitize_nvm(int fd, enum nvme_sanitize_sanact sanact, bool ause, + __u8 owpass, bool oipbp, bool nodas, __u32 ovrpat); + +/** + * nvme_dev_self_test() - Start or abort a self test + * @fd: File descriptor of nvme device + * @nsid: Namespace ID to test + * @stc: Self test code, see &enum nvme_dst_stc + * + * The Device Self-test command is used to start a device self-test operation + * or abort a device self-test operation. A device self-test operation is a + * diagnostic testing sequence that tests the integrity and functionality of + * the controller and may include testing of the media associated with + * namespaces. The controller may return a response to this command immediately + * while running the self-test in the background. + * + * Set the 'nsid' field to 0 to not include namepsaces in the test. Set to + * 0xffffffff to test all namespaces. All other values tests a specific + * namespace, if present. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_dev_self_test(int fd, __u32 nsid, enum nvme_dst_stc stc); + +/** + * nvme_virtual_mgmt() - Virtualization resource management + * @fd: File descriptor of nvme device + * @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 + * @result: If successful, the CQE dword0 + * + * The Virtualization Management command is supported by primary controllers + * that support the Virtualization Enhancements capability. This command is + * used for several functions: + * + * - Modifying Flexible Resource allocation for the primary controller + * - Assigning Flexible Resources for secondary controllers + * - Setting the Online and Offline state for secondary controllers + * + * Return: The nvme command status if a response was received or -1 + * with errno set otherwise. + */ +int nvme_virtual_mgmt(int fd, enum nvme_virt_mgmt_act act, + enum nvme_virt_mgmt_rt rt, __u16 cntlid, __u16 nr, + __u32 *result); + +/** + * DOC: NVMe IO command + */ + +/** + * enum nvme_io_opcode - + * @nvme_cmd_flush: + * @nvme_cmd_write: + * @nvme_cmd_read: + * @nvme_cmd_write_uncor: + * @nvme_cmd_compare: + * @nvme_cmd_write_zeroes: + * @nvme_cmd_dsm: + * @nvme_cmd_verify: + * @nvme_cmd_resv_register: + * @nvme_cmd_resv_report: + * @nvme_cmd_resv_acquire: + * @nvme_cmd_resv_release: + */ +enum nvme_io_opcode { + nvme_cmd_flush = 0x00, + nvme_cmd_write = 0x01, + nvme_cmd_read = 0x02, + nvme_cmd_write_uncor = 0x04, + nvme_cmd_compare = 0x05, + nvme_cmd_write_zeroes = 0x08, + nvme_cmd_dsm = 0x09, + nvme_cmd_verify = 0x0c, + nvme_cmd_resv_register = 0x0d, + nvme_cmd_resv_report = 0x0e, + nvme_cmd_resv_acquire = 0x11, + nvme_cmd_resv_release = 0x15, +}; + +/** + * nvme_flush() - Send an nvme flush command + * @fd: File descriptor of nvme device + * @nsid: Namespace identifier + * + * The Flush command is used to request that the contents of volatile write + * cache be made non-volatile. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_flush(int fd, __u32 nsid); + +/** + * enum nvme_io_control_flags - + * @NVME_IO_DTYPE_STREAMS: + * @NVME_IO_DEAC: + * @NVME_IO_PRINFO_PRCHK_REF: + * @NVME_IO_PRINFO_PRCHK_APP: + * @NVME_IO_PRINFO_PRCHK_GUARD: + * @NVME_IO_PRINFO_PRACT: + * @NVME_IO_FUA: + * @NVME_IO_LR: + */ +enum nvme_io_control_flags { + NVME_IO_DTYPE_STREAMS = 1 << 4, + NVME_IO_DEAC = 1 << 9, + NVME_IO_PRINFO_PRCHK_REF = 1 << 10, + NVME_IO_PRINFO_PRCHK_APP = 1 << 11, + NVME_IO_PRINFO_PRCHK_GUARD = 1 << 12, + NVME_IO_PRINFO_PRACT = 1 << 13, + NVME_IO_FUA = 1 << 14, + NVME_IO_LR = 1 << 15, +}; + +/** + * enum nvme_io_dsm_flag - + * @NVME_IO_DSM_FREQ_UNSPEC: + * @NVME_IO_DSM_FREQ_TYPICAL: + * @NVME_IO_DSM_FREQ_RARE: + * @NVME_IO_DSM_FREQ_READS: + * @NVME_IO_DSM_FREQ_WRITES: + * @NVME_IO_DSM_FREQ_RW: + * @NVME_IO_DSM_FREQ_ONCE: + * @NVME_IO_DSM_FREQ_PREFETCH: + * @NVME_IO_DSM_FREQ_TEMP: + * @NVME_IO_DSM_LATENCY_NONE: + * @NVME_IO_DSM_LATENCY_IDLE: + * @NVME_IO_DSM_LATENCY_NORM: + * @NVME_IO_DSM_LATENCY_LOW: + * @NVME_IO_DSM_SEQ_REQ: + * @NVME_IO_DSM_COMPRESSED: + */ +enum nvme_io_dsm_flags { + NVME_IO_DSM_FREQ_UNSPEC = 0, + NVME_IO_DSM_FREQ_TYPICAL = 1, + NVME_IO_DSM_FREQ_RARE = 2, + NVME_IO_DSM_FREQ_READS = 3, + NVME_IO_DSM_FREQ_WRITES = 4, + NVME_IO_DSM_FREQ_RW = 5, + NVME_IO_DSM_FREQ_ONCE = 6, + NVME_IO_DSM_FREQ_PREFETCH = 7, + NVME_IO_DSM_FREQ_TEMP = 8, + NVME_IO_DSM_LATENCY_NONE = 0 << 4, + NVME_IO_DSM_LATENCY_IDLE = 1 << 4, + NVME_IO_DSM_LATENCY_NORM = 2 << 4, + NVME_IO_DSM_LATENCY_LOW = 3 << 4, + NVME_IO_DSM_SEQ_REQ = 1 << 6, + NVME_IO_DSM_COMPRESSED = 1 << 7, +}; + +/** + * nvme_read() - Submit an nvme user read command + * @fd: File descriptor of nvme device + * @nsid: Namespace ID + * @slba: Starting logical block + * @nblocks: Number of logical blocks to send (0's based value) + * @control: Command control flags, see &enum nvme_io_control_flags. + * @dsm: Data set management attributes, see &enum nvme_io_dsm_flags + * @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. + * @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. + * @data_len: Length of user buffer, @data, in bytes + * @data: Pointer to user address of the data buffer + * metadata_len:Length of user buffer, @metadata, in bytes + * @metadata: Pointer to user address of the metadata buffer + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_read(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, + __u8 dsm, __u32 reftag, __u16 apptag, __u16 appmask, + __u32 data_len, void *data, __u32 metadata_len, void *metadata); + +/** + * nvme_write() - Submit an nvme user write command + * @fd: File descriptor of nvme device + * @nsid: Namespace ID + * @slba: Starting logical block + * @nblocks: Number of logical blocks to send (0's based value) + * @control: Command control flags, see &enum nvme_io_control_flags. + * @dsm: Data set management attributes, see &enum nvme_io_dsm_flags + * @dspec: Directive specific command, eg: stream identifier + * @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. + * @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. + * @data_len: Length of user buffer, @data, in bytes + * @data: Pointer to user address of the data buffer + * metadata_len:Length of user buffer, @metadata, in bytes + * @metadata: Pointer to user address of the metadata buffer + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_write(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, + __u8 dsm, __u16 dspec, __u32 reftag, __u16 apptag, + __u16 appmask, __u32 data_len, void *data, __u32 metadata_len, + void *metadata); + +/** + * nvme_compare() - Submit an nvme user compare command + * @fd: File descriptor of nvme device + * @nsid: Namespace ID + * @slba: Starting logical block + * @nblocks: Number of logical blocks to send (0's based value) + * @control: Command control flags, see &enum nvme_io_control_flags. + * @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. + * @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. + * @data_len: Length of user buffer, @data, in bytes + * @data: Pointer to user address of the data buffer + * metadata_len:Length of user buffer, @metadata, in bytes + * @metadata: Pointer to user address of the metadata buffer + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_compare(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, + __u32 reftag, __u16 apptag, __u16 appmask, __u32 data_len, + void *data, __u32 metadata_len, void *metadata); + +/** + * nvme_write_zeros() - Submit an nvme write zeroes command + * @fd: File descriptor of nvme device + * @nsid: Namespace identifier + * @slba: Starting logical block + * @nlb: Number of logical blocks to clear (0's based value) + * @control: Command control flags, see &enum nvme_io_control_flags. + * @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. + * @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. + * + * The Write Zeroes command is used to set a range of logical blocks to zero. + * After successful completion of this command, the value returned by + * subsequent reads of logical blocks in this range shall be all bytes cleared + * to 0h until a write occurs to this LBA range. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_write_zeros(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, + __u32 reftag, __u16 apptag, __u16 appmask); + +/** + * nvme_write_uncorrectable() - Submit an nvme write uncorrectable command + * @fd: File descriptor of nvme device + * @nsid: Namespace identifier + * @slba: Starting logical block + * @nlb: Number of logical blocks to invalidate (0's based value) + * + * The Write Uncorrectable command is used to mark a range of logical blocks as + * invalid. When the specified logical block(s) are read after this operation, + * a failure is returned with Unrecovered Read Error status. To clear the + * invalid logical block status, a write operation on those logical blocks is + * required. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_write_uncorrectable(int fd, __u32 nsid, __u64 slba, __u16 nlb); + +/** + * nvme_verify() - Send an nvme verify command + * @fd: File descriptor of nvme device + * @nsid: Namespace identifier + * @slba: Starting logical block + * @nlb: Number of logical blocks to verify (0's based value) + * @control: Command control flags, see &enum nvme_io_control_flags. + * @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. + * @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. + * + * The Verify command verifies integrity of stored information by reading data + * and metadata, if applicable, for the LBAs indicated without transferring any + * data or metadata to the host. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_verify(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, + __u32 reftag, __u16 apptag, __u16 appmask); + +/** + * enum nvme_dsm_attributes - + * @NVME_DSMGMT_IDR: + * @NVME_DSMGMT_IDW: + * @NVME_DSMGMT_AD: + */ +enum nvme_dsm_attributes { + NVME_DSMGMT_IDR = 1 << 0, + NVME_DSMGMT_IDW = 1 << 1, + NVME_DSMGMT_AD = 1 << 2, +}; + +/** + * nvme_dsm() - Send an nvme data set management command + * @fd: File descriptor of nvme device + * @nsid: Namespace identifier + * @attrs: DSM attributes, see &enum nvme_dsm_attributes + * &nr_ranges: Number of block ranges in the data set management attributes + * @dsm: The data set management attributes + * + * The Dataset Management command is used by the host to indicate attributes + * for ranges of logical blocks. This includes attributes like frequency that + * data is read or written, access size, and other information that may be used + * to optimize performance and reliability, and may be used to + * deallocate/unmap/trim those logical blocks. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_dsm(int fd, __u32 nsid, __u32 attrs, __u16 nr_ranges, + struct nvme_dsm_range *dsm); + +/** + * enum nvme_reservation_rtype - + * @NVME_RESERVATION_RTYPE_WE: + * @NVME_RESERVATION_RTYPE_EA: + * @NVME_RESERVATION_RTYPE_WERO: + * @NVME_RESERVATION_RTYPE_EARO: + * @NVME_RESERVATION_RTYPE_WEAR: + * @NVME_RESERVATION_RTYPE_EAAR: + */ +enum nvme_reservation_rtype { + NVME_RESERVATION_RTYPE_WE = 1, + NVME_RESERVATION_RTYPE_EA = 2, + NVME_RESERVATION_RTYPE_WERO = 3, + NVME_RESERVATION_RTYPE_EARO = 4, + NVME_RESERVATION_RTYPE_WEAR = 5, + NVME_RESERVATION_RTYPE_EAAR = 6, +}; + +/** + * enum nvme_reservation_racqa - + * @NVME_RESERVATION_RACQA_ACQUIRE: + * @NVME_RESERVATION_RACQA_PREEMPT: + * @NVME_RESERVATION_RACQA_PREEMPT_AND_ABORT: + */ +enum nvme_reservation_racqa { + NVME_RESERVATION_RACQA_ACQUIRE = 0, + NVME_RESERVATION_RACQA_PREEMPT = 1, + NVME_RESERVATION_RACQA_PREEMPT_AND_ABORT = 2, +}; + +/** + * nvme_resv_acquire() - Send an nvme reservation acquire + * @fd: File descriptor of nvme device + * @nsid: Namespace identifier + * @rtype: The type of reservation to be create, see &enum nvme_reservation_rtype + * @racqa: The action that is performed by the command, see &enum nvme_reservation_racqa + * @iekey: Set to ignore the existing key + * @crkey: The current reservation key associated with the host + * @nrkey: The reservation key to be unregistered from the namespace if + * the action is preempt + * + * The Reservation Acquire command is used to acquire a reservation on a + * namespace, preempt a reservation held on a namespace, and abort a + * reservation held on a namespace. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_resv_acquire(int fd, __u32 nsid, enum nvme_reservation_rtype rtype, + enum nvme_reservation_racqa racqa, bool iekey, + __u64 crkey, __u64 nrkey); + +/** + * enum nvme_reservation_rrega - + * @NVME_RESERVATION_RREGA_REGISTER_KEY: + * @NVME_RESERVATION_RREGA_UNREGISTER_KEY: + * @NVME_RESERVATION_RREGA_REPLACE_KEY: + */ +enum nvme_reservation_rrega { + NVME_RESERVATION_RREGA_REGISTER_KEY = 0, + NVME_RESERVATION_RREGA_UNREGISTER_KEY = 1, + NVME_RESERVATION_RREGA_REPLACE_KEY = 2, +}; + +/** + * enum nvme_reservation_cptpl - + * @NVME_RESERVATION_CPTPL_NO_CHANGE: + * @NVME_RESERVATION_CPTPL_CLEAR: + * @NVME_RESERVATION_CPTPL_PERSIST: + */ +enum nvme_reservation_cptpl { + NVME_RESERVATION_CPTPL_NO_CHANGE = 0, + NVME_RESERVATION_CPTPL_CLEAR = 2, + NVME_RESERVATION_CPTPL_PERSIST = 3, +}; + +/** + * nvme_resv_register() - Send an nvme reservation register + * @fd: File descriptor of nvme device + * @nsid: Namespace identifier + * @rrega: The registration action, see &enum nvme_reservation_rrega + * @cptpl: Change persist through power loss, see &enum nvme_reservation_cptpl + * @iekey: Set to ignore the existing key + * @crkey: The current reservation key associated with the host + * @nrkey: The new reservation key to be register if action is register or + * replace + * + * The Reservation Register command is used to register, unregister, or replace + * a reservation key. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_resv_register(int fd, __u32 nsid, enum nvme_reservation_rrega rrega, + enum nvme_reservation_cptpl cptpl, bool iekey, + __u64 crkey, __u64 nrkey); + +/** + * enum nvme_reservation_rrela - + * @NVME_RESERVATION_RRELA_RELEASE: + * @NVME_RESERVATION_RRELA_CLEAR: + */ +enum nvme_reservation_rrela { + NVME_RESERVATION_RRELA_RELEASE = 0, + NVME_RESERVATION_RRELA_CLEAR = 1 +}; + +/** + * nvme_resv_release() - Send an nvme reservation release + * @fd: File descriptor of nvme device + * @nsid: Namespace identifier + * @rtype: The type of reservation to be create, see &enum nvme_reservation_rtype + * @rrela: Reservation releast action, see &enum nvme_reservation_rrela + * @iekey: Set to ignore the existing key + * @crkey: The current reservation key to release + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_resv_release(int fd, __u32 nsid, enum nvme_reservation_rtype rtype, + enum nvme_reservation_rrela rrela, bool iekey, + __u64 crkey); + +/** + * nvme_resv_report() - Send an nvme reservation report + * @fd: File descriptor of nvme device + * @nsid: Namespace identifier + * @eds: Request extended Data Structure + * @len: Number of bytes to request transfered with this command + * @report: The user space destination address to store the reservation report + * + * Returns a Reservation Status data structure to memory that describes the + * registration and reservation status of a namespace. See the defintion for + * the returned structure, &struct nvme_reservation_status, for more details. + * + * Return: The nvme command status if a response was received or -1 with errno + * set otherwise. + */ +int nvme_resv_report(int fd, __u32 nsid, bool eds, __u32 len, + struct nvme_reservation_status *report); #endif /* _LIBNVME_IOCTL_H */ diff --git a/src/nvme/private.h b/src/nvme/private.h deleted file mode 100644 index e49a1b1f99..0000000000 --- a/src/nvme/private.h +++ /dev/null @@ -1,101 +0,0 @@ -#ifndef _LIBNVME_PRIVATE_H -#define _LIBNVME_PRIVATE_H - -#include -#include -#include - -#include - -#include "tree.h" - -struct nvme_path { - struct list_node entry; - struct list_node nentry; - - struct nvme_ctrl *c; - struct nvme_ns *n; - - char *name; - char *sysfs_dir; - char *ana_state; - int grpid; -}; - -struct nvme_ns { - struct list_node entry; - struct list_head paths; - - struct nvme_subsystem *s; - struct nvme_ctrl *c; - - int fd; - char *name; - char *sysfs_dir; - int nsid; - - int lba_size; - int meta_size; - uint64_t lba_count; - uint64_t lba_util; -}; - -struct nvme_ctrl { - struct list_node entry; - struct list_head paths; - struct list_head namespaces; - - struct nvme_subsystem *s; - - int fd; - char *name; - char *sysfs_dir; - char *address; - char *firmware; - char *model; - char *state; - char *numa_node; - char *queue_count; - char *serial; - char *sqsize; - char *transport; - char *subsysnqn; -}; - -struct nvme_subsystem { - struct list_node entry; - struct list_head ctrls; - struct list_head namespaces; - struct nvme_root *r; - - char *name; - char *sysfs_dir; - char *subsysnqn; -}; - -struct nvme_root { - struct list_head subsystems; -}; - -void nvme_free_ctrl(struct nvme_ctrl *c); -void nvme_ctrl_free_ns(struct nvme_ns *n); -void nvme_subsystem_free_ns(struct nvme_ns *n); -void nvme_free_path(struct nvme_path *p); -void nvme_free_subsystem(struct nvme_subsystem *s); - -int nvme_scan_subsystem(struct nvme_root *t, char *name, nvme_scan_filter_t f); -int nvme_subsystem_scan_namespace(struct nvme_subsystem *s, char *name); -int nvme_subsystem_scan_ctrls(struct nvme_subsystem *s); -int nvme_subsystem_scan_ctrl(struct nvme_subsystem *s, char *name); - -int nvme_ctrl_scan_namespace(struct nvme_ctrl *c, char *name); -int nvme_ctrl_scan_path(struct nvme_ctrl *c, char *name); - -static inline void nvme_free_dirents(struct dirent **d, int i) -{ - while (i-- > 0) - free(d[i]); - free(d); -} - -#endif /* _LIBNVME_PRIVATE_H */ diff --git a/src/nvme/tree.c b/src/nvme/tree.c index a2f3bca834..79dced51ee 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -1,18 +1,109 @@ #define _GNU_SOURCE +#include #include +#include +#include #include #include #include #include +#include + #include "ioctl.h" #include "filters.h" #include "tree.h" -#include "private.h" #include "filters.h" #include "util.h" -#include "cmd.h" +struct nvme_path { + struct list_node entry; + struct list_node nentry; + + struct nvme_ctrl *c; + struct nvme_ns *n; + + char *name; + char *sysfs_dir; + char *ana_state; + int grpid; +}; + +struct nvme_ns { + struct list_node entry; + struct list_head paths; + + struct nvme_subsystem *s; + struct nvme_ctrl *c; + + int fd; + char *name; + char *sysfs_dir; + int nsid; + + int lba_size; + int meta_size; + uint64_t lba_count; + uint64_t lba_util; +}; + +struct nvme_ctrl { + struct list_node entry; + struct list_head paths; + struct list_head namespaces; + + struct nvme_subsystem *s; + + int fd; + char *name; + char *sysfs_dir; + char *address; + char *firmware; + char *model; + char *state; + char *numa_node; + char *queue_count; + char *serial; + char *sqsize; + char *transport; + char *subsysnqn; +}; + +struct nvme_subsystem { + struct list_node entry; + struct list_head ctrls; + struct list_head namespaces; + struct nvme_root *r; + + char *name; + char *sysfs_dir; + char *subsysnqn; +}; + +struct nvme_root { + struct list_head subsystems; +}; + +void nvme_free_ctrl(struct nvme_ctrl *c); +void nvme_ctrl_free_ns(struct nvme_ns *n); +void nvme_subsystem_free_ns(struct nvme_ns *n); +void nvme_free_path(struct nvme_path *p); +void nvme_free_subsystem(struct nvme_subsystem *s); + +int nvme_scan_subsystem(struct nvme_root *t, char *name, nvme_scan_filter_t f); +int nvme_subsystem_scan_namespace(struct nvme_subsystem *s, char *name); +int nvme_subsystem_scan_ctrls(struct nvme_subsystem *s); +int nvme_subsystem_scan_ctrl(struct nvme_subsystem *s, char *name); + +int nvme_ctrl_scan_namespace(struct nvme_ctrl *c, char *name); +int nvme_ctrl_scan_path(struct nvme_ctrl *c, char *name); + +static inline void nvme_free_dirents(struct dirent **d, int i) +{ + while (i-- > 0) + free(d[i]); + free(d); +} static int nvme_scan_topology(struct nvme_root *r, nvme_scan_filter_t f) { struct dirent **subsys; diff --git a/src/nvme/util.c b/src/nvme/util.c index 11760263f7..8870dd1c2e 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -16,8 +16,6 @@ #include #include "filters.h" -#include "types.h" -#include "cmd.h" #include "ioctl.h" #include "util.h" #include "tree.h" diff --git a/src/nvme/util.h b/src/nvme/util.h index 82588dd144..e3cff30dfc 100644 --- a/src/nvme/util.h +++ b/src/nvme/util.h @@ -4,7 +4,7 @@ #include #include -#include "cmd.h" +#include "ioctl.h" /** * nvme_status_to_errno() - Converts nvme return status to errno From 149f96e67039dc3c886c93678345502ac286c995 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Mon, 10 Feb 2020 13:09:13 -0800 Subject: [PATCH 0022/1564] Update .gitignore Signed-off-by: Keith Busch --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 364c1d0e86..25a0499497 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,9 @@ examples/display-columnar examples/telemetry-listen examples/discover-loop +src/ccan/config.h +src/ccan/tools/configurator/configurator + config-host.h config-host.mak config.log From 14f550e99ce9e493ed3d22b42f288ff68b65f82b Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Mon, 10 Feb 2020 15:29:10 -0800 Subject: [PATCH 0023/1564] Make systemd-devel optional There's only one libnvme feature that uses this package. Let's make this feature optional and return error ENOTSUP if the package is not available. Signed-off-by: Keith Busch --- configure | 28 ++++++++++++++++++++-------- src/Makefile | 2 +- src/nvme/fabrics.c | 12 +++++++++++- 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/configure b/configure index 63d26a50c9..88663d6bc5 100755 --- a/configure +++ b/configure @@ -138,6 +138,18 @@ compile_prog() { do_cc $CFLAGS $local_cflags -o $TMPE $TMPC $LDFLAGS $local_ldflags } +feature_not_found() { + feature=$1 + packages=$2 + + echo "" + echo "ERROR: $feature package requirements not met" + if test ! -z "$packages" ; then + echo "ERROR: needs $packages installed" + fi + fatal "" +} + has() { type "$1" >/dev/null 2>&1 } @@ -167,25 +179,25 @@ print_and_output_mak "datadir" "$datadir" libuuid="no" ${ld} -o /dev/null -luuid >/dev/null 2>&1 if [ $? -eq 0 ]; then - libuuid="yes" + libuuid="yes" fi print_config "libuuid" "${libuuid}" ########################################## # check for SystemD -havesystemd="no" -pkg-config --exists systemd --atleast-version=232 +systemd="no" +pkg-config --exists systemd --atleast-version=232 if [ $? -eq 0 ]; then - havesystemd="yes" + systemd="yes" fi -print_config "havesystemd" "${havesystemd}" +print_config "systemd" "${systemd}" if test "$libuuid" = "yes"; then - output_sym "LIBUUID" + output_sym "CONFIG_LIBUUID" echo "override LDFLAGS += -luuid" >> $config_host_mak echo "override LIB_DEPENDS += uuid" >> $config_host_mak fi -if test "$havesystemd" = "yes"; then - output_sym "HAVE_SYSTEMD" +if test "$systemd" = "yes"; then + output_sym "CONFIG_SYSTEMD" echo "override LDFLAGS += -lsystemd" >> $config_host_mak fi diff --git a/src/Makefile b/src/Makefile index 5f42219cb8..03e5abc550 100644 --- a/src/Makefile +++ b/src/Makefile @@ -8,7 +8,7 @@ libdir ?= $(prefix)/lib CCANDIR=ccan/ -CFLAGS ?= -g -fomit-frame-pointer -O2 -I/usr/include -Invme/ -I$(CCANDIR) +CFLAGS ?= -g -fomit-frame-pointer -O2 -I/usr/include -Invme/ -I$(CCANDIR) -include ../config-host.h override CFLAGS += -Wall -fPIC SO_CFLAGS=-shared $(CFLAGS) L_CFLAGS=$(CFLAGS) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 795a060adf..1eeeac355b 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -13,7 +13,10 @@ #include #include +#ifdef CONFIG_SYSTEMD #include +#define NVME_HOSTNQN_ID SD_ID128_MAKE(c7,f4,61,81,12,be,49,32,8c,83,10,6f,9d,dd,d8,6b) +#endif #include @@ -22,7 +25,6 @@ #include "util.h" #define NVMF_HOSTID_SIZE 36 -#define NVME_HOSTNQN_ID SD_ID128_MAKE(c7,f4,61,81,12,be,49,32,8c,83,10,6f,9d,dd,d8,6b) const char *nvmf_dev = "/dev/nvme-fabrics"; const char *nvmf_hostnqn_file = "/etc/nvme/hostnqn"; @@ -336,6 +338,7 @@ int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, return ret; } +#ifdef CONFIG_SYSTEMD char *nvmf_hostnqn_generate() { char *ret = NULL; @@ -351,6 +354,13 @@ char *nvmf_hostnqn_generate() return ret; } +#else +char *nvmf_hostnqn_generate() +{ + errno = ENOTSUP; + return NULL; +} +#endif static char *nvmf_read_file(const char *f, int len) { From 7da106fc54cdb79f425c9112beff157409a749f2 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Mon, 10 Feb 2020 17:38:36 -0800 Subject: [PATCH 0024/1564] Add c++ inclusion support extern "C" the top level header file, and add a simple c++ compile test. Signed-off-by: Keith Busch --- .gitignore | 1 + configure | 13 +++++++++++++ examples/Makefile | 6 +----- src/libnvme.h | 8 ++++++++ test/Makefile | 22 ++++++++++++++++------ test/cpp.cc | 40 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 79 insertions(+), 11 deletions(-) create mode 100644 test/cpp.cc diff --git a/.gitignore b/.gitignore index 25a0499497..8ff3e73c89 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ a.out *.so.* test/test +test/cpp examples/display-tree examples/display-columnar diff --git a/configure b/configure index 88663d6bc5..0d6ebc6da9 100755 --- a/configure +++ b/configure @@ -192,6 +192,16 @@ if [ $? -eq 0 ]; then fi print_config "systemd" "${systemd}" +########################################## +# check for c++ +cpp="no" +which g++ > /dev/null 2> /dev/null +if [ $? -eq 0 ]; then + cpp="yes" +fi +print_config "cpp" "${cpp}" + + if test "$libuuid" = "yes"; then output_sym "CONFIG_LIBUUID" echo "override LDFLAGS += -luuid" >> $config_host_mak @@ -201,3 +211,6 @@ if test "$systemd" = "yes"; then output_sym "CONFIG_SYSTEMD" echo "override LDFLAGS += -lsystemd" >> $config_host_mak fi +if test "$cpp" = "yes"; then + output_mak "CONFIG_CPLUSPLUS" "y" +fi diff --git a/examples/Makefile b/examples/Makefile index 0a70e9b812..8cb7ded58d 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -11,12 +11,8 @@ all_targets += telemetry-listen display-tree display-columnar discover-loop all: $(all_targets) -test_srcs := telemetry-listen.c display-tree.c display-columnar.c discover-loop.c - -test_objs := $(patsubst %.c,%.ol,$(test_srcs)) - %: %.c $(QUIET_CC)$(CC) $(CFLAGS) -o $@ $< -lnvme clean: - @rm -f $(all_targets) $(test_objs) + rm -f $(all_targets) diff --git a/src/libnvme.h b/src/libnvme.h index 66e17d0c15..2a04bf8b46 100644 --- a/src/libnvme.h +++ b/src/libnvme.h @@ -1,6 +1,10 @@ #ifndef _LIBNVME_H #define _LIBNVME_H +#ifdef __cplusplus +extern "C" { +#endif + #include "nvme/types.h" #include "nvme/ioctl.h" #include "nvme/fabrics.h" @@ -8,4 +12,8 @@ #include "nvme/tree.h" #include "nvme/util.h" +#ifdef __cplusplus +} +#endif + #endif /* _LIBNVME_H */ diff --git a/test/Makefile b/test/Makefile index b21e464320..ddb80b7a27 100644 --- a/test/Makefile +++ b/test/Makefile @@ -5,18 +5,28 @@ include ../Makefile.quiet ifneq ($(MAKECMDGOALS),clean) include ../config-host.mak +else +CONFIG_CPLUSPLUS=y endif -all_targets += test +c_targets += test +ifdef CONFIG_CPLUSPLUS +cpp_targets += cpp +else +cpp_targets += +endif + +all_targets += $(c_targets) $(cpp_targets) all: $(all_targets) -%: %.c - $(QUIET_CC)$(CC) $(CFLAGS) -o $@ $< -lnvme +CXXFLAGS ?= -lstdc++ -test_srs := test.c +%: %.cc + $(QUIET_CC)$(CC) $(CFLAGS) $(CXXFLAGS) -o $@ $< -lnvme -test_objs := $(patsubst %.c,%.ol,$(test_srcs)) +%: %.c + $(QUIET_CC)$(CC) $(CFLAGS) -o $@ $< -lnvme clean: - @rm -f $(all_targets) $(test_objs) + rm -f $(all_targets) diff --git a/test/cpp.cc b/test/cpp.cc new file mode 100644 index 0000000000..f294d00144 --- /dev/null +++ b/test/cpp.cc @@ -0,0 +1,40 @@ +#include +#include + +int main() +{ + nvme_root_t r; + nvme_subsystem_t s; + nvme_ctrl_t c; + nvme_path_t p; + nvme_ns_t n; + + r = nvme_scan(); + if (!r) + return -1; + + nvme_for_each_subsystem(r, s) { + std::cout << nvme_subsystem_get_name(s) << " - NQN=" << nvme_subsystem_get_nqn(s) << "\n"; + nvme_subsystem_for_each_ctrl(s, c) { + std::cout << " `- " << nvme_ctrl_get_name(c) << " " << + nvme_ctrl_get_transport(c) << " " << + nvme_ctrl_get_address(c) << " " << + nvme_ctrl_get_state(c) << "\n"; + nvme_ctrl_for_each_ns(c, n) + std::cout << " `- " << nvme_ns_get_name(n) << + "lba size:" << nvme_ns_get_lba_size(n) << " lba max:" << + nvme_ns_get_lba_count(n) << "\n"; + nvme_ctrl_for_each_path(c, p) + std::cout << " `- " << nvme_path_get_name(p) << " " << + nvme_path_get_ana_state(p) << "\n"; + } + nvme_subsystem_for_each_ns(s, n) { + std::cout << " `- " << nvme_ns_get_name(n) << + "lba size:" << nvme_ns_get_lba_size(n) << " lba max:" << + nvme_ns_get_lba_count(n) << "\n"; + } + } + std::cout << "\n"; + + return 0; +} From c79ae91a5d4ed5013de2c807fe560a9253ff0fc1 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 13 Feb 2020 00:19:13 +0900 Subject: [PATCH 0025/1564] Add licence tags, copyright, and author comments Signed-off-by: Keith Busch --- Makefile | 2 +- README | 4 ++-- examples/discover-loop.c | 8 ++++++++ examples/display-columnar.c | 8 ++++++++ examples/display-tree.c | 8 ++++++++ examples/telemetry-listen.c | 8 ++++++++ src/Makefile | 2 +- src/libnvme.h | 9 +++++++++ src/nvme/fabrics.c | 10 +++++++++- src/nvme/fabrics.h | 8 ++++++++ src/nvme/filters.c | 9 ++++++++- src/nvme/filters.h | 8 ++++++++ src/nvme/ioctl.c | 8 ++++++++ src/nvme/ioctl.h | 10 +++++++++- src/nvme/tree.c | 9 ++++++++- src/nvme/tree.h | 9 +++++++++ src/nvme/types.h | 9 +++++++++ src/nvme/util.c | 10 +++++++++- src/nvme/util.h | 8 ++++++++ test/cpp.cc | 9 +++++++++ test/test.c | 8 ++++++++ 21 files changed, 155 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index f197496306..32bc5afca1 100644 --- a/Makefile +++ b/Makefile @@ -49,7 +49,7 @@ install-tests: @$(MAKE) -C test install prefix=$(DESTDIR)$(prefix) datadir=$(DESTDIR)$(datadir) clean: - @rm -f config-host.mak config-host.h cscope.out cscope.files $(NAME).pc + @rm -f config-host.mak config-host.h cscope.out $(NAME).pc @$(MAKE) -C src clean @$(MAKE) -C test clean @$(MAKE) -C examples clean diff --git a/README b/README index e54c8e8bd8..1b40be2ea1 100644 --- a/README +++ b/README @@ -20,7 +20,7 @@ and development for both kernel and userspace. The list is archived here: License ------- -All software contained within this repo is currently licensed LGPL, see -COPYING for more information. +Except where otherwise stated, all software contained within this repo is +currently licensed LGPL, see COPYING for more information. Keith Busch 2020-02-06 diff --git a/examples/discover-loop.c b/examples/discover-loop.c index 6b9d01ff0a..2aaa9b6137 100644 --- a/examples/discover-loop.c +++ b/examples/discover-loop.c @@ -1,3 +1,11 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/** + * This file is part of libnvme. + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + * + * Authors: Keith Busch + */ + /** * discover-loop: Use fabrics commands to discover any loop targets and print * those records. You must have at least one configured nvme loop target on the diff --git a/examples/display-columnar.c b/examples/display-columnar.c index 014c8dc44d..283f073e44 100644 --- a/examples/display-columnar.c +++ b/examples/display-columnar.c @@ -1,3 +1,11 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/** + * This file is part of libnvme. + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + * + * Authors: Keith Busch + */ + /** * display-columnar: Scans the nvme topology, prints each record type in a * column format for easy visual scanning. diff --git a/examples/display-tree.c b/examples/display-tree.c index 9d00da2791..58520dfd96 100644 --- a/examples/display-tree.c +++ b/examples/display-tree.c @@ -1,3 +1,11 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/** + * This file is part of libnvme. + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + * + * Authors: Keith Busch + */ + /** * display-tree: Scans the nvme topology, prints as an ascii tree with some * selected attributes for each component. diff --git a/examples/telemetry-listen.c b/examples/telemetry-listen.c index 00c43f7bef..1bc250b537 100644 --- a/examples/telemetry-listen.c +++ b/examples/telemetry-listen.c @@ -1,3 +1,11 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/** + * This file is part of libnvme. + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + * + * Authors: Keith Busch + */ + /** * Open all nvme controller's uevent and listen for changes. If NVME_AEN event * is observed with controller telemetry data, read the log and save it to a diff --git a/src/Makefile b/src/Makefile index 03e5abc550..57b562425e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -8,7 +8,7 @@ libdir ?= $(prefix)/lib CCANDIR=ccan/ -CFLAGS ?= -g -fomit-frame-pointer -O2 -I/usr/include -Invme/ -I$(CCANDIR) -include ../config-host.h +CFLAGS ?= -g -fomit-frame-pointer -O2 -I/usr/include -Invme/ -I$(CCANDIR) -include ../config-host.h -D_GNU_SOURCE override CFLAGS += -Wall -fPIC SO_CFLAGS=-shared $(CFLAGS) L_CFLAGS=$(CFLAGS) diff --git a/src/libnvme.h b/src/libnvme.h index 2a04bf8b46..1b648feab9 100644 --- a/src/libnvme.h +++ b/src/libnvme.h @@ -1,3 +1,12 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/** + * This file is part of libnvme. + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + * + * Authors: Keith Busch + * Chaitanya Kulkarni + */ + #ifndef _LIBNVME_H #define _LIBNVME_H diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 1eeeac355b..19a0dc6bf5 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -1,4 +1,12 @@ -#define _GNU_SOURCE +// SPDX-License-Identifier: LGPL-2.1-or-later +/** + * This file is part of libnvme. + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + * + * Authors: Keith Busch + * Chaitanya Kulkarni + */ + #include #include #include diff --git a/src/nvme/fabrics.h b/src/nvme/fabrics.h index d794136224..702dd926ac 100644 --- a/src/nvme/fabrics.h +++ b/src/nvme/fabrics.h @@ -1,3 +1,11 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/** + * This file is part of libnvme. + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + * + * Authors: Keith Busch + * Chaitanya Kulkarni + */ #ifndef _LIBNVME_FABRICS_H #define _LIBNVME_FABRICS_H diff --git a/src/nvme/filters.c b/src/nvme/filters.c index 2579403b6b..336254f58b 100644 --- a/src/nvme/filters.c +++ b/src/nvme/filters.c @@ -1,4 +1,11 @@ -#define _GNU_SOURCE +// SPDX-License-Identifier: LGPL-2.1-or-later +/** + * This file is part of libnvme. + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + * + * Authors: Keith Busch + * Chaitanya Kulkarni + */ #include #include #include diff --git a/src/nvme/filters.h b/src/nvme/filters.h index 0c6df91667..6f7e8579a5 100644 --- a/src/nvme/filters.h +++ b/src/nvme/filters.h @@ -1,3 +1,11 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/** + * This file is part of libnvme. + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + * + * Authors: Keith Busch + */ + #ifndef _LIBNVME_FILTERS_H #define _LIBNVME_FILTERS_H diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 6105f443cf..233dea4aab 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -1,3 +1,11 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/** + * This file is part of libnvme. + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + * + * Authors: Keith Busch + * Chaitanya Kulkarni + */ #include #include #include diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 167162164e..9287ad68cc 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -1,8 +1,16 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/** + * This file is part of libnvme. + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + * + * Authors: Keith Busch + * Chaitanya Kulkarni + */ + #ifndef _LIBNVME_IOCTL_H #define _LIBNVME_IOCTL_H #include - #include "types.h" /* diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 79dced51ee..de0cd4d7b9 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -1,4 +1,11 @@ -#define _GNU_SOURCE +// SPDX-License-Identifier: LGPL-2.1-or-later +/** + * This file is part of libnvme. + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + * + * Authors: Keith Busch + * Chaitanya Kulkarni + */ #include #include #include diff --git a/src/nvme/tree.h b/src/nvme/tree.h index a37541ab89..9023ee9ef1 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -1,3 +1,12 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/** + * This file is part of libnvme. + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + * + * Authors: Keith Busch + * Chaitanya Kulkarni + */ + #ifndef _LIBNVME_TREE_H #define _LIBNVME_TREE_H diff --git a/src/nvme/types.h b/src/nvme/types.h index 179510de8a..34b3ebe31c 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -1,3 +1,12 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/** + * This file is part of libnvme. + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + * + * Authors: Keith Busch + * Chaitanya Kulkarni + */ + #ifndef _LIBNVME_TYPES_H #define _LIBNVME_TYPES_H diff --git a/src/nvme/util.c b/src/nvme/util.c index 8870dd1c2e..4bf9af22d7 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -1,4 +1,12 @@ -#define _GNU_SOURCE +// SPDX-License-Identifier: LGPL-2.1-or-later +/** + * This file is part of libnvme. + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + * + * Authors: Keith Busch + * Chaitanya Kulkarni + */ + #include #include #include diff --git a/src/nvme/util.h b/src/nvme/util.h index e3cff30dfc..a920681071 100644 --- a/src/nvme/util.h +++ b/src/nvme/util.h @@ -1,3 +1,11 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/** + * This file is part of libnvme. + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + * + * Authors: Keith Busch + * Chaitanya Kulkarni + */ #ifndef _LIBNVME_UTIL_H #define _LIBNVME_UTIL_H diff --git a/test/cpp.cc b/test/cpp.cc index f294d00144..eb48b78e3a 100644 --- a/test/cpp.cc +++ b/test/cpp.cc @@ -1,3 +1,11 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/** + * This file is part of libnvme. + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + * + * Authors: Keith Busch + */ + #include #include @@ -35,6 +43,7 @@ int main() } } std::cout << "\n"; + nvme_free_tree(r); return 0; } diff --git a/test/test.c b/test/test.c index 64a7febe28..8992554531 100644 --- a/test/test.c +++ b/test/test.c @@ -1,3 +1,11 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/** + * This file is part of libnvme. + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + * + * Authors: Keith Busch + */ + /** * Basic libnvme test: uses scan filters, single controllers, and many admin * command APIs for identifications, logs, and features. No verification for From 135602b6a6101177a1b17b44b0292c2d81fffeee Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 13 Feb 2020 09:50:49 -0800 Subject: [PATCH 0026/1564] Apply kernel-doc comments to more structs and enums Signed-off-by: Keith Busch --- src/nvme/types.h | 2219 +++++++++++++++++++++++++++++++++------------- 1 file changed, 1588 insertions(+), 631 deletions(-) diff --git a/src/nvme/types.h b/src/nvme/types.h index 34b3ebe31c..1ce3f1d10e 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -52,23 +52,33 @@ static inline uint64_t le64_to_cpu(__le64 x) } /** - * enum nvme_constants - - * @NVME_NSID_ALL: - * @NVME_NSID_NONE: - * @NVME_UUID_NONE: - * @NVME_CNTLID_NONE: - * @NVME_NVMSETID_NONE: - * @NVME_LOG_LSP_NONE: - * @NVME_LOG_LSI_NONE: - * @NVME_IDENTIFY_DATA_SIZE: - * @NVME_ID_NVMSET_LIST_MAX: - * @NVME_ID_UUID_LIST_MAX: - * @NVME_ID_CTRL_LIST_MAX: - * @NVME_ID_NS_LIST_MAX: - * @NVME_ID_SECONDARY_CTRL_MAX: - * @NVME_FEAT_LBA_RANGE_MAX: - * @NVME_LOG_ST_MAX_RESULTS: - * @NVME_DSM_MAX_RANGES: + * enum nvme_constants - A place to stash various constant nvme values + * @NVME_NSID_ALL: A broadcast value that is used to specify all + * namespaces + * @NVME_NSID_NONE: The invalid namespace id, for when the nsid + * parameter is not used in a command + * @NVME_UUID_NONE: Use to omit the uuid command parameter + * @NVME_CNTLID_NONE: Use to omit the cntlid command parameter + * @NVME_NVMSETID_NONE: Use to omit the nvmsetid command parameter + * @NVME_LOG_LSP_NONE: Use to omit the log lsp command parameter + * @NVME_LOG_LSI_NONE: Use to omit the log lsi command parameter + * @NVME_IDENTIFY_DATA_SIZE: The transfer size for nvme identify commands + * @NVME_ID_NVMSET_LIST_MAX: The largest possible nvmset index in identify + * nvmeset + * @NVME_ID_UUID_LIST_MAX: The largest possible uuid index in identify + * uuid list + * @NVME_ID_CTRL_LIST_MAX: The largest possible controller index in + * identify controller list + * @NVME_ID_NS_LIST_MAX: The largest possible namespace index in + * identify namespace list + * @NVME_ID_SECONDARY_CTRL_MAX: The largest possible secondary controller index + * in identify secondary controller + * @NVME_FEAT_LBA_RANGE_MAX: The largest possible LBA range index in feature + * lba range type + * @NVME_LOG_ST_MAX_RESULTS: The largest possible self test result index in the + * device self test log + * @NVME_DSM_MAX_RANGES: The largest possible range index in a data-set + * management command */ enum nvme_constants { NVME_NSID_ALL = 0xffffffff, @@ -91,11 +101,9 @@ enum nvme_constants { }; /** - * DOC: NVMe controller registers/properties - */ - -/** - * enum nvme_registers - + * enum nvme_registers - The nvme controller registers for all transports. This + * 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 @@ -172,9 +180,6 @@ enum nvme_registers { #define NVME_CMB_CQS(cmbsz) ((cmbsz) & 0x2) #define NVME_CMB_SQS(cmbsz) ((cmbsz) & 0x1) -/** - * enum - - */ enum { NVME_CC_ENABLE = 1 << 0, NVME_CC_CSS_NVM = 0 << 4, @@ -202,7 +207,7 @@ enum { NVME_CSTS_SHST_MASK = 3 << 2, }; -/* +/** * is_64bit_reg() - Checks if offset of the controller register is 64bit or not. * @offset: Offset of controller register field in bytes * @@ -227,24 +232,105 @@ static inline bool is_64bit_reg(__u32 offset) } /** - * DOC: NVMe Identify + * 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. + * @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. + */ +enum nvme_psd_flags { + NVME_PSD_FLAGS_MXPS = 1 << 0, + NVME_PSD_FLAGS_NOPS = 1 << 1, +}; + +/** + * 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_IPS_100_MICRO_WATT: 0.0001 watt scale + * NVME_PSD_IPS_10_MILLI_WATT: 0.01 watt scale + */ +enum nvme_psd_ps { + NVME_PSD_PS_100_MICRO_WATT = 1, + NVME_PSD_PS_10_MILLI_WATT = 2, +}; + +/** + * nvme_psd_power_scale() - power scale occupies the upper 3 bits + */ +static inline unsigned nvme_psd_power_scale(__u8 ps) +{ + return ps >> 6; +} + +/** + * 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. + * @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. + * @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 + * NVM subsystem are idle. The submission queue(s) + * should be sufficiently large allowing the host to + * ensure there are multiple commands pending at all + * times during the workload. */ +enum nvme_psd_workload { + NVME_PSD_WORKLOAD_1 = 1, + NVME_PSD_WORKLOAD_2 = 2, +}; /** * struct nvme_id_psd - - * @mp: - * @flags: - * @enlat: - * @exlat: - * @rrt: - * @rrl: - * @rwt: - * @rwl: - * @idlp: - * @ips: - * @actp: - * @apw: - * @aps: + * @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. + * @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. + * @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. + * @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. + * @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 + * @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 + * @idlp: Idle Power indicates the typical power consumed by the NVM + * 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. + * @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. + * @apw: Active Power Workload indicates the workload used to calculate + * maximum power for this power state. See &enum nvme_psd_workload for + * decoding this field. + * @aps: Active Power Scale indicates the scale for the &struct + * nvme_id_psd.actp, see &enum nvme_psd_ps for decoding this value. */ struct nvme_id_psd { __le16 mp; @@ -265,112 +351,194 @@ struct nvme_id_psd { __u8 rsvd23[8]; }; -/** - * nvme_psd_power_scale() - power scale occupies the upper 3 bits - */ -static inline unsigned nvme_psd_power_scale(__u8 ps) -{ - return ps >> 6; -} - -/** - * enum - - * @NVME_PSD_FLAGS_MAX_POWER_SCALE: - * @NVME_PSD_FLAGS_NON_OP_STATE: - * @NVME_PSD_RELATIVE_MASK: - * @NVME_PSD_APW_MASK: - */ -enum { - NVME_PSD_FLAGS_MAX_POWER_SCALE = 1 << 0, - NVME_PSD_FLAGS_NON_OP_STATE = 1 << 1, - NVME_PSD_RELATIVE_MASK = 0x1f, - NVME_PSD_APW_MASK = 0x7, -}; - /** * struct nvme_id_ctrl - Identify Controller data structure - * @vid: Vendor ID - * @ssvid: Subsystem Vendor Id - * @sn: Serial Number - * @mn: Model Number - * @fr: Firmware Revision - * @rab: Recommended Arbitration Burst - * @ieee: IEEE - * @cmic: Controller Mulitpathing Capabilities - * @mdts: Max Data Transfer Size - * @cntlid: Controller Identifier - * @ver: Version - * @rtd3r: Runtime D3 Resume - * @rtd3e: Runtime D3 Exit - * @oaes: Optional Async Events Supported - * @ctratt: Controller Attributes - * @rrls: Read Recovery Levels - * @cntrltype: Controller Type - * @fguid: FRU GUID - * @crdt1: Controller Retry Delay 1 - * @crdt2: Controller Retry Delay 2 - * @crdt3: Controller Retry Delay 3 - * @nvmsr: - * @vwci: - * @mec: - * @oacs: Optional Admin Commands Supported - * @acl: Abort Command Limit - * @aerl: Async Event Request Limit - * @frmw: - * @lpa: Log Page Attributes - * @elpe: - * @npss: Number of Power States Supported - * @avscc: - * @apsta: - * @wctemp: - * @cctemp: - * @mtfa: - * @hmpre: - * @hmmin: - * @tnvmcap: - * @unvmcap: - * @rpmbs: - * @edstt: - * @dsto: - * @fwug: - * @kas: - * @hctma: - * @mntmt: - * @mxtmt: - * @sanicap: - * @hmminds: - * @hmmaxd: - * @nsetidmax: - * @endgidmax: - * @anatt: - * @anacap: - * @anagrpmax: - * @nanagrpid: - * @pels: - * @sqes: - * @cqes: - * @maxcmd: - * @nn: - * @onc: - * @fuses: - * @fna: - * @vwc: - * @awun: - * @awupf: - * @nvscc: - * @nwpc: - * @acwu: - * @sgls: - * @mnan: - * @subnqn: - * @ioccsz: - * @iorcsz: - * @icdoff: - * @fcatt: - * @msdbd: - * @ofcs: - * @psd: - * @vs: + * @vid: PCI Vendor ID, the company vendor identifier that is assigned by + * 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 + * @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. + * @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 + * @cntlid: Controller ID, the NVM subsystem unique controller identifier + * 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). + * @rtd3r: RTD3 Resume Latency, the expected latency in microseconds to resume + * from Runtime D3 + * @rtd3e: RTD3 Exit Latency, the typical latency in microseconds to enter + * 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. + * @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 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 + * @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. + * @acl: Abort Command Limit, the maximum number of concurrently + * 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. + * @frmw: Firmware Updates indicates capabilities regarding firmware + * 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. + * @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. + * @avscc: Admin Vendor Specific Command Configuration, see &enum + * nvme_id_ctrl_avscc. + * @apsta: Autonomous Power State Transition Attributes, see &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. + * @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. + * @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. + * @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. + * @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. + * @tnvmcap: Total NVM Capacity, the total NVM capacity in the NVM subsystem. + * 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. + * @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 + * @kas: Keep Alive Support indicates the granularity of the Keep Alive + * Timer in 100 millisecond units. + * @hctma: Host Controlled Thermal Management Attributes, see &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. + * @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. + * @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. + * @hmmaxd: Host Memory Maximum Descriptors Entries indicates the number of + * 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. + * @endgidmax: Endurance Group Identifier Maximum, defines the maximum value of + * 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. + * @anacap: Asymmetric Namespace Access Capabilities, see &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. + * @nanagrpid: Number of ANA Group Identifiers indicates the number of ANA + * groups supported by this controller. + * @pels: Persistent Event Log Size indicates the maximum reportable size + * for the Persistent Event Log. + * @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. + * @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 + * maximum number of namespaces supported by the NVM. subsystem. + * @oncs: Optional NVM Command Support, see &enum nvme_id_ctrl_oncs. + * @fuses: Fused Operation Support, see &enum nvme_id_ctrl_fuses. + * @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. + * @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. + * @nvscc: NVM Vendor Specific Command Configuration, see &enum + * nvme_id_ctrl_nvscc. + * @nwpc: Namespace Write Protection Capabilities, see &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. + * @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. + * @subnqn: NVM Subsystem NVMe Qualified Name, UTF-8 null terminated string + * @ioccsz: I/O Queue Command Capsule Supported Size, defines the maximum + * 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. + * @icdoff: In Capsule Data Offset, defines the offset where data starts + * 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. + * @ofcs: Optional Fabric Commands Support, see &enum nvme_id_ctrl_ofcs. + * @psd: Power State Descriptors, see &struct nvme_id_psd. + * @vs: Vendor Specific */ struct nvme_id_ctrl { __le16 vid; @@ -468,9 +636,13 @@ struct nvme_id_ctrl { }; /** - * enum - + * enum nvme_id_ctrl_cmic - + * @NVME_CTRL_CMIC_MULTI_PORT: + * @NVME_CTRL_CMIC_MULTI_CTRL: + * @NVME_CTRL_CMIC_MULTI_SRIOV: + * @NVME_CTRL_CMIC_MULTI_ANA_REPORTING: */ -enum { +enum nvme_id_ctrl_cmic { NVME_CTRL_CMIC_MULTI_PORT = 1 << 0, NVME_CTRL_CMIC_MULTI_CTRL = 1 << 1, NVME_CTRL_CMIC_MULTI_SRIOV = 1 << 2, @@ -478,9 +650,15 @@ enum { }; /** - * enum - + * enum nvme_id_ctrl_oaes - The typical latency in microseconds to enter Runtime D3 + * @NVME_CTRL_OAES_NA: + * @NVME_CTRL_OAES_FA: + * @NVME_CTRL_OAES_ANA: + * @NVME_CTRL_OAES_PLEA: + * @NVME_CTRL_OAES_LBAS:: + * @NVME_CTRL_OAES_EGE: */ -enum { +enum nvme_id_ctrl_oaes { NVME_CTRL_OAES_NA = 1 << 8, NVME_CTRL_OAES_FA = 1 << 9, NVME_CTRL_OAES_ANA = 1 << 11, @@ -490,9 +668,19 @@ enum { }; /** - * enum - + * enum nvme_id_ctrl_ctratt - + * @NVME_CTRL_CTRATT_128_ID: + * @NVME_CTRL_CTRATT_NON_OP_PSP: + * @NVME_CTRL_CTRATT_NVM_SETS: + * @NVME_CTRL_CTRATT_READ_RECV_LVLS: + * @NVME_CTRL_CTRATT_ENDURANCE_GROUPS: + * @NVME_CTRL_CTRATT_PREDICTABLE_LAT: + * @NVME_CTRL_CTRATT_TBKAS: + * @NVME_CTRL_CTRATT_NAMESPACE_GRANULARITY: + * @NVME_CTRL_CTRATT_SQ_ASSOCIATIONS: + * @NVME_CTRL_CTRATT_UUID_LIST: */ -enum { +enum nvme_id_ctrl_ctratt { NVME_CTRL_CTRATT_128_ID = 1 << 0, NVME_CTRL_CTRATT_NON_OP_PSP = 1 << 1, NVME_CTRL_CTRATT_NVM_SETS = 1 << 2, @@ -506,43 +694,95 @@ enum { }; /** - * enum - + * enum nvme_id_ctrl_cntrltype - + * @NVME_CTRL_CNTRLTYPE_IO: + * @NVME_CTRL_CNTRLTYPE_DISCOVERY: + * @NVME_CTRL_CNTRLTYPE_ADMIN: */ -enum { - NVME_CTRL_CNTRLTYPE_RESERVED = 0, +enum nvme_id_ctrl_cntrltype { NVME_CTRL_CNTRLTYPE_IO = 1, NVME_CTRL_CNTRLTYPE_DISCOVERY = 2, NVME_CTRL_CNTRLTYPE_ADMIN = 3, }; /** - * enum - + * enum nvme_id_ctrl_nvmsr - This field reports information associated with the + * 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. + * @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. */ -enum { +enum nvme_id_ctrl_nvmsr { NVME_CTRL_NVMSR_NVMESD = 1 << 0, NVME_CTRL_NVMSR_NVMEE = 1 << 1, }; /** - * enum - - */ -enum { + * 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. + * @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. + * @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. + */ +enum nvme_id_ctrl_vwci { NVME_CTRL_VWCI_VWCR = 0x7f << 0, NVME_CTRL_VWCI_VWCRV = 1 << 7, }; /** - * enum - + * enum nvme_id_ctrl_mec - Flags indicatings 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. + * @NVME_CTRL_MEC_PCIEME: If set, then the NVM Subsystem contains a Management + * Endpoint on a PCIe port. */ -enum { +enum nvme_id_ctrl_mec { NVME_CTRL_MEC_SMBUSME = 1 << 0, NVME_CTRL_MEC_PCIEME = 1 << 1, }; /** - * enum - - */ -enum { + * enum nvme_id_ctrl_oacs - Flags indicating the optional Admin commands and + * 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. + * @NVME_CTRL_OACS_FORMAT: If set then the controller supports the Format + * NVM command. + * @NVME_CTRL_OACS_FW: If set, then the controller supports the + * Firmware Commit and Firmware Image Download commands. + * @NVME_CTRL_OACS_NS_MGMT: If set, then the controller supports the + * Namespace Management capability + * @NVME_CTRL_OACS_SELF_TEST: If set, then the controller supports the Device + * 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. + * @NVME_CTRL_OACS_VIRT_MGMT: If set, then the controller supports the + * Virtualization Management command. + * @NVME_CTRL_OACS_DBBUF_CFG: If set, then the controller supports the + * Doorbell Buffer Config command. + * @NVME_CTRL_OACS_LBA_STATUS: If set, then the controller supports the Get LBA + * Status capability. + */ +enum nvme_id_ctrl_oacs { NVME_CTRL_OACS_SECURITY = 1 << 0, NVME_CTRL_OACS_FORMAT = 1 << 1, NVME_CTRL_OACS_FW = 1 << 2, @@ -556,18 +796,30 @@ enum { }; /** - * enum - + * enum nvme_id_ctrl_frmw - Flags and values indicates capabilities regarding + * 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. + * @NVME_CTRL_FRMW_FW_ACT_NO_RESET: If set, the controller supports firmware + * activation without a reset. */ -enum { +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, }; /** - * enum - + * 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: */ -enum { +enum nvme_id_ctrl_lpa { NVME_CTRL_LPA_SMART_PER_NS = 1 << 0, NVME_CTRL_LPA_CMD_EFFECTS = 1 << 1, NVME_CTRL_LPA_EXTENDED = 1 << 2, @@ -576,47 +828,82 @@ enum { }; /** - * enum - + * enum nvme_id_ctrl_avscc - Flags indicating the configuration settings for + * 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. */ -enum { +enum nvme_id_ctrl_avscc { NVME_CTRL_AVSCC_AVS = 1 << 0, }; /** - * enum - + * enum nvme_id_ctrl_apsta - Flags indicating the attributes of the autonomous + * power state transition feature. + * @NVME_CTRL_APSTA_APST: If set, then the controller supports autonomous power + * state transitions. */ -enum { +enum nvme_id_ctrl_apsta { NVME_CTRL_APSTA_APST = 1 << 0, }; /** - * enum - + * 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. + * @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_ACCESS_SIZE: Mask to get the value of Access Size */ -enum { +enum nvme_id_ctrl_rpmbs { NVME_CTRL_RPMBS_NR_UNITS = 7 << 0, NVME_CTRL_RPMBS_AUTH_METHOD = 7 << 3, - NVME_CTRL_RPMBS_TOTAL_SIZE = 255 << 16, - NVME_CTRL_RPMBS_ACCESS_SIZE = 255 << 24, + NVME_CTRL_RPMBS_TOTAL_SIZE = 0xff << 16, + NVME_CTRL_RPMBS_ACCESS_SIZE = 0xff << 24, }; /** - * enum - + * enum nvme_id_ctrl_dsto - Flags indicating the optional Device Self-test + * 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. */ -enum { +enum nvme_id_ctrl_dsto { NVME_CTRL_DSTO_ONE_DST = 1 << 0, }; /** - * enum - + * enum nvme_id_ctrl_hctm - Flags indicate the attributes of the host + * 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. */ -enum { +enum nvme_id_ctrl_hctm { NVME_CTRL_HCTMA_HCTM = 1 << 0, }; /** - * enum - + * 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. + * @NVME_CTRL_SANICAP_BES: Block Erase Support. If set, then the controller + * supports the Block Erase sanitize operation. + * @NVME_CTRL_SANICAP_OWS: Overwrite Support. If set, then the controller + * 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. + * @NVME_CTRL_SANICAP_NODMMAS: No-Deallocate Modifies Media After Sanitize, + * mask to extract value. */ -enum { +enum nvme_id_ctrl_sanicap { NVME_CTRL_SANICAP_CES = 1 << 0, NVME_CTRL_SANICAP_BES = 1 << 1, NVME_CTRL_SANICAP_OWS = 1 << 2, @@ -625,9 +912,28 @@ enum { }; /** - * enum - - */ -enum { + * 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. + * @NVME_CTRL_ANACAP_INACCESSIBLE: If set, then the controller is able to + * 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. + * @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. + * @NVME_CTRL_ANACAP_GRPID_MGMT: If set, then the controller supports a + * non-zero value in the ANAGRPID field of + * the Namespace Management command. + */ +enum nvme_id_ctrl_anacap { NVME_CTRL_ANACAP_OPT = 1 << 0, NVME_CTRL_ANACAP_NON_OPT = 1 << 1, NVME_CTRL_ANACAP_INACCESSIBLE = 1 << 2, @@ -638,25 +944,55 @@ enum { }; /** - * enum - + * enum nvme_id_ctrl_sqes - Defines the required and maximum Submission Queue + * 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. + * @NVME_CTRL_SQES_MAX: Mask to get the value of the maximum Submission Queue + * entry size when using the NVM Command Set. */ -enum { - NVME_CTRL_SQES_MIN = 15 << 0, - NVME_CTRL_SQES_MAX = 15 << 4, +enum nvme_id_ctrl_sqes { + NVME_CTRL_SQES_MIN = 0xf << 0, + NVME_CTRL_SQES_MAX = 0xf << 4, }; /** - * enum - + * enum nvme_id_ctrl_cqes - Defines the required and maximum Completion Queue + * 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. + * @NVME_CTRL_CQES_MAX: Mask to get the value of the maximum Completion Queue + * entry size when using the NVM Command Set. */ enum { - NVME_CTRL_CQES_MIN = 15 << 0, - NVME_CTRL_CQES_MAX = 15 << 4, + NVME_CTRL_CQES_MIN = 0xf << 0, + NVME_CTRL_CQES_MAX = 0xf << 4, }; /** - * enum - + * enum nvme_id_ctrl_oncs - This field indicates the optional NVM commands and + * features supported by the controller. + * @NVME_CTRL_ONCS_COMPARE: If set, then the controller supports + * the Compare command. + * @NVME_CTRL_ONCS_WRITE_UNCORRECTABLE: If set, then the controller supports + * the Write Uncorrectable command. + * @NVME_CTRL_ONCS_DSM: If set, then the controller supports + * the Dataset Management command. + * @NVME_CTRL_ONCS_WRITE_ZEROES: If set, then the controller supports + * 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. + * @NVME_CTRL_ONCS_RESERVATIONS: If set, then the controller supports + * reservations. + * @NVME_CTRL_ONCS_TIMESTAMP: If set, then the controller supports + * the Timestamp feature. + * @NVME_CTRL_ONCS_VERIFY: If set, then the controller supports + * the Verify command. */ -enum { +enum nvme_id_ctrl_oncs { NVME_CTRL_ONCS_COMPARE = 1 << 0, NVME_CTRL_ONCS_WRITE_UNCORRECTABLE = 1 << 1, NVME_CTRL_ONCS_DSM = 1 << 2, @@ -668,49 +1004,105 @@ enum { }; /** - * enum - + * enum nvme_id_ctrl_fuses - This field indicates the fused operations that the + * controller supports. + * @NVME_CTRL_FUSES_COMPARE_AND_WRITE: If set, then the controller supports the + * Compare and Write fused operation. */ -enum { +enum nvme_id_ctrl_fuses { NVME_CTRL_FUSES_COMPARE_AND_WRITE = 1 << 0, }; /** - * enum - - */ -enum { + * enum nvme_id_ctrl_fna - This field indicates attributes for the Format NVM + * 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. + * @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. + */ +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, }; /** - * enum - + * enum nvme_id_ctrl_vwc - + * @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. + * @NVME_CTRL_VWC_FLUSH: Mask to get the value of the flush command behavior. */ -enum { +enum nvme_id_ctrl_vwc { NVME_CTRL_VWC_PRESENT = 1 << 0, NVME_CTRL_VWC_FLUSH = 3 << 1, }; /** - * enum - + * enum nvme_id_ctrl_nvscc - This field indicates the configuration settings + * 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. */ -enum { +enum nvme_id_ctrl_nvscc { NVME_CTRL_NVSCC_FMT = 1 << 0, }; /** - * enum - - */ -enum { + * enum nvme_id_ctrl_nwpc - This field indicates the optional namespace write + * 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. + * @NVME_CTRL_NWPC_WRITE_PROTECT_POWER_CYCLE: If set, then the controller + * 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. + */ +enum nvme_id_ctrl_nwpc { NVME_CTRL_NWPC_WRITE_PROTECT = 1 << 0, NVME_CTRL_NWPC_WRITE_PROTECT_POWER_CYCLE= 1 << 1, NVME_CTRL_NWPC_WRITE_PROTECT_PERMANENT = 1 << 2, }; /** - * enum - + * enum nvme_id_ctrl_sgls - This field indicates if SGLs are supported for the + * NVM Command Set and the particular SGL types supported. + * @NVME_CTRL_SGLS_SUPPORTED: + * @NVME_CTRL_SGLS_KEYED: + * @NVME_CTRL_SGLS_BIT_BUCKET: + * @NVME_CTRL_SGLS_MPTR_BYTE_ALIGNED: + * @NVME_CTRL_SGLS_OVERSIZE: + * @NVME_CTRL_SGLS_MPTR_SGL: + * @NVME_CTRL_SGLS_OFFSET: + * @NVME_CTRL_SGLS_TPORT: */ -enum { +enum nvme_id_ctrl_sgls { NVME_CTRL_SGLS_SUPPORTED = 3 << 0, NVME_CTRL_SGLS_KEYED = 1 << 2, NVME_CTRL_SGLS_BIT_BUCKET = 1 << 16, @@ -722,24 +1114,34 @@ enum { }; /** - * enum - + * enum nvme_id_ctrl_fcatt - This field indicates attributes of the controller + * 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. */ -enum { +enum nvme_id_ctrl_fcatt { NVME_CTRL_FCATT_DYNAMIC = 1 << 0, }; /** - * enum - + * enum nvme_id_ctrl_ofcs - Indicate whether the controller supports optional + * fabric commands. + * @NVME_CTRL_OFCS_DISCONNECT: If set, then the controller supports the + * Disconnect command and deletion of individual + * I/O Queues. */ -enum { +enum nvme_id_ctrl_ofcs { NVME_CTRL_OFCS_DISCONNECT = 1 << 0, }; /** - * struct nvme_lbaf - - * @ms: - * @ds: - * @rp: + * 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. + * @ds: LBA Data Size indicates the LBA data size supported, reported as a + * power of two. + * @rp: Relative Performance, see &enum nvme_lbaf_rp. */ struct nvme_lbaf { __le16 ms; @@ -748,13 +1150,17 @@ struct nvme_lbaf { }; /** - * enum - - * @NVME_LBAF_RP_BEST: - * @NVME_LBAF_RP_BETTER: - * @NVME_LBAF_RP_GOOD: - * @NVME_LBAF_RP_DEGRADED: + * enum nvme_lbaf_rp - This field indicates the relative performance of the LBA + * 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 */ -enum { +enum nvme_lbaf_rp { NVME_LBAF_RP_BEST = 0, NVME_LBAF_RP_BETTER = 1, NVME_LBAF_RP_GOOD = 2, @@ -763,41 +1169,91 @@ enum { }; /** - * struct nvme_id_ns - - * @nsze: - * @ncap: - * @nuse: - * @nsfeat: - * @nlbaf: - * @flbas: - * @mc: - * @dpc: - * @dps: - * @nmic: - * @rescap: - * @fpi: - * @dlfeat: - * @nawun: - * @nawupf: - * @nacwu: - * @nabsn: - * @nabo: - * @nabspf: - * @noiob: - * @nvmcap: - * @npwg: - * @npwa: - * @npdg: - * @npda: - * @nows: - * @anagrpid: - * @nsattr: - * @nvmsetid: - * @endgid: - * @nguid: - * @eui64: - * @lbaf: - * @vs: + * 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. + * @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. + * @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. + * @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.labf. + * @flbas: Formatted LBA Size, see &enum nvme_id_ns_flbas. + * @mc: Metadata Capabilities, see &enum nvme_id_ns_mc. + * @dpc: End-to-end Data Protection Capabilities, see &enum + * nvme_id_ns_dpc. + * @dps: End-to-end Data Protection Type Settings, see &enum + * nvme_id_ns_dps. + * @nmic: Namespace Multi-path I/O and Namespace Sharing Capabilities, see + * &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. + * @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. + * @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. + * @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. + * @nabo: Namespace Atomic Boundary Offset indicates the LBA on this + * 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. + * @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. + * @nvmcap: NVM Capacity indicates the total size of the NVM allocated to + * 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. + * @npwa: Namespace Preferred Write Alignment indicates the recommended + * 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. + * @npda: Namespace Preferred Deallocate Alignment indicates the + * 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. + * @anagrpid: ANA Group Identifier indicates the ANA Group Identifier of the + * ANA group of which the namespace is a member. + * @nsattr: Namespace Attributes, see &enum nvme_id_ns_attr. + * @nvmsetid: NVM Set Identifier indicates the NVM Set with which this + * namespace is associated. + * @endgid: Endurance Group Identifier indicates the Endurance Group with + * 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 + * @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 + * remains fixed throughout the life of the namespace and is + * preserved across namespace and controller operations + * @lbaf: LBA Format, see &struct nvme_lbaf. + * @vs: Vendor Specific */ struct nvme_id_ns { __le64 nsze; @@ -840,9 +1296,28 @@ struct nvme_id_ns { }; /** - * enum - - */ -enum { + * 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. + * @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. + * @NVME_NS_FEAT_DULBE: If set, indicates that the controller supports the + * 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. + * @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 + */ +enum nvme_id_nsfeat { NVME_NS_FEAT_THIN = 1 << 0, NVME_NS_FEAT_NATOMIC = 1 << 1, NVME_NS_FEAT_DULBE = 1 << 2, @@ -851,25 +1326,53 @@ enum { }; /** - * enum - + * enum nvme_id_ns_flbas - This field indicates the LBA data size & metadata + * size combination that the namespace has been + * formatted with + * @NVME_NS_FLBAS_LBA_MASK: Mask to get the index of one of the 16 supported + * LBA Formats indicated in &struct nvme_id_ns.lbaf. + * @NVME_NS_FLBAS_META_EXT: Applicable only if format contains metadata. If + * this bit is set, indicates that the metadata is + * transferred at the end of the data LBA, creating an + * extended data LBA. If cleared, indicates that all + * of the metadata for a command is transferred as a + * separate contiguous buffer of data. */ -enum { +enum nvme_id_ns_flbas { NVME_NS_FLBAS_LBA_MASK = 15 << 0, NVME_NS_FLBAS_META_EXT = 1 << 4, }; /** - * enum - + * 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. + * @NVME_NS_MC_SEPARATE: If set, indicates that the namespace supports the + * metadata being transferred as part of an extended data LBA. */ -enum { +enum nvme_id_ns_mc { NVME_NS_MC_EXTENDED = 1 << 0, NVME_NS_MC_SEPARATE = 1 << 1, }; /** - * enum - + * enum nvme_id_ns_dpc - This field indicates the capabilities for the + * end-to-end data protection feature. + * @NVME_NS_DPC_PI_TYPE1: If set, indicates that the namespace supports + * Protection Information Type 1. + * @NVME_NS_DPC_PI_TYPE2: If set, indicates that the namespace supports + * Protection Information Type 2. + * @NVME_NS_DPC_PI_TYPE3: If set, indicates that the namespace supports + * 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. + * @NVME_NS_DPC_PI_LAST: If set, indicates that the namespace supports + * protection information transferred as the last eight + * bytes of metadata. */ -enum { +enum nvme_id_ns_dpc { NVME_NS_DPC_PI_TYPE1 = 1 << 0, NVME_NS_DPC_PI_TYPE2 = 1 << 1, NVME_NS_DPC_PI_TYPE3 = 1 << 2, @@ -878,9 +1381,18 @@ enum { }; /** - * enum - + * enum nvme_id_ns_dps - This field indicates the Type settings for the + * 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. */ -enum { +enum nvme_id_ns_dps { NVME_NS_DPS_PI_NONE = 0, NVME_NS_DPS_PI_TYPE1 = 1, NVME_NS_DPS_PI_TYPE2 = 2, @@ -890,16 +1402,36 @@ enum { }; /** - * enum - + * enum nvme_id_ns_nmic - This field specifies multi-path I/O and 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 */ -enum { +enum nvme_id_ns_nmic { NVME_NS_NMIC_SHARED = 1 << 0, }; /** - * enum - - */ -enum { + * enum nvme_id_ns_rescap - This field indicates the reservation capabilities + * 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. + * @NVME_NS_RESCAP_WERO: If set, indicates that the namespace supports the + * Write Exclusive - Registrants Only reservation type. + * @NVME_NS_RESCAP_EARO: If set, indicates that the namespace supports the + * Exclusive Access - Registrants Only reservation type. + * @NVME_NS_RESCAP_WEAR: If set, indicates that the namespace supports the + * Write Exclusive - All Registrants reservation type. + * @NVME_NS_RESCAP_EAAR: If set, indicates that the namespace supports the + * 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. + */ +enum nvme_id_ns_rescap { NVME_NS_RESCAP_PTPL = 1 << 0, NVME_NS_RESCAP_WE = 1 << 1, NVME_NS_RESCAP_EA = 1 << 2, @@ -911,17 +1443,38 @@ enum { }; /** - * enum - + * 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. + * @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. */ -enum { - NVME_NS_FPI_REMAINING = 127 << 0, +enum nvme_nd_ns_fpi { + NVME_NS_FPI_REMAINING = 0x7f << 0, NVME_NS_FPI_SUPPORTED = 1 << 7, }; /** - * enum - - */ -enum { + * 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 + * cleared to 0h. + * @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 + */ +enum nvme_id_ns_dlfeat { NVME_NS_DLFEAT_RB = 7 << 0, NVME_NS_DLFEAT_RB_NR = 0, NVME_NS_DLFEAT_RB_ALL_0S = 1, @@ -931,14 +1484,23 @@ enum { }; /** - * enum - + * 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. */ -enum { +enum nvme_id_ns_attr { NVME_NS_NSATTR_WRITE_PROTECTED = 1 << 0 }; /** * struct nvme_ns_id_desc - + * @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. + * @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. */ struct nvme_ns_id_desc { __u8 nidt; @@ -948,16 +1510,32 @@ struct nvme_ns_id_desc { }; /** - * enum - + * 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. + * @NVME_NIDT_NGUID: Namespace Globally Unique Identifier, the NID field + * 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. */ -enum { +enum nvme_ns_id_desc_nidt { NVME_NIDT_EUI64 = 1, NVME_NIDT_NGUID = 2, NVME_NIDT_UUID = 3, }; /** - * struct nvme_nvmset_attr - + * struct nvme_nvmset_attr - NVM Set Attributes Entry + * @id: NVM Set Identifier + * @endurance_group_id: Endurance Group Identifier + * @random_4k_read_typical: Random 4 KiB Read Typical indicates the typical + * time to complete a 4 KiB random read in 100 + * nanosecond units when the NVM Set is in a + * Predictable Latency Mode Deterministic Window and + * there is 1 outstanding command per NVM Set. + * @opt_write_size: + * @total_nvmset_cap: + * @unalloc_nvmset_cap: */ struct nvme_nvmset_attr { __le16 id; @@ -972,6 +1550,8 @@ struct nvme_nvmset_attr { /** * struct nvme_id_nvmset_list - + * @nid; + * @ent:; */ struct nvme_id_nvmset_list { __u8 nid; @@ -981,6 +1561,8 @@ struct nvme_id_nvmset_list { /** * struct nvme_id_ns_granularity_desc - + * @namespace_size_granularity: + * @namespace_capacity_granularity: */ struct nvme_id_ns_granularity_desc { __le64 namespace_size_granularity; @@ -989,6 +1571,9 @@ struct nvme_id_ns_granularity_desc { /** * struct nvme_id_ns_granularity_list - + * @attributes: + * @num_descriptors: + * @entry: */ struct nvme_id_ns_granularity_list { __le32 attributes; @@ -1000,6 +1585,8 @@ struct nvme_id_ns_granularity_list { /** * struct nvme_id_uuid_list_entry - + * @header: + * @uuid: */ struct nvme_id_uuid_list_entry { __u8 header; @@ -1009,6 +1596,10 @@ struct nvme_id_uuid_list_entry { /** * enum - + * @NVME_ID_UUID_HDR_ASSOCIATION_MASK: + * @NVME_ID_UUID_ASSOCIATION_NONE: + * @NVME_ID_UUID_ASSOCIATION_VENDOR: + * @NVME_ID_UUID_ASSOCIATION_SUBSYSTEM_VENDOR: */ enum { NVME_ID_UUID_HDR_ASSOCIATION_MASK = 0x3, @@ -1019,6 +1610,7 @@ enum { /** * struct nvme_id_uuid_list - + * @entry: */ struct nvme_id_uuid_list { __u8 rsvd0[32]; @@ -1027,6 +1619,8 @@ struct nvme_id_uuid_list { /** * struct nvme_ctrl_list - + * @num; + * @identifier: */ struct nvme_ctrl_list { __le16 num; @@ -1035,6 +1629,7 @@ struct nvme_ctrl_list { /** * struct nvme_ns_list - + * @ns: */ struct nvme_ns_list { __le32 ns[NVME_ID_NS_LIST_MAX]; @@ -1042,6 +1637,21 @@ struct nvme_ns_list { /** * struct nvme_primary_ctrl_cap - + * @cntlid: + * @portid: + * @crt: + * @vqfrt: + * @vqrfa: + * @vqrfap: + * @vqprt: + * @vqfrsm: + * @vqgran: + * @vifrt: + * @virfa: + * @virfap: + * @viprt: + * @vifrsm: + * @vigran: */ struct nvme_primary_ctrl_cap { __le16 cntlid; @@ -1066,6 +1676,12 @@ struct nvme_primary_ctrl_cap { /** * struct nvme_secondary_ctrl - + * @scid: + * @pcid: + * @scs: + * @vfn: + * @nvq: + * @nvi: */ struct nvme_secondary_ctrl { __le16 scid; @@ -1080,6 +1696,8 @@ struct nvme_secondary_ctrl { /** * struct nvme_secondary_ctrl_list - + * @num; + * @sc_entry: */ struct nvme_secondary_ctrl_list { __u8 num; @@ -1087,10 +1705,6 @@ struct nvme_secondary_ctrl_list { struct nvme_secondary_ctrl sc_entry[NVME_ID_SECONDARY_CTRL_MAX]; }; -/** - * DOC: NVMe Logs - */ - /** * struct nvme_error_log_page - */ @@ -1112,6 +1726,8 @@ struct nvme_error_log_page { /** * enum - + * @NVME_ERR_PEL_BYTE_MASK: + * @NVME_ERR_PEL_BIT_MASK: */ enum { NVME_ERR_PEL_BYTE_MASK = 0xf, @@ -1120,6 +1736,29 @@ enum { /** * struct nvme_smart_log - + * @critical_warning: + * @temperature: + * @avail_spare: + * @spare_thresh: + * @percent_used: + * @endu_grp_crit_warn_sumry: + * @data_units_read: + * @data_units_written: + * @host_reads: + * @host_writes: + * @ctrl_busy_time: + * @power_cycles: + * @power_on_hours: + * @unsafe_shutdowns: + * @media_errors: + * @num_err_log_entries: + * @warning_temp_time: + * @critical_comp_time: + * @temp_sensor: + * @thm_temp1_trans_count: + * @thm_temp2_trans_count: + * @thm_temp1_total_time: + * @thm_temp2_total_time: */ struct nvme_smart_log { __u8 critical_warning; @@ -1151,6 +1790,12 @@ struct nvme_smart_log { /** * enum - + * @NVME_SMART_CRIT_SPARE: + * @NVME_SMART_CRIT_TEMPERATURE: + * @NVME_SMART_CRIT_DEGRADED: + * @NVME_SMART_CRIT_MEDIA: + * @NVME_SMART_CRIT_VOLATILE_MEMORY: + * @NVME_SMART_CRIT_PMR_RO: */ enum { NVME_SMART_CRIT_SPARE = 1 << 0, @@ -1163,6 +1808,9 @@ enum { /** * enum - + * @NVME_SMART_EGCW_SPARE: + * @NVME_SMART_EGCW_DEGRADED: + * @NVME_SMART_EGCW_RO: */ enum { NVME_SMART_EGCW_SPARE = 1 << 0, @@ -1172,6 +1820,7 @@ enum { /** * struct nvme_frs - + * @frs: */ struct nvme_frs { char frs[8]; @@ -1179,6 +1828,8 @@ struct nvme_frs { /** * struct nvme_firmware_slot - + * @afi: + * @frs: */ struct nvme_firmware_slot { __u8 afi; @@ -1189,6 +1840,8 @@ struct nvme_firmware_slot { /** * struct nvme_cmd_effects_log - + * @acs: + * @iocs: */ struct nvme_cmd_effects_log { __le32 acs[256]; @@ -1198,6 +1851,13 @@ struct nvme_cmd_effects_log { /** * enum - + * @NVME_CMD_EFFECTS_CSUPP: + * @NVME_CMD_EFFECTS_LBCC: + * @NVME_CMD_EFFECTS_NCC: + * @NVME_CMD_EFFECTS_NIC: + * @NVME_CMD_EFFECTS_CCC: + * @NVME_CMD_EFFECTS_CSE_MASK: + * @NVME_CMD_EFFECTS_UUID_SEL: */ enum { NVME_CMD_EFFECTS_CSUPP = 1 << 0, @@ -1211,6 +1871,15 @@ enum { /** * struct nvme_st_result - + * @dsts: + * @seg: + * @vdi: + * @poh: + * @nsid: + * @flba: + * @sct: + * @sc: + * @vs: */ struct nvme_st_result { __u8 dsts; @@ -1227,11 +1896,22 @@ struct nvme_st_result { /** * enum - + * @NVME_ST_RESULT_NO_ERR: + * @NVME_ST_RESULT_ABORTED: + * @NVME_ST_RESULT_CLR: + * @NVME_ST_RESULT_NS_REMOVED: + * @NVME_ST_RESULT_ABORTED_FORMAT: + * @NVME_ST_RESULT_FATAL_ERR: + * @NVME_ST_RESULT_UNKNOWN_SEG_FAIL: + * @NVME_ST_RESULT_KNOWN_SEG_FAIL: + * @NVME_ST_RESULT_ABORTED_UNKNOWN: + * @NVME_ST_RESULT_ABORTED_SANITIZE: + * @NVME_ST_RESULT_NOT_USED: */ enum { NVME_ST_RESULT_NO_ERR = 0x0, NVME_ST_RESULT_ABORTED = 0x1, - NVME_ST_RESULT_CLR = 0x2, + NVME_ST_RESULT_CLR = 0x2, NVME_ST_RESULT_NS_REMOVED = 0x3, NVME_ST_RESULT_ABORTED_FORMAT = 0x4, NVME_ST_RESULT_FATAL_ERR = 0x5, @@ -1244,6 +1924,10 @@ enum { /** * enum - + * @NVME_ST_OPERATION_NONE: + * @NVME_ST_OPERATION_SHORT: + * @NVME_ST_OPERATION_EXTENDED: + * @NVME_ST_OPERATION_VS: */ enum { NVME_ST_OPERATION_NONE = 0x0, @@ -1254,6 +1938,10 @@ enum { /** * enum - + * @NVME_ST_VALID_DIAG_INFO_NSID: + * @NVME_ST_VALID_DIAG_INFO_FLBA: + * @NVME_ST_VALID_DIAG_INFO_SCT: + * @NVME_ST_VALID_DIAG_INFO_SC: */ enum { NVME_ST_VALID_DIAG_INFO_NSID = 1 << 0, @@ -1265,6 +1953,9 @@ enum { /** * struct nvme_self_test_log - + * @current_operation: + * @completion: + * @result: */ struct nvme_self_test_log { __u8 current_operation; @@ -1275,6 +1966,15 @@ struct nvme_self_test_log { /** * struct nvme_telemetry_log - + * @lpi: + * @ieee: + * @dalb1: + * @dalb2: + * @dalb3: + * @ctrlavail: + * @ctrldgn: + * @rsnident: + * @telemetry_dataarea: */ struct nvme_telemetry_log { __u8 lpi; @@ -1292,6 +1992,18 @@ struct nvme_telemetry_log { /** * struct nvme_endurance_group_log - + * @critical_warning: + * @avl_spare: + * @avl_spare_threshold: + * @percent_used: + * @endurance_estimate: + * @data_units_read: + * @data_units_written: + * @media_units_written: + * @host_read_cmds: + * @host_write_cmds: + * @media_data_integrity_err: + * @num_err_info_log_entries: */ struct nvme_endurance_group_log { __u8 critical_warning; @@ -1313,6 +2025,9 @@ struct nvme_endurance_group_log { /** * enum - + * @NVME_EG_CRITICAL_WARNING_SPARE: + * @NVME_EG_CRITICAL_WARNING_DEGRADED: + * @NVME_EG_CRITICAL_WARNING_READ_ONLY: */ enum nvme_eg_critical_warning_flags { NVME_EG_CRITICAL_WARNING_SPARE = 1 << 0, @@ -1322,6 +2037,8 @@ enum nvme_eg_critical_warning_flags { /** * struct nvme_aggregate_endurance_group_event - + * @num_entries: + * @entries: */ struct nvme_aggregate_endurance_group_event { __le64 num_entries; @@ -1330,6 +2047,16 @@ struct nvme_aggregate_endurance_group_event { /** * struct nvme_nvmset_predictable_lat_log - + * @status: + * @event_type: + * @dtwin_rt: + * @dtwin_wt: + * @dtwin_tmax: + * @dtwin_tmin_hi: + * @dtwin_tmin_lo: + * @dtwin_re: + * @dtwin_we: + * @dtwin_te: */ struct nvme_nvmset_predictable_lat_log { __u8 status; @@ -1350,6 +2077,9 @@ struct nvme_nvmset_predictable_lat_log { /** * enum - + * @NVME_NVMSET_PL_STATUS_DISABLED: + * @NVME_NVMSET_PL_STATUS_DTWIN: + * @NVME_NVMSET_PL_STATUS_NDWIN: */ enum { NVME_NVMSET_PL_STATUS_DISABLED = 0, @@ -1359,6 +2089,11 @@ enum { /** * enum - + * @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_EVENT_DTWIN_READ_WARN = 1 << 0, @@ -1370,6 +2105,8 @@ enum { /** * struct nvme_aggregate_predictable_lat_event - + * @num_entries: + * @entries: */ struct nvme_aggregate_predictable_lat_event { __le64 num_entries; @@ -1378,6 +2115,11 @@ struct nvme_aggregate_predictable_lat_event { /** * struct nvme_ana_group_desc - + * @grpid: + * @nnsids: + * @chgcnt: + * @state: + * @nsids: */ struct nvme_ana_group_desc { __le32 grpid; @@ -1390,6 +2132,11 @@ struct nvme_ana_group_desc { /** * enum - + * @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_OPTIMIZED = 0x1, @@ -1401,6 +2148,9 @@ enum { /** * struct nvme_ana_log - + * @chgcnt: + * @ngrps: + * @descs: */ struct nvme_ana_log { __le64 chgcnt; @@ -1411,6 +2161,19 @@ struct nvme_ana_log { /** * struct nvme_persistent_event_log - + * @lid: + * @ttl: + * @rv: + * @lht: + * @ts: + * @poh: + * @pcc: + * @vid: + * @ssvid: + * @sn: + * @mn: + * @subnqn: + * @seb: */ struct nvme_persistent_event_log { __u8 lid; @@ -1433,6 +2196,8 @@ struct nvme_persistent_event_log { /** * struct nvme_lba_rd - + * @rslba: + * @rnlb: */ struct nvme_lba_rd { __le64 rslba; @@ -1442,6 +2207,10 @@ struct nvme_lba_rd { /** * struct nvme_lbas_ns_element - + * @neid: + * @nrld: + * @ratype: + * @lba_rd: */ struct nvme_lbas_ns_element { __le32 neid; @@ -1463,6 +2232,11 @@ enum nvme_lba_status_atype { /** * struct nvme_lba_status_log - + * @lslplen: + * @nlslne: + * @estulb: + * @lsgc: + * @elements: */ struct nvme_lba_status_log { __le32 lslplen; @@ -1475,6 +2249,8 @@ struct nvme_lba_status_log { /** * struct nvme_eg_event_aggregate_log - + * @nr_entries: + * @egids: */ struct nvme_eg_event_aggregate_log { __le64 nr_entries; @@ -1483,6 +2259,10 @@ struct nvme_eg_event_aggregate_log { /** * struct nvme_resv_notification_log - + * @lpc: + * @rnlpt: + * @nalp: + * @nsid: */ struct nvme_resv_notification_log { __le64 lpc; @@ -1495,6 +2275,10 @@ struct nvme_resv_notification_log { /** * enum - + * @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_EMPTY = 0, @@ -1505,6 +2289,15 @@ enum { /** * struct nvme_sanitize_log_page - + * @sprog: + * @sstat: + * @scdw10: + * @eto: + * @etbe: + * @etce: + * @etond: + * @etbend: + * @etcend: */ struct nvme_sanitize_log_page { __le16 sprog; @@ -1519,12 +2312,13 @@ struct nvme_sanitize_log_page { __u8 rsvd32[480]; }; -/** - * DOC: NVMe Directives - */ - /** * enum - + * @NVME_SANITIZE_SSTAT_NEVER_SANITIZED: + * @NVME_SANITIZE_SSTAT_COMPLETE_SUCCESS: + * @NVME_SANITIZE_SSTAT_IN_PROGESS: + * @NVME_SANITIZE_SSTAT_COMPLETED_FAILED: + * @NVME_SANITIZE_SSTAT_ND_COMPLETE_SUCCESS: */ enum { NVME_SANITIZE_SSTAT_NEVER_SANITIZED = 0, @@ -1536,17 +2330,23 @@ enum { /** * struct nvme_lba_status_desc - + * @dslba: + * @nlb: + * @status: */ struct nvme_lba_status_desc { - __le64 dslba; - __le32 nlb; - __u8 rsvd12; - __u8 status; - __u8 rsvd14[2]; + __le64 dslba; + __le32 nlb; + __u8 rsvd12; + __u8 status; + __u8 rsvd14[2]; }; /** * struct nvme_lba_status - + * @nlsd: + * @cmpc: + * @descs: */ struct nvme_lba_status { __le32 nlsd; @@ -1555,345 +2355,122 @@ struct nvme_lba_status { struct nvme_lba_status_desc descs[]; }; - -/** - * DOC: NVMe Management Interface - */ - /** - * struct nvme_mi_read_nvm_ss_info - + * struct nvme_feat_auto_pst - + * @apst_entry: */ -struct nvme_mi_read_nvm_ss_info { - __u8 nump; - __u8 mjr; - __u8 mnr; - __u8 rsvd3[29]; +struct nvme_feat_auto_pst { + __le64 apst_entry[32]; }; /** - * struct nvme_mi_port_pcie - + * struct nvme_timestamp - + * timestamp: + * @attr: */ -struct nvme_mi_port_pcie { - __u8 mps; - __u8 sls; - __u8 cls; - __u8 mlw; - __u8 nlw; - __u8 pn; - __u8 rsvd14[18]; +struct nvme_timestamp { + __u8 timestamp[6]; + __u8 attr; + __u8 rsvd; }; /** - * struct nvme_mi_port_smb - + * struct nvme_lba_range_type_entry - + * @type: + * @attributes: + * @slba: + * @nlb: + * @guid: */ -struct nvme_mi_port_smb { - __u8 vpd_addr; - __u8 mvpd_freq; - __u8 mme_addr; - __u8 mme_freq; - __u8 nvmebm; - __u8 rsvd13[19]; +struct nvme_lba_range_type_entry { + __u8 type; + __u8 attributes; + __u8 rsvd2[14]; + __u64 slba; + __u64 nlb; + __u8 guid[16]; + __u8 rsvd48[16]; }; /** - * struct nvme_mi_read_port_info - + * enum - + * @NVME_LBART_TYPE_GP: + * @NVME_LBART_TYPE_FS: + * @NVME_LBART_TYPE_RAID: + * @NVME_LBART_TYPE_CACHE: + * @NVME_LBART_TYPE_SWAP: + * @NVME_LBART_ATTRIB_TEMP: + * @NVME_LBART_ATTRIB_HIDE: */ -struct nvme_mi_read_port_info { - __u8 portt; - __u8 rsvd1; - __le16 mmctptus; - __le32 meb; - union { - struct nvme_mi_port_pcie pcie; - struct nvme_mi_port_smb smb; - }; +enum { + NVME_LBART_TYPE_GP = 0, + NVME_LBART_TYPE_FS = 1, + NVME_LBART_TYPE_RAID = 2, + NVME_LBART_TYPE_CACHE = 3, + NVME_LBART_TYPE_SWAP = 4, + NVME_LBART_ATTRIB_TEMP = 1 << 0, + NVME_LBART_ATTRIB_HIDE = 1 << 1, }; /** - * struct nvme_mi_read_ctrl_info - + * struct nvme_lba_range_type - + * @entry: */ -struct nvme_mi_read_ctrl_info { - __u8 portid; - __u8 rsvd1[4]; - __u8 prii; - __le16 pri; - __le16 vid; - __le16 did; - __le16 ssvid; - __le16 ssid; - __u8 rsvd16[16]; +struct nvme_lba_range_type { + struct nvme_lba_range_type_entry entry[NVME_FEAT_LBA_RANGE_MAX]; }; /** - * struct nvme_mi_osc - + * struct nvme_plm_config - + * @ee; + * @dtwinrt; + * @dtwinwt; + * @dtwintt; */ -struct nvme_mi_osc { - __u8 type; - __u8 opc; +struct nvme_plm_config { + __le16 ee; + __u8 rsvd2[30]; + __le64 dtwinrt; + __le64 dtwinwt; + __le64 dtwintt; + __u8 rsvd56[456]; }; /** - * struct nvme_mi_read_sc_list - + * struct nvme_feat_host_behavior - + * @acre: */ -struct nvme_mi_read_sc_list { - __le16 numcmd; - struct nvme_mi_osc cmds[]; +struct nvme_feat_host_behavior { + __u8 acre; + __u8 resv1[511]; }; /** - * struct nvme_mi_nvm_ss_health_status - + * enum - + * @NVME_ENABLE_ACRE: */ -struct nvme_mi_nvm_ss_health_status { - __u8 nss; - __u8 sw; - __u8 ctemp; - __u8 pdlu; - __le16 ccs; - __u8 rsvd8[2]; +enum { + NVME_ENABLE_ACRE = 1 << 0, }; /** - * enum - + * struct nvme_dsm_range - + * @cattr: + * @nlb: + * @slba: */ -enum { - 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_dsm_range { + __le32 cattr; + __le32 nlb; + __le64 slba; }; /** - * struct nvme_mi_ctrl_heal_status - - */ -struct nvme_mi_ctrl_heal_status { - __le16 ctlid; - __le16 csts; - __le16 ctemp; - __u8 pdlu; - __u8 spare; - __u8 cwarn; - __u8 rsvd9[7]; -}; - -/** - * enum - - */ -enum { - NVME_MI_CSTS_RDY = 1 << 0, - NVME_MI_CSTS_CFS = 1 << 1, - NVME_MI_CSTS_SHST = 1 << 2, - NVME_MI_CSTS_NSSRO = 1 << 4, - NVME_MI_CSTS_CECO = 1 << 5, - NVME_MI_CSTS_NAC = 1 << 6, - NVME_MI_CSTS_FA = 1 << 7, - NVME_MI_CWARN_ST = 1 << 0, - NVME_MI_CWARN_TAUT = 1 << 1, - NVME_MI_CWARN_RD = 1 << 2, - NVME_MI_CWARN_RO = 1 << 3, - NVME_MI_CWARN_VMBF = 1 << 4, -}; - -/** - * struct nvme_mi_vpd_mra - - */ -struct nvme_mi_vpd_mra { - __u8 nmravn; - __u8 ff; - __u8 rsvd7[6]; - __u8 i18vpwr; - __u8 m18vpwr; - __u8 i33vpwr; - __u8 m33vpwr; - __u8 rsvd17; - __u8 m33vapsr; - __u8 i5vapsr; - __u8 m5vapsr; - __u8 i12vapsr; - __u8 m12vapsr; - __u8 mtl; - __u8 tnvmcap[16]; - __u8 rsvd37[27]; -}; - -/** - * struct nvme_mi_vpd_ppmra - - */ -struct nvme_mi_vpd_ppmra { - __u8 nppmravn; - __u8 pn; - __u8 ppi; - __u8 ls; - __u8 mlw; - __u8 mctp; - __u8 refccap; - __u8 pi; - __u8 rsvd13[3]; -}; - -/** - * struct nvme_mi_vpd_telem - - */ -struct nvme_mi_vpd_telem { - __u8 type; - __u8 rev; - __u8 len; - __u8 data[0]; -}; - -/** - * enum - - */ -enum { - NVME_MI_ELEM_EED = 1, - NVME_MI_ELEM_USCE = 2, - NVME_MI_ELEM_ECED = 3, - NVME_MI_ELEM_LED = 4, - NVME_MI_ELEM_SMBMED = 5, - NVME_MI_ELEM_PCIESED = 6, - NVME_MI_ELEM_NVMED = 7, -}; - -/** - * struct nvme_mi_vpd_tra - - */ -struct nvme_mi_vpd_tra { - __u8 vn; - __u8 rsvd6; - __u8 ec; - struct nvme_mi_vpd_telem elems[0]; -}; - -/** - * struct nvme_mi_vpd_mr_common - - */ -struct nvme_mi_vpd_mr_common { - __u8 type; - __u8 rf; - __u8 rlen; - __u8 rchksum; - __u8 hchksum; - - union { - struct nvme_mi_vpd_mra nmra; - struct nvme_mi_vpd_ppmra ppmra; - struct nvme_mi_vpd_tra tmra; - }; -}; - -/** - * struct nvme_mi_vpd_hdr - - */ -struct nvme_mi_vpd_hdr { - __u8 ipmiver; - __u8 iuaoff; - __u8 ciaoff; - __u8 biaoff; - __u8 piaoff; - __u8 mrioff; - __u8 rsvd6; - __u8 chchk; - __u8 vpd[]; -}; - -/** - * DOC: NVMe Features - */ - -/** - * struct nvme_feat_auto_pst - - */ -struct nvme_feat_auto_pst { - __le64 apst_entry[32]; -}; - -/** - * struct nvme_timestamp - - */ -struct nvme_timestamp { - __u8 timestamp[6]; - __u8 attr; - __u8 rsvd; -}; - -/** - * struct nvme_lba_range_type_entry - - */ -struct nvme_lba_range_type_entry { - __u8 type; - __u8 attributes; - __u8 rsvd2[14]; - __u64 slba; - __u64 nlb; - __u8 guid[16]; - __u8 rsvd48[16]; -}; - -/** - * enum - - */ -enum { - NVME_LBART_TYPE_GP = 0, - NVME_LBART_TYPE_FS = 1, - NVME_LBART_TYPE_RAID = 2, - NVME_LBART_TYPE_CACHE = 3, - NVME_LBART_TYPE_SWAP = 4, - NVME_LBART_ATTRIB_TEMP = 1 << 0, - NVME_LBART_ATTRIB_HIDE = 1 << 1, -}; - -/** - * struct nvme_lba_range_type - - */ -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 { - __le16 ee; - __u8 rsvd2[30]; - __le64 dtwinrt; - __le64 dtwinwt; - __le64 dtwintt; - __u8 rsvd56[456]; -}; - -/** - * struct nvme_feat_host_behavior - - */ -struct nvme_feat_host_behavior { - __u8 acre; - __u8 resv1[511]; -}; - -/** - * enum - - */ -enum { - NVME_ENABLE_ACRE = 1 << 0, -}; - -/** - * struct nvme_dsm_range - - */ -struct nvme_dsm_range { - __le32 cattr; - __le32 nlb; - __le64 slba; -}; - -/** - * struct nvme_registered_ctrl - + * struct nvme_registered_ctrl - + * @cntlid: + * @rcsts: + * @hostid: + * @rkey: */ struct nvme_registered_ctrl { __le16 cntlid; @@ -1905,6 +2482,10 @@ struct nvme_registered_ctrl { /** * struct nvme_registered_ctrl_ext - + * @cntlid: + * @rcsts: + * @rkey: + * @hostid: */ struct nvme_registered_ctrl_ext { __le16 cntlid; @@ -1916,7 +2497,13 @@ struct nvme_registered_ctrl_ext { }; /** - * struct nvme_reservation_status - + * struct nvme_reservation_status -{ + * @gen: + * @rtype: + * @regctl: + * @ptpls: + * @regctl_eds: + * @regctl_ds: */ struct nvme_reservation_status { __le32 gen; @@ -2194,9 +2781,23 @@ enum nvme_subsys_type { #define NVMF_TSAS_SIZE 256 /** - * struct nvmf_disc_log_entry - - * - * Discovery log page entry + * struct nvmf_disc_log_entry - Discovery log page entry + * @trtype: + * @adrfam: + * @subtype: + * @treq: + * @portid: + * @cntlid: + * @asqsz: + * @trsvcid: + * @subnqn: + * @traddr: + * @common: + * @qptype: + * @prtype: + * @cms: + * @pkey: + * @sectype: */ struct nvmf_disc_log_entry { __u8 trtype; @@ -2228,14 +2829,12 @@ struct nvmf_disc_log_entry { }; /** - * enum - + * enum - Transport Type codes for Discovery Log Page entry TRTYPE field * @NVMF_TRTYPE_UNSPECIFIED: Not indicated * @NVMF_TRTYPE_RDMA: RDMA * @NVMF_TRTYPE_FC: Fibre Channel * @NVMF_TRTYPE_TCP: TCP * @NVMF_TRTYPE_LOOP: Reserved for host usage - * - * Transport Type codes for Discovery Log Page entry TRTYPE field */ enum { NVMF_TRTYPE_UNSPECIFIED = 0, @@ -2247,14 +2846,12 @@ enum { }; /** - * enum - + * enum - Address Family codes for Discovery Log Page entry ADRFAM field * @NVMF_ADDR_FAMILY_PCI: PCIe * @NVMF_ADDR_FAMILY_IP4: IPv4 * @NVMF_ADDR_FAMILY_IP6: IPv6 * @NVMF_ADDR_FAMILY_IB: InfiniBand * @NVMF_ADDR_FAMILY_FC: Fibre Channel - * - * Address Family codes for Discovery Log Page entry ADRFAM field */ enum { NVMF_ADDR_FAMILY_PCI = 0, @@ -2265,13 +2862,11 @@ enum { }; /** - * enum - + * enum - Transport Requirements codes for Discovery Log Page entry TREQ field * @NVMF_TREQ_NOT_SPECIFIED: Not specified * @NVMF_TREQ_REQUIRED: Required * @NVMF_TREQ_NOT_REQUIRED: Not Required * @NVMF_TREQ_DISABLE_SQFLOW: SQ flow control disable supported - * - * Transport Requirements codes for Discovery Log Page entry TREQ field */ enum { NVMF_TREQ_NOT_SPECIFIED = 0, @@ -2281,12 +2876,10 @@ enum { }; /** - * enum - + * enum - RDMA QP Service Type codes for Discovery Log Page entry TSAS + * RDMA_QPTYPE field * @NVMF_RDMA_QPTYPE_CONNECTED: Reliable Connected * @NVMF_RDMA_QPTYPE_DATAGRAM: Reliable Datagram - * - * RDMA QP Service Type codes for Discovery Log Page entry TSAS - * RDMA_QPTYPE field */ enum { NVMF_RDMA_QPTYPE_CONNECTED = 1, @@ -2294,15 +2887,13 @@ enum { }; /** - * enum - - * @NVMF_RDMA_PRTYPE_NOT_SPECIFIED: No Provider Specified - * @NVMF_RDMA_PRTYPE_IB: InfiniBand - * @NVMF_RDMA_PRTYPE_ROCE: InfiniBand RoCE - * @NVMF_RDMA_PRTYPE_ROCEV2: InfiniBand RoCEV2 - * @NVMF_RDMA_PRTYPE_IWARP: iWARP - * - * RDMA Provider Type codes for Discovery Log Page entry TSAS - * RDMA_PRTYPE field + * enum - RDMA Provider Type codes for Discovery Log Page entry TSAS + * RDMA_PRTYPE field + * @NVMF_RDMA_PRTYPE_NOT_SPECIFIED: No Provider Specified + * @NVMF_RDMA_PRTYPE_IB: InfiniBand + * @NVMF_RDMA_PRTYPE_ROCE: InfiniBand RoCE + * @NVMF_RDMA_PRTYPE_ROCEV2: InfiniBand RoCEV2 + * @NVMF_RDMA_PRTYPE_IWARP: iWARP */ enum { NVMF_RDMA_PRTYPE_NOT_SPECIFIED = 1, @@ -2313,11 +2904,10 @@ enum { }; /** - * enum - - * @NVMF_RDMA_CMS_RDMA_CM: Sockets based endpoint addressing + * enum - RDMA Connection Management Service Type codes for Discovery Log Page + * entry TSAS RDMA_CMS field + * @NVMF_RDMA_CMS_RDMA_CM: Sockets based endpoint addressing * - * RDMA Connection Management Service Type codes for Discovery Log Page - * entry TSAS RDMA_CMS field */ enum { NVMF_RDMA_CMS_RDMA_CM = 1, @@ -2325,8 +2915,8 @@ enum { /** * enum - - * @NVMF_TCP_SECTYPE_NONE: No Security - * @NVMF_TCP_SECTYPE_TLS: Transport Layer Security + * @NVMF_TCP_SECTYPE_NONE: No Security + * @NVMF_TCP_SECTYPE_TLS: Transport Layer Security */ enum { NVMF_TCP_SECTYPE_NONE = 0, @@ -2335,6 +2925,10 @@ enum { /** * struct nvmf_discovery_log - + * @genctr: + * @numrec: + * @recfmt: + * @entries: */ struct nvmf_discovery_log { __le64 genctr; @@ -2346,6 +2940,10 @@ struct nvmf_discovery_log { /** * struct nvmf_connect_data - + * @hostid: + * @cntlid: + * @subsysnqn + * @hostnqn */ struct nvmf_connect_data { __u8 hostid[16]; @@ -2356,6 +2954,365 @@ struct nvmf_connect_data { char resv5[256]; }; +/** + * struct nvme_mi_read_nvm_ss_info - + * @nump: + * @mjr: + * @mnr: + */ +struct nvme_mi_read_nvm_ss_info { + __u8 nump; + __u8 mjr; + __u8 mnr; + __u8 rsvd3[29]; +}; + +/** + * struct nvme_mi_port_pcie - + * @mps: + * @sls: + * @cls: + * @mlw: + * @nlw: + * @pn: + */ +struct nvme_mi_port_pcie { + __u8 mps; + __u8 sls; + __u8 cls; + __u8 mlw; + __u8 nlw; + __u8 pn; + __u8 rsvd14[18]; +}; + +/** + * struct nvme_mi_port_smb - + * @vpd_addr: + * @mvpd_freq: + * @mme_addr: + * @mme_freq: + * @nvmebm: + */ +struct nvme_mi_port_smb { + __u8 vpd_addr; + __u8 mvpd_freq; + __u8 mme_addr; + __u8 mme_freq; + __u8 nvmebm; + __u8 rsvd13[19]; +}; + +/** + * struct nvme_mi_read_port_info - + * @portt: + * @mmctptus; + * @meb: + * @pcie: + * @smb: + */ +struct nvme_mi_read_port_info { + __u8 portt; + __u8 rsvd1; + __le16 mmctptus; + __le32 meb; + union { + struct nvme_mi_port_pcie pcie; + struct nvme_mi_port_smb smb; + }; +}; + +/** + * struct nvme_mi_read_ctrl_info - + * @portid; + * @prii; + * @pri; + * @vid; + * @did; + * @ssvid; + * @ssid; + */ +struct nvme_mi_read_ctrl_info { + __u8 portid; + __u8 rsvd1[4]; + __u8 prii; + __le16 pri; + __le16 vid; + __le16 did; + __le16 ssvid; + __le16 ssid; + __u8 rsvd16[16]; +}; + +/** + * struct nvme_mi_osc - + * @type; + * @opc; + */ +struct nvme_mi_osc { + __u8 type; + __u8 opc; +}; + +/** + * struct nvme_mi_read_sc_list - + * @numcmd: + * @cmds: + */ +struct nvme_mi_read_sc_list { + __le16 numcmd; + struct nvme_mi_osc cmds[]; +}; + +/** + * struct nvme_mi_nvm_ss_health_status - + * @nss: + * @sw: + * @ctemp: + * @pdlu: + * @ccs: + */ +struct nvme_mi_nvm_ss_health_status { + __u8 nss; + __u8 sw; + __u8 ctemp; + __u8 pdlu; + __le16 ccs; + __u8 rsvd8[2]; +}; + +/** + * enum - + * @NVME_MI_CCS_RDY: + * @NVME_MI_CSS_CFS: + * @NVME_MI_CSS_SHST: + * @NVME_MI_CSS_NSSRO: + * @NVME_MI_CSS_CECO: + * @NVME_MI_CSS_NAC: + * @NVME_MI_CSS_FA: + * @NVME_MI_CSS_CSTS: + * @NVME_MI_CSS_CTEMP: + * @NVME_MI_CSS_PDLU: + * @NVME_MI_CSS_SPARE: + * @NVME_MI_CSS_CCWARN: + */ +enum { + 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_heal_status - + * @ctlid: + * @csts: + * @ctemp: + * @pdlu: + * @spare: + * @cwarn: + */ +struct nvme_mi_ctrl_heal_status { + __le16 ctlid; + __le16 csts; + __le16 ctemp; + __u8 pdlu; + __u8 spare; + __u8 cwarn; + __u8 rsvd9[7]; +}; + +/** + * enum - + * @NVME_MI_CSTS_RDY: + * @NVME_MI_CSTS_CFS: + * @NVME_MI_CSTS_SHST: + * @NVME_MI_CSTS_NSSRO: + * @NVME_MI_CSTS_CECO: + * @NVME_MI_CSTS_NAC: + * @NVME_MI_CSTS_FA: + * @NVME_MI_CWARN_ST: + * @NVME_MI_CWARN_TAUT: + * @NVME_MI_CWARN_RD: + * @NVME_MI_CWARN_RO: + * @NVME_MI_CWARN_VMBF: + */ +enum { + NVME_MI_CSTS_RDY = 1 << 0, + NVME_MI_CSTS_CFS = 1 << 1, + NVME_MI_CSTS_SHST = 1 << 2, + NVME_MI_CSTS_NSSRO = 1 << 4, + NVME_MI_CSTS_CECO = 1 << 5, + NVME_MI_CSTS_NAC = 1 << 6, + NVME_MI_CSTS_FA = 1 << 7, + NVME_MI_CWARN_ST = 1 << 0, + NVME_MI_CWARN_TAUT = 1 << 1, + NVME_MI_CWARN_RD = 1 << 2, + NVME_MI_CWARN_RO = 1 << 3, + NVME_MI_CWARN_VMBF = 1 << 4, +}; + +/** + * struct nvme_mi_vpd_mra - + * @nmravn; + * @ff; + * @i18vpwr; + * @m18vpwr; + * @i33vpwr; + * @m33vpwr; + * @m33vapsr; + * @i5vapsr; + * @m5vapsr; + * @i12vapsr; + * @m12vapsr; + * @mtl; + * @tnvmcap[16]; + */ +struct nvme_mi_vpd_mra { + __u8 nmravn; + __u8 ff; + __u8 rsvd7[6]; + __u8 i18vpwr; + __u8 m18vpwr; + __u8 i33vpwr; + __u8 m33vpwr; + __u8 rsvd17; + __u8 m33vapsr; + __u8 i5vapsr; + __u8 m5vapsr; + __u8 i12vapsr; + __u8 m12vapsr; + __u8 mtl; + __u8 tnvmcap[16]; + __u8 rsvd37[27]; +}; + +/** + * struct nvme_mi_vpd_ppmra - + * @nppmravn: + * @pn: + * @ppi: + * @ls: + * @mlw: + * @mctp: + * @refccap: + * @pi: + */ +struct nvme_mi_vpd_ppmra { + __u8 nppmravn; + __u8 pn; + __u8 ppi; + __u8 ls; + __u8 mlw; + __u8 mctp; + __u8 refccap; + __u8 pi; + __u8 rsvd13[3]; +}; + +/** + * struct nvme_mi_vpd_telem - + * @type: + * @rev: + * @len: + * @data: + */ +struct nvme_mi_vpd_telem { + __u8 type; + __u8 rev; + __u8 len; + __u8 data[0]; +}; + +/** + * enum - + * @NVME_MI_ELEM_EED: + * @NVME_MI_ELEM_USCE: + * @NVME_MI_ELEM_ECED: + * @NVME_MI_ELEM_LED: + * @NVME_MI_ELEM_SMBMED: + * @NVME_MI_ELEM_PCIESED: + * @NVME_MI_ELEM_NVMED: + */ +enum { + NVME_MI_ELEM_EED = 1, + NVME_MI_ELEM_USCE = 2, + NVME_MI_ELEM_ECED = 3, + NVME_MI_ELEM_LED = 4, + NVME_MI_ELEM_SMBMED = 5, + NVME_MI_ELEM_PCIESED = 6, + NVME_MI_ELEM_NVMED = 7, +}; + +/** + * struct nvme_mi_vpd_tra - + * @vn: + * @ec: + * @elems: + */ +struct nvme_mi_vpd_tra { + __u8 vn; + __u8 rsvd6; + __u8 ec; + struct nvme_mi_vpd_telem elems[0]; +}; + +/** + * struct nvme_mi_vpd_mr_common - + * @type; + * @rf; + * @rlen; + * @rchksum; + * @hchksum; +nmra; + * @ppmra; + * @tmra; + */ +struct nvme_mi_vpd_mr_common { + __u8 type; + __u8 rf; + __u8 rlen; + __u8 rchksum; + __u8 hchksum; + + union { + struct nvme_mi_vpd_mra nmra; + struct nvme_mi_vpd_ppmra ppmra; + struct nvme_mi_vpd_tra tmra; + }; +}; + +/** + * struct nvme_mi_vpd_hdr - + * @ipmiver: + * @iuaoff: + * @ciaoff: + * @biaoff: + * @piaoff: + * @mrioff: + * @chchk: + * @vpd: + */ +struct nvme_mi_vpd_hdr { + __u8 ipmiver; + __u8 iuaoff; + __u8 ciaoff; + __u8 biaoff; + __u8 piaoff; + __u8 mrioff; + __u8 rsvd6; + __u8 chchk; + __u8 vpd[]; +}; + /** * enum - */ From ab9c473661432321142fe24e962d671cc22436c7 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 13 Feb 2020 09:59:08 -0800 Subject: [PATCH 0027/1564] Move ccan up a directory This will make it easier to generate library documentation when the source is not mixed with external libraries. Signed-off-by: Keith Busch --- {src/ccan => ccan}/ccan/array_size/LICENSE | 0 {src/ccan => ccan}/ccan/array_size/_info | 0 {src/ccan => ccan}/ccan/array_size/array_size.h | 0 {src/ccan => ccan}/ccan/build_assert/LICENSE | 0 {src/ccan => ccan}/ccan/build_assert/_info | 0 {src/ccan => ccan}/ccan/build_assert/build_assert.h | 0 {src/ccan => ccan}/ccan/check_type/LICENSE | 0 {src/ccan => ccan}/ccan/check_type/_info | 0 {src/ccan => ccan}/ccan/check_type/check_type.h | 0 {src/ccan => ccan}/ccan/container_of/LICENSE | 0 {src/ccan => ccan}/ccan/container_of/_info | 0 {src/ccan => ccan}/ccan/container_of/container_of.h | 0 {src/ccan => ccan}/ccan/endian/LICENSE | 0 {src/ccan => ccan}/ccan/endian/_info | 0 {src/ccan => ccan}/ccan/endian/endian.h | 0 {src/ccan => ccan}/ccan/list/LICENSE | 0 {src/ccan => ccan}/ccan/list/_info | 0 {src/ccan => ccan}/ccan/list/list.c | 0 {src/ccan => ccan}/ccan/list/list.h | 0 {src/ccan => ccan}/ccan/minmax/LICENSE | 0 {src/ccan => ccan}/ccan/minmax/_info | 0 {src/ccan => ccan}/ccan/minmax/minmax.h | 0 {src/ccan => ccan}/ccan/short_types/LICENSE | 0 {src/ccan => ccan}/ccan/short_types/short_types.h | 0 {src/ccan => ccan}/ccan/str/LICENSE | 0 {src/ccan => ccan}/ccan/str/_info | 0 {src/ccan => ccan}/ccan/str/debug.c | 0 {src/ccan => ccan}/ccan/str/str.c | 0 {src/ccan => ccan}/ccan/str/str.h | 0 {src/ccan => ccan}/ccan/str/str_debug.h | 0 {src/ccan => ccan}/licenses/BSD-MIT | 0 {src/ccan => ccan}/licenses/CC0 | 0 {src/ccan => ccan}/tools/configurator/configurator.c | 0 src/Makefile | 2 +- 34 files changed, 1 insertion(+), 1 deletion(-) rename {src/ccan => ccan}/ccan/array_size/LICENSE (100%) rename {src/ccan => ccan}/ccan/array_size/_info (100%) rename {src/ccan => ccan}/ccan/array_size/array_size.h (100%) rename {src/ccan => ccan}/ccan/build_assert/LICENSE (100%) rename {src/ccan => ccan}/ccan/build_assert/_info (100%) rename {src/ccan => ccan}/ccan/build_assert/build_assert.h (100%) rename {src/ccan => ccan}/ccan/check_type/LICENSE (100%) rename {src/ccan => ccan}/ccan/check_type/_info (100%) rename {src/ccan => ccan}/ccan/check_type/check_type.h (100%) rename {src/ccan => ccan}/ccan/container_of/LICENSE (100%) rename {src/ccan => ccan}/ccan/container_of/_info (100%) rename {src/ccan => ccan}/ccan/container_of/container_of.h (100%) rename {src/ccan => ccan}/ccan/endian/LICENSE (100%) rename {src/ccan => ccan}/ccan/endian/_info (100%) rename {src/ccan => ccan}/ccan/endian/endian.h (100%) rename {src/ccan => ccan}/ccan/list/LICENSE (100%) rename {src/ccan => ccan}/ccan/list/_info (100%) rename {src/ccan => ccan}/ccan/list/list.c (100%) rename {src/ccan => ccan}/ccan/list/list.h (100%) rename {src/ccan => ccan}/ccan/minmax/LICENSE (100%) rename {src/ccan => ccan}/ccan/minmax/_info (100%) rename {src/ccan => ccan}/ccan/minmax/minmax.h (100%) rename {src/ccan => ccan}/ccan/short_types/LICENSE (100%) rename {src/ccan => ccan}/ccan/short_types/short_types.h (100%) rename {src/ccan => ccan}/ccan/str/LICENSE (100%) rename {src/ccan => ccan}/ccan/str/_info (100%) rename {src/ccan => ccan}/ccan/str/debug.c (100%) rename {src/ccan => ccan}/ccan/str/str.c (100%) rename {src/ccan => ccan}/ccan/str/str.h (100%) rename {src/ccan => ccan}/ccan/str/str_debug.h (100%) rename {src/ccan => ccan}/licenses/BSD-MIT (100%) rename {src/ccan => ccan}/licenses/CC0 (100%) rename {src/ccan => ccan}/tools/configurator/configurator.c (100%) diff --git a/src/ccan/ccan/array_size/LICENSE b/ccan/ccan/array_size/LICENSE similarity index 100% rename from src/ccan/ccan/array_size/LICENSE rename to ccan/ccan/array_size/LICENSE diff --git a/src/ccan/ccan/array_size/_info b/ccan/ccan/array_size/_info similarity index 100% rename from src/ccan/ccan/array_size/_info rename to ccan/ccan/array_size/_info diff --git a/src/ccan/ccan/array_size/array_size.h b/ccan/ccan/array_size/array_size.h similarity index 100% rename from src/ccan/ccan/array_size/array_size.h rename to ccan/ccan/array_size/array_size.h diff --git a/src/ccan/ccan/build_assert/LICENSE b/ccan/ccan/build_assert/LICENSE similarity index 100% rename from src/ccan/ccan/build_assert/LICENSE rename to ccan/ccan/build_assert/LICENSE diff --git a/src/ccan/ccan/build_assert/_info b/ccan/ccan/build_assert/_info similarity index 100% rename from src/ccan/ccan/build_assert/_info rename to ccan/ccan/build_assert/_info diff --git a/src/ccan/ccan/build_assert/build_assert.h b/ccan/ccan/build_assert/build_assert.h similarity index 100% rename from src/ccan/ccan/build_assert/build_assert.h rename to ccan/ccan/build_assert/build_assert.h diff --git a/src/ccan/ccan/check_type/LICENSE b/ccan/ccan/check_type/LICENSE similarity index 100% rename from src/ccan/ccan/check_type/LICENSE rename to ccan/ccan/check_type/LICENSE diff --git a/src/ccan/ccan/check_type/_info b/ccan/ccan/check_type/_info similarity index 100% rename from src/ccan/ccan/check_type/_info rename to ccan/ccan/check_type/_info diff --git a/src/ccan/ccan/check_type/check_type.h b/ccan/ccan/check_type/check_type.h similarity index 100% rename from src/ccan/ccan/check_type/check_type.h rename to ccan/ccan/check_type/check_type.h diff --git a/src/ccan/ccan/container_of/LICENSE b/ccan/ccan/container_of/LICENSE similarity index 100% rename from src/ccan/ccan/container_of/LICENSE rename to ccan/ccan/container_of/LICENSE diff --git a/src/ccan/ccan/container_of/_info b/ccan/ccan/container_of/_info similarity index 100% rename from src/ccan/ccan/container_of/_info rename to ccan/ccan/container_of/_info diff --git a/src/ccan/ccan/container_of/container_of.h b/ccan/ccan/container_of/container_of.h similarity index 100% rename from src/ccan/ccan/container_of/container_of.h rename to ccan/ccan/container_of/container_of.h diff --git a/src/ccan/ccan/endian/LICENSE b/ccan/ccan/endian/LICENSE similarity index 100% rename from src/ccan/ccan/endian/LICENSE rename to ccan/ccan/endian/LICENSE diff --git a/src/ccan/ccan/endian/_info b/ccan/ccan/endian/_info similarity index 100% rename from src/ccan/ccan/endian/_info rename to ccan/ccan/endian/_info diff --git a/src/ccan/ccan/endian/endian.h b/ccan/ccan/endian/endian.h similarity index 100% rename from src/ccan/ccan/endian/endian.h rename to ccan/ccan/endian/endian.h diff --git a/src/ccan/ccan/list/LICENSE b/ccan/ccan/list/LICENSE similarity index 100% rename from src/ccan/ccan/list/LICENSE rename to ccan/ccan/list/LICENSE diff --git a/src/ccan/ccan/list/_info b/ccan/ccan/list/_info similarity index 100% rename from src/ccan/ccan/list/_info rename to ccan/ccan/list/_info diff --git a/src/ccan/ccan/list/list.c b/ccan/ccan/list/list.c similarity index 100% rename from src/ccan/ccan/list/list.c rename to ccan/ccan/list/list.c diff --git a/src/ccan/ccan/list/list.h b/ccan/ccan/list/list.h similarity index 100% rename from src/ccan/ccan/list/list.h rename to ccan/ccan/list/list.h diff --git a/src/ccan/ccan/minmax/LICENSE b/ccan/ccan/minmax/LICENSE similarity index 100% rename from src/ccan/ccan/minmax/LICENSE rename to ccan/ccan/minmax/LICENSE diff --git a/src/ccan/ccan/minmax/_info b/ccan/ccan/minmax/_info similarity index 100% rename from src/ccan/ccan/minmax/_info rename to ccan/ccan/minmax/_info diff --git a/src/ccan/ccan/minmax/minmax.h b/ccan/ccan/minmax/minmax.h similarity index 100% rename from src/ccan/ccan/minmax/minmax.h rename to ccan/ccan/minmax/minmax.h diff --git a/src/ccan/ccan/short_types/LICENSE b/ccan/ccan/short_types/LICENSE similarity index 100% rename from src/ccan/ccan/short_types/LICENSE rename to ccan/ccan/short_types/LICENSE diff --git a/src/ccan/ccan/short_types/short_types.h b/ccan/ccan/short_types/short_types.h similarity index 100% rename from src/ccan/ccan/short_types/short_types.h rename to ccan/ccan/short_types/short_types.h diff --git a/src/ccan/ccan/str/LICENSE b/ccan/ccan/str/LICENSE similarity index 100% rename from src/ccan/ccan/str/LICENSE rename to ccan/ccan/str/LICENSE diff --git a/src/ccan/ccan/str/_info b/ccan/ccan/str/_info similarity index 100% rename from src/ccan/ccan/str/_info rename to ccan/ccan/str/_info diff --git a/src/ccan/ccan/str/debug.c b/ccan/ccan/str/debug.c similarity index 100% rename from src/ccan/ccan/str/debug.c rename to ccan/ccan/str/debug.c diff --git a/src/ccan/ccan/str/str.c b/ccan/ccan/str/str.c similarity index 100% rename from src/ccan/ccan/str/str.c rename to ccan/ccan/str/str.c diff --git a/src/ccan/ccan/str/str.h b/ccan/ccan/str/str.h similarity index 100% rename from src/ccan/ccan/str/str.h rename to ccan/ccan/str/str.h diff --git a/src/ccan/ccan/str/str_debug.h b/ccan/ccan/str/str_debug.h similarity index 100% rename from src/ccan/ccan/str/str_debug.h rename to ccan/ccan/str/str_debug.h diff --git a/src/ccan/licenses/BSD-MIT b/ccan/licenses/BSD-MIT similarity index 100% rename from src/ccan/licenses/BSD-MIT rename to ccan/licenses/BSD-MIT diff --git a/src/ccan/licenses/CC0 b/ccan/licenses/CC0 similarity index 100% rename from src/ccan/licenses/CC0 rename to ccan/licenses/CC0 diff --git a/src/ccan/tools/configurator/configurator.c b/ccan/tools/configurator/configurator.c similarity index 100% rename from src/ccan/tools/configurator/configurator.c rename to ccan/tools/configurator/configurator.c diff --git a/src/Makefile b/src/Makefile index 57b562425e..7e004fc112 100644 --- a/src/Makefile +++ b/src/Makefile @@ -6,7 +6,7 @@ prefix ?= /usr includedir ?= $(prefix)/include libdir ?= $(prefix)/lib -CCANDIR=ccan/ +CCANDIR=../ccan/ CFLAGS ?= -g -fomit-frame-pointer -O2 -I/usr/include -Invme/ -I$(CCANDIR) -include ../config-host.h -D_GNU_SOURCE override CFLAGS += -Wall -fPIC From 841ec959e25a00be4cc2bda029d70a0c9c74d005 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 13 Feb 2020 10:01:09 -0800 Subject: [PATCH 0028/1564] Fix copyright comments Don't use the kernel-doc style as that will try to get interpreted by the scripts. Signed-off-by: Keith Busch --- src/libnvme.h | 2 +- src/nvme/fabrics.c | 2 +- src/nvme/fabrics.h | 2 +- src/nvme/filters.c | 2 +- src/nvme/filters.h | 2 +- src/nvme/ioctl.c | 2 +- src/nvme/ioctl.h | 2 +- src/nvme/tree.c | 2 +- src/nvme/tree.h | 2 +- src/nvme/types.h | 2 +- src/nvme/util.c | 2 +- src/nvme/util.h | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/libnvme.h b/src/libnvme.h index 1b648feab9..bd60d0d8a5 100644 --- a/src/libnvme.h +++ b/src/libnvme.h @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-2.1-or-later -/** +/* * This file is part of libnvme. * Copyright (c) 2020 Western Digital Corporation or its affiliates. * diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 19a0dc6bf5..9744f03775 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-2.1-or-later -/** +/* * This file is part of libnvme. * Copyright (c) 2020 Western Digital Corporation or its affiliates. * diff --git a/src/nvme/fabrics.h b/src/nvme/fabrics.h index 702dd926ac..8af57bcc20 100644 --- a/src/nvme/fabrics.h +++ b/src/nvme/fabrics.h @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-2.1-or-later -/** +/* * This file is part of libnvme. * Copyright (c) 2020 Western Digital Corporation or its affiliates. * diff --git a/src/nvme/filters.c b/src/nvme/filters.c index 336254f58b..790ca64fbd 100644 --- a/src/nvme/filters.c +++ b/src/nvme/filters.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-2.1-or-later -/** +/* * This file is part of libnvme. * Copyright (c) 2020 Western Digital Corporation or its affiliates. * diff --git a/src/nvme/filters.h b/src/nvme/filters.h index 6f7e8579a5..52318311b0 100644 --- a/src/nvme/filters.h +++ b/src/nvme/filters.h @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-2.1-or-later -/** +/* * This file is part of libnvme. * Copyright (c) 2020 Western Digital Corporation or its affiliates. * diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 233dea4aab..0f0a8dd0ab 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-2.1-or-later -/** +/* * This file is part of libnvme. * Copyright (c) 2020 Western Digital Corporation or its affiliates. * diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 9287ad68cc..57e1c84f2b 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-2.1-or-later -/** +/* * This file is part of libnvme. * Copyright (c) 2020 Western Digital Corporation or its affiliates. * diff --git a/src/nvme/tree.c b/src/nvme/tree.c index de0cd4d7b9..f4218a398a 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-2.1-or-later -/** +/* * This file is part of libnvme. * Copyright (c) 2020 Western Digital Corporation or its affiliates. * diff --git a/src/nvme/tree.h b/src/nvme/tree.h index 9023ee9ef1..129ecbd27f 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-2.1-or-later -/** +/* * This file is part of libnvme. * Copyright (c) 2020 Western Digital Corporation or its affiliates. * diff --git a/src/nvme/types.h b/src/nvme/types.h index 1ce3f1d10e..cc139c4fef 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-2.1-or-later -/** +/* * This file is part of libnvme. * Copyright (c) 2020 Western Digital Corporation or its affiliates. * diff --git a/src/nvme/util.c b/src/nvme/util.c index 4bf9af22d7..8acaa6d13d 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-2.1-or-later -/** +/* * This file is part of libnvme. * Copyright (c) 2020 Western Digital Corporation or its affiliates. * diff --git a/src/nvme/util.h b/src/nvme/util.h index a920681071..bed6396d66 100644 --- a/src/nvme/util.h +++ b/src/nvme/util.h @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-2.1-or-later -/** +/* * This file is part of libnvme. * Copyright (c) 2020 Western Digital Corporation or its affiliates. * From 4bbea1397640064a216fca874e54a99c704c2cf0 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 13 Feb 2020 11:48:08 -0800 Subject: [PATCH 0029/1564] Set up ccan make dependency correctly Fixes parallel -j make. Signed-off-by: Keith Busch --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index 7e004fc112..541a8167fc 100644 --- a/src/Makefile +++ b/src/Makefile @@ -51,7 +51,7 @@ libccan_srcs := $(wildcard $(CCANDIR)ccan/*/*.c) libccan_objs := $(patsubst %.c,%.ol,$(libccan_srcs)) libccan_sobjs := $(patsubst %.c,%.os,$(libccan_srcs)) -$(libccan_objs) $(libccan_sobjs): $(libccan_headers) +$(libccan_objs) $(libccan_sobjs): $(libccan_headers) $(CCANDIR)config.h libnvme_priv := nvme/private.h libnvme_api := libnvme.h nvme/types.h nvme/ioctl.h nvme/filters.h nvme/tree.h nvme/util.h From e4ac4459ae98e7bee9f5292c7d96eb0528838092 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 13 Feb 2020 13:00:03 -0800 Subject: [PATCH 0030/1564] Add man pages for exports Generate man-pages from existing source. This will likely change soon as the types (struct and enum) should probably be grouped in the same manual as the primary function that uses it rather than have their own, and similiar functions can in turn be grouped in the same manual as well. Signed-off-by: Keith Busch --- doc/libnvme.rst | 7828 +++++++++-------- doc/man/__nvme_get_log_page.2 | 27 + doc/man/enum .2 | 678 ++ doc/man/enum nvme_admin_opcode.2 | 174 + doc/man/enum nvme_ae_info_css_nvm.2 | 24 + doc/man/enum nvme_ae_info_error.2 | 42 + doc/man/enum nvme_ae_info_notice.2 | 54 + doc/man/enum nvme_ae_info_smart.2 | 24 + doc/man/enum nvme_ae_type.2 | 36 + doc/man/enum nvme_cmd_format_mset.2 | 18 + doc/man/enum nvme_cmd_format_pi.2 | 30 + doc/man/enum nvme_cmd_format_ses.2 | 24 + doc/man/enum nvme_cmd_get_log_lid.2 | 114 + doc/man/enum nvme_constants.2 | 118 + doc/man/enum nvme_directive_dtype.2 | 18 + doc/man/enum nvme_directive_receive_doper.2 | 30 + doc/man/enum nvme_directive_send_doper.2 | 24 + .../enum nvme_directive_send_identify_endir.2 | 18 + doc/man/enum nvme_dsm_attributes.2 | 24 + doc/man/enum nvme_dst_stc.2 | 30 + doc/man/enum nvme_eg_critical_warning_flags.2 | 24 + doc/man/enum nvme_fctype.2 | 42 + doc/man/enum nvme_feat_nswpcfg_state.2 | 30 + doc/man/enum nvme_feat_plm_window_select.2 | 18 + doc/man/enum nvme_feat_tmpthresh_thsel.2 | 18 + ...m nvme_features_async_event_config_flags.2 | 90 + doc/man/enum nvme_features_id.2 | 180 + doc/man/enum nvme_fw_commit_ca.2 | 42 + doc/man/enum nvme_get_features_sel.2 | 24 + doc/man/enum nvme_id_ctrl_anacap.2 | 59 + doc/man/enum nvme_id_ctrl_apsta.2 | 13 + doc/man/enum nvme_id_ctrl_avscc.2 | 14 + doc/man/enum nvme_id_ctrl_cmic.2 | 30 + doc/man/enum nvme_id_ctrl_cntrltype.2 | 24 + doc/man/enum nvme_id_ctrl_ctratt.2 | 66 + doc/man/enum nvme_id_ctrl_dsto.2 | 13 + doc/man/enum nvme_id_ctrl_fcatt.2 | 14 + doc/man/enum nvme_id_ctrl_fna.2 | 39 + doc/man/enum nvme_id_ctrl_frmw.2 | 26 + doc/man/enum nvme_id_ctrl_fuses.2 | 13 + doc/man/enum nvme_id_ctrl_hctm.2 | 15 + doc/man/enum nvme_id_ctrl_lpa.2 | 36 + doc/man/enum nvme_id_ctrl_mec.2 | 20 + doc/man/enum nvme_id_ctrl_nvmsr.2 | 22 + doc/man/enum nvme_id_ctrl_nvscc.2 | 13 + doc/man/enum nvme_id_ctrl_nwpc.2 | 35 + doc/man/enum nvme_id_ctrl_oacs.2 | 77 + doc/man/enum nvme_id_ctrl_oaes.2 | 42 + doc/man/enum nvme_id_ctrl_ofcs.2 | 14 + doc/man/enum nvme_id_ctrl_oncs.2 | 65 + doc/man/enum nvme_id_ctrl_rpmbs.2 | 30 + doc/man/enum nvme_id_ctrl_sanicap.2 | 44 + doc/man/enum nvme_id_ctrl_sgls.2 | 54 + doc/man/enum nvme_id_ctrl_sqes.2 | 20 + doc/man/enum nvme_id_ctrl_vwc.2 | 22 + doc/man/enum nvme_id_ctrl_vwci.2 | 28 + doc/man/enum nvme_id_ns_attr.2 | 14 + doc/man/enum nvme_id_ns_dlfeat.2 | 50 + doc/man/enum nvme_id_ns_dpc.2 | 43 + doc/man/enum nvme_id_ns_dps.2 | 44 + doc/man/enum nvme_id_ns_flbas.2 | 24 + doc/man/enum nvme_id_ns_mc.2 | 21 + doc/man/enum nvme_id_ns_nmic.2 | 13 + doc/man/enum nvme_id_ns_rescap.2 | 62 + doc/man/enum nvme_id_nsfeat.2 | 51 + doc/man/enum nvme_identify_cns.2 | 84 + doc/man/enum nvme_io_control_flags.2 | 54 + doc/man/enum nvme_io_dsm_flags.2 | 96 + doc/man/enum nvme_io_opcode.2 | 78 + doc/man/enum nvme_lba_status_atype.2 | 18 + doc/man/enum nvme_lbaf_rp.2 | 37 + doc/man/enum nvme_nd_ns_fpi.2 | 19 + doc/man/enum nvme_ns_attach_sel.2 | 18 + doc/man/enum nvme_ns_id_desc_nidt.2 | 27 + doc/man/enum nvme_ns_mgmt_sel.2 | 18 + doc/man/enum nvme_psd_flags.2 | 26 + doc/man/enum nvme_psd_ps.2 | 18 + doc/man/enum nvme_psd_workload.2 | 29 + doc/man/enum nvme_registers.2 | 150 + doc/man/enum nvme_reservation_cptpl.2 | 24 + doc/man/enum nvme_reservation_racqa.2 | 24 + doc/man/enum nvme_reservation_rrega.2 | 24 + doc/man/enum nvme_reservation_rrela.2 | 18 + doc/man/enum nvme_reservation_rtype.2 | 42 + doc/man/enum nvme_sanitize_sanact.2 | 30 + doc/man/enum nvme_subsys_type.2 | 18 + doc/man/enum nvme_virt_mgmt_act.2 | 30 + doc/man/enum nvme_virt_mgmt_rt.2 | 18 + doc/man/is_64bit_reg.2 | 16 + doc/man/libnvme.2 | 2 + doc/man/nvme_admin_passthru.2 | 71 + doc/man/nvme_admin_passthru64.2 | 71 + doc/man/nvme_compare.2 | 52 + doc/man/nvme_ctrl_disconnect.2 | 8 + doc/man/nvme_ctrl_first_ns.2 | 8 + doc/man/nvme_ctrl_first_path.2 | 8 + doc/man/nvme_ctrl_for_each_ns.2 | 12 + doc/man/nvme_ctrl_for_each_ns_safe.2 | 15 + doc/man/nvme_ctrl_for_each_path.2 | 12 + doc/man/nvme_ctrl_for_each_path_safe.2 | 15 + doc/man/nvme_ctrl_get_address.2 | 8 + doc/man/nvme_ctrl_get_fd.2 | 8 + doc/man/nvme_ctrl_get_firmware.2 | 8 + doc/man/nvme_ctrl_get_model.2 | 8 + doc/man/nvme_ctrl_get_name.2 | 8 + doc/man/nvme_ctrl_get_nqn.2 | 8 + doc/man/nvme_ctrl_get_numa_node.2 | 8 + doc/man/nvme_ctrl_get_queue_count.2 | 8 + doc/man/nvme_ctrl_get_serial.2 | 8 + doc/man/nvme_ctrl_get_sqsize.2 | 8 + doc/man/nvme_ctrl_get_state.2 | 8 + doc/man/nvme_ctrl_get_subsysnqn.2 | 8 + doc/man/nvme_ctrl_get_subsystem.2 | 8 + doc/man/nvme_ctrl_get_sysfs_dir.2 | 8 + doc/man/nvme_ctrl_get_transport.2 | 8 + doc/man/nvme_ctrl_identify.2 | 11 + doc/man/nvme_ctrl_next_ns.2 | 11 + doc/man/nvme_ctrl_next_path.2 | 11 + doc/man/nvme_ctrl_reset.2 | 13 + doc/man/nvme_ctrls_filter.2 | 8 + doc/man/nvme_dev_self_test.2 | 29 + doc/man/nvme_directive_recv.2 | 36 + .../nvme_directive_recv_identify_parameters.2 | 18 + doc/man/nvme_directive_recv_stream_allocate.2 | 21 + .../nvme_directive_recv_stream_parameters.2 | 18 + doc/man/nvme_directive_recv_stream_status.2 | 21 + doc/man/nvme_directive_send.2 | 42 + doc/man/nvme_directive_send_id_endir.2 | 24 + ...directive_send_stream_release_identifier.2 | 18 + ...e_directive_send_stream_release_resource.2 | 15 + doc/man/nvme_dsm.2 | 31 + doc/man/nvme_first_subsystem.2 | 8 + doc/man/nvme_flush.2 | 18 + doc/man/nvme_for_each_subsystem.2 | 12 + doc/man/nvme_for_each_subsystem_safe.2 | 15 + doc/man/nvme_format_nvm.2 | 39 + doc/man/nvme_free_ctrl.2 | 9 + doc/man/nvme_free_tree.2 | 9 + doc/man/nvme_fw_commit.2 | 25 + doc/man/nvme_fw_download.2 | 34 + doc/man/nvme_fw_download_seq.2 | 20 + doc/man/nvme_get_ana_log_len.2 | 14 + doc/man/nvme_get_ctrl_attr.2 | 11 + doc/man/nvme_get_ctrl_telemetry.2 | 17 + doc/man/nvme_get_directive_receive_length.2 | 18 + doc/man/nvme_get_feature_length.2 | 16 + doc/man/nvme_get_features.2 | 36 + doc/man/nvme_get_features_arbitration.2 | 18 + doc/man/nvme_get_features_async_event.2 | 18 + doc/man/nvme_get_features_auto_pst.2 | 21 + .../nvme_get_features_endurance_event_cfg.2 | 21 + doc/man/nvme_get_features_err_recovery.2 | 18 + doc/man/nvme_get_features_hctm.2 | 18 + doc/man/nvme_get_features_host_behavior.2 | 21 + doc/man/nvme_get_features_host_id.2 | 24 + doc/man/nvme_get_features_host_mem_buf.2 | 18 + doc/man/nvme_get_features_irq_coalesce.2 | 18 + doc/man/nvme_get_features_irq_config.2 | 21 + doc/man/nvme_get_features_kato.2 | 18 + doc/man/nvme_get_features_lba_range.2 | 21 + doc/man/nvme_get_features_lba_sts_interval.2 | 18 + doc/man/nvme_get_features_nopsc.2 | 18 + doc/man/nvme_get_features_num_queues.2 | 18 + doc/man/nvme_get_features_plm_config.2 | 24 + doc/man/nvme_get_features_plm_window.2 | 21 + doc/man/nvme_get_features_power_mgmt.2 | 18 + doc/man/nvme_get_features_resv_mask.2 | 18 + doc/man/nvme_get_features_resv_persist.2 | 18 + doc/man/nvme_get_features_rrl.2 | 18 + doc/man/nvme_get_features_sanitize.2 | 18 + doc/man/nvme_get_features_sw_progress.2 | 18 + doc/man/nvme_get_features_temp_thresh.2 | 18 + doc/man/nvme_get_features_timestamp.2 | 18 + doc/man/nvme_get_features_volatile_wc.2 | 18 + doc/man/nvme_get_features_write_atomic.2 | 18 + doc/man/nvme_get_features_write_protect.2 | 21 + doc/man/nvme_get_host_telemetry.2 | 14 + doc/man/nvme_get_lba_status.2 | 34 + doc/man/nvme_get_log.2 | 39 + doc/man/nvme_get_log_ana.2 | 33 + doc/man/nvme_get_log_ana_groups.2 | 20 + doc/man/nvme_get_log_changed_ns_list.2 | 22 + doc/man/nvme_get_log_cmd_effects.2 | 18 + doc/man/nvme_get_log_create_telemetry_host.2 | 12 + doc/man/nvme_get_log_device_self_test.2 | 19 + doc/man/nvme_get_log_discovery.2 | 27 + doc/man/nvme_get_log_endurance_group.2 | 25 + doc/man/nvme_get_log_endurance_grp_evt.2 | 21 + doc/man/nvme_get_log_error.2 | 25 + doc/man/nvme_get_log_fw_slot.2 | 22 + doc/man/nvme_get_log_lba_status.2 | 21 + doc/man/nvme_get_log_page.2 | 25 + doc/man/nvme_get_log_predictable_lat_event.2 | 21 + doc/man/nvme_get_log_predictable_lat_nvmset.2 | 17 + doc/man/nvme_get_log_reservation.2 | 15 + doc/man/nvme_get_log_sanitize.2 | 21 + doc/man/nvme_get_log_smart.2 | 28 + doc/man/nvme_get_log_telemetry_ctrl.2 | 21 + doc/man/nvme_get_log_telemetry_host.2 | 24 + doc/man/nvme_get_new_host_telemetry.2 | 14 + doc/man/nvme_get_ns_attr.2 | 11 + doc/man/nvme_get_nsid.2 | 14 + doc/man/nvme_get_path_attr.2 | 11 + doc/man/nvme_get_property.2 | 21 + doc/man/nvme_get_subsys_attr.2 | 11 + doc/man/nvme_identify.2 | 33 + doc/man/nvme_identify_active_ns_list.2 | 24 + doc/man/nvme_identify_allocated_ns.2 | 18 + doc/man/nvme_identify_allocated_ns_list.2 | 24 + doc/man/nvme_identify_ctrl.2 | 20 + doc/man/nvme_identify_ctrl_list.2 | 24 + doc/man/nvme_identify_ns.2 | 29 + doc/man/nvme_identify_ns_descs.2 | 26 + doc/man/nvme_identify_ns_granularity.2 | 22 + doc/man/nvme_identify_nsid_ctrl_list.2 | 26 + doc/man/nvme_identify_nvmset_list.2 | 25 + doc/man/nvme_identify_primary_ctrl.2 | 19 + doc/man/nvme_identify_secondary_ctrl_list.2 | 26 + doc/man/nvme_identify_uuid.2 | 20 + doc/man/nvme_io_passthru.2 | 71 + doc/man/nvme_io_passthru64.2 | 71 + doc/man/nvme_namespace_attach_ctrls.2 | 21 + doc/man/nvme_namespace_detach_ctrls.2 | 21 + doc/man/nvme_namespace_filter.2 | 8 + doc/man/nvme_next_subsystem.2 | 11 + doc/man/nvme_ns_attach.2 | 18 + doc/man/nvme_ns_attach_ctrls.2 | 15 + doc/man/nvme_ns_compare.2 | 17 + doc/man/nvme_ns_dettach_ctrls.2 | 15 + doc/man/nvme_ns_flush.2 | 8 + doc/man/nvme_ns_get_ctrl.2 | 8 + doc/man/nvme_ns_get_fd.2 | 8 + doc/man/nvme_ns_get_lba_count.2 | 8 + doc/man/nvme_ns_get_lba_size.2 | 8 + doc/man/nvme_ns_get_lba_util.2 | 8 + doc/man/nvme_ns_get_name.2 | 8 + doc/man/nvme_ns_get_nsid.2 | 8 + doc/man/nvme_ns_get_subsystem.2 | 8 + doc/man/nvme_ns_get_sysfs_dir.2 | 8 + doc/man/nvme_ns_identify.2 | 11 + doc/man/nvme_ns_mgmt.2 | 24 + doc/man/nvme_ns_mgmt_create.2 | 26 + doc/man/nvme_ns_mgmt_delete.2 | 19 + doc/man/nvme_ns_read.2 | 17 + doc/man/nvme_ns_rescan.2 | 13 + doc/man/nvme_ns_verify.2 | 14 + doc/man/nvme_ns_write.2 | 17 + doc/man/nvme_ns_write_uncorrectable.2 | 14 + doc/man/nvme_ns_write_zeros.2 | 14 + doc/man/nvme_open.2 | 15 + doc/man/nvme_path_get_ana_state.2 | 8 + doc/man/nvme_path_get_name.2 | 8 + doc/man/nvme_path_get_ns.2 | 8 + doc/man/nvme_path_get_subsystem.2 | 8 + doc/man/nvme_path_get_sysfs_dir.2 | 8 + doc/man/nvme_paths_filter.2 | 8 + doc/man/nvme_psd_power_scale.2 | 9 + doc/man/nvme_read.2 | 55 + doc/man/nvme_refresh_topology.2 | 9 + doc/man/nvme_reset_topology.2 | 9 + doc/man/nvme_resv_acquire.2 | 35 + doc/man/nvme_resv_register.2 | 34 + doc/man/nvme_resv_release.2 | 27 + doc/man/nvme_resv_report.2 | 28 + doc/man/nvme_sanitize_nvm.2 | 40 + doc/man/nvme_scan.2 | 6 + doc/man/nvme_scan_ctrl.2 | 8 + doc/man/nvme_scan_ctrl_namespace_paths.2 | 11 + doc/man/nvme_scan_ctrl_namespaces.2 | 11 + doc/man/nvme_scan_filter.2 | 8 + doc/man/nvme_scan_subsystem_ctrls.2 | 11 + doc/man/nvme_scan_subsystem_namespaces.2 | 11 + doc/man/nvme_scan_subsystems.2 | 8 + doc/man/nvme_security_receive.2 | 39 + doc/man/nvme_security_send.2 | 48 + doc/man/nvme_set_attr.2 | 16 + doc/man/nvme_set_features.2 | 42 + doc/man/nvme_set_features_arbitration.2 | 30 + doc/man/nvme_set_features_async_event.2 | 21 + doc/man/nvme_set_features_auto_pst.2 | 24 + doc/man/nvme_set_features_endurance_evt_cfg.2 | 24 + doc/man/nvme_set_features_err_recovery.2 | 27 + doc/man/nvme_set_features_hctm.2 | 24 + doc/man/nvme_set_features_host_behavior.2 | 18 + doc/man/nvme_set_features_host_id.2 | 21 + doc/man/nvme_set_features_irq_coalesce.2 | 24 + doc/man/nvme_set_features_irq_config.2 | 24 + doc/man/nvme_set_features_lba_range.2 | 27 + doc/man/nvme_set_features_lba_sts_interval.2 | 24 + doc/man/nvme_set_features_nopsc.2 | 18 + doc/man/nvme_set_features_plm_config.2 | 27 + doc/man/nvme_set_features_plm_window.2 | 24 + doc/man/nvme_set_features_power_mgmt.2 | 24 + doc/man/nvme_set_features_resv_mask.2 | 21 + doc/man/nvme_set_features_resv_persist.2 | 21 + doc/man/nvme_set_features_rrl.2 | 24 + doc/man/nvme_set_features_sanitize.2 | 21 + doc/man/nvme_set_features_sw_progress.2 | 21 + doc/man/nvme_set_features_temp_thresh.2 | 27 + doc/man/nvme_set_features_timestamp.2 | 18 + doc/man/nvme_set_features_volatile_wc.2 | 21 + doc/man/nvme_set_features_write_atomic.2 | 21 + doc/man/nvme_set_features_write_protect.2 | 21 + doc/man/nvme_set_property.2 | 21 + doc/man/nvme_setup_ctrl_list.2 | 15 + doc/man/nvme_setup_dsm_range.2 | 26 + doc/man/nvme_setup_id_ns.2 | 30 + doc/man/nvme_status_to_errno.2 | 16 + doc/man/nvme_submit_admin_passthru.2 | 20 + doc/man/nvme_submit_admin_passthru64.2 | 20 + doc/man/nvme_submit_io_passthru.2 | 20 + doc/man/nvme_submit_io_passthru64.2 | 20 + doc/man/nvme_subsys_filter.2 | 8 + doc/man/nvme_subsystem_first_ctrl.2 | 8 + doc/man/nvme_subsystem_first_ns.2 | 8 + doc/man/nvme_subsystem_for_each_ctrl.2 | 12 + doc/man/nvme_subsystem_for_each_ctrl_safe.2 | 15 + doc/man/nvme_subsystem_for_each_ns.2 | 12 + doc/man/nvme_subsystem_for_each_ns_safe.2 | 15 + doc/man/nvme_subsystem_get_name.2 | 8 + doc/man/nvme_subsystem_get_nqn.2 | 8 + doc/man/nvme_subsystem_get_sysfs_dir.2 | 8 + doc/man/nvme_subsystem_next_ctrl.2 | 11 + doc/man/nvme_subsystem_next_ns.2 | 11 + doc/man/nvme_subsystem_reset.2 | 14 + doc/man/nvme_unlink_ctrl.2 | 9 + doc/man/nvme_verify.2 | 43 + doc/man/nvme_virtual_mgmt.2 | 35 + doc/man/nvme_write.2 | 58 + doc/man/nvme_write_uncorrectable.2 | 27 + doc/man/nvme_write_zeros.2 | 44 + doc/man/nvmf_add_ctrl.2 | 9 + doc/man/nvmf_add_ctrl_opts.2 | 9 + doc/man/nvmf_adrfam_str.2 | 9 + doc/man/nvmf_cms_str.2 | 9 + doc/man/nvmf_connect_disc_entry.2 | 15 + doc/man/nvmf_get_discovery_log.2 | 15 + doc/man/nvmf_hostid_from_file.2 | 6 + doc/man/nvmf_hostnqn_from_file.2 | 6 + doc/man/nvmf_hostnqn_generate.2 | 6 + doc/man/nvmf_prtype_str.2 | 9 + doc/man/nvmf_qptype_str.2 | 9 + doc/man/nvmf_sectype_str.2 | 9 + doc/man/nvmf_subtype_str.2 | 9 + doc/man/nvmf_treq_str.2 | 9 + doc/man/nvmf_trtype_str.2 | 9 + ...uct nvme_aggregate_endurance_group_event.2 | 15 + ...uct nvme_aggregate_predictable_lat_event.2 | 15 + doc/man/struct nvme_ana_group_desc.2 | 23 + doc/man/struct nvme_ana_log.2 | 19 + doc/man/struct nvme_cmd_effects_log.2 | 17 + doc/man/struct nvme_ctrl_list.2 | 15 + doc/man/struct nvme_dsm_range.2 | 17 + doc/man/struct nvme_eg_event_aggregate_log.2 | 15 + doc/man/struct nvme_endurance_group_log.2 | 41 + doc/man/struct nvme_error_log_page.2 | 37 + doc/man/struct nvme_fabrics_config.2 | 51 + doc/man/struct nvme_feat_auto_pst.2 | 13 + doc/man/struct nvme_feat_host_behavior.2 | 15 + doc/man/struct nvme_firmware_slot.2 | 19 + doc/man/struct nvme_frs.2 | 13 + doc/man/struct nvme_host_mem_buf_desc.2 | 17 + doc/man/struct nvme_id_ctrl.2 | 455 + doc/man/struct nvme_id_directives.2 | 17 + doc/man/struct nvme_id_ns.2 | 203 + doc/man/struct nvme_id_ns_granularity_desc.2 | 15 + doc/man/struct nvme_id_ns_granularity_list.2 | 21 + doc/man/struct nvme_id_nvmset_list.2 | 19 + doc/man/struct nvme_id_psd.2 | 92 + doc/man/struct nvme_id_uuid_list.2 | 15 + doc/man/struct nvme_id_uuid_list_entry.2 | 17 + doc/man/struct nvme_lba_range_type.2 | 13 + doc/man/struct nvme_lba_range_type_entry.2 | 25 + doc/man/struct nvme_lba_rd.2 | 17 + doc/man/struct nvme_lba_status.2 | 19 + doc/man/struct nvme_lba_status_desc.2 | 21 + doc/man/struct nvme_lba_status_log.2 | 23 + doc/man/struct nvme_lbaf.2 | 25 + doc/man/struct nvme_lbas_ns_element.2 | 21 + doc/man/struct nvme_mi_ctrl_heal_status.2 | 25 + doc/man/struct nvme_mi_nvm_ss_health_status.2 | 23 + doc/man/struct nvme_mi_osc.2 | 15 + doc/man/struct nvme_mi_port_pcie.2 | 25 + doc/man/struct nvme_mi_port_smb.2 | 23 + doc/man/struct nvme_mi_read_ctrl_info.2 | 29 + doc/man/struct nvme_mi_read_nvm_ss_info.2 | 19 + doc/man/struct nvme_mi_read_port_info.2 | 31 + doc/man/struct nvme_mi_read_sc_list.2 | 15 + doc/man/struct nvme_mi_vpd_hdr.2 | 29 + doc/man/struct nvme_mi_vpd_mr_common.2 | 33 + doc/man/struct nvme_mi_vpd_mra.2 | 43 + doc/man/struct nvme_mi_vpd_ppmra.2 | 29 + doc/man/struct nvme_mi_vpd_telem.2 | 19 + doc/man/struct nvme_mi_vpd_tra.2 | 19 + doc/man/struct nvme_ns_id_desc.2 | 28 + doc/man/struct nvme_ns_list.2 | 13 + doc/man/struct nvme_nvmset_attr.2 | 37 + .../struct nvme_nvmset_predictable_lat_log.2 | 39 + doc/man/struct nvme_passthru_cmd.2 | 83 + doc/man/struct nvme_passthru_cmd64.2 | 87 + doc/man/struct nvme_persistent_event_log.2 | 43 + doc/man/struct nvme_plm_config.2 | 23 + doc/man/struct nvme_primary_ctrl_cap.2 | 47 + doc/man/struct nvme_registered_ctrl.2 | 21 + doc/man/struct nvme_registered_ctrl_ext.2 | 23 + doc/man/struct nvme_reservation_status.2 | 41 + doc/man/struct nvme_resv_notification_log.2 | 23 + doc/man/struct nvme_sanitize_log_page.2 | 31 + doc/man/struct nvme_secondary_ctrl.2 | 27 + doc/man/struct nvme_secondary_ctrl_list.2 | 17 + doc/man/struct nvme_self_test_log.2 | 19 + doc/man/struct nvme_smart_log.2 | 61 + doc/man/struct nvme_st_result.2 | 31 + .../struct nvme_streams_directive_params.2 | 31 + .../struct nvme_streams_directive_status.2 | 15 + doc/man/struct nvme_telemetry_log.2 | 33 + doc/man/struct nvme_timestamp.2 | 17 + doc/man/struct nvmf_connect_data.2 | 26 + doc/man/struct nvmf_disc_log_entry.2 | 63 + doc/man/struct nvmf_discovery_log.2 | 21 + 420 files changed, 15783 insertions(+), 3584 deletions(-) create mode 100644 doc/man/__nvme_get_log_page.2 create mode 100644 doc/man/enum .2 create mode 100644 doc/man/enum nvme_admin_opcode.2 create mode 100644 doc/man/enum nvme_ae_info_css_nvm.2 create mode 100644 doc/man/enum nvme_ae_info_error.2 create mode 100644 doc/man/enum nvme_ae_info_notice.2 create mode 100644 doc/man/enum nvme_ae_info_smart.2 create mode 100644 doc/man/enum nvme_ae_type.2 create mode 100644 doc/man/enum nvme_cmd_format_mset.2 create mode 100644 doc/man/enum nvme_cmd_format_pi.2 create mode 100644 doc/man/enum nvme_cmd_format_ses.2 create mode 100644 doc/man/enum nvme_cmd_get_log_lid.2 create mode 100644 doc/man/enum nvme_constants.2 create mode 100644 doc/man/enum nvme_directive_dtype.2 create mode 100644 doc/man/enum nvme_directive_receive_doper.2 create mode 100644 doc/man/enum nvme_directive_send_doper.2 create mode 100644 doc/man/enum nvme_directive_send_identify_endir.2 create mode 100644 doc/man/enum nvme_dsm_attributes.2 create mode 100644 doc/man/enum nvme_dst_stc.2 create mode 100644 doc/man/enum nvme_eg_critical_warning_flags.2 create mode 100644 doc/man/enum nvme_fctype.2 create mode 100644 doc/man/enum nvme_feat_nswpcfg_state.2 create mode 100644 doc/man/enum nvme_feat_plm_window_select.2 create mode 100644 doc/man/enum nvme_feat_tmpthresh_thsel.2 create mode 100644 doc/man/enum nvme_features_async_event_config_flags.2 create mode 100644 doc/man/enum nvme_features_id.2 create mode 100644 doc/man/enum nvme_fw_commit_ca.2 create mode 100644 doc/man/enum nvme_get_features_sel.2 create mode 100644 doc/man/enum nvme_id_ctrl_anacap.2 create mode 100644 doc/man/enum nvme_id_ctrl_apsta.2 create mode 100644 doc/man/enum nvme_id_ctrl_avscc.2 create mode 100644 doc/man/enum nvme_id_ctrl_cmic.2 create mode 100644 doc/man/enum nvme_id_ctrl_cntrltype.2 create mode 100644 doc/man/enum nvme_id_ctrl_ctratt.2 create mode 100644 doc/man/enum nvme_id_ctrl_dsto.2 create mode 100644 doc/man/enum nvme_id_ctrl_fcatt.2 create mode 100644 doc/man/enum nvme_id_ctrl_fna.2 create mode 100644 doc/man/enum nvme_id_ctrl_frmw.2 create mode 100644 doc/man/enum nvme_id_ctrl_fuses.2 create mode 100644 doc/man/enum nvme_id_ctrl_hctm.2 create mode 100644 doc/man/enum nvme_id_ctrl_lpa.2 create mode 100644 doc/man/enum nvme_id_ctrl_mec.2 create mode 100644 doc/man/enum nvme_id_ctrl_nvmsr.2 create mode 100644 doc/man/enum nvme_id_ctrl_nvscc.2 create mode 100644 doc/man/enum nvme_id_ctrl_nwpc.2 create mode 100644 doc/man/enum nvme_id_ctrl_oacs.2 create mode 100644 doc/man/enum nvme_id_ctrl_oaes.2 create mode 100644 doc/man/enum nvme_id_ctrl_ofcs.2 create mode 100644 doc/man/enum nvme_id_ctrl_oncs.2 create mode 100644 doc/man/enum nvme_id_ctrl_rpmbs.2 create mode 100644 doc/man/enum nvme_id_ctrl_sanicap.2 create mode 100644 doc/man/enum nvme_id_ctrl_sgls.2 create mode 100644 doc/man/enum nvme_id_ctrl_sqes.2 create mode 100644 doc/man/enum nvme_id_ctrl_vwc.2 create mode 100644 doc/man/enum nvme_id_ctrl_vwci.2 create mode 100644 doc/man/enum nvme_id_ns_attr.2 create mode 100644 doc/man/enum nvme_id_ns_dlfeat.2 create mode 100644 doc/man/enum nvme_id_ns_dpc.2 create mode 100644 doc/man/enum nvme_id_ns_dps.2 create mode 100644 doc/man/enum nvme_id_ns_flbas.2 create mode 100644 doc/man/enum nvme_id_ns_mc.2 create mode 100644 doc/man/enum nvme_id_ns_nmic.2 create mode 100644 doc/man/enum nvme_id_ns_rescap.2 create mode 100644 doc/man/enum nvme_id_nsfeat.2 create mode 100644 doc/man/enum nvme_identify_cns.2 create mode 100644 doc/man/enum nvme_io_control_flags.2 create mode 100644 doc/man/enum nvme_io_dsm_flags.2 create mode 100644 doc/man/enum nvme_io_opcode.2 create mode 100644 doc/man/enum nvme_lba_status_atype.2 create mode 100644 doc/man/enum nvme_lbaf_rp.2 create mode 100644 doc/man/enum nvme_nd_ns_fpi.2 create mode 100644 doc/man/enum nvme_ns_attach_sel.2 create mode 100644 doc/man/enum nvme_ns_id_desc_nidt.2 create mode 100644 doc/man/enum nvme_ns_mgmt_sel.2 create mode 100644 doc/man/enum nvme_psd_flags.2 create mode 100644 doc/man/enum nvme_psd_ps.2 create mode 100644 doc/man/enum nvme_psd_workload.2 create mode 100644 doc/man/enum nvme_registers.2 create mode 100644 doc/man/enum nvme_reservation_cptpl.2 create mode 100644 doc/man/enum nvme_reservation_racqa.2 create mode 100644 doc/man/enum nvme_reservation_rrega.2 create mode 100644 doc/man/enum nvme_reservation_rrela.2 create mode 100644 doc/man/enum nvme_reservation_rtype.2 create mode 100644 doc/man/enum nvme_sanitize_sanact.2 create mode 100644 doc/man/enum nvme_subsys_type.2 create mode 100644 doc/man/enum nvme_virt_mgmt_act.2 create mode 100644 doc/man/enum nvme_virt_mgmt_rt.2 create mode 100644 doc/man/is_64bit_reg.2 create mode 100644 doc/man/libnvme.2 create mode 100644 doc/man/nvme_admin_passthru.2 create mode 100644 doc/man/nvme_admin_passthru64.2 create mode 100644 doc/man/nvme_compare.2 create mode 100644 doc/man/nvme_ctrl_disconnect.2 create mode 100644 doc/man/nvme_ctrl_first_ns.2 create mode 100644 doc/man/nvme_ctrl_first_path.2 create mode 100644 doc/man/nvme_ctrl_for_each_ns.2 create mode 100644 doc/man/nvme_ctrl_for_each_ns_safe.2 create mode 100644 doc/man/nvme_ctrl_for_each_path.2 create mode 100644 doc/man/nvme_ctrl_for_each_path_safe.2 create mode 100644 doc/man/nvme_ctrl_get_address.2 create mode 100644 doc/man/nvme_ctrl_get_fd.2 create mode 100644 doc/man/nvme_ctrl_get_firmware.2 create mode 100644 doc/man/nvme_ctrl_get_model.2 create mode 100644 doc/man/nvme_ctrl_get_name.2 create mode 100644 doc/man/nvme_ctrl_get_nqn.2 create mode 100644 doc/man/nvme_ctrl_get_numa_node.2 create mode 100644 doc/man/nvme_ctrl_get_queue_count.2 create mode 100644 doc/man/nvme_ctrl_get_serial.2 create mode 100644 doc/man/nvme_ctrl_get_sqsize.2 create mode 100644 doc/man/nvme_ctrl_get_state.2 create mode 100644 doc/man/nvme_ctrl_get_subsysnqn.2 create mode 100644 doc/man/nvme_ctrl_get_subsystem.2 create mode 100644 doc/man/nvme_ctrl_get_sysfs_dir.2 create mode 100644 doc/man/nvme_ctrl_get_transport.2 create mode 100644 doc/man/nvme_ctrl_identify.2 create mode 100644 doc/man/nvme_ctrl_next_ns.2 create mode 100644 doc/man/nvme_ctrl_next_path.2 create mode 100644 doc/man/nvme_ctrl_reset.2 create mode 100644 doc/man/nvme_ctrls_filter.2 create mode 100644 doc/man/nvme_dev_self_test.2 create mode 100644 doc/man/nvme_directive_recv.2 create mode 100644 doc/man/nvme_directive_recv_identify_parameters.2 create mode 100644 doc/man/nvme_directive_recv_stream_allocate.2 create mode 100644 doc/man/nvme_directive_recv_stream_parameters.2 create mode 100644 doc/man/nvme_directive_recv_stream_status.2 create mode 100644 doc/man/nvme_directive_send.2 create mode 100644 doc/man/nvme_directive_send_id_endir.2 create mode 100644 doc/man/nvme_directive_send_stream_release_identifier.2 create mode 100644 doc/man/nvme_directive_send_stream_release_resource.2 create mode 100644 doc/man/nvme_dsm.2 create mode 100644 doc/man/nvme_first_subsystem.2 create mode 100644 doc/man/nvme_flush.2 create mode 100644 doc/man/nvme_for_each_subsystem.2 create mode 100644 doc/man/nvme_for_each_subsystem_safe.2 create mode 100644 doc/man/nvme_format_nvm.2 create mode 100644 doc/man/nvme_free_ctrl.2 create mode 100644 doc/man/nvme_free_tree.2 create mode 100644 doc/man/nvme_fw_commit.2 create mode 100644 doc/man/nvme_fw_download.2 create mode 100644 doc/man/nvme_fw_download_seq.2 create mode 100644 doc/man/nvme_get_ana_log_len.2 create mode 100644 doc/man/nvme_get_ctrl_attr.2 create mode 100644 doc/man/nvme_get_ctrl_telemetry.2 create mode 100644 doc/man/nvme_get_directive_receive_length.2 create mode 100644 doc/man/nvme_get_feature_length.2 create mode 100644 doc/man/nvme_get_features.2 create mode 100644 doc/man/nvme_get_features_arbitration.2 create mode 100644 doc/man/nvme_get_features_async_event.2 create mode 100644 doc/man/nvme_get_features_auto_pst.2 create mode 100644 doc/man/nvme_get_features_endurance_event_cfg.2 create mode 100644 doc/man/nvme_get_features_err_recovery.2 create mode 100644 doc/man/nvme_get_features_hctm.2 create mode 100644 doc/man/nvme_get_features_host_behavior.2 create mode 100644 doc/man/nvme_get_features_host_id.2 create mode 100644 doc/man/nvme_get_features_host_mem_buf.2 create mode 100644 doc/man/nvme_get_features_irq_coalesce.2 create mode 100644 doc/man/nvme_get_features_irq_config.2 create mode 100644 doc/man/nvme_get_features_kato.2 create mode 100644 doc/man/nvme_get_features_lba_range.2 create mode 100644 doc/man/nvme_get_features_lba_sts_interval.2 create mode 100644 doc/man/nvme_get_features_nopsc.2 create mode 100644 doc/man/nvme_get_features_num_queues.2 create mode 100644 doc/man/nvme_get_features_plm_config.2 create mode 100644 doc/man/nvme_get_features_plm_window.2 create mode 100644 doc/man/nvme_get_features_power_mgmt.2 create mode 100644 doc/man/nvme_get_features_resv_mask.2 create mode 100644 doc/man/nvme_get_features_resv_persist.2 create mode 100644 doc/man/nvme_get_features_rrl.2 create mode 100644 doc/man/nvme_get_features_sanitize.2 create mode 100644 doc/man/nvme_get_features_sw_progress.2 create mode 100644 doc/man/nvme_get_features_temp_thresh.2 create mode 100644 doc/man/nvme_get_features_timestamp.2 create mode 100644 doc/man/nvme_get_features_volatile_wc.2 create mode 100644 doc/man/nvme_get_features_write_atomic.2 create mode 100644 doc/man/nvme_get_features_write_protect.2 create mode 100644 doc/man/nvme_get_host_telemetry.2 create mode 100644 doc/man/nvme_get_lba_status.2 create mode 100644 doc/man/nvme_get_log.2 create mode 100644 doc/man/nvme_get_log_ana.2 create mode 100644 doc/man/nvme_get_log_ana_groups.2 create mode 100644 doc/man/nvme_get_log_changed_ns_list.2 create mode 100644 doc/man/nvme_get_log_cmd_effects.2 create mode 100644 doc/man/nvme_get_log_create_telemetry_host.2 create mode 100644 doc/man/nvme_get_log_device_self_test.2 create mode 100644 doc/man/nvme_get_log_discovery.2 create mode 100644 doc/man/nvme_get_log_endurance_group.2 create mode 100644 doc/man/nvme_get_log_endurance_grp_evt.2 create mode 100644 doc/man/nvme_get_log_error.2 create mode 100644 doc/man/nvme_get_log_fw_slot.2 create mode 100644 doc/man/nvme_get_log_lba_status.2 create mode 100644 doc/man/nvme_get_log_page.2 create mode 100644 doc/man/nvme_get_log_predictable_lat_event.2 create mode 100644 doc/man/nvme_get_log_predictable_lat_nvmset.2 create mode 100644 doc/man/nvme_get_log_reservation.2 create mode 100644 doc/man/nvme_get_log_sanitize.2 create mode 100644 doc/man/nvme_get_log_smart.2 create mode 100644 doc/man/nvme_get_log_telemetry_ctrl.2 create mode 100644 doc/man/nvme_get_log_telemetry_host.2 create mode 100644 doc/man/nvme_get_new_host_telemetry.2 create mode 100644 doc/man/nvme_get_ns_attr.2 create mode 100644 doc/man/nvme_get_nsid.2 create mode 100644 doc/man/nvme_get_path_attr.2 create mode 100644 doc/man/nvme_get_property.2 create mode 100644 doc/man/nvme_get_subsys_attr.2 create mode 100644 doc/man/nvme_identify.2 create mode 100644 doc/man/nvme_identify_active_ns_list.2 create mode 100644 doc/man/nvme_identify_allocated_ns.2 create mode 100644 doc/man/nvme_identify_allocated_ns_list.2 create mode 100644 doc/man/nvme_identify_ctrl.2 create mode 100644 doc/man/nvme_identify_ctrl_list.2 create mode 100644 doc/man/nvme_identify_ns.2 create mode 100644 doc/man/nvme_identify_ns_descs.2 create mode 100644 doc/man/nvme_identify_ns_granularity.2 create mode 100644 doc/man/nvme_identify_nsid_ctrl_list.2 create mode 100644 doc/man/nvme_identify_nvmset_list.2 create mode 100644 doc/man/nvme_identify_primary_ctrl.2 create mode 100644 doc/man/nvme_identify_secondary_ctrl_list.2 create mode 100644 doc/man/nvme_identify_uuid.2 create mode 100644 doc/man/nvme_io_passthru.2 create mode 100644 doc/man/nvme_io_passthru64.2 create mode 100644 doc/man/nvme_namespace_attach_ctrls.2 create mode 100644 doc/man/nvme_namespace_detach_ctrls.2 create mode 100644 doc/man/nvme_namespace_filter.2 create mode 100644 doc/man/nvme_next_subsystem.2 create mode 100644 doc/man/nvme_ns_attach.2 create mode 100644 doc/man/nvme_ns_attach_ctrls.2 create mode 100644 doc/man/nvme_ns_compare.2 create mode 100644 doc/man/nvme_ns_dettach_ctrls.2 create mode 100644 doc/man/nvme_ns_flush.2 create mode 100644 doc/man/nvme_ns_get_ctrl.2 create mode 100644 doc/man/nvme_ns_get_fd.2 create mode 100644 doc/man/nvme_ns_get_lba_count.2 create mode 100644 doc/man/nvme_ns_get_lba_size.2 create mode 100644 doc/man/nvme_ns_get_lba_util.2 create mode 100644 doc/man/nvme_ns_get_name.2 create mode 100644 doc/man/nvme_ns_get_nsid.2 create mode 100644 doc/man/nvme_ns_get_subsystem.2 create mode 100644 doc/man/nvme_ns_get_sysfs_dir.2 create mode 100644 doc/man/nvme_ns_identify.2 create mode 100644 doc/man/nvme_ns_mgmt.2 create mode 100644 doc/man/nvme_ns_mgmt_create.2 create mode 100644 doc/man/nvme_ns_mgmt_delete.2 create mode 100644 doc/man/nvme_ns_read.2 create mode 100644 doc/man/nvme_ns_rescan.2 create mode 100644 doc/man/nvme_ns_verify.2 create mode 100644 doc/man/nvme_ns_write.2 create mode 100644 doc/man/nvme_ns_write_uncorrectable.2 create mode 100644 doc/man/nvme_ns_write_zeros.2 create mode 100644 doc/man/nvme_open.2 create mode 100644 doc/man/nvme_path_get_ana_state.2 create mode 100644 doc/man/nvme_path_get_name.2 create mode 100644 doc/man/nvme_path_get_ns.2 create mode 100644 doc/man/nvme_path_get_subsystem.2 create mode 100644 doc/man/nvme_path_get_sysfs_dir.2 create mode 100644 doc/man/nvme_paths_filter.2 create mode 100644 doc/man/nvme_psd_power_scale.2 create mode 100644 doc/man/nvme_read.2 create mode 100644 doc/man/nvme_refresh_topology.2 create mode 100644 doc/man/nvme_reset_topology.2 create mode 100644 doc/man/nvme_resv_acquire.2 create mode 100644 doc/man/nvme_resv_register.2 create mode 100644 doc/man/nvme_resv_release.2 create mode 100644 doc/man/nvme_resv_report.2 create mode 100644 doc/man/nvme_sanitize_nvm.2 create mode 100644 doc/man/nvme_scan.2 create mode 100644 doc/man/nvme_scan_ctrl.2 create mode 100644 doc/man/nvme_scan_ctrl_namespace_paths.2 create mode 100644 doc/man/nvme_scan_ctrl_namespaces.2 create mode 100644 doc/man/nvme_scan_filter.2 create mode 100644 doc/man/nvme_scan_subsystem_ctrls.2 create mode 100644 doc/man/nvme_scan_subsystem_namespaces.2 create mode 100644 doc/man/nvme_scan_subsystems.2 create mode 100644 doc/man/nvme_security_receive.2 create mode 100644 doc/man/nvme_security_send.2 create mode 100644 doc/man/nvme_set_attr.2 create mode 100644 doc/man/nvme_set_features.2 create mode 100644 doc/man/nvme_set_features_arbitration.2 create mode 100644 doc/man/nvme_set_features_async_event.2 create mode 100644 doc/man/nvme_set_features_auto_pst.2 create mode 100644 doc/man/nvme_set_features_endurance_evt_cfg.2 create mode 100644 doc/man/nvme_set_features_err_recovery.2 create mode 100644 doc/man/nvme_set_features_hctm.2 create mode 100644 doc/man/nvme_set_features_host_behavior.2 create mode 100644 doc/man/nvme_set_features_host_id.2 create mode 100644 doc/man/nvme_set_features_irq_coalesce.2 create mode 100644 doc/man/nvme_set_features_irq_config.2 create mode 100644 doc/man/nvme_set_features_lba_range.2 create mode 100644 doc/man/nvme_set_features_lba_sts_interval.2 create mode 100644 doc/man/nvme_set_features_nopsc.2 create mode 100644 doc/man/nvme_set_features_plm_config.2 create mode 100644 doc/man/nvme_set_features_plm_window.2 create mode 100644 doc/man/nvme_set_features_power_mgmt.2 create mode 100644 doc/man/nvme_set_features_resv_mask.2 create mode 100644 doc/man/nvme_set_features_resv_persist.2 create mode 100644 doc/man/nvme_set_features_rrl.2 create mode 100644 doc/man/nvme_set_features_sanitize.2 create mode 100644 doc/man/nvme_set_features_sw_progress.2 create mode 100644 doc/man/nvme_set_features_temp_thresh.2 create mode 100644 doc/man/nvme_set_features_timestamp.2 create mode 100644 doc/man/nvme_set_features_volatile_wc.2 create mode 100644 doc/man/nvme_set_features_write_atomic.2 create mode 100644 doc/man/nvme_set_features_write_protect.2 create mode 100644 doc/man/nvme_set_property.2 create mode 100644 doc/man/nvme_setup_ctrl_list.2 create mode 100644 doc/man/nvme_setup_dsm_range.2 create mode 100644 doc/man/nvme_setup_id_ns.2 create mode 100644 doc/man/nvme_status_to_errno.2 create mode 100644 doc/man/nvme_submit_admin_passthru.2 create mode 100644 doc/man/nvme_submit_admin_passthru64.2 create mode 100644 doc/man/nvme_submit_io_passthru.2 create mode 100644 doc/man/nvme_submit_io_passthru64.2 create mode 100644 doc/man/nvme_subsys_filter.2 create mode 100644 doc/man/nvme_subsystem_first_ctrl.2 create mode 100644 doc/man/nvme_subsystem_first_ns.2 create mode 100644 doc/man/nvme_subsystem_for_each_ctrl.2 create mode 100644 doc/man/nvme_subsystem_for_each_ctrl_safe.2 create mode 100644 doc/man/nvme_subsystem_for_each_ns.2 create mode 100644 doc/man/nvme_subsystem_for_each_ns_safe.2 create mode 100644 doc/man/nvme_subsystem_get_name.2 create mode 100644 doc/man/nvme_subsystem_get_nqn.2 create mode 100644 doc/man/nvme_subsystem_get_sysfs_dir.2 create mode 100644 doc/man/nvme_subsystem_next_ctrl.2 create mode 100644 doc/man/nvme_subsystem_next_ns.2 create mode 100644 doc/man/nvme_subsystem_reset.2 create mode 100644 doc/man/nvme_unlink_ctrl.2 create mode 100644 doc/man/nvme_verify.2 create mode 100644 doc/man/nvme_virtual_mgmt.2 create mode 100644 doc/man/nvme_write.2 create mode 100644 doc/man/nvme_write_uncorrectable.2 create mode 100644 doc/man/nvme_write_zeros.2 create mode 100644 doc/man/nvmf_add_ctrl.2 create mode 100644 doc/man/nvmf_add_ctrl_opts.2 create mode 100644 doc/man/nvmf_adrfam_str.2 create mode 100644 doc/man/nvmf_cms_str.2 create mode 100644 doc/man/nvmf_connect_disc_entry.2 create mode 100644 doc/man/nvmf_get_discovery_log.2 create mode 100644 doc/man/nvmf_hostid_from_file.2 create mode 100644 doc/man/nvmf_hostnqn_from_file.2 create mode 100644 doc/man/nvmf_hostnqn_generate.2 create mode 100644 doc/man/nvmf_prtype_str.2 create mode 100644 doc/man/nvmf_qptype_str.2 create mode 100644 doc/man/nvmf_sectype_str.2 create mode 100644 doc/man/nvmf_subtype_str.2 create mode 100644 doc/man/nvmf_treq_str.2 create mode 100644 doc/man/nvmf_trtype_str.2 create mode 100644 doc/man/struct nvme_aggregate_endurance_group_event.2 create mode 100644 doc/man/struct nvme_aggregate_predictable_lat_event.2 create mode 100644 doc/man/struct nvme_ana_group_desc.2 create mode 100644 doc/man/struct nvme_ana_log.2 create mode 100644 doc/man/struct nvme_cmd_effects_log.2 create mode 100644 doc/man/struct nvme_ctrl_list.2 create mode 100644 doc/man/struct nvme_dsm_range.2 create mode 100644 doc/man/struct nvme_eg_event_aggregate_log.2 create mode 100644 doc/man/struct nvme_endurance_group_log.2 create mode 100644 doc/man/struct nvme_error_log_page.2 create mode 100644 doc/man/struct nvme_fabrics_config.2 create mode 100644 doc/man/struct nvme_feat_auto_pst.2 create mode 100644 doc/man/struct nvme_feat_host_behavior.2 create mode 100644 doc/man/struct nvme_firmware_slot.2 create mode 100644 doc/man/struct nvme_frs.2 create mode 100644 doc/man/struct nvme_host_mem_buf_desc.2 create mode 100644 doc/man/struct nvme_id_ctrl.2 create mode 100644 doc/man/struct nvme_id_directives.2 create mode 100644 doc/man/struct nvme_id_ns.2 create mode 100644 doc/man/struct nvme_id_ns_granularity_desc.2 create mode 100644 doc/man/struct nvme_id_ns_granularity_list.2 create mode 100644 doc/man/struct nvme_id_nvmset_list.2 create mode 100644 doc/man/struct nvme_id_psd.2 create mode 100644 doc/man/struct nvme_id_uuid_list.2 create mode 100644 doc/man/struct nvme_id_uuid_list_entry.2 create mode 100644 doc/man/struct nvme_lba_range_type.2 create mode 100644 doc/man/struct nvme_lba_range_type_entry.2 create mode 100644 doc/man/struct nvme_lba_rd.2 create mode 100644 doc/man/struct nvme_lba_status.2 create mode 100644 doc/man/struct nvme_lba_status_desc.2 create mode 100644 doc/man/struct nvme_lba_status_log.2 create mode 100644 doc/man/struct nvme_lbaf.2 create mode 100644 doc/man/struct nvme_lbas_ns_element.2 create mode 100644 doc/man/struct nvme_mi_ctrl_heal_status.2 create mode 100644 doc/man/struct nvme_mi_nvm_ss_health_status.2 create mode 100644 doc/man/struct nvme_mi_osc.2 create mode 100644 doc/man/struct nvme_mi_port_pcie.2 create mode 100644 doc/man/struct nvme_mi_port_smb.2 create mode 100644 doc/man/struct nvme_mi_read_ctrl_info.2 create mode 100644 doc/man/struct nvme_mi_read_nvm_ss_info.2 create mode 100644 doc/man/struct nvme_mi_read_port_info.2 create mode 100644 doc/man/struct nvme_mi_read_sc_list.2 create mode 100644 doc/man/struct nvme_mi_vpd_hdr.2 create mode 100644 doc/man/struct nvme_mi_vpd_mr_common.2 create mode 100644 doc/man/struct nvme_mi_vpd_mra.2 create mode 100644 doc/man/struct nvme_mi_vpd_ppmra.2 create mode 100644 doc/man/struct nvme_mi_vpd_telem.2 create mode 100644 doc/man/struct nvme_mi_vpd_tra.2 create mode 100644 doc/man/struct nvme_ns_id_desc.2 create mode 100644 doc/man/struct nvme_ns_list.2 create mode 100644 doc/man/struct nvme_nvmset_attr.2 create mode 100644 doc/man/struct nvme_nvmset_predictable_lat_log.2 create mode 100644 doc/man/struct nvme_passthru_cmd.2 create mode 100644 doc/man/struct nvme_passthru_cmd64.2 create mode 100644 doc/man/struct nvme_persistent_event_log.2 create mode 100644 doc/man/struct nvme_plm_config.2 create mode 100644 doc/man/struct nvme_primary_ctrl_cap.2 create mode 100644 doc/man/struct nvme_registered_ctrl.2 create mode 100644 doc/man/struct nvme_registered_ctrl_ext.2 create mode 100644 doc/man/struct nvme_reservation_status.2 create mode 100644 doc/man/struct nvme_resv_notification_log.2 create mode 100644 doc/man/struct nvme_sanitize_log_page.2 create mode 100644 doc/man/struct nvme_secondary_ctrl.2 create mode 100644 doc/man/struct nvme_secondary_ctrl_list.2 create mode 100644 doc/man/struct nvme_self_test_log.2 create mode 100644 doc/man/struct nvme_smart_log.2 create mode 100644 doc/man/struct nvme_st_result.2 create mode 100644 doc/man/struct nvme_streams_directive_params.2 create mode 100644 doc/man/struct nvme_streams_directive_status.2 create mode 100644 doc/man/struct nvme_telemetry_log.2 create mode 100644 doc/man/struct nvme_timestamp.2 create mode 100644 doc/man/struct nvmf_connect_data.2 create mode 100644 doc/man/struct nvmf_disc_log_entry.2 create mode 100644 doc/man/struct nvmf_discovery_log.2 diff --git a/doc/libnvme.rst b/doc/libnvme.rst index 39c23592aa..7a18d40a4e 100644 --- a/doc/libnvme.rst +++ b/doc/libnvme.rst @@ -1,692 +1,737 @@ -**NVMe Admin command enums** +.. c:type:: struct nvme_fabrics_config -.. c:type:: enum nvme_admin_opcode +**Definition** - Known NVMe admin opcodes +:: -**Constants** + struct nvme_fabrics_config { + const char *transport; + const char *traddr; + const char *trsvcid; + const char *nqn; + const char *hostnqn; + const char *host_traddr; + const char *hostid; + int queue_size; + int nr_io_queues; + int reconnect_delay; + int ctrl_loss_tmo; + int keep_alive_tmo; + int nr_write_queues; + int nr_poll_queues; + int tos; + bool duplicate_connect; + bool disable_sqflow; + bool hdr_digest; + bool data_digest; + uint8_t rsvd[0x200]; + }; -``nvme_admin_delete_sq`` - *undescribed* +**Members** -``nvme_admin_create_sq`` - *undescribed* -``nvme_admin_get_log_page`` - *undescribed* -``nvme_admin_delete_cq`` - *undescribed* +.. c:function:: int nvmf_add_ctrl_opts (struct nvme_fabrics_config * cfg) -``nvme_admin_create_cq`` - *undescribed* -``nvme_admin_identify`` - *undescribed* +**Parameters** -``nvme_admin_abort_cmd`` +``struct nvme_fabrics_config * cfg`` *undescribed* -``nvme_admin_set_features`` - *undescribed* -``nvme_admin_get_features`` - *undescribed* +.. c:function:: nvme_ctrl_t nvmf_add_ctrl (struct nvme_fabrics_config * cfg) -``nvme_admin_async_event`` - *undescribed* -``nvme_admin_ns_mgmt`` - *undescribed* +**Parameters** -``nvme_admin_fw_commit`` +``struct nvme_fabrics_config * cfg`` *undescribed* -``nvme_admin_fw_download`` - *undescribed* -``nvme_admin_dev_self_test`` - *undescribed* +.. c:function:: int nvmf_get_discovery_log (nvme_ctrl_t c, struct nvmf_discovery_log ** logp, int max_retries) -``nvme_admin_ns_attach`` - *undescribed* -``nvme_admin_keep_alive`` - *undescribed* +**Parameters** -``nvme_admin_directive_send`` +``nvme_ctrl_t c`` *undescribed* -``nvme_admin_directive_recv`` +``struct nvmf_discovery_log ** logp`` *undescribed* -``nvme_admin_virtual_mgmt`` +``int max_retries`` *undescribed* -``nvme_admin_nvme_mi_send`` - *undescribed* -``nvme_admin_nvme_mi_recv`` - *undescribed* +.. c:function:: char * nvmf_hostnqn_generate () -``nvme_admin_dbbuf`` - *undescribed* -``nvme_admin_fabrics`` - *undescribed* +**Parameters** -``nvme_admin_format_nvm`` - *undescribed* -``nvme_admin_security_send`` - *undescribed* +.. c:function:: char * nvmf_hostnqn_from_file () -``nvme_admin_security_recv`` - *undescribed* -``nvme_admin_sanitize_nvm`` - *undescribed* +**Parameters** -``nvme_admin_get_lba_status`` - *undescribed* +.. c:function:: char * nvmf_hostid_from_file () +**Parameters** -.. c:type:: enum nvme_identify_cns +.. c:function:: const char * nvmf_trtype_str (__u8 trtype) -**Constants** -``NVME_IDENTIFY_CNS_NS`` - *undescribed* +**Parameters** -``NVME_IDENTIFY_CNS_CTRL`` +``__u8 trtype`` *undescribed* -``NVME_IDENTIFY_CNS_NS_ACTIVE_LIST`` - *undescribed* -``NVME_IDENTIFY_CNS_NS_DESC_LIST`` - *undescribed* +.. c:function:: const char * nvmf_adrfam_str (__u8 adrfam) -``NVME_IDENTIFY_CNS_NVMSET_LIST`` - *undescribed* -``NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST`` - *undescribed* +**Parameters** -``NVME_IDENTIFY_CNS_ALLOCATED_NS`` +``__u8 adrfam`` *undescribed* -``NVME_IDENTIFY_CNS_NS_CTRL_LIST`` - *undescribed* -``NVME_IDENTIFY_CNS_CTRL_LIST`` - *undescribed* +.. c:function:: const char * nvmf_subtype_str (__u8 subtype) -``NVME_IDENTIFY_CNS_PRIMARY_CTRL_CAP`` - *undescribed* -``NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST`` - *undescribed* +**Parameters** -``NVME_IDENTIFY_CNS_NS_GRANULARITY`` +``__u8 subtype`` *undescribed* -``NVME_IDENTIFY_CNS_UUID_LIST`` - *undescribed* +.. c:function:: const char * nvmf_treq_str (__u8 treq) +**Parameters** -.. c:type:: enum nvme_cmd_get_log_lid +``__u8 treq`` + *undescribed* -**Constants** +.. c:function:: const char * nvmf_sectype_str (__u8 sectype) -``NVME_LOG_LID_ERROR`` - *undescribed* -``NVME_LOG_LID_SMART`` - *undescribed* +**Parameters** -``NVME_LOG_LID_FW_SLOT`` +``__u8 sectype`` *undescribed* -``NVME_LOG_LID_CHANGED_NS`` - *undescribed* -``NVME_LOG_LID_CMD_EFFECTS`` - *undescribed* +.. c:function:: const char * nvmf_prtype_str (__u8 prtype) -``NVME_LOG_LID_DEVICE_SELF_TEST`` - *undescribed* -``NVME_LOG_LID_TELEMETRY_HOST`` - *undescribed* +**Parameters** -``NVME_LOG_LID_TELEMETRY_CTRL`` +``__u8 prtype`` *undescribed* -``NVME_LOG_LID_ENDURANCE_GROUP`` - *undescribed* -``NVME_LOG_LID_PREDICTABLE_LAT_NVMSET`` - *undescribed* +.. c:function:: const char * nvmf_qptype_str (__u8 qptype) -``NVME_LOG_LID_PREDICTABLE_LAT_AGG`` - *undescribed* -``NVME_LOG_LID_ANA`` - *undescribed* +**Parameters** -``NVME_LOG_LID_PERSISTENT_EVENT`` +``__u8 qptype`` *undescribed* -``NVME_LOG_LID_LBA_STATUS`` - *undescribed* -``NVME_LOG_LID_ENDURANCE_GRP_EVT`` - *undescribed* +.. c:function:: const char * nvmf_cms_str (__u8 cm) -``NVME_LOG_LID_DISCOVER`` - *undescribed* -``NVME_LOG_LID_RESERVATION`` - *undescribed* +**Parameters** -``NVME_LOG_LID_SANITIZE`` +``__u8 cm`` *undescribed* +.. c:function:: nvme_ctrl_t nvmf_connect_disc_entry (struct nvmf_disc_log_entry * e, const struct nvme_fabrics_config * defcfg, bool * discover) -.. c:type:: enum nvme_features_id - - -**Constants** +**Parameters** -``NVME_FEAT_FID_ARBITRATION`` +``struct nvmf_disc_log_entry * e`` *undescribed* -``NVME_FEAT_FID_POWER_MGMT`` +``const struct nvme_fabrics_config * defcfg`` *undescribed* -``NVME_FEAT_FID_LBA_RANGE`` +``bool * discover`` *undescribed* -``NVME_FEAT_FID_TEMP_THRESH`` - *undescribed* -``NVME_FEAT_FID_ERR_RECOVERY`` - *undescribed* +.. c:function:: int nvme_namespace_filter (const struct dirent * d) -``NVME_FEAT_FID_VOLATILE_WC`` - *undescribed* -``NVME_FEAT_FID_NUM_QUEUES`` - *undescribed* +**Parameters** -``NVME_FEAT_FID_IRQ_COALESCE`` - *undescribed* +``const struct dirent * d`` -``NVME_FEAT_FID_IRQ_CONFIG`` - *undescribed* -``NVME_FEAT_FID_WRITE_ATOMIC`` - *undescribed* +.. c:function:: int nvme_paths_filter (const struct dirent * d) -``NVME_FEAT_FID_ASYNC_EVENT`` - *undescribed* -``NVME_FEAT_FID_AUTO_PST`` - *undescribed* +**Parameters** -``NVME_FEAT_FID_HOST_MEM_BUF`` - *undescribed* +``const struct dirent * d`` -``NVME_FEAT_FID_TIMESTAMP`` - *undescribed* -``NVME_FEAT_FID_KATO`` - *undescribed* +.. c:function:: int nvme_ctrls_filter (const struct dirent * d) -``NVME_FEAT_FID_HCTM`` - *undescribed* -``NVME_FEAT_FID_NOPSC`` - *undescribed* +**Parameters** -``NVME_FEAT_FID_RRL`` - *undescribed* +``const struct dirent * d`` -``NVME_FEAT_FID_PLM_CONFIG`` - *undescribed* -``NVME_FEAT_FID_PLM_WINDOW`` - *undescribed* +.. c:function:: int nvme_subsys_filter (const struct dirent * d) -``NVME_FEAT_FID_LBA_STS_INTERVAL`` - *undescribed* -``NVME_FEAT_FID_HOST_BEHAVIOR`` - *undescribed* +**Parameters** -``NVME_FEAT_FID_SANITIZE`` - *undescribed* +``const struct dirent * d`` -``NVME_FEAT_FID_ENDURANCE_EVT_CFG`` - *undescribed* -``NVME_FEAT_FID_SW_PROGRESS`` - *undescribed* +.. c:function:: int nvme_scan_subsystems (struct dirent *** subsys) -``NVME_FEAT_FID_HOST_ID`` - *undescribed* -``NVME_FEAT_FID_RESV_MASK`` - *undescribed* +**Parameters** -``NVME_FEAT_RESV_PERSIST`` - *undescribed* - -``NVME_FEAT_FID_WRITE_PROTECT`` - *undescribed* +``struct dirent *** subsys`` +.. c:function:: int nvme_scan_subsystem_ctrls (nvme_subsystem_t s, struct dirent *** ctrls) -.. c:type:: enum nvme_get_features_sel +**Parameters** +``nvme_subsystem_t s`` + *undescribed* -**Constants** +``struct dirent *** ctrls`` -``NVME_GET_FEATURES_SEL_CURRENT`` - *undescribed* -``NVME_GET_FEATURES_SEL_DEFAULT`` - *undescribed* +.. c:function:: int nvme_scan_subsystem_namespaces (nvme_subsystem_t s, struct dirent *** namespaces) -``NVME_GET_FEATURES_SEL_SAVED`` - *undescribed* +**Parameters** +``nvme_subsystem_t s`` + *undescribed* +``struct dirent *** namespaces`` -.. c:type:: enum nvme_cmd_format_mset +.. c:function:: int nvme_scan_ctrl_namespace_paths (nvme_ctrl_t c, struct dirent *** namespaces) -**Constants** -``NVME_FORMAT_MSET_SEPARATE`` - *undescribed* +**Parameters** -``NVME_FORMAT_MSET_EXTENEDED`` +``nvme_ctrl_t c`` *undescribed* +``struct dirent *** namespaces`` - -.. c:type:: enum nvme_cmd_format_pi +.. c:function:: int nvme_scan_ctrl_namespaces (nvme_ctrl_t c, struct dirent *** namespaces) -**Constants** +**Parameters** -``NVME_FORMAT_PI_DISABLE`` +``nvme_ctrl_t c`` *undescribed* -``NVME_FORMAT_PI_TYPE1`` - *undescribed* +``struct dirent *** namespaces`` -``NVME_FORMAT_PI_TYPE2`` - *undescribed* -``NVME_FORMAT_PI_TYPE3`` - *undescribed* +.. c:type:: struct nvme_passthru_cmd -.. c:type:: enum nvme_cmd_format_ses +**Definition** +:: -**Constants** + struct nvme_passthru_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 result; + }; -``NVME_FORMAT_SES_NONE`` - *undescribed* +**Members** -``NVME_FORMAT_SES_USER_DATA_ERASE`` - *undescribed* +``opcode`` + Operation code, see :c:type:`enum nvme_io_opcodes ` and :c:type:`enum nvme_admin_opcodes ` -``NVME_FORMAT_SES_CRYPTO_ERASE`` - *undescribed* +``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) -.. c:type:: enum nvme_ns_mgmt_sel +``cdw3`` + Command Dword 3 (no spec defined use) +``metadata`` + User space address to metadata buffer (NULL if not used) -**Constants** +``addr`` + User space address to data buffer (NULL if not used) -``NVME_NS_MGMT_SEL_CREATE`` - *undescribed* +``metadata_len`` + Metadata buffer transfer length -``NVME_NS_MGMT_SEL_DELETE`` - *undescribed* +``data_len`` + Data buffer transfer length +``cdw10`` + Command Dword 10 (command specific) +``cdw11`` + Command Dword 11 (command specific) +``cdw12`` + Command Dword 12 (command specific) -.. c:type:: enum nvme_ns_attach_sel +``cdw13`` + Command Dword 13 (command specific) - NVME_NS_ATTACH_SEL_CTRL_ATTACH: NVME_NP_ATTACH_SEL_CTRL_DEATTACH: +``cdw14`` + Command Dword 14 (command specific) -**Constants** +``cdw15`` + Command Dword 15 (command specific) -``NVME_NS_ATTACH_SEL_CTRL_ATTACH`` - *undescribed* +``timeout_ms`` + If non-zero, overrides system default timeout in milliseconds -``NVME_NS_ATTACH_SEL_CTRL_DEATTACH`` - *undescribed* +``result`` + Set on completion to the command's CQE DWORD 0 controller response -.. c:type:: enum nvme_fw_commit_ca +.. c:type:: struct nvme_passthru_cmd64 -**Constants** -``NVME_FW_COMMIT_CA_REPLACE`` - *undescribed* +**Definition** -``NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE`` - *undescribed* +:: -``NVME_FW_COMMIT_CA_SET_ACTIVE`` - *undescribed* + 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; + }; -``NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE_IMMEDIATE`` - *undescribed* +**Members** -``NVME_FW_COMMIT_CA_REPLACE_BOOT_PARTITION`` - *undescribed* +``opcode`` + Operation code, see :c:type:`enum nvme_io_opcodes ` and :c:type:`enum nvme_admin_opcodes ` -``NVME_FW_COMMIT_CA_ACTIVATE_BOOT_PARTITION`` - *undescribed* +``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) -.. c:type:: enum nvme_directive_dtype +``cdw3`` + Command Dword 3 (no spec defined use) +``metadata`` + User space address to metadata buffer (NULL if not used) -**Constants** +``addr`` + User space address to data buffer (NULL if not used) -``NVME_DIRECTIVE_DTYPE_IDENTIFY`` - *undescribed* +``metadata_len`` + Metadata buffer transfer length -``NVME_DIRECTIVE_DTYPE_STREAMS`` - *undescribed* +``data_len`` + Data buffer transfer length +``cdw10`` + Command Dword 10 (command specific) +``cdw11`` + Command Dword 11 (command specific) +``cdw12`` + Command Dword 12 (command specific) -.. c:type:: enum nvme_cmd_directive_receive_identify_doper +``cdw13`` + Command Dword 13 (command specific) +``cdw14`` + Command Dword 14 (command specific) -**Constants** +``cdw15`` + Command Dword 15 (command specific) -``NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM`` - *undescribed* +``timeout_ms`` + If non-zero, overrides system default timeout in milliseconds +``rsvd2`` + Reserved for future use (and fills an impicit struct pad +``result`` + Set on completion to the command's CQE DWORD 0-1 controller response -.. c:type:: enum nvme_cmd_directive_receive_streams_doper +.. c:function:: int nvme_submit_admin_passthru64 (int fd, struct nvme_passthru_cmd64 * cmd, __u64 * result) -**Constants** + Submit a 64-bit nvme passthrough admin command -``NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM`` - *undescribed* +**Parameters** -``NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS`` - *undescribed* +``int fd`` + File descriptor of nvme device -``NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE`` - *undescribed* +``struct nvme_passthru_cmd64 * cmd`` + The nvme admin command to send +``__u64 * result`` + Optional field to return the result from the CQE DW0-1 +**Description** +Uses NVME_IOCTL_ADMIN64_CMD for the ioctl request. -.. c:type:: enum nvme_cmd_directive_send_identify_doper +**Return** +The nvme command status if a response was received or -1 + with errno set otherwise. -**Constants** -``NVME_DIRECTIVE_SEND_IDENTIFY_DOPER_ENDIR`` - *undescribed* +.. c:function:: int nvme_admin_passthru64 (int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, __u32 data_len, void * data, __u32 metadata_len, void * metadata, __u32 timeout_ms, __u64 * result) + Submit an nvme passthrough command +**Parameters** +``int fd`` + File descriptor of nvme device -.. c:type:: enum nvme_cmd_directive_send_identify_endir +``__u8 opcode`` + The nvme io command to send +``__u8 flags`` + NVMe command flags (not used) -**Constants** +``__u16 rsvd`` + Reserevd for future use -``NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_DISABLE`` - *undescribed* - -``NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_ENABLE`` - *undescribed* - - - - -.. c:type:: enum nvme_cmd_directive_send_streams_doper +``__u32 nsid`` + Namespace identifier +``__u32 cdw2`` + Command dword 2 -**Constants** +``__u32 cdw3`` + Command dword 3 -``NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_IDENTIFIER`` - *undescribed* +``__u32 cdw10`` + Command dword 10 -``NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE`` - *undescribed* +``__u32 cdw11`` + Command dword 11 +``__u32 cdw12`` + Command dword 12 +``__u32 cdw13`` + Command dword 13 +``__u32 cdw14`` + Command dword 14 -.. c:type:: enum nvme_sanitize_sanact +``__u32 cdw15`` + Command dword 15 +``__u32 data_len`` + Length of the data transfered in this command in bytes -**Constants** +``void * data`` + Pointer to user address of the data buffer -``NVME_SANITIZE_SANACT_EXIT_FAILURE`` - *undescribed* +``__u32 metadata_len`` + Length of metadata transfered in this command -``NVME_SANITIZE_SANACT_START_BLOCK_ERASE`` - *undescribed* +``void * metadata`` + Pointer to user address of the metadata buffer -``NVME_SANITIZE_SANACT_START_OVERWRITE`` - *undescribed* +``__u32 timeout_ms`` + How long the kernel waits for the command to complete -``NVME_SANITIZE_SANACT_START_CRYPTO_ERASE`` - *undescribed* +``__u64 * result`` + Optional field to return the result from the CQE dword 0 +**Description** +Parameterized form of nvme_submit_admin_passthru64(). This sets up and +submits a :c:type:`struct nvme_passthru_cmd64 `. +Known values for **opcode** are defined in :c:type:`enum nvme_admin_opcode `. -.. c:type:: enum nvme_dst_stc +**Return** +The nvme command status if a response was received or -1 + with errno set otherwise. -**Constants** -``NVME_DST_STC_SHORT`` - *undescribed* +.. c:function:: int nvme_submit_admin_passthru (int fd, struct nvme_passthru_cmd * cmd, __u32 * result) -``NVME_DST_STC_LONG`` - *undescribed* + Submit an nvme passthrough admin command -``NVME_DST_STC_VS`` - *undescribed* +**Parameters** -``NVME_DST_STC_ABORT`` - *undescribed* +``int fd`` + File descriptor of nvme device +``struct nvme_passthru_cmd * cmd`` + The nvme admin command to send +``__u32 * result`` + Optional field to return the result from the CQE DW0 +**Description** -.. c:type:: enum nvme_virt_mgmt_act +Uses NVME_IOCTL_ADMIN_CMD for the ioctl request. +**Return** -**Constants** +The nvme command status if a response was received or -1 + with errno set otherwise. -``NVME_VIRT_MGMT_ACT_PRIM_CTRL_FLEX_ALLOC`` - *undescribed* -``NVME_VIRT_MGMT_ACT_OFFLINE_SEC_CTRL`` - *undescribed* +.. c:function:: int nvme_admin_passthru (int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, __u32 data_len, void * data, __u32 metadata_len, void * metadata, __u32 timeout_ms, __u32 * result) -``NVME_VIRT_MGMT_ACT_ASSIGN_SEC_CTRL`` - *undescribed* + Submit an nvme passthrough command -``NVME_VIRT_MGMT_ACT_ONLINE_SEC_CTRL`` - *undescribed* +**Parameters** +``int fd`` + File descriptor of nvme device +``__u8 opcode`` + The nvme io command to send +``__u8 flags`` + NVMe command flags (not used) -.. c:type:: enum nvme_virt_mgmt_rt +``__u16 rsvd`` + Reserevd for future use +``__u32 nsid`` + Namespace identifier -**Constants** +``__u32 cdw2`` + Command dword 2 -``NVME_VIRT_MGMT_RT_VQ_RESOURCE`` - *undescribed* +``__u32 cdw3`` + Command dword 3 -``NVME_VIRT_MGMT_RT_VI_RESOURCE`` - *undescribed* +``__u32 cdw10`` + Command dword 10 +``__u32 cdw11`` + Command dword 11 -.. c:function:: int nvme_identify (int fd, enum nvme_identify_cns cns, __u32 nsid, __u16 cntid, __u16 nvmsetid, __u8 uuidx, void * data) +``__u32 cdw12`` + Command dword 12 - Send the NVMe Identify command +``__u32 cdw13`` + Command dword 13 -**Parameters** +``__u32 cdw14`` + Command dword 14 -``int fd`` - File descriptor of nvme device +``__u32 cdw15`` + Command dword 15 -``enum nvme_identify_cns cns`` - The Controller or Namespace structure, see **enum** nvme_identify_cns +``__u32 data_len`` + Length of the data transfered in this command in bytes -``__u32 nsid`` - Namespace identifier, if applicable +``void * data`` + Pointer to user address of the data buffer -``__u16 cntid`` - The Controller Identifier, if applicable +``__u32 metadata_len`` + Length of metadata transfered in this command -``__u16 nvmsetid`` - The NVMe Set ID if CNS is 04h +``void * metadata`` + Pointer to user address of the metadata buffer -``__u8 uuidx`` - UUID Index if controller supports this id selection method +``__u32 timeout_ms`` + How long the kernel waits for the command to complete -``void * data`` - User space destination address to transfer the data +``__u32 * result`` + Optional field to return the result from the CQE dword 0 **Description** -The Identify command returns a data buffer that describes information about -the NVM subsystem, the controller or the namespace(s). +Parameterized form of nvme_submit_admin_passthru(). This sets up and +submits a :c:type:`struct nvme_passthru_cmd `. + +Known values for **opcode** are defined in :c:type:`enum nvme_admin_opcode `. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received or -1 + with errno set otherwise. -.. c:function:: int nvme_identify_ctrl (int fd, struct nvme_id_ctrl * id) +.. c:function:: int nvme_submit_io_passthru64 (int fd, struct nvme_passthru_cmd64 * cmd, __u64 * result) - Retrieves nvme identify controller + Submit a 64-bit nvme passthrough command **Parameters** ``int fd`` File descriptor of nvme device - id: User space destination address to transfer the data, -``struct nvme_id_ctrl * id`` - *undescribed* +``struct nvme_passthru_cmd64 * cmd`` + The nvme io command to send -**Description** +``__u64 * result`` + Optional field to return the result from the CQE DW0-1 -Sends nvme identify with CNS value ``NVME_IDENTIFY_CNS_CTRL``. +**Description** -See :c:type:`struct nvme_id_ctrl ` for details on the data returned. +Uses NVME_IOCTL_IO64_CMD for the ioctl request. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received or -1 + with errno set otherwise. -.. c:function:: int nvme_identify_ns (int fd, __u32 nsid, struct nvme_id_ns * ns) +.. c:function:: int nvme_io_passthru64 (int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, __u32 data_len, void * data, __u32 metadata_len, void * metadata, __u32 timeout_ms, __u64 * result) - Retrieves nvme identify namespace + Submit an nvme io passthrough command **Parameters** ``int fd`` File descriptor of nvme device +``__u8 opcode`` + The nvme io command to send + +``__u8 flags`` + NVMe command flags (not used) + +``__u16 rsvd`` + Reserevd for future use + ``__u32 nsid`` - Namespace to identify + Namespace identifier -``struct nvme_id_ns * ns`` - User space destination address to transfer the data +``__u32 cdw2`` + Command dword 2 -**Description** +``__u32 cdw3`` + Command dword 3 -If the Namespace Identifier (NSID) field specifies an active NSID, then the -Identify Namespace data structure is returned to the host for that specified -namespace. +``__u32 cdw10`` + Command dword 10 -If the controller supports the Namespace Management capability and the NSID -field is set to ``NVME_NSID_ALL``, then the controller returns an Identify Namespace -data structure that specifies capabilities that are common across namespaces -for this controller. +``__u32 cdw11`` + Command dword 11 -See :c:type:`struct nvme_id_ns ` for details on the structure returned. +``__u32 cdw12`` + Command dword 12 -**Return** +``__u32 cdw13`` + Command dword 13 -The nvme command status if a response was received or -1 with errno - set otherwise. +``__u32 cdw14`` + Command dword 14 +``__u32 cdw15`` + Command dword 15 -.. c:function:: int nvme_identify_allocated_ns (int fd, __u32 nsid, struct nvme_id_ns * ns) +``__u32 data_len`` + Length of the data transfered in this command in bytes - Same as nvme_identify_ns, but only for allocated namespaces +``void * data`` + Pointer to user address of the data buffer -**Parameters** +``__u32 metadata_len`` + Length of metadata transfered in this command -``int fd`` - File descriptor of nvme device +``void * metadata`` + Pointer to user address of the metadata buffer -``__u32 nsid`` - Namespace to identify +``__u32 timeout_ms`` + How long the kernel waits for the command to complete -``struct nvme_id_ns * ns`` - User space destination address to transfer the data +``__u64 * result`` + Optional field to return the result from the CQE dword 0 + +**Description** + +Parameterized form of nvme_submit_io_passthru64(). This sets up and submits +a :c:type:`struct nvme_passthru_cmd64 `. + +Known values for **opcode** are defined in :c:type:`enum nvme_io_opcode `. **Return** @@ -694,869 +739,774 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_identify_active_ns_list (int fd, __u32 nsid, struct nvme_ns_list * list) +.. c:function:: int nvme_submit_io_passthru (int fd, struct nvme_passthru_cmd * cmd, __u32 * result) - Retrieves active namespaces id list + Submit an nvme passthrough command **Parameters** ``int fd`` File descriptor of nvme device -``__u32 nsid`` - Return namespaces greater than this identifer +``struct nvme_passthru_cmd * cmd`` + The nvme io command to send -``struct nvme_ns_list * list`` - *undescribed* +``__u32 * result`` + Optional field to return the result from the CQE DW0 **Description** -A list of 1024 namespace IDs is returned to the host containing NSIDs in -increasing order that are greater than the value specified in the Namespace -Identifier (nsid) field of the command. - -See :c:type:`struct nvme_ns_list ` for the definition of the returned structure. +Uses NVME_IOCTL_IO_CMD for the ioctl request. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received or -1 + with errno set otherwise. -.. c:function:: int nvme_identify_allocated_ns_list (int fd, __u32 nsid, struct nvme_ns_list * list) +.. c:function:: int nvme_io_passthru (int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, __u32 data_len, void * data, __u32 metadata_len, void * metadata, __u32 timeout_ms, __u32 * result) - Retrieves allocated namespace id list + Submit an nvme io passthrough command **Parameters** ``int fd`` File descriptor of nvme device +``__u8 opcode`` + The nvme io command to send + +``__u8 flags`` + NVMe command flags (not used) + +``__u16 rsvd`` + Reserevd for future use + ``__u32 nsid`` - Return namespaces greater than this identifer + Namespace identifier -``struct nvme_ns_list * list`` - *undescribed* +``__u32 cdw2`` + Command dword 2 -**Description** +``__u32 cdw3`` + Command dword 3 -A list of 1024 namespace IDs is returned to the host containing NSIDs in -increasing order that are greater than the value specified in the Namespace -Identifier (nsid) field of the command. +``__u32 cdw10`` + Command dword 10 -See :c:type:`struct nvme_ns_list ` for the definition of the returned structure. +``__u32 cdw11`` + Command dword 11 -**Return** +``__u32 cdw12`` + Command dword 12 -The nvme command status if a response was received or -1 with errno - set otherwise. +``__u32 cdw13`` + Command dword 13 +``__u32 cdw14`` + Command dword 14 -.. c:function:: int nvme_identify_ctrl_list (int fd, __u16 cntid, struct nvme_ctrl_list * ctrlist) +``__u32 cdw15`` + Command dword 15 - Retrieves identify controller list +``__u32 data_len`` + Length of the data transfered in this command in bytes -**Parameters** +``void * data`` + Pointer to user address of the data buffer -``int fd`` - File descriptor of nvme device +``__u32 metadata_len`` + Length of metadata transfered in this command -``__u16 cntid`` - *undescribed* +``void * metadata`` + Pointer to user address of the metadata buffer -``struct nvme_ctrl_list * ctrlist`` - *undescribed* +``__u32 timeout_ms`` + How long the kernel waits for the command to complete + +``__u32 * result`` + Optional field to return the result from the CQE dword 0 **Description** -Up to 2047 controller identifiers is returned containing a controller -identifier greater than or equal to the controller identifier specified in -**cntid**. +Parameterized form of nvme_submit_io_passthru(). This sets up and submits +a :c:type:`struct nvme_passthru_cmd `. -See :c:type:`struct nvme_ctrl_list ` for a definition of the structure returned. +Known values for **opcode** are defined in :c:type:`enum nvme_io_opcode `. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received or -1 + with errno set otherwise. -.. c:function:: int nvme_identify_nsid_ctrl_list (int fd, __u32 nsid, __u16 cntid, struct nvme_ctrl_list * ctrlist) +.. c:function:: int nvme_subsystem_reset (int fd) + Initiate a subsystem reset **Parameters** ``int fd`` File descriptor of nvme device -``__u32 nsid`` - Return controllers that are attached to this nsid - -``__u16 cntid`` - *undescribed* - -``struct nvme_ctrl_list * ctrlist`` - *undescribed* - **Description** -Up to 2047 controller identifiers is returned containing a controller -identifier greater than or equal to the controller identifier specified in -**cntid**. - -See :c:type:`struct nvme_ctrl_list ` for a definition of the structure returned. +This should only be sent to controller handles, not to namespaces. **Return** -The nvme command status if a response was received or -1 +Zero if a subsystem reset was initiated or -1 with errno set + otherwise. -.. c:function:: int nvme_identify_ns_descs (int fd, __u32 nsid, struct nvme_ns_id_desc * descs) +.. c:function:: int nvme_ctrl_reset (int fd) - Retrieves namespace descriptor list + Initiate a controller reset **Parameters** ``int fd`` File descriptor of nvme device -``__u32 nsid`` - The namespace id to retrieve destriptors - -``struct nvme_ns_id_desc * descs`` - User space destination address to transfer the data - **Description** -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'. - -See :c:type:`struct nvme_ns_id_desc ` for the definition of the returned structure. +This should only be sent to controller handles, not to namespaces. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +Zero if a reset was initiated or -1 with errno set otherwise. -.. c:function:: int nvme_identify_nvmset_list (int fd, __u16 nvmsetid, struct nvme_id_nvmset_list * nvmset) +.. c:function:: int nvme_ns_rescan (int fd) - Retrieves NVM Set List + Initiate a controller rescan **Parameters** ``int fd`` File descriptor of nvme device -``__u16 nvmsetid`` - *undescribed* - -``struct nvme_id_nvmset_list * nvmset`` - User space destination address to transfer the data - **Description** -Retrieves an NVM Set List, struct nvme_id_nvmset. The data structure is an -ordered list by NVM Set Identifier, starting with the first NVM Set -Identifier supported by the NVM subsystem that is equal to or greater than -the NVM Set Identifier. - -See :c:type:`struct nvme_id_nvmset_list ` for the defintion of the returned structure. +This should only be sent to controller handles, not to namespaces. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +Zero if a rescan was initiated or -1 with errno set otherwise. -.. c:function:: int nvme_identify_primary_ctrl (int fd, __u16 cntid, struct nvme_primary_ctrl_cap * cap) +.. c:function:: int nvme_get_nsid (int fd) - Retrieve NVMe Primary Controller identification :c:type:`fd`: + Retrieve the NSID from a namespace file descriptor **Parameters** ``int fd`` - *undescribed* - -``__u16 cntid`` - *undescribed* - -``struct nvme_primary_ctrl_cap * cap`` + File descriptor of nvme namespace **Description** -See :c:type:`struct nvme_primary_ctrl_cap ` for the defintion of the returned structure, **cap**. +This should only be sent to namespace handles, not to controllers. **Return** -The nvme command status if a response was received or -1 - with errno set otherwise. - - -.. c:function:: int nvme_identify_secondary_ctrl_list (int fd, __u16 cntid, struct nvme_secondary_ctrl_list * list) - - Retrieves secondary controller list +The namespace identifier if a succecssful or -1 with errno set + otherwise. -**Parameters** -``int fd`` - File descriptor of nvme device +**NVMe Admin command enums** -``__u16 cntid`` - Return controllers starting at this identifier -``struct nvme_secondary_ctrl_list * list`` - *undescribed* -**Description** -A Secondary Controller List is returned to the host for up to 127 secondary -controllers associated with the primary controller processing this command. -The list contains entries for controller identifiers greater than or equal -to the value specified in the Controller Identifier (cntid). +.. c:type:: enum nvme_admin_opcode -See :c:type:`struct nvme_secondary_ctrls_list ` for a defintion of the returned -structure. + Known NVMe admin opcodes -**Return** +**Constants** -The nvme command status if a response was received or -1 with errno - set otherwise. +``nvme_admin_delete_sq`` + *undescribed* +``nvme_admin_create_sq`` + *undescribed* -.. c:function:: int nvme_identify_ns_granularity (int fd, struct nvme_id_ns_granularity_list * list) +``nvme_admin_get_log_page`` + *undescribed* - Retrieves namespace granularity identification +``nvme_admin_delete_cq`` + *undescribed* -**Parameters** +``nvme_admin_create_cq`` + *undescribed* -``int fd`` - File descriptor of nvme device +``nvme_admin_identify`` + *undescribed* -``struct nvme_id_ns_granularity_list * list`` +``nvme_admin_abort_cmd`` *undescribed* -**Description** +``nvme_admin_set_features`` + *undescribed* -If the controller supports reporting of Namespace Granularity, then a -Namespace Granularity List is returned to the host for up to sixteen -namespace granularity descriptors +``nvme_admin_get_features`` + *undescribed* -See :c:type:`struct nvme_id_ns_granularity_list ` for the definition of the returned -structure. +``nvme_admin_async_event`` + *undescribed* -**Return** +``nvme_admin_ns_mgmt`` + *undescribed* -The nvme command status if a response was received or -1 with errno - set otherwise. +``nvme_admin_fw_commit`` + *undescribed* +``nvme_admin_fw_download`` + *undescribed* -.. c:function:: int nvme_identify_uuid (int fd, struct nvme_id_uuid_list * list) +``nvme_admin_dev_self_test`` + *undescribed* - Retrieves device's UUIDs +``nvme_admin_ns_attach`` + *undescribed* -**Parameters** +``nvme_admin_keep_alive`` + *undescribed* -``int fd`` - File descriptor of nvme device +``nvme_admin_directive_send`` + *undescribed* -``struct nvme_id_uuid_list * list`` +``nvme_admin_directive_recv`` *undescribed* -**Description** +``nvme_admin_virtual_mgmt`` + *undescribed* -Each UUID List entry is either 0h, the NVMe Invalid UUID, or a valid UUID. -Valid UUIDs are those which are non-zero and are not the NVMe Invalid UUID. +``nvme_admin_nvme_mi_send`` + *undescribed* -See :c:type:`struct nvme_id_uuid_list ` for the definition of the returned structure. +``nvme_admin_nvme_mi_recv`` + *undescribed* -**Return** +``nvme_admin_dbbuf`` + *undescribed* -The nvme command status if a response was received or -1 with errno - set otherwise. +``nvme_admin_fabrics`` + *undescribed* +``nvme_admin_format_nvm`` + *undescribed* -.. c:function:: int nvme_get_log (int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, __u8 lsp, __u16 lsi, bool rae, __u8 uuidx, __u32 len, void * log) +``nvme_admin_security_send`` + *undescribed* - NVMe Admin Get Log command +``nvme_admin_security_recv`` + *undescribed* -**Parameters** +``nvme_admin_sanitize_nvm`` + *undescribed* -``int fd`` - File descriptor of nvme device +``nvme_admin_get_lba_status`` + *undescribed* -``enum nvme_cmd_get_log_lid lid`` - Log page identifier, see :c:type:`enum nvme_cmd_get_log_lid ` for known values -``__u32 nsid`` - Namespace identifier, if applicable -``__u64 lpo`` - Log page offset for partial log transfers -``__u8 lsp`` - Log specific field +.. c:type:: enum nvme_identify_cns -``__u16 lsi`` - Endurance group information -``bool rae`` - Retain asynchronous events +**Constants** -``__u8 uuidx`` - UUID selection, if supported +``NVME_IDENTIFY_CNS_NS`` + *undescribed* -``__u32 len`` - Length of provided user buffer to hold the log data in bytes +``NVME_IDENTIFY_CNS_CTRL`` + *undescribed* -``void * log`` - User space destination address to transfer the data +``NVME_IDENTIFY_CNS_NS_ACTIVE_LIST`` + *undescribed* -**Return** +``NVME_IDENTIFY_CNS_NS_DESC_LIST`` + *undescribed* -The nvme command status if a response was received or -1 with errno - set otherwise. +``NVME_IDENTIFY_CNS_NVMSET_LIST`` + *undescribed* +``NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST`` + *undescribed* -.. c:function:: int nvme_get_log_error (int fd, unsigned nr_entries, bool rae, struct nvme_error_log_page * log) +``NVME_IDENTIFY_CNS_ALLOCATED_NS`` + *undescribed* - Retrieve nvme error log +``NVME_IDENTIFY_CNS_NS_CTRL_LIST`` + *undescribed* -**Parameters** +``NVME_IDENTIFY_CNS_CTRL_LIST`` + *undescribed* -``int fd`` - File descriptor of nvme device +``NVME_IDENTIFY_CNS_PRIMARY_CTRL_CAP`` + *undescribed* -``unsigned nr_entries`` +``NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST`` *undescribed* -``bool rae`` - Retain asynchronous events +``NVME_IDENTIFY_CNS_NS_GRANULARITY`` + *undescribed* -``struct nvme_error_log_page * log`` +``NVME_IDENTIFY_CNS_UUID_LIST`` *undescribed* -**Description** -This log page is used to describe extended error information for a command -that completed with error, or may report an error that is not specific to a -particular command. -**Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +.. c:type:: enum nvme_cmd_get_log_lid -.. c:function:: int nvme_get_log_smart (int fd, __u32 nsid, bool rae, struct nvme_smart_log * log) +**Constants** - Retrieve nvme smart log +``NVME_LOG_LID_ERROR`` + *undescribed* -**Parameters** +``NVME_LOG_LID_SMART`` + *undescribed* -``int fd`` - File descriptor of nvme device +``NVME_LOG_LID_FW_SLOT`` + *undescribed* -``__u32 nsid`` - Optional namespace identifier +``NVME_LOG_LID_CHANGED_NS`` + *undescribed* -``bool rae`` - Retain asynchronous events +``NVME_LOG_LID_CMD_EFFECTS`` + *undescribed* -``struct nvme_smart_log * log`` +``NVME_LOG_LID_DEVICE_SELF_TEST`` *undescribed* -**Description** +``NVME_LOG_LID_TELEMETRY_HOST`` + *undescribed* -This log page is used to provide SMART and general health information. The -information provided is over the life of the controller and is retained -across power cycles. To request the controller log page, the namespace -identifier specified is FFFFFFFFh. The controller may also support -requesting the log page on a per namespace basis, as indicated by bit 0 of -the LPA field in the Identify Controller data structure. +``NVME_LOG_LID_TELEMETRY_CTRL`` + *undescribed* -**Return** +``NVME_LOG_LID_ENDURANCE_GROUP`` + *undescribed* -The nvme command status if a response was received or -1 with errno - set otherwise. +``NVME_LOG_LID_PREDICTABLE_LAT_NVMSET`` + *undescribed* +``NVME_LOG_LID_PREDICTABLE_LAT_AGG`` + *undescribed* -.. c:function:: int nvme_get_log_fw_slot (int fd, bool rae, struct nvme_firmware_slot * log) +``NVME_LOG_LID_ANA`` + *undescribed* - Retrieves the controller firmware log +``NVME_LOG_LID_PERSISTENT_EVENT`` + *undescribed* -**Parameters** +``NVME_LOG_LID_LBA_STATUS`` + *undescribed* -``int fd`` - File descriptor of nvme device +``NVME_LOG_LID_ENDURANCE_GRP_EVT`` + *undescribed* -``bool rae`` - Retain asynchronous events +``NVME_LOG_LID_DISCOVER`` + *undescribed* -``struct nvme_firmware_slot * log`` +``NVME_LOG_LID_RESERVATION`` *undescribed* -**Description** +``NVME_LOG_LID_SANITIZE`` + *undescribed* -This log page is used to describe the firmware revision stored in each -firmware slot supported. The firmware revision is indicated as an ASCII -string. The log page also indicates the active slot number. -**Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +.. c:type:: enum nvme_features_id -.. c:function:: int nvme_get_log_changed_ns_list (int fd, bool rae, struct nvme_ns_list * log) - Retrieve namespace changed list +**Constants** -**Parameters** +``NVME_FEAT_FID_ARBITRATION`` + *undescribed* -``int fd`` - File descriptor of nvme device +``NVME_FEAT_FID_POWER_MGMT`` + *undescribed* -``bool rae`` - Retain asynchronous events +``NVME_FEAT_FID_LBA_RANGE`` + *undescribed* -``struct nvme_ns_list * log`` +``NVME_FEAT_FID_TEMP_THRESH`` *undescribed* -**Description** +``NVME_FEAT_FID_ERR_RECOVERY`` + *undescribed* -This log page is used to describe namespaces attached to this controller -that have changed since the last time the namespace was identified, been -added, or deleted. +``NVME_FEAT_FID_VOLATILE_WC`` + *undescribed* -**Return** +``NVME_FEAT_FID_NUM_QUEUES`` + *undescribed* -The nvme command status if a response was received or -1 with errno - set otherwise. +``NVME_FEAT_FID_IRQ_COALESCE`` + *undescribed* +``NVME_FEAT_FID_IRQ_CONFIG`` + *undescribed* -.. c:function:: int nvme_get_log_cmd_effects (int fd, struct nvme_cmd_effects_log * log) +``NVME_FEAT_FID_WRITE_ATOMIC`` + *undescribed* - Retrieve nvme command effects log +``NVME_FEAT_FID_ASYNC_EVENT`` + *undescribed* -**Parameters** +``NVME_FEAT_FID_AUTO_PST`` + *undescribed* -``int fd`` - File descriptor of nvme device +``NVME_FEAT_FID_HOST_MEM_BUF`` + *undescribed* -``struct nvme_cmd_effects_log * log`` +``NVME_FEAT_FID_TIMESTAMP`` *undescribed* -**Description** +``NVME_FEAT_FID_KATO`` + *undescribed* -This log page is used to describe the commands that the controller supports -and the effects of those commands on the state of the NVM subsystem. +``NVME_FEAT_FID_HCTM`` + *undescribed* -**Return** +``NVME_FEAT_FID_NOPSC`` + *undescribed* -The nvme command status if a response was received or -1 with errno - set otherwise. +``NVME_FEAT_FID_RRL`` + *undescribed* +``NVME_FEAT_FID_PLM_CONFIG`` + *undescribed* -.. c:function:: int nvme_get_log_device_self_test (int fd, struct nvme_self_test_log * log) +``NVME_FEAT_FID_PLM_WINDOW`` + *undescribed* - Retrieve the device self test log +``NVME_FEAT_FID_LBA_STS_INTERVAL`` + *undescribed* -**Parameters** +``NVME_FEAT_FID_HOST_BEHAVIOR`` + *undescribed* -``int fd`` - File descriptor of nvme device +``NVME_FEAT_FID_SANITIZE`` + *undescribed* -``struct nvme_self_test_log * log`` - Userspace address of the log payload +``NVME_FEAT_FID_ENDURANCE_EVT_CFG`` + *undescribed* -**Description** +``NVME_FEAT_FID_SW_PROGRESS`` + *undescribed* -The log page is used to indicate the status of an in progress self test and -the percent complete of that operation, and the results of the previous 20 -self-test operations. +``NVME_FEAT_FID_HOST_ID`` + *undescribed* -**Return** - -The nvme command status if a response was received or -1 with errno - set otherwise. +``NVME_FEAT_FID_RESV_MASK`` + *undescribed* +``NVME_FEAT_RESV_PERSIST`` + *undescribed* -.. c:function:: int nvme_get_log_create_telemetry_host (int fd, struct nvme_telemetry_log * log) +``NVME_FEAT_FID_WRITE_PROTECT`` + *undescribed* -**Parameters** -``int fd`` - *undescribed* -``struct nvme_telemetry_log * log`` - *undescribed* +.. c:type:: enum nvme_get_features_sel -.. c:function:: int nvme_get_log_telemetry_host (int fd, __u64 offset, __u32 len, void * log) +**Constants** +``NVME_GET_FEATURES_SEL_CURRENT`` + *undescribed* -**Parameters** +``NVME_GET_FEATURES_SEL_DEFAULT`` + *undescribed* -``int fd`` - File descriptor of nvme device +``NVME_GET_FEATURES_SEL_SAVED`` + *undescribed* -``__u64 offset`` - Offset into the telemetry data -``__u32 len`` - Length of provided user buffer to hold the log data in bytes -``void * log`` - User address for log page data -**Description** +.. c:type:: enum nvme_cmd_format_mset -Retreives the Telemetry Host-Initiated log page at the requested offset -using the previously existing capture. -**Return** +**Constants** -The nvme command status if a response was received or -1 with errno - set otherwise. +``NVME_FORMAT_MSET_SEPARATE`` + *undescribed* +``NVME_FORMAT_MSET_EXTENEDED`` + *undescribed* -.. c:function:: int nvme_get_log_telemetry_ctrl (int fd, bool rae, __u64 offset, __u32 len, void * log) -**Parameters** -``int fd`` - File descriptor of nvme device +.. c:type:: enum nvme_cmd_format_pi -``bool rae`` - Retain asynchronous events -``__u64 offset`` - Offset into the telemetry data +**Constants** -``__u32 len`` - Length of provided user buffer to hold the log data in bytes +``NVME_FORMAT_PI_DISABLE`` + *undescribed* -``void * log`` - User address for log page data +``NVME_FORMAT_PI_TYPE1`` + *undescribed* +``NVME_FORMAT_PI_TYPE2`` + *undescribed* -.. c:function:: int nvme_get_log_endurance_group (int fd, __u16 endgid, struct nvme_endurance_group_log * log) +``NVME_FORMAT_PI_TYPE3`` + *undescribed* -**Parameters** -``int fd`` - File descriptor of nvme device -``__u16 endgid`` - Starting group identifier to return in the list +.. c:type:: enum nvme_cmd_format_ses -``struct nvme_endurance_group_log * log`` - User address to store the endurance log -**Description** +**Constants** -This log page indicates if an Endurance Group Event has occurred for a -particular Endurance Group. If an Endurance Group Event has occurred, the -details of the particular event are included in the Endurance Group -Information log page for that Endurance Group. An asynchronous event is -generated when an entry for an Endurance Group is newly added to this log -page. +``NVME_FORMAT_SES_NONE`` + *undescribed* -**Return** +``NVME_FORMAT_SES_USER_DATA_ERASE`` + *undescribed* -The nvme command status if a response was received or -1 with errno - set otherwise. +``NVME_FORMAT_SES_CRYPTO_ERASE`` + *undescribed* -.. c:function:: int nvme_get_log_predictable_lat_nvmset (int fd, __u16 nvmsetid, struct nvme_nvmset_predictable_lat_log * log) -**Parameters** +.. c:type:: enum nvme_ns_mgmt_sel -``int fd`` - *undescribed* -``__u16 nvmsetid`` +**Constants** -``struct nvme_nvmset_predictable_lat_log * log`` +``NVME_NS_MGMT_SEL_CREATE`` *undescribed* -**Return** - -The nvme command status if a response was received or -1 with errno - set otherwise. - +``NVME_NS_MGMT_SEL_DELETE`` + *undescribed* -.. c:function:: int nvme_get_log_predictable_lat_event (int fd, bool rae, __u32 offset, __u32 len, void * log) -**Parameters** -``int fd`` - File descriptor of nvme device +.. c:type:: enum nvme_ns_attach_sel -``bool rae`` - Retain asynchronous events + NVME_NS_ATTACH_SEL_CTRL_ATTACH: NVME_NP_ATTACH_SEL_CTRL_DEATTACH: -``__u32 offset`` - *undescribed* +**Constants** -``__u32 len`` +``NVME_NS_ATTACH_SEL_CTRL_ATTACH`` *undescribed* -``void * log`` +``NVME_NS_ATTACH_SEL_CTRL_DEATTACH`` *undescribed* -.. c:function:: int nvme_get_log_ana (int fd, enum nvme_log_ana_lsp lsp, bool rae, __u64 offset, __u32 len, void * log) - -**Parameters** -``int fd`` - File descriptor of nvme device +.. c:type:: enum nvme_fw_commit_ca -``enum nvme_log_ana_lsp lsp`` - Log specific, see :c:type:`enum nvme_get_log_ana_lsp ` -``bool rae`` - Retain asynchronous events +**Constants** -``__u64 offset`` +``NVME_FW_COMMIT_CA_REPLACE`` *undescribed* -``__u32 len`` - The allocated length of the log page - -``void * log`` - User address to store the ana log - -**Description** +``NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE`` + *undescribed* -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. +``NVME_FW_COMMIT_CA_SET_ACTIVE`` + *undescribed* -See :c:type:`struct nvme_ana_rsp_hdr ` for the defintion of the returned structure. +``NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE_IMMEDIATE`` + *undescribed* -**Return** +``NVME_FW_COMMIT_CA_REPLACE_BOOT_PARTITION`` + *undescribed* -The nvme command status if a response was received or -1 with errno - set otherwise. +``NVME_FW_COMMIT_CA_ACTIVATE_BOOT_PARTITION`` + *undescribed* -.. c:function:: int nvme_get_log_ana_groups (int fd, bool rae, __u32 len, struct nvme_ana_group_desc * log) -**Parameters** +.. c:type:: enum nvme_directive_dtype -``int fd`` - File descriptor of nvme device -``bool rae`` - Retain asynchronous events +**Constants** -``__u32 len`` +``NVME_DIRECTIVE_DTYPE_IDENTIFY`` *undescribed* -``struct nvme_ana_group_desc * log`` +``NVME_DIRECTIVE_DTYPE_STREAMS`` *undescribed* -**Description** - -See :c:type:`struct nvme_ana_group_desc ` for the defintion of the returned structure. -.. c:function:: int nvme_get_log_lba_status (int fd, bool rae, __u64 offset, __u32 len, void * log) +.. c:type:: enum nvme_directive_receive_doper -**Parameters** -``int fd`` - File descriptor of nvme device +**Constants** -``bool rae`` - Retain asynchronous events +``NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM`` + *undescribed* -``__u64 offset`` +``NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM`` *undescribed* -``__u32 len`` +``NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS`` *undescribed* -``void * log`` +``NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE`` *undescribed* -.. c:function:: int nvme_get_log_endurance_grp_evt (int fd, bool rae, __u32 offset, __u32 len, void * log) -**Parameters** +.. c:type:: enum nvme_directive_send_doper -``int fd`` - File descriptor of nvme device -``bool rae`` - Retain asynchronous events +**Constants** -``__u32 offset`` +``NVME_DIRECTIVE_SEND_IDENTIFY_DOPER_ENDIR`` *undescribed* -``__u32 len`` +``NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_IDENTIFIER`` *undescribed* -``void * log`` +``NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE`` *undescribed* -.. c:function:: int nvme_get_log_discovery (int fd, bool rae, __u32 offset, __u32 len, void * log) - - -**Parameters** -``int fd`` - File descriptor of nvme device -``bool rae`` - Retain asynchronous events +.. c:type:: enum nvme_directive_send_identify_endir -``__u32 offset`` - Offset of this log to retrieve -``__u32 len`` - The allocated size for this portion of the log +**Constants** -``void * log`` - User address to store the discovery log +``NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_DISABLE`` + *undescribed* -**Description** +``NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_ENABLE`` + *undescribed* -Supported only by fabrics discovery controllers, returning discovery -records. -**Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +.. c:type:: enum nvme_sanitize_sanact -.. c:function:: int nvme_get_log_reservation (int fd, bool rae, struct nvme_resv_notification_log * log) +**Constants** -**Parameters** +``NVME_SANITIZE_SANACT_EXIT_FAILURE`` + *undescribed* -``int fd`` - File descriptor of nvme device +``NVME_SANITIZE_SANACT_START_BLOCK_ERASE`` + *undescribed* -``bool rae`` - Retain asynchronous events +``NVME_SANITIZE_SANACT_START_OVERWRITE`` + *undescribed* -``struct nvme_resv_notification_log * log`` +``NVME_SANITIZE_SANACT_START_CRYPTO_ERASE`` *undescribed* -.. c:function:: int nvme_get_log_sanitize (int fd, bool rae, struct nvme_sanitize_log_page * log) -**Parameters** +.. c:type:: enum nvme_dst_stc -``int fd`` - File descriptor of nvme device -``bool rae`` - Retain asynchronous events +**Constants** -``struct nvme_sanitize_log_page * log`` - User address to store the sanitize log +``NVME_DST_STC_SHORT`` + *undescribed* -**Description** +``NVME_DST_STC_LONG`` + *undescribed* -The Sanitize Status log page is used to report sanitize operation time -estimates and information about the most recent sanitize operation. +``NVME_DST_STC_VS`` + *undescribed* -**Return** +``NVME_DST_STC_ABORT`` + *undescribed* -The nvme command status if a response was received or -1 with errno - set otherwise. -.. c:function:: int nvme_set_features (int fd, __u8 fid, __u32 nsid, __u32 cdw11, __u32 cdw12, bool save, __u8 uuidx, __u32 cdw15, __u32 data_len, void * data, __u32 * result) - Set a feature attribute +.. c:type:: enum nvme_virt_mgmt_act -**Parameters** -``int fd`` - File descriptor of nvme device +**Constants** -``__u8 fid`` - Feature identifier +``NVME_VIRT_MGMT_ACT_PRIM_CTRL_FLEX_ALLOC`` + *undescribed* -``__u32 nsid`` - Namespace ID, if applicable +``NVME_VIRT_MGMT_ACT_OFFLINE_SEC_CTRL`` + *undescribed* -``__u32 cdw11`` - Value to set the feature to +``NVME_VIRT_MGMT_ACT_ASSIGN_SEC_CTRL`` + *undescribed* -``__u32 cdw12`` - Feature specific command dword12 field +``NVME_VIRT_MGMT_ACT_ONLINE_SEC_CTRL`` + *undescribed* -``bool save`` - Save value across power states -``__u8 uuidx`` - UUID Index for differentiating vendor specific encoding -``__u32 cdw15`` - *undescribed* -``__u32 data_len`` - Length of feature data, if applicable, in bytes +.. c:type:: enum nvme_virt_mgmt_rt -``void * data`` - User address of feature data, if applicable -``__u32 * result`` - The command completion result from CQE dword0 +**Constants** -**Return** +``NVME_VIRT_MGMT_RT_VQ_RESOURCE`` + *undescribed* -The nvme command status if a response was received or -1 with errno - set otherwise. +``NVME_VIRT_MGMT_RT_VI_RESOURCE`` + *undescribed* -.. c:function:: int nvme_set_features_arbitration (int fd, __u8 ab, __u8 lpw, __u8 mpw, __u8 hpw, bool save, __u32 * result) +.. c:function:: int nvme_identify (int fd, enum nvme_identify_cns cns, __u32 nsid, __u16 cntid, __u16 nvmsetid, __u8 uuidx, void * data) + Send the NVMe Identify command **Parameters** ``int fd`` File descriptor of nvme device -``__u8 ab`` - *undescribed* +``enum nvme_identify_cns cns`` + The Controller or Namespace structure, see **enum** nvme_identify_cns -``__u8 lpw`` - *undescribed* +``__u32 nsid`` + Namespace identifier, if applicable -``__u8 mpw`` - *undescribed* +``__u16 cntid`` + The Controller Identifier, if applicable -``__u8 hpw`` - *undescribed* +``__u16 nvmsetid`` + The NVMe Set ID if CNS is 04h -``bool save`` - Save value across power states +``__u8 uuidx`` + UUID Index if controller supports this id selection method -``__u32 * result`` - The command completion result from CQE dword0 +``void * data`` + User space destination address to transfer the data + +**Description** + +The Identify command returns a data buffer that describes information about +the NVM subsystem, the controller or the namespace(s). **Return** @@ -1564,25 +1514,24 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_power_mgmt (int fd, __u8 ps, __u8 wh, bool save, __u32 * result) +.. c:function:: int nvme_identify_ctrl (int fd, struct nvme_id_ctrl * id) + Retrieves nvme identify controller **Parameters** ``int fd`` File descriptor of nvme device + id: User space destination address to transfer the data, -``__u8 ps`` +``struct nvme_id_ctrl * id`` *undescribed* -``__u8 wh`` - *undescribed* +**Description** -``bool save`` - Save value across power states +Sends nvme identify with CNS value ``NVME_IDENTIFY_CNS_CTRL``. -``__u32 * result`` - The command completion result from CQE dword0 +See :c:type:`struct nvme_id_ctrl ` for details on the data returned. **Return** @@ -1590,8 +1539,9 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_lba_range (int fd, __u32 nsid, __u32 nr_ranges, bool save, struct nvme_lba_range_type * data, __u32 * result) +.. c:function:: int nvme_identify_ns (int fd, __u32 nsid, struct nvme_id_ns * ns) + Retrieves nvme identify namespace **Parameters** @@ -1599,19 +1549,23 @@ The nvme command status if a response was received or -1 with errno File descriptor of nvme device ``__u32 nsid`` - *undescribed* + Namespace to identify -``__u32 nr_ranges`` - *undescribed* +``struct nvme_id_ns * ns`` + User space destination address to transfer the data -``bool save`` - Save value across power states +**Description** -``struct nvme_lba_range_type * data`` - *undescribed* +If the Namespace Identifier (NSID) field specifies an active NSID, then the +Identify Namespace data structure is returned to the host for that specified +namespace. -``__u32 * result`` - The command completion result from CQE dword0 +If the controller supports the Namespace Management capability and the NSID +field is set to ``NVME_NSID_ALL``, then the controller returns an Identify Namespace +data structure that specifies capabilities that are common across namespaces +for this controller. + +See :c:type:`struct nvme_id_ns ` for details on the structure returned. **Return** @@ -1619,42 +1573,49 @@ The nvme command status if a response was received or -1 with errno set otherwise. +.. c:function:: int nvme_identify_allocated_ns (int fd, __u32 nsid, struct nvme_id_ns * ns) + Same as nvme_identify_ns, but only for allocated namespaces -.. c:type:: enum nvme_feat_tmpthresh_thsel +**Parameters** +``int fd`` + File descriptor of nvme device -**Constants** +``__u32 nsid`` + Namespace to identify -``NVME_FEATURE_TEMPTHRESH_THSEL_OVER`` - *undescribed* +``struct nvme_id_ns * ns`` + User space destination address to transfer the data -``NVME_FEATURETEMPTHRESH__THSEL_UNDER`` - *undescribed* +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. -.. c:function:: int nvme_set_features_temp_thresh (int fd, __u16 tmpth, __u8 tmpsel, enum nvme_feat_tmpthresh_thsel thsel, bool save, __u32 * result) +.. c:function:: int nvme_identify_active_ns_list (int fd, __u32 nsid, struct nvme_ns_list * list) + Retrieves active namespaces id list **Parameters** ``int fd`` File descriptor of nvme device -``__u16 tmpth`` - *undescribed* +``__u32 nsid`` + Return namespaces greater than this identifer -``__u8 tmpsel`` +``struct nvme_ns_list * list`` *undescribed* -``enum nvme_feat_tmpthresh_thsel thsel`` - *undescribed* +**Description** -``bool save`` - Save value across power states +A list of 1024 namespace IDs is returned to the host containing NSIDs in +increasing order that are greater than the value specified in the Namespace +Identifier (nsid) field of the command. -``__u32 * result`` - The command completion result from CQE dword0 +See :c:type:`struct nvme_ns_list ` for the definition of the returned structure. **Return** @@ -1662,8 +1623,9 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_err_recovery (int fd, __u32 nsid, __u16 tler, bool dulbe, bool save, __u32 * result) +.. c:function:: int nvme_identify_allocated_ns_list (int fd, __u32 nsid, struct nvme_ns_list * list) + Retrieves allocated namespace id list **Parameters** @@ -1671,19 +1633,18 @@ The nvme command status if a response was received or -1 with errno File descriptor of nvme device ``__u32 nsid`` - *undescribed* + Return namespaces greater than this identifer -``__u16 tler`` +``struct nvme_ns_list * list`` *undescribed* -``bool dulbe`` - *undescribed* +**Description** -``bool save`` - Save value across power states +A list of 1024 namespace IDs is returned to the host containing NSIDs in +increasing order that are greater than the value specified in the Namespace +Identifier (nsid) field of the command. -``__u32 * result`` - The command completion result from CQE dword0 +See :c:type:`struct nvme_ns_list ` for the definition of the returned structure. **Return** @@ -1691,22 +1652,28 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_volatile_wc (int fd, bool wce, bool save, __u32 * result) +.. c:function:: int nvme_identify_ctrl_list (int fd, __u16 cntid, struct nvme_ctrl_list * ctrlist) + Retrieves identify controller list **Parameters** ``int fd`` File descriptor of nvme device -``bool wce`` +``__u16 cntid`` *undescribed* -``bool save`` - Save value across power states +``struct nvme_ctrl_list * ctrlist`` + *undescribed* -``__u32 * result`` - The command completion result from CQE dword0 +**Description** + +Up to 2047 controller identifiers is returned containing a controller +identifier greater than or equal to the controller identifier specified in +**cntid**. + +See :c:type:`struct nvme_ctrl_list ` for a definition of the structure returned. **Return** @@ -1714,7 +1681,7 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_irq_coalesce (int fd, __u8 thr, __u8 time, bool save, __u32 * result) +.. c:function:: int nvme_identify_nsid_ctrl_list (int fd, __u32 nsid, __u16 cntid, struct nvme_ctrl_list * ctrlist) **Parameters** @@ -1722,43 +1689,52 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``__u8 thr`` +``__u32 nsid`` + Return controllers that are attached to this nsid + +``__u16 cntid`` *undescribed* -``__u8 time`` +``struct nvme_ctrl_list * ctrlist`` *undescribed* -``bool save`` - Save value across power states +**Description** -``__u32 * result`` - The command completion result from CQE dword0 +Up to 2047 controller identifiers is returned containing a controller +identifier greater than or equal to the controller identifier specified in +**cntid**. + +See :c:type:`struct nvme_ctrl_list ` for a definition of the structure returned. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received or -1 -.. c:function:: int nvme_set_features_irq_config (int fd, __u16 iv, bool cd, bool save, __u32 * result) +.. c:function:: int nvme_identify_ns_descs (int fd, __u32 nsid, struct nvme_ns_id_desc * descs) + Retrieves namespace descriptor list **Parameters** ``int fd`` File descriptor of nvme device -``__u16 iv`` - *undescribed* +``__u32 nsid`` + The namespace id to retrieve destriptors -``bool cd`` - *undescribed* +``struct nvme_ns_id_desc * descs`` + User space destination address to transfer the data -``bool save`` - Save value across power states +**Description** -``__u32 * result`` - The command completion result from CQE dword0 +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'. + +See :c:type:`struct nvme_ns_id_desc ` for the definition of the returned structure. **Return** @@ -1766,22 +1742,29 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_write_atomic (int fd, bool dn, bool save, __u32 * result) +.. c:function:: int nvme_identify_nvmset_list (int fd, __u16 nvmsetid, struct nvme_id_nvmset_list * nvmset) + Retrieves NVM Set List **Parameters** ``int fd`` File descriptor of nvme device -``bool dn`` +``__u16 nvmsetid`` *undescribed* -``bool save`` - Save value across power states +``struct nvme_id_nvmset_list * nvmset`` + User space destination address to transfer the data -``__u32 * result`` - The command completion result from CQE dword0 +**Description** + +Retrieves an NVM Set List, struct nvme_id_nvmset. The data structure is an +ordered list by NVM Set Identifier, starting with the first NVM Set +Identifier supported by the NVM subsystem that is equal to or greater than +the NVM Set Identifier. + +See :c:type:`struct nvme_id_nvmset_list ` for the defintion of the returned structure. **Return** @@ -1789,72 +1772,54 @@ The nvme command status if a response was received or -1 with errno set otherwise. +.. c:function:: int nvme_identify_primary_ctrl (int fd, __u16 cntid, struct nvme_primary_ctrl_cap * cap) + Retrieve NVMe Primary Controller identification :c:type:`fd`: -.. c:type:: enum nvme_features_async_event_config_flags - - -**Constants** - -``NVME_FEATURE_AENCFG_SMART_CRIT_SPARE`` - *undescribed* - -``NVME_FEATURE_AENCFG_SMART_CRIT_TEMPERATURE`` - *undescribed* - -``NVME_FEATURE_AENCFG_SMART_CRIT_DEGRADED`` - *undescribed* - -``NVME_FEATURE_AENCFG_SMART_CRIT_READ_ONLY`` - *undescribed* - -``NVME_FEATURE_AENCFG_SMART_CRIT_VOLATILE_BACKUP`` - *undescribed* - -``NVME_FEATURE_AENCFG_SMART_CRIT_READ_ONLY_PMR`` - *undescribed* - -``NVME_FEATURE_AENCFG_NOTICE_NAMESPACE_ATTRIBUTES`` - *undescribed* +**Parameters** -``NVME_FEATURE_AENCFG_NOTICE_FIRMWARE_ACTIVATION`` +``int fd`` *undescribed* -``NVME_FEATURE_AENCFG_NOTICE_TELEMETRY_LOG`` +``__u16 cntid`` *undescribed* -``NVME_FEATURE_AENCFG_NOTICE_ANA_CHANGE`` - *undescribed* +``struct nvme_primary_ctrl_cap * cap`` -``NVME_FEATURE_AENCFG_NOTICE_PL_EVENT`` - *undescribed* +**Description** -``NVME_FEATURE_AENCFG_NOTICE_LBA_STATUS`` - *undescribed* +See :c:type:`struct nvme_primary_ctrl_cap ` for the defintion of the returned structure, **cap**. -``NVME_FEATURE_AENCFG_NOTICE_EG_EVENT`` - *undescribed* +**Return** -``NVME_FEATURE_AENCFG_NOTICE_DISCOVERY_CHANGE`` - *undescribed* +The nvme command status if a response was received or -1 + with errno set otherwise. -.. c:function:: int nvme_set_features_async_event (int fd, __u32 events, bool save, __u32 * result) +.. c:function:: int nvme_identify_secondary_ctrl_list (int fd, __u16 cntid, struct nvme_secondary_ctrl_list * list) + Retrieves secondary controller list **Parameters** ``int fd`` File descriptor of nvme device -``__u32 events`` +``__u16 cntid`` + Return controllers starting at this identifier + +``struct nvme_secondary_ctrl_list * list`` *undescribed* -``bool save`` - Save value across power states +**Description** -``__u32 * result`` - The command completion result from CQE dword0 +A Secondary Controller List is returned to the host for up to 127 secondary +controllers associated with the primary controller processing this command. +The list contains entries for controller identifiers greater than or equal +to the value specified in the Controller Identifier (cntid). + +See :c:type:`struct nvme_secondary_ctrls_list ` for a defintion of the returned +structure. **Return** @@ -1862,25 +1827,26 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_auto_pst (int fd, bool apste, bool save, struct nvme_feat_auto_pst * apst, __u32 * result) +.. c:function:: int nvme_identify_ns_granularity (int fd, struct nvme_id_ns_granularity_list * list) + Retrieves namespace granularity identification **Parameters** ``int fd`` File descriptor of nvme device -``bool apste`` +``struct nvme_id_ns_granularity_list * list`` *undescribed* -``bool save`` - Save value across power states +**Description** -``struct nvme_feat_auto_pst * apst`` - *undescribed* +If the controller supports reporting of Namespace Granularity, then a +Namespace Granularity List is returned to the host for up to sixteen +namespace granularity descriptors -``__u32 * result`` - The command completion result from CQE dword0 +See :c:type:`struct nvme_id_ns_granularity_list ` for the definition of the returned +structure. **Return** @@ -1888,19 +1854,24 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_timestamp (int fd, bool save, __u64 timestamp) +.. c:function:: int nvme_identify_uuid (int fd, struct nvme_id_uuid_list * list) + Retrieves device's UUIDs **Parameters** ``int fd`` File descriptor of nvme device -``bool save`` - Save value across power states +``struct nvme_id_uuid_list * list`` + *undescribed* -``__u64 timestamp`` - The current timestamp value to assign to this this feature +**Description** + +Each UUID List entry is either 0h, the NVMe Invalid UUID, or a valid UUID. +Valid UUIDs are those which are non-zero and are not the NVMe Invalid UUID. + +See :c:type:`struct nvme_id_uuid_list ` for the definition of the returned structure. **Return** @@ -1908,69 +1879,71 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_hctm (int fd, __u16 tmt2, __u16 tmt1, bool save, __u32 * result) +.. c:function:: int nvme_get_log (int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, __u8 lsp, __u16 lsi, bool rae, __u8 uuidx, __u32 len, void * log) + NVMe Admin Get Log command **Parameters** ``int fd`` File descriptor of nvme device -``__u16 tmt2`` - *undescribed* - -``__u16 tmt1`` - *undescribed* - -``bool save`` - Save value across power states - -``__u32 * result`` - The command completion result from CQE dword0 +``enum nvme_cmd_get_log_lid lid`` + Log page identifier, see :c:type:`enum nvme_cmd_get_log_lid ` for known values -**Return** +``__u32 nsid`` + Namespace identifier, if applicable -The nvme command status if a response was received or -1 with errno - set otherwise. +``__u64 lpo`` + Log page offset for partial log transfers +``__u8 lsp`` + Log specific field -.. c:function:: int nvme_set_features_nopsc (int fd, bool noppme, bool save, __u32 * result) +``__u16 lsi`` + Endurance group information +``bool rae`` + Retain asynchronous events -**Parameters** +``__u8 uuidx`` + UUID selection, if supported -``int fd`` - *undescribed* +``__u32 len`` + Length of provided user buffer to hold the log data in bytes -``bool noppme`` - *undescribed* +``void * log`` + User space destination address to transfer the data -``bool save`` - *undescribed* +**Return** -``__u32 * result`` - *undescribed* +The nvme command status if a response was received or -1 with errno + set otherwise. -.. c:function:: int nvme_set_features_rrl (int fd, __u8 rrl, __u16 nvmsetid, bool save, __u32 * result) +.. c:function:: int nvme_get_log_error (int fd, unsigned nr_entries, bool rae, struct nvme_error_log_page * log) + Retrieve nvme error log **Parameters** ``int fd`` File descriptor of nvme device -``__u8 rrl`` +``unsigned nr_entries`` *undescribed* -``__u16 nvmsetid`` +``bool rae`` + Retain asynchronous events + +``struct nvme_error_log_page * log`` *undescribed* -``bool save`` - Save value across power states +**Description** -``__u32 * result`` - The command completion result from CQE dword0 +This log page is used to describe extended error information for a command +that completed with error, or may report an error that is not specific to a +particular command. **Return** @@ -1978,28 +1951,32 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_plm_config (int fd, bool enable, __u16 nvmsetid, bool save, struct nvme_plm_config * data, __u32 * result) +.. c:function:: int nvme_get_log_smart (int fd, __u32 nsid, bool rae, struct nvme_smart_log * log) + Retrieve nvme smart log **Parameters** ``int fd`` File descriptor of nvme device -``bool enable`` - *undescribed* - -``__u16 nvmsetid`` - *undescribed* +``__u32 nsid`` + Optional namespace identifier -``bool save`` - Save value across power states +``bool rae`` + Retain asynchronous events -``struct nvme_plm_config * data`` +``struct nvme_smart_log * log`` *undescribed* -``__u32 * result`` - The command completion result from CQE dword0 +**Description** + +This log page is used to provide SMART and general health information. The +information provided is over the life of the controller and is retained +across power cycles. To request the controller log page, the namespace +identifier specified is FFFFFFFFh. The controller may also support +requesting the log page on a per namespace basis, as indicated by bit 0 of +the LPA field in the Identify Controller data structure. **Return** @@ -2007,39 +1984,26 @@ The nvme command status if a response was received or -1 with errno set otherwise. +.. c:function:: int nvme_get_log_fw_slot (int fd, bool rae, struct nvme_firmware_slot * log) - -.. c:type:: enum nvme_feat_plm_window_select - - -**Constants** - -``NVME_FEATURE_PLM_DTWIN`` - *undescribed* - -``NVME_FEATURE_PLM_NDWIN`` - *undescribed* - - -.. c:function:: int nvme_set_features_plm_window (int fd, enum nvme_feat_plm_window_select sel, __u16 nvmsetid, bool save, __u32 * result) - + Retrieves the controller firmware log **Parameters** ``int fd`` File descriptor of nvme device -``enum nvme_feat_plm_window_select sel`` - *undescribed* +``bool rae`` + Retain asynchronous events -``__u16 nvmsetid`` +``struct nvme_firmware_slot * log`` *undescribed* -``bool save`` - Save value across power states +**Description** -``__u32 * result`` - The command completion result from CQE dword0 +This log page is used to describe the firmware revision stored in each +firmware slot supported. The firmware revision is indicated as an ASCII +string. The log page also indicates the active slot number. **Return** @@ -2047,25 +2011,26 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_lba_sts_interval (int fd, __u16 lsiri, __u16 lsipi, bool save, __u32 * result) +.. c:function:: int nvme_get_log_changed_ns_list (int fd, bool rae, struct nvme_ns_list * log) + Retrieve namespace changed list **Parameters** ``int fd`` File descriptor of nvme device -``__u16 lsiri`` - *undescribed* +``bool rae`` + Retain asynchronous events -``__u16 lsipi`` +``struct nvme_ns_list * log`` *undescribed* -``bool save`` - Save value across power states +**Description** -``__u32 * result`` - The command completion result from CQE dword0 +This log page is used to describe namespaces attached to this controller +that have changed since the last time the namespace was identified, been +added, or deleted. **Return** @@ -2073,42 +2038,46 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_host_behavior (int fd, bool save, struct nvme_feat_host_behavior * data) +.. c:function:: int nvme_get_log_cmd_effects (int fd, struct nvme_cmd_effects_log * log) + Retrieve nvme command effects log **Parameters** ``int fd`` File descriptor of nvme device -``bool save`` - Save value across power states - -``struct nvme_feat_host_behavior * data`` +``struct nvme_cmd_effects_log * log`` *undescribed* +**Description** + +This log page is used to describe the commands that the controller supports +and the effects of those commands on the state of the NVM subsystem. + **Return** The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_sanitize (int fd, bool nodrm, bool save, __u32 * result) +.. c:function:: int nvme_get_log_device_self_test (int fd, struct nvme_self_test_log * log) + Retrieve the device self test log **Parameters** ``int fd`` File descriptor of nvme device -``bool nodrm`` - *undescribed* +``struct nvme_self_test_log * log`` + Userspace address of the log payload -``bool save`` - Save value across power states +**Description** -``__u32 * result`` - The command completion result from CQE dword0 +The log page is used to indicate the status of an in progress self test and +the percent complete of that operation, and the results of the previous 20 +self-test operations. **Return** @@ -2116,33 +2085,19 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_endurance_evt_cfg (int fd, __u16 endgid, __u8 egwarn, bool save, __u32 * result) +.. c:function:: int nvme_get_log_create_telemetry_host (int fd, struct nvme_telemetry_log * log) **Parameters** ``int fd`` - File descriptor of nvme device - -``__u16 endgid`` *undescribed* -``__u8 egwarn`` - Flags to enable warning, see :c:type:`enum nvme_eg_critical_warning_flags ` - -``bool save`` - Save value across power states - -``__u32 * result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received or -1 with errno - set otherwise. +``struct nvme_telemetry_log * log`` + *undescribed* -.. c:function:: int nvme_set_features_sw_progress (int fd, __u8 pbslc, bool save, __u32 * result) +.. c:function:: int nvme_get_log_telemetry_host (int fd, __u64 offset, __u32 len, void * log) **Parameters** @@ -2150,14 +2105,19 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``__u8 pbslc`` - *undescribed* +``__u64 offset`` + Offset into the telemetry data -``bool save`` - Save value across power states +``__u32 len`` + Length of provided user buffer to hold the log data in bytes -``__u32 * result`` - The command completion result from CQE dword0 +``void * log`` + User address for log page data + +**Description** + +Retreives the Telemetry Host-Initiated log page at the requested offset +using the previously existing capture. **Return** @@ -2165,7 +2125,7 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_host_id (int fd, bool exhid, bool save, __u8 * hostid) +.. c:function:: int nvme_get_log_telemetry_ctrl (int fd, bool rae, __u64 offset, __u32 len, void * log) **Parameters** @@ -2173,22 +2133,20 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``bool exhid`` - *undescribed* - -``bool save`` - Save value across power states +``bool rae`` + Retain asynchronous events -``__u8 * hostid`` - *undescribed* +``__u64 offset`` + Offset into the telemetry data -**Return** +``__u32 len`` + Length of provided user buffer to hold the log data in bytes -The nvme command status if a response was received or -1 with errno - set otherwise. +``void * log`` + User address for log page data -.. c:function:: int nvme_set_features_resv_mask (int fd, __u32 mask, bool save, __u32 * result) +.. c:function:: int nvme_get_log_endurance_group (int fd, __u16 endgid, struct nvme_endurance_group_log * log) **Parameters** @@ -2196,14 +2154,20 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``__u32 mask`` - *undescribed* +``__u16 endgid`` + Starting group identifier to return in the list -``bool save`` - Save value across power states +``struct nvme_endurance_group_log * log`` + User address to store the endurance log -``__u32 * result`` - The command completion result from CQE dword0 +**Description** + +This log page indicates if an Endurance Group Event has occurred for a +particular Endurance Group. If an Endurance Group Event has occurred, the +details of the particular event are included in the Endurance Group +Information log page for that Endurance Group. An asynchronous event is +generated when an entry for an Endurance Group is newly added to this log +page. **Return** @@ -2211,22 +2175,18 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_resv_persist (int fd, bool ptpl, bool save, __u32 * result) +.. c:function:: int nvme_get_log_predictable_lat_nvmset (int fd, __u16 nvmsetid, struct nvme_nvmset_predictable_lat_log * log) **Parameters** ``int fd`` - File descriptor of nvme device - -``bool ptpl`` *undescribed* -``bool save`` - Save value across power states +``__u16 nvmsetid`` -``__u32 * result`` - The command completion result from CQE dword0 +``struct nvme_nvmset_predictable_lat_log * log`` + *undescribed* **Return** @@ -2234,27 +2194,28 @@ The nvme command status if a response was received or -1 with errno set otherwise. +.. c:function:: int nvme_get_log_predictable_lat_event (int fd, bool rae, __u32 offset, __u32 len, void * log) -.. c:type:: enum nvme_feat_nswpcfg_state - +**Parameters** -**Constants** +``int fd`` + File descriptor of nvme device -``NVME_FEAT_NS_NO_WRITE_PROTECT`` - *undescribed* +``bool rae`` + Retain asynchronous events -``NVME_FEAT_NS_WRITE_PROTECT`` +``__u32 offset`` *undescribed* -``NVME_FEAT_NS_WRITE_PROTECT_PWR_CYCLE`` +``__u32 len`` *undescribed* -``NVME_FEAT_NS_WRITE_PROTECT_PERMANENT`` +``void * log`` *undescribed* -.. c:function:: int nvme_set_features_write_protect (int fd, enum nvme_feat_nswpcfg_state state, bool save, __u32 * result) +.. c:function:: int nvme_get_log_ana (int fd, enum nvme_log_ana_lsp lsp, bool rae, __u64 offset, __u32 len, void * log) **Parameters** @@ -2262,14 +2223,28 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``enum nvme_feat_nswpcfg_state state`` +``enum nvme_log_ana_lsp lsp`` + Log specific, see :c:type:`enum nvme_get_log_ana_lsp ` + +``bool rae`` + Retain asynchronous events + +``__u64 offset`` *undescribed* -``bool save`` - Save value across power states +``__u32 len`` + The allocated length of the log page -``__u32 * result`` - The command completion result from CQE dword0 +``void * log`` + User address to store the ana log + +**Description** + +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 :c:type:`struct nvme_ana_rsp_hdr ` for the defintion of the returned structure. **Return** @@ -2277,46 +2252,29 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_get_features (int fd, enum nvme_features_id fid, __u32 nsid, enum nvme_get_features_sel sel, __u32 cdw11, __u8 uuidx, __u32 data_len, void * data, __u32 * result) +.. c:function:: int nvme_get_log_ana_groups (int fd, bool rae, __u32 len, struct nvme_ana_group_desc * log) - Retrieve a feature attribute **Parameters** ``int fd`` File descriptor of nvme device -``enum nvme_features_id fid`` - Feature identifier - -``__u32 nsid`` - Namespace ID, if applicable - -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``__u32 cdw11`` - Feature specific command dword11 field - -``__u8 uuidx`` - UUID Index for differentiating vendor specific encoding - -``__u32 data_len`` - Length of feature data, if applicable, in bytes +``bool rae`` + Retain asynchronous events -``void * data`` - User address of feature data, if applicable +``__u32 len`` + *undescribed* -``__u32 * result`` - The command completion result from CQE dword0 +``struct nvme_ana_group_desc * log`` + *undescribed* -**Return** +**Description** -The nvme command status if a response was received or -1 with errno - set otherwise. +See :c:type:`struct nvme_ana_group_desc ` for the defintion of the returned structure. -.. c:function:: int nvme_get_features_arbitration (int fd, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_get_log_lba_status (int fd, bool rae, __u64 offset, __u32 len, void * log) **Parameters** @@ -2324,19 +2282,20 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` +``bool rae`` + Retain asynchronous events -``__u32 * result`` - The command completion result from CQE dword0 +``__u64 offset`` + *undescribed* -**Return** +``__u32 len`` + *undescribed* -The nvme command status if a response was received or -1 with errno - set otherwise. +``void * log`` + *undescribed* -.. c:function:: int nvme_get_features_power_mgmt (int fd, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_get_log_endurance_grp_evt (int fd, bool rae, __u32 offset, __u32 len, void * log) **Parameters** @@ -2344,19 +2303,20 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` +``bool rae`` + Retain asynchronous events -``__u32 * result`` - The command completion result from CQE dword0 +``__u32 offset`` + *undescribed* -**Return** +``__u32 len`` + *undescribed* -The nvme command status if a response was received or -1 with errno - set otherwise. +``void * log`` + *undescribed* -.. c:function:: int nvme_get_features_lba_range (int fd, enum nvme_get_features_sel sel, struct nvme_lba_range_type * data, __u32 * result) +.. c:function:: int nvme_get_log_discovery (int fd, bool rae, __u32 offset, __u32 len, void * log) **Parameters** @@ -2364,14 +2324,22 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` +``bool rae`` + Retain asynchronous events -``struct nvme_lba_range_type * data`` - *undescribed* +``__u32 offset`` + Offset of this log to retrieve -``__u32 * result`` - The command completion result from CQE dword0 +``__u32 len`` + The allocated size for this portion of the log + +``void * log`` + User address to store the discovery log + +**Description** + +Supported only by fabrics discovery controllers, returning discovery +records. **Return** @@ -2379,7 +2347,7 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_temp_thresh (int fd, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_get_log_reservation (int fd, bool rae, struct nvme_resv_notification_log * log) **Parameters** @@ -2387,19 +2355,14 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` +``bool rae`` + Retain asynchronous events -``__u32 * result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received or -1 with errno - set otherwise. +``struct nvme_resv_notification_log * log`` + *undescribed* -.. c:function:: int nvme_get_features_err_recovery (int fd, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_get_log_sanitize (int fd, bool rae, struct nvme_sanitize_log_page * log) **Parameters** @@ -2407,11 +2370,16 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` +``bool rae`` + Retain asynchronous events -``__u32 * result`` - The command completion result from CQE dword0 +``struct nvme_sanitize_log_page * log`` + User address to store the sanitize log + +**Description** + +The Sanitize Status log page is used to report sanitize operation time +estimates and information about the most recent sanitize operation. **Return** @@ -2419,36 +2387,41 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_volatile_wc (int fd, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_set_features (int fd, __u8 fid, __u32 nsid, __u32 cdw11, __u32 cdw12, bool save, __u8 uuidx, __u32 cdw15, __u32 data_len, void * data, __u32 * result) + Set a feature attribute **Parameters** ``int fd`` File descriptor of nvme device -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``__u32 * result`` - The command completion result from CQE dword0 +``__u8 fid`` + Feature identifier -**Return** +``__u32 nsid`` + Namespace ID, if applicable -The nvme command status if a response was received or -1 with errno - set otherwise. +``__u32 cdw11`` + Value to set the feature to +``__u32 cdw12`` + Feature specific command dword12 field -.. c:function:: int nvme_get_features_num_queues (int fd, enum nvme_get_features_sel sel, __u32 * result) +``bool save`` + Save value across power states +``__u8 uuidx`` + UUID Index for differentiating vendor specific encoding -**Parameters** +``__u32 cdw15`` + *undescribed* -``int fd`` - File descriptor of nvme device +``__u32 data_len`` + Length of feature data, if applicable, in bytes -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` +``void * data`` + User address of feature data, if applicable ``__u32 * result`` The command completion result from CQE dword0 @@ -2459,7 +2432,7 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_irq_coalesce (int fd, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_set_features_arbitration (int fd, __u8 ab, __u8 lpw, __u8 mpw, __u8 hpw, bool save, __u32 * result) **Parameters** @@ -2467,8 +2440,20 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` +``__u8 ab`` + *undescribed* + +``__u8 lpw`` + *undescribed* + +``__u8 mpw`` + *undescribed* + +``__u8 hpw`` + *undescribed* + +``bool save`` + Save value across power states ``__u32 * result`` The command completion result from CQE dword0 @@ -2479,7 +2464,7 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_irq_config (int fd, enum nvme_get_features_sel sel, __u16 iv, __u32 * result) +.. c:function:: int nvme_set_features_power_mgmt (int fd, __u8 ps, __u8 wh, bool save, __u32 * result) **Parameters** @@ -2487,12 +2472,15 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` +``__u8 ps`` + *undescribed* -``__u16 iv`` +``__u8 wh`` *undescribed* +``bool save`` + Save value across power states + ``__u32 * result`` The command completion result from CQE dword0 @@ -2502,7 +2490,7 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_write_atomic (int fd, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_set_features_lba_range (int fd, __u32 nsid, __u32 nr_ranges, bool save, struct nvme_lba_range_type * data, __u32 * result) **Parameters** @@ -2510,8 +2498,17 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` +``__u32 nsid`` + *undescribed* + +``__u32 nr_ranges`` + *undescribed* + +``bool save`` + Save value across power states + +``struct nvme_lba_range_type * data`` + *undescribed* ``__u32 * result`` The command completion result from CQE dword0 @@ -2522,27 +2519,21 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_async_event (int fd, enum nvme_get_features_sel sel, __u32 * result) - -**Parameters** -``int fd`` - File descriptor of nvme device +.. c:type:: enum nvme_feat_tmpthresh_thsel -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``__u32 * result`` - The command completion result from CQE dword0 +**Constants** -**Return** +``NVME_FEATURE_TEMPTHRESH_THSEL_OVER`` + *undescribed* -The nvme command status if a response was received or -1 with errno - set otherwise. +``NVME_FEATURETEMPTHRESH__THSEL_UNDER`` + *undescribed* -.. c:function:: int nvme_get_features_auto_pst (int fd, enum nvme_get_features_sel sel, struct nvme_feat_auto_pst * apst, __u32 * result) +.. c:function:: int nvme_set_features_temp_thresh (int fd, __u16 tmpth, __u8 tmpsel, enum nvme_feat_tmpthresh_thsel thsel, bool save, __u32 * result) **Parameters** @@ -2550,12 +2541,18 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` +``__u16 tmpth`` + *undescribed* -``struct nvme_feat_auto_pst * apst`` +``__u8 tmpsel`` + *undescribed* + +``enum nvme_feat_tmpthresh_thsel thsel`` *undescribed* +``bool save`` + Save value across power states + ``__u32 * result`` The command completion result from CQE dword0 @@ -2565,7 +2562,7 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_host_mem_buf (int fd, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_set_features_err_recovery (int fd, __u32 nsid, __u16 tler, bool dulbe, bool save, __u32 * result) **Parameters** @@ -2573,8 +2570,17 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` +``__u32 nsid`` + *undescribed* + +``__u16 tler`` + *undescribed* + +``bool dulbe`` + *undescribed* + +``bool save`` + Save value across power states ``__u32 * result`` The command completion result from CQE dword0 @@ -2585,7 +2591,7 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_timestamp (int fd, enum nvme_get_features_sel sel, struct nvme_timestamp * ts) +.. c:function:: int nvme_set_features_volatile_wc (int fd, bool wce, bool save, __u32 * result) **Parameters** @@ -2593,19 +2599,22 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``struct nvme_timestamp * ts`` +``bool wce`` *undescribed* +``bool save`` + Save value across power states + +``__u32 * result`` + The command completion result from CQE dword0 + **Return** The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_kato (int fd, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_set_features_irq_coalesce (int fd, __u8 thr, __u8 time, bool save, __u32 * result) **Parameters** @@ -2613,8 +2622,14 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` +``__u8 thr`` + *undescribed* + +``__u8 time`` + *undescribed* + +``bool save`` + Save value across power states ``__u32 * result`` The command completion result from CQE dword0 @@ -2625,7 +2640,7 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_hctm (int fd, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_set_features_irq_config (int fd, __u16 iv, bool cd, bool save, __u32 * result) **Parameters** @@ -2633,8 +2648,14 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` +``__u16 iv`` + *undescribed* + +``bool cd`` + *undescribed* + +``bool save`` + Save value across power states ``__u32 * result`` The command completion result from CQE dword0 @@ -2645,7 +2666,7 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_nopsc (int fd, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_set_features_write_atomic (int fd, bool dn, bool save, __u32 * result) **Parameters** @@ -2653,8 +2674,11 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` +``bool dn`` + *undescribed* + +``bool save`` + Save value across power states ``__u32 * result`` The command completion result from CQE dword0 @@ -2665,53 +2689,57 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_rrl (int fd, enum nvme_get_features_sel sel, __u32 * result) -**Parameters** +.. c:type:: enum nvme_features_async_event_config_flags -``int fd`` - File descriptor of nvme device -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` +**Constants** -``__u32 * result`` - The command completion result from CQE dword0 +``NVME_FEATURE_AENCFG_SMART_CRIT_SPARE`` + *undescribed* -**Return** +``NVME_FEATURE_AENCFG_SMART_CRIT_TEMPERATURE`` + *undescribed* -The nvme command status if a response was received or -1 with errno - set otherwise. +``NVME_FEATURE_AENCFG_SMART_CRIT_DEGRADED`` + *undescribed* +``NVME_FEATURE_AENCFG_SMART_CRIT_READ_ONLY`` + *undescribed* -.. c:function:: int nvme_get_features_plm_config (int fd, enum nvme_get_features_sel sel, __u16 nvmsetid, struct nvme_plm_config * data, __u32 * result) +``NVME_FEATURE_AENCFG_SMART_CRIT_VOLATILE_BACKUP`` + *undescribed* +``NVME_FEATURE_AENCFG_SMART_CRIT_READ_ONLY_PMR`` + *undescribed* -**Parameters** +``NVME_FEATURE_AENCFG_NOTICE_NAMESPACE_ATTRIBUTES`` + *undescribed* -``int fd`` - File descriptor of nvme device +``NVME_FEATURE_AENCFG_NOTICE_FIRMWARE_ACTIVATION`` + *undescribed* -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` +``NVME_FEATURE_AENCFG_NOTICE_TELEMETRY_LOG`` + *undescribed* -``__u16 nvmsetid`` +``NVME_FEATURE_AENCFG_NOTICE_ANA_CHANGE`` *undescribed* -``struct nvme_plm_config * data`` +``NVME_FEATURE_AENCFG_NOTICE_PL_EVENT`` *undescribed* -``__u32 * result`` - The command completion result from CQE dword0 +``NVME_FEATURE_AENCFG_NOTICE_LBA_STATUS`` + *undescribed* -**Return** +``NVME_FEATURE_AENCFG_NOTICE_EG_EVENT`` + *undescribed* -The nvme command status if a response was received or -1 with errno - set otherwise. +``NVME_FEATURE_AENCFG_NOTICE_DISCOVERY_CHANGE`` + *undescribed* -.. c:function:: int nvme_get_features_plm_window (int fd, enum nvme_get_features_sel sel, __u16 nvmsetid, __u32 * result) +.. c:function:: int nvme_set_features_async_event (int fd, __u32 events, bool save, __u32 * result) **Parameters** @@ -2719,13 +2747,13 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``__u16 nvmsetid`` +``__u32 events`` *undescribed* -``__u32 * result`` +``bool save`` + Save value across power states + +``__u32 * result`` The command completion result from CQE dword0 **Return** @@ -2734,7 +2762,7 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_lba_sts_interval (int fd, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_set_features_auto_pst (int fd, bool apste, bool save, struct nvme_feat_auto_pst * apst, __u32 * result) **Parameters** @@ -2742,8 +2770,14 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` +``bool apste`` + *undescribed* + +``bool save`` + Save value across power states + +``struct nvme_feat_auto_pst * apst`` + *undescribed* ``__u32 * result`` The command completion result from CQE dword0 @@ -2754,7 +2788,7 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_host_behavior (int fd, enum nvme_get_features_sel sel, struct nvme_feat_host_behavior * data, __u32 * result) +.. c:function:: int nvme_set_features_timestamp (int fd, bool save, __u64 timestamp) **Parameters** @@ -2762,14 +2796,11 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``struct nvme_feat_host_behavior * data`` - *undescribed* +``bool save`` + Save value across power states -``__u32 * result`` - The command completion result from CQE dword0 +``__u64 timestamp`` + The current timestamp value to assign to this this feature **Return** @@ -2777,7 +2808,7 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_sanitize (int fd, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_set_features_hctm (int fd, __u16 tmt2, __u16 tmt1, bool save, __u32 * result) **Parameters** @@ -2785,8 +2816,14 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` +``__u16 tmt2`` + *undescribed* + +``__u16 tmt1`` + *undescribed* + +``bool save`` + Save value across power states ``__u32 * result`` The command completion result from CQE dword0 @@ -2797,7 +2834,25 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_endurance_event_cfg (int fd, enum nvme_get_features_sel sel, __u16 endgid, __u32 * result) +.. c:function:: int nvme_set_features_nopsc (int fd, bool noppme, bool save, __u32 * result) + + +**Parameters** + +``int fd`` + *undescribed* + +``bool noppme`` + *undescribed* + +``bool save`` + *undescribed* + +``__u32 * result`` + *undescribed* + + +.. c:function:: int nvme_set_features_rrl (int fd, __u8 rrl, __u16 nvmsetid, bool save, __u32 * result) **Parameters** @@ -2805,12 +2860,15 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` +``__u8 rrl`` + *undescribed* -``__u16 endgid`` +``__u16 nvmsetid`` *undescribed* +``bool save`` + Save value across power states + ``__u32 * result`` The command completion result from CQE dword0 @@ -2820,7 +2878,7 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_sw_progress (int fd, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_set_features_plm_config (int fd, bool enable, __u16 nvmsetid, bool save, struct nvme_plm_config * data, __u32 * result) **Parameters** @@ -2828,8 +2886,17 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` +``bool enable`` + *undescribed* + +``__u16 nvmsetid`` + *undescribed* + +``bool save`` + Save value across power states + +``struct nvme_plm_config * data`` + *undescribed* ``__u32 * result`` The command completion result from CQE dword0 @@ -2840,7 +2907,21 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_host_id (int fd, enum nvme_get_features_sel sel, bool exhid, __u32 len, __u8 * hostid) + + +.. c:type:: enum nvme_feat_plm_window_select + + +**Constants** + +``NVME_FEATURE_PLM_DTWIN`` + *undescribed* + +``NVME_FEATURE_PLM_NDWIN`` + *undescribed* + + +.. c:function:: int nvme_set_features_plm_window (int fd, enum nvme_feat_plm_window_select sel, __u16 nvmsetid, bool save, __u32 * result) **Parameters** @@ -2848,17 +2929,17 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``bool exhid`` +``enum nvme_feat_plm_window_select sel`` *undescribed* -``__u32 len`` +``__u16 nvmsetid`` *undescribed* -``__u8 * hostid`` - *undescribed* +``bool save`` + Save value across power states + +``__u32 * result`` + The command completion result from CQE dword0 **Return** @@ -2866,7 +2947,7 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_resv_mask (int fd, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_set_features_lba_sts_interval (int fd, __u16 lsiri, __u16 lsipi, bool save, __u32 * result) **Parameters** @@ -2874,8 +2955,14 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` +``__u16 lsiri`` + *undescribed* + +``__u16 lsipi`` + *undescribed* + +``bool save`` + Save value across power states ``__u32 * result`` The command completion result from CQE dword0 @@ -2886,7 +2973,7 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_resv_persist (int fd, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_set_features_host_behavior (int fd, bool save, struct nvme_feat_host_behavior * data) **Parameters** @@ -2894,11 +2981,11 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` +``bool save`` + Save value across power states -``__u32 * result`` - The command completion result from CQE dword0 +``struct nvme_feat_host_behavior * data`` + *undescribed* **Return** @@ -2906,7 +2993,7 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_write_protect (int fd, __u32 nsid, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_set_features_sanitize (int fd, bool nodrm, bool save, __u32 * result) **Parameters** @@ -2914,11 +3001,11 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``__u32 nsid`` - Namespace ID +``bool nodrm`` + *undescribed* -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` +``bool save`` + Save value across power states ``__u32 * result`` The command completion result from CQE dword0 @@ -2929,43 +3016,25 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_format_nvm (int fd, __u32 nsid, __u8 lbaf, enum nvme_cmd_format_mset mset, enum nvme_cmd_format_pi pi, enum nvme_cmd_format_pil pil, enum nvme_cmd_format_ses ses, __u32 timeout) +.. c:function:: int nvme_set_features_endurance_evt_cfg (int fd, __u16 endgid, __u8 egwarn, bool save, __u32 * result) - Format nvme namespace(s) **Parameters** ``int fd`` File descriptor of nvme device -``__u32 nsid`` - Namespace ID to format - -``__u8 lbaf`` - Logical block address format - -``enum nvme_cmd_format_mset mset`` - Metadata settings (extended or separated), true if extended - -``enum nvme_cmd_format_pi pi`` - Protection information type - -``enum nvme_cmd_format_pil pil`` - Protection information location (beginning or end), true if end - -``enum nvme_cmd_format_ses ses`` - Secure erase settings +``__u16 endgid`` + *undescribed* -``__u32 timeout`` - Set to override default timeout to this value in milliseconds; - useful for long running formats. 0 will use system default. +``__u8 egwarn`` + Flags to enable warning, see :c:type:`enum nvme_eg_critical_warning_flags ` -**Description** +``bool save`` + Save value across power states -The Format NVM command is used to low level format the NVM media. This -command is used by the host to change the LBA data size and/or metadata -size. A low level format may destroy all data and metadata associated with -all namespaces or only the specific namespace associated with the command +``__u32 * result`` + The command completion result from CQE dword0 **Return** @@ -2973,7 +3042,7 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_ns_mgmt (int fd, __u32 nsid, enum nvme_ns_mgmt_sel sel, struct nvme_id_ns * ns, __u32 * result, __u32 timeout) +.. c:function:: int nvme_set_features_sw_progress (int fd, __u8 pbslc, bool save, __u32 * result) **Parameters** @@ -2981,23 +3050,22 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``__u32 nsid`` - *undescribed* - -``enum nvme_ns_mgmt_sel sel`` +``__u8 pbslc`` *undescribed* -``struct nvme_id_ns * ns`` - *undescribed* +``bool save`` + Save value across power states ``__u32 * result`` - *undescribed* + The command completion result from CQE dword0 -``__u32 timeout`` - *undescribed* +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. -.. c:function:: int nvme_ns_mgmt_create (int fd, struct nvme_id_ns * ns, __u32 * nsid, __u32 timeout) +.. c:function:: int nvme_set_features_host_id (int fd, bool exhid, bool save, __u8 * hostid) **Parameters** @@ -3005,21 +3073,14 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``struct nvme_id_ns * ns`` - Namespace identifiaction that defines creation parameters - -``__u32 * nsid`` - On success, set to the namespace id that was created - -``__u32 timeout`` - Overide the default timeout to this value in milliseconds; - set to 0 to use the system default. +``bool exhid`` + *undescribed* -**Description** +``bool save`` + Save value across power states -On successful creation, the namespace exists in the subsystem, but is not -attached to any controller. Use the nvme_ns_attach_ctrls() to assign the -namespace to one or more controllers. +``__u8 * hostid`` + *undescribed* **Return** @@ -3027,7 +3088,7 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_ns_mgmt_delete (int fd, __u32 nsid) +.. c:function:: int nvme_set_features_resv_mask (int fd, __u32 mask, bool save, __u32 * result) **Parameters** @@ -3035,14 +3096,14 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``__u32 nsid`` - Namespace identifier to delete +``__u32 mask`` + *undescribed* -**Description** +``bool save`` + Save value across power states -It is recommended that a namespace being deleted is not attached to any -controller. Use the nvme_ns_detach_ctrls() first if the namespace is still -attached. +``__u32 * result`` + The command completion result from CQE dword0 **Return** @@ -3050,87 +3111,65 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_ns_attach (int fd, __u32 nsid, enum nvme_ns_attach_sel sel, struct nvme_ctrl_list * ctrlist) +.. c:function:: int nvme_set_features_resv_persist (int fd, bool ptpl, bool save, __u32 * result) - Attach or detach namespace to controller(s) **Parameters** ``int fd`` File descriptor of nvme device -``__u32 nsid`` - Namespace ID to execute attach selection +``bool ptpl`` + *undescribed* -``enum nvme_ns_attach_sel sel`` - Attachment selection, see :c:type:`enum nvme_ns_attach_sel ` +``bool save`` + Save value across power states -``struct nvme_ctrl_list * ctrlist`` - Controller list to modify attachment state of nsid +``__u32 * result`` + The command completion result from CQE dword0 +**Return** -.. c:function:: int nvme_ns_attach_ctrls (int fd, __u32 nsid, struct nvme_ctrl_list * ctrlist) +The nvme command status if a response was received or -1 with errno + set otherwise. -**Parameters** - -``int fd`` - File descriptor of nvme device -``__u32 nsid`` - Namespace ID to attach - -``struct nvme_ctrl_list * ctrlist`` - Controller list to modify attachment state of nsid +.. c:type:: enum nvme_feat_nswpcfg_state -.. c:function:: int nvme_ns_dettach_ctrls (int fd, __u32 nsid, struct nvme_ctrl_list * ctrlist) +**Constants** -**Parameters** +``NVME_FEAT_NS_NO_WRITE_PROTECT`` + *undescribed* -``int fd`` - File descriptor of nvme device +``NVME_FEAT_NS_WRITE_PROTECT`` + *undescribed* -``__u32 nsid`` - Namespace ID to dettach +``NVME_FEAT_NS_WRITE_PROTECT_PWR_CYCLE`` + *undescribed* -``struct nvme_ctrl_list * ctrlist`` - Controller list to modify attachment state of nsid +``NVME_FEAT_NS_WRITE_PROTECT_PERMANENT`` + *undescribed* -.. c:function:: int nvme_fw_download (int fd, __u32 offset, __u32 data_len, void * data) +.. c:function:: int nvme_set_features_write_protect (int fd, enum nvme_feat_nswpcfg_state state, bool save, __u32 * result) - Download part or all of a firmware image to the controller **Parameters** ``int fd`` File descriptor of nvme device -``__u32 offset`` - Offset in the firmware data - -``__u32 data_len`` - Length of data in this command in bytes - -``void * data`` - Userspace address of the firmware data - -**Description** - -The Firmware Image Download command is used to download all or a portion of -an image for a future update to the controller. The Firmware Image Download -command downloads a new image (in whole or in part) to the controller. +``enum nvme_feat_nswpcfg_state state`` + *undescribed* -The image may be constructed of multiple pieces that are individually -downloaded with separate Firmware Image Download commands. Each Firmware -Image Download command includes a Dword Offset and Number of Dwords that -specify a dword range. +``bool save`` + Save value across power states -The new firmware image is not activated as part of the Firmware Image -Download command. Use the nvme_fw_commit() to activate a newly downloaded -image. +``__u32 * result`` + The command completion result from CQE dword0 **Return** @@ -3138,37 +3177,46 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_fw_commit (int fd, __u8 slot, enum nvme_fw_commit_ca action, bool bpid) +.. c:function:: int nvme_get_features (int fd, enum nvme_features_id fid, __u32 nsid, enum nvme_get_features_sel sel, __u32 cdw11, __u8 uuidx, __u32 data_len, void * data, __u32 * result) - Commit firmware using the specified action + Retrieve a feature attribute **Parameters** ``int fd`` File descriptor of nvme device -``__u8 slot`` - Firmware slot to commit the downloaded image +``enum nvme_features_id fid`` + Feature identifier -``enum nvme_fw_commit_ca action`` - Action to use for the firmware image, see :c:type:`enum nvme_fw_commit_ca ` +``__u32 nsid`` + Namespace ID, if applicable -``bool bpid`` - Set to true to select the boot partition id +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -**Description** +``__u32 cdw11`` + Feature specific command dword11 field -The Firmware Commit command is used to modify the firmware image or Boot -Partitions. +``__u8 uuidx`` + UUID Index for differentiating vendor specific encoding + +``__u32 data_len`` + Length of feature data, if applicable, in bytes + +``void * data`` + User address of feature data, if applicable + +``__u32 * result`` + The command completion result from CQE dword0 **Return** The nvme command status if a response was received or -1 with errno - set otherwise. The command status response may specify additional - reset actions required to complete the commit process. + set otherwise. -.. c:function:: int nvme_security_send (int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, __u8 secp, __u32 tl, __u32 data_len, void * data, __u32 * result) +.. c:function:: int nvme_get_features_arbitration (int fd, enum nvme_get_features_sel sel, __u32 * result) **Parameters** @@ -3176,51 +3224,19 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``__u32 nsid`` - Namespace ID to issue security command on - -``__u8 nssf`` - NVMe Security Specific field - -``__u8 spsp0`` - Security Protocol Specific field - -``__u8 spsp1`` - Security Protocol Specific field - -``__u8 secp`` - Security Protocol - -``__u32 tl`` - Protocol specific transfer length - -``__u32 data_len`` - Data length of the payload in bytes - -``void * data`` - Security data payload to send +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` ``__u32 * result`` The command completion result from CQE dword0 -**Description** - -The Security Send command is used to transfer security protocol data to the -controller. The data structure transferred to the controller as part of this -command contains security protocol specific commands to be performed by the -controller. The data structure transferred may also contain data or -parameters associated with the security protocol commands. - -The security data is protocol specific and is not defined by the NVMe -specification. - **Return** The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_security_receive (int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, __u8 secp, __u32 al, __u32 data_len, void * data, __u32 * result) +.. c:function:: int nvme_get_features_power_mgmt (int fd, enum nvme_get_features_sel sel, __u32 * result) **Parameters** @@ -3228,29 +3244,8 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``__u32 nsid`` - Namespace ID to issue security command on - -``__u8 nssf`` - NVMe Security Specific field - -``__u8 spsp0`` - Security Protocol Specific field - -``__u8 spsp1`` - Security Protocol Specific field - -``__u8 secp`` - Security Protocol - -``__u32 al`` - Protocol specific allocation length - -``__u32 data_len`` - Data length of the payload in bytes - -``void * data`` - Security data payload to send +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` ``__u32 * result`` The command completion result from CQE dword0 @@ -3261,38 +3256,22 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_get_lba_status (int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl, enum nvme_lba_status_atype atype, struct nvme_lba_status * lbas) +.. c:function:: int nvme_get_features_lba_range (int fd, enum nvme_get_features_sel sel, struct nvme_lba_range_type * data, __u32 * result) - Retrieve information on possibly unrecoverable LBAs **Parameters** ``int fd`` File descriptor of nvme device -``__u32 nsid`` - Namespace ID to retrieve LBA status - -``__u64 slba`` - Starting logical block address to check statuses - -``__u32 mndw`` - Maximum number of dwords to return - -``__u16 rl`` - Range length from slba to perform the action - -``enum nvme_lba_status_atype atype`` - Action type mechanism to determine LBA status desctriptors to - return, see :c:type:`enum nvme_lba_status_atype ` - -``struct nvme_lba_status * lbas`` - Data payload to return status descriptors +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -**Description** +``struct nvme_lba_range_type * data`` + *undescribed* -The Get LBA Status command requests information about Potentially -Unrecoverable LBAs. Refer to the specification for action type descriptions. +``__u32 * result`` + The command completion result from CQE dword0 **Return** @@ -3300,46 +3279,19 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_directive_send (int fd, __u32 nsid, __u16 dspec, __u8 doper, enum nvme_directive_dtype dtype, __u32 cdw12, __u32 data_len, void * data, __u32 * result) +.. c:function:: int nvme_get_features_temp_thresh (int fd, enum nvme_get_features_sel sel, __u32 * result) - Send directive command **Parameters** ``int fd`` File descriptor of nvme device -``__u32 nsid`` - Namespace ID, if applicable - -``__u16 dspec`` - Directive specific field - -``__u8 doper`` - Directive operation - -``enum nvme_directive_dtype dtype`` - Directive type, see :c:type:`enum nvme_directive_dtype ` - -``__u32 cdw12`` - *undescribed* - -``__u32 data_len`` - Length of data payload in bytes - -``void * data`` - Usespace address of data payload +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` ``__u32 * result`` - If successful, the CQE dword0 value - -**Description** - -Directives is a mechanism to enable host and NVM subsystem or controller -information exchange. The Directive Send command is used to transfer data -related to a specific Directive Type from the host to the controller. - -See the NVMe specification for more information. + The command completion result from CQE dword0 **Return** @@ -3347,7 +3299,7 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_directive_send_id_endir (int fd, __u32 nsid, bool endir, enum nvme_directive_dtype dtype, struct nvme_id_directives * id) +.. c:function:: int nvme_get_features_err_recovery (int fd, enum nvme_get_features_sel sel, __u32 * result) **Parameters** @@ -3355,17 +3307,11 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``__u32 nsid`` - Namespace ID - -``bool endir`` - *undescribed* - -``enum nvme_directive_dtype dtype`` - *undescribed* +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``struct nvme_id_directives * id`` - *undescribed* +``__u32 * result`` + The command completion result from CQE dword0 **Return** @@ -3373,7 +3319,7 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_directive_send_stream_release_identifier (int fd, __u32 nsid, __u16 stream_id) +.. c:function:: int nvme_get_features_volatile_wc (int fd, enum nvme_get_features_sel sel, __u32 * result) **Parameters** @@ -3381,11 +3327,11 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``__u32 nsid`` - Namespace ID +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``__u16 stream_id`` - *undescribed* +``__u32 * result`` + The command completion result from CQE dword0 **Return** @@ -3393,7 +3339,7 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_directive_send_stream_release_resource (int fd, __u32 nsid) +.. c:function:: int nvme_get_features_num_queues (int fd, enum nvme_get_features_sel sel, __u32 * result) **Parameters** @@ -3401,8 +3347,11 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``__u32 nsid`` - Namespace ID +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` + +``__u32 * result`` + The command completion result from CQE dword0 **Return** @@ -3410,38 +3359,42 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_directive_recv (int fd, __u32 nsid, __u16 dspec, __u8 doper, enum nvme_directive_dtype dtype, __u32 cdw12, __u32 data_len, void * data, __u32 * result) +.. c:function:: int nvme_get_features_irq_coalesce (int fd, enum nvme_get_features_sel sel, __u32 * result) - Receive directive specific data **Parameters** ``int fd`` File descriptor of nvme device -``__u32 nsid`` - Namespace ID, if applicable +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``__u16 dspec`` - Directive specific field +``__u32 * result`` + The command completion result from CQE dword0 -``__u8 doper`` - Directive operation +**Return** -``enum nvme_directive_dtype dtype`` - Directive type, see :c:type:`enum nvme_directive_dtype ` +The nvme command status if a response was received or -1 with errno + set otherwise. -``__u32 cdw12`` - *undescribed* -``__u32 data_len`` - Length of data payload +.. c:function:: int nvme_get_features_irq_config (int fd, enum nvme_get_features_sel sel, __u16 iv, __u32 * result) -``void * data`` - Usespace address of data payload in bytes + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` + +``__u16 iv`` + *undescribed* ``__u32 * result`` - If successful, the CQE dword0 value + The command completion result from CQE dword0 **Return** @@ -3449,7 +3402,7 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_directive_recv_identify_parameters (int fd, __u32 nsid, struct nvme_id_directives * id) +.. c:function:: int nvme_get_features_write_atomic (int fd, enum nvme_get_features_sel sel, __u32 * result) **Parameters** @@ -3457,11 +3410,11 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``__u32 nsid`` - Namespace ID +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``struct nvme_id_directives * id`` - *undescribed* +``__u32 * result`` + The command completion result from CQE dword0 **Return** @@ -3469,7 +3422,7 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_directive_recv_stream_parameters (int fd, __u32 nsid, struct nvme_streams_directive_params * parms) +.. c:function:: int nvme_get_features_async_event (int fd, enum nvme_get_features_sel sel, __u32 * result) **Parameters** @@ -3477,11 +3430,11 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``__u32 nsid`` - Namespace ID +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``struct nvme_streams_directive_params * parms`` - *undescribed* +``__u32 * result`` + The command completion result from CQE dword0 **Return** @@ -3489,7 +3442,7 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_directive_recv_stream_status (int fd, __u32 nsid, unsigned nr_entries, struct nvme_streams_directive_status * id) +.. c:function:: int nvme_get_features_auto_pst (int fd, enum nvme_get_features_sel sel, struct nvme_feat_auto_pst * apst, __u32 * result) **Parameters** @@ -3497,14 +3450,14 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``__u32 nsid`` - Namespace ID +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``unsigned nr_entries`` +``struct nvme_feat_auto_pst * apst`` *undescribed* -``struct nvme_streams_directive_status * id`` - *undescribed* +``__u32 * result`` + The command completion result from CQE dword0 **Return** @@ -3512,7 +3465,7 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_directive_recv_stream_allocate (int fd, __u32 nsid, __u16 nsr, __u32 * result) +.. c:function:: int nvme_get_features_host_mem_buf (int fd, enum nvme_get_features_sel sel, __u32 * result) **Parameters** @@ -3520,14 +3473,11 @@ The nvme command status if a response was received or -1 with errno ``int fd`` File descriptor of nvme device -``__u32 nsid`` - Namespace ID - -``__u16 nsr`` - *undescribed* +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` ``__u32 * result`` - *undescribed* + The command completion result from CQE dword0 **Return** @@ -3535,51 +3485,39 @@ The nvme command status if a response was received or -1 with errno set otherwise. +.. c:function:: int nvme_get_features_timestamp (int fd, enum nvme_get_features_sel sel, struct nvme_timestamp * ts) -.. c:type:: enum nvme_fctype - - -**Constants** - -``nvme_fabrics_type_property_set`` - *undescribed* +**Parameters** -``nvme_fabrics_type_connect`` - *undescribed* +``int fd`` + File descriptor of nvme device -``nvme_fabrics_type_property_get`` - *undescribed* +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``nvme_fabrics_type_auth_send`` +``struct nvme_timestamp * ts`` *undescribed* -``nvme_fabrics_type_auth_receive`` - *undescribed* +**Return** -``nvme_fabrics_type_disconnect`` - *undescribed* +The nvme command status if a response was received or -1 with errno + set otherwise. -.. c:function:: int nvme_set_property (int fd, int offset, __u64 value) +.. c:function:: int nvme_get_features_kato (int fd, enum nvme_get_features_sel sel, __u32 * result) - Set controller property **Parameters** ``int fd`` File descriptor of nvme device -``int offset`` - Property offset from the base to set - -``__u64 value`` - The value to set the property - -**Description** +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -This is an NVMe-over-Fabrics specific command, not applicable to PCIe. These -properties align to the PCI MMIO controller registers. +``__u32 * result`` + The command completion result from CQE dword0 **Return** @@ -3587,25 +3525,19 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_get_property (int fd, int offset, __u64 * value) +.. c:function:: int nvme_get_features_hctm (int fd, enum nvme_get_features_sel sel, __u32 * result) - Get a controller property **Parameters** ``int fd`` File descriptor of nvme device -``int offset`` - Property offset from the base to retrieve - -``__u64 * value`` - Where the property's value will be stored on success - -**Description** +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -This is an NVMe-over-Fabrics specific command, not applicable to PCIe. These -properties align to the PCI MMIO controller registers. +``__u32 * result`` + The command completion result from CQE dword0 **Return** @@ -3613,44 +3545,39 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_sanitize_nvm (int fd, enum nvme_sanitize_sanact sanact, bool ause, __u8 owpass, bool oipbp, bool nodas, __u32 ovrpat) +.. c:function:: int nvme_get_features_nopsc (int fd, enum nvme_get_features_sel sel, __u32 * result) - Start a sanitize operation **Parameters** ``int fd`` File descriptor of nvme device -``enum nvme_sanitize_sanact sanact`` - Sanitize action, see :c:type:`enum nvme_sanitize_sanact ` +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``bool ause`` - Set to allow unrestriced sanitize exit +``__u32 * result`` + The command completion result from CQE dword0 -``__u8 owpass`` - Overwrite pass count +**Return** -``bool oipbp`` - Set to overwrite invert pattern between passes +The nvme command status if a response was received or -1 with errno + set otherwise. -``bool nodas`` - Set to not deallocate blocks after sanitizing -``__u32 ovrpat`` - Overwrite pattern +.. c:function:: int nvme_get_features_rrl (int fd, enum nvme_get_features_sel sel, __u32 * result) -**Description** -A sanitize operation alters all user data in the NVM subsystem such that -recovery of any previous user data from any cache, the non-volatile media, -or any Controller Memory Buffer is not possible. +**Parameters** -The Sanitize command is used to start a sanitize operation or to recover -from a previously failed sanitize operation. The sanitize operation types -that may be supported are Block Erase, Crypto Erase, and Overwrite. All -sanitize operations are processed in the background, i.e., completion of the -sanitize command does not indicate completion of the sanitize operation. +``int fd`` + File descriptor of nvme device + +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` + +``__u32 * result`` + The command completion result from CQE dword0 **Return** @@ -3658,33 +3585,25 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_dev_self_test (int fd, __u32 nsid, enum nvme_dst_stc stc) +.. c:function:: int nvme_get_features_plm_config (int fd, enum nvme_get_features_sel sel, __u16 nvmsetid, struct nvme_plm_config * data, __u32 * result) - Start or abort a self test **Parameters** ``int fd`` File descriptor of nvme device -``__u32 nsid`` - Namespace ID to test - -``enum nvme_dst_stc stc`` - Self test code, see :c:type:`enum nvme_dst_stc ` +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -**Description** +``__u16 nvmsetid`` + *undescribed* -The Device Self-test command is used to start a device self-test operation -or abort a device self-test operation. A device self-test operation is a -diagnostic testing sequence that tests the integrity and functionality of -the controller and may include testing of the media associated with -namespaces. The controller may return a response to this command immediately -while running the self-test in the background. +``struct nvme_plm_config * data`` + *undescribed* -Set the 'nsid' field to 0 to not include namepsaces in the test. Set to -0xffffffff to test all namespaces. All other values tests a specific -namespace, if present. +``__u32 * result`` + The command completion result from CQE dword0 **Return** @@ -3692,109 +3611,85 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_virtual_mgmt (int fd, enum nvme_virt_mgmt_act act, enum nvme_virt_mgmt_rt rt, __u16 cntlid, __u16 nr, __u32 * result) +.. c:function:: int nvme_get_features_plm_window (int fd, enum nvme_get_features_sel sel, __u16 nvmsetid, __u32 * result) - Virtualization resource management **Parameters** ``int fd`` File descriptor of nvme device -``enum nvme_virt_mgmt_act act`` - Virtual resource action, see :c:type:`enum nvme_virt_mgmt_act ` - -``enum nvme_virt_mgmt_rt rt`` - Resource type to modify, see :c:type:`enum nvme_virt_mgmt_rt ` - -``__u16 cntlid`` - Controller id for which resources are bing modified +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``__u16 nr`` - Number of resources being allocated or assigned +``__u16 nvmsetid`` + *undescribed* ``__u32 * result`` - If successful, the CQE dword0 - -**Description** + The command completion result from CQE dword0 -The Virtualization Management command is supported by primary controllers -that support the Virtualization Enhancements capability. This command is -used for several functions: +**Return** - - Modifying Flexible Resource allocation for the primary controller - - Assigning Flexible Resources for secondary controllers - - Setting the Online and Offline state for secondary controllers +The nvme command status if a response was received or -1 with errno + set otherwise. -**Return** -The nvme command status if a response was received or -1 - with errno set otherwise. +.. c:function:: int nvme_get_features_lba_sts_interval (int fd, enum nvme_get_features_sel sel, __u32 * result) -**NVMe IO command** +**Parameters** +``int fd`` + File descriptor of nvme device +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` +``__u32 * result`` + The command completion result from CQE dword0 -.. c:type:: enum nvme_io_opcode +**Return** +The nvme command status if a response was received or -1 with errno + set otherwise. -**Constants** -``nvme_cmd_flush`` - *undescribed* +.. c:function:: int nvme_get_features_host_behavior (int fd, enum nvme_get_features_sel sel, struct nvme_feat_host_behavior * data, __u32 * result) -``nvme_cmd_write`` - *undescribed* -``nvme_cmd_read`` - *undescribed* +**Parameters** -``nvme_cmd_write_uncor`` - *undescribed* - -``nvme_cmd_compare`` - *undescribed* - -``nvme_cmd_write_zeroes`` - *undescribed* - -``nvme_cmd_dsm`` - *undescribed* +``int fd`` + File descriptor of nvme device -``nvme_cmd_verify`` - *undescribed* +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``nvme_cmd_resv_register`` +``struct nvme_feat_host_behavior * data`` *undescribed* -``nvme_cmd_resv_report`` - *undescribed* +``__u32 * result`` + The command completion result from CQE dword0 -``nvme_cmd_resv_acquire`` - *undescribed* +**Return** -``nvme_cmd_resv_release`` - *undescribed* +The nvme command status if a response was received or -1 with errno + set otherwise. -.. c:function:: int nvme_flush (int fd, __u32 nsid) +.. c:function:: int nvme_get_features_sanitize (int fd, enum nvme_get_features_sel sel, __u32 * result) - Send an nvme flush command **Parameters** ``int fd`` File descriptor of nvme device -``__u32 nsid`` - Namespace identifier - -**Description** +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -The Flush command is used to request that the contents of volatile write -cache be made non-volatile. +``__u32 * result`` + The command completion result from CQE dword0 **Return** @@ -3802,142 +3697,131 @@ The nvme command status if a response was received or -1 with errno set otherwise. +.. c:function:: int nvme_get_features_endurance_event_cfg (int fd, enum nvme_get_features_sel sel, __u16 endgid, __u32 * result) -.. c:type:: enum nvme_io_control_flags +**Parameters** +``int fd`` + File descriptor of nvme device -**Constants** +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``NVME_IO_DTYPE_STREAMS`` +``__u16 endgid`` *undescribed* -``NVME_IO_DEAC`` - *undescribed* +``__u32 * result`` + The command completion result from CQE dword0 -``NVME_IO_PRINFO_PRCHK_REF`` - *undescribed* +**Return** -``NVME_IO_PRINFO_PRCHK_APP`` - *undescribed* +The nvme command status if a response was received or -1 with errno + set otherwise. -``NVME_IO_PRINFO_PRCHK_GUARD`` - *undescribed* -``NVME_IO_PRINFO_PRACT`` - *undescribed* +.. c:function:: int nvme_get_features_sw_progress (int fd, enum nvme_get_features_sel sel, __u32 * result) -``NVME_IO_FUA`` - *undescribed* -``NVME_IO_LR`` - *undescribed* +**Parameters** +``int fd`` + File descriptor of nvme device +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` +``__u32 * result`` + The command completion result from CQE dword0 -.. c:type:: enum nvme_io_dsm_flags +**Return** +The nvme command status if a response was received or -1 with errno + set otherwise. -**Constants** -``NVME_IO_DSM_FREQ_UNSPEC`` - *undescribed* +.. c:function:: int nvme_get_features_host_id (int fd, enum nvme_get_features_sel sel, bool exhid, __u32 len, __u8 * hostid) -``NVME_IO_DSM_FREQ_TYPICAL`` - *undescribed* -``NVME_IO_DSM_FREQ_RARE`` - *undescribed* +**Parameters** -``NVME_IO_DSM_FREQ_READS`` - *undescribed* +``int fd`` + File descriptor of nvme device -``NVME_IO_DSM_FREQ_WRITES`` - *undescribed* +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``NVME_IO_DSM_FREQ_RW`` +``bool exhid`` *undescribed* -``NVME_IO_DSM_FREQ_ONCE`` +``__u32 len`` *undescribed* -``NVME_IO_DSM_FREQ_PREFETCH`` +``__u8 * hostid`` *undescribed* -``NVME_IO_DSM_FREQ_TEMP`` - *undescribed* +**Return** -``NVME_IO_DSM_LATENCY_NONE`` - *undescribed* +The nvme command status if a response was received or -1 with errno + set otherwise. -``NVME_IO_DSM_LATENCY_IDLE`` - *undescribed* -``NVME_IO_DSM_LATENCY_NORM`` - *undescribed* +.. c:function:: int nvme_get_features_resv_mask (int fd, enum nvme_get_features_sel sel, __u32 * result) -``NVME_IO_DSM_LATENCY_LOW`` - *undescribed* -``NVME_IO_DSM_SEQ_REQ`` - *undescribed* +**Parameters** -``NVME_IO_DSM_COMPRESSED`` - *undescribed* +``int fd`` + File descriptor of nvme device +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -.. c:function:: int nvme_read (int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u8 dsm, __u32 reftag, __u16 apptag, __u16 appmask, __u32 data_len, void * data, __u32 metadata_len, void * metadata) +``__u32 * result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_get_features_resv_persist (int fd, enum nvme_get_features_sel sel, __u32 * result) - Submit an nvme user read command **Parameters** ``int fd`` File descriptor of nvme device -``__u32 nsid`` - Namespace ID +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``__u64 slba`` - Starting logical block +``__u32 * result`` + The command completion result from CQE dword0 -``__u16 nlb`` - *undescribed* +**Return** -``__u16 control`` - Command control flags, see :c:type:`enum nvme_io_control_flags `. +The nvme command status if a response was received or -1 with errno + set otherwise. -``__u8 dsm`` - Data set management attributes, see :c:type:`enum nvme_io_dsm_flags ` -``__u32 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. +.. c:function:: int nvme_get_features_write_protect (int fd, __u32 nsid, enum nvme_get_features_sel sel, __u32 * result) -``__u16 apptag`` - This field specifies the Application Tag Mask expected value. - Used only if the namespace is formatted to use end-to-end - protection information. -``__u16 appmask`` - This field specifies the Application Tag expected value. Used - only if the namespace is formatted to use end-to-end protection - information. +**Parameters** -``__u32 data_len`` - Length of user buffer, **data**, in bytes +``int fd`` + File descriptor of nvme device -``void * data`` - Pointer to user address of the data buffer - metadata_len:Length of user buffer, **metadata**, in bytes +``__u32 nsid`` + Namespace ID -``__u32 metadata_len`` - *undescribed* +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``void * metadata`` - Pointer to user address of the metadata buffer +``__u32 * result`` + The command completion result from CQE dword0 **Return** @@ -3945,9 +3829,9 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_write (int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u8 dsm, __u16 dspec, __u32 reftag, __u16 apptag, __u16 appmask, __u32 data_len, void * data, __u32 metadata_len, void * metadata) +.. c:function:: int nvme_format_nvm (int fd, __u32 nsid, __u8 lbaf, enum nvme_cmd_format_mset mset, enum nvme_cmd_format_pi pi, enum nvme_cmd_format_pil pil, enum nvme_cmd_format_ses ses, __u32 timeout) - Submit an nvme user write command + Format nvme namespace(s) **Parameters** @@ -3955,50 +3839,33 @@ The nvme command status if a response was received or -1 with errno File descriptor of nvme device ``__u32 nsid`` - Namespace ID - -``__u64 slba`` - Starting logical block - -``__u16 nlb`` - *undescribed* - -``__u16 control`` - Command control flags, see :c:type:`enum nvme_io_control_flags `. - -``__u8 dsm`` - Data set management attributes, see :c:type:`enum nvme_io_dsm_flags ` + Namespace ID to format -``__u16 dspec`` - Directive specific command, eg: stream identifier +``__u8 lbaf`` + Logical block address format -``__u32 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. +``enum nvme_cmd_format_mset mset`` + Metadata settings (extended or separated), true if extended -``__u16 apptag`` - This field specifies the Application Tag Mask expected value. - Used only if the namespace is formatted to use end-to-end - protection information. +``enum nvme_cmd_format_pi pi`` + Protection information type -``__u16 appmask`` - This field specifies the Application Tag expected value. Used - only if the namespace is formatted to use end-to-end protection - information. +``enum nvme_cmd_format_pil pil`` + Protection information location (beginning or end), true if end -``__u32 data_len`` - Length of user buffer, **data**, in bytes +``enum nvme_cmd_format_ses ses`` + Secure erase settings -``void * data`` - Pointer to user address of the data buffer - metadata_len:Length of user buffer, **metadata**, in bytes +``__u32 timeout`` + Set to override default timeout to this value in milliseconds; + useful for long running formats. 0 will use system default. -``__u32 metadata_len`` - *undescribed* +**Description** -``void * metadata`` - Pointer to user address of the metadata buffer +The Format NVM command is used to low level format the NVM media. This +command is used by the host to change the LBA data size and/or metadata +size. A low level format may destroy all data and metadata associated with +all namespaces or only the specific namespace associated with the command **Return** @@ -4006,9 +3873,8 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_compare (int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 reftag, __u16 apptag, __u16 appmask, __u32 data_len, void * data, __u32 metadata_len, void * metadata) +.. c:function:: int nvme_ns_mgmt (int fd, __u32 nsid, enum nvme_ns_mgmt_sel sel, struct nvme_id_ns * ns, __u32 * result, __u32 timeout) - Submit an nvme user compare command **Parameters** @@ -4016,93 +3882,44 @@ The nvme command status if a response was received or -1 with errno File descriptor of nvme device ``__u32 nsid`` - Namespace ID + *undescribed* -``__u64 slba`` - Starting logical block - -``__u16 nlb`` +``enum nvme_ns_mgmt_sel sel`` *undescribed* -``__u16 control`` - Command control flags, see :c:type:`enum nvme_io_control_flags `. - -``__u32 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. - -``__u16 apptag`` - This field specifies the Application Tag Mask expected value. - Used only if the namespace is formatted to use end-to-end - protection information. - -``__u16 appmask`` - This field specifies the Application Tag expected value. Used - only if the namespace is formatted to use end-to-end protection - information. - -``__u32 data_len`` - Length of user buffer, **data**, in bytes - -``void * data`` - Pointer to user address of the data buffer - metadata_len:Length of user buffer, **metadata**, in bytes - -``__u32 metadata_len`` +``struct nvme_id_ns * ns`` *undescribed* -``void * metadata`` - Pointer to user address of the metadata buffer - -**Return** +``__u32 * result`` + *undescribed* -The nvme command status if a response was received or -1 with errno - set otherwise. +``__u32 timeout`` + *undescribed* -.. c:function:: int nvme_write_zeros (int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 reftag, __u16 apptag, __u16 appmask) +.. c:function:: int nvme_ns_mgmt_create (int fd, struct nvme_id_ns * ns, __u32 * nsid, __u32 timeout) - Submit an nvme write zeroes command **Parameters** ``int fd`` File descriptor of nvme device -``__u32 nsid`` - Namespace identifier - -``__u64 slba`` - Starting logical block - -``__u16 nlb`` - Number of logical blocks to clear (0's based value) - -``__u16 control`` - Command control flags, see :c:type:`enum nvme_io_control_flags `. - -``__u32 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. +``struct nvme_id_ns * ns`` + Namespace identifiaction that defines creation parameters -``__u16 apptag`` - This field specifies the Application Tag Mask expected value. - Used only if the namespace is formatted to use end-to-end - protection information. +``__u32 * nsid`` + On success, set to the namespace id that was created -``__u16 appmask`` - This field specifies the Application Tag expected value. Used - only if the namespace is formatted to use end-to-end protection - information. +``__u32 timeout`` + Overide the default timeout to this value in milliseconds; + set to 0 to use the system default. **Description** -The Write Zeroes command is used to set a range of logical blocks to zero. -After successful completion of this command, the value returned by -subsequent reads of logical blocks in this range shall be all bytes cleared -to 0h until a write occurs to this LBA range. +On successful creation, the namespace exists in the subsystem, but is not +attached to any controller. Use the nvme_ns_attach_ctrls() to assign the +namespace to one or more controllers. **Return** @@ -4110,9 +3927,8 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_write_uncorrectable (int fd, __u32 nsid, __u64 slba, __u16 nlb) +.. c:function:: int nvme_ns_mgmt_delete (int fd, __u32 nsid) - Submit an nvme write uncorrectable command **Parameters** @@ -4120,21 +3936,13 @@ The nvme command status if a response was received or -1 with errno File descriptor of nvme device ``__u32 nsid`` - Namespace identifier - -``__u64 slba`` - Starting logical block - -``__u16 nlb`` - Number of logical blocks to invalidate (0's based value) + Namespace identifier to delete **Description** -The Write Uncorrectable command is used to mark a range of logical blocks as -invalid. When the specified logical block(s) are read after this operation, -a failure is returned with Unrecovered Read Error status. To clear the -invalid logical block status, a write operation on those logical blocks is -required. +It is recommended that a namespace being deleted is not attached to any +controller. Use the nvme_ns_detach_ctrls() first if the namespace is still +attached. **Return** @@ -4142,9 +3950,9 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_verify (int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 reftag, __u16 apptag, __u16 appmask) +.. c:function:: int nvme_ns_attach (int fd, __u32 nsid, enum nvme_ns_attach_sel sel, struct nvme_ctrl_list * ctrlist) - Send an nvme verify command + Attach or detach namespace to controller(s) **Parameters** @@ -4152,90 +3960,77 @@ The nvme command status if a response was received or -1 with errno File descriptor of nvme device ``__u32 nsid`` - Namespace identifier - -``__u64 slba`` - Starting logical block - -``__u16 nlb`` - Number of logical blocks to verify (0's based value) - -``__u16 control`` - Command control flags, see :c:type:`enum nvme_io_control_flags `. + Namespace ID to execute attach selection -``__u32 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. +``enum nvme_ns_attach_sel sel`` + Attachment selection, see :c:type:`enum nvme_ns_attach_sel ` -``__u16 apptag`` - This field specifies the Application Tag Mask expected value. - Used only if the namespace is formatted to use end-to-end - protection information. +``struct nvme_ctrl_list * ctrlist`` + Controller list to modify attachment state of nsid -``__u16 appmask`` - This field specifies the Application Tag expected value. Used - only if the namespace is formatted to use end-to-end protection - information. -**Description** +.. c:function:: int nvme_ns_attach_ctrls (int fd, __u32 nsid, struct nvme_ctrl_list * ctrlist) -The Verify command verifies integrity of stored information by reading data -and metadata, if applicable, for the LBAs indicated without transferring any -data or metadata to the host. -**Return** +**Parameters** -The nvme command status if a response was received or -1 with errno - set otherwise. +``int fd`` + File descriptor of nvme device +``__u32 nsid`` + Namespace ID to attach +``struct nvme_ctrl_list * ctrlist`` + Controller list to modify attachment state of nsid -.. c:type:: enum nvme_dsm_attributes +.. c:function:: int nvme_ns_dettach_ctrls (int fd, __u32 nsid, struct nvme_ctrl_list * ctrlist) -**Constants** +**Parameters** -``NVME_DSMGMT_IDR`` - *undescribed* +``int fd`` + File descriptor of nvme device -``NVME_DSMGMT_IDW`` - *undescribed* +``__u32 nsid`` + Namespace ID to dettach -``NVME_DSMGMT_AD`` - *undescribed* +``struct nvme_ctrl_list * ctrlist`` + Controller list to modify attachment state of nsid -.. c:function:: int nvme_dsm (int fd, __u32 nsid, __u32 attrs, __u16 nr_ranges, struct nvme_dsm_range * dsm) +.. c:function:: int nvme_fw_download (int fd, __u32 offset, __u32 data_len, void * data) - Send an nvme data set management command + Download part or all of a firmware image to the controller **Parameters** ``int fd`` File descriptor of nvme device -``__u32 nsid`` - Namespace identifier - -``__u32 attrs`` - DSM attributes, see :c:type:`enum nvme_dsm_attributes ` - :c:type:`nr_ranges`: Number of block ranges in the data set management attributes +``__u32 offset`` + Offset in the firmware data -``__u16 nr_ranges`` - *undescribed* +``__u32 data_len`` + Length of data in this command in bytes -``struct nvme_dsm_range * dsm`` - The data set management attributes +``void * data`` + Userspace address of the firmware data **Description** -The Dataset Management command is used by the host to indicate attributes -for ranges of logical blocks. This includes attributes like frequency that -data is read or written, access size, and other information that may be used -to optimize performance and reliability, and may be used to -deallocate/unmap/trim those logical blocks. +The Firmware Image Download command is used to download all or a portion of +an image for a future update to the controller. The Firmware Image Download +command downloads a new image (in whole or in part) to the controller. + +The image may be constructed of multiple pieces that are individually +downloaded with separate Firmware Image Download commands. Each Firmware +Image Download command includes a Dword Offset and Number of Dwords that +specify a dword range. + +The new firmware image is not activated as part of the Firmware Image +Download command. Use the nvme_fw_commit() to activate a newly downloaded +image. **Return** @@ -4243,52 +4038,90 @@ The nvme command status if a response was received or -1 with errno set otherwise. +.. c:function:: int nvme_fw_commit (int fd, __u8 slot, enum nvme_fw_commit_ca action, bool bpid) + Commit firmware using the specified action -.. c:type:: enum nvme_reservation_rtype +**Parameters** +``int fd`` + File descriptor of nvme device -**Constants** +``__u8 slot`` + Firmware slot to commit the downloaded image -``NVME_RESERVATION_RTYPE_WE`` - *undescribed* +``enum nvme_fw_commit_ca action`` + Action to use for the firmware image, see :c:type:`enum nvme_fw_commit_ca ` -``NVME_RESERVATION_RTYPE_EA`` - *undescribed* +``bool bpid`` + Set to true to select the boot partition id -``NVME_RESERVATION_RTYPE_WERO`` - *undescribed* +**Description** -``NVME_RESERVATION_RTYPE_EARO`` - *undescribed* +The Firmware Commit command is used to modify the firmware image or Boot +Partitions. -``NVME_RESERVATION_RTYPE_WEAR`` - *undescribed* +**Return** -``NVME_RESERVATION_RTYPE_EAAR`` - *undescribed* +The nvme command status if a response was received or -1 with errno + set otherwise. The command status response may specify additional + reset actions required to complete the commit process. +.. c:function:: int nvme_security_send (int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, __u8 secp, __u32 tl, __u32 data_len, void * data, __u32 * result) -.. c:type:: enum nvme_reservation_racqa +**Parameters** +``int fd`` + File descriptor of nvme device -**Constants** +``__u32 nsid`` + Namespace ID to issue security command on -``NVME_RESERVATION_RACQA_ACQUIRE`` - *undescribed* +``__u8 nssf`` + NVMe Security Specific field -``NVME_RESERVATION_RACQA_PREEMPT`` - *undescribed* +``__u8 spsp0`` + Security Protocol Specific field -``NVME_RESERVATION_RACQA_PREEMPT_AND_ABORT`` - *undescribed* +``__u8 spsp1`` + Security Protocol Specific field +``__u8 secp`` + Security Protocol -.. c:function:: int nvme_resv_acquire (int fd, __u32 nsid, enum nvme_reservation_rtype rtype, enum nvme_reservation_racqa racqa, bool iekey, __u64 crkey, __u64 nrkey) +``__u32 tl`` + Protocol specific transfer length + +``__u32 data_len`` + Data length of the payload in bytes + +``void * data`` + Security data payload to send + +``__u32 * result`` + The command completion result from CQE dword0 + +**Description** + +The Security Send command is used to transfer security protocol data to the +controller. The data structure transferred to the controller as part of this +command contains security protocol specific commands to be performed by the +controller. The data structure transferred may also contain data or +parameters associated with the security protocol commands. + +The security data is protocol specific and is not defined by the NVMe +specification. + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_security_receive (int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, __u8 secp, __u32 al, __u32 data_len, void * data, __u32 * result) - Send an nvme reservation acquire **Parameters** @@ -4296,29 +4129,31 @@ The nvme command status if a response was received or -1 with errno File descriptor of nvme device ``__u32 nsid`` - Namespace identifier + Namespace ID to issue security command on -``enum nvme_reservation_rtype rtype`` - The type of reservation to be create, see :c:type:`enum nvme_reservation_rtype ` +``__u8 nssf`` + NVMe Security Specific field -``enum nvme_reservation_racqa racqa`` - The action that is performed by the command, see :c:type:`enum nvme_reservation_racqa ` +``__u8 spsp0`` + Security Protocol Specific field -``bool iekey`` - Set to ignore the existing key +``__u8 spsp1`` + Security Protocol Specific field -``__u64 crkey`` - The current reservation key associated with the host +``__u8 secp`` + Security Protocol -``__u64 nrkey`` - The reservation key to be unregistered from the namespace if - the action is preempt +``__u32 al`` + Protocol specific allocation length -**Description** +``__u32 data_len`` + Data length of the payload in bytes -The Reservation Acquire command is used to acquire a reservation on a -namespace, preempt a reservation held on a namespace, and abort a -reservation held on a namespace. +``void * data`` + Security data payload to send + +``__u32 * result`` + The command completion result from CQE dword0 **Return** @@ -4326,43 +4161,48 @@ The nvme command status if a response was received or -1 with errno set otherwise. +.. c:function:: int nvme_get_lba_status (int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl, enum nvme_lba_status_atype atype, struct nvme_lba_status * lbas) + Retrieve information on possibly unrecoverable LBAs -.. c:type:: enum nvme_reservation_rrega - - -**Constants** - -``NVME_RESERVATION_RREGA_REGISTER_KEY`` - *undescribed* +**Parameters** -``NVME_RESERVATION_RREGA_UNREGISTER_KEY`` - *undescribed* +``int fd`` + File descriptor of nvme device -``NVME_RESERVATION_RREGA_REPLACE_KEY`` - *undescribed* +``__u32 nsid`` + Namespace ID to retrieve LBA status +``__u64 slba`` + Starting logical block address to check statuses +``__u32 mndw`` + Maximum number of dwords to return +``__u16 rl`` + Range length from slba to perform the action -.. c:type:: enum nvme_reservation_cptpl +``enum nvme_lba_status_atype atype`` + Action type mechanism to determine LBA status desctriptors to + return, see :c:type:`enum nvme_lba_status_atype ` +``struct nvme_lba_status * lbas`` + Data payload to return status descriptors -**Constants** +**Description** -``NVME_RESERVATION_CPTPL_NO_CHANGE`` - *undescribed* +The Get LBA Status command requests information about Potentially +Unrecoverable LBAs. Refer to the specification for action type descriptions. -``NVME_RESERVATION_CPTPL_CLEAR`` - *undescribed* +**Return** -``NVME_RESERVATION_CPTPL_PERSIST`` - *undescribed* +The nvme command status if a response was received or -1 with errno + set otherwise. -.. c:function:: int nvme_resv_register (int fd, __u32 nsid, enum nvme_reservation_rrega rrega, enum nvme_reservation_cptpl cptpl, bool iekey, __u64 crkey, __u64 nrkey) +.. c:function:: int nvme_directive_send (int fd, __u32 nsid, __u16 dspec, enum nvme_directive_send_doper doper, enum nvme_directive_dtype dtype, __u32 cdw12, __u32 data_len, void * data, __u32 * result) - Send an nvme reservation register + Send directive command **Parameters** @@ -4370,28 +4210,36 @@ The nvme command status if a response was received or -1 with errno File descriptor of nvme device ``__u32 nsid`` - Namespace identifier + Namespace ID, if applicable -``enum nvme_reservation_rrega rrega`` - The registration action, see :c:type:`enum nvme_reservation_rrega ` +``__u16 dspec`` + Directive specific field -``enum nvme_reservation_cptpl cptpl`` - Change persist through power loss, see :c:type:`enum nvme_reservation_cptpl ` +``enum nvme_directive_send_doper doper`` + Directive send operation, see :c:type:`enum nvme_directive_send_doper ` -``bool iekey`` - Set to ignore the existing key +``enum nvme_directive_dtype dtype`` + Directive type, see :c:type:`enum nvme_directive_dtype ` -``__u64 crkey`` - The current reservation key associated with the host +``__u32 cdw12`` + *undescribed* -``__u64 nrkey`` - The new reservation key to be register if action is register or - replace +``__u32 data_len`` + Length of data payload in bytes + +``void * data`` + Usespace address of data payload + +``__u32 * result`` + If successful, the CQE dword0 value **Description** -The Reservation Register command is used to register, unregister, or replace -a reservation key. +Directives is a mechanism to enable host and NVM subsystem or controller +information exchange. The Directive Send command is used to transfer data +related to a specific Directive Type from the host to the controller. + +See the NVMe specification for more information. **Return** @@ -4399,23 +4247,34 @@ The nvme command status if a response was received or -1 with errno set otherwise. +.. c:function:: int nvme_directive_send_id_endir (int fd, __u32 nsid, bool endir, enum nvme_directive_dtype dtype, struct nvme_id_directives * id) -.. c:type:: enum nvme_reservation_rrela +**Parameters** +``int fd`` + File descriptor of nvme device -**Constants** +``__u32 nsid`` + Namespace ID -``NVME_RESERVATION_RRELA_RELEASE`` +``bool endir`` *undescribed* -``NVME_RESERVATION_RRELA_CLEAR`` +``enum nvme_directive_dtype dtype`` *undescribed* +``struct nvme_id_directives * id`` + *undescribed* -.. c:function:: int nvme_resv_release (int fd, __u32 nsid, enum nvme_reservation_rtype rtype, enum nvme_reservation_rrela rrela, bool iekey, __u64 crkey) +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_directive_send_stream_release_identifier (int fd, __u32 nsid, __u16 stream_id) - Send an nvme reservation release **Parameters** @@ -4423,19 +4282,10 @@ The nvme command status if a response was received or -1 with errno File descriptor of nvme device ``__u32 nsid`` - Namespace identifier - -``enum nvme_reservation_rtype rtype`` - The type of reservation to be create, see :c:type:`enum nvme_reservation_rtype ` - -``enum nvme_reservation_rrela rrela`` - Reservation releast action, see :c:type:`enum nvme_reservation_rrela ` - -``bool iekey`` - Set to ignore the existing key + Namespace ID -``__u64 crkey`` - The current reservation key to release +``__u16 stream_id`` + *undescribed* **Return** @@ -4443,9 +4293,8 @@ The nvme command status if a response was received or -1 with errno set otherwise. -.. c:function:: int nvme_resv_report (int fd, __u32 nsid, bool eds, __u32 len, struct nvme_reservation_status * report) +.. c:function:: int nvme_directive_send_stream_release_resource (int fd, __u32 nsid) - Send an nvme reservation report **Parameters** @@ -4453,22 +4302,7 @@ The nvme command status if a response was received or -1 with errno File descriptor of nvme device ``__u32 nsid`` - Namespace identifier - -``bool eds`` - Request extended Data Structure - -``__u32 len`` - Number of bytes to request transfered with this command - -``struct nvme_reservation_status * report`` - The user space destination address to store the reservation report - -**Description** - -Returns a Reservation Status data structure to memory that describes the -registration and reservation status of a namespace. See the defintion for -the returned structure, :c:type:`struct nvme_reservation_status `, for more details. + Namespace ID **Return** @@ -4476,929 +4310,1070 @@ The nvme command status if a response was received or -1 with errno set otherwise. +.. c:function:: int nvme_directive_recv (int fd, __u32 nsid, __u16 dspec, enum nvme_directive_receive_doper doper, enum nvme_directive_dtype dtype, __u32 cdw12, __u32 data_len, void * data, __u32 * result) + Receive directive specific data -.. c:type:: struct nvme_fabrics_config +**Parameters** +``int fd`` + File descriptor of nvme device -**Definition** +``__u32 nsid`` + Namespace ID, if applicable -:: +``__u16 dspec`` + Directive specific field - struct nvme_fabrics_config { - const char *transport; - const char *traddr; - const char *trsvcid; - const char *nqn; - const char *hostnqn; - const char *host_traddr; - const char *hostid; - int queue_size; - int nr_io_queues; - int reconnect_delay; - int ctrl_loss_tmo; - int keep_alive_tmo; - int nr_write_queues; - int nr_poll_queues; - int tos; - bool duplicate_connect; - bool disable_sqflow; - bool hdr_digest; - bool data_digest; - uint8_t rsvd[0x200]; - }; +``enum nvme_directive_receive_doper doper`` + Directive receive operation, see :c:type:`enum nvme_directive_receive_doper ` -**Members** +``enum nvme_directive_dtype dtype`` + Directive type, see :c:type:`enum nvme_directive_dtype ` +``__u32 cdw12`` + *undescribed* +``__u32 data_len`` + Length of data payload -.. c:function:: int nvmf_add_ctrl_opts (struct nvme_fabrics_config * cfg) +``void * data`` + Usespace address of data payload in bytes +``__u32 * result`` + If successful, the CQE dword0 value -**Parameters** +**Return** -``struct nvme_fabrics_config * cfg`` - *undescribed* +The nvme command status if a response was received or -1 with errno + set otherwise. -.. c:function:: nvme_ctrl_t nvmf_add_ctrl (struct nvme_fabrics_config * cfg) +.. c:function:: int nvme_directive_recv_identify_parameters (int fd, __u32 nsid, struct nvme_id_directives * id) **Parameters** -``struct nvme_fabrics_config * cfg`` - *undescribed* - - -.. c:function:: int nvmf_get_discovery_log (nvme_ctrl_t c, struct nvmf_discovery_log ** logp, int max_retries) - +``int fd`` + File descriptor of nvme device -**Parameters** +``__u32 nsid`` + Namespace ID -``nvme_ctrl_t c`` +``struct nvme_id_directives * id`` *undescribed* -``struct nvmf_discovery_log ** logp`` - *undescribed* +**Return** -``int max_retries`` - *undescribed* +The nvme command status if a response was received or -1 with errno + set otherwise. -.. c:function:: char * nvmf_hostnqn_generate () +.. c:function:: int nvme_directive_recv_stream_parameters (int fd, __u32 nsid, struct nvme_streams_directive_params * parms) **Parameters** +``int fd`` + File descriptor of nvme device -.. c:function:: char * nvmf_hostnqn_from_file () - +``__u32 nsid`` + Namespace ID -**Parameters** +``struct nvme_streams_directive_params * parms`` + *undescribed* +**Return** -.. c:function:: char * nvmf_hostid_from_file () +The nvme command status if a response was received or -1 with errno + set otherwise. -**Parameters** +.. c:function:: int nvme_directive_recv_stream_status (int fd, __u32 nsid, unsigned nr_entries, struct nvme_streams_directive_status * id) -.. c:function:: const char * nvmf_trtype_str (__u8 trtype) +**Parameters** +``int fd`` + File descriptor of nvme device -**Parameters** +``__u32 nsid`` + Namespace ID -``__u8 trtype`` +``unsigned nr_entries`` *undescribed* +``struct nvme_streams_directive_status * id`` + *undescribed* -.. c:function:: const char * nvmf_adrfam_str (__u8 adrfam) +**Return** +The nvme command status if a response was received or -1 with errno + set otherwise. -**Parameters** -``__u8 adrfam`` - *undescribed* +.. c:function:: int nvme_directive_recv_stream_allocate (int fd, __u32 nsid, __u16 nsr, __u32 * result) -.. c:function:: const char * nvmf_subtype_str (__u8 subtype) +**Parameters** +``int fd`` + File descriptor of nvme device -**Parameters** +``__u32 nsid`` + Namespace ID -``__u8 subtype`` +``__u16 nsr`` *undescribed* +``__u32 * result`` + *undescribed* -.. c:function:: const char * nvmf_treq_str (__u8 treq) +**Return** +The nvme command status if a response was received or -1 with errno + set otherwise. -**Parameters** -``__u8 treq`` - *undescribed* -.. c:function:: const char * nvmf_sectype_str (__u8 sectype) +.. c:type:: enum nvme_fctype -**Parameters** +**Constants** -``__u8 sectype`` +``nvme_fabrics_type_property_set`` *undescribed* +``nvme_fabrics_type_connect`` + *undescribed* -.. c:function:: const char * nvmf_prtype_str (__u8 prtype) +``nvme_fabrics_type_property_get`` + *undescribed* +``nvme_fabrics_type_auth_send`` + *undescribed* -**Parameters** +``nvme_fabrics_type_auth_receive`` + *undescribed* -``__u8 prtype`` +``nvme_fabrics_type_disconnect`` *undescribed* -.. c:function:: const char * nvmf_qptype_str (__u8 qptype) +.. c:function:: int nvme_set_property (int fd, int offset, __u64 value) + Set controller property **Parameters** -``__u8 qptype`` - *undescribed* +``int fd`` + File descriptor of nvme device +``int offset`` + Property offset from the base to set -.. c:function:: const char * nvmf_cms_str (__u8 cm) +``__u64 value`` + The value to set the property +**Description** -**Parameters** +This is an NVMe-over-Fabrics specific command, not applicable to PCIe. These +properties align to the PCI MMIO controller registers. -``__u8 cm`` - *undescribed* +**Return** +The nvme command status if a response was received or -1 with errno + set otherwise. -.. c:function:: nvme_ctrl_t nvmf_connect_disc_entry (struct nvmf_disc_log_entry * e, const struct nvme_fabrics_config * defcfg, bool * discover) +.. c:function:: int nvme_get_property (int fd, int offset, __u64 * value) -**Parameters** + Get a controller property -``struct nvmf_disc_log_entry * e`` - *undescribed* +**Parameters** -``const struct nvme_fabrics_config * defcfg`` - *undescribed* +``int fd`` + File descriptor of nvme device -``bool * discover`` - *undescribed* +``int offset`` + Property offset from the base to retrieve +``__u64 * value`` + Where the property's value will be stored on success -.. c:function:: int nvme_namespace_filter (const struct dirent * d) +**Description** +This is an NVMe-over-Fabrics specific command, not applicable to PCIe. These +properties align to the PCI MMIO controller registers. -**Parameters** +**Return** -``const struct dirent * d`` - *undescribed* +The nvme command status if a response was received or -1 with errno + set otherwise. -.. c:function:: int nvme_paths_filter (const struct dirent * d) +.. c:function:: int nvme_sanitize_nvm (int fd, enum nvme_sanitize_sanact sanact, bool ause, __u8 owpass, bool oipbp, bool nodas, __u32 ovrpat) + Start a sanitize operation **Parameters** -``const struct dirent * d`` - *undescribed* +``int fd`` + File descriptor of nvme device +``enum nvme_sanitize_sanact sanact`` + Sanitize action, see :c:type:`enum nvme_sanitize_sanact ` -.. c:function:: int nvme_ctrls_filter (const struct dirent * d) +``bool ause`` + Set to allow unrestriced sanitize exit + +``__u8 owpass`` + Overwrite pass count +``bool oipbp`` + Set to overwrite invert pattern between passes -**Parameters** +``bool nodas`` + Set to not deallocate blocks after sanitizing -``const struct dirent * d`` - *undescribed* +``__u32 ovrpat`` + Overwrite pattern +**Description** -.. c:function:: int nvme_subsys_filter (const struct dirent * d) +A sanitize operation alters all user data in the NVM subsystem such that +recovery of any previous user data from any cache, the non-volatile media, +or any Controller Memory Buffer is not possible. +The Sanitize command is used to start a sanitize operation or to recover +from a previously failed sanitize operation. The sanitize operation types +that may be supported are Block Erase, Crypto Erase, and Overwrite. All +sanitize operations are processed in the background, i.e., completion of the +sanitize command does not indicate completion of the sanitize operation. -**Parameters** +**Return** -``const struct dirent * d`` - *undescribed* +The nvme command status if a response was received or -1 with errno + set otherwise. -.. c:function:: int nvme_scan_subsystems (struct dirent *** subsys) +.. c:function:: int nvme_dev_self_test (int fd, __u32 nsid, enum nvme_dst_stc stc) + Start or abort a self test **Parameters** -``struct dirent *** subsys`` - *undescribed* +``int fd`` + File descriptor of nvme device +``__u32 nsid`` + Namespace ID to test -.. c:function:: int nvme_scan_subsystem_ctrls (nvme_subsystem_t s, struct dirent *** ctrls) +``enum nvme_dst_stc stc`` + Self test code, see :c:type:`enum nvme_dst_stc ` +**Description** -**Parameters** +The Device Self-test command is used to start a device self-test operation +or abort a device self-test operation. A device self-test operation is a +diagnostic testing sequence that tests the integrity and functionality of +the controller and may include testing of the media associated with +namespaces. The controller may return a response to this command immediately +while running the self-test in the background. -``nvme_subsystem_t s`` - *undescribed* +Set the 'nsid' field to 0 to not include namepsaces in the test. Set to +0xffffffff to test all namespaces. All other values tests a specific +namespace, if present. -``struct dirent *** ctrls`` - *undescribed* +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. -.. c:function:: int nvme_scan_subsystem_namespaces (nvme_subsystem_t s, struct dirent *** namespaces) +.. c:function:: int nvme_virtual_mgmt (int fd, enum nvme_virt_mgmt_act act, enum nvme_virt_mgmt_rt rt, __u16 cntlid, __u16 nr, __u32 * result) + Virtualization resource management **Parameters** -``nvme_subsystem_t s`` - *undescribed* - -``struct dirent *** namespaces`` - *undescribed* +``int fd`` + File descriptor of nvme device +``enum nvme_virt_mgmt_act act`` + Virtual resource action, see :c:type:`enum nvme_virt_mgmt_act ` -.. c:function:: int nvme_scan_ctrl_namespace_paths (nvme_ctrl_t c, struct dirent *** namespaces) +``enum nvme_virt_mgmt_rt rt`` + Resource type to modify, see :c:type:`enum nvme_virt_mgmt_rt ` +``__u16 cntlid`` + Controller id for which resources are bing modified -**Parameters** +``__u16 nr`` + Number of resources being allocated or assigned -``nvme_ctrl_t c`` - *undescribed* +``__u32 * result`` + If successful, the CQE dword0 -``struct dirent *** namespaces`` - *undescribed* +**Description** +The Virtualization Management command is supported by primary controllers +that support the Virtualization Enhancements capability. This command is +used for several functions: -.. c:function:: int nvme_scan_ctrl_namespaces (nvme_ctrl_t c, struct dirent *** namespaces) + - Modifying Flexible Resource allocation for the primary controller + - Assigning Flexible Resources for secondary controllers + - Setting the Online and Offline state for secondary controllers +**Return** -**Parameters** +The nvme command status if a response was received or -1 + with errno set otherwise. -``nvme_ctrl_t c`` - *undescribed* -``struct dirent *** namespaces`` - *undescribed* +**NVMe IO command** -.. c:type:: struct nvme_passthru_cmd +.. c:type:: enum nvme_io_opcode -**Definition** +**Constants** -:: +``nvme_cmd_flush`` + *undescribed* - struct nvme_passthru_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 result; - }; +``nvme_cmd_write`` + *undescribed* -**Members** +``nvme_cmd_read`` + *undescribed* -``opcode`` - Operation code, see :c:type:`enum nvme_io_opcodes ` and :c:type:`enum nvme_admin_opcodes ` +``nvme_cmd_write_uncor`` + *undescribed* -``flags`` - Not supported: intended for command flags (eg: SGL, FUSE) +``nvme_cmd_compare`` + *undescribed* -``rsvd1`` - Reserved for future use +``nvme_cmd_write_zeroes`` + *undescribed* -``nsid`` - Namespace Identifier, or Fabrics type +``nvme_cmd_dsm`` + *undescribed* -``cdw2`` - Command Dword 2 (no spec defined use) +``nvme_cmd_verify`` + *undescribed* -``cdw3`` - Command Dword 3 (no spec defined use) +``nvme_cmd_resv_register`` + *undescribed* -``metadata`` - User space address to metadata buffer (NULL if not used) +``nvme_cmd_resv_report`` + *undescribed* -``addr`` - User space address to data buffer (NULL if not used) +``nvme_cmd_resv_acquire`` + *undescribed* -``metadata_len`` - Metadata buffer transfer length +``nvme_cmd_resv_release`` + *undescribed* -``data_len`` - Data buffer transfer length -``cdw10`` - Command Dword 10 (command specific) +.. c:function:: int nvme_flush (int fd, __u32 nsid) -``cdw11`` - Command Dword 11 (command specific) + Send an nvme flush command -``cdw12`` - Command Dword 12 (command specific) +**Parameters** -``cdw13`` - Command Dword 13 (command specific) +``int fd`` + File descriptor of nvme device -``cdw14`` - Command Dword 14 (command specific) +``__u32 nsid`` + Namespace identifier -``cdw15`` - Command Dword 15 (command specific) +**Description** -``timeout_ms`` - If non-zero, overrides system default timeout in milliseconds +The Flush command is used to request that the contents of volatile write +cache be made non-volatile. -``result`` - Set on completion to the command's CQE DWORD 0 controller response +**Return** +The nvme command status if a response was received or -1 with errno + set otherwise. -.. c:type:: struct nvme_passthru_cmd64 +.. c:type:: enum nvme_io_control_flags -**Definition** +**Constants** -:: +``NVME_IO_DTYPE_STREAMS`` + *undescribed* - 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; - }; +``NVME_IO_DEAC`` + *undescribed* -**Members** +``NVME_IO_PRINFO_PRCHK_REF`` + *undescribed* -``opcode`` - Operation code, see :c:type:`enum nvme_io_opcodes ` and :c:type:`enum nvme_admin_opcodes ` +``NVME_IO_PRINFO_PRCHK_APP`` + *undescribed* -``flags`` - Not supported: intended for command flags (eg: SGL, FUSE) +``NVME_IO_PRINFO_PRCHK_GUARD`` + *undescribed* -``rsvd1`` - Reserved for future use +``NVME_IO_PRINFO_PRACT`` + *undescribed* -``nsid`` - Namespace Identifier, or Fabrics type +``NVME_IO_FUA`` + *undescribed* -``cdw2`` - Command Dword 2 (no spec defined use) +``NVME_IO_LR`` + *undescribed* -``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 +.. c:type:: enum nvme_io_dsm_flags -``data_len`` - Data buffer transfer length -``cdw10`` - Command Dword 10 (command specific) +**Constants** -``cdw11`` - Command Dword 11 (command specific) +``NVME_IO_DSM_FREQ_UNSPEC`` + *undescribed* -``cdw12`` - Command Dword 12 (command specific) +``NVME_IO_DSM_FREQ_TYPICAL`` + *undescribed* -``cdw13`` - Command Dword 13 (command specific) +``NVME_IO_DSM_FREQ_RARE`` + *undescribed* -``cdw14`` - Command Dword 14 (command specific) +``NVME_IO_DSM_FREQ_READS`` + *undescribed* -``cdw15`` - Command Dword 15 (command specific) +``NVME_IO_DSM_FREQ_WRITES`` + *undescribed* -``timeout_ms`` - If non-zero, overrides system default timeout in milliseconds +``NVME_IO_DSM_FREQ_RW`` + *undescribed* -``rsvd2`` - Reserved for future use (and fills an impicit struct pad +``NVME_IO_DSM_FREQ_ONCE`` + *undescribed* -``result`` - Set on completion to the command's CQE DWORD 0-1 controller response +``NVME_IO_DSM_FREQ_PREFETCH`` + *undescribed* +``NVME_IO_DSM_FREQ_TEMP`` + *undescribed* +``NVME_IO_DSM_LATENCY_NONE`` + *undescribed* -.. c:function:: int nvme_submit_admin_passthru64 (int fd, struct nvme_passthru_cmd64 * cmd, __u64 * result) +``NVME_IO_DSM_LATENCY_IDLE`` + *undescribed* - Submit a 64-bit nvme passthrough admin command +``NVME_IO_DSM_LATENCY_NORM`` + *undescribed* + +``NVME_IO_DSM_LATENCY_LOW`` + *undescribed* + +``NVME_IO_DSM_SEQ_REQ`` + *undescribed* + +``NVME_IO_DSM_COMPRESSED`` + *undescribed* + + +.. c:function:: int nvme_read (int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u8 dsm, __u32 reftag, __u16 apptag, __u16 appmask, __u32 data_len, void * data, __u32 metadata_len, void * metadata) + + Submit an nvme user read command **Parameters** ``int fd`` File descriptor of nvme device -``struct nvme_passthru_cmd64 * cmd`` - The nvme admin command to send +``__u32 nsid`` + Namespace ID -``__u64 * result`` - Optional field to return the result from the CQE DW0-1 +``__u64 slba`` + Starting logical block -**Description** +``__u16 nlb`` + *undescribed* + +``__u16 control`` + Command control flags, see :c:type:`enum nvme_io_control_flags `. + +``__u8 dsm`` + Data set management attributes, see :c:type:`enum nvme_io_dsm_flags ` + +``__u32 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. + +``__u16 apptag`` + This field specifies the Application Tag Mask expected value. + Used only if the namespace is formatted to use end-to-end + protection information. + +``__u16 appmask`` + This field specifies the Application Tag expected value. Used + only if the namespace is formatted to use end-to-end protection + information. + +``__u32 data_len`` + Length of user buffer, **data**, in bytes + +``void * data`` + Pointer to user address of the data buffer + metadata_len:Length of user buffer, **metadata**, in bytes + +``__u32 metadata_len`` + *undescribed* + +``void * metadata`` + Pointer to user address of the metadata buffer + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_write (int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u8 dsm, __u16 dspec, __u32 reftag, __u16 apptag, __u16 appmask, __u32 data_len, void * data, __u32 metadata_len, void * metadata) + + Submit an nvme user write command + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace ID + +``__u64 slba`` + Starting logical block + +``__u16 nlb`` + *undescribed* + +``__u16 control`` + Command control flags, see :c:type:`enum nvme_io_control_flags `. + +``__u8 dsm`` + Data set management attributes, see :c:type:`enum nvme_io_dsm_flags ` + +``__u16 dspec`` + Directive specific command, eg: stream identifier + +``__u32 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. + +``__u16 apptag`` + This field specifies the Application Tag Mask expected value. + Used only if the namespace is formatted to use end-to-end + protection information. + +``__u16 appmask`` + This field specifies the Application Tag expected value. Used + only if the namespace is formatted to use end-to-end protection + information. + +``__u32 data_len`` + Length of user buffer, **data**, in bytes + +``void * data`` + Pointer to user address of the data buffer + metadata_len:Length of user buffer, **metadata**, in bytes + +``__u32 metadata_len`` + *undescribed* + +``void * metadata`` + Pointer to user address of the metadata buffer + +**Return** + +The nvme command status if a response was received or -1 with errno + set otherwise. + + +.. c:function:: int nvme_compare (int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 reftag, __u16 apptag, __u16 appmask, __u32 data_len, void * data, __u32 metadata_len, void * metadata) + + Submit an nvme user compare command + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace ID + +``__u64 slba`` + Starting logical block + +``__u16 nlb`` + *undescribed* + +``__u16 control`` + Command control flags, see :c:type:`enum nvme_io_control_flags `. + +``__u32 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. + +``__u16 apptag`` + This field specifies the Application Tag Mask expected value. + Used only if the namespace is formatted to use end-to-end + protection information. + +``__u16 appmask`` + This field specifies the Application Tag expected value. Used + only if the namespace is formatted to use end-to-end protection + information. + +``__u32 data_len`` + Length of user buffer, **data**, in bytes + +``void * data`` + Pointer to user address of the data buffer + metadata_len:Length of user buffer, **metadata**, in bytes + +``__u32 metadata_len`` + *undescribed* -Uses NVME_IOCTL_ADMIN64_CMD for the ioctl request. +``void * metadata`` + Pointer to user address of the metadata buffer **Return** -The nvme command status if a response was received or -1 - with errno set otherwise. +The nvme command status if a response was received or -1 with errno + set otherwise. -.. c:function:: int nvme_admin_passthru64 (int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, __u32 data_len, void * data, __u32 metadata_len, void * metadata, __u32 timeout_ms, __u64 * result) +.. c:function:: int nvme_write_zeros (int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 reftag, __u16 apptag, __u16 appmask) - Submit an nvme passthrough command + Submit an nvme write zeroes command **Parameters** ``int fd`` File descriptor of nvme device -``__u8 opcode`` - The nvme io command to send - -``__u8 flags`` - NVMe command flags (not used) - -``__u16 rsvd`` - Reserevd for future use - ``__u32 nsid`` Namespace identifier -``__u32 cdw2`` - Command dword 2 - -``__u32 cdw3`` - Command dword 3 - -``__u32 cdw10`` - Command dword 10 - -``__u32 cdw11`` - Command dword 11 - -``__u32 cdw12`` - Command dword 12 - -``__u32 cdw13`` - Command dword 13 - -``__u32 cdw14`` - Command dword 14 - -``__u32 cdw15`` - Command dword 15 - -``__u32 data_len`` - Length of the data transfered in this command in bytes +``__u64 slba`` + Starting logical block -``void * data`` - Pointer to user address of the data buffer +``__u16 nlb`` + Number of logical blocks to clear (0's based value) -``__u32 metadata_len`` - Length of metadata transfered in this command +``__u16 control`` + Command control flags, see :c:type:`enum nvme_io_control_flags `. -``void * metadata`` - Pointer to user address of the metadata buffer +``__u32 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. -``__u32 timeout_ms`` - How long the kernel waits for the command to complete +``__u16 apptag`` + This field specifies the Application Tag Mask expected value. + Used only if the namespace is formatted to use end-to-end + protection information. -``__u64 * result`` - Optional field to return the result from the CQE dword 0 +``__u16 appmask`` + This field specifies the Application Tag expected value. Used + only if the namespace is formatted to use end-to-end protection + information. **Description** -Parameterized form of nvme_submit_admin_passthru64(). This sets up and -submits a :c:type:`struct nvme_passthru_cmd64 `. - -Known values for **opcode** are defined in :c:type:`enum nvme_admin_opcode `. +The Write Zeroes command is used to set a range of logical blocks to zero. +After successful completion of this command, the value returned by +subsequent reads of logical blocks in this range shall be all bytes cleared +to 0h until a write occurs to this LBA range. **Return** -The nvme command status if a response was received or -1 - with errno set otherwise. +The nvme command status if a response was received or -1 with errno + set otherwise. -.. c:function:: int nvme_submit_admin_passthru (int fd, struct nvme_passthru_cmd * cmd, __u32 * result) +.. c:function:: int nvme_write_uncorrectable (int fd, __u32 nsid, __u64 slba, __u16 nlb) - Submit an nvme passthrough admin command + Submit an nvme write uncorrectable command **Parameters** ``int fd`` File descriptor of nvme device -``struct nvme_passthru_cmd * cmd`` - The nvme admin command to send +``__u32 nsid`` + Namespace identifier -``__u32 * result`` - Optional field to return the result from the CQE DW0 +``__u64 slba`` + Starting logical block + +``__u16 nlb`` + Number of logical blocks to invalidate (0's based value) **Description** -Uses NVME_IOCTL_ADMIN_CMD for the ioctl request. +The Write Uncorrectable command is used to mark a range of logical blocks as +invalid. When the specified logical block(s) are read after this operation, +a failure is returned with Unrecovered Read Error status. To clear the +invalid logical block status, a write operation on those logical blocks is +required. **Return** -The nvme command status if a response was received or -1 - with errno set otherwise. +The nvme command status if a response was received or -1 with errno + set otherwise. -.. c:function:: int nvme_admin_passthru (int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, __u32 data_len, void * data, __u32 metadata_len, void * metadata, __u32 timeout_ms, __u32 * result) +.. c:function:: int nvme_verify (int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 reftag, __u16 apptag, __u16 appmask) - Submit an nvme passthrough command + Send an nvme verify command **Parameters** ``int fd`` File descriptor of nvme device -``__u8 opcode`` - The nvme io command to send - -``__u8 flags`` - NVMe command flags (not used) - -``__u16 rsvd`` - Reserevd for future use - ``__u32 nsid`` Namespace identifier -``__u32 cdw2`` - Command dword 2 +``__u64 slba`` + Starting logical block -``__u32 cdw3`` - Command dword 3 +``__u16 nlb`` + Number of logical blocks to verify (0's based value) -``__u32 cdw10`` - Command dword 10 +``__u16 control`` + Command control flags, see :c:type:`enum nvme_io_control_flags `. -``__u32 cdw11`` - Command dword 11 +``__u32 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. -``__u32 cdw12`` - Command dword 12 +``__u16 apptag`` + This field specifies the Application Tag Mask expected value. + Used only if the namespace is formatted to use end-to-end + protection information. -``__u32 cdw13`` - Command dword 13 +``__u16 appmask`` + This field specifies the Application Tag expected value. Used + only if the namespace is formatted to use end-to-end protection + information. -``__u32 cdw14`` - Command dword 14 +**Description** -``__u32 cdw15`` - Command dword 15 +The Verify command verifies integrity of stored information by reading data +and metadata, if applicable, for the LBAs indicated without transferring any +data or metadata to the host. -``__u32 data_len`` - Length of the data transfered in this command in bytes +**Return** -``void * data`` - Pointer to user address of the data buffer +The nvme command status if a response was received or -1 with errno + set otherwise. -``__u32 metadata_len`` - Length of metadata transfered in this command -``void * metadata`` - Pointer to user address of the metadata buffer -``__u32 timeout_ms`` - How long the kernel waits for the command to complete -``__u32 * result`` - Optional field to return the result from the CQE dword 0 +.. c:type:: enum nvme_dsm_attributes -**Description** -Parameterized form of nvme_submit_admin_passthru(). This sets up and -submits a :c:type:`struct nvme_passthru_cmd `. +**Constants** -Known values for **opcode** are defined in :c:type:`enum nvme_admin_opcode `. +``NVME_DSMGMT_IDR`` + *undescribed* -**Return** +``NVME_DSMGMT_IDW`` + *undescribed* -The nvme command status if a response was received or -1 - with errno set otherwise. +``NVME_DSMGMT_AD`` + *undescribed* -.. c:function:: int nvme_submit_io_passthru64 (int fd, struct nvme_passthru_cmd64 * cmd, __u64 * result) +.. c:function:: int nvme_dsm (int fd, __u32 nsid, __u32 attrs, __u16 nr_ranges, struct nvme_dsm_range * dsm) - Submit a 64-bit nvme passthrough command + Send an nvme data set management command **Parameters** ``int fd`` File descriptor of nvme device -``struct nvme_passthru_cmd64 * cmd`` - The nvme io command to send - -``__u64 * result`` - Optional field to return the result from the CQE DW0-1 - -**Description** - -Uses NVME_IOCTL_IO64_CMD for the ioctl request. - -**Return** - -The nvme command status if a response was received or -1 - with errno set otherwise. +``__u32 nsid`` + Namespace identifier +``__u32 attrs`` + DSM attributes, see :c:type:`enum nvme_dsm_attributes ` + :c:type:`nr_ranges`: Number of block ranges in the data set management attributes -.. c:function:: int nvme_io_passthru64 (int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, __u32 data_len, void * data, __u32 metadata_len, void * metadata, __u32 timeout_ms, __u64 * result) +``__u16 nr_ranges`` + *undescribed* - Submit an nvme io passthrough command +``struct nvme_dsm_range * dsm`` + The data set management attributes -**Parameters** +**Description** -``int fd`` - File descriptor of nvme device +The Dataset Management command is used by the host to indicate attributes +for ranges of logical blocks. This includes attributes like frequency that +data is read or written, access size, and other information that may be used +to optimize performance and reliability, and may be used to +deallocate/unmap/trim those logical blocks. -``__u8 opcode`` - The nvme io command to send +**Return** -``__u8 flags`` - NVMe command flags (not used) +The nvme command status if a response was received or -1 with errno + set otherwise. -``__u16 rsvd`` - Reserevd for future use -``__u32 nsid`` - Namespace identifier -``__u32 cdw2`` - Command dword 2 -``__u32 cdw3`` - Command dword 3 +.. c:type:: enum nvme_reservation_rtype -``__u32 cdw10`` - Command dword 10 -``__u32 cdw11`` - Command dword 11 +**Constants** -``__u32 cdw12`` - Command dword 12 +``NVME_RESERVATION_RTYPE_WE`` + *undescribed* -``__u32 cdw13`` - Command dword 13 +``NVME_RESERVATION_RTYPE_EA`` + *undescribed* -``__u32 cdw14`` - Command dword 14 +``NVME_RESERVATION_RTYPE_WERO`` + *undescribed* -``__u32 cdw15`` - Command dword 15 +``NVME_RESERVATION_RTYPE_EARO`` + *undescribed* -``__u32 data_len`` - Length of the data transfered in this command in bytes +``NVME_RESERVATION_RTYPE_WEAR`` + *undescribed* -``void * data`` - Pointer to user address of the data buffer +``NVME_RESERVATION_RTYPE_EAAR`` + *undescribed* -``__u32 metadata_len`` - Length of metadata transfered in this command -``void * metadata`` - Pointer to user address of the metadata buffer -``__u32 timeout_ms`` - How long the kernel waits for the command to complete -``__u64 * result`` - Optional field to return the result from the CQE dword 0 +.. c:type:: enum nvme_reservation_racqa -**Description** -Parameterized form of nvme_submit_io_passthru64(). This sets up and submits -a :c:type:`struct nvme_passthru_cmd64 `. +**Constants** -Known values for **opcode** are defined in :c:type:`enum nvme_io_opcode `. +``NVME_RESERVATION_RACQA_ACQUIRE`` + *undescribed* -**Return** +``NVME_RESERVATION_RACQA_PREEMPT`` + *undescribed* -The nvme command status if a response was received or -1 with errno - set otherwise. +``NVME_RESERVATION_RACQA_PREEMPT_AND_ABORT`` + *undescribed* -.. c:function:: int nvme_submit_io_passthru (int fd, struct nvme_passthru_cmd * cmd, __u32 * result) +.. c:function:: int nvme_resv_acquire (int fd, __u32 nsid, enum nvme_reservation_rtype rtype, enum nvme_reservation_racqa racqa, bool iekey, __u64 crkey, __u64 nrkey) - Submit an nvme passthrough command + Send an nvme reservation acquire **Parameters** ``int fd`` File descriptor of nvme device -``struct nvme_passthru_cmd * cmd`` - The nvme io command to send +``__u32 nsid`` + Namespace identifier -``__u32 * result`` - Optional field to return the result from the CQE DW0 +``enum nvme_reservation_rtype rtype`` + The type of reservation to be create, see :c:type:`enum nvme_reservation_rtype ` -**Description** +``enum nvme_reservation_racqa racqa`` + The action that is performed by the command, see :c:type:`enum nvme_reservation_racqa ` -Uses NVME_IOCTL_IO_CMD for the ioctl request. +``bool iekey`` + Set to ignore the existing key -**Return** +``__u64 crkey`` + The current reservation key associated with the host -The nvme command status if a response was received or -1 - with errno set otherwise. +``__u64 nrkey`` + The reservation key to be unregistered from the namespace if + the action is preempt +**Description** -.. c:function:: int nvme_io_passthru (int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, __u32 data_len, void * data, __u32 metadata_len, void * metadata, __u32 timeout_ms, __u32 * result) +The Reservation Acquire command is used to acquire a reservation on a +namespace, preempt a reservation held on a namespace, and abort a +reservation held on a namespace. - Submit an nvme io passthrough command +**Return** -**Parameters** +The nvme command status if a response was received or -1 with errno + set otherwise. -``int fd`` - File descriptor of nvme device -``__u8 opcode`` - The nvme io command to send -``__u8 flags`` - NVMe command flags (not used) -``__u16 rsvd`` - Reserevd for future use +.. c:type:: enum nvme_reservation_rrega -``__u32 nsid`` - Namespace identifier -``__u32 cdw2`` - Command dword 2 +**Constants** -``__u32 cdw3`` - Command dword 3 +``NVME_RESERVATION_RREGA_REGISTER_KEY`` + *undescribed* -``__u32 cdw10`` - Command dword 10 +``NVME_RESERVATION_RREGA_UNREGISTER_KEY`` + *undescribed* -``__u32 cdw11`` - Command dword 11 +``NVME_RESERVATION_RREGA_REPLACE_KEY`` + *undescribed* -``__u32 cdw12`` - Command dword 12 -``__u32 cdw13`` - Command dword 13 -``__u32 cdw14`` - Command dword 14 -``__u32 cdw15`` - Command dword 15 +.. c:type:: enum nvme_reservation_cptpl -``__u32 data_len`` - Length of the data transfered in this command in bytes -``void * data`` - Pointer to user address of the data buffer +**Constants** -``__u32 metadata_len`` - Length of metadata transfered in this command +``NVME_RESERVATION_CPTPL_NO_CHANGE`` + *undescribed* -``void * metadata`` - Pointer to user address of the metadata buffer +``NVME_RESERVATION_CPTPL_CLEAR`` + *undescribed* -``__u32 timeout_ms`` - How long the kernel waits for the command to complete +``NVME_RESERVATION_CPTPL_PERSIST`` + *undescribed* -``__u32 * result`` - Optional field to return the result from the CQE dword 0 -**Description** +.. c:function:: int nvme_resv_register (int fd, __u32 nsid, enum nvme_reservation_rrega rrega, enum nvme_reservation_cptpl cptpl, bool iekey, __u64 crkey, __u64 nrkey) -Parameterized form of nvme_submit_io_passthru(). This sets up and submits -a :c:type:`struct nvme_passthru_cmd `. + Send an nvme reservation register -Known values for **opcode** are defined in :c:type:`enum nvme_io_opcode `. +**Parameters** -**Return** +``int fd`` + File descriptor of nvme device -The nvme command status if a response was received or -1 - with errno set otherwise. +``__u32 nsid`` + Namespace identifier +``enum nvme_reservation_rrega rrega`` + The registration action, see :c:type:`enum nvme_reservation_rrega ` -.. c:function:: int nvme_subsystem_reset (int fd) +``enum nvme_reservation_cptpl cptpl`` + Change persist through power loss, see :c:type:`enum nvme_reservation_cptpl ` - Initiate a subsystem reset +``bool iekey`` + Set to ignore the existing key -**Parameters** +``__u64 crkey`` + The current reservation key associated with the host -``int fd`` - File descriptor of nvme device +``__u64 nrkey`` + The new reservation key to be register if action is register or + replace **Description** -This should only be sent to controller handles, not to namespaces. +The Reservation Register command is used to register, unregister, or replace +a reservation key. **Return** -Zero if a subsystem reset was initiated or -1 with errno set - otherwise. - +The nvme command status if a response was received or -1 with errno + set otherwise. -.. c:function:: int nvme_ctrl_reset (int fd) - Initiate a controller reset -**Parameters** -``int fd`` - File descriptor of nvme device +.. c:type:: enum nvme_reservation_rrela -**Description** -This should only be sent to controller handles, not to namespaces. +**Constants** -**Return** +``NVME_RESERVATION_RRELA_RELEASE`` + *undescribed* -Zero if a reset was initiated or -1 with errno set otherwise. +``NVME_RESERVATION_RRELA_CLEAR`` + *undescribed* -.. c:function:: int nvme_ns_rescan (int fd) +.. c:function:: int nvme_resv_release (int fd, __u32 nsid, enum nvme_reservation_rtype rtype, enum nvme_reservation_rrela rrela, bool iekey, __u64 crkey) - Initiate a controller rescan + Send an nvme reservation release **Parameters** ``int fd`` File descriptor of nvme device -**Description** +``__u32 nsid`` + Namespace identifier -This should only be sent to controller handles, not to namespaces. +``enum nvme_reservation_rtype rtype`` + The type of reservation to be create, see :c:type:`enum nvme_reservation_rtype ` + +``enum nvme_reservation_rrela rrela`` + Reservation releast action, see :c:type:`enum nvme_reservation_rrela ` + +``bool iekey`` + Set to ignore the existing key + +``__u64 crkey`` + The current reservation key to release **Return** -Zero if a rescan was initiated or -1 with errno set otherwise. +The nvme command status if a response was received or -1 with errno + set otherwise. -.. c:function:: int nvme_get_nsid (int fd) +.. c:function:: int nvme_resv_report (int fd, __u32 nsid, bool eds, __u32 len, struct nvme_reservation_status * report) - Retrieve the NSID from a namespace file descriptor + Send an nvme reservation report **Parameters** ``int fd`` - File descriptor of nvme namespace + File descriptor of nvme device + +``__u32 nsid`` + Namespace identifier + +``bool eds`` + Request extended Data Structure + +``__u32 len`` + Number of bytes to request transfered with this command + +``struct nvme_reservation_status * report`` + The user space destination address to store the reservation report **Description** -This should only be sent to namespace handles, not to controllers. +Returns a Reservation Status data structure to memory that describes the +registration and reservation status of a namespace. See the defintion for +the returned structure, :c:type:`struct nvme_reservation_status `, for more details. **Return** -The namespace identifier if a succecssful or -1 with errno set - otherwise. +The nvme command status if a response was received or -1 with errno + set otherwise. .. c:function:: nvme_subsystem_t nvme_first_subsystem (nvme_root_t r) @@ -5407,7 +5382,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_root_t r`` - *undescribed* .. c:function:: nvme_subsystem_t nvme_next_subsystem (nvme_root_t r, nvme_subsystem_t s) @@ -5419,7 +5393,6 @@ The namespace identifier if a succecssful or -1 with errno set *undescribed* ``nvme_subsystem_t s`` - *undescribed* .. c:function:: nvme_ns_t nvme_ctrl_first_ns (nvme_ctrl_t c) @@ -5428,7 +5401,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_ctrl_t c`` - *undescribed* .. c:function:: nvme_ns_t nvme_ctrl_next_ns (nvme_ctrl_t c, nvme_ns_t n) @@ -5440,7 +5412,6 @@ The namespace identifier if a succecssful or -1 with errno set *undescribed* ``nvme_ns_t n`` - *undescribed* .. c:function:: nvme_path_t nvme_ctrl_first_path (nvme_ctrl_t c) @@ -5449,7 +5420,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_ctrl_t c`` - *undescribed* .. c:function:: nvme_path_t nvme_ctrl_next_path (nvme_ctrl_t c, nvme_path_t p) @@ -5461,7 +5431,6 @@ The namespace identifier if a succecssful or -1 with errno set *undescribed* ``nvme_path_t p`` - *undescribed* .. c:function:: nvme_ctrl_t nvme_subsystem_first_ctrl (nvme_subsystem_t s) @@ -5470,7 +5439,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_subsystem_t s`` - *undescribed* .. c:function:: nvme_ctrl_t nvme_subsystem_next_ctrl (nvme_subsystem_t s, nvme_ctrl_t c) @@ -5482,7 +5450,6 @@ The namespace identifier if a succecssful or -1 with errno set *undescribed* ``nvme_ctrl_t c`` - *undescribed* .. c:function:: nvme_ns_t nvme_subsystem_first_ns (nvme_subsystem_t s) @@ -5491,7 +5458,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_subsystem_t s`` - *undescribed* .. c:function:: nvme_ns_t nvme_subsystem_next_ns (nvme_subsystem_t s, nvme_ns_t n) @@ -5503,7 +5469,6 @@ The namespace identifier if a succecssful or -1 with errno set *undescribed* ``nvme_ns_t n`` - *undescribed* .. c:function:: nvme_for_each_subsystem_safe ( r, s, _s) @@ -5647,7 +5612,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_ns_t n`` - *undescribed* .. c:function:: int nvme_ns_get_nsid (nvme_ns_t n) @@ -5656,7 +5620,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_ns_t n`` - *undescribed* .. c:function:: int nvme_ns_get_lba_size (nvme_ns_t n) @@ -5665,7 +5628,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_ns_t n`` - *undescribed* .. c:function:: uint64_t nvme_ns_get_lba_count (nvme_ns_t n) @@ -5674,7 +5636,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_ns_t n`` - *undescribed* .. c:function:: uint64_t nvme_ns_get_lba_util (nvme_ns_t n) @@ -5683,7 +5644,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_ns_t n`` - *undescribed* .. c:function:: const char * nvme_ns_get_sysfs_dir (nvme_ns_t n) @@ -5692,7 +5652,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_ns_t n`` - *undescribed* .. c:function:: const char * nvme_ns_get_name (nvme_ns_t n) @@ -5701,7 +5660,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_ns_t n`` - *undescribed* .. c:function:: nvme_subsystem_t nvme_ns_get_subsystem (nvme_ns_t n) @@ -5710,7 +5668,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_ns_t n`` - *undescribed* .. c:function:: nvme_ctrl_t nvme_ns_get_ctrl (nvme_ns_t n) @@ -5719,7 +5676,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_ns_t n`` - *undescribed* .. c:function:: int nvme_ns_read (nvme_ns_t n, void * buf, off_t offset, size_t count) @@ -5737,7 +5693,6 @@ The namespace identifier if a succecssful or -1 with errno set *undescribed* ``size_t count`` - *undescribed* .. c:function:: int nvme_ns_write (nvme_ns_t n, void * buf, off_t offset, size_t count) @@ -5755,7 +5710,6 @@ The namespace identifier if a succecssful or -1 with errno set *undescribed* ``size_t count`` - *undescribed* .. c:function:: int nvme_ns_verify (nvme_ns_t n, off_t offset, size_t count) @@ -5770,7 +5724,6 @@ The namespace identifier if a succecssful or -1 with errno set *undescribed* ``size_t count`` - *undescribed* .. c:function:: int nvme_ns_compare (nvme_ns_t n, void * buf, off_t offset, size_t count) @@ -5788,7 +5741,6 @@ The namespace identifier if a succecssful or -1 with errno set *undescribed* ``size_t count`` - *undescribed* .. c:function:: int nvme_ns_write_zeros (nvme_ns_t n, off_t offset, size_t count) @@ -5803,7 +5755,6 @@ The namespace identifier if a succecssful or -1 with errno set *undescribed* ``size_t count`` - *undescribed* .. c:function:: int nvme_ns_write_uncorrectable (nvme_ns_t n, off_t offset, size_t count) @@ -5818,7 +5769,6 @@ The namespace identifier if a succecssful or -1 with errno set *undescribed* ``size_t count`` - *undescribed* .. c:function:: int nvme_ns_flush (nvme_ns_t n) @@ -5827,7 +5777,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_ns_t n`` - *undescribed* .. c:function:: int nvme_ns_identify (nvme_ns_t n, struct nvme_id_ns * ns) @@ -5839,7 +5788,6 @@ The namespace identifier if a succecssful or -1 with errno set *undescribed* ``struct nvme_id_ns * ns`` - *undescribed* .. c:function:: const char * nvme_path_get_name (nvme_path_t p) @@ -5848,7 +5796,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_path_t p`` - *undescribed* .. c:function:: const char * nvme_path_get_sysfs_dir (nvme_path_t p) @@ -5857,7 +5804,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_path_t p`` - *undescribed* .. c:function:: const char * nvme_path_get_ana_state (nvme_path_t p) @@ -5866,7 +5812,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_path_t p`` - *undescribed* .. c:function:: nvme_ctrl_t nvme_path_get_subsystem (nvme_path_t p) @@ -5875,7 +5820,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_path_t p`` - *undescribed* .. c:function:: nvme_ns_t nvme_path_get_ns (nvme_path_t p) @@ -5884,7 +5828,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_path_t p`` - *undescribed* .. c:function:: int nvme_ctrl_get_fd (nvme_ctrl_t c) @@ -5893,7 +5836,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_ctrl_t c`` - *undescribed* .. c:function:: const char * nvme_ctrl_get_name (nvme_ctrl_t c) @@ -5902,7 +5844,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_ctrl_t c`` - *undescribed* .. c:function:: const char * nvme_ctrl_get_sysfs_dir (nvme_ctrl_t c) @@ -5911,7 +5852,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_ctrl_t c`` - *undescribed* .. c:function:: const char * nvme_ctrl_get_address (nvme_ctrl_t c) @@ -5920,7 +5860,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_ctrl_t c`` - *undescribed* .. c:function:: const char * nvme_ctrl_get_firmware (nvme_ctrl_t c) @@ -5929,7 +5868,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_ctrl_t c`` - *undescribed* .. c:function:: const char * nvme_ctrl_get_model (nvme_ctrl_t c) @@ -5938,7 +5876,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_ctrl_t c`` - *undescribed* .. c:function:: const char * nvme_ctrl_get_state (nvme_ctrl_t c) @@ -5947,7 +5884,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_ctrl_t c`` - *undescribed* .. c:function:: const char * nvme_ctrl_get_numa_node (nvme_ctrl_t c) @@ -5956,7 +5892,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_ctrl_t c`` - *undescribed* .. c:function:: const char * nvme_ctrl_get_queue_count (nvme_ctrl_t c) @@ -5965,7 +5900,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_ctrl_t c`` - *undescribed* .. c:function:: const char * nvme_ctrl_get_serial (nvme_ctrl_t c) @@ -5974,7 +5908,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_ctrl_t c`` - *undescribed* .. c:function:: const char * nvme_ctrl_get_sqsize (nvme_ctrl_t c) @@ -5983,7 +5916,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_ctrl_t c`` - *undescribed* .. c:function:: const char * nvme_ctrl_get_transport (nvme_ctrl_t c) @@ -5992,7 +5924,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_ctrl_t c`` - *undescribed* .. c:function:: const char * nvme_ctrl_get_nqn (nvme_ctrl_t c) @@ -6001,7 +5932,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_ctrl_t c`` - *undescribed* .. c:function:: const char * nvme_ctrl_get_subsysnqn (nvme_ctrl_t c) @@ -6010,7 +5940,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_ctrl_t c`` - *undescribed* .. c:function:: nvme_subsystem_t nvme_ctrl_get_subsystem (nvme_ctrl_t c) @@ -6019,7 +5948,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_ctrl_t c`` - *undescribed* .. c:function:: int nvme_ctrl_identify (nvme_ctrl_t c, struct nvme_id_ctrl * id) @@ -6031,7 +5959,6 @@ The namespace identifier if a succecssful or -1 with errno set *undescribed* ``struct nvme_id_ctrl * id`` - *undescribed* .. c:function:: int nvme_ctrl_disconnect (nvme_ctrl_t c) @@ -6040,7 +5967,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_ctrl_t c`` - *undescribed* .. c:function:: nvme_ctrl_t nvme_scan_ctrl (const char * name) @@ -6049,7 +5975,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``const char * name`` - *undescribed* .. c:function:: void nvme_free_ctrl (struct nvme_ctrl * c) @@ -6076,7 +6001,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_subsystem_t s`` - *undescribed* .. c:function:: const char * nvme_subsystem_get_sysfs_dir (nvme_subsystem_t s) @@ -6085,7 +6009,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_subsystem_t s`` - *undescribed* .. c:function:: const char * nvme_subsystem_get_name (nvme_subsystem_t s) @@ -6094,7 +6017,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_subsystem_t s`` - *undescribed* .. c:function:: nvme_root_t nvme_scan_filter (nvme_scan_filter_t f) @@ -6103,7 +6025,6 @@ The namespace identifier if a succecssful or -1 with errno set **Parameters** ``nvme_scan_filter_t f`` - *undescribed* .. c:function:: nvme_root_t nvme_scan () @@ -6148,7 +6069,6 @@ The namespace identifier if a succecssful or -1 with errno set *undescribed* ``const char * attr`` - *undescribed* .. c:function:: char * nvme_get_ctrl_attr (nvme_ctrl_t c, const char * attr) @@ -6160,7 +6080,6 @@ The namespace identifier if a succecssful or -1 with errno set *undescribed* ``const char * attr`` - *undescribed* .. c:function:: char * nvme_get_ns_attr (nvme_ns_t n, const char * attr) @@ -6172,7 +6091,6 @@ The namespace identifier if a succecssful or -1 with errno set *undescribed* ``const char * attr`` - *undescribed* .. c:function:: char * nvme_get_path_attr (nvme_path_t p, const char * attr) @@ -6184,72 +6102,83 @@ The namespace identifier if a succecssful or -1 with errno set *undescribed* ``const char * attr`` - *undescribed* .. c:type:: enum nvme_constants + A place to stash various constant nvme values **Constants** ``NVME_NSID_ALL`` - *undescribed* + A broadcast value that is used to specify all + namespaces ``NVME_NSID_NONE`` - *undescribed* + The invalid namespace id, for when the nsid + parameter is not used in a command ``NVME_UUID_NONE`` - *undescribed* + Use to omit the uuid command parameter ``NVME_CNTLID_NONE`` - *undescribed* + Use to omit the cntlid command parameter ``NVME_NVMSETID_NONE`` - *undescribed* + Use to omit the nvmsetid command parameter ``NVME_LOG_LSP_NONE`` - *undescribed* + Use to omit the log lsp command parameter ``NVME_LOG_LSI_NONE`` - *undescribed* + Use to omit the log lsi command parameter ``NVME_IDENTIFY_DATA_SIZE`` - *undescribed* + The transfer size for nvme identify commands ``NVME_ID_NVMSET_LIST_MAX`` - *undescribed* + The largest possible nvmset index in identify + nvmeset ``NVME_ID_UUID_LIST_MAX`` - *undescribed* + The largest possible uuid index in identify + uuid list ``NVME_ID_CTRL_LIST_MAX`` - *undescribed* + The largest possible controller index in + identify controller list ``NVME_ID_NS_LIST_MAX`` - *undescribed* + The largest possible namespace index in + identify namespace list ``NVME_ID_SECONDARY_CTRL_MAX`` + The largest possible secondary controller index + in identify secondary controller + +``NVME_ID_ND_DESCRIPTOR_MAX`` *undescribed* ``NVME_FEAT_LBA_RANGE_MAX`` - *undescribed* + The largest possible LBA range index in feature + lba range type ``NVME_LOG_ST_MAX_RESULTS`` - *undescribed* + The largest possible self test result index in the + device self test log ``NVME_DSM_MAX_RANGES`` - *undescribed* - - -**NVMe controller registers/properties** + The largest possible range index in a data-set + management command .. c:type:: enum nvme_registers + The nvme controller registers for all transports. This is the layout of BAR0/1 for PCIe, and properties for fabrics. **Constants** @@ -6326,87 +6255,97 @@ The namespace identifier if a succecssful or -1 with errno set SQ 0 Tail Doorbell +.. c:function:: bool is_64bit_reg (__u32 offset) + Checks if offset of the controller register is 64bit or not. -.. c:type:: enum +**Parameters** +``__u32 offset`` + Offset of controller register field in bytes -**Constants** +**Description** -``NVME_CC_ENABLE`` - *undescribed* +This function does not care about transport so that the offset is not going +to be checked inside of this function for the unsupported fields in a +specific transport. For example, BPMBL(Boot Partition Memory Buffer +Location) register is not supported by fabrics, but it can be chcked here. -``NVME_CC_CSS_NVM`` - *undescribed* +Returns true if given offset is 64bit register, otherwise it returns false. -``NVME_CC_EN_SHIFT`` - *undescribed* -``NVME_CC_CSS_SHIFT`` - *undescribed* -``NVME_CC_MPS_SHIFT`` - *undescribed* -``NVME_CC_AMS_SHIFT`` - *undescribed* +.. c:type:: enum nvme_psd_flags -``NVME_CC_SHN_SHIFT`` - *undescribed* + Possible flag values in nvme power state descriptor -``NVME_CC_IOSQES_SHIFT`` - *undescribed* +**Constants** -``NVME_CC_IOCQES_SHIFT`` - *undescribed* +``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. -``NVME_CC_AMS_RR`` - *undescribed* +``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. -``NVME_CC_AMS_WRRU`` - *undescribed* -``NVME_CC_AMS_VS`` - *undescribed* -``NVME_CC_SHN_NONE`` - *undescribed* -``NVME_CC_SHN_NORMAL`` - *undescribed* +.. c:type:: enum nvme_psd_ps -``NVME_CC_SHN_ABRUPT`` - *undescribed* + Known values for :c:type:`struct nvme_psd ` #ips and #aps. Use with nvme_psd_power_scale() to extract the power scale field to match this enum. NVME_PSD_IPS_100_MICRO_WATT: 0.0001 watt scale NVME_PSD_IPS_10_MILLI_WATT: 0.01 watt scale -``NVME_CC_SHN_MASK`` - *undescribed* +**Constants** -``NVME_CSTS_RDY`` +``NVME_PSD_PS_100_MICRO_WATT`` *undescribed* -``NVME_CSTS_CFS`` +``NVME_PSD_PS_10_MILLI_WATT`` *undescribed* -``NVME_CSTS_NSSRO`` - *undescribed* -``NVME_CSTS_PP`` - *undescribed* +.. c:function:: unsigned nvme_psd_power_scale (__u8 ps) -``NVME_CSTS_SHST_NORMAL`` - *undescribed* + power scale occupies the upper 3 bits -``NVME_CSTS_SHST_OCCUR`` - *undescribed* +**Parameters** -``NVME_CSTS_SHST_CMPLT`` +``__u8 ps`` *undescribed* -``NVME_CSTS_SHST_MASK`` - *undescribed* -**NVMe Identify** + +.. c:type:: enum nvme_psd_workload + + Specifies a workload hint in the Power Management Feature (see :c:type:`struct nvme_psd `.apw) to inform the NVM subsystem or indicate the conditions for the active power level. + +**Constants** + +``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. + +``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 + NVM subsystem are idle. The submission queue(s) + should be sufficiently large allowing the host to + ensure there are multiple commands pending at all + times during the workload. @@ -6439,36 +6378,68 @@ The namespace identifier if a succecssful or -1 with errno set **Members** +``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 :c:type:`enum nvme_psd_flags `). A value of 0 indicates + Maximum Power is not reported. +``flags`` + Additional decoding flags, see :c:type:`enum nvme_psd_flags `. -.. c:function:: unsigned nvme_psd_power_scale (__u8 ps) - - power scale occupies the upper 3 bits - -**Parameters** +``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. -``__u8 ps`` - *undescribed* +``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. +``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. +``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 -.. c:type:: enum +``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 +``idlp`` + Idle Power indicates the typical power consumed by the NVM + subsystem over 30 seconds in this power state when idle. -**Constants** +``ips`` + Idle Power Scale indicates the scale for :c:type:`struct nvme_id_psd `.idlp, + see :c:type:`enum nvme_psd_ps ` for decoding this field. -``NVME_PSD_FLAGS_MAX_POWER_SCALE`` - *undescribed* +``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. -``NVME_PSD_FLAGS_NON_OP_STATE`` - *undescribed* +``apw`` + Active Power Workload indicates the workload used to calculate + maximum power for this power state. See :c:type:`enum nvme_psd_workload ` for + decoding this field. -``NVME_PSD_RELATIVE_MASK`` - *undescribed* +``aps`` + Active Power Scale indicates the scale for the :c:type:`struct + nvme_id_psd `.actp, see :c:type:`enum nvme_psd_ps ` for decoding this value. -``NVME_PSD_APW_MASK`` - *undescribed* @@ -6576,88 +6547,356 @@ The namespace identifier if a succecssful or -1 with errno set **Members** ``vid`` - Vendor ID + PCI Vendor ID, the company vendor identifier that is assigned by + the PCI SIG. ``ssvid`` - Subsystem Vendor Id + PCI Subsystem Vendor ID, the company vendor identifier that is + assigned by the PCI SIG for the subsystem. ``sn`` - Serial Number + Serial Number in ascii ``mn`` - Model Number + Model Number in ascii ``fr`` - Firmware Revision + Firmware Revision in ascii, the currently active firmware + revision for the NVM subsystem ``rab`` - Recommended Arbitration Burst + Recommended Arbitration Burst, reported as a power of two ``ieee`` - IEEE + IEEE assigned Organization Unique Identifier ``cmic`` - Controller Mulitpathing Capabilities + Controller Multipath IO and Namespace Sharing Capabilities of + the controller and NVM subsystem. See :c:type:`enum nvme_id_ctrl_cmic `. ``mdts`` - Max Data Transfer Size + 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 ``cntlid`` - Controller Identifier + Controller ID, the NVM subsystem unique controller identifier + associated with the controller. ``ver`` - Version + Version, this field contains the value reported in the Version + register, or property (see :c:type:`enum nvme_registers ` ``NVME_REG_VS``). ``rtd3r`` - Runtime D3 Resume + RTD3 Resume Latency, the expected latency in microseconds to resume + from Runtime D3 ``rtd3e`` - Runtime D3 Exit + RTD3 Exit Latency, the typical latency in microseconds to enter + Runtime D3. ``oaes`` - Optional Async Events Supported + Optional Async Events Supported, see **enum** nvme_id_ctrl_oaes . ``ctratt`` - Controller Attributes + Controller Attributes, see **enum** nvme_id_ctrl_ctratt ``rrls`` - Read Recovery Levels + 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. ``cntrltype`` - Controller Type + Controller Type, see :c:type:`enum nvme_id_ctrl_cntrltype ` ``fguid`` - FRU GUID + FRU GUID, a 128-bit value that is globally unique for a given + Field Replaceable Unit ``crdt1`` - Controller Retry Delay 1 + Controller Retry Delay time in 100 millisecod units if CQE CRD + field is 1 ``crdt2`` - Controller Retry Delay 2 + Controller Retry Delay time in 100 millisecod units if CQE CRD + field is 2 ``crdt3`` - Controller Retry Delay 3 + Controller Retry Delay time in 100 millisecod units if CQE CRD + field is 3 + +``nvmsr`` + NVM Subsystem Report, see :c:type:`enum nvme_id_ctrl_nvmsr ` + +``vwci`` + VPD Write Cycle Information, see :c:type:`enum nvme_id_ctrl_vwci ` + +``mec`` + Management Endpoint Capabilities, see :c:type:`enum nvme_id_ctrl_mec ` ``oacs`` - Optional Admin Commands Supported + Optional Admin Command Support,the optional Admin commands and + features supported by the controller, see :c:type:`enum nvme_id_ctrl_oacs `. ``acl`` - Abort Command Limit + Abort Command Limit, the maximum number of concurrently + executing Abort commands supported by the controller. This is a + 0's based value. ``aerl`` - Async Event Request Limit + 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. + +``frmw`` + Firmware Updates indicates capabilities regarding firmware + updates. See :c:type:`enum nvme_id_ctrl_frmw `. ``lpa`` - Log Page Attributes + Log Page Attributes, see :c:type:`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. ``npss`` - Number of Power States Supported + Number of Power States Supported, the number of NVM Express + power states supported by the controller, indicating the number + of valid entries in :c:type:`struct nvme_id_ctrl `.psd. This is a 0's + based value. + +``avscc`` + Admin Vendor Specific Command Configuration, see :c:type:`enum + nvme_id_ctrl_avscc `. + +``apsta`` + Autonomous Power State Transition Attributes, see :c:type:`enum + nvme_id_ctrl_apsta `. + +``wctemp`` + Warning Composite Temperature Threshold indicates + the minimum Composite Temperature field value (see :c:type:`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 :c:type:`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. + +``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. + +``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. + +``tnvmcap`` + Total NVM Capacity, the total NVM capacity in the NVM subsystem. + 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 :c:type:`enum + nvme_id_ctrl_rpmbs `. + **edstt** Extended Device Self-test Time, if Device Self-test command is + supported (see :c:type:`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 :c:type:`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 + +``kas`` + Keep Alive Support indicates the granularity of the Keep Alive + Timer in 100 millisecond units. + +``hctma`` + Host Controlled Thermal Management Attributes, see :c:type:`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. + +``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. + +``sanicap`` + Sanitize Capabilities, see :c:type:`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. + +``hmmaxd`` + Host Memory Maximum Descriptors Entries indicates the number of + 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. + +``endgidmax`` + Endurance Group Identifier Maximum, defines the maximum value of + 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. + +``anacap`` + Asymmetric Namespace Access Capabilities, see :c:type:`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. + +``nanagrpid`` + Number of ANA Group Identifiers indicates the number of ANA + groups supported by this controller. + +``pels`` + Persistent Event Log Size indicates the maximum reportable size + for the Persistent Event Log. + +``sqes`` + Submission Queue Entry Size, see :c:type:`enum nvme_id_ctrl_sqes `. + +``cqes`` + Completion Queue Entry Size, see :c:type:`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. +``nn`` + Number of Namespaces indicates the maximum value of a valid + nsid for the NVM subsystem. If the MNAN (:c:type:`struct nvme_id_ctrl `.mnan + field is cleared to 0h, then this field also indicates the + maximum number of namespaces supported by the NVM. subsystem. +``oncs`` + Optional NVM Command Support, see :c:type:`enum nvme_id_ctrl_oncs `. +``fuses`` + Fused Operation Support, see :c:type:`enum nvme_id_ctrl_fuses `. +``fna`` + Format NVM Attributes, see :c:type:`enum nvme_id_ctrl_fna `. -.. c:type:: enum +``vwc`` + Volatile Write Cache, see :c:type:`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. + +``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. + +``nvscc`` + NVM Vendor Specific Command Configuration, see :c:type:`enum + nvme_id_ctrl_nvscc `. + +``nwpc`` + Namespace Write Protection Capabilities, see :c:type:`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. + +``sgls`` + SGL Support, see :c:type:`enum nvme_id_ctrl_sgls ` + +``mnan`` + Maximum Number of Allowed Namespaces indicates the maximum + number of namespaces supported by the NVM subsystem. + +``subnqn`` + NVM Subsystem NVMe Qualified Name, UTF-8 null terminated string + +``ioccsz`` + I/O Queue Command Capsule Supported Size, defines the maximum + 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. + +``icdoff`` + In Capsule Data Offset, defines the offset where data starts + within a capsule. This value is applicable to I/O Queues only. + +``fcatt`` + Fabrics Controller Attributes, see :c:type:`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. + +``ofcs`` + Optional Fabric Commands Support, see :c:type:`enum nvme_id_ctrl_ofcs `. + +``psd`` + Power State Descriptors, see :c:type:`struct nvme_id_psd `. + +``vs`` + Vendor Specific + + + + + +.. c:type:: enum nvme_id_ctrl_cmic **Constants** @@ -6677,8 +6916,9 @@ The namespace identifier if a succecssful or -1 with errno set -.. c:type:: enum +.. c:type:: enum nvme_id_ctrl_oaes + The typical latency in microseconds to enter Runtime D3 **Constants** @@ -6695,7 +6935,7 @@ The namespace identifier if a succecssful or -1 with errno set *undescribed* ``NVME_CTRL_OAES_LBAS`` - *undescribed* + : ``NVME_CTRL_OAES_EGE`` *undescribed* @@ -6703,7 +6943,7 @@ The namespace identifier if a succecssful or -1 with errno set -.. c:type:: enum +.. c:type:: enum nvme_id_ctrl_ctratt **Constants** @@ -6741,14 +6981,11 @@ The namespace identifier if a succecssful or -1 with errno set -.. c:type:: enum +.. c:type:: enum nvme_id_ctrl_cntrltype **Constants** -``NVME_CTRL_CNTRLTYPE_RESERVED`` - *undescribed* - ``NVME_CTRL_CNTRLTYPE_IO`` *undescribed* @@ -6761,105 +6998,140 @@ The namespace identifier if a succecssful or -1 with errno set -.. c:type:: enum +.. c:type:: enum nvme_id_ctrl_nvmsr + This field reports information associated with the NVM Subsystem, see :c:type:`struct nvme_id_ctrl `.nvmsr. **Constants** ``NVME_CTRL_NVMSR_NVMESD`` - *undescribed* + 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. ``NVME_CTRL_NVMSR_NVMEE`` - *undescribed* + 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. -.. c:type:: enum +.. c:type:: 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 :c:type:`struct nvme_id_ctrl `.vwci. **Constants** ``NVME_CTRL_VWCI_VWCR`` - *undescribed* + 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. ``NVME_CTRL_VWCI_VWCRV`` - *undescribed* + 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. -.. c:type:: enum +.. c:type:: enum nvme_id_ctrl_mec + Flags indicatings the capabilities of the Management Endpoint in the Controller, :c:type:`struct nvme_id_ctrl `.mec. **Constants** ``NVME_CTRL_MEC_SMBUSME`` - *undescribed* + If set, then the NVM Subsystem contains a Management + Endpoint on an SMBus/I2C port. ``NVME_CTRL_MEC_PCIEME`` - *undescribed* + If set, then the NVM Subsystem contains a Management + Endpoint on a PCIe port. -.. c:type:: enum +.. c:type:: enum nvme_id_ctrl_oacs + Flags indicating the optional Admin commands and features supported by the controller, see :c:type:`struct nvme_id_ctrl `.oacs. **Constants** ``NVME_CTRL_OACS_SECURITY`` - *undescribed* + If set, then the controller supports the + Security Send and Security Receive commands. ``NVME_CTRL_OACS_FORMAT`` - *undescribed* + If set then the controller supports the Format + NVM command. ``NVME_CTRL_OACS_FW`` - *undescribed* + If set, then the controller supports the + Firmware Commit and Firmware Image Download commands. ``NVME_CTRL_OACS_NS_MGMT`` - *undescribed* + If set, then the controller supports the + Namespace Management capability ``NVME_CTRL_OACS_SELF_TEST`` - *undescribed* + If set, then the controller supports the Device + Self-test command. ``NVME_CTRL_OACS_DIRECTIVES`` - *undescribed* + If set, then the controller supports Directives + and the Directive Send and Directive Receive + commands. ``NVME_CTRL_OACS_NVME_MI`` - *undescribed* + If set, then the controller supports the NVMe-MI + Send and NVMe-MI Receive commands. ``NVME_CTRL_OACS_VIRT_MGMT`` - *undescribed* + If set, then the controller supports the + Virtualization Management command. ``NVME_CTRL_OACS_DBBUF_CFG`` - *undescribed* + If set, then the controller supports the + Doorbell Buffer Config command. ``NVME_CTRL_OACS_LBA_STATUS`` - *undescribed* + If set, then the controller supports the Get LBA + Status capability. -.. c:type:: enum +.. c:type:: enum nvme_id_ctrl_frmw + Flags and values indicates capabilities regarding firmware updates from :c:type:`struct nvme_id_ctrl `.frmw. **Constants** ``NVME_CTRL_FRMW_1ST_RO`` - *undescribed* + If set, the first firmware slot is readonly ``NVME_CTRL_FRMW_NR_SLOTS`` - *undescribed* + Mask to get the value of the number of + firmware slots that the controller supports. ``NVME_CTRL_FRMW_FW_ACT_NO_RESET`` - *undescribed* + If set, the controller supports firmware + activation without a reset. -.. c:type:: enum +.. c:type:: enum nvme_id_ctrl_lpa + Flags indicating optional attributes for log pages that are accessed via the Get Log Page command. **Constants** @@ -6881,254 +7153,342 @@ The namespace identifier if a succecssful or -1 with errno set -.. c:type:: enum +.. c:type:: enum nvme_id_ctrl_avscc + Flags indicating the configuration settings for Admin Vendor Specific command handling. **Constants** ``NVME_CTRL_AVSCC_AVS`` - *undescribed* + If set, all Admin Vendor Specific Commands use the + optional vendor specific command format with NDT and + NDM fields. -.. c:type:: enum +.. c:type:: enum nvme_id_ctrl_apsta + Flags indicating the attributes of the autonomous power state transition feature. **Constants** ``NVME_CTRL_APSTA_APST`` - *undescribed* + If set, then the controller supports autonomous power + state transitions. -.. c:type:: enum +.. c:type:: enum nvme_id_ctrl_rpmbs + This field indicates if the controller supports one or more Replay Protected Memory Blocks, from :c:type:`struct nvme_id_ctrl `.rpmbs. **Constants** ``NVME_CTRL_RPMBS_NR_UNITS`` - *undescribed* + Mask to get the value of the Number of RPMB Units ``NVME_CTRL_RPMBS_AUTH_METHOD`` - *undescribed* + Mask to get the value of the Authentication Method ``NVME_CTRL_RPMBS_TOTAL_SIZE`` - *undescribed* + Mask to get the value of Total Size ``NVME_CTRL_RPMBS_ACCESS_SIZE`` - *undescribed* + Mask to get the value of Access Size -.. c:type:: enum +.. c:type:: enum nvme_id_ctrl_dsto + Flags indicating the optional Device Self-test command or operation behaviors supported by the controller or NVM subsystem. **Constants** ``NVME_CTRL_DSTO_ONE_DST`` - *undescribed* + If set, then the NVM subsystem supports only one + device self-test operation in progress at a time. -.. c:type:: enum +.. c:type:: enum nvme_id_ctrl_hctm + Flags indicate the attributes of the host controlled thermal management feature **Constants** ``NVME_CTRL_HCTMA_HCTM`` - *undescribed* + 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``. -.. c:type:: enum +.. c:type:: enum nvme_id_ctrl_sanicap + Indicates attributes for sanitize operations. **Constants** ``NVME_CTRL_SANICAP_CES`` - *undescribed* + Crypto Erase Support. If set, then the + controller supports the Crypto Erase sanitize operation. ``NVME_CTRL_SANICAP_BES`` - *undescribed* + Block Erase Support. If set, then the controller + supports the Block Erase sanitize operation. ``NVME_CTRL_SANICAP_OWS`` - *undescribed* + Overwrite Support. If set, then the controller + supports the Overwrite sanitize operation. ``NVME_CTRL_SANICAP_NDI`` - *undescribed* + 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. ``NVME_CTRL_SANICAP_NODMMAS`` - *undescribed* + No-Deallocate Modifies Media After Sanitize, + mask to extract value. -.. c:type:: enum +.. c:type:: enum nvme_id_ctrl_anacap + This field indicates the capabilities associated with Asymmetric Namespace Access Reporting. **Constants** ``NVME_CTRL_ANACAP_OPT`` - *undescribed* + If set, then the controller is able to + report ANA Optimized state. ``NVME_CTRL_ANACAP_NON_OPT`` - *undescribed* + If set, then the controller is able to + report ANA Non-Optimized state. ``NVME_CTRL_ANACAP_INACCESSIBLE`` - *undescribed* + If set, then the controller is able to + report ANA Inaccessible state. ``NVME_CTRL_ANACAP_PERSISTENT_LOSS`` - *undescribed* + If set, then the controller is able to + report ANA Persistent Loss state. ``NVME_CTRL_ANACAP_CHANGE`` - *undescribed* + If set, then the controller is able to + report ANA Change state. ``NVME_CTRL_ANACAP_GRPID_NO_CHG`` - *undescribed* + If set, then the ANAGRPID field in the + Identify Namespace data structure + (:c:type:`struct nvme_id_ns `.anagrpid), does not + change while the namespace is attached to + any controller. ``NVME_CTRL_ANACAP_GRPID_MGMT`` - *undescribed* + If set, then the controller supports a + non-zero value in the ANAGRPID field of + the Namespace Management command. -.. c:type:: enum +.. c:type:: enum nvme_id_ctrl_sqes + Defines the required and maximum Submission Queue entry size when using the NVM Command Set. **Constants** ``NVME_CTRL_SQES_MIN`` - *undescribed* + Mask to get the value of the required Submission Queue + Entry size when using the NVM Command Set. ``NVME_CTRL_SQES_MAX`` - *undescribed* + Mask to get the value of the maximum Submission Queue + entry size when using the NVM Command Set. .. c:type:: enum + Defines the required and maximum Completion Queue entry size when using the NVM Command Set. **Constants** ``NVME_CTRL_CQES_MIN`` - *undescribed* + Mask to get the value of the required Completion Queue + Entry size when using the NVM Command Set. ``NVME_CTRL_CQES_MAX`` - *undescribed* + Mask to get the value of the maximum Completion Queue + entry size when using the NVM Command Set. -.. c:type:: enum +.. c:type:: enum nvme_id_ctrl_oncs + This field indicates the optional NVM commands and features supported by the controller. **Constants** ``NVME_CTRL_ONCS_COMPARE`` - *undescribed* + If set, then the controller supports + the Compare command. ``NVME_CTRL_ONCS_WRITE_UNCORRECTABLE`` - *undescribed* + If set, then the controller supports + the Write Uncorrectable command. ``NVME_CTRL_ONCS_DSM`` - *undescribed* + If set, then the controller supports + the Dataset Management command. ``NVME_CTRL_ONCS_WRITE_ZEROES`` - *undescribed* + If set, then the controller supports + the Write Zeroes command. ``NVME_CTRL_ONCS_SAVE_FEATURES`` - *undescribed* + 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. ``NVME_CTRL_ONCS_RESERVATIONS`` - *undescribed* + If set, then the controller supports + reservations. ``NVME_CTRL_ONCS_TIMESTAMP`` - *undescribed* + If set, then the controller supports + the Timestamp feature. ``NVME_CTRL_ONCS_VERIFY`` - *undescribed* + If set, then the controller supports + the Verify command. -.. c:type:: enum +.. c:type:: enum nvme_id_ctrl_fuses + This field indicates the fused operations that the controller supports. **Constants** ``NVME_CTRL_FUSES_COMPARE_AND_WRITE`` - *undescribed* + If set, then the controller supports the + Compare and Write fused operation. -.. c:type:: enum +.. c:type:: enum nvme_id_ctrl_fna + This field indicates attributes for the Format NVM command. **Constants** ``NVME_CTRL_FNA_FMT_ALL_NAMESPACES`` - *undescribed* + 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. ``NVME_CTRL_FNA_SEC_ALL_NAMESPACES`` - *undescribed* + 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`` - *undescribed* + If set, then cryptographic erase is + supported. If cleared, then cryptographic + erase is not supported. -.. c:type:: enum +.. c:type:: enum nvme_id_ctrl_vwc **Constants** ``NVME_CTRL_VWC_PRESENT`` - *undescribed* + 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``. ``NVME_CTRL_VWC_FLUSH`` - *undescribed* + Mask to get the value of the flush command behavior. -.. c:type:: enum +.. c:type:: enum nvme_id_ctrl_nvscc + This field indicates the configuration settings for NVM Vendor Specific command handling. **Constants** ``NVME_CTRL_NVSCC_FMT`` - *undescribed* + If set, all NVM Vendor Specific Commands use the + format format with NDT and NDM fields. -.. c:type:: enum +.. c:type:: enum nvme_id_ctrl_nwpc + This field indicates the optional namespace write protection capabilities supported by the controller. **Constants** ``NVME_CTRL_NWPC_WRITE_PROTECT`` - *undescribed* + 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. ``NVME_CTRL_NWPC_WRITE_PROTECT_POWER_CYCLE`` - *undescribed* + If set, then the controller + supports the Write Protect Until + Power Cycle state. ``NVME_CTRL_NWPC_WRITE_PROTECT_PERMANENT`` - *undescribed* + If set, then the controller + supports the Permanent Write + Protect state. -.. c:type:: enum +.. c:type:: enum nvme_id_ctrl_sgls + This field indicates if SGLs are supported for the NVM Command Set and the particular SGL types supported. **Constants** @@ -7159,30 +7519,37 @@ The namespace identifier if a succecssful or -1 with errno set -.. c:type:: enum +.. c:type:: enum nvme_id_ctrl_fcatt + This field indicates attributes of the controller that are specific to NVMe over Fabrics. **Constants** ``NVME_CTRL_FCATT_DYNAMIC`` - *undescribed* + If cleared, then the NVM subsystem uses a dynamic + controller model. If set, then the NVM subsystem + uses a static controller model. -.. c:type:: enum +.. c:type:: enum nvme_id_ctrl_ofcs + Indicate whether the controller supports optional fabric commands. **Constants** ``NVME_CTRL_OFCS_DISCONNECT`` - *undescribed* + If set, then the controller supports the + Disconnect command and deletion of individual + I/O Queues. .. c:type:: struct nvme_lbaf + LBA Format Data Structure **Definition** @@ -7196,35 +7563,49 @@ The namespace identifier if a succecssful or -1 with errno set **Members** +``ms`` + Metadata Size indicates the number of metadata bytes provided per LBA + based on the LBA Data Size indicated. +``ds`` + LBA Data Size indicates the LBA data size supported, reported as a + power of two. + +``rp`` + Relative Performance, see :c:type:`enum nvme_lbaf_rp `. -.. c:type:: enum +.. c:type:: enum nvme_lbaf_rp + + This field indicates the relative performance of the LBA format indicated relative to other LBA formats supported by the controller. + **Constants** ``NVME_LBAF_RP_BEST`` - *undescribed* + Best performance ``NVME_LBAF_RP_BETTER`` - *undescribed* + Better performance ``NVME_LBAF_RP_GOOD`` - *undescribed* + Good performance ``NVME_LBAF_RP_DEGRADED`` - *undescribed* + Degraded performance ``NVME_LBAF_RP_MASK`` - *undescribed* + Mask to get the relative performance value from the + field .. c:type:: struct nvme_id_ns + Identify Namespace data structure **Definition** @@ -7272,200 +7653,415 @@ The namespace identifier if a succecssful or -1 with errno set **Members** +``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. + +``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. + +``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. + +``nsfeat`` + Namespace Features, see :c:type:`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 :c:type:`struct nvme_id_ns `.labf. + +``flbas`` + Formatted LBA Size, see :c:type:`enum nvme_id_ns_flbas `. + +``mc`` + Metadata Capabilities, see :c:type:`enum nvme_id_ns_mc `. + +``dpc`` + End-to-end Data Protection Capabilities, see :c:type:`enum + nvme_id_ns_dpc `. + +``dps`` + End-to-end Data Protection Type Settings, see :c:type:`enum + nvme_id_ns_dps `. + +``nmic`` + Namespace Multi-path I/O and Namespace Sharing Capabilities, see + :c:type:`enum nvme_id_ns_nmic `. + +``rescap`` + Reservation Capabilities, see :c:type:`enum nvme_id_ns_rescap `. + +``fpi`` + Format Progress Indicator, see :c:type:`enum nvme_nd_ns_fpi `. + +``dlfeat`` + Deallocate Logical Block Features, see :c:type:`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. + +``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. + +``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. + +``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. + +``nabo`` + Namespace Atomic Boundary Offset indicates the LBA on this + 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. + +``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. + +``nvmcap`` + NVM Capacity indicates the total size of the NVM allocated to + 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. + +``npwa`` + Namespace Preferred Write Alignment indicates the recommended + 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. + +``npda`` + Namespace Preferred Deallocate Alignment indicates the + 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. + +``anagrpid`` + ANA Group Identifier indicates the ANA Group Identifier of the + ANA group of which the namespace is a member. + +``nsattr`` + Namespace Attributes, see :c:type:`enum nvme_id_ns_attr `. + +``nvmsetid`` + NVM Set Identifier indicates the NVM Set with which this + namespace is associated. + +``endgid`` + Endurance Group Identifier indicates the Endurance Group with + 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 + +``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 + remains fixed throughout the life of the namespace and is + preserved across namespace and controller operations + +``lbaf`` + LBA Format, see :c:type:`struct nvme_lbaf `. + +``vs`` + Vendor Specific + -.. c:type:: enum +.. c:type:: enum nvme_id_nsfeat + This field defines features of the namespace. **Constants** ``NVME_NS_FEAT_THIN`` - *undescribed* + If set, indicates that the namespace supports thin + provisioning. Specifically, the Namespace Capacity + reported may be less than the Namespace Size. ``NVME_NS_FEAT_NATOMIC`` - *undescribed* + 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. ``NVME_NS_FEAT_DULBE`` - *undescribed* + If set, indicates that the controller supports the + 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. ``NVME_NS_FEAT_ID_REUSE`` *undescribed* ``NVME_NS_FEAT_IO_OPT`` - *undescribed* + 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 -.. c:type:: enum +.. c:type:: enum nvme_id_ns_flbas + This field indicates the LBA data size & metadata size combination that the namespace has been formatted with **Constants** ``NVME_NS_FLBAS_LBA_MASK`` - *undescribed* + Mask to get the index of one of the 16 supported + LBA Formats indicated in :c:type:`struct nvme_id_ns `.lbaf. ``NVME_NS_FLBAS_META_EXT`` - *undescribed* + Applicable only if format contains metadata. If + this bit is set, indicates that the metadata is + transferred at the end of the data LBA, creating an + extended data LBA. If cleared, indicates that all + of the metadata for a command is transferred as a + separate contiguous buffer of data. -.. c:type:: enum +.. c:type:: enum nvme_id_ns_mc + This field indicates the capabilities for metadata. **Constants** ``NVME_NS_MC_EXTENDED`` - *undescribed* + If set, indicates the namespace supports the metadata + being transferred as part of a separate buffer that is + specified in the Metadata Pointer. ``NVME_NS_MC_SEPARATE`` - *undescribed* + If set, indicates that the namespace supports the + metadata being transferred as part of an extended data LBA. -.. c:type:: enum +.. c:type:: enum nvme_id_ns_dpc + This field indicates the capabilities for the end-to-end data protection feature. **Constants** ``NVME_NS_DPC_PI_TYPE1`` - *undescribed* + If set, indicates that the namespace supports + Protection Information Type 1. ``NVME_NS_DPC_PI_TYPE2`` - *undescribed* + If set, indicates that the namespace supports + Protection Information Type 2. ``NVME_NS_DPC_PI_TYPE3`` - *undescribed* + If set, indicates that the namespace supports + Protection Information Type 3. ``NVME_NS_DPC_PI_FIRST`` - *undescribed* + If set, indicates that the namespace supports + protection information transferred as the first eight + bytes of metadata. ``NVME_NS_DPC_PI_LAST`` - *undescribed* + If set, indicates that the namespace supports + protection information transferred as the last eight + bytes of metadata. -.. c:type:: enum +.. c:type:: enum nvme_id_ns_dps + This field indicates the Type settings for the end-to-end data protection feature. **Constants** ``NVME_NS_DPS_PI_NONE`` - *undescribed* + Protection information is not enabled ``NVME_NS_DPS_PI_TYPE1`` - *undescribed* + Protection information is enabled, Type 1 ``NVME_NS_DPS_PI_TYPE2`` - *undescribed* + Protection information is enabled, Type 2 ``NVME_NS_DPS_PI_TYPE3`` - *undescribed* + Protection information is enabled, Type 3 ``NVME_NS_DPS_PI_MASK`` - *undescribed* + Mask to get the value of the PI type ``NVME_NS_DPS_PI_FIRST`` - *undescribed* + If set, indicates that the protection information, if + enabled, is transferred as the first eight bytes of + metadata. -.. c:type:: enum +.. c:type:: enum nvme_id_ns_nmic + This field specifies multi-path I/O and namespace sharing capabilities of the namespace. **Constants** ``NVME_NS_NMIC_SHARED`` - *undescribed* + If set, then the namespace may be attached to two or + more controllers in the NVM subsystem concurrently -.. c:type:: enum +.. c:type:: enum nvme_id_ns_rescap + This field indicates the reservation capabilities of the namespace. **Constants** ``NVME_NS_RESCAP_PTPL`` - *undescribed* + If set, indicates that the namespace supports the + Persist Through Power Loss capability. ``NVME_NS_RESCAP_WE`` - *undescribed* + If set, indicates that the namespace supports the + Write Exclusive reservation type. ``NVME_NS_RESCAP_EA`` - *undescribed* + If set, indicates that the namespace supports the + Exclusive Access reservation type. ``NVME_NS_RESCAP_WERO`` - *undescribed* + If set, indicates that the namespace supports the + Write Exclusive - Registrants Only reservation type. ``NVME_NS_RESCAP_EARO`` - *undescribed* + If set, indicates that the namespace supports the + Exclusive Access - Registrants Only reservation type. ``NVME_NS_RESCAP_WEAR`` - *undescribed* + If set, indicates that the namespace supports the + Write Exclusive - All Registrants reservation type. ``NVME_NS_RESCAP_EAAR`` - *undescribed* + If set, indicates that the namespace supports the + Exclusive Access - All Registrants reservation type. ``NVME_NS_RESCAP_IEK_13`` - *undescribed* + If set, indicates that Ignore Existing Key is used + as defined in revision 1.3 or later of this specification. -.. c:type:: enum +.. c:type:: 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. **Constants** ``NVME_NS_FPI_REMAINING`` - *undescribed* + Mask to get the format percent remaining value ``NVME_NS_FPI_SUPPORTED`` - *undescribed* + If set, indicates that the namespace supports the + Format Progress Indicator defined for the field. -.. c:type:: enum +.. c:type:: enum nvme_id_ns_dlfeat + This field indicates information about features that affect deallocating logical blocks for this namespace. **Constants** ``NVME_NS_DLFEAT_RB`` - *undescribed* + Mask to get the value of the read behavior ``NVME_NS_DLFEAT_RB_NR`` - *undescribed* + Read behvaior is not reported ``NVME_NS_DLFEAT_RB_ALL_0S`` - *undescribed* + A deallocated logical block returns all bytes + cleared to 0h. ``NVME_NS_DLFEAT_RB_ALL_FS`` - *undescribed* + A deallocated logical block returns all bytes + set to FFh. ``NVME_NS_DLFEAT_WRITE_ZEROES`` - *undescribed* + If set, indicates that the controller supports + the Deallocate bit in the Write Zeroes command + for this namespace. ``NVME_NS_DLFEAT_CRC_GUARD`` - *undescribed* + 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 -.. c:type:: enum +.. c:type:: enum nvme_id_ns_attr + Specifies attributes of the namespace. **Constants** ``NVME_NS_NSATTR_WRITE_PROTECTED`` - *undescribed* + If set, then the namespace is currently + write protected and all write access to the + namespace shall fail. @@ -7486,29 +8082,46 @@ The namespace identifier if a succecssful or -1 with errno set **Members** +``nidt`` + Namespace Identifier Type, see :c:type:`enum nvme_ns_id_desc_nidt ` +``nidl`` + Namespace Identifier Length contains the length in bytes of the + :c:type:`struct nvme_id_ns `.nid. +``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 :c:type:`struct nvme_id_ns `.nidl. -.. c:type:: enum + +.. c:type:: enum nvme_ns_id_desc_nidt + + Known namespace identifier types + **Constants** ``NVME_NIDT_EUI64`` - *undescribed* + IEEE Extended Unique Identifier, the NID field contains a + copy of the EUI64 field in the struct nvme_id_ns.eui64. ``NVME_NIDT_NGUID`` - *undescribed* + Namespace Globally Unique Identifier, the NID field + contains a copy of the NGUID field in struct nvme_id_ns.nguid. ``NVME_NIDT_UUID`` - *undescribed* + The NID field contains a 128-bit Universally Unique + Identifier (UUID) as specified in RFC 4122. .. c:type:: struct nvme_nvmset_attr + NVM Set Attributes Entry **Definition** @@ -7527,12 +8140,26 @@ The namespace identifier if a succecssful or -1 with errno set **Members** +``id`` + NVM Set Identifier + +``endurance_group_id`` + Endurance Group Identifier + +``random_4k_read_typical`` + Random 4 KiB Read Typical indicates the typical + time to complete a 4 KiB random read in 100 + nanosecond units when the NVM Set is in a + Predictable Latency Mode Deterministic Window and + there is 1 outstanding command per NVM Set. + .. c:type:: struct nvme_id_nvmset_list + **nid**; **Definition** @@ -7546,18 +8173,21 @@ The namespace identifier if a succecssful or -1 with errno set **Members** +``ent`` + ; + -.. c:type:: struct nvme_id_ns_granularity_list_entry +.. c:type:: struct nvme_id_ns_granularity_desc **Definition** :: - struct nvme_id_ns_granularity_list_entry { + struct nvme_id_ns_granularity_desc { __le64 namespace_size_granularity; __le64 namespace_capacity_granularity; }; @@ -7579,7 +8209,8 @@ The namespace identifier if a succecssful or -1 with errno set __le32 attributes; __u8 num_descriptors; __u8 rsvd[27]; - struct nvme_id_ns_granularity_list_entry entry[16]; + struct nvme_id_ns_granularity_desc entry[NVME_ID_ND_DESCRIPTOR_MAX]; + __u8 rsvd288[3808]; }; **Members** @@ -7647,6 +8278,7 @@ The namespace identifier if a succecssful or -1 with errno set .. c:type:: struct nvme_ctrl_list + **num**; **Definition** @@ -7740,6 +8372,7 @@ The namespace identifier if a succecssful or -1 with errno set .. c:type:: struct nvme_secondary_ctrl_list + **num**; **Definition** @@ -7755,9 +8388,6 @@ The namespace identifier if a succecssful or -1 with errno set -**NVMe Logs** - - .. c:type:: struct nvme_error_log_page @@ -8537,9 +9167,6 @@ The namespace identifier if a succecssful or -1 with errno set -**NVMe Directives** - - .. c:type:: enum @@ -8604,46 +9231,17 @@ The namespace identifier if a succecssful or -1 with errno set -**NVMe Management Interface** - - - - -.. c:type:: struct nvme_mi_read_nvm_ss_info - - -**Definition** - -:: - - struct nvme_mi_read_nvm_ss_info { - __u8 nump; - __u8 mjr; - __u8 mnr; - __u8 rsvd3[29]; - }; - -**Members** - - - -.. c:type:: struct nvme_mi_port_pcie +.. c:type:: struct nvme_feat_auto_pst **Definition** :: - struct nvme_mi_port_pcie { - __u8 mps; - __u8 sls; - __u8 cls; - __u8 mlw; - __u8 nlw; - __u8 pn; - __u8 rsvd14[18]; + struct nvme_feat_auto_pst { + __le64 apst_entry[32]; }; **Members** @@ -8652,20 +9250,18 @@ The namespace identifier if a succecssful or -1 with errno set -.. c:type:: struct nvme_mi_port_smb +.. c:type:: struct nvme_timestamp + timestamp: **Definition** :: - struct nvme_mi_port_smb { - __u8 vpd_addr; - __u8 mvpd_freq; - __u8 mme_addr; - __u8 mme_freq; - __u8 nvmebm; - __u8 rsvd13[19]; + struct nvme_timestamp { + __u8 timestamp[6]; + __u8 attr; + __u8 rsvd; }; **Members** @@ -8674,86 +9270,67 @@ The namespace identifier if a succecssful or -1 with errno set -.. c:type:: struct nvme_mi_read_port_info +.. c:type:: struct nvme_lba_range_type_entry **Definition** :: - struct nvme_mi_read_port_info { - __u8 portt; - __u8 rsvd1; - __le16 mmctptus; - __le32 meb; - union { - struct nvme_mi_port_pcie pcie; - struct nvme_mi_port_smb smb; - }; + struct nvme_lba_range_type_entry { + __u8 type; + __u8 attributes; + __u8 rsvd2[14]; + __u64 slba; + __u64 nlb; + __u8 guid[16]; + __u8 rsvd48[16]; }; **Members** -``{unnamed_union}`` - anonymous - - - - - -.. c:type:: struct nvme_mi_read_ctrl_info -**Definition** - -:: - - struct nvme_mi_read_ctrl_info { - __u8 portid; - __u8 rsvd1[4]; - __u8 prii; - __le16 pri; - __le16 vid; - __le16 did; - __le16 ssvid; - __le16 ssid; - __u8 rsvd16[16]; - }; - -**Members** +.. c:type:: enum +**Constants** -.. c:type:: struct nvme_mi_osc +``NVME_LBART_TYPE_GP`` + *undescribed* +``NVME_LBART_TYPE_FS`` + *undescribed* -**Definition** +``NVME_LBART_TYPE_RAID`` + *undescribed* -:: +``NVME_LBART_TYPE_CACHE`` + *undescribed* - struct nvme_mi_osc { - __u8 type; - __u8 opc; - }; +``NVME_LBART_TYPE_SWAP`` + *undescribed* -**Members** +``NVME_LBART_ATTRIB_TEMP`` + *undescribed* +``NVME_LBART_ATTRIB_HIDE`` + *undescribed* -.. c:type:: struct nvme_mi_read_sc_list +.. c:type:: struct nvme_lba_range_type **Definition** :: - struct nvme_mi_read_sc_list { - __le16 numcmd; - struct nvme_mi_osc cmds[]; + struct nvme_lba_range_type { + struct nvme_lba_range_type_entry entry[NVME_FEAT_LBA_RANGE_MAX]; }; **Members** @@ -8762,20 +9339,21 @@ The namespace identifier if a succecssful or -1 with errno set -.. c:type:: struct nvme_mi_nvm_ss_health_status +.. c:type:: struct nvme_plm_config + **ee**; **dtwinrt**; **dtwinwt**; **dtwintt**; **Definition** :: - struct nvme_mi_nvm_ss_health_status { - __u8 nss; - __u8 sw; - __u8 ctemp; - __u8 pdlu; - __le16 ccs; - __u8 rsvd8[2]; + struct nvme_plm_config { + __le16 ee; + __u8 rsvd2[30]; + __le64 dtwinrt; + __le64 dtwinwt; + __le64 dtwintt; + __u8 rsvd56[456]; }; **Members** @@ -8784,65 +9362,16 @@ The namespace identifier if a succecssful or -1 with errno set -.. c:type:: enum - - -**Constants** - -``NVME_MI_CCS_RDY`` - *undescribed* - -``NVME_MI_CSS_CFS`` - *undescribed* - -``NVME_MI_CSS_SHST`` - *undescribed* - -``NVME_MI_CSS_NSSRO`` - *undescribed* - -``NVME_MI_CSS_CECO`` - *undescribed* - -``NVME_MI_CSS_NAC`` - *undescribed* - -``NVME_MI_CSS_FA`` - *undescribed* - -``NVME_MI_CSS_CSTS`` - *undescribed* - -``NVME_MI_CSS_CTEMP`` - *undescribed* - -``NVME_MI_CSS_PDLU`` - *undescribed* - -``NVME_MI_CSS_SPARE`` - *undescribed* - -``NVME_MI_CSS_CCWARN`` - *undescribed* - - - - -.. c:type:: struct nvme_mi_ctrl_heal_status +.. c:type:: struct nvme_feat_host_behavior **Definition** :: - struct nvme_mi_ctrl_heal_status { - __le16 ctlid; - __le16 csts; - __le16 ctemp; - __u8 pdlu; - __u8 spare; - __u8 cwarn; - __u8 rsvd9[7]; + struct nvme_feat_host_behavior { + __u8 acre; + __u8 resv1[511]; }; **Members** @@ -8856,69 +9385,44 @@ The namespace identifier if a succecssful or -1 with errno set **Constants** -``NVME_MI_CSTS_RDY`` - *undescribed* - -``NVME_MI_CSTS_CFS`` +``NVME_ENABLE_ACRE`` *undescribed* -``NVME_MI_CSTS_SHST`` - *undescribed* -``NVME_MI_CSTS_NSSRO`` - *undescribed* -``NVME_MI_CSTS_CECO`` - *undescribed* -``NVME_MI_CSTS_NAC`` - *undescribed* +.. c:type:: struct nvme_dsm_range -``NVME_MI_CSTS_FA`` - *undescribed* -``NVME_MI_CWARN_ST`` - *undescribed* +**Definition** -``NVME_MI_CWARN_TAUT`` - *undescribed* +:: -``NVME_MI_CWARN_RD`` - *undescribed* + struct nvme_dsm_range { + __le32 cattr; + __le32 nlb; + __le64 slba; + }; -``NVME_MI_CWARN_RO`` - *undescribed* +**Members** -``NVME_MI_CWARN_VMBF`` - *undescribed* -.. c:type:: struct nvme_mi_vpd_mra +.. c:type:: struct nvme_registered_ctrl **Definition** :: - struct nvme_mi_vpd_mra { - __u8 nmravn; - __u8 ff; - __u8 rsvd7[6]; - __u8 i18vpwr; - __u8 m18vpwr; - __u8 i33vpwr; - __u8 m33vpwr; - __u8 rsvd17; - __u8 m33vapsr; - __u8 i5vapsr; - __u8 m5vapsr; - __u8 i12vapsr; - __u8 m12vapsr; - __u8 mtl; - __u8 tnvmcap[16]; - __u8 rsvd37[27]; + struct nvme_registered_ctrl { + __le16 cntlid; + __u8 rcsts; + __u8 rsvd3[5]; + __le64 hostid; + __le64 rkey; }; **Members** @@ -8927,23 +9431,20 @@ The namespace identifier if a succecssful or -1 with errno set -.. c:type:: struct nvme_mi_vpd_ppmra +.. c:type:: struct nvme_registered_ctrl_ext **Definition** :: - struct nvme_mi_vpd_ppmra { - __u8 nppmravn; - __u8 pn; - __u8 ppi; - __u8 ls; - __u8 mlw; - __u8 mctp; - __u8 refccap; - __u8 pi; - __u8 rsvd13[3]; + struct nvme_registered_ctrl_ext { + __le16 cntlid; + __u8 rcsts; + __u8 resv3[5]; + __le64 rkey; + __u8 hostid[16]; + __u8 resv32[32]; }; **Members** @@ -8952,67 +9453,78 @@ The namespace identifier if a succecssful or -1 with errno set -.. c:type:: struct nvme_mi_vpd_telem +.. c:type:: struct nvme_reservation_status + { **Definition** :: - struct nvme_mi_vpd_telem { - __u8 type; - __u8 rev; - __u8 len; - __u8 data[0]; + struct nvme_reservation_status { + __le32 gen; + __u8 rtype; + __u8 regctl[2]; + __u8 rsvd7[2]; + __u8 ptpls; + __u8 rsvd10[14]; + union { + struct { + __u8 resv24[40]; + struct nvme_registered_ctrl_ext regctl_eds[0]; + }; + struct nvme_registered_ctrl regctl_ds[0]; + }; }; **Members** +``{unnamed_union}`` + anonymous +``{unnamed_struct}`` + anonymous -.. c:type:: enum - -**Constants** -``NVME_MI_ELEM_EED`` - *undescribed* +.. c:type:: struct nvme_streams_directive_params -``NVME_MI_ELEM_USCE`` - *undescribed* -``NVME_MI_ELEM_ECED`` - *undescribed* +**Definition** -``NVME_MI_ELEM_LED`` - *undescribed* +:: -``NVME_MI_ELEM_SMBMED`` - *undescribed* + struct nvme_streams_directive_params { + __le16 msl; + __le16 nssa; + __le16 nsso; + __u8 nssc; + __u8 rsvd[9]; + __le32 sws; + __le16 sgs; + __le16 nsa; + __le16 nso; + __u8 rsvd2[6]; + }; -``NVME_MI_ELEM_PCIESED`` - *undescribed* +**Members** -``NVME_MI_ELEM_NVMED`` - *undescribed* -.. c:type:: struct nvme_mi_vpd_tra +.. c:type:: struct nvme_streams_directive_status **Definition** :: - struct nvme_mi_vpd_tra { - __u8 vn; - __u8 rsvd6; - __u8 ec; - struct nvme_mi_vpd_telem elems[0]; + struct nvme_streams_directive_status { + __le16 osc; + __le16 sid[]; }; **Members** @@ -9021,160 +9533,222 @@ The namespace identifier if a succecssful or -1 with errno set -.. c:type:: struct nvme_mi_vpd_mr_common +.. c:type:: struct nvme_id_directives **Definition** :: - struct nvme_mi_vpd_mr_common { - __u8 type; - __u8 rf; - __u8 rlen; - __u8 rchksum; - __u8 hchksum; - union { - struct nvme_mi_vpd_mra nmra; - struct nvme_mi_vpd_ppmra ppmra; - struct nvme_mi_vpd_tra tmra; - }; + struct nvme_id_directives { + __u8 supported[32]; + __u8 enabled[32]; + __u8 rsvd64[4032]; }; **Members** -``{unnamed_union}`` - anonymous +.. c:type:: enum -.. c:type:: struct nvme_mi_vpd_hdr + +**Constants** + +``NVME_ID_DIR_ID_BIT`` + *undescribed* + +``NVME_ID_DIR_SD_BIT`` + *undescribed* + + + + +.. c:type:: struct nvme_host_mem_buf_desc **Definition** :: - struct nvme_mi_vpd_hdr { - __u8 ipmiver; - __u8 iuaoff; - __u8 ciaoff; - __u8 biaoff; - __u8 piaoff; - __u8 mrioff; - __u8 rsvd6; - __u8 chchk; - __u8 vpd[]; + struct nvme_host_mem_buf_desc { + __le64 addr; + __le32 size; + __u32 rsvd; }; **Members** -**NVMe Features** +.. c:type:: enum nvme_ae_type -.. c:type:: struct nvme_feat_auto_pst +**Constants** +``NVME_AER_ERROR`` + *undescribed* -**Definition** +``NVME_AER_SMART`` + *undescribed* -:: +``NVME_AER_NOTICE`` + *undescribed* - struct nvme_feat_auto_pst { - __le64 apst_entry[32]; - }; +``NVME_AER_CSS`` + *undescribed* -**Members** +``NVME_AER_VS`` + *undescribed* +.. c:type:: enum nvme_ae_info_error -.. c:type:: struct nvme_timestamp +**Constants** -**Definition** +``NVME_AER_ERROR_INVALID_DB_REG`` + *undescribed* -:: +``NVME_AER_ERROR_INVALID_DB_VAL`` + *undescribed* - struct nvme_timestamp { - __u8 timestamp[6]; - __u8 attr; - __u8 rsvd; - }; +``NVME_AER_ERROR_DIAG_FAILURE`` + *undescribed* -**Members** +``NVME_AER_ERROR_PERSISTENT_INTERNAL_ERROR`` + *undescribed* + +``NVME_AER_ERROR_TRANSIENT_INTERNAL_ERROR`` + *undescribed* +``NVME_AER_ERROR_FW_IMAGE_LOAD_ERROR`` + *undescribed* -.. c:type:: struct nvme_lba_range_type_entry +.. c:type:: enum nvme_ae_info_smart -**Definition** +**Constants** + +``NVME_AER_SMART_SUBSYSTEM_RELIABILITY`` + *undescribed* + +``NVME_AER_SMART_TEMPERATURE_THRESHOLD`` + *undescribed* + +``NVME_AER_SMART_SPARE_THRESHOLD`` + *undescribed* + + + + +.. c:type:: enum nvme_ae_info_css_nvm + -:: +**Constants** - struct nvme_lba_range_type_entry { - __u8 type; - __u8 attributes; - __u8 rsvd2[14]; - __u64 slba; - __u64 nlb; - __u8 guid[16]; - __u8 rsvd48[16]; - }; +``NVME_AER_CSS_NVM_RESERVATION`` + *undescribed* -**Members** +``NVME_AER_CSS_NVM_SANITIZE_COMPLETED`` + *undescribed* +``NVME_AER_CSS_NVM_UNEXPECTED_SANITIZE_DEALLOC`` + *undescribed* -.. c:type:: enum +.. c:type:: enum nvme_ae_info_notice **Constants** -``NVME_LBART_TYPE_GP`` +``NVME_AER_NOTICE_NS_CHANGED`` *undescribed* -``NVME_LBART_TYPE_FS`` +``NVME_AER_NOTICE_FW_ACT_STARTING`` *undescribed* -``NVME_LBART_TYPE_RAID`` +``NVME_AER_NOTICE_TELEMETRY`` *undescribed* -``NVME_LBART_TYPE_CACHE`` +``NVME_AER_NOTICE_ANA`` *undescribed* -``NVME_LBART_TYPE_SWAP`` +``NVME_AER_NOTICE_PL_EVENT`` *undescribed* -``NVME_LBART_ATTRIB_TEMP`` +``NVME_AER_NOTICE_LBA_STATUS_ALERT`` *undescribed* -``NVME_LBART_ATTRIB_HIDE`` +``NVME_AER_NOTICE_EG_EVENT`` + *undescribed* + +``NVME_AER_NOTICE_DISC_CHANGED`` *undescribed* -.. c:type:: struct nvme_lba_range_type +.. c:type:: enum nvme_subsys_type + + +**Constants** + +``NVME_NQN_DISC`` + Discovery type target subsystem + +``NVME_NQN_NVME`` + NVME type target subsystem + + + +.. c:type:: struct nvmf_disc_log_entry + + Discovery log page entry **Definition** :: - struct nvme_lba_range_type { - struct nvme_lba_range_type_entry entry[NVME_FEAT_LBA_RANGE_MAX]; + struct nvmf_disc_log_entry { + __u8 trtype; + __u8 adrfam; + __u8 subtype; + __u8 treq; + __le16 portid; + __le16 cntlid; + __le16 asqsz; + __u8 resv10[22]; + char trsvcid[NVMF_TRSVCID_SIZE]; + __u8 resv64[192]; + char subnqn[NVMF_NQN_FIELD_LEN]; + char traddr[NVMF_TRADDR_SIZE]; + union tsas { + char common[NVMF_TSAS_SIZE]; + struct rdma { + __u8 qptype; + __u8 prtype; + __u8 cms; + __u8 resv3[5]; + __u16 pkey; + __u8 resv10[246]; + } rdma; + struct tcp { + __u8 sectype; + } tcp; + } tsas; }; **Members** @@ -9183,190 +9757,202 @@ The namespace identifier if a succecssful or -1 with errno set -.. c:type:: struct nvme_plm_config +.. c:type:: enum + Transport Type codes for Discovery Log Page entry TRTYPE field -**Definition** +**Constants** -:: +``NVMF_TRTYPE_UNSPECIFIED`` + Not indicated - struct nvme_plm_config { - __le16 ee; - __u8 rsvd2[30]; - __le64 dtwinrt; - __le64 dtwinwt; - __le64 dtwintt; - __u8 rsvd56[456]; - }; +``NVMF_TRTYPE_RDMA`` + RDMA -**Members** +``NVMF_TRTYPE_FC`` + Fibre Channel +``NVMF_TRTYPE_TCP`` + TCP +``NVMF_TRTYPE_LOOP`` + Reserved for host usage +``NVMF_TRTYPE_MAX`` + *undescribed* -.. c:type:: struct nvme_feat_host_behavior -**Definition** +.. c:type:: enum -:: + Address Family codes for Discovery Log Page entry ADRFAM field - struct nvme_feat_host_behavior { - __u8 acre; - __u8 resv1[511]; - }; +**Constants** -**Members** +``NVMF_ADDR_FAMILY_PCI`` + PCIe + +``NVMF_ADDR_FAMILY_IP4`` + IPv4 + +``NVMF_ADDR_FAMILY_IP6`` + IPv6 + +``NVMF_ADDR_FAMILY_IB`` + InfiniBand +``NVMF_ADDR_FAMILY_FC`` + Fibre Channel .. c:type:: enum + Transport Requirements codes for Discovery Log Page entry TREQ field **Constants** -``NVME_ENABLE_ACRE`` - *undescribed* +``NVMF_TREQ_NOT_SPECIFIED`` + Not specified +``NVMF_TREQ_REQUIRED`` + Required +``NVMF_TREQ_NOT_REQUIRED`` + Not Required +``NVMF_TREQ_DISABLE_SQFLOW`` + SQ flow control disable supported -.. c:type:: struct nvme_dsm_range -**Definition** -:: +.. c:type:: enum - struct nvme_dsm_range { - __le32 cattr; - __le32 nlb; - __le64 slba; - }; + RDMA QP Service Type codes for Discovery Log Page entry TSAS RDMA_QPTYPE field -**Members** +**Constants** +``NVMF_RDMA_QPTYPE_CONNECTED`` + Reliable Connected +``NVMF_RDMA_QPTYPE_DATAGRAM`` + Reliable Datagram -.. c:type:: struct nvme_registered_ctrl +.. c:type:: enum -**Definition** + RDMA Provider Type codes for Discovery Log Page entry TSAS RDMA_PRTYPE field -:: +**Constants** - struct nvme_registered_ctrl { - __le16 cntlid; - __u8 rcsts; - __u8 rsvd3[5]; - __le64 hostid; - __le64 rkey; - }; +``NVMF_RDMA_PRTYPE_NOT_SPECIFIED`` + No Provider Specified -**Members** +``NVMF_RDMA_PRTYPE_IB`` + InfiniBand +``NVMF_RDMA_PRTYPE_ROCE`` + InfiniBand RoCE +``NVMF_RDMA_PRTYPE_ROCEV2`` + InfiniBand RoCEV2 +``NVMF_RDMA_PRTYPE_IWARP`` + iWARP -.. c:type:: struct nvme_registered_ctrl_ext -**Definition** +.. c:type:: enum -:: + RDMA Connection Management Service Type codes for Discovery Log Page entry TSAS RDMA_CMS field - struct nvme_registered_ctrl_ext { - __le16 cntlid; - __u8 rcsts; - __u8 resv3[5]; - __le64 rkey; - __u8 hostid[16]; - __u8 resv32[32]; - }; +**Constants** -**Members** +``NVMF_RDMA_CMS_RDMA_CM`` + Sockets based endpoint addressing +.. c:type:: enum + + +**Constants** + +``NVMF_TCP_SECTYPE_NONE`` + No Security + +``NVMF_TCP_SECTYPE_TLS`` + Transport Layer Security + -.. c:type:: struct nvme_reservation_status + + +.. c:type:: struct nvmf_discovery_log **Definition** :: - struct nvme_reservation_status { - __le32 gen; - __u8 rtype; - __u8 regctl[2]; - __u8 rsvd7[2]; - __u8 ptpls; - __u8 rsvd10[14]; - union { - struct { - __u8 resv24[40]; - struct nvme_registered_ctrl_ext regctl_eds[0]; - }; - struct nvme_registered_ctrl regctl_ds[0]; - }; + struct nvmf_discovery_log { + __le64 genctr; + __le64 numrec; + __le16 recfmt; + __u8 resv14[1006]; + struct nvmf_disc_log_entry entries[0]; }; **Members** -``{unnamed_union}`` - anonymous - -``{unnamed_struct}`` - anonymous - -.. c:type:: struct nvme_streams_directive_params +.. c:type:: struct nvmf_connect_data **Definition** :: - struct nvme_streams_directive_params { - __le16 msl; - __le16 nssa; - __le16 nsso; - __u8 nssc; - __u8 rsvd[9]; - __le32 sws; - __le16 sgs; - __le16 nsa; - __le16 nso; - __u8 rsvd2[6]; + struct nvmf_connect_data { + __u8 hostid[16]; + __le16 cntlid; + char resv4[238]; + char subsysnqn[NVMF_NQN_FIELD_LEN]; + char hostnqn[NVMF_NQN_FIELD_LEN]; + char resv5[256]; }; **Members** +``cntlid`` + **subsysnqn** + **hostnqn** + -.. c:type:: struct nvme_streams_directive_status +.. c:type:: struct nvme_mi_read_nvm_ss_info **Definition** :: - struct nvme_streams_directive_status { - __le16 osc; - __le16 sid[]; + struct nvme_mi_read_nvm_ss_info { + __u8 nump; + __u8 mjr; + __u8 mnr; + __u8 rsvd3[29]; }; **Members** @@ -9375,17 +9961,21 @@ The namespace identifier if a succecssful or -1 with errno set -.. c:type:: struct nvme_id_directives +.. c:type:: struct nvme_mi_port_pcie **Definition** :: - struct nvme_id_directives { - __u8 supported[32]; - __u8 enabled[32]; - __u8 rsvd64[4032]; + struct nvme_mi_port_pcie { + __u8 mps; + __u8 sls; + __u8 cls; + __u8 mlw; + __u8 nlw; + __u8 pn; + __u8 rsvd14[18]; }; **Members** @@ -9394,212 +9984,207 @@ The namespace identifier if a succecssful or -1 with errno set -.. c:type:: enum +.. c:type:: struct nvme_mi_port_smb -**Constants** +**Definition** -``NVME_ID_DIR_ID_BIT`` - *undescribed* +:: -``NVME_ID_DIR_SD_BIT`` - *undescribed* + struct nvme_mi_port_smb { + __u8 vpd_addr; + __u8 mvpd_freq; + __u8 mme_addr; + __u8 mme_freq; + __u8 nvmebm; + __u8 rsvd13[19]; + }; +**Members** -.. c:type:: struct nvme_host_mem_buf_desc + + +.. c:type:: struct nvme_mi_read_port_info **Definition** :: - struct nvme_host_mem_buf_desc { - __le64 addr; - __le32 size; - __u32 rsvd; + struct nvme_mi_read_port_info { + __u8 portt; + __u8 rsvd1; + __le16 mmctptus; + __le32 meb; + union { + struct nvme_mi_port_pcie pcie; + struct nvme_mi_port_smb smb; + }; }; **Members** +``portt`` + **mmctptus**; +``{unnamed_union}`` + anonymous -.. c:type:: enum nvme_ae_type -**Constants** +.. c:type:: struct nvme_mi_read_ctrl_info -``NVME_AER_ERROR`` - *undescribed* + **portid**; **prii**; **pri**; **vid**; **did**; **ssvid**; **ssid**; -``NVME_AER_SMART`` - *undescribed* +**Definition** -``NVME_AER_NOTICE`` - *undescribed* +:: -``NVME_AER_CSS`` - *undescribed* + struct nvme_mi_read_ctrl_info { + __u8 portid; + __u8 rsvd1[4]; + __u8 prii; + __le16 pri; + __le16 vid; + __le16 did; + __le16 ssvid; + __le16 ssid; + __u8 rsvd16[16]; + }; -``NVME_AER_VS`` - *undescribed* +**Members** -.. c:type:: enum nvme_ae_info_error +.. c:type:: struct nvme_mi_osc -**Constants** + **type**; **opc**; -``NVME_AER_ERROR_INVALID_DB_REG`` - *undescribed* +**Definition** -``NVME_AER_ERROR_INVALID_DB_VAL`` - *undescribed* +:: -``NVME_AER_ERROR_DIAG_FAILURE`` - *undescribed* + struct nvme_mi_osc { + __u8 type; + __u8 opc; + }; -``NVME_AER_ERROR_PERSISTENT_INTERNAL_ERROR`` - *undescribed* +**Members** -``NVME_AER_ERROR_TRANSIENT_INTERNAL_ERROR`` - *undescribed* -``NVME_AER_ERROR_FW_IMAGE_LOAD_ERROR`` - *undescribed* +.. c:type:: struct nvme_mi_read_sc_list -.. c:type:: enum nvme_ae_info_smart +**Definition** -**Constants** +:: -``NVME_AER_SMART_SUBSYSTEM_RELIABILITY`` - *undescribed* + struct nvme_mi_read_sc_list { + __le16 numcmd; + struct nvme_mi_osc cmds[]; + }; -``NVME_AER_SMART_TEMPERATURE_THRESHOLD`` - *undescribed* +**Members** -``NVME_AER_SMART_SPARE_THRESHOLD`` - *undescribed* -.. c:type:: enum nvme_ae_info_css_nvm +.. c:type:: struct nvme_mi_nvm_ss_health_status -**Constants** +**Definition** -``NVME_AER_CSS_NVM_RESERVATION`` - *undescribed* +:: -``NVME_AER_CSS_NVM_SANITIZE_COMPLETED`` - *undescribed* + struct nvme_mi_nvm_ss_health_status { + __u8 nss; + __u8 sw; + __u8 ctemp; + __u8 pdlu; + __le16 ccs; + __u8 rsvd8[2]; + }; -``NVME_AER_CSS_NVM_UNEXPECTED_SANITIZE_DEALLOC`` - *undescribed* +**Members** -.. c:type:: enum nvme_ae_info_notice + +.. c:type:: enum **Constants** -``NVME_AER_NOTICE_NS_CHANGED`` +``NVME_MI_CCS_RDY`` *undescribed* -``NVME_AER_NOTICE_FW_ACT_STARTING`` +``NVME_MI_CSS_CFS`` *undescribed* -``NVME_AER_NOTICE_TELEMETRY`` +``NVME_MI_CSS_SHST`` *undescribed* -``NVME_AER_NOTICE_ANA`` +``NVME_MI_CSS_NSSRO`` *undescribed* -``NVME_AER_NOTICE_PL_EVENT`` +``NVME_MI_CSS_CECO`` *undescribed* -``NVME_AER_NOTICE_LBA_STATUS_ALERT`` +``NVME_MI_CSS_NAC`` *undescribed* -``NVME_AER_NOTICE_EG_EVENT`` +``NVME_MI_CSS_FA`` *undescribed* -``NVME_AER_NOTICE_DISC_CHANGED`` +``NVME_MI_CSS_CSTS`` *undescribed* +``NVME_MI_CSS_CTEMP`` + *undescribed* +``NVME_MI_CSS_PDLU`` + *undescribed* +``NVME_MI_CSS_SPARE`` + *undescribed* -.. c:type:: enum nvme_subsys_type - - -**Constants** - -``NVME_NQN_DISC`` - Discovery type target subsystem - -``NVME_NQN_NVME`` - NVME type target subsystem +``NVME_MI_CSS_CCWARN`` + *undescribed* -.. c:type:: struct nvmf_disc_log_entry +.. c:type:: struct nvme_mi_ctrl_heal_status **Definition** :: - struct nvmf_disc_log_entry { - __u8 trtype; - __u8 adrfam; - __u8 subtype; - __u8 treq; - __le16 portid; - __le16 cntlid; - __le16 asqsz; - __u8 resv10[22]; - char trsvcid[NVMF_TRSVCID_SIZE]; - __u8 resv64[192]; - char subnqn[NVMF_NQN_FIELD_LEN]; - char traddr[NVMF_TRADDR_SIZE]; - union tsas { - char common[NVMF_TSAS_SIZE]; - struct rdma { - __u8 qptype; - __u8 prtype; - __u8 cms; - __u8 resv3[5]; - __u16 pkey; - __u8 resv10[246]; - } rdma; - struct tcp { - __u8 sectype; - } tcp; - } tsas; + struct nvme_mi_ctrl_heal_status { + __le16 ctlid; + __le16 csts; + __le16 ctemp; + __u8 pdlu; + __u8 spare; + __u8 cwarn; + __u8 rsvd9[7]; }; **Members** -**Description** - - -Discovery log page entry - @@ -9608,194 +10193,219 @@ Discovery log page entry **Constants** -``NVMF_TRTYPE_UNSPECIFIED`` - Not indicated - -``NVMF_TRTYPE_RDMA`` - RDMA - -``NVMF_TRTYPE_FC`` - Fibre Channel - -``NVMF_TRTYPE_TCP`` - TCP - -``NVMF_TRTYPE_LOOP`` - Reserved for host usage - -``NVMF_TRTYPE_MAX`` +``NVME_MI_CSTS_RDY`` *undescribed* -**Description** - -Transport Type codes for Discovery Log Page entry TRTYPE field - - +``NVME_MI_CSTS_CFS`` + *undescribed* +``NVME_MI_CSTS_SHST`` + *undescribed* -.. c:type:: enum +``NVME_MI_CSTS_NSSRO`` + *undescribed* +``NVME_MI_CSTS_CECO`` + *undescribed* -**Constants** +``NVME_MI_CSTS_NAC`` + *undescribed* -``NVMF_ADDR_FAMILY_PCI`` - PCIe +``NVME_MI_CSTS_FA`` + *undescribed* -``NVMF_ADDR_FAMILY_IP4`` - IPv4 +``NVME_MI_CWARN_ST`` + *undescribed* -``NVMF_ADDR_FAMILY_IP6`` - IPv6 +``NVME_MI_CWARN_TAUT`` + *undescribed* -``NVMF_ADDR_FAMILY_IB`` - InfiniBand +``NVME_MI_CWARN_RD`` + *undescribed* -``NVMF_ADDR_FAMILY_FC`` - Fibre Channel +``NVME_MI_CWARN_RO`` + *undescribed* -**Description** +``NVME_MI_CWARN_VMBF`` + *undescribed* -Address Family codes for Discovery Log Page entry ADRFAM field +.. c:type:: struct nvme_mi_vpd_mra -.. c:type:: enum + **nmravn**; **ff**; **i18vpwr**; **m18vpwr**; **i33vpwr**; **m33vpwr**; **m33vapsr**; **i5vapsr**; **m5vapsr**; **i12vapsr**; **m12vapsr**; **mtl**; **tnvmcap**[16]; +**Definition** -**Constants** +:: -``NVMF_TREQ_NOT_SPECIFIED`` - Not specified + struct nvme_mi_vpd_mra { + __u8 nmravn; + __u8 ff; + __u8 rsvd7[6]; + __u8 i18vpwr; + __u8 m18vpwr; + __u8 i33vpwr; + __u8 m33vpwr; + __u8 rsvd17; + __u8 m33vapsr; + __u8 i5vapsr; + __u8 m5vapsr; + __u8 i12vapsr; + __u8 m12vapsr; + __u8 mtl; + __u8 tnvmcap[16]; + __u8 rsvd37[27]; + }; -``NVMF_TREQ_REQUIRED`` - Required +**Members** -``NVMF_TREQ_NOT_REQUIRED`` - Not Required -``NVMF_TREQ_DISABLE_SQFLOW`` - SQ flow control disable supported -**Description** -Transport Requirements codes for Discovery Log Page entry TREQ field +.. c:type:: struct nvme_mi_vpd_ppmra +**Definition** -.. c:type:: enum +:: + struct nvme_mi_vpd_ppmra { + __u8 nppmravn; + __u8 pn; + __u8 ppi; + __u8 ls; + __u8 mlw; + __u8 mctp; + __u8 refccap; + __u8 pi; + __u8 rsvd13[3]; + }; -**Constants** +**Members** -``NVMF_RDMA_QPTYPE_CONNECTED`` - Reliable Connected -``NVMF_RDMA_QPTYPE_DATAGRAM`` - Reliable Datagram -**Description** -RDMA QP Service Type codes for Discovery Log Page entry TSAS -RDMA_QPTYPE field +.. c:type:: struct nvme_mi_vpd_telem +**Definition** -.. c:type:: enum +:: + struct nvme_mi_vpd_telem { + __u8 type; + __u8 rev; + __u8 len; + __u8 data[0]; + }; -**Constants** +**Members** -``NVMF_RDMA_PRTYPE_NOT_SPECIFIED`` - No Provider Specified -``NVMF_RDMA_PRTYPE_IB`` - InfiniBand -``NVMF_RDMA_PRTYPE_ROCE`` - InfiniBand RoCE -``NVMF_RDMA_PRTYPE_ROCEV2`` - InfiniBand RoCEV2 -``NVMF_RDMA_PRTYPE_IWARP`` - iWARP +.. c:type:: enum -**Description** -RDMA Provider Type codes for Discovery Log Page entry TSAS -RDMA_PRTYPE field +**Constants** +``NVME_MI_ELEM_EED`` + *undescribed* +``NVME_MI_ELEM_USCE`` + *undescribed* +``NVME_MI_ELEM_ECED`` + *undescribed* -.. c:type:: enum +``NVME_MI_ELEM_LED`` + *undescribed* +``NVME_MI_ELEM_SMBMED`` + *undescribed* -**Constants** +``NVME_MI_ELEM_PCIESED`` + *undescribed* -``NVMF_RDMA_CMS_RDMA_CM`` - Sockets based endpoint addressing +``NVME_MI_ELEM_NVMED`` + *undescribed* -**Description** -RDMA Connection Management Service Type codes for Discovery Log Page -entry TSAS RDMA_CMS field +.. c:type:: struct nvme_mi_vpd_tra -.. c:type:: enum +**Definition** +:: -**Constants** + struct nvme_mi_vpd_tra { + __u8 vn; + __u8 rsvd6; + __u8 ec; + struct nvme_mi_vpd_telem elems[0]; + }; -``NVMF_TCP_SECTYPE_NONE`` - No Security +**Members** -``NVMF_TCP_SECTYPE_TLS`` - Transport Layer Security -.. c:type:: struct nvmf_discovery_log +.. c:type:: struct nvme_mi_vpd_mr_common + **type**; **rf**; **rlen**; **rchksum**; **hchksum**; **ppmra**; **tmra**; **Definition** :: - struct nvmf_discovery_log { - __le64 genctr; - __le64 numrec; - __le16 recfmt; - __u8 resv14[1006]; - struct nvmf_disc_log_entry entries[0]; + struct nvme_mi_vpd_mr_common { + __u8 type; + __u8 rf; + __u8 rlen; + __u8 rchksum; + __u8 hchksum; + union { + struct nvme_mi_vpd_mra nmra; + struct nvme_mi_vpd_ppmra ppmra; + struct nvme_mi_vpd_tra tmra; + }; }; **Members** +``{unnamed_union}`` + anonymous -.. c:type:: struct nvmf_connect_data + +.. c:type:: struct nvme_mi_vpd_hdr **Definition** :: - struct nvmf_connect_data { - __u8 hostid[16]; - __le16 cntlid; - char resv4[238]; - char subsysnqn[NVMF_NQN_FIELD_LEN]; - char hostnqn[NVMF_NQN_FIELD_LEN]; - char resv5[256]; + struct nvme_mi_vpd_hdr { + __u8 ipmiver; + __u8 iuaoff; + __u8 ciaoff; + __u8 biaoff; + __u8 piaoff; + __u8 mrioff; + __u8 rsvd6; + __u8 chchk; + __u8 vpd[]; }; **Members** @@ -10146,27 +10756,25 @@ entry TSAS RDMA_CMS field *undescribed* -.. c:function:: __u8 nvme_status_type (__u16 status) +.. c:function:: __u8 nvme_status_to_errno (int status, bool fabrics) - Returns SCT(Status Code Type) in status field of the completion queue entry. + Converts nvme return status to errno **Parameters** -``__u16 status`` - return value from nvme passthrough commands, which is the nvme - status field, located at DW3 in completion queue entry - +``int status`` + Return status from an nvme passthrough commmand -.. c:function:: const char * nvme_status_to_string (int status, bool fabrics) +``bool fabrics`` + true if given status is for fabrics +**Description** -**Parameters** +If status < 0, errno is already set. -``int status`` - *undescribed* +**Return** -``bool fabrics`` - *undescribed* +Appropriate errno for the given nvme status .. c:function:: int nvme_fw_download_seq (int fd, __u32 size, __u32 xfer, __u32 offset, void * buf) @@ -10187,10 +10795,9 @@ entry TSAS RDMA_CMS field *undescribed* ``void * buf`` - *undescribed* -.. c:function:: int nvme_get_telemetry_log (int fd, bool create, bool ctrl, int data_area, void ** buf, __u32 * log_size) +.. c:function:: int nvme_get_ctrl_telemetry (int fd, bool rae, void ** buf, __u32 * log_size) **Parameters** @@ -10198,21 +10805,42 @@ entry TSAS RDMA_CMS field ``int fd`` *undescribed* -``bool create`` +``bool rae`` *undescribed* -``bool ctrl`` +``void ** buf`` *undescribed* -``int data_area`` +``__u32 * log_size`` + + +.. c:function:: int nvme_get_host_telemetry (int fd, void ** buf, __u32 * log_size) + + +**Parameters** + +``int fd`` *undescribed* ``void ** buf`` *undescribed* ``__u32 * log_size`` + + +.. c:function:: int nvme_get_new_host_telemetry (int fd, void ** buf, __u32 * log_size) + + +**Parameters** + +``int fd`` + *undescribed* + +``void ** buf`` *undescribed* +``__u32 * log_size`` + .. c:function:: void nvme_setup_id_ns (struct nvme_id_ns * ns, __u64 nsze, __u64 ncap, __u8 flbas, __u8 dps, __u8 nmic, __u32 anagrpid, __u16 nvmsetid) @@ -10346,14 +10974,19 @@ Calls __nvme_get_log_page() with a default 4k transfer length. .. c:function:: int nvme_get_ana_log_len (int fd, size_t * analen) + Retreive size of the current ANA log **Parameters** ``int fd`` - *undescribed* + File descriptor of nvme device ``size_t * analen`` - *undescribed* + Pointer to where the length will be set on success + +**Return** + +0 on success, -1 otherwise with errno set .. c:function:: int nvme_namespace_attach_ctrls (int fd, __u32 nsid, __u16 num_ctrls, __u16 * ctrlist) @@ -10376,8 +11009,8 @@ Calls __nvme_get_log_page() with a default 4k transfer length. **Return** -The nvme command status if a response was received or -errno - otherwise. +The nvme command status if a response was received or -1 + with errno set otherwise. .. c:function:: int nvme_namespace_detach_ctrls (int fd, __u32 nsid, __u16 num_ctrls, __u16 * ctrlist) @@ -10400,12 +11033,13 @@ The nvme command status if a response was received or -errno **Return** -The nvme command status if a response was received or -errno - otherwise. +The nvme command status if a response was received or -1 + with errno set otherwise. .. c:function:: int nvme_get_feature_length (int fid, __u32 cdw11, __u32 * len) + Retreive the command payload length for a specific feature identifier **Parameters** @@ -10416,22 +11050,30 @@ The nvme command status if a response was received or -errno *undescribed* ``__u32 * len`` - *undescribed* + +**Return** + +0 on success, -1 with errno set otherwise -.. c:function:: int nvme_get_directive_receive_length (__u8 dtype, __u8 doper, __u32 * len) +.. c:function:: int nvme_get_directive_receive_length (enum nvme_directive_dtype dtype, enum nvme_directive_receive_doper doper, __u32 * len) **Parameters** -``__u8 dtype`` - *undescribed* +``enum nvme_directive_dtype dtype`` + Directive type, see :c:type:`enum nvme_directive_dtype ` -``__u8 doper`` - *undescribed* +``enum nvme_directive_receive_doper doper`` + Directive receive operation, see :c:type:`enum nvme_directive_receive_doper ` ``__u32 * len`` - *undescribed* + Address to save the payload length of the directive in bytes on + a successful decode + +**Return** + +0 on success, -1 with errno set to EINVAL. .. c:function:: int nvme_open (const char * name) @@ -10454,3 +11096,21 @@ A file descriptor for the device on a successful open, or -1 with errno set otherwise. +.. c:function:: int nvme_set_attr (const char * dir, const char * attr, const char * value) + + +**Parameters** + +``const char * dir`` + *undescribed* + +``const char * attr`` + *undescribed* + +``const char * value`` + +**Description** + +Return + + diff --git a/doc/man/__nvme_get_log_page.2 b/doc/man/__nvme_get_log_page.2 new file mode 100644 index 0000000000..e240ffd665 --- /dev/null +++ b/doc/man/__nvme_get_log_page.2 @@ -0,0 +1,27 @@ +.TH "__nvme_get_log_page" 2 "__nvme_get_log_page" "February 2020" "libnvme Manual" +.SH NAME +__nvme_get_log_page \- +.SH SYNOPSIS +.B "int" __nvme_get_log_page +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "__u8 " log_id "," +.BI "bool " rae "," +.BI "__u32 " xfer_len "," +.BI "__u32 " data_len "," +.BI "void *" data ");" +.SH ARGUMENTS +.IP "fd" 12 +-- undescribed -- +.IP "nsid" 12 +-- undescribed -- +.IP "log_id" 12 +-- undescribed -- +.IP "rae" 12 +-- undescribed -- +.IP "xfer_len" 12 +Max partial log transfer size to request while splitting +.IP "data_len" 12 +-- undescribed -- +.IP "data" 12 +-- undescribed -- diff --git a/doc/man/enum .2 b/doc/man/enum .2 new file mode 100644 index 0000000000..54a840a5c6 --- /dev/null +++ b/doc/man/enum .2 @@ -0,0 +1,678 @@ +.TH "libnvme" 2 "enum " "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum \- +.SH SYNOPSIS +enum { +.br +.BI " NVME_SCT_GENERIC" +, +.br +.br +.BI " NVME_SCT_CMD_SPECIFIC" +, +.br +.br +.BI " NVME_SCT_MEDIA" +, +.br +.br +.BI " NVME_SCT_PATH" +, +.br +.br +.BI " NVME_SCT_VS" +, +.br +.br +.BI " NVME_SCT_MASK" +, +.br +.br +.BI " NVME_SC_SUCCESS" +, +.br +.br +.BI " NVME_SC_INVALID_OPCODE" +, +.br +.br +.BI " NVME_SC_INVALID_FIELD" +, +.br +.br +.BI " NVME_SC_CMDID_CONFLICT" +, +.br +.br +.BI " NVME_SC_DATA_XFER_ERROR" +, +.br +.br +.BI " NVME_SC_POWER_LOSS" +, +.br +.br +.BI " NVME_SC_INTERNAL" +, +.br +.br +.BI " NVME_SC_ABORT_REQ" +, +.br +.br +.BI " NVME_SC_ABORT_QUEUE" +, +.br +.br +.BI " NVME_SC_FUSED_FAIL" +, +.br +.br +.BI " NVME_SC_FUSED_MISSING" +, +.br +.br +.BI " NVME_SC_INVALID_NS" +, +.br +.br +.BI " NVME_SC_CMD_SEQ_ERROR" +, +.br +.br +.BI " NVME_SC_SGL_INVALID_LAST" +, +.br +.br +.BI " NVME_SC_SGL_INVALID_COUNT" +, +.br +.br +.BI " NVME_SC_SGL_INVALID_DATA" +, +.br +.br +.BI " NVME_SC_SGL_INVALID_METADATA" +, +.br +.br +.BI " NVME_SC_SGL_INVALID_TYPE" +, +.br +.br +.BI " NVME_SC_CMB_INVALID_USE" +, +.br +.br +.BI " NVME_SC_PRP_INVALID_OFFSET" +, +.br +.br +.BI " NVME_SC_AWU_EXCEEDED" +, +.br +.br +.BI " NVME_SC_OP_DENIED" +, +.br +.br +.BI " NVME_SC_SGL_INVALID_OFFSET" +, +.br +.br +.BI " NVME_SC_HOSTID_FORMAT" +, +.br +.br +.BI " NVME_SC_KAT_EXPIRED" +, +.br +.br +.BI " NVME_SC_KAT_INVALID" +, +.br +.br +.BI " NVME_SC_CMD_ABORTED_PREMEPT" +, +.br +.br +.BI " NVME_SC_SANITIZE_FAILED" +, +.br +.br +.BI " NVME_SC_SANITIZE_IN_PROGRESS" +, +.br +.br +.BI " NVME_SC_SGL_INVALID_GRANULARITY" +, +.br +.br +.BI " NVME_SC_CMD_IN_CMBQ_NOT_SUPP" +, +.br +.br +.BI " NVME_SC_NS_WRITE_PROTECTED" +, +.br +.br +.BI " NVME_SC_CMD_INTERRUPTED" +, +.br +.br +.BI " NVME_SC_TRAN_TPORT_ERROR" +, +.br +.br +.BI " NVME_SC_LBA_RANGE" +, +.br +.br +.BI " NVME_SC_CAP_EXCEEDED" +, +.br +.br +.BI " NVME_SC_NS_NOT_READY" +, +.br +.br +.BI " NVME_SC_RESERVATION_CONFLICT" +, +.br +.br +.BI " NVME_SC_FORMAT_IN_PROGRESS" +, +.br +.br +.BI " NVME_SC_CQ_INVALID" +, +.br +.br +.BI " NVME_SC_QID_INVALID" +, +.br +.br +.BI " NVME_SC_QUEUE_SIZE" +, +.br +.br +.BI " NVME_SC_ABORT_LIMIT" +, +.br +.br +.BI " NVME_SC_ABORT_MISSING" +, +.br +.br +.BI " NVME_SC_ASYNC_LIMIT" +, +.br +.br +.BI " NVME_SC_FIRMWARE_SLOT" +, +.br +.br +.BI " NVME_SC_FIRMWARE_IMAGE" +, +.br +.br +.BI " NVME_SC_INVALID_VECTOR" +, +.br +.br +.BI " NVME_SC_INVALID_LOG_PAGE" +, +.br +.br +.BI " NVME_SC_INVALID_FORMAT" +, +.br +.br +.BI " NVME_SC_FW_NEEDS_CONV_RESET" +, +.br +.br +.BI " NVME_SC_INVALID_QUEUE" +, +.br +.br +.BI " NVME_SC_FEATURE_NOT_SAVEABLE" +, +.br +.br +.BI " NVME_SC_FEATURE_NOT_CHANGEABLE" +, +.br +.br +.BI " NVME_SC_FEATURE_NOT_PER_NS" +, +.br +.br +.BI " NVME_SC_FW_NEEDS_SUBSYS_RESET" +, +.br +.br +.BI " NVME_SC_FW_NEEDS_RESET" +, +.br +.br +.BI " NVME_SC_FW_NEEDS_MAX_TIME" +, +.br +.br +.BI " NVME_SC_FW_ACTIVATE_PROHIBITED" +, +.br +.br +.BI " NVME_SC_OVERLAPPING_RANGE" +, +.br +.br +.BI " NVME_SC_NS_INSUFFICIENT_CAP" +, +.br +.br +.BI " NVME_SC_NS_ID_UNAVAILABLE" +, +.br +.br +.BI " NVME_SC_NS_ALREADY_ATTACHED" +, +.br +.br +.BI " NVME_SC_NS_IS_PRIVATE" +, +.br +.br +.BI " NVME_SC_NS_NOT_ATTACHED" +, +.br +.br +.BI " NVME_SC_THIN_PROV_NOT_SUPP" +, +.br +.br +.BI " NVME_SC_CTRL_LIST_INVALID" +, +.br +.br +.BI " NVME_SC_SELF_TEST_IN_PROGRESS" +, +.br +.br +.BI " NVME_SC_BP_WRITE_PROHIBITED" +, +.br +.br +.BI " NVME_SC_INVALID_CTRL_ID" +, +.br +.br +.BI " NVME_SC_INVALID_SEC_CTRL_STATE" +, +.br +.br +.BI " NVME_SC_INVALID_CTRL_RESOURCES" +, +.br +.br +.BI " NVME_SC_INVALID_RESOURCE_ID" +, +.br +.br +.BI " NVME_SC_PMR_SAN_PROHIBITED" +, +.br +.br +.BI " NVME_SC_ANA_GROUP_ID_INVALID" +, +.br +.br +.BI " NVME_SC_ANA_ATTACH_FAILED" +, +.br +.br +.BI " NVME_SC_BAD_ATTRIBUTES" +, +.br +.br +.BI " NVME_SC_INVALID_PI" +, +.br +.br +.BI " NVME_SC_READ_ONLY" +, +.br +.br +.BI " NVME_SC_CONNECT_FORMAT" +, +.br +.br +.BI " NVME_SC_CONNECT_CTRL_BUSY" +, +.br +.br +.BI " NVME_SC_CONNECT_INVALID_PARAM" +, +.br +.br +.BI " NVME_SC_CONNECT_RESTART_DISC" +, +.br +.br +.BI " NVME_SC_CONNECT_INVALID_HOST" +, +.br +.br +.BI " NVME_SC_DISCONNECT_INVALID_QTYPE" +, +.br +.br +.BI " NVME_SC_DISCOVERY_RESTART" +, +.br +.br +.BI " NVME_SC_AUTH_REQUIRED" +, +.br +.br +.BI " NVME_SC_WRITE_FAULT" +, +.br +.br +.BI " NVME_SC_READ_ERROR" +, +.br +.br +.BI " NVME_SC_GUARD_CHECK" +, +.br +.br +.BI " NVME_SC_APPTAG_CHECK" +, +.br +.br +.BI " NVME_SC_REFTAG_CHECK" +, +.br +.br +.BI " NVME_SC_COMPARE_FAILED" +, +.br +.br +.BI " NVME_SC_ACCESS_DENIED" +, +.br +.br +.BI " NVME_SC_UNWRITTEN_BLOCK" +, +.br +.br +.BI " NVME_SC_ANA_INTERNAL_PATH_ERROR" +, +.br +.br +.BI " NVME_SC_ANA_PERSISTENT_LOSS" +, +.br +.br +.BI " NVME_SC_ANA_INACCESSIBLE" +, +.br +.br +.BI " NVME_SC_ANA_TRANSITION" +, +.br +.br +.BI " NVME_SC_CTRL_PATH_ERROR" +, +.br +.br +.BI " NVME_SC_HOST_PATH_ERROR" +, +.br +.br +.BI " NVME_SC_CMD_ABORTED_BY_HOST" +, +.br +.br +.BI " NVME_SC_MASK" +, +.br +.br +.BI " NVME_SC_CRD" +, +.br +.br +.BI " NVME_SC_MORE" +, +.br +.br +.BI " NVME_SC_DNR" + +}; +.SH Constants +.IP "NVME_SCT_GENERIC" 12 +-- undescribed -- +.IP "NVME_SCT_CMD_SPECIFIC" 12 +-- undescribed -- +.IP "NVME_SCT_MEDIA" 12 +-- undescribed -- +.IP "NVME_SCT_PATH" 12 +-- undescribed -- +.IP "NVME_SCT_VS" 12 +-- undescribed -- +.IP "NVME_SCT_MASK" 12 +-- undescribed -- +.IP "NVME_SC_SUCCESS" 12 +-- undescribed -- +.IP "NVME_SC_INVALID_OPCODE" 12 +-- undescribed -- +.IP "NVME_SC_INVALID_FIELD" 12 +-- undescribed -- +.IP "NVME_SC_CMDID_CONFLICT" 12 +-- undescribed -- +.IP "NVME_SC_DATA_XFER_ERROR" 12 +-- undescribed -- +.IP "NVME_SC_POWER_LOSS" 12 +-- undescribed -- +.IP "NVME_SC_INTERNAL" 12 +-- undescribed -- +.IP "NVME_SC_ABORT_REQ" 12 +-- undescribed -- +.IP "NVME_SC_ABORT_QUEUE" 12 +-- undescribed -- +.IP "NVME_SC_FUSED_FAIL" 12 +-- undescribed -- +.IP "NVME_SC_FUSED_MISSING" 12 +-- undescribed -- +.IP "NVME_SC_INVALID_NS" 12 +-- undescribed -- +.IP "NVME_SC_CMD_SEQ_ERROR" 12 +-- undescribed -- +.IP "NVME_SC_SGL_INVALID_LAST" 12 +-- undescribed -- +.IP "NVME_SC_SGL_INVALID_COUNT" 12 +-- undescribed -- +.IP "NVME_SC_SGL_INVALID_DATA" 12 +-- undescribed -- +.IP "NVME_SC_SGL_INVALID_METADATA" 12 +-- undescribed -- +.IP "NVME_SC_SGL_INVALID_TYPE" 12 +-- undescribed -- +.IP "NVME_SC_CMB_INVALID_USE" 12 +-- undescribed -- +.IP "NVME_SC_PRP_INVALID_OFFSET" 12 +-- undescribed -- +.IP "NVME_SC_AWU_EXCEEDED" 12 +-- undescribed -- +.IP "NVME_SC_OP_DENIED" 12 +-- undescribed -- +.IP "NVME_SC_SGL_INVALID_OFFSET" 12 +-- undescribed -- +.IP "NVME_SC_HOSTID_FORMAT" 12 +-- undescribed -- +.IP "NVME_SC_KAT_EXPIRED" 12 +-- undescribed -- +.IP "NVME_SC_KAT_INVALID" 12 +-- undescribed -- +.IP "NVME_SC_CMD_ABORTED_PREMEPT" 12 +-- undescribed -- +.IP "NVME_SC_SANITIZE_FAILED" 12 +-- undescribed -- +.IP "NVME_SC_SANITIZE_IN_PROGRESS" 12 +-- undescribed -- +.IP "NVME_SC_SGL_INVALID_GRANULARITY" 12 +-- undescribed -- +.IP "NVME_SC_CMD_IN_CMBQ_NOT_SUPP" 12 +-- undescribed -- +.IP "NVME_SC_NS_WRITE_PROTECTED" 12 +-- undescribed -- +.IP "NVME_SC_CMD_INTERRUPTED" 12 +-- undescribed -- +.IP "NVME_SC_TRAN_TPORT_ERROR" 12 +-- undescribed -- +.IP "NVME_SC_LBA_RANGE" 12 +-- undescribed -- +.IP "NVME_SC_CAP_EXCEEDED" 12 +-- undescribed -- +.IP "NVME_SC_NS_NOT_READY" 12 +-- undescribed -- +.IP "NVME_SC_RESERVATION_CONFLICT" 12 +-- undescribed -- +.IP "NVME_SC_FORMAT_IN_PROGRESS" 12 +-- undescribed -- +.IP "NVME_SC_CQ_INVALID" 12 +-- undescribed -- +.IP "NVME_SC_QID_INVALID" 12 +-- undescribed -- +.IP "NVME_SC_QUEUE_SIZE" 12 +-- undescribed -- +.IP "NVME_SC_ABORT_LIMIT" 12 +-- undescribed -- +.IP "NVME_SC_ABORT_MISSING" 12 +-- undescribed -- +.IP "NVME_SC_ASYNC_LIMIT" 12 +-- undescribed -- +.IP "NVME_SC_FIRMWARE_SLOT" 12 +-- undescribed -- +.IP "NVME_SC_FIRMWARE_IMAGE" 12 +-- undescribed -- +.IP "NVME_SC_INVALID_VECTOR" 12 +-- undescribed -- +.IP "NVME_SC_INVALID_LOG_PAGE" 12 +-- undescribed -- +.IP "NVME_SC_INVALID_FORMAT" 12 +-- undescribed -- +.IP "NVME_SC_FW_NEEDS_CONV_RESET" 12 +-- undescribed -- +.IP "NVME_SC_INVALID_QUEUE" 12 +-- undescribed -- +.IP "NVME_SC_FEATURE_NOT_SAVEABLE" 12 +-- undescribed -- +.IP "NVME_SC_FEATURE_NOT_CHANGEABLE" 12 +-- undescribed -- +.IP "NVME_SC_FEATURE_NOT_PER_NS" 12 +-- undescribed -- +.IP "NVME_SC_FW_NEEDS_SUBSYS_RESET" 12 +-- undescribed -- +.IP "NVME_SC_FW_NEEDS_RESET" 12 +-- undescribed -- +.IP "NVME_SC_FW_NEEDS_MAX_TIME" 12 +-- undescribed -- +.IP "NVME_SC_FW_ACTIVATE_PROHIBITED" 12 +-- undescribed -- +.IP "NVME_SC_OVERLAPPING_RANGE" 12 +-- undescribed -- +.IP "NVME_SC_NS_INSUFFICIENT_CAP" 12 +-- undescribed -- +.IP "NVME_SC_NS_ID_UNAVAILABLE" 12 +-- undescribed -- +.IP "NVME_SC_NS_ALREADY_ATTACHED" 12 +-- undescribed -- +.IP "NVME_SC_NS_IS_PRIVATE" 12 +-- undescribed -- +.IP "NVME_SC_NS_NOT_ATTACHED" 12 +-- undescribed -- +.IP "NVME_SC_THIN_PROV_NOT_SUPP" 12 +-- undescribed -- +.IP "NVME_SC_CTRL_LIST_INVALID" 12 +-- undescribed -- +.IP "NVME_SC_SELF_TEST_IN_PROGRESS" 12 +-- undescribed -- +.IP "NVME_SC_BP_WRITE_PROHIBITED" 12 +-- undescribed -- +.IP "NVME_SC_INVALID_CTRL_ID" 12 +-- undescribed -- +.IP "NVME_SC_INVALID_SEC_CTRL_STATE" 12 +-- undescribed -- +.IP "NVME_SC_INVALID_CTRL_RESOURCES" 12 +-- undescribed -- +.IP "NVME_SC_INVALID_RESOURCE_ID" 12 +-- undescribed -- +.IP "NVME_SC_PMR_SAN_PROHIBITED" 12 +-- undescribed -- +.IP "NVME_SC_ANA_GROUP_ID_INVALID" 12 +-- undescribed -- +.IP "NVME_SC_ANA_ATTACH_FAILED" 12 +-- undescribed -- +.IP "NVME_SC_BAD_ATTRIBUTES" 12 +-- undescribed -- +.IP "NVME_SC_INVALID_PI" 12 +-- undescribed -- +.IP "NVME_SC_READ_ONLY" 12 +-- undescribed -- +.IP "NVME_SC_CONNECT_FORMAT" 12 +-- undescribed -- +.IP "NVME_SC_CONNECT_CTRL_BUSY" 12 +-- undescribed -- +.IP "NVME_SC_CONNECT_INVALID_PARAM" 12 +-- undescribed -- +.IP "NVME_SC_CONNECT_RESTART_DISC" 12 +-- undescribed -- +.IP "NVME_SC_CONNECT_INVALID_HOST" 12 +-- undescribed -- +.IP "NVME_SC_DISCONNECT_INVALID_QTYPE" 12 +-- undescribed -- +.IP "NVME_SC_DISCOVERY_RESTART" 12 +-- undescribed -- +.IP "NVME_SC_AUTH_REQUIRED" 12 +-- undescribed -- +.IP "NVME_SC_WRITE_FAULT" 12 +-- undescribed -- +.IP "NVME_SC_READ_ERROR" 12 +-- undescribed -- +.IP "NVME_SC_GUARD_CHECK" 12 +-- undescribed -- +.IP "NVME_SC_APPTAG_CHECK" 12 +-- undescribed -- +.IP "NVME_SC_REFTAG_CHECK" 12 +-- undescribed -- +.IP "NVME_SC_COMPARE_FAILED" 12 +-- undescribed -- +.IP "NVME_SC_ACCESS_DENIED" 12 +-- undescribed -- +.IP "NVME_SC_UNWRITTEN_BLOCK" 12 +-- undescribed -- +.IP "NVME_SC_ANA_INTERNAL_PATH_ERROR" 12 +-- undescribed -- +.IP "NVME_SC_ANA_PERSISTENT_LOSS" 12 +-- undescribed -- +.IP "NVME_SC_ANA_INACCESSIBLE" 12 +-- undescribed -- +.IP "NVME_SC_ANA_TRANSITION" 12 +-- undescribed -- +.IP "NVME_SC_CTRL_PATH_ERROR" 12 +-- undescribed -- +.IP "NVME_SC_HOST_PATH_ERROR" 12 +-- undescribed -- +.IP "NVME_SC_CMD_ABORTED_BY_HOST" 12 +-- undescribed -- +.IP "NVME_SC_MASK" 12 +-- undescribed -- +.IP "NVME_SC_CRD" 12 +-- undescribed -- +.IP "NVME_SC_MORE" 12 +-- undescribed -- +.IP "NVME_SC_DNR" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_admin_opcode.2 b/doc/man/enum nvme_admin_opcode.2 new file mode 100644 index 0000000000..8b52caae52 --- /dev/null +++ b/doc/man/enum nvme_admin_opcode.2 @@ -0,0 +1,174 @@ +.TH "libnvme" 2 "enum nvme_admin_opcode" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_admin_opcode \- Known NVMe admin opcodes +.SH SYNOPSIS +enum nvme_admin_opcode { +.br +.BI " nvme_admin_delete_sq" +, +.br +.br +.BI " nvme_admin_create_sq" +, +.br +.br +.BI " nvme_admin_get_log_page" +, +.br +.br +.BI " nvme_admin_delete_cq" +, +.br +.br +.BI " nvme_admin_create_cq" +, +.br +.br +.BI " nvme_admin_identify" +, +.br +.br +.BI " nvme_admin_abort_cmd" +, +.br +.br +.BI " nvme_admin_set_features" +, +.br +.br +.BI " nvme_admin_get_features" +, +.br +.br +.BI " nvme_admin_async_event" +, +.br +.br +.BI " nvme_admin_ns_mgmt" +, +.br +.br +.BI " nvme_admin_fw_commit" +, +.br +.br +.BI " nvme_admin_fw_download" +, +.br +.br +.BI " nvme_admin_dev_self_test" +, +.br +.br +.BI " nvme_admin_ns_attach" +, +.br +.br +.BI " nvme_admin_keep_alive" +, +.br +.br +.BI " nvme_admin_directive_send" +, +.br +.br +.BI " nvme_admin_directive_recv" +, +.br +.br +.BI " nvme_admin_virtual_mgmt" +, +.br +.br +.BI " nvme_admin_nvme_mi_send" +, +.br +.br +.BI " nvme_admin_nvme_mi_recv" +, +.br +.br +.BI " nvme_admin_dbbuf" +, +.br +.br +.BI " nvme_admin_fabrics" +, +.br +.br +.BI " nvme_admin_format_nvm" +, +.br +.br +.BI " nvme_admin_security_send" +, +.br +.br +.BI " nvme_admin_security_recv" +, +.br +.br +.BI " nvme_admin_sanitize_nvm" +, +.br +.br +.BI " nvme_admin_get_lba_status" + +}; +.SH Constants +.IP "nvme_admin_delete_sq" 12 +-- undescribed -- +.IP "nvme_admin_create_sq" 12 +-- undescribed -- +.IP "nvme_admin_get_log_page" 12 +-- undescribed -- +.IP "nvme_admin_delete_cq" 12 +-- undescribed -- +.IP "nvme_admin_create_cq" 12 +-- undescribed -- +.IP "nvme_admin_identify" 12 +-- undescribed -- +.IP "nvme_admin_abort_cmd" 12 +-- undescribed -- +.IP "nvme_admin_set_features" 12 +-- undescribed -- +.IP "nvme_admin_get_features" 12 +-- undescribed -- +.IP "nvme_admin_async_event" 12 +-- undescribed -- +.IP "nvme_admin_ns_mgmt" 12 +-- undescribed -- +.IP "nvme_admin_fw_commit" 12 +-- undescribed -- +.IP "nvme_admin_fw_download" 12 +-- undescribed -- +.IP "nvme_admin_dev_self_test" 12 +-- undescribed -- +.IP "nvme_admin_ns_attach" 12 +-- undescribed -- +.IP "nvme_admin_keep_alive" 12 +-- undescribed -- +.IP "nvme_admin_directive_send" 12 +-- undescribed -- +.IP "nvme_admin_directive_recv" 12 +-- undescribed -- +.IP "nvme_admin_virtual_mgmt" 12 +-- undescribed -- +.IP "nvme_admin_nvme_mi_send" 12 +-- undescribed -- +.IP "nvme_admin_nvme_mi_recv" 12 +-- undescribed -- +.IP "nvme_admin_dbbuf" 12 +-- undescribed -- +.IP "nvme_admin_fabrics" 12 +-- undescribed -- +.IP "nvme_admin_format_nvm" 12 +-- undescribed -- +.IP "nvme_admin_security_send" 12 +-- undescribed -- +.IP "nvme_admin_security_recv" 12 +-- undescribed -- +.IP "nvme_admin_sanitize_nvm" 12 +-- undescribed -- +.IP "nvme_admin_get_lba_status" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_ae_info_css_nvm.2 b/doc/man/enum nvme_ae_info_css_nvm.2 new file mode 100644 index 0000000000..5d3fed48ef --- /dev/null +++ b/doc/man/enum nvme_ae_info_css_nvm.2 @@ -0,0 +1,24 @@ +.TH "libnvme" 2 "enum nvme_ae_info_css_nvm" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_ae_info_css_nvm \- +.SH SYNOPSIS +enum nvme_ae_info_css_nvm { +.br +.BI " NVME_AER_CSS_NVM_RESERVATION" +, +.br +.br +.BI " NVME_AER_CSS_NVM_SANITIZE_COMPLETED" +, +.br +.br +.BI " NVME_AER_CSS_NVM_UNEXPECTED_SANITIZE_DEALLOC" + +}; +.SH Constants +.IP "NVME_AER_CSS_NVM_RESERVATION" 12 +-- undescribed -- +.IP "NVME_AER_CSS_NVM_SANITIZE_COMPLETED" 12 +-- undescribed -- +.IP "NVME_AER_CSS_NVM_UNEXPECTED_SANITIZE_DEALLOC" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_ae_info_error.2 b/doc/man/enum nvme_ae_info_error.2 new file mode 100644 index 0000000000..9087e72ce1 --- /dev/null +++ b/doc/man/enum nvme_ae_info_error.2 @@ -0,0 +1,42 @@ +.TH "libnvme" 2 "enum nvme_ae_info_error" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_ae_info_error \- +.SH SYNOPSIS +enum nvme_ae_info_error { +.br +.BI " NVME_AER_ERROR_INVALID_DB_REG" +, +.br +.br +.BI " NVME_AER_ERROR_INVALID_DB_VAL" +, +.br +.br +.BI " NVME_AER_ERROR_DIAG_FAILURE" +, +.br +.br +.BI " NVME_AER_ERROR_PERSISTENT_INTERNAL_ERROR" +, +.br +.br +.BI " NVME_AER_ERROR_TRANSIENT_INTERNAL_ERROR" +, +.br +.br +.BI " NVME_AER_ERROR_FW_IMAGE_LOAD_ERROR" + +}; +.SH Constants +.IP "NVME_AER_ERROR_INVALID_DB_REG" 12 +-- undescribed -- +.IP "NVME_AER_ERROR_INVALID_DB_VAL" 12 +-- undescribed -- +.IP "NVME_AER_ERROR_DIAG_FAILURE" 12 +-- undescribed -- +.IP "NVME_AER_ERROR_PERSISTENT_INTERNAL_ERROR" 12 +-- undescribed -- +.IP "NVME_AER_ERROR_TRANSIENT_INTERNAL_ERROR" 12 +-- undescribed -- +.IP "NVME_AER_ERROR_FW_IMAGE_LOAD_ERROR" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_ae_info_notice.2 b/doc/man/enum nvme_ae_info_notice.2 new file mode 100644 index 0000000000..a49a508d24 --- /dev/null +++ b/doc/man/enum nvme_ae_info_notice.2 @@ -0,0 +1,54 @@ +.TH "libnvme" 2 "enum nvme_ae_info_notice" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_ae_info_notice \- +.SH SYNOPSIS +enum nvme_ae_info_notice { +.br +.BI " NVME_AER_NOTICE_NS_CHANGED" +, +.br +.br +.BI " NVME_AER_NOTICE_FW_ACT_STARTING" +, +.br +.br +.BI " NVME_AER_NOTICE_TELEMETRY" +, +.br +.br +.BI " NVME_AER_NOTICE_ANA" +, +.br +.br +.BI " NVME_AER_NOTICE_PL_EVENT" +, +.br +.br +.BI " NVME_AER_NOTICE_LBA_STATUS_ALERT" +, +.br +.br +.BI " NVME_AER_NOTICE_EG_EVENT" +, +.br +.br +.BI " NVME_AER_NOTICE_DISC_CHANGED" + +}; +.SH Constants +.IP "NVME_AER_NOTICE_NS_CHANGED" 12 +-- undescribed -- +.IP "NVME_AER_NOTICE_FW_ACT_STARTING" 12 +-- undescribed -- +.IP "NVME_AER_NOTICE_TELEMETRY" 12 +-- undescribed -- +.IP "NVME_AER_NOTICE_ANA" 12 +-- undescribed -- +.IP "NVME_AER_NOTICE_PL_EVENT" 12 +-- undescribed -- +.IP "NVME_AER_NOTICE_LBA_STATUS_ALERT" 12 +-- undescribed -- +.IP "NVME_AER_NOTICE_EG_EVENT" 12 +-- undescribed -- +.IP "NVME_AER_NOTICE_DISC_CHANGED" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_ae_info_smart.2 b/doc/man/enum nvme_ae_info_smart.2 new file mode 100644 index 0000000000..6c43a3d283 --- /dev/null +++ b/doc/man/enum nvme_ae_info_smart.2 @@ -0,0 +1,24 @@ +.TH "libnvme" 2 "enum nvme_ae_info_smart" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_ae_info_smart \- +.SH SYNOPSIS +enum nvme_ae_info_smart { +.br +.BI " NVME_AER_SMART_SUBSYSTEM_RELIABILITY" +, +.br +.br +.BI " NVME_AER_SMART_TEMPERATURE_THRESHOLD" +, +.br +.br +.BI " NVME_AER_SMART_SPARE_THRESHOLD" + +}; +.SH Constants +.IP "NVME_AER_SMART_SUBSYSTEM_RELIABILITY" 12 +-- undescribed -- +.IP "NVME_AER_SMART_TEMPERATURE_THRESHOLD" 12 +-- undescribed -- +.IP "NVME_AER_SMART_SPARE_THRESHOLD" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_ae_type.2 b/doc/man/enum nvme_ae_type.2 new file mode 100644 index 0000000000..24b8482f46 --- /dev/null +++ b/doc/man/enum nvme_ae_type.2 @@ -0,0 +1,36 @@ +.TH "libnvme" 2 "enum nvme_ae_type" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_ae_type \- +.SH SYNOPSIS +enum nvme_ae_type { +.br +.BI " NVME_AER_ERROR" +, +.br +.br +.BI " NVME_AER_SMART" +, +.br +.br +.BI " NVME_AER_NOTICE" +, +.br +.br +.BI " NVME_AER_CSS" +, +.br +.br +.BI " NVME_AER_VS" + +}; +.SH Constants +.IP "NVME_AER_ERROR" 12 +-- undescribed -- +.IP "NVME_AER_SMART" 12 +-- undescribed -- +.IP "NVME_AER_NOTICE" 12 +-- undescribed -- +.IP "NVME_AER_CSS" 12 +-- undescribed -- +.IP "NVME_AER_VS" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_cmd_format_mset.2 b/doc/man/enum nvme_cmd_format_mset.2 new file mode 100644 index 0000000000..baf172b316 --- /dev/null +++ b/doc/man/enum nvme_cmd_format_mset.2 @@ -0,0 +1,18 @@ +.TH "libnvme" 2 "enum nvme_cmd_format_mset" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_cmd_format_mset \- +.SH SYNOPSIS +enum nvme_cmd_format_mset { +.br +.BI " NVME_FORMAT_MSET_SEPARATE" +, +.br +.br +.BI " NVME_FORMAT_MSET_EXTENEDED" + +}; +.SH Constants +.IP "NVME_FORMAT_MSET_SEPARATE" 12 +-- undescribed -- +.IP "NVME_FORMAT_MSET_EXTENEDED" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_cmd_format_pi.2 b/doc/man/enum nvme_cmd_format_pi.2 new file mode 100644 index 0000000000..71be5a6ae0 --- /dev/null +++ b/doc/man/enum nvme_cmd_format_pi.2 @@ -0,0 +1,30 @@ +.TH "libnvme" 2 "enum nvme_cmd_format_pi" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_cmd_format_pi \- +.SH SYNOPSIS +enum nvme_cmd_format_pi { +.br +.BI " NVME_FORMAT_PI_DISABLE" +, +.br +.br +.BI " NVME_FORMAT_PI_TYPE1" +, +.br +.br +.BI " NVME_FORMAT_PI_TYPE2" +, +.br +.br +.BI " NVME_FORMAT_PI_TYPE3" + +}; +.SH Constants +.IP "NVME_FORMAT_PI_DISABLE" 12 +-- undescribed -- +.IP "NVME_FORMAT_PI_TYPE1" 12 +-- undescribed -- +.IP "NVME_FORMAT_PI_TYPE2" 12 +-- undescribed -- +.IP "NVME_FORMAT_PI_TYPE3" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_cmd_format_ses.2 b/doc/man/enum nvme_cmd_format_ses.2 new file mode 100644 index 0000000000..9f28db3b2c --- /dev/null +++ b/doc/man/enum nvme_cmd_format_ses.2 @@ -0,0 +1,24 @@ +.TH "libnvme" 2 "enum nvme_cmd_format_ses" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_cmd_format_ses \- +.SH SYNOPSIS +enum nvme_cmd_format_ses { +.br +.BI " NVME_FORMAT_SES_NONE" +, +.br +.br +.BI " NVME_FORMAT_SES_USER_DATA_ERASE" +, +.br +.br +.BI " NVME_FORMAT_SES_CRYPTO_ERASE" + +}; +.SH Constants +.IP "NVME_FORMAT_SES_NONE" 12 +-- undescribed -- +.IP "NVME_FORMAT_SES_USER_DATA_ERASE" 12 +-- undescribed -- +.IP "NVME_FORMAT_SES_CRYPTO_ERASE" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_cmd_get_log_lid.2 b/doc/man/enum nvme_cmd_get_log_lid.2 new file mode 100644 index 0000000000..e292734115 --- /dev/null +++ b/doc/man/enum nvme_cmd_get_log_lid.2 @@ -0,0 +1,114 @@ +.TH "libnvme" 2 "enum nvme_cmd_get_log_lid" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_cmd_get_log_lid \- +.SH SYNOPSIS +enum nvme_cmd_get_log_lid { +.br +.BI " NVME_LOG_LID_ERROR" +, +.br +.br +.BI " NVME_LOG_LID_SMART" +, +.br +.br +.BI " NVME_LOG_LID_FW_SLOT" +, +.br +.br +.BI " NVME_LOG_LID_CHANGED_NS" +, +.br +.br +.BI " NVME_LOG_LID_CMD_EFFECTS" +, +.br +.br +.BI " NVME_LOG_LID_DEVICE_SELF_TEST" +, +.br +.br +.BI " NVME_LOG_LID_TELEMETRY_HOST" +, +.br +.br +.BI " NVME_LOG_LID_TELEMETRY_CTRL" +, +.br +.br +.BI " NVME_LOG_LID_ENDURANCE_GROUP" +, +.br +.br +.BI " NVME_LOG_LID_PREDICTABLE_LAT_NVMSET" +, +.br +.br +.BI " NVME_LOG_LID_PREDICTABLE_LAT_AGG" +, +.br +.br +.BI " NVME_LOG_LID_ANA" +, +.br +.br +.BI " NVME_LOG_LID_PERSISTENT_EVENT" +, +.br +.br +.BI " NVME_LOG_LID_LBA_STATUS" +, +.br +.br +.BI " NVME_LOG_LID_ENDURANCE_GRP_EVT" +, +.br +.br +.BI " NVME_LOG_LID_DISCOVER" +, +.br +.br +.BI " NVME_LOG_LID_RESERVATION" +, +.br +.br +.BI " NVME_LOG_LID_SANITIZE" + +}; +.SH Constants +.IP "NVME_LOG_LID_ERROR" 12 +-- undescribed -- +.IP "NVME_LOG_LID_SMART" 12 +-- undescribed -- +.IP "NVME_LOG_LID_FW_SLOT" 12 +-- undescribed -- +.IP "NVME_LOG_LID_CHANGED_NS" 12 +-- undescribed -- +.IP "NVME_LOG_LID_CMD_EFFECTS" 12 +-- undescribed -- +.IP "NVME_LOG_LID_DEVICE_SELF_TEST" 12 +-- undescribed -- +.IP "NVME_LOG_LID_TELEMETRY_HOST" 12 +-- undescribed -- +.IP "NVME_LOG_LID_TELEMETRY_CTRL" 12 +-- undescribed -- +.IP "NVME_LOG_LID_ENDURANCE_GROUP" 12 +-- undescribed -- +.IP "NVME_LOG_LID_PREDICTABLE_LAT_NVMSET" 12 +-- undescribed -- +.IP "NVME_LOG_LID_PREDICTABLE_LAT_AGG" 12 +-- undescribed -- +.IP "NVME_LOG_LID_ANA" 12 +-- undescribed -- +.IP "NVME_LOG_LID_PERSISTENT_EVENT" 12 +-- undescribed -- +.IP "NVME_LOG_LID_LBA_STATUS" 12 +-- undescribed -- +.IP "NVME_LOG_LID_ENDURANCE_GRP_EVT" 12 +-- undescribed -- +.IP "NVME_LOG_LID_DISCOVER" 12 +-- undescribed -- +.IP "NVME_LOG_LID_RESERVATION" 12 +-- undescribed -- +.IP "NVME_LOG_LID_SANITIZE" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_constants.2 b/doc/man/enum nvme_constants.2 new file mode 100644 index 0000000000..9d83563aa9 --- /dev/null +++ b/doc/man/enum nvme_constants.2 @@ -0,0 +1,118 @@ +.TH "libnvme" 2 "enum nvme_constants" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_constants \- A place to stash various constant nvme values +.SH SYNOPSIS +enum nvme_constants { +.br +.BI " NVME_NSID_ALL" +, +.br +.br +.BI " NVME_NSID_NONE" +, +.br +.br +.BI " NVME_UUID_NONE" +, +.br +.br +.BI " NVME_CNTLID_NONE" +, +.br +.br +.BI " NVME_NVMSETID_NONE" +, +.br +.br +.BI " NVME_LOG_LSP_NONE" +, +.br +.br +.BI " NVME_LOG_LSI_NONE" +, +.br +.br +.BI " NVME_IDENTIFY_DATA_SIZE" +, +.br +.br +.BI " NVME_ID_NVMSET_LIST_MAX" +, +.br +.br +.BI " NVME_ID_UUID_LIST_MAX" +, +.br +.br +.BI " NVME_ID_CTRL_LIST_MAX" +, +.br +.br +.BI " NVME_ID_NS_LIST_MAX" +, +.br +.br +.BI " NVME_ID_SECONDARY_CTRL_MAX" +, +.br +.br +.BI " NVME_ID_ND_DESCRIPTOR_MAX" +, +.br +.br +.BI " NVME_FEAT_LBA_RANGE_MAX" +, +.br +.br +.BI " NVME_LOG_ST_MAX_RESULTS" +, +.br +.br +.BI " NVME_DSM_MAX_RANGES" + +}; +.SH Constants +.IP "NVME_NSID_ALL" 12 +A broadcast value that is used to specify all +namespaces +.IP "NVME_NSID_NONE" 12 +The invalid namespace id, for when the nsid +parameter is not used in a command +.IP "NVME_UUID_NONE" 12 +Use to omit the uuid command parameter +.IP "NVME_CNTLID_NONE" 12 +Use to omit the cntlid command parameter +.IP "NVME_NVMSETID_NONE" 12 +Use to omit the nvmsetid command parameter +.IP "NVME_LOG_LSP_NONE" 12 +Use to omit the log lsp command parameter +.IP "NVME_LOG_LSI_NONE" 12 +Use to omit the log lsi command parameter +.IP "NVME_IDENTIFY_DATA_SIZE" 12 +The transfer size for nvme identify commands +.IP "NVME_ID_NVMSET_LIST_MAX" 12 +The largest possible nvmset index in identify +nvmeset +.IP "NVME_ID_UUID_LIST_MAX" 12 +The largest possible uuid index in identify +uuid list +.IP "NVME_ID_CTRL_LIST_MAX" 12 +The largest possible controller index in +identify controller list +.IP "NVME_ID_NS_LIST_MAX" 12 +The largest possible namespace index in +identify namespace list +.IP "NVME_ID_SECONDARY_CTRL_MAX" 12 +The largest possible secondary controller index +in identify secondary controller +.IP "NVME_ID_ND_DESCRIPTOR_MAX" 12 +-- undescribed -- +.IP "NVME_FEAT_LBA_RANGE_MAX" 12 +The largest possible LBA range index in feature +lba range type +.IP "NVME_LOG_ST_MAX_RESULTS" 12 +The largest possible self test result index in the +device self test log +.IP "NVME_DSM_MAX_RANGES" 12 +The largest possible range index in a data-set +management command diff --git a/doc/man/enum nvme_directive_dtype.2 b/doc/man/enum nvme_directive_dtype.2 new file mode 100644 index 0000000000..2b50c797f9 --- /dev/null +++ b/doc/man/enum nvme_directive_dtype.2 @@ -0,0 +1,18 @@ +.TH "libnvme" 2 "enum nvme_directive_dtype" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_directive_dtype \- +.SH SYNOPSIS +enum nvme_directive_dtype { +.br +.BI " NVME_DIRECTIVE_DTYPE_IDENTIFY" +, +.br +.br +.BI " NVME_DIRECTIVE_DTYPE_STREAMS" + +}; +.SH Constants +.IP "NVME_DIRECTIVE_DTYPE_IDENTIFY" 12 +-- undescribed -- +.IP "NVME_DIRECTIVE_DTYPE_STREAMS" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_directive_receive_doper.2 b/doc/man/enum nvme_directive_receive_doper.2 new file mode 100644 index 0000000000..29c653b5da --- /dev/null +++ b/doc/man/enum nvme_directive_receive_doper.2 @@ -0,0 +1,30 @@ +.TH "libnvme" 2 "enum nvme_directive_receive_doper" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_directive_receive_doper \- +.SH SYNOPSIS +enum nvme_directive_receive_doper { +.br +.BI " NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM" +, +.br +.br +.BI " NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM" +, +.br +.br +.BI " NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS" +, +.br +.br +.BI " NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE" + +}; +.SH Constants +.IP "NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM" 12 +-- undescribed -- +.IP "NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM" 12 +-- undescribed -- +.IP "NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS" 12 +-- undescribed -- +.IP "NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_directive_send_doper.2 b/doc/man/enum nvme_directive_send_doper.2 new file mode 100644 index 0000000000..0fbdcd29e8 --- /dev/null +++ b/doc/man/enum nvme_directive_send_doper.2 @@ -0,0 +1,24 @@ +.TH "libnvme" 2 "enum nvme_directive_send_doper" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_directive_send_doper \- +.SH SYNOPSIS +enum nvme_directive_send_doper { +.br +.BI " NVME_DIRECTIVE_SEND_IDENTIFY_DOPER_ENDIR" +, +.br +.br +.BI " NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_IDENTIFIER" +, +.br +.br +.BI " NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE" + +}; +.SH Constants +.IP "NVME_DIRECTIVE_SEND_IDENTIFY_DOPER_ENDIR" 12 +-- undescribed -- +.IP "NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_IDENTIFIER" 12 +-- undescribed -- +.IP "NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_directive_send_identify_endir.2 b/doc/man/enum nvme_directive_send_identify_endir.2 new file mode 100644 index 0000000000..22d4cef68f --- /dev/null +++ b/doc/man/enum nvme_directive_send_identify_endir.2 @@ -0,0 +1,18 @@ +.TH "libnvme" 2 "enum nvme_directive_send_identify_endir" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_directive_send_identify_endir \- +.SH SYNOPSIS +enum nvme_directive_send_identify_endir { +.br +.BI " NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_DISABLE" +, +.br +.br +.BI " NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_ENABLE" + +}; +.SH Constants +.IP "NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_DISABLE" 12 +-- undescribed -- +.IP "NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_ENABLE" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_dsm_attributes.2 b/doc/man/enum nvme_dsm_attributes.2 new file mode 100644 index 0000000000..747db904d7 --- /dev/null +++ b/doc/man/enum nvme_dsm_attributes.2 @@ -0,0 +1,24 @@ +.TH "libnvme" 2 "enum nvme_dsm_attributes" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_dsm_attributes \- +.SH SYNOPSIS +enum nvme_dsm_attributes { +.br +.BI " NVME_DSMGMT_IDR" +, +.br +.br +.BI " NVME_DSMGMT_IDW" +, +.br +.br +.BI " NVME_DSMGMT_AD" + +}; +.SH Constants +.IP "NVME_DSMGMT_IDR" 12 +-- undescribed -- +.IP "NVME_DSMGMT_IDW" 12 +-- undescribed -- +.IP "NVME_DSMGMT_AD" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_dst_stc.2 b/doc/man/enum nvme_dst_stc.2 new file mode 100644 index 0000000000..1058069533 --- /dev/null +++ b/doc/man/enum nvme_dst_stc.2 @@ -0,0 +1,30 @@ +.TH "libnvme" 2 "enum nvme_dst_stc" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_dst_stc \- +.SH SYNOPSIS +enum nvme_dst_stc { +.br +.BI " NVME_DST_STC_SHORT" +, +.br +.br +.BI " NVME_DST_STC_LONG" +, +.br +.br +.BI " NVME_DST_STC_VS" +, +.br +.br +.BI " NVME_DST_STC_ABORT" + +}; +.SH Constants +.IP "NVME_DST_STC_SHORT" 12 +-- undescribed -- +.IP "NVME_DST_STC_LONG" 12 +-- undescribed -- +.IP "NVME_DST_STC_VS" 12 +-- undescribed -- +.IP "NVME_DST_STC_ABORT" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_eg_critical_warning_flags.2 b/doc/man/enum nvme_eg_critical_warning_flags.2 new file mode 100644 index 0000000000..d1ed9686ab --- /dev/null +++ b/doc/man/enum nvme_eg_critical_warning_flags.2 @@ -0,0 +1,24 @@ +.TH "libnvme" 2 "enum nvme_eg_critical_warning_flags" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_eg_critical_warning_flags \- +.SH SYNOPSIS +enum nvme_eg_critical_warning_flags { +.br +.BI " NVME_EG_CRITICAL_WARNING_SPARE" +, +.br +.br +.BI " NVME_EG_CRITICAL_WARNING_DEGRADED" +, +.br +.br +.BI " NVME_EG_CRITICAL_WARNING_READ_ONLY" + +}; +.SH Constants +.IP "NVME_EG_CRITICAL_WARNING_SPARE" 12 +-- undescribed -- +.IP "NVME_EG_CRITICAL_WARNING_DEGRADED" 12 +-- undescribed -- +.IP "NVME_EG_CRITICAL_WARNING_READ_ONLY" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_fctype.2 b/doc/man/enum nvme_fctype.2 new file mode 100644 index 0000000000..9a7fa6a0d7 --- /dev/null +++ b/doc/man/enum nvme_fctype.2 @@ -0,0 +1,42 @@ +.TH "libnvme" 2 "enum nvme_fctype" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_fctype \- +.SH SYNOPSIS +enum nvme_fctype { +.br +.BI " nvme_fabrics_type_property_set" +, +.br +.br +.BI " nvme_fabrics_type_connect" +, +.br +.br +.BI " nvme_fabrics_type_property_get" +, +.br +.br +.BI " nvme_fabrics_type_auth_send" +, +.br +.br +.BI " nvme_fabrics_type_auth_receive" +, +.br +.br +.BI " nvme_fabrics_type_disconnect" + +}; +.SH Constants +.IP "nvme_fabrics_type_property_set" 12 +-- undescribed -- +.IP "nvme_fabrics_type_connect" 12 +-- undescribed -- +.IP "nvme_fabrics_type_property_get" 12 +-- undescribed -- +.IP "nvme_fabrics_type_auth_send" 12 +-- undescribed -- +.IP "nvme_fabrics_type_auth_receive" 12 +-- undescribed -- +.IP "nvme_fabrics_type_disconnect" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_feat_nswpcfg_state.2 b/doc/man/enum nvme_feat_nswpcfg_state.2 new file mode 100644 index 0000000000..0d9961811b --- /dev/null +++ b/doc/man/enum nvme_feat_nswpcfg_state.2 @@ -0,0 +1,30 @@ +.TH "libnvme" 2 "enum nvme_feat_nswpcfg_state" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_feat_nswpcfg_state \- +.SH SYNOPSIS +enum nvme_feat_nswpcfg_state { +.br +.BI " NVME_FEAT_NS_NO_WRITE_PROTECT" +, +.br +.br +.BI " NVME_FEAT_NS_WRITE_PROTECT" +, +.br +.br +.BI " NVME_FEAT_NS_WRITE_PROTECT_PWR_CYCLE" +, +.br +.br +.BI " NVME_FEAT_NS_WRITE_PROTECT_PERMANENT" + +}; +.SH Constants +.IP "NVME_FEAT_NS_NO_WRITE_PROTECT" 12 +-- undescribed -- +.IP "NVME_FEAT_NS_WRITE_PROTECT" 12 +-- undescribed -- +.IP "NVME_FEAT_NS_WRITE_PROTECT_PWR_CYCLE" 12 +-- undescribed -- +.IP "NVME_FEAT_NS_WRITE_PROTECT_PERMANENT" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_feat_plm_window_select.2 b/doc/man/enum nvme_feat_plm_window_select.2 new file mode 100644 index 0000000000..cc210c92f7 --- /dev/null +++ b/doc/man/enum nvme_feat_plm_window_select.2 @@ -0,0 +1,18 @@ +.TH "libnvme" 2 "enum nvme_feat_plm_window_select" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_feat_plm_window_select \- +.SH SYNOPSIS +enum nvme_feat_plm_window_select { +.br +.BI " NVME_FEATURE_PLM_DTWIN" +, +.br +.br +.BI " NVME_FEATURE_PLM_NDWIN" + +}; +.SH Constants +.IP "NVME_FEATURE_PLM_DTWIN" 12 +-- undescribed -- +.IP "NVME_FEATURE_PLM_NDWIN" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_feat_tmpthresh_thsel.2 b/doc/man/enum nvme_feat_tmpthresh_thsel.2 new file mode 100644 index 0000000000..305c8a0075 --- /dev/null +++ b/doc/man/enum nvme_feat_tmpthresh_thsel.2 @@ -0,0 +1,18 @@ +.TH "libnvme" 2 "enum nvme_feat_tmpthresh_thsel" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_feat_tmpthresh_thsel \- +.SH SYNOPSIS +enum nvme_feat_tmpthresh_thsel { +.br +.BI " NVME_FEATURE_TEMPTHRESH_THSEL_OVER" +, +.br +.br +.BI " NVME_FEATURETEMPTHRESH__THSEL_UNDER" + +}; +.SH Constants +.IP "NVME_FEATURE_TEMPTHRESH_THSEL_OVER" 12 +-- undescribed -- +.IP "NVME_FEATURETEMPTHRESH__THSEL_UNDER" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_features_async_event_config_flags.2 b/doc/man/enum nvme_features_async_event_config_flags.2 new file mode 100644 index 0000000000..9f1dd9d0d3 --- /dev/null +++ b/doc/man/enum nvme_features_async_event_config_flags.2 @@ -0,0 +1,90 @@ +.TH "libnvme" 2 "enum nvme_features_async_event_config_flags" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_features_async_event_config_flags \- +.SH SYNOPSIS +enum nvme_features_async_event_config_flags { +.br +.BI " NVME_FEATURE_AENCFG_SMART_CRIT_SPARE" +, +.br +.br +.BI " NVME_FEATURE_AENCFG_SMART_CRIT_TEMPERATURE" +, +.br +.br +.BI " NVME_FEATURE_AENCFG_SMART_CRIT_DEGRADED" +, +.br +.br +.BI " NVME_FEATURE_AENCFG_SMART_CRIT_READ_ONLY" +, +.br +.br +.BI " NVME_FEATURE_AENCFG_SMART_CRIT_VOLATILE_BACKUP" +, +.br +.br +.BI " NVME_FEATURE_AENCFG_SMART_CRIT_READ_ONLY_PMR" +, +.br +.br +.BI " NVME_FEATURE_AENCFG_NOTICE_NAMESPACE_ATTRIBUTES" +, +.br +.br +.BI " NVME_FEATURE_AENCFG_NOTICE_FIRMWARE_ACTIVATION" +, +.br +.br +.BI " NVME_FEATURE_AENCFG_NOTICE_TELEMETRY_LOG" +, +.br +.br +.BI " NVME_FEATURE_AENCFG_NOTICE_ANA_CHANGE" +, +.br +.br +.BI " NVME_FEATURE_AENCFG_NOTICE_PL_EVENT" +, +.br +.br +.BI " NVME_FEATURE_AENCFG_NOTICE_LBA_STATUS" +, +.br +.br +.BI " NVME_FEATURE_AENCFG_NOTICE_EG_EVENT" +, +.br +.br +.BI " NVME_FEATURE_AENCFG_NOTICE_DISCOVERY_CHANGE" + +}; +.SH Constants +.IP "NVME_FEATURE_AENCFG_SMART_CRIT_SPARE" 12 +-- undescribed -- +.IP "NVME_FEATURE_AENCFG_SMART_CRIT_TEMPERATURE" 12 +-- undescribed -- +.IP "NVME_FEATURE_AENCFG_SMART_CRIT_DEGRADED" 12 +-- undescribed -- +.IP "NVME_FEATURE_AENCFG_SMART_CRIT_READ_ONLY" 12 +-- undescribed -- +.IP "NVME_FEATURE_AENCFG_SMART_CRIT_VOLATILE_BACKUP" 12 +-- undescribed -- +.IP "NVME_FEATURE_AENCFG_SMART_CRIT_READ_ONLY_PMR" 12 +-- undescribed -- +.IP "NVME_FEATURE_AENCFG_NOTICE_NAMESPACE_ATTRIBUTES" 12 +-- undescribed -- +.IP "NVME_FEATURE_AENCFG_NOTICE_FIRMWARE_ACTIVATION" 12 +-- undescribed -- +.IP "NVME_FEATURE_AENCFG_NOTICE_TELEMETRY_LOG" 12 +-- undescribed -- +.IP "NVME_FEATURE_AENCFG_NOTICE_ANA_CHANGE" 12 +-- undescribed -- +.IP "NVME_FEATURE_AENCFG_NOTICE_PL_EVENT" 12 +-- undescribed -- +.IP "NVME_FEATURE_AENCFG_NOTICE_LBA_STATUS" 12 +-- undescribed -- +.IP "NVME_FEATURE_AENCFG_NOTICE_EG_EVENT" 12 +-- undescribed -- +.IP "NVME_FEATURE_AENCFG_NOTICE_DISCOVERY_CHANGE" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_features_id.2 b/doc/man/enum nvme_features_id.2 new file mode 100644 index 0000000000..36b33148f6 --- /dev/null +++ b/doc/man/enum nvme_features_id.2 @@ -0,0 +1,180 @@ +.TH "libnvme" 2 "enum nvme_features_id" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_features_id \- +.SH SYNOPSIS +enum nvme_features_id { +.br +.BI " NVME_FEAT_FID_ARBITRATION" +, +.br +.br +.BI " NVME_FEAT_FID_POWER_MGMT" +, +.br +.br +.BI " NVME_FEAT_FID_LBA_RANGE" +, +.br +.br +.BI " NVME_FEAT_FID_TEMP_THRESH" +, +.br +.br +.BI " NVME_FEAT_FID_ERR_RECOVERY" +, +.br +.br +.BI " NVME_FEAT_FID_VOLATILE_WC" +, +.br +.br +.BI " NVME_FEAT_FID_NUM_QUEUES" +, +.br +.br +.BI " NVME_FEAT_FID_IRQ_COALESCE" +, +.br +.br +.BI " NVME_FEAT_FID_IRQ_CONFIG" +, +.br +.br +.BI " NVME_FEAT_FID_WRITE_ATOMIC" +, +.br +.br +.BI " NVME_FEAT_FID_ASYNC_EVENT" +, +.br +.br +.BI " NVME_FEAT_FID_AUTO_PST" +, +.br +.br +.BI " NVME_FEAT_FID_HOST_MEM_BUF" +, +.br +.br +.BI " NVME_FEAT_FID_TIMESTAMP" +, +.br +.br +.BI " NVME_FEAT_FID_KATO" +, +.br +.br +.BI " NVME_FEAT_FID_HCTM" +, +.br +.br +.BI " NVME_FEAT_FID_NOPSC" +, +.br +.br +.BI " NVME_FEAT_FID_RRL" +, +.br +.br +.BI " NVME_FEAT_FID_PLM_CONFIG" +, +.br +.br +.BI " NVME_FEAT_FID_PLM_WINDOW" +, +.br +.br +.BI " NVME_FEAT_FID_LBA_STS_INTERVAL" +, +.br +.br +.BI " NVME_FEAT_FID_HOST_BEHAVIOR" +, +.br +.br +.BI " NVME_FEAT_FID_SANITIZE" +, +.br +.br +.BI " NVME_FEAT_FID_ENDURANCE_EVT_CFG" +, +.br +.br +.BI " NVME_FEAT_FID_SW_PROGRESS" +, +.br +.br +.BI " NVME_FEAT_FID_HOST_ID" +, +.br +.br +.BI " NVME_FEAT_FID_RESV_MASK" +, +.br +.br +.BI " NVME_FEAT_RESV_PERSIST" +, +.br +.br +.BI " NVME_FEAT_FID_WRITE_PROTECT" + +}; +.SH Constants +.IP "NVME_FEAT_FID_ARBITRATION" 12 +-- undescribed -- +.IP "NVME_FEAT_FID_POWER_MGMT" 12 +-- undescribed -- +.IP "NVME_FEAT_FID_LBA_RANGE" 12 +-- undescribed -- +.IP "NVME_FEAT_FID_TEMP_THRESH" 12 +-- undescribed -- +.IP "NVME_FEAT_FID_ERR_RECOVERY" 12 +-- undescribed -- +.IP "NVME_FEAT_FID_VOLATILE_WC" 12 +-- undescribed -- +.IP "NVME_FEAT_FID_NUM_QUEUES" 12 +-- undescribed -- +.IP "NVME_FEAT_FID_IRQ_COALESCE" 12 +-- undescribed -- +.IP "NVME_FEAT_FID_IRQ_CONFIG" 12 +-- undescribed -- +.IP "NVME_FEAT_FID_WRITE_ATOMIC" 12 +-- undescribed -- +.IP "NVME_FEAT_FID_ASYNC_EVENT" 12 +-- undescribed -- +.IP "NVME_FEAT_FID_AUTO_PST" 12 +-- undescribed -- +.IP "NVME_FEAT_FID_HOST_MEM_BUF" 12 +-- undescribed -- +.IP "NVME_FEAT_FID_TIMESTAMP" 12 +-- undescribed -- +.IP "NVME_FEAT_FID_KATO" 12 +-- undescribed -- +.IP "NVME_FEAT_FID_HCTM" 12 +-- undescribed -- +.IP "NVME_FEAT_FID_NOPSC" 12 +-- undescribed -- +.IP "NVME_FEAT_FID_RRL" 12 +-- undescribed -- +.IP "NVME_FEAT_FID_PLM_CONFIG" 12 +-- undescribed -- +.IP "NVME_FEAT_FID_PLM_WINDOW" 12 +-- undescribed -- +.IP "NVME_FEAT_FID_LBA_STS_INTERVAL" 12 +-- undescribed -- +.IP "NVME_FEAT_FID_HOST_BEHAVIOR" 12 +-- undescribed -- +.IP "NVME_FEAT_FID_SANITIZE" 12 +-- undescribed -- +.IP "NVME_FEAT_FID_ENDURANCE_EVT_CFG" 12 +-- undescribed -- +.IP "NVME_FEAT_FID_SW_PROGRESS" 12 +-- undescribed -- +.IP "NVME_FEAT_FID_HOST_ID" 12 +-- undescribed -- +.IP "NVME_FEAT_FID_RESV_MASK" 12 +-- undescribed -- +.IP "NVME_FEAT_RESV_PERSIST" 12 +-- undescribed -- +.IP "NVME_FEAT_FID_WRITE_PROTECT" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_fw_commit_ca.2 b/doc/man/enum nvme_fw_commit_ca.2 new file mode 100644 index 0000000000..46cdd7f4e9 --- /dev/null +++ b/doc/man/enum nvme_fw_commit_ca.2 @@ -0,0 +1,42 @@ +.TH "libnvme" 2 "enum nvme_fw_commit_ca" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_fw_commit_ca \- +.SH SYNOPSIS +enum nvme_fw_commit_ca { +.br +.BI " NVME_FW_COMMIT_CA_REPLACE" +, +.br +.br +.BI " NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE" +, +.br +.br +.BI " NVME_FW_COMMIT_CA_SET_ACTIVE" +, +.br +.br +.BI " NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE_IMMEDIATE" +, +.br +.br +.BI " NVME_FW_COMMIT_CA_REPLACE_BOOT_PARTITION" +, +.br +.br +.BI " NVME_FW_COMMIT_CA_ACTIVATE_BOOT_PARTITION" + +}; +.SH Constants +.IP "NVME_FW_COMMIT_CA_REPLACE" 12 +-- undescribed -- +.IP "NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE" 12 +-- undescribed -- +.IP "NVME_FW_COMMIT_CA_SET_ACTIVE" 12 +-- undescribed -- +.IP "NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE_IMMEDIATE" 12 +-- undescribed -- +.IP "NVME_FW_COMMIT_CA_REPLACE_BOOT_PARTITION" 12 +-- undescribed -- +.IP "NVME_FW_COMMIT_CA_ACTIVATE_BOOT_PARTITION" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_get_features_sel.2 b/doc/man/enum nvme_get_features_sel.2 new file mode 100644 index 0000000000..99b6496874 --- /dev/null +++ b/doc/man/enum nvme_get_features_sel.2 @@ -0,0 +1,24 @@ +.TH "libnvme" 2 "enum nvme_get_features_sel" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_get_features_sel \- +.SH SYNOPSIS +enum nvme_get_features_sel { +.br +.BI " NVME_GET_FEATURES_SEL_CURRENT" +, +.br +.br +.BI " NVME_GET_FEATURES_SEL_DEFAULT" +, +.br +.br +.BI " NVME_GET_FEATURES_SEL_SAVED" + +}; +.SH Constants +.IP "NVME_GET_FEATURES_SEL_CURRENT" 12 +-- undescribed -- +.IP "NVME_GET_FEATURES_SEL_DEFAULT" 12 +-- undescribed -- +.IP "NVME_GET_FEATURES_SEL_SAVED" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_id_ctrl_anacap.2 b/doc/man/enum nvme_id_ctrl_anacap.2 new file mode 100644 index 0000000000..8ff1515fde --- /dev/null +++ b/doc/man/enum nvme_id_ctrl_anacap.2 @@ -0,0 +1,59 @@ +.TH "libnvme" 2 "enum nvme_id_ctrl_anacap" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_id_ctrl_anacap \- This field indicates the capabilities associated with Asymmetric Namespace Access Reporting. +.SH SYNOPSIS +enum nvme_id_ctrl_anacap { +.br +.BI " NVME_CTRL_ANACAP_OPT" +, +.br +.br +.BI " NVME_CTRL_ANACAP_NON_OPT" +, +.br +.br +.BI " NVME_CTRL_ANACAP_INACCESSIBLE" +, +.br +.br +.BI " NVME_CTRL_ANACAP_PERSISTENT_LOSS" +, +.br +.br +.BI " NVME_CTRL_ANACAP_CHANGE" +, +.br +.br +.BI " NVME_CTRL_ANACAP_GRPID_NO_CHG" +, +.br +.br +.BI " NVME_CTRL_ANACAP_GRPID_MGMT" + +}; +.SH Constants +.IP "NVME_CTRL_ANACAP_OPT" 12 +If set, then the controller is able to +report ANA Optimized state. +.IP "NVME_CTRL_ANACAP_NON_OPT" 12 +If set, then the controller is able to +report ANA Non-Optimized state. +.IP "NVME_CTRL_ANACAP_INACCESSIBLE" 12 +If set, then the controller is able to +report ANA Inaccessible state. +.IP "NVME_CTRL_ANACAP_PERSISTENT_LOSS" 12 +If set, then the controller is able to +report ANA Persistent Loss state. +.IP "NVME_CTRL_ANACAP_CHANGE" 12 +If set, then the controller is able to +report ANA Change state. +.IP "NVME_CTRL_ANACAP_GRPID_NO_CHG" 12 +If set, then the ANAGRPID field in the +Identify Namespace data structure +(\fIstruct nvme_id_ns\fP.anagrpid), does not +change while the namespace is attached to +any controller. +.IP "NVME_CTRL_ANACAP_GRPID_MGMT" 12 +If set, then the controller supports a +non-zero value in the ANAGRPID field of +the Namespace Management command. diff --git a/doc/man/enum nvme_id_ctrl_apsta.2 b/doc/man/enum nvme_id_ctrl_apsta.2 new file mode 100644 index 0000000000..a446ecd395 --- /dev/null +++ b/doc/man/enum nvme_id_ctrl_apsta.2 @@ -0,0 +1,13 @@ +.TH "libnvme" 2 "enum nvme_id_ctrl_apsta" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_id_ctrl_apsta \- Flags indicating the attributes of the autonomous power state transition feature. +.SH SYNOPSIS +enum nvme_id_ctrl_apsta { +.br +.BI " NVME_CTRL_APSTA_APST" + +}; +.SH Constants +.IP "NVME_CTRL_APSTA_APST" 12 +If set, then the controller supports autonomous power +state transitions. diff --git a/doc/man/enum nvme_id_ctrl_avscc.2 b/doc/man/enum nvme_id_ctrl_avscc.2 new file mode 100644 index 0000000000..dce414b8b1 --- /dev/null +++ b/doc/man/enum nvme_id_ctrl_avscc.2 @@ -0,0 +1,14 @@ +.TH "libnvme" 2 "enum nvme_id_ctrl_avscc" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_id_ctrl_avscc \- Flags indicating the configuration settings for Admin Vendor Specific command handling. +.SH SYNOPSIS +enum nvme_id_ctrl_avscc { +.br +.BI " NVME_CTRL_AVSCC_AVS" + +}; +.SH Constants +.IP "NVME_CTRL_AVSCC_AVS" 12 +If set, all Admin Vendor Specific Commands use the +optional vendor specific command format with NDT and +NDM fields. diff --git a/doc/man/enum nvme_id_ctrl_cmic.2 b/doc/man/enum nvme_id_ctrl_cmic.2 new file mode 100644 index 0000000000..76a22eb801 --- /dev/null +++ b/doc/man/enum nvme_id_ctrl_cmic.2 @@ -0,0 +1,30 @@ +.TH "libnvme" 2 "enum nvme_id_ctrl_cmic" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_id_ctrl_cmic \- +.SH SYNOPSIS +enum nvme_id_ctrl_cmic { +.br +.BI " NVME_CTRL_CMIC_MULTI_PORT" +, +.br +.br +.BI " NVME_CTRL_CMIC_MULTI_CTRL" +, +.br +.br +.BI " NVME_CTRL_CMIC_MULTI_SRIOV" +, +.br +.br +.BI " NVME_CTRL_CMIC_MULTI_ANA_REPORTING" + +}; +.SH Constants +.IP "NVME_CTRL_CMIC_MULTI_PORT" 12 +-- undescribed -- +.IP "NVME_CTRL_CMIC_MULTI_CTRL" 12 +-- undescribed -- +.IP "NVME_CTRL_CMIC_MULTI_SRIOV" 12 +-- undescribed -- +.IP "NVME_CTRL_CMIC_MULTI_ANA_REPORTING" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_id_ctrl_cntrltype.2 b/doc/man/enum nvme_id_ctrl_cntrltype.2 new file mode 100644 index 0000000000..34f7d1dea6 --- /dev/null +++ b/doc/man/enum nvme_id_ctrl_cntrltype.2 @@ -0,0 +1,24 @@ +.TH "libnvme" 2 "enum nvme_id_ctrl_cntrltype" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_id_ctrl_cntrltype \- +.SH SYNOPSIS +enum nvme_id_ctrl_cntrltype { +.br +.BI " NVME_CTRL_CNTRLTYPE_IO" +, +.br +.br +.BI " NVME_CTRL_CNTRLTYPE_DISCOVERY" +, +.br +.br +.BI " NVME_CTRL_CNTRLTYPE_ADMIN" + +}; +.SH Constants +.IP "NVME_CTRL_CNTRLTYPE_IO" 12 +-- undescribed -- +.IP "NVME_CTRL_CNTRLTYPE_DISCOVERY" 12 +-- undescribed -- +.IP "NVME_CTRL_CNTRLTYPE_ADMIN" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_id_ctrl_ctratt.2 b/doc/man/enum nvme_id_ctrl_ctratt.2 new file mode 100644 index 0000000000..76fde98d92 --- /dev/null +++ b/doc/man/enum nvme_id_ctrl_ctratt.2 @@ -0,0 +1,66 @@ +.TH "libnvme" 2 "enum nvme_id_ctrl_ctratt" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_id_ctrl_ctratt \- +.SH SYNOPSIS +enum nvme_id_ctrl_ctratt { +.br +.BI " NVME_CTRL_CTRATT_128_ID" +, +.br +.br +.BI " NVME_CTRL_CTRATT_NON_OP_PSP" +, +.br +.br +.BI " NVME_CTRL_CTRATT_NVM_SETS" +, +.br +.br +.BI " NVME_CTRL_CTRATT_READ_RECV_LVLS" +, +.br +.br +.BI " NVME_CTRL_CTRATT_ENDURANCE_GROUPS" +, +.br +.br +.BI " NVME_CTRL_CTRATT_PREDICTABLE_LAT" +, +.br +.br +.BI " NVME_CTRL_CTRATT_TBKAS" +, +.br +.br +.BI " NVME_CTRL_CTRATT_NAMESPACE_GRANULARITY" +, +.br +.br +.BI " NVME_CTRL_CTRATT_SQ_ASSOCIATIONS" +, +.br +.br +.BI " NVME_CTRL_CTRATT_UUID_LIST" + +}; +.SH Constants +.IP "NVME_CTRL_CTRATT_128_ID" 12 +-- undescribed -- +.IP "NVME_CTRL_CTRATT_NON_OP_PSP" 12 +-- undescribed -- +.IP "NVME_CTRL_CTRATT_NVM_SETS" 12 +-- undescribed -- +.IP "NVME_CTRL_CTRATT_READ_RECV_LVLS" 12 +-- undescribed -- +.IP "NVME_CTRL_CTRATT_ENDURANCE_GROUPS" 12 +-- undescribed -- +.IP "NVME_CTRL_CTRATT_PREDICTABLE_LAT" 12 +-- undescribed -- +.IP "NVME_CTRL_CTRATT_TBKAS" 12 +-- undescribed -- +.IP "NVME_CTRL_CTRATT_NAMESPACE_GRANULARITY" 12 +-- undescribed -- +.IP "NVME_CTRL_CTRATT_SQ_ASSOCIATIONS" 12 +-- undescribed -- +.IP "NVME_CTRL_CTRATT_UUID_LIST" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_id_ctrl_dsto.2 b/doc/man/enum nvme_id_ctrl_dsto.2 new file mode 100644 index 0000000000..7311a1909c --- /dev/null +++ b/doc/man/enum nvme_id_ctrl_dsto.2 @@ -0,0 +1,13 @@ +.TH "libnvme" 2 "enum nvme_id_ctrl_dsto" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_id_ctrl_dsto \- Flags indicating the optional Device Self-test command or operation behaviors supported by the controller or NVM subsystem. +.SH SYNOPSIS +enum nvme_id_ctrl_dsto { +.br +.BI " NVME_CTRL_DSTO_ONE_DST" + +}; +.SH Constants +.IP "NVME_CTRL_DSTO_ONE_DST" 12 +If set, then the NVM subsystem supports only one +device self-test operation in progress at a time. diff --git a/doc/man/enum nvme_id_ctrl_fcatt.2 b/doc/man/enum nvme_id_ctrl_fcatt.2 new file mode 100644 index 0000000000..c11ab21f60 --- /dev/null +++ b/doc/man/enum nvme_id_ctrl_fcatt.2 @@ -0,0 +1,14 @@ +.TH "libnvme" 2 "enum nvme_id_ctrl_fcatt" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_id_ctrl_fcatt \- This field indicates attributes of the controller that are specific to NVMe over Fabrics. +.SH SYNOPSIS +enum nvme_id_ctrl_fcatt { +.br +.BI " NVME_CTRL_FCATT_DYNAMIC" + +}; +.SH Constants +.IP "NVME_CTRL_FCATT_DYNAMIC" 12 +If cleared, then the NVM subsystem uses a dynamic +controller model. If set, then the NVM subsystem +uses a static controller model. diff --git a/doc/man/enum nvme_id_ctrl_fna.2 b/doc/man/enum nvme_id_ctrl_fna.2 new file mode 100644 index 0000000000..cb0c0a9883 --- /dev/null +++ b/doc/man/enum nvme_id_ctrl_fna.2 @@ -0,0 +1,39 @@ +.TH "libnvme" 2 "enum nvme_id_ctrl_fna" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_id_ctrl_fna \- This field indicates attributes for the Format NVM command. +.SH SYNOPSIS +enum nvme_id_ctrl_fna { +.br +.BI " NVME_CTRL_FNA_FMT_ALL_NAMESPACES" +, +.br +.br +.BI " NVME_CTRL_FNA_SEC_ALL_NAMESPACES" +, +.br +.br +.BI " NVME_CTRL_FNA_CRYPTO_ERASE" + +}; +.SH Constants +.IP "NVME_CTRL_FNA_FMT_ALL_NAMESPACES" 12 +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. +.IP "NVME_CTRL_FNA_SEC_ALL_NAMESPACES" 12 +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. +.IP "NVME_CTRL_FNA_CRYPTO_ERASE" 12 +If set, then cryptographic erase is +supported. If cleared, then cryptographic +erase is not supported. diff --git a/doc/man/enum nvme_id_ctrl_frmw.2 b/doc/man/enum nvme_id_ctrl_frmw.2 new file mode 100644 index 0000000000..40611e652f --- /dev/null +++ b/doc/man/enum nvme_id_ctrl_frmw.2 @@ -0,0 +1,26 @@ +.TH "libnvme" 2 "enum nvme_id_ctrl_frmw" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_id_ctrl_frmw \- Flags and values indicates capabilities regarding firmware updates from &struct nvme_id_ctrl.frmw. +.SH SYNOPSIS +enum nvme_id_ctrl_frmw { +.br +.BI " NVME_CTRL_FRMW_1ST_RO" +, +.br +.br +.BI " NVME_CTRL_FRMW_NR_SLOTS" +, +.br +.br +.BI " NVME_CTRL_FRMW_FW_ACT_NO_RESET" + +}; +.SH Constants +.IP "NVME_CTRL_FRMW_1ST_RO" 12 +If set, the first firmware slot is readonly +.IP "NVME_CTRL_FRMW_NR_SLOTS" 12 +Mask to get the value of the number of +firmware slots that the controller supports. +.IP "NVME_CTRL_FRMW_FW_ACT_NO_RESET" 12 +If set, the controller supports firmware +activation without a reset. diff --git a/doc/man/enum nvme_id_ctrl_fuses.2 b/doc/man/enum nvme_id_ctrl_fuses.2 new file mode 100644 index 0000000000..dbdaddf5ec --- /dev/null +++ b/doc/man/enum nvme_id_ctrl_fuses.2 @@ -0,0 +1,13 @@ +.TH "libnvme" 2 "enum nvme_id_ctrl_fuses" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_id_ctrl_fuses \- This field indicates the fused operations that the controller supports. +.SH SYNOPSIS +enum nvme_id_ctrl_fuses { +.br +.BI " NVME_CTRL_FUSES_COMPARE_AND_WRITE" + +}; +.SH Constants +.IP "NVME_CTRL_FUSES_COMPARE_AND_WRITE" 12 +If set, then the controller supports the +Compare and Write fused operation. diff --git a/doc/man/enum nvme_id_ctrl_hctm.2 b/doc/man/enum nvme_id_ctrl_hctm.2 new file mode 100644 index 0000000000..0e2d3e6db4 --- /dev/null +++ b/doc/man/enum nvme_id_ctrl_hctm.2 @@ -0,0 +1,15 @@ +.TH "libnvme" 2 "enum nvme_id_ctrl_hctm" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_id_ctrl_hctm \- Flags indicate the attributes of the host controlled thermal management feature +.SH SYNOPSIS +enum nvme_id_ctrl_hctm { +.br +.BI " NVME_CTRL_HCTMA_HCTM" + +}; +.SH Constants +.IP "NVME_CTRL_HCTMA_HCTM" 12 +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. diff --git a/doc/man/enum nvme_id_ctrl_lpa.2 b/doc/man/enum nvme_id_ctrl_lpa.2 new file mode 100644 index 0000000000..ada9b2b1e5 --- /dev/null +++ b/doc/man/enum nvme_id_ctrl_lpa.2 @@ -0,0 +1,36 @@ +.TH "libnvme" 2 "enum nvme_id_ctrl_lpa" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_id_ctrl_lpa \- Flags indicating optional attributes for log pages that are accessed via the Get Log Page command. +.SH SYNOPSIS +enum nvme_id_ctrl_lpa { +.br +.BI " NVME_CTRL_LPA_SMART_PER_NS" +, +.br +.br +.BI " NVME_CTRL_LPA_CMD_EFFECTS" +, +.br +.br +.BI " NVME_CTRL_LPA_EXTENDED" +, +.br +.br +.BI " NVME_CTRL_LPA_TELEMETRY" +, +.br +.br +.BI " NVME_CTRL_LPA_PERSETENT_EVENT" + +}; +.SH Constants +.IP "NVME_CTRL_LPA_SMART_PER_NS" 12 +-- undescribed -- +.IP "NVME_CTRL_LPA_CMD_EFFECTS" 12 +-- undescribed -- +.IP "NVME_CTRL_LPA_EXTENDED" 12 +-- undescribed -- +.IP "NVME_CTRL_LPA_TELEMETRY" 12 +-- undescribed -- +.IP "NVME_CTRL_LPA_PERSETENT_EVENT" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_id_ctrl_mec.2 b/doc/man/enum nvme_id_ctrl_mec.2 new file mode 100644 index 0000000000..d530757f86 --- /dev/null +++ b/doc/man/enum nvme_id_ctrl_mec.2 @@ -0,0 +1,20 @@ +.TH "libnvme" 2 "enum nvme_id_ctrl_mec" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_id_ctrl_mec \- Flags indicatings the capabilities of the Management Endpoint in the Controller, &struct nvme_id_ctrl.mec. +.SH SYNOPSIS +enum nvme_id_ctrl_mec { +.br +.BI " NVME_CTRL_MEC_SMBUSME" +, +.br +.br +.BI " NVME_CTRL_MEC_PCIEME" + +}; +.SH Constants +.IP "NVME_CTRL_MEC_SMBUSME" 12 +If set, then the NVM Subsystem contains a Management +Endpoint on an SMBus/I2C port. +.IP "NVME_CTRL_MEC_PCIEME" 12 +If set, then the NVM Subsystem contains a Management +Endpoint on a PCIe port. diff --git a/doc/man/enum nvme_id_ctrl_nvmsr.2 b/doc/man/enum nvme_id_ctrl_nvmsr.2 new file mode 100644 index 0000000000..b8e1a21625 --- /dev/null +++ b/doc/man/enum nvme_id_ctrl_nvmsr.2 @@ -0,0 +1,22 @@ +.TH "libnvme" 2 "enum nvme_id_ctrl_nvmsr" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_id_ctrl_nvmsr \- This field reports information associated with the NVM Subsystem, see &struct nvme_id_ctrl.nvmsr. +.SH SYNOPSIS +enum nvme_id_ctrl_nvmsr { +.br +.BI " NVME_CTRL_NVMSR_NVMESD" +, +.br +.br +.BI " NVME_CTRL_NVMSR_NVMEE" + +}; +.SH Constants +.IP "NVME_CTRL_NVMSR_NVMESD" 12 +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. +.IP "NVME_CTRL_NVMSR_NVMEE" 12 +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. diff --git a/doc/man/enum nvme_id_ctrl_nvscc.2 b/doc/man/enum nvme_id_ctrl_nvscc.2 new file mode 100644 index 0000000000..2dc529b094 --- /dev/null +++ b/doc/man/enum nvme_id_ctrl_nvscc.2 @@ -0,0 +1,13 @@ +.TH "libnvme" 2 "enum nvme_id_ctrl_nvscc" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_id_ctrl_nvscc \- This field indicates the configuration settings for NVM Vendor Specific command handling. +.SH SYNOPSIS +enum nvme_id_ctrl_nvscc { +.br +.BI " NVME_CTRL_NVSCC_FMT" + +}; +.SH Constants +.IP "NVME_CTRL_NVSCC_FMT" 12 +If set, all NVM Vendor Specific Commands use the +format format with NDT and NDM fields. diff --git a/doc/man/enum nvme_id_ctrl_nwpc.2 b/doc/man/enum nvme_id_ctrl_nwpc.2 new file mode 100644 index 0000000000..d7a82c55a4 --- /dev/null +++ b/doc/man/enum nvme_id_ctrl_nwpc.2 @@ -0,0 +1,35 @@ +.TH "libnvme" 2 "enum nvme_id_ctrl_nwpc" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_id_ctrl_nwpc \- This field indicates the optional namespace write protection capabilities supported by the controller. +.SH SYNOPSIS +enum nvme_id_ctrl_nwpc { +.br +.BI " NVME_CTRL_NWPC_WRITE_PROTECT" +, +.br +.br +.BI " NVME_CTRL_NWPC_WRITE_PROTECT_POWER_CYCLE" +, +.br +.br +.BI " NVME_CTRL_NWPC_WRITE_PROTECT_PERMANENT" + +}; +.SH Constants +.IP "NVME_CTRL_NWPC_WRITE_PROTECT" 12 +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. +.IP "NVME_CTRL_NWPC_WRITE_PROTECT_POWER_CYCLE" 12 +If set, then the controller +supports the Write Protect Until +Power Cycle state. +.IP "NVME_CTRL_NWPC_WRITE_PROTECT_PERMANENT" 12 +If set, then the controller +supports the Permanent Write +Protect state. diff --git a/doc/man/enum nvme_id_ctrl_oacs.2 b/doc/man/enum nvme_id_ctrl_oacs.2 new file mode 100644 index 0000000000..d70bb240a7 --- /dev/null +++ b/doc/man/enum nvme_id_ctrl_oacs.2 @@ -0,0 +1,77 @@ +.TH "libnvme" 2 "enum nvme_id_ctrl_oacs" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_id_ctrl_oacs \- Flags indicating the optional Admin commands and features supported by the controller, see &struct nvme_id_ctrl.oacs. +.SH SYNOPSIS +enum nvme_id_ctrl_oacs { +.br +.BI " NVME_CTRL_OACS_SECURITY" +, +.br +.br +.BI " NVME_CTRL_OACS_FORMAT" +, +.br +.br +.BI " NVME_CTRL_OACS_FW" +, +.br +.br +.BI " NVME_CTRL_OACS_NS_MGMT" +, +.br +.br +.BI " NVME_CTRL_OACS_SELF_TEST" +, +.br +.br +.BI " NVME_CTRL_OACS_DIRECTIVES" +, +.br +.br +.BI " NVME_CTRL_OACS_NVME_MI" +, +.br +.br +.BI " NVME_CTRL_OACS_VIRT_MGMT" +, +.br +.br +.BI " NVME_CTRL_OACS_DBBUF_CFG" +, +.br +.br +.BI " NVME_CTRL_OACS_LBA_STATUS" + +}; +.SH Constants +.IP "NVME_CTRL_OACS_SECURITY" 12 +If set, then the controller supports the +Security Send and Security Receive commands. +.IP "NVME_CTRL_OACS_FORMAT" 12 +If set then the controller supports the Format +NVM command. +.IP "NVME_CTRL_OACS_FW" 12 +If set, then the controller supports the +Firmware Commit and Firmware Image Download commands. +.IP "NVME_CTRL_OACS_NS_MGMT" 12 +If set, then the controller supports the +Namespace Management capability +.IP "NVME_CTRL_OACS_SELF_TEST" 12 +If set, then the controller supports the Device +Self-test command. +.IP "NVME_CTRL_OACS_DIRECTIVES" 12 +If set, then the controller supports Directives +and the Directive Send and Directive Receive +commands. +.IP "NVME_CTRL_OACS_NVME_MI" 12 +If set, then the controller supports the NVMe-MI +Send and NVMe-MI Receive commands. +.IP "NVME_CTRL_OACS_VIRT_MGMT" 12 +If set, then the controller supports the +Virtualization Management command. +.IP "NVME_CTRL_OACS_DBBUF_CFG" 12 +If set, then the controller supports the +Doorbell Buffer Config command. +.IP "NVME_CTRL_OACS_LBA_STATUS" 12 +If set, then the controller supports the Get LBA +Status capability. diff --git a/doc/man/enum nvme_id_ctrl_oaes.2 b/doc/man/enum nvme_id_ctrl_oaes.2 new file mode 100644 index 0000000000..82810cbd48 --- /dev/null +++ b/doc/man/enum nvme_id_ctrl_oaes.2 @@ -0,0 +1,42 @@ +.TH "libnvme" 2 "enum nvme_id_ctrl_oaes" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_id_ctrl_oaes \- The typical latency in microseconds to enter Runtime D3 +.SH SYNOPSIS +enum nvme_id_ctrl_oaes { +.br +.BI " NVME_CTRL_OAES_NA" +, +.br +.br +.BI " NVME_CTRL_OAES_FA" +, +.br +.br +.BI " NVME_CTRL_OAES_ANA" +, +.br +.br +.BI " NVME_CTRL_OAES_PLEA" +, +.br +.br +.BI " NVME_CTRL_OAES_LBAS" +, +.br +.br +.BI " NVME_CTRL_OAES_EGE" + +}; +.SH Constants +.IP "NVME_CTRL_OAES_NA" 12 +-- undescribed -- +.IP "NVME_CTRL_OAES_FA" 12 +-- undescribed -- +.IP "NVME_CTRL_OAES_ANA" 12 +-- undescribed -- +.IP "NVME_CTRL_OAES_PLEA" 12 +-- undescribed -- +.IP "NVME_CTRL_OAES_LBAS" 12 +: +.IP "NVME_CTRL_OAES_EGE" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_id_ctrl_ofcs.2 b/doc/man/enum nvme_id_ctrl_ofcs.2 new file mode 100644 index 0000000000..a594dd2d5f --- /dev/null +++ b/doc/man/enum nvme_id_ctrl_ofcs.2 @@ -0,0 +1,14 @@ +.TH "libnvme" 2 "enum nvme_id_ctrl_ofcs" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_id_ctrl_ofcs \- Indicate whether the controller supports optional fabric commands. +.SH SYNOPSIS +enum nvme_id_ctrl_ofcs { +.br +.BI " NVME_CTRL_OFCS_DISCONNECT" + +}; +.SH Constants +.IP "NVME_CTRL_OFCS_DISCONNECT" 12 +If set, then the controller supports the +Disconnect command and deletion of individual +I/O Queues. diff --git a/doc/man/enum nvme_id_ctrl_oncs.2 b/doc/man/enum nvme_id_ctrl_oncs.2 new file mode 100644 index 0000000000..ae82bb75c0 --- /dev/null +++ b/doc/man/enum nvme_id_ctrl_oncs.2 @@ -0,0 +1,65 @@ +.TH "libnvme" 2 "enum nvme_id_ctrl_oncs" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_id_ctrl_oncs \- This field indicates the optional NVM commands and features supported by the controller. +.SH SYNOPSIS +enum nvme_id_ctrl_oncs { +.br +.BI " NVME_CTRL_ONCS_COMPARE" +, +.br +.br +.BI " NVME_CTRL_ONCS_WRITE_UNCORRECTABLE" +, +.br +.br +.BI " NVME_CTRL_ONCS_DSM" +, +.br +.br +.BI " NVME_CTRL_ONCS_WRITE_ZEROES" +, +.br +.br +.BI " NVME_CTRL_ONCS_SAVE_FEATURES" +, +.br +.br +.BI " NVME_CTRL_ONCS_RESERVATIONS" +, +.br +.br +.BI " NVME_CTRL_ONCS_TIMESTAMP" +, +.br +.br +.BI " NVME_CTRL_ONCS_VERIFY" + +}; +.SH Constants +.IP "NVME_CTRL_ONCS_COMPARE" 12 +If set, then the controller supports +the Compare command. +.IP "NVME_CTRL_ONCS_WRITE_UNCORRECTABLE" 12 +If set, then the controller supports +the Write Uncorrectable command. +.IP "NVME_CTRL_ONCS_DSM" 12 +If set, then the controller supports +the Dataset Management command. +.IP "NVME_CTRL_ONCS_WRITE_ZEROES" 12 +If set, then the controller supports +the Write Zeroes command. +.IP "NVME_CTRL_ONCS_SAVE_FEATURES" 12 +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. +.IP "NVME_CTRL_ONCS_RESERVATIONS" 12 +If set, then the controller supports +reservations. +.IP "NVME_CTRL_ONCS_TIMESTAMP" 12 +If set, then the controller supports +the Timestamp feature. +.IP "NVME_CTRL_ONCS_VERIFY" 12 +If set, then the controller supports +the Verify command. diff --git a/doc/man/enum nvme_id_ctrl_rpmbs.2 b/doc/man/enum nvme_id_ctrl_rpmbs.2 new file mode 100644 index 0000000000..36a1d3e174 --- /dev/null +++ b/doc/man/enum nvme_id_ctrl_rpmbs.2 @@ -0,0 +1,30 @@ +.TH "libnvme" 2 "enum nvme_id_ctrl_rpmbs" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +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. +.SH SYNOPSIS +enum nvme_id_ctrl_rpmbs { +.br +.BI " NVME_CTRL_RPMBS_NR_UNITS" +, +.br +.br +.BI " NVME_CTRL_RPMBS_AUTH_METHOD" +, +.br +.br +.BI " NVME_CTRL_RPMBS_TOTAL_SIZE" +, +.br +.br +.BI " NVME_CTRL_RPMBS_ACCESS_SIZE" + +}; +.SH Constants +.IP "NVME_CTRL_RPMBS_NR_UNITS" 12 +Mask to get the value of the Number of RPMB Units +.IP "NVME_CTRL_RPMBS_AUTH_METHOD" 12 +Mask to get the value of the Authentication Method +.IP "NVME_CTRL_RPMBS_TOTAL_SIZE" 12 +Mask to get the value of Total Size +.IP "NVME_CTRL_RPMBS_ACCESS_SIZE" 12 +Mask to get the value of Access Size diff --git a/doc/man/enum nvme_id_ctrl_sanicap.2 b/doc/man/enum nvme_id_ctrl_sanicap.2 new file mode 100644 index 0000000000..e0b518cd87 --- /dev/null +++ b/doc/man/enum nvme_id_ctrl_sanicap.2 @@ -0,0 +1,44 @@ +.TH "libnvme" 2 "enum nvme_id_ctrl_sanicap" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_id_ctrl_sanicap \- Indicates attributes for sanitize operations. +.SH SYNOPSIS +enum nvme_id_ctrl_sanicap { +.br +.BI " NVME_CTRL_SANICAP_CES" +, +.br +.br +.BI " NVME_CTRL_SANICAP_BES" +, +.br +.br +.BI " NVME_CTRL_SANICAP_OWS" +, +.br +.br +.BI " NVME_CTRL_SANICAP_NDI" +, +.br +.br +.BI " NVME_CTRL_SANICAP_NODMMAS" + +}; +.SH Constants +.IP "NVME_CTRL_SANICAP_CES" 12 +Crypto Erase Support. If set, then the +controller supports the Crypto Erase sanitize operation. +.IP "NVME_CTRL_SANICAP_BES" 12 +Block Erase Support. If set, then the controller +supports the Block Erase sanitize operation. +.IP "NVME_CTRL_SANICAP_OWS" 12 +Overwrite Support. If set, then the controller +supports the Overwrite sanitize operation. +.IP "NVME_CTRL_SANICAP_NDI" 12 +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. +.IP "NVME_CTRL_SANICAP_NODMMAS" 12 +No-Deallocate Modifies Media After Sanitize, +mask to extract value. diff --git a/doc/man/enum nvme_id_ctrl_sgls.2 b/doc/man/enum nvme_id_ctrl_sgls.2 new file mode 100644 index 0000000000..4e86051063 --- /dev/null +++ b/doc/man/enum nvme_id_ctrl_sgls.2 @@ -0,0 +1,54 @@ +.TH "libnvme" 2 "enum nvme_id_ctrl_sgls" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_id_ctrl_sgls \- This field indicates if SGLs are supported for the NVM Command Set and the particular SGL types supported. +.SH SYNOPSIS +enum nvme_id_ctrl_sgls { +.br +.BI " NVME_CTRL_SGLS_SUPPORTED" +, +.br +.br +.BI " NVME_CTRL_SGLS_KEYED" +, +.br +.br +.BI " NVME_CTRL_SGLS_BIT_BUCKET" +, +.br +.br +.BI " NVME_CTRL_SGLS_MPTR_BYTE_ALIGNED" +, +.br +.br +.BI " NVME_CTRL_SGLS_OVERSIZE" +, +.br +.br +.BI " NVME_CTRL_SGLS_MPTR_SGL" +, +.br +.br +.BI " NVME_CTRL_SGLS_OFFSET" +, +.br +.br +.BI " NVME_CTRL_SGLS_TPORT" + +}; +.SH Constants +.IP "NVME_CTRL_SGLS_SUPPORTED" 12 +-- undescribed -- +.IP "NVME_CTRL_SGLS_KEYED" 12 +-- undescribed -- +.IP "NVME_CTRL_SGLS_BIT_BUCKET" 12 +-- undescribed -- +.IP "NVME_CTRL_SGLS_MPTR_BYTE_ALIGNED" 12 +-- undescribed -- +.IP "NVME_CTRL_SGLS_OVERSIZE" 12 +-- undescribed -- +.IP "NVME_CTRL_SGLS_MPTR_SGL" 12 +-- undescribed -- +.IP "NVME_CTRL_SGLS_OFFSET" 12 +-- undescribed -- +.IP "NVME_CTRL_SGLS_TPORT" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_id_ctrl_sqes.2 b/doc/man/enum nvme_id_ctrl_sqes.2 new file mode 100644 index 0000000000..c5b25ca603 --- /dev/null +++ b/doc/man/enum nvme_id_ctrl_sqes.2 @@ -0,0 +1,20 @@ +.TH "libnvme" 2 "enum nvme_id_ctrl_sqes" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_id_ctrl_sqes \- Defines the required and maximum Submission Queue entry size when using the NVM Command Set. +.SH SYNOPSIS +enum nvme_id_ctrl_sqes { +.br +.BI " NVME_CTRL_SQES_MIN" +, +.br +.br +.BI " NVME_CTRL_SQES_MAX" + +}; +.SH Constants +.IP "NVME_CTRL_SQES_MIN" 12 +Mask to get the value of the required Submission Queue +Entry size when using the NVM Command Set. +.IP "NVME_CTRL_SQES_MAX" 12 +Mask to get the value of the maximum Submission Queue +entry size when using the NVM Command Set. diff --git a/doc/man/enum nvme_id_ctrl_vwc.2 b/doc/man/enum nvme_id_ctrl_vwc.2 new file mode 100644 index 0000000000..d2b6ac95e6 --- /dev/null +++ b/doc/man/enum nvme_id_ctrl_vwc.2 @@ -0,0 +1,22 @@ +.TH "libnvme" 2 "enum nvme_id_ctrl_vwc" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_id_ctrl_vwc \- +.SH SYNOPSIS +enum nvme_id_ctrl_vwc { +.br +.BI " NVME_CTRL_VWC_PRESENT" +, +.br +.br +.BI " NVME_CTRL_VWC_FLUSH" + +}; +.SH Constants +.IP "NVME_CTRL_VWC_PRESENT" 12 +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. +.IP "NVME_CTRL_VWC_FLUSH" 12 +Mask to get the value of the flush command behavior. diff --git a/doc/man/enum nvme_id_ctrl_vwci.2 b/doc/man/enum nvme_id_ctrl_vwci.2 new file mode 100644 index 0000000000..0dbfef4d6c --- /dev/null +++ b/doc/man/enum nvme_id_ctrl_vwci.2 @@ -0,0 +1,28 @@ +.TH "libnvme" 2 "enum nvme_id_ctrl_vwci" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +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. +.SH SYNOPSIS +enum nvme_id_ctrl_vwci { +.br +.BI " NVME_CTRL_VWCI_VWCR" +, +.br +.br +.BI " NVME_CTRL_VWCI_VWCRV" + +}; +.SH Constants +.IP "NVME_CTRL_VWCI_VWCR" 12 +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. +.IP "NVME_CTRL_VWCI_VWCRV" 12 +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. diff --git a/doc/man/enum nvme_id_ns_attr.2 b/doc/man/enum nvme_id_ns_attr.2 new file mode 100644 index 0000000000..ec63417557 --- /dev/null +++ b/doc/man/enum nvme_id_ns_attr.2 @@ -0,0 +1,14 @@ +.TH "libnvme" 2 "enum nvme_id_ns_attr" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_id_ns_attr \- Specifies attributes of the namespace. +.SH SYNOPSIS +enum nvme_id_ns_attr { +.br +.BI " NVME_NS_NSATTR_WRITE_PROTECTED" + +}; +.SH Constants +.IP "NVME_NS_NSATTR_WRITE_PROTECTED" 12 +If set, then the namespace is currently +write protected and all write access to the +namespace shall fail. diff --git a/doc/man/enum nvme_id_ns_dlfeat.2 b/doc/man/enum nvme_id_ns_dlfeat.2 new file mode 100644 index 0000000000..b55d45c49b --- /dev/null +++ b/doc/man/enum nvme_id_ns_dlfeat.2 @@ -0,0 +1,50 @@ +.TH "libnvme" 2 "enum nvme_id_ns_dlfeat" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_id_ns_dlfeat \- This field indicates information about features that affect deallocating logical blocks for this namespace. +.SH SYNOPSIS +enum nvme_id_ns_dlfeat { +.br +.BI " NVME_NS_DLFEAT_RB" +, +.br +.br +.BI " NVME_NS_DLFEAT_RB_NR" +, +.br +.br +.BI " NVME_NS_DLFEAT_RB_ALL_0S" +, +.br +.br +.BI " NVME_NS_DLFEAT_RB_ALL_FS" +, +.br +.br +.BI " NVME_NS_DLFEAT_WRITE_ZEROES" +, +.br +.br +.BI " NVME_NS_DLFEAT_CRC_GUARD" + +}; +.SH Constants +.IP "NVME_NS_DLFEAT_RB" 12 +Mask to get the value of the read behavior +.IP "NVME_NS_DLFEAT_RB_NR" 12 +Read behvaior is not reported +.IP "NVME_NS_DLFEAT_RB_ALL_0S" 12 +A deallocated logical block returns all bytes +cleared to 0h. +.IP "NVME_NS_DLFEAT_RB_ALL_FS" 12 +A deallocated logical block returns all bytes +set to FFh. +.IP "NVME_NS_DLFEAT_WRITE_ZEROES" 12 +If set, indicates that the controller supports +the Deallocate bit in the Write Zeroes command +for this namespace. +.IP "NVME_NS_DLFEAT_CRC_GUARD" 12 +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 diff --git a/doc/man/enum nvme_id_ns_dpc.2 b/doc/man/enum nvme_id_ns_dpc.2 new file mode 100644 index 0000000000..358b8b154f --- /dev/null +++ b/doc/man/enum nvme_id_ns_dpc.2 @@ -0,0 +1,43 @@ +.TH "libnvme" 2 "enum nvme_id_ns_dpc" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_id_ns_dpc \- This field indicates the capabilities for the end-to-end data protection feature. +.SH SYNOPSIS +enum nvme_id_ns_dpc { +.br +.BI " NVME_NS_DPC_PI_TYPE1" +, +.br +.br +.BI " NVME_NS_DPC_PI_TYPE2" +, +.br +.br +.BI " NVME_NS_DPC_PI_TYPE3" +, +.br +.br +.BI " NVME_NS_DPC_PI_FIRST" +, +.br +.br +.BI " NVME_NS_DPC_PI_LAST" + +}; +.SH Constants +.IP "NVME_NS_DPC_PI_TYPE1" 12 +If set, indicates that the namespace supports +Protection Information Type 1. +.IP "NVME_NS_DPC_PI_TYPE2" 12 +If set, indicates that the namespace supports +Protection Information Type 2. +.IP "NVME_NS_DPC_PI_TYPE3" 12 +If set, indicates that the namespace supports +Protection Information Type 3. +.IP "NVME_NS_DPC_PI_FIRST" 12 +If set, indicates that the namespace supports +protection information transferred as the first eight +bytes of metadata. +.IP "NVME_NS_DPC_PI_LAST" 12 +If set, indicates that the namespace supports +protection information transferred as the last eight +bytes of metadata. diff --git a/doc/man/enum nvme_id_ns_dps.2 b/doc/man/enum nvme_id_ns_dps.2 new file mode 100644 index 0000000000..93d51bb4f2 --- /dev/null +++ b/doc/man/enum nvme_id_ns_dps.2 @@ -0,0 +1,44 @@ +.TH "libnvme" 2 "enum nvme_id_ns_dps" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_id_ns_dps \- This field indicates the Type settings for the end-to-end data protection feature. +.SH SYNOPSIS +enum nvme_id_ns_dps { +.br +.BI " NVME_NS_DPS_PI_NONE" +, +.br +.br +.BI " NVME_NS_DPS_PI_TYPE1" +, +.br +.br +.BI " NVME_NS_DPS_PI_TYPE2" +, +.br +.br +.BI " NVME_NS_DPS_PI_TYPE3" +, +.br +.br +.BI " NVME_NS_DPS_PI_MASK" +, +.br +.br +.BI " NVME_NS_DPS_PI_FIRST" + +}; +.SH Constants +.IP "NVME_NS_DPS_PI_NONE" 12 +Protection information is not enabled +.IP "NVME_NS_DPS_PI_TYPE1" 12 +Protection information is enabled, Type 1 +.IP "NVME_NS_DPS_PI_TYPE2" 12 +Protection information is enabled, Type 2 +.IP "NVME_NS_DPS_PI_TYPE3" 12 +Protection information is enabled, Type 3 +.IP "NVME_NS_DPS_PI_MASK" 12 +Mask to get the value of the PI type +.IP "NVME_NS_DPS_PI_FIRST" 12 +If set, indicates that the protection information, if +enabled, is transferred as the first eight bytes of +metadata. diff --git a/doc/man/enum nvme_id_ns_flbas.2 b/doc/man/enum nvme_id_ns_flbas.2 new file mode 100644 index 0000000000..080d2ee274 --- /dev/null +++ b/doc/man/enum nvme_id_ns_flbas.2 @@ -0,0 +1,24 @@ +.TH "libnvme" 2 "enum nvme_id_ns_flbas" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_id_ns_flbas \- This field indicates the LBA data size & metadata size combination that the namespace has been formatted with +.SH SYNOPSIS +enum nvme_id_ns_flbas { +.br +.BI " NVME_NS_FLBAS_LBA_MASK" +, +.br +.br +.BI " NVME_NS_FLBAS_META_EXT" + +}; +.SH Constants +.IP "NVME_NS_FLBAS_LBA_MASK" 12 +Mask to get the index of one of the 16 supported +LBA Formats indicated in \fIstruct nvme_id_ns\fP.lbaf. +.IP "NVME_NS_FLBAS_META_EXT" 12 +Applicable only if format contains metadata. If +this bit is set, indicates that the metadata is +transferred at the end of the data LBA, creating an +extended data LBA. If cleared, indicates that all +of the metadata for a command is transferred as a +separate contiguous buffer of data. diff --git a/doc/man/enum nvme_id_ns_mc.2 b/doc/man/enum nvme_id_ns_mc.2 new file mode 100644 index 0000000000..801f280c6c --- /dev/null +++ b/doc/man/enum nvme_id_ns_mc.2 @@ -0,0 +1,21 @@ +.TH "libnvme" 2 "enum nvme_id_ns_mc" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_id_ns_mc \- This field indicates the capabilities for metadata. +.SH SYNOPSIS +enum nvme_id_ns_mc { +.br +.BI " NVME_NS_MC_EXTENDED" +, +.br +.br +.BI " NVME_NS_MC_SEPARATE" + +}; +.SH Constants +.IP "NVME_NS_MC_EXTENDED" 12 +If set, indicates the namespace supports the metadata +being transferred as part of a separate buffer that is +specified in the Metadata Pointer. +.IP "NVME_NS_MC_SEPARATE" 12 +If set, indicates that the namespace supports the +metadata being transferred as part of an extended data LBA. diff --git a/doc/man/enum nvme_id_ns_nmic.2 b/doc/man/enum nvme_id_ns_nmic.2 new file mode 100644 index 0000000000..030e3af0dd --- /dev/null +++ b/doc/man/enum nvme_id_ns_nmic.2 @@ -0,0 +1,13 @@ +.TH "libnvme" 2 "enum nvme_id_ns_nmic" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_id_ns_nmic \- This field specifies multi-path I/O and namespace sharing capabilities of the namespace. +.SH SYNOPSIS +enum nvme_id_ns_nmic { +.br +.BI " NVME_NS_NMIC_SHARED" + +}; +.SH Constants +.IP "NVME_NS_NMIC_SHARED" 12 +If set, then the namespace may be attached to two or +more controllers in the NVM subsystem concurrently diff --git a/doc/man/enum nvme_id_ns_rescap.2 b/doc/man/enum nvme_id_ns_rescap.2 new file mode 100644 index 0000000000..162cef4763 --- /dev/null +++ b/doc/man/enum nvme_id_ns_rescap.2 @@ -0,0 +1,62 @@ +.TH "libnvme" 2 "enum nvme_id_ns_rescap" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_id_ns_rescap \- This field indicates the reservation capabilities of the namespace. +.SH SYNOPSIS +enum nvme_id_ns_rescap { +.br +.BI " NVME_NS_RESCAP_PTPL" +, +.br +.br +.BI " NVME_NS_RESCAP_WE" +, +.br +.br +.BI " NVME_NS_RESCAP_EA" +, +.br +.br +.BI " NVME_NS_RESCAP_WERO" +, +.br +.br +.BI " NVME_NS_RESCAP_EARO" +, +.br +.br +.BI " NVME_NS_RESCAP_WEAR" +, +.br +.br +.BI " NVME_NS_RESCAP_EAAR" +, +.br +.br +.BI " NVME_NS_RESCAP_IEK_13" + +}; +.SH Constants +.IP "NVME_NS_RESCAP_PTPL" 12 +If set, indicates that the namespace supports the +Persist Through Power Loss capability. +.IP "NVME_NS_RESCAP_WE" 12 +If set, indicates that the namespace supports the +Write Exclusive reservation type. +.IP "NVME_NS_RESCAP_EA" 12 +If set, indicates that the namespace supports the +Exclusive Access reservation type. +.IP "NVME_NS_RESCAP_WERO" 12 +If set, indicates that the namespace supports the +Write Exclusive - Registrants Only reservation type. +.IP "NVME_NS_RESCAP_EARO" 12 +If set, indicates that the namespace supports the +Exclusive Access - Registrants Only reservation type. +.IP "NVME_NS_RESCAP_WEAR" 12 +If set, indicates that the namespace supports the +Write Exclusive - All Registrants reservation type. +.IP "NVME_NS_RESCAP_EAAR" 12 +If set, indicates that the namespace supports the +Exclusive Access - All Registrants reservation type. +.IP "NVME_NS_RESCAP_IEK_13" 12 +If set, indicates that Ignore Existing Key is used +as defined in revision 1.3 or later of this specification. diff --git a/doc/man/enum nvme_id_nsfeat.2 b/doc/man/enum nvme_id_nsfeat.2 new file mode 100644 index 0000000000..f97d6901a1 --- /dev/null +++ b/doc/man/enum nvme_id_nsfeat.2 @@ -0,0 +1,51 @@ +.TH "libnvme" 2 "enum nvme_id_nsfeat" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_id_nsfeat \- This field defines features of the namespace. +.SH SYNOPSIS +enum nvme_id_nsfeat { +.br +.BI " NVME_NS_FEAT_THIN" +, +.br +.br +.BI " NVME_NS_FEAT_NATOMIC" +, +.br +.br +.BI " NVME_NS_FEAT_DULBE" +, +.br +.br +.BI " NVME_NS_FEAT_ID_REUSE" +, +.br +.br +.BI " NVME_NS_FEAT_IO_OPT" + +}; +.SH Constants +.IP "NVME_NS_FEAT_THIN" 12 +If set, indicates that the namespace supports thin +provisioning. Specifically, the Namespace Capacity +reported may be less than the Namespace Size. +.IP "NVME_NS_FEAT_NATOMIC" 12 +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. +.IP "NVME_NS_FEAT_DULBE" 12 +If set, indicates that the controller supports the +Deallocated or Unwritten Logical Block error for +this namespace. \fINVME_NS_FEAT_ID_REUSE\fP: 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. +.IP "NVME_NS_FEAT_ID_REUSE" 12 +-- undescribed -- +.IP "NVME_NS_FEAT_IO_OPT" 12 +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 diff --git a/doc/man/enum nvme_identify_cns.2 b/doc/man/enum nvme_identify_cns.2 new file mode 100644 index 0000000000..9588548dee --- /dev/null +++ b/doc/man/enum nvme_identify_cns.2 @@ -0,0 +1,84 @@ +.TH "libnvme" 2 "enum nvme_identify_cns" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_identify_cns \- +.SH SYNOPSIS +enum nvme_identify_cns { +.br +.BI " NVME_IDENTIFY_CNS_NS" +, +.br +.br +.BI " NVME_IDENTIFY_CNS_CTRL" +, +.br +.br +.BI " NVME_IDENTIFY_CNS_NS_ACTIVE_LIST" +, +.br +.br +.BI " NVME_IDENTIFY_CNS_NS_DESC_LIST" +, +.br +.br +.BI " NVME_IDENTIFY_CNS_NVMSET_LIST" +, +.br +.br +.BI " NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST" +, +.br +.br +.BI " NVME_IDENTIFY_CNS_ALLOCATED_NS" +, +.br +.br +.BI " NVME_IDENTIFY_CNS_NS_CTRL_LIST" +, +.br +.br +.BI " NVME_IDENTIFY_CNS_CTRL_LIST" +, +.br +.br +.BI " NVME_IDENTIFY_CNS_PRIMARY_CTRL_CAP" +, +.br +.br +.BI " NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST" +, +.br +.br +.BI " NVME_IDENTIFY_CNS_NS_GRANULARITY" +, +.br +.br +.BI " NVME_IDENTIFY_CNS_UUID_LIST" + +}; +.SH Constants +.IP "NVME_IDENTIFY_CNS_NS" 12 +-- undescribed -- +.IP "NVME_IDENTIFY_CNS_CTRL" 12 +-- undescribed -- +.IP "NVME_IDENTIFY_CNS_NS_ACTIVE_LIST" 12 +-- undescribed -- +.IP "NVME_IDENTIFY_CNS_NS_DESC_LIST" 12 +-- undescribed -- +.IP "NVME_IDENTIFY_CNS_NVMSET_LIST" 12 +-- undescribed -- +.IP "NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST" 12 +-- undescribed -- +.IP "NVME_IDENTIFY_CNS_ALLOCATED_NS" 12 +-- undescribed -- +.IP "NVME_IDENTIFY_CNS_NS_CTRL_LIST" 12 +-- undescribed -- +.IP "NVME_IDENTIFY_CNS_CTRL_LIST" 12 +-- undescribed -- +.IP "NVME_IDENTIFY_CNS_PRIMARY_CTRL_CAP" 12 +-- undescribed -- +.IP "NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST" 12 +-- undescribed -- +.IP "NVME_IDENTIFY_CNS_NS_GRANULARITY" 12 +-- undescribed -- +.IP "NVME_IDENTIFY_CNS_UUID_LIST" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_io_control_flags.2 b/doc/man/enum nvme_io_control_flags.2 new file mode 100644 index 0000000000..8390b059de --- /dev/null +++ b/doc/man/enum nvme_io_control_flags.2 @@ -0,0 +1,54 @@ +.TH "libnvme" 2 "enum nvme_io_control_flags" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_io_control_flags \- +.SH SYNOPSIS +enum nvme_io_control_flags { +.br +.BI " NVME_IO_DTYPE_STREAMS" +, +.br +.br +.BI " NVME_IO_DEAC" +, +.br +.br +.BI " NVME_IO_PRINFO_PRCHK_REF" +, +.br +.br +.BI " NVME_IO_PRINFO_PRCHK_APP" +, +.br +.br +.BI " NVME_IO_PRINFO_PRCHK_GUARD" +, +.br +.br +.BI " NVME_IO_PRINFO_PRACT" +, +.br +.br +.BI " NVME_IO_FUA" +, +.br +.br +.BI " NVME_IO_LR" + +}; +.SH Constants +.IP "NVME_IO_DTYPE_STREAMS" 12 +-- undescribed -- +.IP "NVME_IO_DEAC" 12 +-- undescribed -- +.IP "NVME_IO_PRINFO_PRCHK_REF" 12 +-- undescribed -- +.IP "NVME_IO_PRINFO_PRCHK_APP" 12 +-- undescribed -- +.IP "NVME_IO_PRINFO_PRCHK_GUARD" 12 +-- undescribed -- +.IP "NVME_IO_PRINFO_PRACT" 12 +-- undescribed -- +.IP "NVME_IO_FUA" 12 +-- undescribed -- +.IP "NVME_IO_LR" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_io_dsm_flags.2 b/doc/man/enum nvme_io_dsm_flags.2 new file mode 100644 index 0000000000..76e5f2103c --- /dev/null +++ b/doc/man/enum nvme_io_dsm_flags.2 @@ -0,0 +1,96 @@ +.TH "libnvme" 2 "enum nvme_io_dsm_flags" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_io_dsm_flags \- +.SH SYNOPSIS +enum nvme_io_dsm_flags { +.br +.BI " NVME_IO_DSM_FREQ_UNSPEC" +, +.br +.br +.BI " NVME_IO_DSM_FREQ_TYPICAL" +, +.br +.br +.BI " NVME_IO_DSM_FREQ_RARE" +, +.br +.br +.BI " NVME_IO_DSM_FREQ_READS" +, +.br +.br +.BI " NVME_IO_DSM_FREQ_WRITES" +, +.br +.br +.BI " NVME_IO_DSM_FREQ_RW" +, +.br +.br +.BI " NVME_IO_DSM_FREQ_ONCE" +, +.br +.br +.BI " NVME_IO_DSM_FREQ_PREFETCH" +, +.br +.br +.BI " NVME_IO_DSM_FREQ_TEMP" +, +.br +.br +.BI " NVME_IO_DSM_LATENCY_NONE" +, +.br +.br +.BI " NVME_IO_DSM_LATENCY_IDLE" +, +.br +.br +.BI " NVME_IO_DSM_LATENCY_NORM" +, +.br +.br +.BI " NVME_IO_DSM_LATENCY_LOW" +, +.br +.br +.BI " NVME_IO_DSM_SEQ_REQ" +, +.br +.br +.BI " NVME_IO_DSM_COMPRESSED" + +}; +.SH Constants +.IP "NVME_IO_DSM_FREQ_UNSPEC" 12 +-- undescribed -- +.IP "NVME_IO_DSM_FREQ_TYPICAL" 12 +-- undescribed -- +.IP "NVME_IO_DSM_FREQ_RARE" 12 +-- undescribed -- +.IP "NVME_IO_DSM_FREQ_READS" 12 +-- undescribed -- +.IP "NVME_IO_DSM_FREQ_WRITES" 12 +-- undescribed -- +.IP "NVME_IO_DSM_FREQ_RW" 12 +-- undescribed -- +.IP "NVME_IO_DSM_FREQ_ONCE" 12 +-- undescribed -- +.IP "NVME_IO_DSM_FREQ_PREFETCH" 12 +-- undescribed -- +.IP "NVME_IO_DSM_FREQ_TEMP" 12 +-- undescribed -- +.IP "NVME_IO_DSM_LATENCY_NONE" 12 +-- undescribed -- +.IP "NVME_IO_DSM_LATENCY_IDLE" 12 +-- undescribed -- +.IP "NVME_IO_DSM_LATENCY_NORM" 12 +-- undescribed -- +.IP "NVME_IO_DSM_LATENCY_LOW" 12 +-- undescribed -- +.IP "NVME_IO_DSM_SEQ_REQ" 12 +-- undescribed -- +.IP "NVME_IO_DSM_COMPRESSED" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_io_opcode.2 b/doc/man/enum nvme_io_opcode.2 new file mode 100644 index 0000000000..64ee88e6a5 --- /dev/null +++ b/doc/man/enum nvme_io_opcode.2 @@ -0,0 +1,78 @@ +.TH "libnvme" 2 "enum nvme_io_opcode" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_io_opcode \- +.SH SYNOPSIS +enum nvme_io_opcode { +.br +.BI " nvme_cmd_flush" +, +.br +.br +.BI " nvme_cmd_write" +, +.br +.br +.BI " nvme_cmd_read" +, +.br +.br +.BI " nvme_cmd_write_uncor" +, +.br +.br +.BI " nvme_cmd_compare" +, +.br +.br +.BI " nvme_cmd_write_zeroes" +, +.br +.br +.BI " nvme_cmd_dsm" +, +.br +.br +.BI " nvme_cmd_verify" +, +.br +.br +.BI " nvme_cmd_resv_register" +, +.br +.br +.BI " nvme_cmd_resv_report" +, +.br +.br +.BI " nvme_cmd_resv_acquire" +, +.br +.br +.BI " nvme_cmd_resv_release" + +}; +.SH Constants +.IP "nvme_cmd_flush" 12 +-- undescribed -- +.IP "nvme_cmd_write" 12 +-- undescribed -- +.IP "nvme_cmd_read" 12 +-- undescribed -- +.IP "nvme_cmd_write_uncor" 12 +-- undescribed -- +.IP "nvme_cmd_compare" 12 +-- undescribed -- +.IP "nvme_cmd_write_zeroes" 12 +-- undescribed -- +.IP "nvme_cmd_dsm" 12 +-- undescribed -- +.IP "nvme_cmd_verify" 12 +-- undescribed -- +.IP "nvme_cmd_resv_register" 12 +-- undescribed -- +.IP "nvme_cmd_resv_report" 12 +-- undescribed -- +.IP "nvme_cmd_resv_acquire" 12 +-- undescribed -- +.IP "nvme_cmd_resv_release" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_lba_status_atype.2 b/doc/man/enum nvme_lba_status_atype.2 new file mode 100644 index 0000000000..511fc5cc5d --- /dev/null +++ b/doc/man/enum nvme_lba_status_atype.2 @@ -0,0 +1,18 @@ +.TH "libnvme" 2 "enum nvme_lba_status_atype" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_lba_status_atype \- +.SH SYNOPSIS +enum nvme_lba_status_atype { +.br +.BI " NVME_LBA_STATUS_ATYPE_SCAN_UNTRACKED" +, +.br +.br +.BI " NVME_LBA_STATUS_ATYPE_SCAN_TRACKED" + +}; +.SH Constants +.IP "NVME_LBA_STATUS_ATYPE_SCAN_UNTRACKED" 12 +-- undescribed -- +.IP "NVME_LBA_STATUS_ATYPE_SCAN_TRACKED" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_lbaf_rp.2 b/doc/man/enum nvme_lbaf_rp.2 new file mode 100644 index 0000000000..537e74440e --- /dev/null +++ b/doc/man/enum nvme_lbaf_rp.2 @@ -0,0 +1,37 @@ +.TH "libnvme" 2 "enum nvme_lbaf_rp" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_lbaf_rp \- This field indicates the relative performance of the LBA format indicated relative to other LBA formats supported by the controller. +.SH SYNOPSIS +enum nvme_lbaf_rp { +.br +.BI " NVME_LBAF_RP_BEST" +, +.br +.br +.BI " NVME_LBAF_RP_BETTER" +, +.br +.br +.BI " NVME_LBAF_RP_GOOD" +, +.br +.br +.BI " NVME_LBAF_RP_DEGRADED" +, +.br +.br +.BI " NVME_LBAF_RP_MASK" + +}; +.SH Constants +.IP "NVME_LBAF_RP_BEST" 12 +Best performance +.IP "NVME_LBAF_RP_BETTER" 12 +Better performance +.IP "NVME_LBAF_RP_GOOD" 12 +Good performance +.IP "NVME_LBAF_RP_DEGRADED" 12 +Degraded performance +.IP "NVME_LBAF_RP_MASK" 12 +Mask to get the relative performance value from the +field diff --git a/doc/man/enum nvme_nd_ns_fpi.2 b/doc/man/enum nvme_nd_ns_fpi.2 new file mode 100644 index 0000000000..23460f7d62 --- /dev/null +++ b/doc/man/enum nvme_nd_ns_fpi.2 @@ -0,0 +1,19 @@ +.TH "libnvme" 2 "enum nvme_nd_ns_fpi" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +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. +.SH SYNOPSIS +enum nvme_nd_ns_fpi { +.br +.BI " NVME_NS_FPI_REMAINING" +, +.br +.br +.BI " NVME_NS_FPI_SUPPORTED" + +}; +.SH Constants +.IP "NVME_NS_FPI_REMAINING" 12 +Mask to get the format percent remaining value +.IP "NVME_NS_FPI_SUPPORTED" 12 +If set, indicates that the namespace supports the +Format Progress Indicator defined for the field. diff --git a/doc/man/enum nvme_ns_attach_sel.2 b/doc/man/enum nvme_ns_attach_sel.2 new file mode 100644 index 0000000000..7d3c0dcf48 --- /dev/null +++ b/doc/man/enum nvme_ns_attach_sel.2 @@ -0,0 +1,18 @@ +.TH "libnvme" 2 "enum nvme_ns_attach_sel" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_ns_attach_sel \- NVME_NS_ATTACH_SEL_CTRL_ATTACH: NVME_NP_ATTACH_SEL_CTRL_DEATTACH: +.SH SYNOPSIS +enum nvme_ns_attach_sel { +.br +.BI " NVME_NS_ATTACH_SEL_CTRL_ATTACH" +, +.br +.br +.BI " NVME_NS_ATTACH_SEL_CTRL_DEATTACH" + +}; +.SH Constants +.IP "NVME_NS_ATTACH_SEL_CTRL_ATTACH" 12 +-- undescribed -- +.IP "NVME_NS_ATTACH_SEL_CTRL_DEATTACH" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_ns_id_desc_nidt.2 b/doc/man/enum nvme_ns_id_desc_nidt.2 new file mode 100644 index 0000000000..6e028e1640 --- /dev/null +++ b/doc/man/enum nvme_ns_id_desc_nidt.2 @@ -0,0 +1,27 @@ +.TH "libnvme" 2 "enum nvme_ns_id_desc_nidt" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_ns_id_desc_nidt \- Known namespace identifier types +.SH SYNOPSIS +enum nvme_ns_id_desc_nidt { +.br +.BI " NVME_NIDT_EUI64" +, +.br +.br +.BI " NVME_NIDT_NGUID" +, +.br +.br +.BI " NVME_NIDT_UUID" + +}; +.SH Constants +.IP "NVME_NIDT_EUI64" 12 +IEEE Extended Unique Identifier, the NID field contains a +copy of the EUI64 field in the struct nvme_id_ns.eui64. +.IP "NVME_NIDT_NGUID" 12 +Namespace Globally Unique Identifier, the NID field +contains a copy of the NGUID field in struct nvme_id_ns.nguid. +.IP "NVME_NIDT_UUID" 12 +The NID field contains a 128-bit Universally Unique +Identifier (UUID) as specified in RFC 4122. diff --git a/doc/man/enum nvme_ns_mgmt_sel.2 b/doc/man/enum nvme_ns_mgmt_sel.2 new file mode 100644 index 0000000000..4132c8952d --- /dev/null +++ b/doc/man/enum nvme_ns_mgmt_sel.2 @@ -0,0 +1,18 @@ +.TH "libnvme" 2 "enum nvme_ns_mgmt_sel" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_ns_mgmt_sel \- +.SH SYNOPSIS +enum nvme_ns_mgmt_sel { +.br +.BI " NVME_NS_MGMT_SEL_CREATE" +, +.br +.br +.BI " NVME_NS_MGMT_SEL_DELETE" + +}; +.SH Constants +.IP "NVME_NS_MGMT_SEL_CREATE" 12 +-- undescribed -- +.IP "NVME_NS_MGMT_SEL_DELETE" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_psd_flags.2 b/doc/man/enum nvme_psd_flags.2 new file mode 100644 index 0000000000..1b4e7435af --- /dev/null +++ b/doc/man/enum nvme_psd_flags.2 @@ -0,0 +1,26 @@ +.TH "libnvme" 2 "enum nvme_psd_flags" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_psd_flags \- Possible flag values in nvme power state descriptor +.SH SYNOPSIS +enum nvme_psd_flags { +.br +.BI " NVME_PSD_FLAGS_MXPS" +, +.br +.br +.BI " NVME_PSD_FLAGS_NOPS" + +}; +.SH Constants +.IP "NVME_PSD_FLAGS_MXPS" 12 +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. +.IP "NVME_PSD_FLAGS_NOPS" 12 +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. diff --git a/doc/man/enum nvme_psd_ps.2 b/doc/man/enum nvme_psd_ps.2 new file mode 100644 index 0000000000..7649922743 --- /dev/null +++ b/doc/man/enum nvme_psd_ps.2 @@ -0,0 +1,18 @@ +.TH "libnvme" 2 "enum nvme_psd_ps" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +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_IPS_100_MICRO_WATT: 0.0001 watt scale NVME_PSD_IPS_10_MILLI_WATT: 0.01 watt scale +.SH SYNOPSIS +enum nvme_psd_ps { +.br +.BI " NVME_PSD_PS_100_MICRO_WATT" +, +.br +.br +.BI " NVME_PSD_PS_10_MILLI_WATT" + +}; +.SH Constants +.IP "NVME_PSD_PS_100_MICRO_WATT" 12 +-- undescribed -- +.IP "NVME_PSD_PS_10_MILLI_WATT" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_psd_workload.2 b/doc/man/enum nvme_psd_workload.2 new file mode 100644 index 0000000000..b370397f75 --- /dev/null +++ b/doc/man/enum nvme_psd_workload.2 @@ -0,0 +1,29 @@ +.TH "libnvme" 2 "enum nvme_psd_workload" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +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. +.SH SYNOPSIS +enum nvme_psd_workload { +.br +.BI " NVME_PSD_WORKLOAD_1" +, +.br +.br +.BI " NVME_PSD_WORKLOAD_2" + +}; +.SH Constants +.IP "NVME_PSD_WORKLOAD_1" 12 +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. +.IP "NVME_PSD_WORKLOAD_2" 12 +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 +NVM subsystem are idle. The submission queue(s) +should be sufficiently large allowing the host to +ensure there are multiple commands pending at all +times during the workload. diff --git a/doc/man/enum nvme_registers.2 b/doc/man/enum nvme_registers.2 new file mode 100644 index 0000000000..8fb1776aa8 --- /dev/null +++ b/doc/man/enum nvme_registers.2 @@ -0,0 +1,150 @@ +.TH "libnvme" 2 "enum nvme_registers" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_registers \- The nvme controller registers for all transports. This is the layout of BAR0/1 for PCIe, and properties for fabrics. +.SH SYNOPSIS +enum nvme_registers { +.br +.BI " NVME_REG_CAP" +, +.br +.br +.BI " NVME_REG_VS" +, +.br +.br +.BI " NVME_REG_INTMS" +, +.br +.br +.BI " NVME_REG_INTMC" +, +.br +.br +.BI " NVME_REG_CC" +, +.br +.br +.BI " NVME_REG_CSTS" +, +.br +.br +.BI " NVME_REG_NSSR" +, +.br +.br +.BI " NVME_REG_AQA" +, +.br +.br +.BI " NVME_REG_ASQ" +, +.br +.br +.BI " NVME_REG_ACQ" +, +.br +.br +.BI " NVME_REG_CMBLOC" +, +.br +.br +.BI " NVME_REG_CMBSZ" +, +.br +.br +.BI " NVME_REG_BPINFO" +, +.br +.br +.BI " NVME_REG_BPRSEL" +, +.br +.br +.BI " NVME_REG_BPMBL" +, +.br +.br +.BI " NVME_REG_CMBMSC" +, +.br +.br +.BI " NVME_REG_CMBSTS" +, +.br +.br +.BI " NVME_REG_PMRCAP" +, +.br +.br +.BI " NVME_REG_PMRCTL" +, +.br +.br +.BI " NVME_REG_PMRSTS" +, +.br +.br +.BI " NVME_REG_PMREBS" +, +.br +.br +.BI " NVME_REG_PMRSWTP" +, +.br +.br +.BI " NVME_REG_PMRMSC" +, +.br +.br +.BI " NVME_REG_DBS" + +}; +.SH Constants +.IP "NVME_REG_CAP" 12 +Controller Capabilities +.IP "NVME_REG_VS" 12 +Version +.IP "NVME_REG_INTMS" 12 +Interrupt Mask Set +.IP "NVME_REG_INTMC" 12 +Interrupt Mask Clear +.IP "NVME_REG_CC" 12 +Controller Configuration +.IP "NVME_REG_CSTS" 12 +Controller Status +.IP "NVME_REG_NSSR" 12 +NVM Subsystem Reset +.IP "NVME_REG_AQA" 12 +Admin Queue Attributes +.IP "NVME_REG_ASQ" 12 +Admin SQ Base Address +.IP "NVME_REG_ACQ" 12 +Admin CQ Base Address +.IP "NVME_REG_CMBLOC" 12 +Controller Memory Buffer Location +.IP "NVME_REG_CMBSZ" 12 +Controller Memory Buffer Size +.IP "NVME_REG_BPINFO" 12 +Boot Partition Information +.IP "NVME_REG_BPRSEL" 12 +Boot Partition Read Select +.IP "NVME_REG_BPMBL" 12 +Boot Partition Memory Buffer Location +.IP "NVME_REG_CMBMSC" 12 +Controller Memory Buffer Memory Space Control +.IP "NVME_REG_CMBSTS" 12 +Controller Memory Buffer Status +.IP "NVME_REG_PMRCAP" 12 +Persistent Memory Capabilities +.IP "NVME_REG_PMRCTL" 12 +Persistent Memory Region Control +.IP "NVME_REG_PMRSTS" 12 +Persistent Memory Region Status +.IP "NVME_REG_PMREBS" 12 +Persistent Memory Region Elasticity Buffer Size +.IP "NVME_REG_PMRSWTP" 12 +Memory Region Sustained Write Throughput +.IP "NVME_REG_PMRMSC" 12 +Persistent Memory Region Controller Memory Space Control +.IP "NVME_REG_DBS" 12 +SQ 0 Tail Doorbell diff --git a/doc/man/enum nvme_reservation_cptpl.2 b/doc/man/enum nvme_reservation_cptpl.2 new file mode 100644 index 0000000000..7033a1764d --- /dev/null +++ b/doc/man/enum nvme_reservation_cptpl.2 @@ -0,0 +1,24 @@ +.TH "libnvme" 2 "enum nvme_reservation_cptpl" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_reservation_cptpl \- +.SH SYNOPSIS +enum nvme_reservation_cptpl { +.br +.BI " NVME_RESERVATION_CPTPL_NO_CHANGE" +, +.br +.br +.BI " NVME_RESERVATION_CPTPL_CLEAR" +, +.br +.br +.BI " NVME_RESERVATION_CPTPL_PERSIST" + +}; +.SH Constants +.IP "NVME_RESERVATION_CPTPL_NO_CHANGE" 12 +-- undescribed -- +.IP "NVME_RESERVATION_CPTPL_CLEAR" 12 +-- undescribed -- +.IP "NVME_RESERVATION_CPTPL_PERSIST" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_reservation_racqa.2 b/doc/man/enum nvme_reservation_racqa.2 new file mode 100644 index 0000000000..89168c2f54 --- /dev/null +++ b/doc/man/enum nvme_reservation_racqa.2 @@ -0,0 +1,24 @@ +.TH "libnvme" 2 "enum nvme_reservation_racqa" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_reservation_racqa \- +.SH SYNOPSIS +enum nvme_reservation_racqa { +.br +.BI " NVME_RESERVATION_RACQA_ACQUIRE" +, +.br +.br +.BI " NVME_RESERVATION_RACQA_PREEMPT" +, +.br +.br +.BI " NVME_RESERVATION_RACQA_PREEMPT_AND_ABORT" + +}; +.SH Constants +.IP "NVME_RESERVATION_RACQA_ACQUIRE" 12 +-- undescribed -- +.IP "NVME_RESERVATION_RACQA_PREEMPT" 12 +-- undescribed -- +.IP "NVME_RESERVATION_RACQA_PREEMPT_AND_ABORT" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_reservation_rrega.2 b/doc/man/enum nvme_reservation_rrega.2 new file mode 100644 index 0000000000..155f305f50 --- /dev/null +++ b/doc/man/enum nvme_reservation_rrega.2 @@ -0,0 +1,24 @@ +.TH "libnvme" 2 "enum nvme_reservation_rrega" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_reservation_rrega \- +.SH SYNOPSIS +enum nvme_reservation_rrega { +.br +.BI " NVME_RESERVATION_RREGA_REGISTER_KEY" +, +.br +.br +.BI " NVME_RESERVATION_RREGA_UNREGISTER_KEY" +, +.br +.br +.BI " NVME_RESERVATION_RREGA_REPLACE_KEY" + +}; +.SH Constants +.IP "NVME_RESERVATION_RREGA_REGISTER_KEY" 12 +-- undescribed -- +.IP "NVME_RESERVATION_RREGA_UNREGISTER_KEY" 12 +-- undescribed -- +.IP "NVME_RESERVATION_RREGA_REPLACE_KEY" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_reservation_rrela.2 b/doc/man/enum nvme_reservation_rrela.2 new file mode 100644 index 0000000000..c8a9d26600 --- /dev/null +++ b/doc/man/enum nvme_reservation_rrela.2 @@ -0,0 +1,18 @@ +.TH "libnvme" 2 "enum nvme_reservation_rrela" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_reservation_rrela \- +.SH SYNOPSIS +enum nvme_reservation_rrela { +.br +.BI " NVME_RESERVATION_RRELA_RELEASE" +, +.br +.br +.BI " NVME_RESERVATION_RRELA_CLEAR" + +}; +.SH Constants +.IP "NVME_RESERVATION_RRELA_RELEASE" 12 +-- undescribed -- +.IP "NVME_RESERVATION_RRELA_CLEAR" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_reservation_rtype.2 b/doc/man/enum nvme_reservation_rtype.2 new file mode 100644 index 0000000000..079b3c52e3 --- /dev/null +++ b/doc/man/enum nvme_reservation_rtype.2 @@ -0,0 +1,42 @@ +.TH "libnvme" 2 "enum nvme_reservation_rtype" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_reservation_rtype \- +.SH SYNOPSIS +enum nvme_reservation_rtype { +.br +.BI " NVME_RESERVATION_RTYPE_WE" +, +.br +.br +.BI " NVME_RESERVATION_RTYPE_EA" +, +.br +.br +.BI " NVME_RESERVATION_RTYPE_WERO" +, +.br +.br +.BI " NVME_RESERVATION_RTYPE_EARO" +, +.br +.br +.BI " NVME_RESERVATION_RTYPE_WEAR" +, +.br +.br +.BI " NVME_RESERVATION_RTYPE_EAAR" + +}; +.SH Constants +.IP "NVME_RESERVATION_RTYPE_WE" 12 +-- undescribed -- +.IP "NVME_RESERVATION_RTYPE_EA" 12 +-- undescribed -- +.IP "NVME_RESERVATION_RTYPE_WERO" 12 +-- undescribed -- +.IP "NVME_RESERVATION_RTYPE_EARO" 12 +-- undescribed -- +.IP "NVME_RESERVATION_RTYPE_WEAR" 12 +-- undescribed -- +.IP "NVME_RESERVATION_RTYPE_EAAR" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_sanitize_sanact.2 b/doc/man/enum nvme_sanitize_sanact.2 new file mode 100644 index 0000000000..36ebbadbc6 --- /dev/null +++ b/doc/man/enum nvme_sanitize_sanact.2 @@ -0,0 +1,30 @@ +.TH "libnvme" 2 "enum nvme_sanitize_sanact" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_sanitize_sanact \- +.SH SYNOPSIS +enum nvme_sanitize_sanact { +.br +.BI " NVME_SANITIZE_SANACT_EXIT_FAILURE" +, +.br +.br +.BI " NVME_SANITIZE_SANACT_START_BLOCK_ERASE" +, +.br +.br +.BI " NVME_SANITIZE_SANACT_START_OVERWRITE" +, +.br +.br +.BI " NVME_SANITIZE_SANACT_START_CRYPTO_ERASE" + +}; +.SH Constants +.IP "NVME_SANITIZE_SANACT_EXIT_FAILURE" 12 +-- undescribed -- +.IP "NVME_SANITIZE_SANACT_START_BLOCK_ERASE" 12 +-- undescribed -- +.IP "NVME_SANITIZE_SANACT_START_OVERWRITE" 12 +-- undescribed -- +.IP "NVME_SANITIZE_SANACT_START_CRYPTO_ERASE" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_subsys_type.2 b/doc/man/enum nvme_subsys_type.2 new file mode 100644 index 0000000000..17e11b82b5 --- /dev/null +++ b/doc/man/enum nvme_subsys_type.2 @@ -0,0 +1,18 @@ +.TH "libnvme" 2 "enum nvme_subsys_type" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_subsys_type \- +.SH SYNOPSIS +enum nvme_subsys_type { +.br +.BI " NVME_NQN_DISC" +, +.br +.br +.BI " NVME_NQN_NVME" + +}; +.SH Constants +.IP "NVME_NQN_DISC" 12 +Discovery type target subsystem +.IP "NVME_NQN_NVME" 12 +NVME type target subsystem diff --git a/doc/man/enum nvme_virt_mgmt_act.2 b/doc/man/enum nvme_virt_mgmt_act.2 new file mode 100644 index 0000000000..0151350e1d --- /dev/null +++ b/doc/man/enum nvme_virt_mgmt_act.2 @@ -0,0 +1,30 @@ +.TH "libnvme" 2 "enum nvme_virt_mgmt_act" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_virt_mgmt_act \- +.SH SYNOPSIS +enum nvme_virt_mgmt_act { +.br +.BI " NVME_VIRT_MGMT_ACT_PRIM_CTRL_FLEX_ALLOC" +, +.br +.br +.BI " NVME_VIRT_MGMT_ACT_OFFLINE_SEC_CTRL" +, +.br +.br +.BI " NVME_VIRT_MGMT_ACT_ASSIGN_SEC_CTRL" +, +.br +.br +.BI " NVME_VIRT_MGMT_ACT_ONLINE_SEC_CTRL" + +}; +.SH Constants +.IP "NVME_VIRT_MGMT_ACT_PRIM_CTRL_FLEX_ALLOC" 12 +-- undescribed -- +.IP "NVME_VIRT_MGMT_ACT_OFFLINE_SEC_CTRL" 12 +-- undescribed -- +.IP "NVME_VIRT_MGMT_ACT_ASSIGN_SEC_CTRL" 12 +-- undescribed -- +.IP "NVME_VIRT_MGMT_ACT_ONLINE_SEC_CTRL" 12 +-- undescribed -- diff --git a/doc/man/enum nvme_virt_mgmt_rt.2 b/doc/man/enum nvme_virt_mgmt_rt.2 new file mode 100644 index 0000000000..eaaff80a4f --- /dev/null +++ b/doc/man/enum nvme_virt_mgmt_rt.2 @@ -0,0 +1,18 @@ +.TH "libnvme" 2 "enum nvme_virt_mgmt_rt" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +enum nvme_virt_mgmt_rt \- +.SH SYNOPSIS +enum nvme_virt_mgmt_rt { +.br +.BI " NVME_VIRT_MGMT_RT_VQ_RESOURCE" +, +.br +.br +.BI " NVME_VIRT_MGMT_RT_VI_RESOURCE" + +}; +.SH Constants +.IP "NVME_VIRT_MGMT_RT_VQ_RESOURCE" 12 +-- undescribed -- +.IP "NVME_VIRT_MGMT_RT_VI_RESOURCE" 12 +-- undescribed -- diff --git a/doc/man/is_64bit_reg.2 b/doc/man/is_64bit_reg.2 new file mode 100644 index 0000000000..62331f8bac --- /dev/null +++ b/doc/man/is_64bit_reg.2 @@ -0,0 +1,16 @@ +.TH "is_64bit_reg" 2 "is_64bit_reg" "February 2020" "libnvme Manual" +.SH NAME +is_64bit_reg \- Checks if offset of the controller register is 64bit or not. +.SH SYNOPSIS +.B "bool" is_64bit_reg +.BI "(__u32 " offset ");" +.SH ARGUMENTS +.IP "offset" 12 +Offset of controller register field in bytes +.SH "DESCRIPTION" +This function does not care about transport so that the offset is not going +to be checked inside of this function for the unsupported fields in a +specific transport. For example, BPMBL(Boot Partition Memory Buffer +Location) register is not supported by fabrics, but it can be chcked here. + +Returns true if given offset is 64bit register, otherwise it returns false. diff --git a/doc/man/libnvme.2 b/doc/man/libnvme.2 new file mode 100644 index 0000000000..b214923f96 --- /dev/null +++ b/doc/man/libnvme.2 @@ -0,0 +1,2 @@ +.TH "libnvme" 2 "libnvme" "February 2020" "LIBNVME API Manual" LINUX +.SH "NVMe IO command" diff --git a/doc/man/nvme_admin_passthru.2 b/doc/man/nvme_admin_passthru.2 new file mode 100644 index 0000000000..a4f83cd9de --- /dev/null +++ b/doc/man/nvme_admin_passthru.2 @@ -0,0 +1,71 @@ +.TH "nvme_admin_passthru" 2 "nvme_admin_passthru" "February 2020" "libnvme Manual" +.SH NAME +nvme_admin_passthru \- Submit an nvme passthrough command +.SH SYNOPSIS +.B "int" nvme_admin_passthru +.BI "(int " fd "," +.BI "__u8 " opcode "," +.BI "__u8 " flags "," +.BI "__u16 " rsvd "," +.BI "__u32 " nsid "," +.BI "__u32 " cdw2 "," +.BI "__u32 " cdw3 "," +.BI "__u32 " cdw10 "," +.BI "__u32 " cdw11 "," +.BI "__u32 " cdw12 "," +.BI "__u32 " cdw13 "," +.BI "__u32 " cdw14 "," +.BI "__u32 " cdw15 "," +.BI "__u32 " data_len "," +.BI "void *" data "," +.BI "__u32 " metadata_len "," +.BI "void *" metadata "," +.BI "__u32 " timeout_ms "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "opcode" 12 +The nvme io command to send +.IP "flags" 12 +NVMe command flags (not used) +.IP "rsvd" 12 +Reserevd for future use +.IP "nsid" 12 +Namespace identifier +.IP "cdw2" 12 +Command dword 2 +.IP "cdw3" 12 +Command dword 3 +.IP "cdw10" 12 +Command dword 10 +.IP "cdw11" 12 +Command dword 11 +.IP "cdw12" 12 +Command dword 12 +.IP "cdw13" 12 +Command dword 13 +.IP "cdw14" 12 +Command dword 14 +.IP "cdw15" 12 +Command dword 15 +.IP "data_len" 12 +Length of the data transfered in this command in bytes +.IP "data" 12 +Pointer to user address of the data buffer +.IP "metadata_len" 12 +Length of metadata transfered in this command +.IP "metadata" 12 +Pointer to user address of the metadata buffer +.IP "timeout_ms" 12 +How long the kernel waits for the command to complete +.IP "result" 12 +Optional field to return the result from the CQE dword 0 +.SH "DESCRIPTION" +Parameterized form of \fBnvme_submit_admin_passthru\fP. This sets up and +submits a \fIstruct nvme_passthru_cmd\fP. + +Known values for \fIopcode\fP are defined in \fIenum nvme_admin_opcode\fP. +.SH "RETURN" +The nvme command status if a response was received or -1 +with errno set otherwise. diff --git a/doc/man/nvme_admin_passthru64.2 b/doc/man/nvme_admin_passthru64.2 new file mode 100644 index 0000000000..46b10f7e7e --- /dev/null +++ b/doc/man/nvme_admin_passthru64.2 @@ -0,0 +1,71 @@ +.TH "nvme_admin_passthru64" 2 "nvme_admin_passthru64" "February 2020" "libnvme Manual" +.SH NAME +nvme_admin_passthru64 \- Submit an nvme passthrough command +.SH SYNOPSIS +.B "int" nvme_admin_passthru64 +.BI "(int " fd "," +.BI "__u8 " opcode "," +.BI "__u8 " flags "," +.BI "__u16 " rsvd "," +.BI "__u32 " nsid "," +.BI "__u32 " cdw2 "," +.BI "__u32 " cdw3 "," +.BI "__u32 " cdw10 "," +.BI "__u32 " cdw11 "," +.BI "__u32 " cdw12 "," +.BI "__u32 " cdw13 "," +.BI "__u32 " cdw14 "," +.BI "__u32 " cdw15 "," +.BI "__u32 " data_len "," +.BI "void *" data "," +.BI "__u32 " metadata_len "," +.BI "void *" metadata "," +.BI "__u32 " timeout_ms "," +.BI "__u64 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "opcode" 12 +The nvme io command to send +.IP "flags" 12 +NVMe command flags (not used) +.IP "rsvd" 12 +Reserevd for future use +.IP "nsid" 12 +Namespace identifier +.IP "cdw2" 12 +Command dword 2 +.IP "cdw3" 12 +Command dword 3 +.IP "cdw10" 12 +Command dword 10 +.IP "cdw11" 12 +Command dword 11 +.IP "cdw12" 12 +Command dword 12 +.IP "cdw13" 12 +Command dword 13 +.IP "cdw14" 12 +Command dword 14 +.IP "cdw15" 12 +Command dword 15 +.IP "data_len" 12 +Length of the data transfered in this command in bytes +.IP "data" 12 +Pointer to user address of the data buffer +.IP "metadata_len" 12 +Length of metadata transfered in this command +.IP "metadata" 12 +Pointer to user address of the metadata buffer +.IP "timeout_ms" 12 +How long the kernel waits for the command to complete +.IP "result" 12 +Optional field to return the result from the CQE dword 0 +.SH "DESCRIPTION" +Parameterized form of \fBnvme_submit_admin_passthru64\fP. This sets up and +submits a \fIstruct nvme_passthru_cmd64\fP. + +Known values for \fIopcode\fP are defined in \fIenum nvme_admin_opcode\fP. +.SH "RETURN" +The nvme command status if a response was received or -1 +with errno set otherwise. diff --git a/doc/man/nvme_compare.2 b/doc/man/nvme_compare.2 new file mode 100644 index 0000000000..fc93bd877d --- /dev/null +++ b/doc/man/nvme_compare.2 @@ -0,0 +1,52 @@ +.TH "nvme_compare" 2 "nvme_compare" "February 2020" "libnvme Manual" +.SH NAME +nvme_compare \- Submit an nvme user compare command +.SH SYNOPSIS +.B "int" nvme_compare +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "__u64 " slba "," +.BI "__u16 " nlb "," +.BI "__u16 " control "," +.BI "__u32 " reftag "," +.BI "__u16 " apptag "," +.BI "__u16 " appmask "," +.BI "__u32 " data_len "," +.BI "void *" data "," +.BI "__u32 " metadata_len "," +.BI "void *" metadata ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Namespace ID +.IP "slba" 12 +Starting logical block +.IP "nlb" 12 +-- undescribed -- +.IP "control" 12 +Command control flags, see \fIenum nvme_io_control_flags\fP. +.IP "reftag" 12 +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. +.IP "apptag" 12 +This field specifies the Application Tag Mask expected value. +Used only if the namespace is formatted to use end-to-end +protection information. +.IP "appmask" 12 +This field specifies the Application Tag expected value. Used +only if the namespace is formatted to use end-to-end protection +information. +.IP "data_len" 12 +Length of user buffer, \fIdata\fP, in bytes +.IP "data" 12 +Pointer to user address of the data buffer +metadata_len:Length of user buffer, \fImetadata\fP, in bytes +.IP "metadata_len" 12 +-- undescribed -- +.IP "metadata" 12 +Pointer to user address of the metadata buffer +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_ctrl_disconnect.2 b/doc/man/nvme_ctrl_disconnect.2 new file mode 100644 index 0000000000..9ad29a6827 --- /dev/null +++ b/doc/man/nvme_ctrl_disconnect.2 @@ -0,0 +1,8 @@ +.TH "nvme_ctrl_disconnect" 2 "nvme_ctrl_disconnect" "February 2020" "libnvme Manual" +.SH NAME +nvme_ctrl_disconnect \- +.SH SYNOPSIS +.B "int" nvme_ctrl_disconnect +.BI "(nvme_ctrl_t " c ");" +.SH ARGUMENTS +.IP "c" 12 diff --git a/doc/man/nvme_ctrl_first_ns.2 b/doc/man/nvme_ctrl_first_ns.2 new file mode 100644 index 0000000000..c73e541351 --- /dev/null +++ b/doc/man/nvme_ctrl_first_ns.2 @@ -0,0 +1,8 @@ +.TH "nvme_ctrl_first_ns" 2 "nvme_ctrl_first_ns" "February 2020" "libnvme Manual" +.SH NAME +nvme_ctrl_first_ns \- +.SH SYNOPSIS +.B "nvme_ns_t" nvme_ctrl_first_ns +.BI "(nvme_ctrl_t " c ");" +.SH ARGUMENTS +.IP "c" 12 diff --git a/doc/man/nvme_ctrl_first_path.2 b/doc/man/nvme_ctrl_first_path.2 new file mode 100644 index 0000000000..74f95c027b --- /dev/null +++ b/doc/man/nvme_ctrl_first_path.2 @@ -0,0 +1,8 @@ +.TH "nvme_ctrl_first_path" 2 "nvme_ctrl_first_path" "February 2020" "libnvme Manual" +.SH NAME +nvme_ctrl_first_path \- +.SH SYNOPSIS +.B "nvme_path_t" nvme_ctrl_first_path +.BI "(nvme_ctrl_t " c ");" +.SH ARGUMENTS +.IP "c" 12 diff --git a/doc/man/nvme_ctrl_for_each_ns.2 b/doc/man/nvme_ctrl_for_each_ns.2 new file mode 100644 index 0000000000..d0abb504e1 --- /dev/null +++ b/doc/man/nvme_ctrl_for_each_ns.2 @@ -0,0 +1,12 @@ +.TH "nvme_ctrl_for_each_ns" 2 "nvme_ctrl_for_each_ns" "February 2020" "libnvme Manual" +.SH NAME +nvme_ctrl_for_each_ns \- +.SH SYNOPSIS +.B "nvme_ctrl_for_each_ns +.BI "(" c "," +.BI "" n ");" +.SH ARGUMENTS +.IP "c" 12 +-- undescribed -- +.IP "n" 12 +-- undescribed -- diff --git a/doc/man/nvme_ctrl_for_each_ns_safe.2 b/doc/man/nvme_ctrl_for_each_ns_safe.2 new file mode 100644 index 0000000000..e5697bfaa6 --- /dev/null +++ b/doc/man/nvme_ctrl_for_each_ns_safe.2 @@ -0,0 +1,15 @@ +.TH "nvme_ctrl_for_each_ns_safe" 2 "nvme_ctrl_for_each_ns_safe" "February 2020" "libnvme Manual" +.SH NAME +nvme_ctrl_for_each_ns_safe \- +.SH SYNOPSIS +.B "nvme_ctrl_for_each_ns_safe +.BI "(" c "," +.BI "" n "," +.BI "" _n ");" +.SH ARGUMENTS +.IP "c" 12 +-- undescribed -- +.IP "n" 12 +-- undescribed -- +.IP "_n" 12 +-- undescribed -- diff --git a/doc/man/nvme_ctrl_for_each_path.2 b/doc/man/nvme_ctrl_for_each_path.2 new file mode 100644 index 0000000000..c4b20218e3 --- /dev/null +++ b/doc/man/nvme_ctrl_for_each_path.2 @@ -0,0 +1,12 @@ +.TH "nvme_ctrl_for_each_path" 2 "nvme_ctrl_for_each_path" "February 2020" "libnvme Manual" +.SH NAME +nvme_ctrl_for_each_path \- +.SH SYNOPSIS +.B "nvme_ctrl_for_each_path +.BI "(" c "," +.BI "" p ");" +.SH ARGUMENTS +.IP "c" 12 +-- undescribed -- +.IP "p" 12 +-- undescribed -- diff --git a/doc/man/nvme_ctrl_for_each_path_safe.2 b/doc/man/nvme_ctrl_for_each_path_safe.2 new file mode 100644 index 0000000000..1cbe96e95a --- /dev/null +++ b/doc/man/nvme_ctrl_for_each_path_safe.2 @@ -0,0 +1,15 @@ +.TH "nvme_ctrl_for_each_path_safe" 2 "nvme_ctrl_for_each_path_safe" "February 2020" "libnvme Manual" +.SH NAME +nvme_ctrl_for_each_path_safe \- +.SH SYNOPSIS +.B "nvme_ctrl_for_each_path_safe +.BI "(" c "," +.BI "" p "," +.BI "" _p ");" +.SH ARGUMENTS +.IP "c" 12 +-- undescribed -- +.IP "p" 12 +-- undescribed -- +.IP "_p" 12 +-- undescribed -- diff --git a/doc/man/nvme_ctrl_get_address.2 b/doc/man/nvme_ctrl_get_address.2 new file mode 100644 index 0000000000..e3b49904c0 --- /dev/null +++ b/doc/man/nvme_ctrl_get_address.2 @@ -0,0 +1,8 @@ +.TH "nvme_ctrl_get_address" 2 "nvme_ctrl_get_address" "February 2020" "libnvme Manual" +.SH NAME +nvme_ctrl_get_address \- +.SH SYNOPSIS +.B "const char *" nvme_ctrl_get_address +.BI "(nvme_ctrl_t " c ");" +.SH ARGUMENTS +.IP "c" 12 diff --git a/doc/man/nvme_ctrl_get_fd.2 b/doc/man/nvme_ctrl_get_fd.2 new file mode 100644 index 0000000000..f268f64fe9 --- /dev/null +++ b/doc/man/nvme_ctrl_get_fd.2 @@ -0,0 +1,8 @@ +.TH "nvme_ctrl_get_fd" 2 "nvme_ctrl_get_fd" "February 2020" "libnvme Manual" +.SH NAME +nvme_ctrl_get_fd \- +.SH SYNOPSIS +.B "int" nvme_ctrl_get_fd +.BI "(nvme_ctrl_t " c ");" +.SH ARGUMENTS +.IP "c" 12 diff --git a/doc/man/nvme_ctrl_get_firmware.2 b/doc/man/nvme_ctrl_get_firmware.2 new file mode 100644 index 0000000000..18ac42a6d1 --- /dev/null +++ b/doc/man/nvme_ctrl_get_firmware.2 @@ -0,0 +1,8 @@ +.TH "nvme_ctrl_get_firmware" 2 "nvme_ctrl_get_firmware" "February 2020" "libnvme Manual" +.SH NAME +nvme_ctrl_get_firmware \- +.SH SYNOPSIS +.B "const char *" nvme_ctrl_get_firmware +.BI "(nvme_ctrl_t " c ");" +.SH ARGUMENTS +.IP "c" 12 diff --git a/doc/man/nvme_ctrl_get_model.2 b/doc/man/nvme_ctrl_get_model.2 new file mode 100644 index 0000000000..8b1013e1d9 --- /dev/null +++ b/doc/man/nvme_ctrl_get_model.2 @@ -0,0 +1,8 @@ +.TH "nvme_ctrl_get_model" 2 "nvme_ctrl_get_model" "February 2020" "libnvme Manual" +.SH NAME +nvme_ctrl_get_model \- +.SH SYNOPSIS +.B "const char *" nvme_ctrl_get_model +.BI "(nvme_ctrl_t " c ");" +.SH ARGUMENTS +.IP "c" 12 diff --git a/doc/man/nvme_ctrl_get_name.2 b/doc/man/nvme_ctrl_get_name.2 new file mode 100644 index 0000000000..e0b73933fd --- /dev/null +++ b/doc/man/nvme_ctrl_get_name.2 @@ -0,0 +1,8 @@ +.TH "nvme_ctrl_get_name" 2 "nvme_ctrl_get_name" "February 2020" "libnvme Manual" +.SH NAME +nvme_ctrl_get_name \- +.SH SYNOPSIS +.B "const char *" nvme_ctrl_get_name +.BI "(nvme_ctrl_t " c ");" +.SH ARGUMENTS +.IP "c" 12 diff --git a/doc/man/nvme_ctrl_get_nqn.2 b/doc/man/nvme_ctrl_get_nqn.2 new file mode 100644 index 0000000000..47180ac2c9 --- /dev/null +++ b/doc/man/nvme_ctrl_get_nqn.2 @@ -0,0 +1,8 @@ +.TH "nvme_ctrl_get_nqn" 2 "nvme_ctrl_get_nqn" "February 2020" "libnvme Manual" +.SH NAME +nvme_ctrl_get_nqn \- +.SH SYNOPSIS +.B "const char *" nvme_ctrl_get_nqn +.BI "(nvme_ctrl_t " c ");" +.SH ARGUMENTS +.IP "c" 12 diff --git a/doc/man/nvme_ctrl_get_numa_node.2 b/doc/man/nvme_ctrl_get_numa_node.2 new file mode 100644 index 0000000000..93a856d972 --- /dev/null +++ b/doc/man/nvme_ctrl_get_numa_node.2 @@ -0,0 +1,8 @@ +.TH "nvme_ctrl_get_numa_node" 2 "nvme_ctrl_get_numa_node" "February 2020" "libnvme Manual" +.SH NAME +nvme_ctrl_get_numa_node \- +.SH SYNOPSIS +.B "const char *" nvme_ctrl_get_numa_node +.BI "(nvme_ctrl_t " c ");" +.SH ARGUMENTS +.IP "c" 12 diff --git a/doc/man/nvme_ctrl_get_queue_count.2 b/doc/man/nvme_ctrl_get_queue_count.2 new file mode 100644 index 0000000000..63bfa969f2 --- /dev/null +++ b/doc/man/nvme_ctrl_get_queue_count.2 @@ -0,0 +1,8 @@ +.TH "nvme_ctrl_get_queue_count" 2 "nvme_ctrl_get_queue_count" "February 2020" "libnvme Manual" +.SH NAME +nvme_ctrl_get_queue_count \- +.SH SYNOPSIS +.B "const char *" nvme_ctrl_get_queue_count +.BI "(nvme_ctrl_t " c ");" +.SH ARGUMENTS +.IP "c" 12 diff --git a/doc/man/nvme_ctrl_get_serial.2 b/doc/man/nvme_ctrl_get_serial.2 new file mode 100644 index 0000000000..7e417e701e --- /dev/null +++ b/doc/man/nvme_ctrl_get_serial.2 @@ -0,0 +1,8 @@ +.TH "nvme_ctrl_get_serial" 2 "nvme_ctrl_get_serial" "February 2020" "libnvme Manual" +.SH NAME +nvme_ctrl_get_serial \- +.SH SYNOPSIS +.B "const char *" nvme_ctrl_get_serial +.BI "(nvme_ctrl_t " c ");" +.SH ARGUMENTS +.IP "c" 12 diff --git a/doc/man/nvme_ctrl_get_sqsize.2 b/doc/man/nvme_ctrl_get_sqsize.2 new file mode 100644 index 0000000000..938eaee8d3 --- /dev/null +++ b/doc/man/nvme_ctrl_get_sqsize.2 @@ -0,0 +1,8 @@ +.TH "nvme_ctrl_get_sqsize" 2 "nvme_ctrl_get_sqsize" "February 2020" "libnvme Manual" +.SH NAME +nvme_ctrl_get_sqsize \- +.SH SYNOPSIS +.B "const char *" nvme_ctrl_get_sqsize +.BI "(nvme_ctrl_t " c ");" +.SH ARGUMENTS +.IP "c" 12 diff --git a/doc/man/nvme_ctrl_get_state.2 b/doc/man/nvme_ctrl_get_state.2 new file mode 100644 index 0000000000..8bfa163c51 --- /dev/null +++ b/doc/man/nvme_ctrl_get_state.2 @@ -0,0 +1,8 @@ +.TH "nvme_ctrl_get_state" 2 "nvme_ctrl_get_state" "February 2020" "libnvme Manual" +.SH NAME +nvme_ctrl_get_state \- +.SH SYNOPSIS +.B "const char *" nvme_ctrl_get_state +.BI "(nvme_ctrl_t " c ");" +.SH ARGUMENTS +.IP "c" 12 diff --git a/doc/man/nvme_ctrl_get_subsysnqn.2 b/doc/man/nvme_ctrl_get_subsysnqn.2 new file mode 100644 index 0000000000..a4505a11d0 --- /dev/null +++ b/doc/man/nvme_ctrl_get_subsysnqn.2 @@ -0,0 +1,8 @@ +.TH "nvme_ctrl_get_subsysnqn" 2 "nvme_ctrl_get_subsysnqn" "February 2020" "libnvme Manual" +.SH NAME +nvme_ctrl_get_subsysnqn \- +.SH SYNOPSIS +.B "const char *" nvme_ctrl_get_subsysnqn +.BI "(nvme_ctrl_t " c ");" +.SH ARGUMENTS +.IP "c" 12 diff --git a/doc/man/nvme_ctrl_get_subsystem.2 b/doc/man/nvme_ctrl_get_subsystem.2 new file mode 100644 index 0000000000..812eb9b7e7 --- /dev/null +++ b/doc/man/nvme_ctrl_get_subsystem.2 @@ -0,0 +1,8 @@ +.TH "nvme_ctrl_get_subsystem" 2 "nvme_ctrl_get_subsystem" "February 2020" "libnvme Manual" +.SH NAME +nvme_ctrl_get_subsystem \- +.SH SYNOPSIS +.B "nvme_subsystem_t" nvme_ctrl_get_subsystem +.BI "(nvme_ctrl_t " c ");" +.SH ARGUMENTS +.IP "c" 12 diff --git a/doc/man/nvme_ctrl_get_sysfs_dir.2 b/doc/man/nvme_ctrl_get_sysfs_dir.2 new file mode 100644 index 0000000000..7de493fc45 --- /dev/null +++ b/doc/man/nvme_ctrl_get_sysfs_dir.2 @@ -0,0 +1,8 @@ +.TH "nvme_ctrl_get_sysfs_dir" 2 "nvme_ctrl_get_sysfs_dir" "February 2020" "libnvme Manual" +.SH NAME +nvme_ctrl_get_sysfs_dir \- +.SH SYNOPSIS +.B "const char *" nvme_ctrl_get_sysfs_dir +.BI "(nvme_ctrl_t " c ");" +.SH ARGUMENTS +.IP "c" 12 diff --git a/doc/man/nvme_ctrl_get_transport.2 b/doc/man/nvme_ctrl_get_transport.2 new file mode 100644 index 0000000000..8e9d2e5dd8 --- /dev/null +++ b/doc/man/nvme_ctrl_get_transport.2 @@ -0,0 +1,8 @@ +.TH "nvme_ctrl_get_transport" 2 "nvme_ctrl_get_transport" "February 2020" "libnvme Manual" +.SH NAME +nvme_ctrl_get_transport \- +.SH SYNOPSIS +.B "const char *" nvme_ctrl_get_transport +.BI "(nvme_ctrl_t " c ");" +.SH ARGUMENTS +.IP "c" 12 diff --git a/doc/man/nvme_ctrl_identify.2 b/doc/man/nvme_ctrl_identify.2 new file mode 100644 index 0000000000..c29769a433 --- /dev/null +++ b/doc/man/nvme_ctrl_identify.2 @@ -0,0 +1,11 @@ +.TH "nvme_ctrl_identify" 2 "nvme_ctrl_identify" "February 2020" "libnvme Manual" +.SH NAME +nvme_ctrl_identify \- +.SH SYNOPSIS +.B "int" nvme_ctrl_identify +.BI "(nvme_ctrl_t " c "," +.BI "struct nvme_id_ctrl *" id ");" +.SH ARGUMENTS +.IP "c" 12 +-- undescribed -- +.IP "id" 12 diff --git a/doc/man/nvme_ctrl_next_ns.2 b/doc/man/nvme_ctrl_next_ns.2 new file mode 100644 index 0000000000..36b7863c57 --- /dev/null +++ b/doc/man/nvme_ctrl_next_ns.2 @@ -0,0 +1,11 @@ +.TH "nvme_ctrl_next_ns" 2 "nvme_ctrl_next_ns" "February 2020" "libnvme Manual" +.SH NAME +nvme_ctrl_next_ns \- +.SH SYNOPSIS +.B "nvme_ns_t" nvme_ctrl_next_ns +.BI "(nvme_ctrl_t " c "," +.BI "nvme_ns_t " n ");" +.SH ARGUMENTS +.IP "c" 12 +-- undescribed -- +.IP "n" 12 diff --git a/doc/man/nvme_ctrl_next_path.2 b/doc/man/nvme_ctrl_next_path.2 new file mode 100644 index 0000000000..bd205ad2e5 --- /dev/null +++ b/doc/man/nvme_ctrl_next_path.2 @@ -0,0 +1,11 @@ +.TH "nvme_ctrl_next_path" 2 "nvme_ctrl_next_path" "February 2020" "libnvme Manual" +.SH NAME +nvme_ctrl_next_path \- +.SH SYNOPSIS +.B "nvme_path_t" nvme_ctrl_next_path +.BI "(nvme_ctrl_t " c "," +.BI "nvme_path_t " p ");" +.SH ARGUMENTS +.IP "c" 12 +-- undescribed -- +.IP "p" 12 diff --git a/doc/man/nvme_ctrl_reset.2 b/doc/man/nvme_ctrl_reset.2 new file mode 100644 index 0000000000..9ff7841e34 --- /dev/null +++ b/doc/man/nvme_ctrl_reset.2 @@ -0,0 +1,13 @@ +.TH "nvme_ctrl_reset" 2 "nvme_ctrl_reset" "February 2020" "libnvme Manual" +.SH NAME +nvme_ctrl_reset \- Initiate a controller reset +.SH SYNOPSIS +.B "int" nvme_ctrl_reset +.BI "(int " fd ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.SH "DESCRIPTION" +This should only be sent to controller handles, not to namespaces. +.SH "RETURN" +Zero if a reset was initiated or -1 with errno set otherwise. diff --git a/doc/man/nvme_ctrls_filter.2 b/doc/man/nvme_ctrls_filter.2 new file mode 100644 index 0000000000..c3695924a9 --- /dev/null +++ b/doc/man/nvme_ctrls_filter.2 @@ -0,0 +1,8 @@ +.TH "nvme_ctrls_filter" 2 "nvme_ctrls_filter" "February 2020" "libnvme Manual" +.SH NAME +nvme_ctrls_filter \- +.SH SYNOPSIS +.B "int" nvme_ctrls_filter +.BI "(const struct dirent *" d ");" +.SH ARGUMENTS +.IP "d" 12 diff --git a/doc/man/nvme_dev_self_test.2 b/doc/man/nvme_dev_self_test.2 new file mode 100644 index 0000000000..09aa25c5aa --- /dev/null +++ b/doc/man/nvme_dev_self_test.2 @@ -0,0 +1,29 @@ +.TH "nvme_dev_self_test" 2 "nvme_dev_self_test" "February 2020" "libnvme Manual" +.SH NAME +nvme_dev_self_test \- Start or abort a self test +.SH SYNOPSIS +.B "int" nvme_dev_self_test +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "enum nvme_dst_stc " stc ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Namespace ID to test +.IP "stc" 12 +Self test code, see \fIenum nvme_dst_stc\fP +.SH "DESCRIPTION" +The Device Self-test command is used to start a device self-test operation +or abort a device self-test operation. A device self-test operation is a +diagnostic testing sequence that tests the integrity and functionality of +the controller and may include testing of the media associated with +namespaces. The controller may return a response to this command immediately +while running the self-test in the background. + +Set the 'nsid' field to 0 to not include namepsaces in the test. Set to +0xffffffff to test all namespaces. All other values tests a specific +namespace, if present. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_directive_recv.2 b/doc/man/nvme_directive_recv.2 new file mode 100644 index 0000000000..208a9fc65d --- /dev/null +++ b/doc/man/nvme_directive_recv.2 @@ -0,0 +1,36 @@ +.TH "nvme_directive_recv" 2 "nvme_directive_recv" "February 2020" "libnvme Manual" +.SH NAME +nvme_directive_recv \- Receive directive specific data +.SH SYNOPSIS +.B "int" nvme_directive_recv +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "__u16 " dspec "," +.BI "enum nvme_directive_receive_doper " doper "," +.BI "enum nvme_directive_dtype " dtype "," +.BI "__u32 " cdw12 "," +.BI "__u32 " data_len "," +.BI "void *" data "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Namespace ID, if applicable +.IP "dspec" 12 +Directive specific field +.IP "doper" 12 +Directive receive operation, see \fIenum nvme_directive_receive_doper\fP +.IP "dtype" 12 +Directive type, see \fIenum nvme_directive_dtype\fP +.IP "cdw12" 12 +-- undescribed -- +.IP "data_len" 12 +Length of data payload +.IP "data" 12 +Usespace address of data payload in bytes +.IP "result" 12 +If successful, the CQE dword0 value +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_directive_recv_identify_parameters.2 b/doc/man/nvme_directive_recv_identify_parameters.2 new file mode 100644 index 0000000000..5553410e0d --- /dev/null +++ b/doc/man/nvme_directive_recv_identify_parameters.2 @@ -0,0 +1,18 @@ +.TH "nvme_directive_recv_identify_parameters" 2 "nvme_directive_recv_identify_parameters" "February 2020" "libnvme Manual" +.SH NAME +nvme_directive_recv_identify_parameters \- +.SH SYNOPSIS +.B "int" nvme_directive_recv_identify_parameters +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "struct nvme_id_directives *" id ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Namespace ID +.IP "id" 12 +-- undescribed -- +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_directive_recv_stream_allocate.2 b/doc/man/nvme_directive_recv_stream_allocate.2 new file mode 100644 index 0000000000..c813c78d2e --- /dev/null +++ b/doc/man/nvme_directive_recv_stream_allocate.2 @@ -0,0 +1,21 @@ +.TH "nvme_directive_recv_stream_allocate" 2 "nvme_directive_recv_stream_allocate" "February 2020" "libnvme Manual" +.SH NAME +nvme_directive_recv_stream_allocate \- +.SH SYNOPSIS +.B "int" nvme_directive_recv_stream_allocate +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "__u16 " nsr "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Namespace ID +.IP "nsr" 12 +-- undescribed -- +.IP "result" 12 +-- undescribed -- +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_directive_recv_stream_parameters.2 b/doc/man/nvme_directive_recv_stream_parameters.2 new file mode 100644 index 0000000000..2fbb5b2d5a --- /dev/null +++ b/doc/man/nvme_directive_recv_stream_parameters.2 @@ -0,0 +1,18 @@ +.TH "nvme_directive_recv_stream_parameters" 2 "nvme_directive_recv_stream_parameters" "February 2020" "libnvme Manual" +.SH NAME +nvme_directive_recv_stream_parameters \- +.SH SYNOPSIS +.B "int" nvme_directive_recv_stream_parameters +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "struct nvme_streams_directive_params *" parms ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Namespace ID +.IP "parms" 12 +-- undescribed -- +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_directive_recv_stream_status.2 b/doc/man/nvme_directive_recv_stream_status.2 new file mode 100644 index 0000000000..027a029efd --- /dev/null +++ b/doc/man/nvme_directive_recv_stream_status.2 @@ -0,0 +1,21 @@ +.TH "nvme_directive_recv_stream_status" 2 "nvme_directive_recv_stream_status" "February 2020" "libnvme Manual" +.SH NAME +nvme_directive_recv_stream_status \- +.SH SYNOPSIS +.B "int" nvme_directive_recv_stream_status +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "unsigned " nr_entries "," +.BI "struct nvme_streams_directive_status *" id ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Namespace ID +.IP "nr_entries" 12 +-- undescribed -- +.IP "id" 12 +-- undescribed -- +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_directive_send.2 b/doc/man/nvme_directive_send.2 new file mode 100644 index 0000000000..8847383a23 --- /dev/null +++ b/doc/man/nvme_directive_send.2 @@ -0,0 +1,42 @@ +.TH "nvme_directive_send" 2 "nvme_directive_send" "February 2020" "libnvme Manual" +.SH NAME +nvme_directive_send \- Send directive command +.SH SYNOPSIS +.B "int" nvme_directive_send +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "__u16 " dspec "," +.BI "enum nvme_directive_send_doper " doper "," +.BI "enum nvme_directive_dtype " dtype "," +.BI "__u32 " cdw12 "," +.BI "__u32 " data_len "," +.BI "void *" data "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Namespace ID, if applicable +.IP "dspec" 12 +Directive specific field +.IP "doper" 12 +Directive send operation, see \fIenum nvme_directive_send_doper\fP +.IP "dtype" 12 +Directive type, see \fIenum nvme_directive_dtype\fP +.IP "cdw12" 12 +-- undescribed -- +.IP "data_len" 12 +Length of data payload in bytes +.IP "data" 12 +Usespace address of data payload +.IP "result" 12 +If successful, the CQE dword0 value +.SH "DESCRIPTION" +Directives is a mechanism to enable host and NVM subsystem or controller +information exchange. The Directive Send command is used to transfer data +related to a specific Directive Type from the host to the controller. + +See the NVMe specification for more information. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_directive_send_id_endir.2 b/doc/man/nvme_directive_send_id_endir.2 new file mode 100644 index 0000000000..76d3bcb7eb --- /dev/null +++ b/doc/man/nvme_directive_send_id_endir.2 @@ -0,0 +1,24 @@ +.TH "nvme_directive_send_id_endir" 2 "nvme_directive_send_id_endir" "February 2020" "libnvme Manual" +.SH NAME +nvme_directive_send_id_endir \- +.SH SYNOPSIS +.B "int" nvme_directive_send_id_endir +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "bool " endir "," +.BI "enum nvme_directive_dtype " dtype "," +.BI "struct nvme_id_directives *" id ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Namespace ID +.IP "endir" 12 +-- undescribed -- +.IP "dtype" 12 +-- undescribed -- +.IP "id" 12 +-- undescribed -- +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_directive_send_stream_release_identifier.2 b/doc/man/nvme_directive_send_stream_release_identifier.2 new file mode 100644 index 0000000000..bad7cc37d2 --- /dev/null +++ b/doc/man/nvme_directive_send_stream_release_identifier.2 @@ -0,0 +1,18 @@ +.TH "nvme_directive_send_stream_release_identifier" 2 "nvme_directive_send_stream_release_identifier" "February 2020" "libnvme Manual" +.SH NAME +nvme_directive_send_stream_release_identifier \- +.SH SYNOPSIS +.B "int" nvme_directive_send_stream_release_identifier +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "__u16 " stream_id ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Namespace ID +.IP "stream_id" 12 +-- undescribed -- +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_directive_send_stream_release_resource.2 b/doc/man/nvme_directive_send_stream_release_resource.2 new file mode 100644 index 0000000000..e1852a3913 --- /dev/null +++ b/doc/man/nvme_directive_send_stream_release_resource.2 @@ -0,0 +1,15 @@ +.TH "nvme_directive_send_stream_release_resource" 2 "nvme_directive_send_stream_release_resource" "February 2020" "libnvme Manual" +.SH NAME +nvme_directive_send_stream_release_resource \- +.SH SYNOPSIS +.B "int" nvme_directive_send_stream_release_resource +.BI "(int " fd "," +.BI "__u32 " nsid ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Namespace ID +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_dsm.2 b/doc/man/nvme_dsm.2 new file mode 100644 index 0000000000..7b2e7f1926 --- /dev/null +++ b/doc/man/nvme_dsm.2 @@ -0,0 +1,31 @@ +.TH "nvme_dsm" 2 "nvme_dsm" "February 2020" "libnvme Manual" +.SH NAME +nvme_dsm \- Send an nvme data set management command +.SH SYNOPSIS +.B "int" nvme_dsm +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "__u32 " attrs "," +.BI "__u16 " nr_ranges "," +.BI "struct nvme_dsm_range *" dsm ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Namespace identifier +.IP "attrs" 12 +DSM attributes, see \fIenum nvme_dsm_attributes\fP +\fInr_ranges\fP: Number of block ranges in the data set management attributes +.IP "nr_ranges" 12 +-- undescribed -- +.IP "dsm" 12 +The data set management attributes +.SH "DESCRIPTION" +The Dataset Management command is used by the host to indicate attributes +for ranges of logical blocks. This includes attributes like frequency that +data is read or written, access size, and other information that may be used +to optimize performance and reliability, and may be used to +deallocate/unmap/trim those logical blocks. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_first_subsystem.2 b/doc/man/nvme_first_subsystem.2 new file mode 100644 index 0000000000..bcc1bc5879 --- /dev/null +++ b/doc/man/nvme_first_subsystem.2 @@ -0,0 +1,8 @@ +.TH "nvme_first_subsystem" 2 "nvme_first_subsystem" "February 2020" "libnvme Manual" +.SH NAME +nvme_first_subsystem \- +.SH SYNOPSIS +.B "nvme_subsystem_t" nvme_first_subsystem +.BI "(nvme_root_t " r ");" +.SH ARGUMENTS +.IP "r" 12 diff --git a/doc/man/nvme_flush.2 b/doc/man/nvme_flush.2 new file mode 100644 index 0000000000..090cf19d6f --- /dev/null +++ b/doc/man/nvme_flush.2 @@ -0,0 +1,18 @@ +.TH "nvme_flush" 2 "nvme_flush" "February 2020" "libnvme Manual" +.SH NAME +nvme_flush \- Send an nvme flush command +.SH SYNOPSIS +.B "int" nvme_flush +.BI "(int " fd "," +.BI "__u32 " nsid ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Namespace identifier +.SH "DESCRIPTION" +The Flush command is used to request that the contents of volatile write +cache be made non-volatile. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_for_each_subsystem.2 b/doc/man/nvme_for_each_subsystem.2 new file mode 100644 index 0000000000..2cfeca5c78 --- /dev/null +++ b/doc/man/nvme_for_each_subsystem.2 @@ -0,0 +1,12 @@ +.TH "nvme_for_each_subsystem" 2 "nvme_for_each_subsystem" "February 2020" "libnvme Manual" +.SH NAME +nvme_for_each_subsystem \- +.SH SYNOPSIS +.B "nvme_for_each_subsystem +.BI "(" r "," +.BI "" s ");" +.SH ARGUMENTS +.IP "r" 12 +-- undescribed -- +.IP "s" 12 +-- undescribed -- diff --git a/doc/man/nvme_for_each_subsystem_safe.2 b/doc/man/nvme_for_each_subsystem_safe.2 new file mode 100644 index 0000000000..5604544a84 --- /dev/null +++ b/doc/man/nvme_for_each_subsystem_safe.2 @@ -0,0 +1,15 @@ +.TH "nvme_for_each_subsystem_safe" 2 "nvme_for_each_subsystem_safe" "February 2020" "libnvme Manual" +.SH NAME +nvme_for_each_subsystem_safe \- +.SH SYNOPSIS +.B "nvme_for_each_subsystem_safe +.BI "(" r "," +.BI "" s "," +.BI "" _s ");" +.SH ARGUMENTS +.IP "r" 12 +-- undescribed -- +.IP "s" 12 +-- undescribed -- +.IP "_s" 12 +-- undescribed -- diff --git a/doc/man/nvme_format_nvm.2 b/doc/man/nvme_format_nvm.2 new file mode 100644 index 0000000000..87023b3655 --- /dev/null +++ b/doc/man/nvme_format_nvm.2 @@ -0,0 +1,39 @@ +.TH "nvme_format_nvm" 2 "nvme_format_nvm" "February 2020" "libnvme Manual" +.SH NAME +nvme_format_nvm \- Format nvme namespace(s) +.SH SYNOPSIS +.B "int" nvme_format_nvm +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "__u8 " lbaf "," +.BI "enum nvme_cmd_format_mset " mset "," +.BI "enum nvme_cmd_format_pi " pi "," +.BI "enum nvme_cmd_format_pil " pil "," +.BI "enum nvme_cmd_format_ses " ses "," +.BI "__u32 " timeout ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Namespace ID to format +.IP "lbaf" 12 +Logical block address format +.IP "mset" 12 +Metadata settings (extended or separated), true if extended +.IP "pi" 12 +Protection information type +.IP "pil" 12 +Protection information location (beginning or end), true if end +.IP "ses" 12 +Secure erase settings +.IP "timeout" 12 +Set to override default timeout to this value in milliseconds; +useful for long running formats. 0 will use system default. +.SH "DESCRIPTION" +The Format NVM command is used to low level format the NVM media. This +command is used by the host to change the LBA data size and/or metadata +size. A low level format may destroy all data and metadata associated with +all namespaces or only the specific namespace associated with the command +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_free_ctrl.2 b/doc/man/nvme_free_ctrl.2 new file mode 100644 index 0000000000..78d9f92802 --- /dev/null +++ b/doc/man/nvme_free_ctrl.2 @@ -0,0 +1,9 @@ +.TH "nvme_free_ctrl" 2 "nvme_free_ctrl" "February 2020" "libnvme Manual" +.SH NAME +nvme_free_ctrl \- +.SH SYNOPSIS +.B "void" nvme_free_ctrl +.BI "(struct nvme_ctrl *" c ");" +.SH ARGUMENTS +.IP "c" 12 +-- undescribed -- diff --git a/doc/man/nvme_free_tree.2 b/doc/man/nvme_free_tree.2 new file mode 100644 index 0000000000..ef1138efc7 --- /dev/null +++ b/doc/man/nvme_free_tree.2 @@ -0,0 +1,9 @@ +.TH "nvme_free_tree" 2 "nvme_free_tree" "February 2020" "libnvme Manual" +.SH NAME +nvme_free_tree \- +.SH SYNOPSIS +.B "void" nvme_free_tree +.BI "(nvme_root_t " r ");" +.SH ARGUMENTS +.IP "r" 12 +-- undescribed -- diff --git a/doc/man/nvme_fw_commit.2 b/doc/man/nvme_fw_commit.2 new file mode 100644 index 0000000000..093e97282a --- /dev/null +++ b/doc/man/nvme_fw_commit.2 @@ -0,0 +1,25 @@ +.TH "nvme_fw_commit" 2 "nvme_fw_commit" "February 2020" "libnvme Manual" +.SH NAME +nvme_fw_commit \- Commit firmware using the specified action +.SH SYNOPSIS +.B "int" nvme_fw_commit +.BI "(int " fd "," +.BI "__u8 " slot "," +.BI "enum nvme_fw_commit_ca " action "," +.BI "bool " bpid ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "slot" 12 +Firmware slot to commit the downloaded image +.IP "action" 12 +Action to use for the firmware image, see \fIenum nvme_fw_commit_ca\fP +.IP "bpid" 12 +Set to true to select the boot partition id +.SH "DESCRIPTION" +The Firmware Commit command is used to modify the firmware image or Boot +Partitions. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. The command status response may specify additional +reset actions required to complete the commit process. diff --git a/doc/man/nvme_fw_download.2 b/doc/man/nvme_fw_download.2 new file mode 100644 index 0000000000..be478dac0a --- /dev/null +++ b/doc/man/nvme_fw_download.2 @@ -0,0 +1,34 @@ +.TH "nvme_fw_download" 2 "nvme_fw_download" "February 2020" "libnvme Manual" +.SH NAME +nvme_fw_download \- Download part or all of a firmware image to the controller +.SH SYNOPSIS +.B "int" nvme_fw_download +.BI "(int " fd "," +.BI "__u32 " offset "," +.BI "__u32 " data_len "," +.BI "void *" data ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "offset" 12 +Offset in the firmware data +.IP "data_len" 12 +Length of data in this command in bytes +.IP "data" 12 +Userspace address of the firmware data +.SH "DESCRIPTION" +The Firmware Image Download command is used to download all or a portion of +an image for a future update to the controller. The Firmware Image Download +command downloads a new image (in whole or in part) to the controller. + +The image may be constructed of multiple pieces that are individually +downloaded with separate Firmware Image Download commands. Each Firmware +Image Download command includes a Dword Offset and Number of Dwords that +specify a dword range. + +The new firmware image is not activated as part of the Firmware Image +Download command. Use the \fBnvme_fw_commit\fP to activate a newly downloaded +image. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_fw_download_seq.2 b/doc/man/nvme_fw_download_seq.2 new file mode 100644 index 0000000000..fcba60af5a --- /dev/null +++ b/doc/man/nvme_fw_download_seq.2 @@ -0,0 +1,20 @@ +.TH "nvme_fw_download_seq" 2 "nvme_fw_download_seq" "February 2020" "libnvme Manual" +.SH NAME +nvme_fw_download_seq \- +.SH SYNOPSIS +.B "int" nvme_fw_download_seq +.BI "(int " fd "," +.BI "__u32 " size "," +.BI "__u32 " xfer "," +.BI "__u32 " offset "," +.BI "void *" buf ");" +.SH ARGUMENTS +.IP "fd" 12 +-- undescribed -- +.IP "size" 12 +-- undescribed -- +.IP "xfer" 12 +-- undescribed -- +.IP "offset" 12 +-- undescribed -- +.IP "buf" 12 diff --git a/doc/man/nvme_get_ana_log_len.2 b/doc/man/nvme_get_ana_log_len.2 new file mode 100644 index 0000000000..08d7b422a6 --- /dev/null +++ b/doc/man/nvme_get_ana_log_len.2 @@ -0,0 +1,14 @@ +.TH "nvme_get_ana_log_len" 2 "nvme_get_ana_log_len" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_ana_log_len \- Retreive size of the current ANA log +.SH SYNOPSIS +.B "int" nvme_get_ana_log_len +.BI "(int " fd "," +.BI "size_t *" analen ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "analen" 12 +Pointer to where the length will be set on success +.SH "RETURN" +0 on success, -1 otherwise with errno set diff --git a/doc/man/nvme_get_ctrl_attr.2 b/doc/man/nvme_get_ctrl_attr.2 new file mode 100644 index 0000000000..eecaa87a98 --- /dev/null +++ b/doc/man/nvme_get_ctrl_attr.2 @@ -0,0 +1,11 @@ +.TH "nvme_get_ctrl_attr" 2 "nvme_get_ctrl_attr" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_ctrl_attr \- +.SH SYNOPSIS +.B "char *" nvme_get_ctrl_attr +.BI "(nvme_ctrl_t " c "," +.BI "const char *" attr ");" +.SH ARGUMENTS +.IP "c" 12 +-- undescribed -- +.IP "attr" 12 diff --git a/doc/man/nvme_get_ctrl_telemetry.2 b/doc/man/nvme_get_ctrl_telemetry.2 new file mode 100644 index 0000000000..6fb9dde64a --- /dev/null +++ b/doc/man/nvme_get_ctrl_telemetry.2 @@ -0,0 +1,17 @@ +.TH "nvme_get_ctrl_telemetry" 2 "nvme_get_ctrl_telemetry" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_ctrl_telemetry \- +.SH SYNOPSIS +.B "int" nvme_get_ctrl_telemetry +.BI "(int " fd "," +.BI "bool " rae "," +.BI "void **" buf "," +.BI "__u32 *" log_size ");" +.SH ARGUMENTS +.IP "fd" 12 +-- undescribed -- +.IP "rae" 12 +-- undescribed -- +.IP "buf" 12 +-- undescribed -- +.IP "log_size" 12 diff --git a/doc/man/nvme_get_directive_receive_length.2 b/doc/man/nvme_get_directive_receive_length.2 new file mode 100644 index 0000000000..c5b6e2b496 --- /dev/null +++ b/doc/man/nvme_get_directive_receive_length.2 @@ -0,0 +1,18 @@ +.TH "nvme_get_directive_receive_length" 2 "nvme_get_directive_receive_length" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_directive_receive_length \- +.SH SYNOPSIS +.B "int" nvme_get_directive_receive_length +.BI "(enum nvme_directive_dtype " dtype "," +.BI "enum nvme_directive_receive_doper " doper "," +.BI "__u32 *" len ");" +.SH ARGUMENTS +.IP "dtype" 12 +Directive type, see \fIenum nvme_directive_dtype\fP +.IP "doper" 12 +Directive receive operation, see \fIenum nvme_directive_receive_doper\fP +.IP "len" 12 +Address to save the payload length of the directive in bytes on +a successful decode +.SH "RETURN" +0 on success, -1 with errno set to EINVAL. diff --git a/doc/man/nvme_get_feature_length.2 b/doc/man/nvme_get_feature_length.2 new file mode 100644 index 0000000000..0456c360b5 --- /dev/null +++ b/doc/man/nvme_get_feature_length.2 @@ -0,0 +1,16 @@ +.TH "nvme_get_feature_length" 2 "nvme_get_feature_length" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_feature_length \- Retreive the command payload length for a specific feature identifier +.SH SYNOPSIS +.B "int" nvme_get_feature_length +.BI "(int " fid "," +.BI "__u32 " cdw11 "," +.BI "__u32 *" len ");" +.SH ARGUMENTS +.IP "fid" 12 +-- undescribed -- +.IP "cdw11" 12 +-- undescribed -- +.IP "len" 12 +.SH "RETURN" +0 on success, -1 with errno set otherwise diff --git a/doc/man/nvme_get_features.2 b/doc/man/nvme_get_features.2 new file mode 100644 index 0000000000..76ff35c148 --- /dev/null +++ b/doc/man/nvme_get_features.2 @@ -0,0 +1,36 @@ +.TH "nvme_get_features" 2 "nvme_get_features" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_features \- Retrieve a feature attribute +.SH SYNOPSIS +.B "int" nvme_get_features +.BI "(int " fd "," +.BI "enum nvme_features_id " fid "," +.BI "__u32 " nsid "," +.BI "enum nvme_get_features_sel " sel "," +.BI "__u32 " cdw11 "," +.BI "__u8 " uuidx "," +.BI "__u32 " data_len "," +.BI "void *" data "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "fid" 12 +Feature identifier +.IP "nsid" 12 +Namespace ID, if applicable +.IP "sel" 12 +Select which type of attribute to return, see \fIenum nvme_get_features_sel\fP +.IP "cdw11" 12 +Feature specific command dword11 field +.IP "uuidx" 12 +UUID Index for differentiating vendor specific encoding +.IP "data_len" 12 +Length of feature data, if applicable, in bytes +.IP "data" 12 +User address of feature data, if applicable +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_features_arbitration.2 b/doc/man/nvme_get_features_arbitration.2 new file mode 100644 index 0000000000..b81cb905d7 --- /dev/null +++ b/doc/man/nvme_get_features_arbitration.2 @@ -0,0 +1,18 @@ +.TH "nvme_get_features_arbitration" 2 "nvme_get_features_arbitration" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_features_arbitration \- +.SH SYNOPSIS +.B "int" nvme_get_features_arbitration +.BI "(int " fd "," +.BI "enum nvme_get_features_sel " sel "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "sel" 12 +Select which type of attribute to return, see \fIenum nvme_get_features_sel\fP +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_features_async_event.2 b/doc/man/nvme_get_features_async_event.2 new file mode 100644 index 0000000000..2ff8ef8928 --- /dev/null +++ b/doc/man/nvme_get_features_async_event.2 @@ -0,0 +1,18 @@ +.TH "nvme_get_features_async_event" 2 "nvme_get_features_async_event" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_features_async_event \- +.SH SYNOPSIS +.B "int" nvme_get_features_async_event +.BI "(int " fd "," +.BI "enum nvme_get_features_sel " sel "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "sel" 12 +Select which type of attribute to return, see \fIenum nvme_get_features_sel\fP +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_features_auto_pst.2 b/doc/man/nvme_get_features_auto_pst.2 new file mode 100644 index 0000000000..63822dc361 --- /dev/null +++ b/doc/man/nvme_get_features_auto_pst.2 @@ -0,0 +1,21 @@ +.TH "nvme_get_features_auto_pst" 2 "nvme_get_features_auto_pst" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_features_auto_pst \- +.SH SYNOPSIS +.B "int" nvme_get_features_auto_pst +.BI "(int " fd "," +.BI "enum nvme_get_features_sel " sel "," +.BI "struct nvme_feat_auto_pst *" apst "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "sel" 12 +Select which type of attribute to return, see \fIenum nvme_get_features_sel\fP +.IP "apst" 12 +-- undescribed -- +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_features_endurance_event_cfg.2 b/doc/man/nvme_get_features_endurance_event_cfg.2 new file mode 100644 index 0000000000..531a3bf87d --- /dev/null +++ b/doc/man/nvme_get_features_endurance_event_cfg.2 @@ -0,0 +1,21 @@ +.TH "nvme_get_features_endurance_event_cfg" 2 "nvme_get_features_endurance_event_cfg" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_features_endurance_event_cfg \- +.SH SYNOPSIS +.B "int" nvme_get_features_endurance_event_cfg +.BI "(int " fd "," +.BI "enum nvme_get_features_sel " sel "," +.BI "__u16 " endgid "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "sel" 12 +Select which type of attribute to return, see \fIenum nvme_get_features_sel\fP +.IP "endgid" 12 +-- undescribed -- +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_features_err_recovery.2 b/doc/man/nvme_get_features_err_recovery.2 new file mode 100644 index 0000000000..7f847ba0e4 --- /dev/null +++ b/doc/man/nvme_get_features_err_recovery.2 @@ -0,0 +1,18 @@ +.TH "nvme_get_features_err_recovery" 2 "nvme_get_features_err_recovery" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_features_err_recovery \- +.SH SYNOPSIS +.B "int" nvme_get_features_err_recovery +.BI "(int " fd "," +.BI "enum nvme_get_features_sel " sel "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "sel" 12 +Select which type of attribute to return, see \fIenum nvme_get_features_sel\fP +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_features_hctm.2 b/doc/man/nvme_get_features_hctm.2 new file mode 100644 index 0000000000..0ce7465efe --- /dev/null +++ b/doc/man/nvme_get_features_hctm.2 @@ -0,0 +1,18 @@ +.TH "nvme_get_features_hctm" 2 "nvme_get_features_hctm" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_features_hctm \- +.SH SYNOPSIS +.B "int" nvme_get_features_hctm +.BI "(int " fd "," +.BI "enum nvme_get_features_sel " sel "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "sel" 12 +Select which type of attribute to return, see \fIenum nvme_get_features_sel\fP +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_features_host_behavior.2 b/doc/man/nvme_get_features_host_behavior.2 new file mode 100644 index 0000000000..23cfe9888f --- /dev/null +++ b/doc/man/nvme_get_features_host_behavior.2 @@ -0,0 +1,21 @@ +.TH "nvme_get_features_host_behavior" 2 "nvme_get_features_host_behavior" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_features_host_behavior \- +.SH SYNOPSIS +.B "int" nvme_get_features_host_behavior +.BI "(int " fd "," +.BI "enum nvme_get_features_sel " sel "," +.BI "struct nvme_feat_host_behavior *" data "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "sel" 12 +Select which type of attribute to return, see \fIenum nvme_get_features_sel\fP +.IP "data" 12 +-- undescribed -- +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_features_host_id.2 b/doc/man/nvme_get_features_host_id.2 new file mode 100644 index 0000000000..152e9482d7 --- /dev/null +++ b/doc/man/nvme_get_features_host_id.2 @@ -0,0 +1,24 @@ +.TH "nvme_get_features_host_id" 2 "nvme_get_features_host_id" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_features_host_id \- +.SH SYNOPSIS +.B "int" nvme_get_features_host_id +.BI "(int " fd "," +.BI "enum nvme_get_features_sel " sel "," +.BI "bool " exhid "," +.BI "__u32 " len "," +.BI "__u8 *" hostid ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "sel" 12 +Select which type of attribute to return, see \fIenum nvme_get_features_sel\fP +.IP "exhid" 12 +-- undescribed -- +.IP "len" 12 +-- undescribed -- +.IP "hostid" 12 +-- undescribed -- +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_features_host_mem_buf.2 b/doc/man/nvme_get_features_host_mem_buf.2 new file mode 100644 index 0000000000..28393b0cfa --- /dev/null +++ b/doc/man/nvme_get_features_host_mem_buf.2 @@ -0,0 +1,18 @@ +.TH "nvme_get_features_host_mem_buf" 2 "nvme_get_features_host_mem_buf" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_features_host_mem_buf \- +.SH SYNOPSIS +.B "int" nvme_get_features_host_mem_buf +.BI "(int " fd "," +.BI "enum nvme_get_features_sel " sel "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "sel" 12 +Select which type of attribute to return, see \fIenum nvme_get_features_sel\fP +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_features_irq_coalesce.2 b/doc/man/nvme_get_features_irq_coalesce.2 new file mode 100644 index 0000000000..1e5f7c180f --- /dev/null +++ b/doc/man/nvme_get_features_irq_coalesce.2 @@ -0,0 +1,18 @@ +.TH "nvme_get_features_irq_coalesce" 2 "nvme_get_features_irq_coalesce" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_features_irq_coalesce \- +.SH SYNOPSIS +.B "int" nvme_get_features_irq_coalesce +.BI "(int " fd "," +.BI "enum nvme_get_features_sel " sel "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "sel" 12 +Select which type of attribute to return, see \fIenum nvme_get_features_sel\fP +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_features_irq_config.2 b/doc/man/nvme_get_features_irq_config.2 new file mode 100644 index 0000000000..1c353e88b1 --- /dev/null +++ b/doc/man/nvme_get_features_irq_config.2 @@ -0,0 +1,21 @@ +.TH "nvme_get_features_irq_config" 2 "nvme_get_features_irq_config" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_features_irq_config \- +.SH SYNOPSIS +.B "int" nvme_get_features_irq_config +.BI "(int " fd "," +.BI "enum nvme_get_features_sel " sel "," +.BI "__u16 " iv "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "sel" 12 +Select which type of attribute to return, see \fIenum nvme_get_features_sel\fP +.IP "iv" 12 +-- undescribed -- +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_features_kato.2 b/doc/man/nvme_get_features_kato.2 new file mode 100644 index 0000000000..3e06022223 --- /dev/null +++ b/doc/man/nvme_get_features_kato.2 @@ -0,0 +1,18 @@ +.TH "nvme_get_features_kato" 2 "nvme_get_features_kato" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_features_kato \- +.SH SYNOPSIS +.B "int" nvme_get_features_kato +.BI "(int " fd "," +.BI "enum nvme_get_features_sel " sel "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "sel" 12 +Select which type of attribute to return, see \fIenum nvme_get_features_sel\fP +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_features_lba_range.2 b/doc/man/nvme_get_features_lba_range.2 new file mode 100644 index 0000000000..01969af9c2 --- /dev/null +++ b/doc/man/nvme_get_features_lba_range.2 @@ -0,0 +1,21 @@ +.TH "nvme_get_features_lba_range" 2 "nvme_get_features_lba_range" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_features_lba_range \- +.SH SYNOPSIS +.B "int" nvme_get_features_lba_range +.BI "(int " fd "," +.BI "enum nvme_get_features_sel " sel "," +.BI "struct nvme_lba_range_type *" data "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "sel" 12 +Select which type of attribute to return, see \fIenum nvme_get_features_sel\fP +.IP "data" 12 +-- undescribed -- +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_features_lba_sts_interval.2 b/doc/man/nvme_get_features_lba_sts_interval.2 new file mode 100644 index 0000000000..15ae7d8663 --- /dev/null +++ b/doc/man/nvme_get_features_lba_sts_interval.2 @@ -0,0 +1,18 @@ +.TH "nvme_get_features_lba_sts_interval" 2 "nvme_get_features_lba_sts_interval" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_features_lba_sts_interval \- +.SH SYNOPSIS +.B "int" nvme_get_features_lba_sts_interval +.BI "(int " fd "," +.BI "enum nvme_get_features_sel " sel "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "sel" 12 +Select which type of attribute to return, see \fIenum nvme_get_features_sel\fP +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_features_nopsc.2 b/doc/man/nvme_get_features_nopsc.2 new file mode 100644 index 0000000000..d702cd35d0 --- /dev/null +++ b/doc/man/nvme_get_features_nopsc.2 @@ -0,0 +1,18 @@ +.TH "nvme_get_features_nopsc" 2 "nvme_get_features_nopsc" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_features_nopsc \- +.SH SYNOPSIS +.B "int" nvme_get_features_nopsc +.BI "(int " fd "," +.BI "enum nvme_get_features_sel " sel "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "sel" 12 +Select which type of attribute to return, see \fIenum nvme_get_features_sel\fP +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_features_num_queues.2 b/doc/man/nvme_get_features_num_queues.2 new file mode 100644 index 0000000000..ffc529c792 --- /dev/null +++ b/doc/man/nvme_get_features_num_queues.2 @@ -0,0 +1,18 @@ +.TH "nvme_get_features_num_queues" 2 "nvme_get_features_num_queues" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_features_num_queues \- +.SH SYNOPSIS +.B "int" nvme_get_features_num_queues +.BI "(int " fd "," +.BI "enum nvme_get_features_sel " sel "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "sel" 12 +Select which type of attribute to return, see \fIenum nvme_get_features_sel\fP +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_features_plm_config.2 b/doc/man/nvme_get_features_plm_config.2 new file mode 100644 index 0000000000..e694343d45 --- /dev/null +++ b/doc/man/nvme_get_features_plm_config.2 @@ -0,0 +1,24 @@ +.TH "nvme_get_features_plm_config" 2 "nvme_get_features_plm_config" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_features_plm_config \- +.SH SYNOPSIS +.B "int" nvme_get_features_plm_config +.BI "(int " fd "," +.BI "enum nvme_get_features_sel " sel "," +.BI "__u16 " nvmsetid "," +.BI "struct nvme_plm_config *" data "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "sel" 12 +Select which type of attribute to return, see \fIenum nvme_get_features_sel\fP +.IP "nvmsetid" 12 +-- undescribed -- +.IP "data" 12 +-- undescribed -- +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_features_plm_window.2 b/doc/man/nvme_get_features_plm_window.2 new file mode 100644 index 0000000000..3745d206a0 --- /dev/null +++ b/doc/man/nvme_get_features_plm_window.2 @@ -0,0 +1,21 @@ +.TH "nvme_get_features_plm_window" 2 "nvme_get_features_plm_window" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_features_plm_window \- +.SH SYNOPSIS +.B "int" nvme_get_features_plm_window +.BI "(int " fd "," +.BI "enum nvme_get_features_sel " sel "," +.BI "__u16 " nvmsetid "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "sel" 12 +Select which type of attribute to return, see \fIenum nvme_get_features_sel\fP +.IP "nvmsetid" 12 +-- undescribed -- +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_features_power_mgmt.2 b/doc/man/nvme_get_features_power_mgmt.2 new file mode 100644 index 0000000000..afb40d6f11 --- /dev/null +++ b/doc/man/nvme_get_features_power_mgmt.2 @@ -0,0 +1,18 @@ +.TH "nvme_get_features_power_mgmt" 2 "nvme_get_features_power_mgmt" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_features_power_mgmt \- +.SH SYNOPSIS +.B "int" nvme_get_features_power_mgmt +.BI "(int " fd "," +.BI "enum nvme_get_features_sel " sel "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "sel" 12 +Select which type of attribute to return, see \fIenum nvme_get_features_sel\fP +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_features_resv_mask.2 b/doc/man/nvme_get_features_resv_mask.2 new file mode 100644 index 0000000000..847951c7fd --- /dev/null +++ b/doc/man/nvme_get_features_resv_mask.2 @@ -0,0 +1,18 @@ +.TH "nvme_get_features_resv_mask" 2 "nvme_get_features_resv_mask" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_features_resv_mask \- +.SH SYNOPSIS +.B "int" nvme_get_features_resv_mask +.BI "(int " fd "," +.BI "enum nvme_get_features_sel " sel "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "sel" 12 +Select which type of attribute to return, see \fIenum nvme_get_features_sel\fP +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_features_resv_persist.2 b/doc/man/nvme_get_features_resv_persist.2 new file mode 100644 index 0000000000..a199048c76 --- /dev/null +++ b/doc/man/nvme_get_features_resv_persist.2 @@ -0,0 +1,18 @@ +.TH "nvme_get_features_resv_persist" 2 "nvme_get_features_resv_persist" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_features_resv_persist \- +.SH SYNOPSIS +.B "int" nvme_get_features_resv_persist +.BI "(int " fd "," +.BI "enum nvme_get_features_sel " sel "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "sel" 12 +Select which type of attribute to return, see \fIenum nvme_get_features_sel\fP +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_features_rrl.2 b/doc/man/nvme_get_features_rrl.2 new file mode 100644 index 0000000000..84585fa9dc --- /dev/null +++ b/doc/man/nvme_get_features_rrl.2 @@ -0,0 +1,18 @@ +.TH "nvme_get_features_rrl" 2 "nvme_get_features_rrl" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_features_rrl \- +.SH SYNOPSIS +.B "int" nvme_get_features_rrl +.BI "(int " fd "," +.BI "enum nvme_get_features_sel " sel "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "sel" 12 +Select which type of attribute to return, see \fIenum nvme_get_features_sel\fP +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_features_sanitize.2 b/doc/man/nvme_get_features_sanitize.2 new file mode 100644 index 0000000000..36fee6accc --- /dev/null +++ b/doc/man/nvme_get_features_sanitize.2 @@ -0,0 +1,18 @@ +.TH "nvme_get_features_sanitize" 2 "nvme_get_features_sanitize" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_features_sanitize \- +.SH SYNOPSIS +.B "int" nvme_get_features_sanitize +.BI "(int " fd "," +.BI "enum nvme_get_features_sel " sel "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "sel" 12 +Select which type of attribute to return, see \fIenum nvme_get_features_sel\fP +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_features_sw_progress.2 b/doc/man/nvme_get_features_sw_progress.2 new file mode 100644 index 0000000000..51357cf351 --- /dev/null +++ b/doc/man/nvme_get_features_sw_progress.2 @@ -0,0 +1,18 @@ +.TH "nvme_get_features_sw_progress" 2 "nvme_get_features_sw_progress" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_features_sw_progress \- +.SH SYNOPSIS +.B "int" nvme_get_features_sw_progress +.BI "(int " fd "," +.BI "enum nvme_get_features_sel " sel "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "sel" 12 +Select which type of attribute to return, see \fIenum nvme_get_features_sel\fP +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_features_temp_thresh.2 b/doc/man/nvme_get_features_temp_thresh.2 new file mode 100644 index 0000000000..61b845ba47 --- /dev/null +++ b/doc/man/nvme_get_features_temp_thresh.2 @@ -0,0 +1,18 @@ +.TH "nvme_get_features_temp_thresh" 2 "nvme_get_features_temp_thresh" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_features_temp_thresh \- +.SH SYNOPSIS +.B "int" nvme_get_features_temp_thresh +.BI "(int " fd "," +.BI "enum nvme_get_features_sel " sel "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "sel" 12 +Select which type of attribute to return, see \fIenum nvme_get_features_sel\fP +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_features_timestamp.2 b/doc/man/nvme_get_features_timestamp.2 new file mode 100644 index 0000000000..c541f8425c --- /dev/null +++ b/doc/man/nvme_get_features_timestamp.2 @@ -0,0 +1,18 @@ +.TH "nvme_get_features_timestamp" 2 "nvme_get_features_timestamp" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_features_timestamp \- +.SH SYNOPSIS +.B "int" nvme_get_features_timestamp +.BI "(int " fd "," +.BI "enum nvme_get_features_sel " sel "," +.BI "struct nvme_timestamp *" ts ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "sel" 12 +Select which type of attribute to return, see \fIenum nvme_get_features_sel\fP +.IP "ts" 12 +-- undescribed -- +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_features_volatile_wc.2 b/doc/man/nvme_get_features_volatile_wc.2 new file mode 100644 index 0000000000..fde62d8d8a --- /dev/null +++ b/doc/man/nvme_get_features_volatile_wc.2 @@ -0,0 +1,18 @@ +.TH "nvme_get_features_volatile_wc" 2 "nvme_get_features_volatile_wc" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_features_volatile_wc \- +.SH SYNOPSIS +.B "int" nvme_get_features_volatile_wc +.BI "(int " fd "," +.BI "enum nvme_get_features_sel " sel "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "sel" 12 +Select which type of attribute to return, see \fIenum nvme_get_features_sel\fP +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_features_write_atomic.2 b/doc/man/nvme_get_features_write_atomic.2 new file mode 100644 index 0000000000..fcfc260dab --- /dev/null +++ b/doc/man/nvme_get_features_write_atomic.2 @@ -0,0 +1,18 @@ +.TH "nvme_get_features_write_atomic" 2 "nvme_get_features_write_atomic" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_features_write_atomic \- +.SH SYNOPSIS +.B "int" nvme_get_features_write_atomic +.BI "(int " fd "," +.BI "enum nvme_get_features_sel " sel "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "sel" 12 +Select which type of attribute to return, see \fIenum nvme_get_features_sel\fP +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_features_write_protect.2 b/doc/man/nvme_get_features_write_protect.2 new file mode 100644 index 0000000000..dd4ecfca5a --- /dev/null +++ b/doc/man/nvme_get_features_write_protect.2 @@ -0,0 +1,21 @@ +.TH "nvme_get_features_write_protect" 2 "nvme_get_features_write_protect" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_features_write_protect \- +.SH SYNOPSIS +.B "int" nvme_get_features_write_protect +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "enum nvme_get_features_sel " sel "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Namespace ID +.IP "sel" 12 +Select which type of attribute to return, see \fIenum nvme_get_features_sel\fP +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_host_telemetry.2 b/doc/man/nvme_get_host_telemetry.2 new file mode 100644 index 0000000000..d1d1c2322d --- /dev/null +++ b/doc/man/nvme_get_host_telemetry.2 @@ -0,0 +1,14 @@ +.TH "nvme_get_host_telemetry" 2 "nvme_get_host_telemetry" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_host_telemetry \- +.SH SYNOPSIS +.B "int" nvme_get_host_telemetry +.BI "(int " fd "," +.BI "void **" buf "," +.BI "__u32 *" log_size ");" +.SH ARGUMENTS +.IP "fd" 12 +-- undescribed -- +.IP "buf" 12 +-- undescribed -- +.IP "log_size" 12 diff --git a/doc/man/nvme_get_lba_status.2 b/doc/man/nvme_get_lba_status.2 new file mode 100644 index 0000000000..ad406f740a --- /dev/null +++ b/doc/man/nvme_get_lba_status.2 @@ -0,0 +1,34 @@ +.TH "nvme_get_lba_status" 2 "nvme_get_lba_status" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_lba_status \- Retrieve information on possibly unrecoverable LBAs +.SH SYNOPSIS +.B "int" nvme_get_lba_status +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "__u64 " slba "," +.BI "__u32 " mndw "," +.BI "__u16 " rl "," +.BI "enum nvme_lba_status_atype " atype "," +.BI "struct nvme_lba_status *" lbas ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Namespace ID to retrieve LBA status +.IP "slba" 12 +Starting logical block address to check statuses +.IP "mndw" 12 +Maximum number of dwords to return +.IP "rl" 12 +Range length from slba to perform the action +.IP "atype" 12 +Action type mechanism to determine LBA status desctriptors to +return, see \fIenum nvme_lba_status_atype\fP +.IP "lbas" 12 +Data payload to return status descriptors +.SH "DESCRIPTION" +The Get LBA Status command requests information about Potentially +Unrecoverable LBAs. Refer to the specification for action type descriptions. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_log.2 b/doc/man/nvme_get_log.2 new file mode 100644 index 0000000000..2f7fd0f65b --- /dev/null +++ b/doc/man/nvme_get_log.2 @@ -0,0 +1,39 @@ +.TH "nvme_get_log" 2 "nvme_get_log" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_log \- NVMe Admin Get Log command +.SH SYNOPSIS +.B "int" nvme_get_log +.BI "(int " fd "," +.BI "enum nvme_cmd_get_log_lid " lid "," +.BI "__u32 " nsid "," +.BI "__u64 " lpo "," +.BI "__u8 " lsp "," +.BI "__u16 " lsi "," +.BI "bool " rae "," +.BI "__u8 " uuidx "," +.BI "__u32 " len "," +.BI "void *" log ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "lid" 12 +Log page identifier, see \fIenum nvme_cmd_get_log_lid\fP for known values +.IP "nsid" 12 +Namespace identifier, if applicable +.IP "lpo" 12 +Log page offset for partial log transfers +.IP "lsp" 12 +Log specific field +.IP "lsi" 12 +Endurance group information +.IP "rae" 12 +Retain asynchronous events +.IP "uuidx" 12 +UUID selection, if supported +.IP "len" 12 +Length of provided user buffer to hold the log data in bytes +.IP "log" 12 +User space destination address to transfer the data +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_log_ana.2 b/doc/man/nvme_get_log_ana.2 new file mode 100644 index 0000000000..af9fe71672 --- /dev/null +++ b/doc/man/nvme_get_log_ana.2 @@ -0,0 +1,33 @@ +.TH "nvme_get_log_ana" 2 "nvme_get_log_ana" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_log_ana \- +.SH SYNOPSIS +.B "int" nvme_get_log_ana +.BI "(int " fd "," +.BI "enum nvme_log_ana_lsp " lsp "," +.BI "bool " rae "," +.BI "__u64 " offset "," +.BI "__u32 " len "," +.BI "void *" log ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "lsp" 12 +Log specific, see \fIenum nvme_get_log_ana_lsp\fP +.IP "rae" 12 +Retain asynchronous events +.IP "offset" 12 +-- undescribed -- +.IP "len" 12 +The allocated length of the log page +.IP "log" 12 +User address to store the ana log +.SH "DESCRIPTION" +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 \fIstruct nvme_ana_rsp_hdr\fP for the defintion of the returned structure. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_log_ana_groups.2 b/doc/man/nvme_get_log_ana_groups.2 new file mode 100644 index 0000000000..228f6546c6 --- /dev/null +++ b/doc/man/nvme_get_log_ana_groups.2 @@ -0,0 +1,20 @@ +.TH "nvme_get_log_ana_groups" 2 "nvme_get_log_ana_groups" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_log_ana_groups \- +.SH SYNOPSIS +.B "int" nvme_get_log_ana_groups +.BI "(int " fd "," +.BI "bool " rae "," +.BI "__u32 " len "," +.BI "struct nvme_ana_group_desc *" log ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "rae" 12 +Retain asynchronous events +.IP "len" 12 +-- undescribed -- +.IP "log" 12 +-- undescribed -- +.SH "DESCRIPTION" +See \fIstruct nvme_ana_group_desc\fP for the defintion of the returned structure. diff --git a/doc/man/nvme_get_log_changed_ns_list.2 b/doc/man/nvme_get_log_changed_ns_list.2 new file mode 100644 index 0000000000..882541b9dd --- /dev/null +++ b/doc/man/nvme_get_log_changed_ns_list.2 @@ -0,0 +1,22 @@ +.TH "nvme_get_log_changed_ns_list" 2 "nvme_get_log_changed_ns_list" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_log_changed_ns_list \- Retrieve namespace changed list +.SH SYNOPSIS +.B "int" nvme_get_log_changed_ns_list +.BI "(int " fd "," +.BI "bool " rae "," +.BI "struct nvme_ns_list *" log ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "rae" 12 +Retain asynchronous events +.IP "log" 12 +-- undescribed -- +.SH "DESCRIPTION" +This log page is used to describe namespaces attached to this controller +that have changed since the last time the namespace was identified, been +added, or deleted. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_log_cmd_effects.2 b/doc/man/nvme_get_log_cmd_effects.2 new file mode 100644 index 0000000000..cedf2536a0 --- /dev/null +++ b/doc/man/nvme_get_log_cmd_effects.2 @@ -0,0 +1,18 @@ +.TH "nvme_get_log_cmd_effects" 2 "nvme_get_log_cmd_effects" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_log_cmd_effects \- Retrieve nvme command effects log +.SH SYNOPSIS +.B "int" nvme_get_log_cmd_effects +.BI "(int " fd "," +.BI "struct nvme_cmd_effects_log *" log ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "log" 12 +-- undescribed -- +.SH "DESCRIPTION" +This log page is used to describe the commands that the controller supports +and the effects of those commands on the state of the NVM subsystem. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_log_create_telemetry_host.2 b/doc/man/nvme_get_log_create_telemetry_host.2 new file mode 100644 index 0000000000..929d957a10 --- /dev/null +++ b/doc/man/nvme_get_log_create_telemetry_host.2 @@ -0,0 +1,12 @@ +.TH "nvme_get_log_create_telemetry_host" 2 "nvme_get_log_create_telemetry_host" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_log_create_telemetry_host \- +.SH SYNOPSIS +.B "int" nvme_get_log_create_telemetry_host +.BI "(int " fd "," +.BI "struct nvme_telemetry_log *" log ");" +.SH ARGUMENTS +.IP "fd" 12 +-- undescribed -- +.IP "log" 12 +-- undescribed -- diff --git a/doc/man/nvme_get_log_device_self_test.2 b/doc/man/nvme_get_log_device_self_test.2 new file mode 100644 index 0000000000..bc236b5d24 --- /dev/null +++ b/doc/man/nvme_get_log_device_self_test.2 @@ -0,0 +1,19 @@ +.TH "nvme_get_log_device_self_test" 2 "nvme_get_log_device_self_test" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_log_device_self_test \- Retrieve the device self test log +.SH SYNOPSIS +.B "int" nvme_get_log_device_self_test +.BI "(int " fd "," +.BI "struct nvme_self_test_log *" log ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "log" 12 +Userspace address of the log payload +.SH "DESCRIPTION" +The log page is used to indicate the status of an in progress self test and +the percent complete of that operation, and the results of the previous 20 +self-test operations. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_log_discovery.2 b/doc/man/nvme_get_log_discovery.2 new file mode 100644 index 0000000000..7eae923741 --- /dev/null +++ b/doc/man/nvme_get_log_discovery.2 @@ -0,0 +1,27 @@ +.TH "nvme_get_log_discovery" 2 "nvme_get_log_discovery" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_log_discovery \- +.SH SYNOPSIS +.B "int" nvme_get_log_discovery +.BI "(int " fd "," +.BI "bool " rae "," +.BI "__u32 " offset "," +.BI "__u32 " len "," +.BI "void *" log ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "rae" 12 +Retain asynchronous events +.IP "offset" 12 +Offset of this log to retrieve +.IP "len" 12 +The allocated size for this portion of the log +.IP "log" 12 +User address to store the discovery log +.SH "DESCRIPTION" +Supported only by fabrics discovery controllers, returning discovery +records. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_log_endurance_group.2 b/doc/man/nvme_get_log_endurance_group.2 new file mode 100644 index 0000000000..a8516a62fb --- /dev/null +++ b/doc/man/nvme_get_log_endurance_group.2 @@ -0,0 +1,25 @@ +.TH "nvme_get_log_endurance_group" 2 "nvme_get_log_endurance_group" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_log_endurance_group \- +.SH SYNOPSIS +.B "int" nvme_get_log_endurance_group +.BI "(int " fd "," +.BI "__u16 " endgid "," +.BI "struct nvme_endurance_group_log *" log ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "endgid" 12 +Starting group identifier to return in the list +.IP "log" 12 +User address to store the endurance log +.SH "DESCRIPTION" +This log page indicates if an Endurance Group Event has occurred for a +particular Endurance Group. If an Endurance Group Event has occurred, the +details of the particular event are included in the Endurance Group +Information log page for that Endurance Group. An asynchronous event is +generated when an entry for an Endurance Group is newly added to this log +page. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_log_endurance_grp_evt.2 b/doc/man/nvme_get_log_endurance_grp_evt.2 new file mode 100644 index 0000000000..66bfe7feca --- /dev/null +++ b/doc/man/nvme_get_log_endurance_grp_evt.2 @@ -0,0 +1,21 @@ +.TH "nvme_get_log_endurance_grp_evt" 2 "nvme_get_log_endurance_grp_evt" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_log_endurance_grp_evt \- +.SH SYNOPSIS +.B "int" nvme_get_log_endurance_grp_evt +.BI "(int " fd "," +.BI "bool " rae "," +.BI "__u32 " offset "," +.BI "__u32 " len "," +.BI "void *" log ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "rae" 12 +Retain asynchronous events +.IP "offset" 12 +-- undescribed -- +.IP "len" 12 +-- undescribed -- +.IP "log" 12 +-- undescribed -- diff --git a/doc/man/nvme_get_log_error.2 b/doc/man/nvme_get_log_error.2 new file mode 100644 index 0000000000..3ae17f1de2 --- /dev/null +++ b/doc/man/nvme_get_log_error.2 @@ -0,0 +1,25 @@ +.TH "nvme_get_log_error" 2 "nvme_get_log_error" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_log_error \- Retrieve nvme error log +.SH SYNOPSIS +.B "int" nvme_get_log_error +.BI "(int " fd "," +.BI "unsigned " nr_entries "," +.BI "bool " rae "," +.BI "struct nvme_error_log_page *" log ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nr_entries" 12 +-- undescribed -- +.IP "rae" 12 +Retain asynchronous events +.IP "log" 12 +-- undescribed -- +.SH "DESCRIPTION" +This log page is used to describe extended error information for a command +that completed with error, or may report an error that is not specific to a +particular command. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_log_fw_slot.2 b/doc/man/nvme_get_log_fw_slot.2 new file mode 100644 index 0000000000..8c95652530 --- /dev/null +++ b/doc/man/nvme_get_log_fw_slot.2 @@ -0,0 +1,22 @@ +.TH "nvme_get_log_fw_slot" 2 "nvme_get_log_fw_slot" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_log_fw_slot \- Retrieves the controller firmware log +.SH SYNOPSIS +.B "int" nvme_get_log_fw_slot +.BI "(int " fd "," +.BI "bool " rae "," +.BI "struct nvme_firmware_slot *" log ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "rae" 12 +Retain asynchronous events +.IP "log" 12 +-- undescribed -- +.SH "DESCRIPTION" +This log page is used to describe the firmware revision stored in each +firmware slot supported. The firmware revision is indicated as an ASCII +string. The log page also indicates the active slot number. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_log_lba_status.2 b/doc/man/nvme_get_log_lba_status.2 new file mode 100644 index 0000000000..6ada5ec8ec --- /dev/null +++ b/doc/man/nvme_get_log_lba_status.2 @@ -0,0 +1,21 @@ +.TH "nvme_get_log_lba_status" 2 "nvme_get_log_lba_status" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_log_lba_status \- +.SH SYNOPSIS +.B "int" nvme_get_log_lba_status +.BI "(int " fd "," +.BI "bool " rae "," +.BI "__u64 " offset "," +.BI "__u32 " len "," +.BI "void *" log ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "rae" 12 +Retain asynchronous events +.IP "offset" 12 +-- undescribed -- +.IP "len" 12 +-- undescribed -- +.IP "log" 12 +-- undescribed -- diff --git a/doc/man/nvme_get_log_page.2 b/doc/man/nvme_get_log_page.2 new file mode 100644 index 0000000000..09a7182632 --- /dev/null +++ b/doc/man/nvme_get_log_page.2 @@ -0,0 +1,25 @@ +.TH "nvme_get_log_page" 2 "nvme_get_log_page" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_log_page \- +.SH SYNOPSIS +.B "int" nvme_get_log_page +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "__u8 " log_id "," +.BI "bool " rae "," +.BI "__u32 " data_len "," +.BI "void *" data ");" +.SH ARGUMENTS +.IP "fd" 12 +-- undescribed -- +.IP "nsid" 12 +-- undescribed -- +.IP "log_id" 12 +-- undescribed -- +.IP "rae" 12 +-- undescribed -- +.IP "data_len" 12 +-- undescribed -- +.IP "data" 12 +.SH "DESCRIPTION" +Calls \fB__nvme_get_log_page\fP with a default 4k transfer length. diff --git a/doc/man/nvme_get_log_predictable_lat_event.2 b/doc/man/nvme_get_log_predictable_lat_event.2 new file mode 100644 index 0000000000..d5ed8c0753 --- /dev/null +++ b/doc/man/nvme_get_log_predictable_lat_event.2 @@ -0,0 +1,21 @@ +.TH "nvme_get_log_predictable_lat_event" 2 "nvme_get_log_predictable_lat_event" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_log_predictable_lat_event \- +.SH SYNOPSIS +.B "int" nvme_get_log_predictable_lat_event +.BI "(int " fd "," +.BI "bool " rae "," +.BI "__u32 " offset "," +.BI "__u32 " len "," +.BI "void *" log ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "rae" 12 +Retain asynchronous events +.IP "offset" 12 +-- undescribed -- +.IP "len" 12 +-- undescribed -- +.IP "log" 12 +-- undescribed -- diff --git a/doc/man/nvme_get_log_predictable_lat_nvmset.2 b/doc/man/nvme_get_log_predictable_lat_nvmset.2 new file mode 100644 index 0000000000..2302b0132a --- /dev/null +++ b/doc/man/nvme_get_log_predictable_lat_nvmset.2 @@ -0,0 +1,17 @@ +.TH "nvme_get_log_predictable_lat_nvmset" 2 "nvme_get_log_predictable_lat_nvmset" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_log_predictable_lat_nvmset \- +.SH SYNOPSIS +.B "int" nvme_get_log_predictable_lat_nvmset +.BI "(int " fd "," +.BI "__u16 " nvmsetid "," +.BI "struct nvme_nvmset_predictable_lat_log *" log ");" +.SH ARGUMENTS +.IP "fd" 12 +-- undescribed -- +.IP "nvmsetid" 12 +.IP "log" 12 +-- undescribed -- +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_log_reservation.2 b/doc/man/nvme_get_log_reservation.2 new file mode 100644 index 0000000000..8311e66ffd --- /dev/null +++ b/doc/man/nvme_get_log_reservation.2 @@ -0,0 +1,15 @@ +.TH "nvme_get_log_reservation" 2 "nvme_get_log_reservation" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_log_reservation \- +.SH SYNOPSIS +.B "int" nvme_get_log_reservation +.BI "(int " fd "," +.BI "bool " rae "," +.BI "struct nvme_resv_notification_log *" log ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "rae" 12 +Retain asynchronous events +.IP "log" 12 +-- undescribed -- diff --git a/doc/man/nvme_get_log_sanitize.2 b/doc/man/nvme_get_log_sanitize.2 new file mode 100644 index 0000000000..177ffe2b57 --- /dev/null +++ b/doc/man/nvme_get_log_sanitize.2 @@ -0,0 +1,21 @@ +.TH "nvme_get_log_sanitize" 2 "nvme_get_log_sanitize" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_log_sanitize \- +.SH SYNOPSIS +.B "int" nvme_get_log_sanitize +.BI "(int " fd "," +.BI "bool " rae "," +.BI "struct nvme_sanitize_log_page *" log ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "rae" 12 +Retain asynchronous events +.IP "log" 12 +User address to store the sanitize log +.SH "DESCRIPTION" +The Sanitize Status log page is used to report sanitize operation time +estimates and information about the most recent sanitize operation. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_log_smart.2 b/doc/man/nvme_get_log_smart.2 new file mode 100644 index 0000000000..ba619ecdb7 --- /dev/null +++ b/doc/man/nvme_get_log_smart.2 @@ -0,0 +1,28 @@ +.TH "nvme_get_log_smart" 2 "nvme_get_log_smart" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_log_smart \- Retrieve nvme smart log +.SH SYNOPSIS +.B "int" nvme_get_log_smart +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "bool " rae "," +.BI "struct nvme_smart_log *" log ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Optional namespace identifier +.IP "rae" 12 +Retain asynchronous events +.IP "log" 12 +-- undescribed -- +.SH "DESCRIPTION" +This log page is used to provide SMART and general health information. The +information provided is over the life of the controller and is retained +across power cycles. To request the controller log page, the namespace +identifier specified is FFFFFFFFh. The controller may also support +requesting the log page on a per namespace basis, as indicated by bit 0 of +the LPA field in the Identify Controller data structure. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_log_telemetry_ctrl.2 b/doc/man/nvme_get_log_telemetry_ctrl.2 new file mode 100644 index 0000000000..0a62767b4e --- /dev/null +++ b/doc/man/nvme_get_log_telemetry_ctrl.2 @@ -0,0 +1,21 @@ +.TH "nvme_get_log_telemetry_ctrl" 2 "nvme_get_log_telemetry_ctrl" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_log_telemetry_ctrl \- +.SH SYNOPSIS +.B "int" nvme_get_log_telemetry_ctrl +.BI "(int " fd "," +.BI "bool " rae "," +.BI "__u64 " offset "," +.BI "__u32 " len "," +.BI "void *" log ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "rae" 12 +Retain asynchronous events +.IP "offset" 12 +Offset into the telemetry data +.IP "len" 12 +Length of provided user buffer to hold the log data in bytes +.IP "log" 12 +User address for log page data diff --git a/doc/man/nvme_get_log_telemetry_host.2 b/doc/man/nvme_get_log_telemetry_host.2 new file mode 100644 index 0000000000..2aff066b2a --- /dev/null +++ b/doc/man/nvme_get_log_telemetry_host.2 @@ -0,0 +1,24 @@ +.TH "nvme_get_log_telemetry_host" 2 "nvme_get_log_telemetry_host" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_log_telemetry_host \- +.SH SYNOPSIS +.B "int" nvme_get_log_telemetry_host +.BI "(int " fd "," +.BI "__u64 " offset "," +.BI "__u32 " len "," +.BI "void *" log ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "offset" 12 +Offset into the telemetry data +.IP "len" 12 +Length of provided user buffer to hold the log data in bytes +.IP "log" 12 +User address for log page data +.SH "DESCRIPTION" +Retreives the Telemetry Host-Initiated log page at the requested offset +using the previously existing capture. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_new_host_telemetry.2 b/doc/man/nvme_get_new_host_telemetry.2 new file mode 100644 index 0000000000..2084fc68f0 --- /dev/null +++ b/doc/man/nvme_get_new_host_telemetry.2 @@ -0,0 +1,14 @@ +.TH "nvme_get_new_host_telemetry" 2 "nvme_get_new_host_telemetry" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_new_host_telemetry \- +.SH SYNOPSIS +.B "int" nvme_get_new_host_telemetry +.BI "(int " fd "," +.BI "void **" buf "," +.BI "__u32 *" log_size ");" +.SH ARGUMENTS +.IP "fd" 12 +-- undescribed -- +.IP "buf" 12 +-- undescribed -- +.IP "log_size" 12 diff --git a/doc/man/nvme_get_ns_attr.2 b/doc/man/nvme_get_ns_attr.2 new file mode 100644 index 0000000000..b015558124 --- /dev/null +++ b/doc/man/nvme_get_ns_attr.2 @@ -0,0 +1,11 @@ +.TH "nvme_get_ns_attr" 2 "nvme_get_ns_attr" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_ns_attr \- +.SH SYNOPSIS +.B "char *" nvme_get_ns_attr +.BI "(nvme_ns_t " n "," +.BI "const char *" attr ");" +.SH ARGUMENTS +.IP "n" 12 +-- undescribed -- +.IP "attr" 12 diff --git a/doc/man/nvme_get_nsid.2 b/doc/man/nvme_get_nsid.2 new file mode 100644 index 0000000000..0b82f6285e --- /dev/null +++ b/doc/man/nvme_get_nsid.2 @@ -0,0 +1,14 @@ +.TH "nvme_get_nsid" 2 "nvme_get_nsid" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_nsid \- Retrieve the NSID from a namespace file descriptor +.SH SYNOPSIS +.B "int" nvme_get_nsid +.BI "(int " fd ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme namespace +.SH "DESCRIPTION" +This should only be sent to namespace handles, not to controllers. +.SH "RETURN" +The namespace identifier if a succecssful or -1 with errno set +otherwise. diff --git a/doc/man/nvme_get_path_attr.2 b/doc/man/nvme_get_path_attr.2 new file mode 100644 index 0000000000..bf798592a4 --- /dev/null +++ b/doc/man/nvme_get_path_attr.2 @@ -0,0 +1,11 @@ +.TH "nvme_get_path_attr" 2 "nvme_get_path_attr" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_path_attr \- +.SH SYNOPSIS +.B "char *" nvme_get_path_attr +.BI "(nvme_path_t " p "," +.BI "const char *" attr ");" +.SH ARGUMENTS +.IP "p" 12 +-- undescribed -- +.IP "attr" 12 diff --git a/doc/man/nvme_get_property.2 b/doc/man/nvme_get_property.2 new file mode 100644 index 0000000000..30469f280b --- /dev/null +++ b/doc/man/nvme_get_property.2 @@ -0,0 +1,21 @@ +.TH "nvme_get_property" 2 "nvme_get_property" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_property \- Get a controller property +.SH SYNOPSIS +.B "int" nvme_get_property +.BI "(int " fd "," +.BI "int " offset "," +.BI "__u64 *" value ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "offset" 12 +Property offset from the base to retrieve +.IP "value" 12 +Where the property's value will be stored on success +.SH "DESCRIPTION" +This is an NVMe-over-Fabrics specific command, not applicable to PCIe. These +properties align to the PCI MMIO controller registers. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_get_subsys_attr.2 b/doc/man/nvme_get_subsys_attr.2 new file mode 100644 index 0000000000..5691cc5943 --- /dev/null +++ b/doc/man/nvme_get_subsys_attr.2 @@ -0,0 +1,11 @@ +.TH "nvme_get_subsys_attr" 2 "nvme_get_subsys_attr" "February 2020" "libnvme Manual" +.SH NAME +nvme_get_subsys_attr \- +.SH SYNOPSIS +.B "char *" nvme_get_subsys_attr +.BI "(nvme_subsystem_t " s "," +.BI "const char *" attr ");" +.SH ARGUMENTS +.IP "s" 12 +-- undescribed -- +.IP "attr" 12 diff --git a/doc/man/nvme_identify.2 b/doc/man/nvme_identify.2 new file mode 100644 index 0000000000..cbf56d8169 --- /dev/null +++ b/doc/man/nvme_identify.2 @@ -0,0 +1,33 @@ +.TH "nvme_identify" 2 "nvme_identify" "February 2020" "libnvme Manual" +.SH NAME +nvme_identify \- Send the NVMe Identify command +.SH SYNOPSIS +.B "int" nvme_identify +.BI "(int " fd "," +.BI "enum nvme_identify_cns " cns "," +.BI "__u32 " nsid "," +.BI "__u16 " cntid "," +.BI "__u16 " nvmsetid "," +.BI "__u8 " uuidx "," +.BI "void *" data ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "cns" 12 +The Controller or Namespace structure, see \fIenum\fP nvme_identify_cns +.IP "nsid" 12 +Namespace identifier, if applicable +.IP "cntid" 12 +The Controller Identifier, if applicable +.IP "nvmsetid" 12 +The NVMe Set ID if CNS is 04h +.IP "uuidx" 12 +UUID Index if controller supports this id selection method +.IP "data" 12 +User space destination address to transfer the data +.SH "DESCRIPTION" +The Identify command returns a data buffer that describes information about +the NVM subsystem, the controller or the namespace(s). +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_identify_active_ns_list.2 b/doc/man/nvme_identify_active_ns_list.2 new file mode 100644 index 0000000000..2edd8fae94 --- /dev/null +++ b/doc/man/nvme_identify_active_ns_list.2 @@ -0,0 +1,24 @@ +.TH "nvme_identify_active_ns_list" 2 "nvme_identify_active_ns_list" "February 2020" "libnvme Manual" +.SH NAME +nvme_identify_active_ns_list \- Retrieves active namespaces id list +.SH SYNOPSIS +.B "int" nvme_identify_active_ns_list +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "struct nvme_ns_list *" list ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Return namespaces greater than this identifer +.IP "list" 12 +-- undescribed -- +.SH "DESCRIPTION" +A list of 1024 namespace IDs is returned to the host containing NSIDs in +increasing order that are greater than the value specified in the Namespace +Identifier (nsid) field of the command. + +See \fIstruct nvme_ns_list\fP for the definition of the returned structure. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_identify_allocated_ns.2 b/doc/man/nvme_identify_allocated_ns.2 new file mode 100644 index 0000000000..ae37636ef8 --- /dev/null +++ b/doc/man/nvme_identify_allocated_ns.2 @@ -0,0 +1,18 @@ +.TH "nvme_identify_allocated_ns" 2 "nvme_identify_allocated_ns" "February 2020" "libnvme Manual" +.SH NAME +nvme_identify_allocated_ns \- Same as nvme_identify_ns, but only for allocated namespaces +.SH SYNOPSIS +.B "int" nvme_identify_allocated_ns +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "struct nvme_id_ns *" ns ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Namespace to identify +.IP "ns" 12 +User space destination address to transfer the data +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_identify_allocated_ns_list.2 b/doc/man/nvme_identify_allocated_ns_list.2 new file mode 100644 index 0000000000..d44a9c01d7 --- /dev/null +++ b/doc/man/nvme_identify_allocated_ns_list.2 @@ -0,0 +1,24 @@ +.TH "nvme_identify_allocated_ns_list" 2 "nvme_identify_allocated_ns_list" "February 2020" "libnvme Manual" +.SH NAME +nvme_identify_allocated_ns_list \- Retrieves allocated namespace id list +.SH SYNOPSIS +.B "int" nvme_identify_allocated_ns_list +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "struct nvme_ns_list *" list ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Return namespaces greater than this identifer +.IP "list" 12 +-- undescribed -- +.SH "DESCRIPTION" +A list of 1024 namespace IDs is returned to the host containing NSIDs in +increasing order that are greater than the value specified in the Namespace +Identifier (nsid) field of the command. + +See \fIstruct nvme_ns_list\fP for the definition of the returned structure. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_identify_ctrl.2 b/doc/man/nvme_identify_ctrl.2 new file mode 100644 index 0000000000..32cde03693 --- /dev/null +++ b/doc/man/nvme_identify_ctrl.2 @@ -0,0 +1,20 @@ +.TH "nvme_identify_ctrl" 2 "nvme_identify_ctrl" "February 2020" "libnvme Manual" +.SH NAME +nvme_identify_ctrl \- Retrieves nvme identify controller +.SH SYNOPSIS +.B "int" nvme_identify_ctrl +.BI "(int " fd "," +.BI "struct nvme_id_ctrl *" id ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +id: User space destination address to transfer the data, +.IP "id" 12 +-- undescribed -- +.SH "DESCRIPTION" +Sends nvme identify with CNS value NVME_IDENTIFY_CNS_CTRL. + +See \fIstruct nvme_id_ctrl\fP for details on the data returned. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_identify_ctrl_list.2 b/doc/man/nvme_identify_ctrl_list.2 new file mode 100644 index 0000000000..a0aa18dd3e --- /dev/null +++ b/doc/man/nvme_identify_ctrl_list.2 @@ -0,0 +1,24 @@ +.TH "nvme_identify_ctrl_list" 2 "nvme_identify_ctrl_list" "February 2020" "libnvme Manual" +.SH NAME +nvme_identify_ctrl_list \- Retrieves identify controller list +.SH SYNOPSIS +.B "int" nvme_identify_ctrl_list +.BI "(int " fd "," +.BI "__u16 " cntid "," +.BI "struct nvme_ctrl_list *" ctrlist ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "cntid" 12 +-- undescribed -- +.IP "ctrlist" 12 +-- undescribed -- +.SH "DESCRIPTION" +Up to 2047 controller identifiers is returned containing a controller +identifier greater than or equal to the controller identifier specified in +\fIcntid\fP. + +See \fIstruct nvme_ctrl_list\fP for a definition of the structure returned. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_identify_ns.2 b/doc/man/nvme_identify_ns.2 new file mode 100644 index 0000000000..fa6e8b57a5 --- /dev/null +++ b/doc/man/nvme_identify_ns.2 @@ -0,0 +1,29 @@ +.TH "nvme_identify_ns" 2 "nvme_identify_ns" "February 2020" "libnvme Manual" +.SH NAME +nvme_identify_ns \- Retrieves nvme identify namespace +.SH SYNOPSIS +.B "int" nvme_identify_ns +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "struct nvme_id_ns *" ns ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Namespace to identify +.IP "ns" 12 +User space destination address to transfer the data +.SH "DESCRIPTION" +If the Namespace Identifier (NSID) field specifies an active NSID, then the +Identify Namespace data structure is returned to the host for that specified +namespace. + +If the controller supports the Namespace Management capability and the NSID +field is set to NVME_NSID_ALL, then the controller returns an Identify Namespace +data structure that specifies capabilities that are common across namespaces +for this controller. + +See \fIstruct nvme_id_ns\fP for details on the structure returned. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_identify_ns_descs.2 b/doc/man/nvme_identify_ns_descs.2 new file mode 100644 index 0000000000..28673b312e --- /dev/null +++ b/doc/man/nvme_identify_ns_descs.2 @@ -0,0 +1,26 @@ +.TH "nvme_identify_ns_descs" 2 "nvme_identify_ns_descs" "February 2020" "libnvme Manual" +.SH NAME +nvme_identify_ns_descs \- Retrieves namespace descriptor list +.SH SYNOPSIS +.B "int" nvme_identify_ns_descs +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "struct nvme_ns_id_desc *" descs ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +The namespace id to retrieve destriptors +.IP "descs" 12 +User space destination address to transfer the data +.SH "DESCRIPTION" +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'. + +See \fIstruct nvme_ns_id_desc\fP for the definition of the returned structure. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_identify_ns_granularity.2 b/doc/man/nvme_identify_ns_granularity.2 new file mode 100644 index 0000000000..1987855c83 --- /dev/null +++ b/doc/man/nvme_identify_ns_granularity.2 @@ -0,0 +1,22 @@ +.TH "nvme_identify_ns_granularity" 2 "nvme_identify_ns_granularity" "February 2020" "libnvme Manual" +.SH NAME +nvme_identify_ns_granularity \- Retrieves namespace granularity identification +.SH SYNOPSIS +.B "int" nvme_identify_ns_granularity +.BI "(int " fd "," +.BI "struct nvme_id_ns_granularity_list *" list ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "list" 12 +-- undescribed -- +.SH "DESCRIPTION" +If the controller supports reporting of Namespace Granularity, then a +Namespace Granularity List is returned to the host for up to sixteen +namespace granularity descriptors + +See \fIstruct nvme_id_ns_granularity_list\fP for the definition of the returned +structure. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_identify_nsid_ctrl_list.2 b/doc/man/nvme_identify_nsid_ctrl_list.2 new file mode 100644 index 0000000000..484dd98164 --- /dev/null +++ b/doc/man/nvme_identify_nsid_ctrl_list.2 @@ -0,0 +1,26 @@ +.TH "nvme_identify_nsid_ctrl_list" 2 "nvme_identify_nsid_ctrl_list" "February 2020" "libnvme Manual" +.SH NAME +nvme_identify_nsid_ctrl_list \- +.SH SYNOPSIS +.B "int" nvme_identify_nsid_ctrl_list +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "__u16 " cntid "," +.BI "struct nvme_ctrl_list *" ctrlist ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Return controllers that are attached to this nsid +.IP "cntid" 12 +-- undescribed -- +.IP "ctrlist" 12 +-- undescribed -- +.SH "DESCRIPTION" +Up to 2047 controller identifiers is returned containing a controller +identifier greater than or equal to the controller identifier specified in +\fIcntid\fP. + +See \fIstruct nvme_ctrl_list\fP for a definition of the structure returned. +.SH "RETURN" +The nvme command status if a response was received or -1 diff --git a/doc/man/nvme_identify_nvmset_list.2 b/doc/man/nvme_identify_nvmset_list.2 new file mode 100644 index 0000000000..5b794549a2 --- /dev/null +++ b/doc/man/nvme_identify_nvmset_list.2 @@ -0,0 +1,25 @@ +.TH "nvme_identify_nvmset_list" 2 "nvme_identify_nvmset_list" "February 2020" "libnvme Manual" +.SH NAME +nvme_identify_nvmset_list \- Retrieves NVM Set List +.SH SYNOPSIS +.B "int" nvme_identify_nvmset_list +.BI "(int " fd "," +.BI "__u16 " nvmsetid "," +.BI "struct nvme_id_nvmset_list *" nvmset ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nvmsetid" 12 +-- undescribed -- +.IP "nvmset" 12 +User space destination address to transfer the data +.SH "DESCRIPTION" +Retrieves an NVM Set List, struct nvme_id_nvmset. The data structure is an +ordered list by NVM Set Identifier, starting with the first NVM Set +Identifier supported by the NVM subsystem that is equal to or greater than +the NVM Set Identifier. + +See \fIstruct nvme_id_nvmset_list\fP for the defintion of the returned structure. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_identify_primary_ctrl.2 b/doc/man/nvme_identify_primary_ctrl.2 new file mode 100644 index 0000000000..c0d31678f5 --- /dev/null +++ b/doc/man/nvme_identify_primary_ctrl.2 @@ -0,0 +1,19 @@ +.TH "nvme_identify_primary_ctrl" 2 "nvme_identify_primary_ctrl" "February 2020" "libnvme Manual" +.SH NAME +nvme_identify_primary_ctrl \- Retrieve NVMe Primary Controller identification &fd: +.SH SYNOPSIS +.B "int" nvme_identify_primary_ctrl +.BI "(int " fd "," +.BI "__u16 " cntid "," +.BI "struct nvme_primary_ctrl_cap *" cap ");" +.SH ARGUMENTS +.IP "fd" 12 +-- undescribed -- +.IP "cntid" 12 +-- undescribed -- +.IP "cap" 12 +.SH "DESCRIPTION" +See \fIstruct nvme_primary_ctrl_cap\fP for the defintion of the returned structure, \fIcap\fP. +.SH "RETURN" +The nvme command status if a response was received or -1 +with errno set otherwise. diff --git a/doc/man/nvme_identify_secondary_ctrl_list.2 b/doc/man/nvme_identify_secondary_ctrl_list.2 new file mode 100644 index 0000000000..976418aaea --- /dev/null +++ b/doc/man/nvme_identify_secondary_ctrl_list.2 @@ -0,0 +1,26 @@ +.TH "nvme_identify_secondary_ctrl_list" 2 "nvme_identify_secondary_ctrl_list" "February 2020" "libnvme Manual" +.SH NAME +nvme_identify_secondary_ctrl_list \- Retrieves secondary controller list +.SH SYNOPSIS +.B "int" nvme_identify_secondary_ctrl_list +.BI "(int " fd "," +.BI "__u16 " cntid "," +.BI "struct nvme_secondary_ctrl_list *" list ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "cntid" 12 +Return controllers starting at this identifier +.IP "list" 12 +-- undescribed -- +.SH "DESCRIPTION" +A Secondary Controller List is returned to the host for up to 127 secondary +controllers associated with the primary controller processing this command. +The list contains entries for controller identifiers greater than or equal +to the value specified in the Controller Identifier (cntid). + +See \fIstruct nvme_secondary_ctrls_list\fP for a defintion of the returned +structure. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_identify_uuid.2 b/doc/man/nvme_identify_uuid.2 new file mode 100644 index 0000000000..2e4c28f06e --- /dev/null +++ b/doc/man/nvme_identify_uuid.2 @@ -0,0 +1,20 @@ +.TH "nvme_identify_uuid" 2 "nvme_identify_uuid" "February 2020" "libnvme Manual" +.SH NAME +nvme_identify_uuid \- Retrieves device's UUIDs +.SH SYNOPSIS +.B "int" nvme_identify_uuid +.BI "(int " fd "," +.BI "struct nvme_id_uuid_list *" list ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "list" 12 +-- undescribed -- +.SH "DESCRIPTION" +Each UUID List entry is either 0h, the NVMe Invalid UUID, or a valid UUID. +Valid UUIDs are those which are non-zero and are not the NVMe Invalid UUID. + +See \fIstruct nvme_id_uuid_list\fP for the definition of the returned structure. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_io_passthru.2 b/doc/man/nvme_io_passthru.2 new file mode 100644 index 0000000000..beb467c91e --- /dev/null +++ b/doc/man/nvme_io_passthru.2 @@ -0,0 +1,71 @@ +.TH "nvme_io_passthru" 2 "nvme_io_passthru" "February 2020" "libnvme Manual" +.SH NAME +nvme_io_passthru \- Submit an nvme io passthrough command +.SH SYNOPSIS +.B "int" nvme_io_passthru +.BI "(int " fd "," +.BI "__u8 " opcode "," +.BI "__u8 " flags "," +.BI "__u16 " rsvd "," +.BI "__u32 " nsid "," +.BI "__u32 " cdw2 "," +.BI "__u32 " cdw3 "," +.BI "__u32 " cdw10 "," +.BI "__u32 " cdw11 "," +.BI "__u32 " cdw12 "," +.BI "__u32 " cdw13 "," +.BI "__u32 " cdw14 "," +.BI "__u32 " cdw15 "," +.BI "__u32 " data_len "," +.BI "void *" data "," +.BI "__u32 " metadata_len "," +.BI "void *" metadata "," +.BI "__u32 " timeout_ms "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "opcode" 12 +The nvme io command to send +.IP "flags" 12 +NVMe command flags (not used) +.IP "rsvd" 12 +Reserevd for future use +.IP "nsid" 12 +Namespace identifier +.IP "cdw2" 12 +Command dword 2 +.IP "cdw3" 12 +Command dword 3 +.IP "cdw10" 12 +Command dword 10 +.IP "cdw11" 12 +Command dword 11 +.IP "cdw12" 12 +Command dword 12 +.IP "cdw13" 12 +Command dword 13 +.IP "cdw14" 12 +Command dword 14 +.IP "cdw15" 12 +Command dword 15 +.IP "data_len" 12 +Length of the data transfered in this command in bytes +.IP "data" 12 +Pointer to user address of the data buffer +.IP "metadata_len" 12 +Length of metadata transfered in this command +.IP "metadata" 12 +Pointer to user address of the metadata buffer +.IP "timeout_ms" 12 +How long the kernel waits for the command to complete +.IP "result" 12 +Optional field to return the result from the CQE dword 0 +.SH "DESCRIPTION" +Parameterized form of \fBnvme_submit_io_passthru\fP. This sets up and submits +a \fIstruct nvme_passthru_cmd\fP. + +Known values for \fIopcode\fP are defined in \fIenum nvme_io_opcode\fP. +.SH "RETURN" +The nvme command status if a response was received or -1 +with errno set otherwise. diff --git a/doc/man/nvme_io_passthru64.2 b/doc/man/nvme_io_passthru64.2 new file mode 100644 index 0000000000..9456bbc26c --- /dev/null +++ b/doc/man/nvme_io_passthru64.2 @@ -0,0 +1,71 @@ +.TH "nvme_io_passthru64" 2 "nvme_io_passthru64" "February 2020" "libnvme Manual" +.SH NAME +nvme_io_passthru64 \- Submit an nvme io passthrough command +.SH SYNOPSIS +.B "int" nvme_io_passthru64 +.BI "(int " fd "," +.BI "__u8 " opcode "," +.BI "__u8 " flags "," +.BI "__u16 " rsvd "," +.BI "__u32 " nsid "," +.BI "__u32 " cdw2 "," +.BI "__u32 " cdw3 "," +.BI "__u32 " cdw10 "," +.BI "__u32 " cdw11 "," +.BI "__u32 " cdw12 "," +.BI "__u32 " cdw13 "," +.BI "__u32 " cdw14 "," +.BI "__u32 " cdw15 "," +.BI "__u32 " data_len "," +.BI "void *" data "," +.BI "__u32 " metadata_len "," +.BI "void *" metadata "," +.BI "__u32 " timeout_ms "," +.BI "__u64 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "opcode" 12 +The nvme io command to send +.IP "flags" 12 +NVMe command flags (not used) +.IP "rsvd" 12 +Reserevd for future use +.IP "nsid" 12 +Namespace identifier +.IP "cdw2" 12 +Command dword 2 +.IP "cdw3" 12 +Command dword 3 +.IP "cdw10" 12 +Command dword 10 +.IP "cdw11" 12 +Command dword 11 +.IP "cdw12" 12 +Command dword 12 +.IP "cdw13" 12 +Command dword 13 +.IP "cdw14" 12 +Command dword 14 +.IP "cdw15" 12 +Command dword 15 +.IP "data_len" 12 +Length of the data transfered in this command in bytes +.IP "data" 12 +Pointer to user address of the data buffer +.IP "metadata_len" 12 +Length of metadata transfered in this command +.IP "metadata" 12 +Pointer to user address of the metadata buffer +.IP "timeout_ms" 12 +How long the kernel waits for the command to complete +.IP "result" 12 +Optional field to return the result from the CQE dword 0 +.SH "DESCRIPTION" +Parameterized form of \fBnvme_submit_io_passthru64\fP. This sets up and submits +a \fIstruct nvme_passthru_cmd64\fP. + +Known values for \fIopcode\fP are defined in \fIenum nvme_io_opcode\fP. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_namespace_attach_ctrls.2 b/doc/man/nvme_namespace_attach_ctrls.2 new file mode 100644 index 0000000000..1459ed4a6d --- /dev/null +++ b/doc/man/nvme_namespace_attach_ctrls.2 @@ -0,0 +1,21 @@ +.TH "nvme_namespace_attach_ctrls" 2 "nvme_namespace_attach_ctrls" "February 2020" "libnvme Manual" +.SH NAME +nvme_namespace_attach_ctrls \- Attach namespace to controller(s) +.SH SYNOPSIS +.B "int" nvme_namespace_attach_ctrls +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "__u16 " num_ctrls "," +.BI "__u16 *" ctrlist ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Namespace ID to attach +.IP "num_ctrls" 12 +Number of controllers in ctrlist +.IP "ctrlist" 12 +List of controller IDs to perform the attach action +.SH "RETURN" +The nvme command status if a response was received or -1 +with errno set otherwise. diff --git a/doc/man/nvme_namespace_detach_ctrls.2 b/doc/man/nvme_namespace_detach_ctrls.2 new file mode 100644 index 0000000000..dfc12eae36 --- /dev/null +++ b/doc/man/nvme_namespace_detach_ctrls.2 @@ -0,0 +1,21 @@ +.TH "nvme_namespace_detach_ctrls" 2 "nvme_namespace_detach_ctrls" "February 2020" "libnvme Manual" +.SH NAME +nvme_namespace_detach_ctrls \- Detach namespace from controller(s) +.SH SYNOPSIS +.B "int" nvme_namespace_detach_ctrls +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "__u16 " num_ctrls "," +.BI "__u16 *" ctrlist ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Namespace ID to detach +.IP "num_ctrls" 12 +Number of controllers in ctrlist +.IP "ctrlist" 12 +List of controller IDs to perform the detach action +.SH "RETURN" +The nvme command status if a response was received or -1 +with errno set otherwise. diff --git a/doc/man/nvme_namespace_filter.2 b/doc/man/nvme_namespace_filter.2 new file mode 100644 index 0000000000..35cdfdeb4e --- /dev/null +++ b/doc/man/nvme_namespace_filter.2 @@ -0,0 +1,8 @@ +.TH "nvme_namespace_filter" 2 "nvme_namespace_filter" "February 2020" "libnvme Manual" +.SH NAME +nvme_namespace_filter \- +.SH SYNOPSIS +.B "int" nvme_namespace_filter +.BI "(const struct dirent *" d ");" +.SH ARGUMENTS +.IP "d" 12 diff --git a/doc/man/nvme_next_subsystem.2 b/doc/man/nvme_next_subsystem.2 new file mode 100644 index 0000000000..c144904640 --- /dev/null +++ b/doc/man/nvme_next_subsystem.2 @@ -0,0 +1,11 @@ +.TH "nvme_next_subsystem" 2 "nvme_next_subsystem" "February 2020" "libnvme Manual" +.SH NAME +nvme_next_subsystem \- +.SH SYNOPSIS +.B "nvme_subsystem_t" nvme_next_subsystem +.BI "(nvme_root_t " r "," +.BI "nvme_subsystem_t " s ");" +.SH ARGUMENTS +.IP "r" 12 +-- undescribed -- +.IP "s" 12 diff --git a/doc/man/nvme_ns_attach.2 b/doc/man/nvme_ns_attach.2 new file mode 100644 index 0000000000..48607c47ae --- /dev/null +++ b/doc/man/nvme_ns_attach.2 @@ -0,0 +1,18 @@ +.TH "nvme_ns_attach" 2 "nvme_ns_attach" "February 2020" "libnvme Manual" +.SH NAME +nvme_ns_attach \- Attach or detach namespace to controller(s) +.SH SYNOPSIS +.B "int" nvme_ns_attach +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "enum nvme_ns_attach_sel " sel "," +.BI "struct nvme_ctrl_list *" ctrlist ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Namespace ID to execute attach selection +.IP "sel" 12 +Attachment selection, see \fIenum nvme_ns_attach_sel\fP +.IP "ctrlist" 12 +Controller list to modify attachment state of nsid diff --git a/doc/man/nvme_ns_attach_ctrls.2 b/doc/man/nvme_ns_attach_ctrls.2 new file mode 100644 index 0000000000..be131410e1 --- /dev/null +++ b/doc/man/nvme_ns_attach_ctrls.2 @@ -0,0 +1,15 @@ +.TH "nvme_ns_attach_ctrls" 2 "nvme_ns_attach_ctrls" "February 2020" "libnvme Manual" +.SH NAME +nvme_ns_attach_ctrls \- +.SH SYNOPSIS +.B "int" nvme_ns_attach_ctrls +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "struct nvme_ctrl_list *" ctrlist ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Namespace ID to attach +.IP "ctrlist" 12 +Controller list to modify attachment state of nsid diff --git a/doc/man/nvme_ns_compare.2 b/doc/man/nvme_ns_compare.2 new file mode 100644 index 0000000000..bf3f6118a0 --- /dev/null +++ b/doc/man/nvme_ns_compare.2 @@ -0,0 +1,17 @@ +.TH "nvme_ns_compare" 2 "nvme_ns_compare" "February 2020" "libnvme Manual" +.SH NAME +nvme_ns_compare \- +.SH SYNOPSIS +.B "int" nvme_ns_compare +.BI "(nvme_ns_t " n "," +.BI "void *" buf "," +.BI "off_t " offset "," +.BI "size_t " count ");" +.SH ARGUMENTS +.IP "n" 12 +-- undescribed -- +.IP "buf" 12 +-- undescribed -- +.IP "offset" 12 +-- undescribed -- +.IP "count" 12 diff --git a/doc/man/nvme_ns_dettach_ctrls.2 b/doc/man/nvme_ns_dettach_ctrls.2 new file mode 100644 index 0000000000..9bc4df1bd6 --- /dev/null +++ b/doc/man/nvme_ns_dettach_ctrls.2 @@ -0,0 +1,15 @@ +.TH "nvme_ns_dettach_ctrls" 2 "nvme_ns_dettach_ctrls" "February 2020" "libnvme Manual" +.SH NAME +nvme_ns_dettach_ctrls \- +.SH SYNOPSIS +.B "int" nvme_ns_dettach_ctrls +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "struct nvme_ctrl_list *" ctrlist ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Namespace ID to dettach +.IP "ctrlist" 12 +Controller list to modify attachment state of nsid diff --git a/doc/man/nvme_ns_flush.2 b/doc/man/nvme_ns_flush.2 new file mode 100644 index 0000000000..0d0cae6bd8 --- /dev/null +++ b/doc/man/nvme_ns_flush.2 @@ -0,0 +1,8 @@ +.TH "nvme_ns_flush" 2 "nvme_ns_flush" "February 2020" "libnvme Manual" +.SH NAME +nvme_ns_flush \- +.SH SYNOPSIS +.B "int" nvme_ns_flush +.BI "(nvme_ns_t " n ");" +.SH ARGUMENTS +.IP "n" 12 diff --git a/doc/man/nvme_ns_get_ctrl.2 b/doc/man/nvme_ns_get_ctrl.2 new file mode 100644 index 0000000000..084cf2eb33 --- /dev/null +++ b/doc/man/nvme_ns_get_ctrl.2 @@ -0,0 +1,8 @@ +.TH "nvme_ns_get_ctrl" 2 "nvme_ns_get_ctrl" "February 2020" "libnvme Manual" +.SH NAME +nvme_ns_get_ctrl \- +.SH SYNOPSIS +.B "nvme_ctrl_t" nvme_ns_get_ctrl +.BI "(nvme_ns_t " n ");" +.SH ARGUMENTS +.IP "n" 12 diff --git a/doc/man/nvme_ns_get_fd.2 b/doc/man/nvme_ns_get_fd.2 new file mode 100644 index 0000000000..c65fea1b34 --- /dev/null +++ b/doc/man/nvme_ns_get_fd.2 @@ -0,0 +1,8 @@ +.TH "nvme_ns_get_fd" 2 "nvme_ns_get_fd" "February 2020" "libnvme Manual" +.SH NAME +nvme_ns_get_fd \- +.SH SYNOPSIS +.B "int" nvme_ns_get_fd +.BI "(nvme_ns_t " n ");" +.SH ARGUMENTS +.IP "n" 12 diff --git a/doc/man/nvme_ns_get_lba_count.2 b/doc/man/nvme_ns_get_lba_count.2 new file mode 100644 index 0000000000..77fc445f04 --- /dev/null +++ b/doc/man/nvme_ns_get_lba_count.2 @@ -0,0 +1,8 @@ +.TH "nvme_ns_get_lba_count" 2 "nvme_ns_get_lba_count" "February 2020" "libnvme Manual" +.SH NAME +nvme_ns_get_lba_count \- +.SH SYNOPSIS +.B "uint64_t" nvme_ns_get_lba_count +.BI "(nvme_ns_t " n ");" +.SH ARGUMENTS +.IP "n" 12 diff --git a/doc/man/nvme_ns_get_lba_size.2 b/doc/man/nvme_ns_get_lba_size.2 new file mode 100644 index 0000000000..9b3d2d860a --- /dev/null +++ b/doc/man/nvme_ns_get_lba_size.2 @@ -0,0 +1,8 @@ +.TH "nvme_ns_get_lba_size" 2 "nvme_ns_get_lba_size" "February 2020" "libnvme Manual" +.SH NAME +nvme_ns_get_lba_size \- +.SH SYNOPSIS +.B "int" nvme_ns_get_lba_size +.BI "(nvme_ns_t " n ");" +.SH ARGUMENTS +.IP "n" 12 diff --git a/doc/man/nvme_ns_get_lba_util.2 b/doc/man/nvme_ns_get_lba_util.2 new file mode 100644 index 0000000000..bbcef5a2cf --- /dev/null +++ b/doc/man/nvme_ns_get_lba_util.2 @@ -0,0 +1,8 @@ +.TH "nvme_ns_get_lba_util" 2 "nvme_ns_get_lba_util" "February 2020" "libnvme Manual" +.SH NAME +nvme_ns_get_lba_util \- +.SH SYNOPSIS +.B "uint64_t" nvme_ns_get_lba_util +.BI "(nvme_ns_t " n ");" +.SH ARGUMENTS +.IP "n" 12 diff --git a/doc/man/nvme_ns_get_name.2 b/doc/man/nvme_ns_get_name.2 new file mode 100644 index 0000000000..351d848d8d --- /dev/null +++ b/doc/man/nvme_ns_get_name.2 @@ -0,0 +1,8 @@ +.TH "nvme_ns_get_name" 2 "nvme_ns_get_name" "February 2020" "libnvme Manual" +.SH NAME +nvme_ns_get_name \- +.SH SYNOPSIS +.B "const char *" nvme_ns_get_name +.BI "(nvme_ns_t " n ");" +.SH ARGUMENTS +.IP "n" 12 diff --git a/doc/man/nvme_ns_get_nsid.2 b/doc/man/nvme_ns_get_nsid.2 new file mode 100644 index 0000000000..a831344d68 --- /dev/null +++ b/doc/man/nvme_ns_get_nsid.2 @@ -0,0 +1,8 @@ +.TH "nvme_ns_get_nsid" 2 "nvme_ns_get_nsid" "February 2020" "libnvme Manual" +.SH NAME +nvme_ns_get_nsid \- +.SH SYNOPSIS +.B "int" nvme_ns_get_nsid +.BI "(nvme_ns_t " n ");" +.SH ARGUMENTS +.IP "n" 12 diff --git a/doc/man/nvme_ns_get_subsystem.2 b/doc/man/nvme_ns_get_subsystem.2 new file mode 100644 index 0000000000..185dc9f30d --- /dev/null +++ b/doc/man/nvme_ns_get_subsystem.2 @@ -0,0 +1,8 @@ +.TH "nvme_ns_get_subsystem" 2 "nvme_ns_get_subsystem" "February 2020" "libnvme Manual" +.SH NAME +nvme_ns_get_subsystem \- +.SH SYNOPSIS +.B "nvme_subsystem_t" nvme_ns_get_subsystem +.BI "(nvme_ns_t " n ");" +.SH ARGUMENTS +.IP "n" 12 diff --git a/doc/man/nvme_ns_get_sysfs_dir.2 b/doc/man/nvme_ns_get_sysfs_dir.2 new file mode 100644 index 0000000000..16e4312be0 --- /dev/null +++ b/doc/man/nvme_ns_get_sysfs_dir.2 @@ -0,0 +1,8 @@ +.TH "nvme_ns_get_sysfs_dir" 2 "nvme_ns_get_sysfs_dir" "February 2020" "libnvme Manual" +.SH NAME +nvme_ns_get_sysfs_dir \- +.SH SYNOPSIS +.B "const char *" nvme_ns_get_sysfs_dir +.BI "(nvme_ns_t " n ");" +.SH ARGUMENTS +.IP "n" 12 diff --git a/doc/man/nvme_ns_identify.2 b/doc/man/nvme_ns_identify.2 new file mode 100644 index 0000000000..cf455cd29f --- /dev/null +++ b/doc/man/nvme_ns_identify.2 @@ -0,0 +1,11 @@ +.TH "nvme_ns_identify" 2 "nvme_ns_identify" "February 2020" "libnvme Manual" +.SH NAME +nvme_ns_identify \- +.SH SYNOPSIS +.B "int" nvme_ns_identify +.BI "(nvme_ns_t " n "," +.BI "struct nvme_id_ns *" ns ");" +.SH ARGUMENTS +.IP "n" 12 +-- undescribed -- +.IP "ns" 12 diff --git a/doc/man/nvme_ns_mgmt.2 b/doc/man/nvme_ns_mgmt.2 new file mode 100644 index 0000000000..420489b2a6 --- /dev/null +++ b/doc/man/nvme_ns_mgmt.2 @@ -0,0 +1,24 @@ +.TH "nvme_ns_mgmt" 2 "nvme_ns_mgmt" "February 2020" "libnvme Manual" +.SH NAME +nvme_ns_mgmt \- +.SH SYNOPSIS +.B "int" nvme_ns_mgmt +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "enum nvme_ns_mgmt_sel " sel "," +.BI "struct nvme_id_ns *" ns "," +.BI "__u32 *" result "," +.BI "__u32 " timeout ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +-- undescribed -- +.IP "sel" 12 +-- undescribed -- +.IP "ns" 12 +-- undescribed -- +.IP "result" 12 +-- undescribed -- +.IP "timeout" 12 +-- undescribed -- diff --git a/doc/man/nvme_ns_mgmt_create.2 b/doc/man/nvme_ns_mgmt_create.2 new file mode 100644 index 0000000000..6ad9c85c92 --- /dev/null +++ b/doc/man/nvme_ns_mgmt_create.2 @@ -0,0 +1,26 @@ +.TH "nvme_ns_mgmt_create" 2 "nvme_ns_mgmt_create" "February 2020" "libnvme Manual" +.SH NAME +nvme_ns_mgmt_create \- +.SH SYNOPSIS +.B "int" nvme_ns_mgmt_create +.BI "(int " fd "," +.BI "struct nvme_id_ns *" ns "," +.BI "__u32 *" nsid "," +.BI "__u32 " timeout ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "ns" 12 +Namespace identifiaction that defines creation parameters +.IP "nsid" 12 +On success, set to the namespace id that was created +.IP "timeout" 12 +Overide the default timeout to this value in milliseconds; +set to 0 to use the system default. +.SH "DESCRIPTION" +On successful creation, the namespace exists in the subsystem, but is not +attached to any controller. Use the \fBnvme_ns_attach_ctrls\fP to assign the +namespace to one or more controllers. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_ns_mgmt_delete.2 b/doc/man/nvme_ns_mgmt_delete.2 new file mode 100644 index 0000000000..c8ddda417e --- /dev/null +++ b/doc/man/nvme_ns_mgmt_delete.2 @@ -0,0 +1,19 @@ +.TH "nvme_ns_mgmt_delete" 2 "nvme_ns_mgmt_delete" "February 2020" "libnvme Manual" +.SH NAME +nvme_ns_mgmt_delete \- +.SH SYNOPSIS +.B "int" nvme_ns_mgmt_delete +.BI "(int " fd "," +.BI "__u32 " nsid ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Namespace identifier to delete +.SH "DESCRIPTION" +It is recommended that a namespace being deleted is not attached to any +controller. Use the \fBnvme_ns_detach_ctrls\fP first if the namespace is still +attached. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_ns_read.2 b/doc/man/nvme_ns_read.2 new file mode 100644 index 0000000000..d29b246d50 --- /dev/null +++ b/doc/man/nvme_ns_read.2 @@ -0,0 +1,17 @@ +.TH "nvme_ns_read" 2 "nvme_ns_read" "February 2020" "libnvme Manual" +.SH NAME +nvme_ns_read \- +.SH SYNOPSIS +.B "int" nvme_ns_read +.BI "(nvme_ns_t " n "," +.BI "void *" buf "," +.BI "off_t " offset "," +.BI "size_t " count ");" +.SH ARGUMENTS +.IP "n" 12 +-- undescribed -- +.IP "buf" 12 +-- undescribed -- +.IP "offset" 12 +-- undescribed -- +.IP "count" 12 diff --git a/doc/man/nvme_ns_rescan.2 b/doc/man/nvme_ns_rescan.2 new file mode 100644 index 0000000000..a2e402f1b7 --- /dev/null +++ b/doc/man/nvme_ns_rescan.2 @@ -0,0 +1,13 @@ +.TH "nvme_ns_rescan" 2 "nvme_ns_rescan" "February 2020" "libnvme Manual" +.SH NAME +nvme_ns_rescan \- Initiate a controller rescan +.SH SYNOPSIS +.B "int" nvme_ns_rescan +.BI "(int " fd ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.SH "DESCRIPTION" +This should only be sent to controller handles, not to namespaces. +.SH "RETURN" +Zero if a rescan was initiated or -1 with errno set otherwise. diff --git a/doc/man/nvme_ns_verify.2 b/doc/man/nvme_ns_verify.2 new file mode 100644 index 0000000000..aa8c132a4e --- /dev/null +++ b/doc/man/nvme_ns_verify.2 @@ -0,0 +1,14 @@ +.TH "nvme_ns_verify" 2 "nvme_ns_verify" "February 2020" "libnvme Manual" +.SH NAME +nvme_ns_verify \- +.SH SYNOPSIS +.B "int" nvme_ns_verify +.BI "(nvme_ns_t " n "," +.BI "off_t " offset "," +.BI "size_t " count ");" +.SH ARGUMENTS +.IP "n" 12 +-- undescribed -- +.IP "offset" 12 +-- undescribed -- +.IP "count" 12 diff --git a/doc/man/nvme_ns_write.2 b/doc/man/nvme_ns_write.2 new file mode 100644 index 0000000000..9e0df75693 --- /dev/null +++ b/doc/man/nvme_ns_write.2 @@ -0,0 +1,17 @@ +.TH "nvme_ns_write" 2 "nvme_ns_write" "February 2020" "libnvme Manual" +.SH NAME +nvme_ns_write \- +.SH SYNOPSIS +.B "int" nvme_ns_write +.BI "(nvme_ns_t " n "," +.BI "void *" buf "," +.BI "off_t " offset "," +.BI "size_t " count ");" +.SH ARGUMENTS +.IP "n" 12 +-- undescribed -- +.IP "buf" 12 +-- undescribed -- +.IP "offset" 12 +-- undescribed -- +.IP "count" 12 diff --git a/doc/man/nvme_ns_write_uncorrectable.2 b/doc/man/nvme_ns_write_uncorrectable.2 new file mode 100644 index 0000000000..45a3d69a2d --- /dev/null +++ b/doc/man/nvme_ns_write_uncorrectable.2 @@ -0,0 +1,14 @@ +.TH "nvme_ns_write_uncorrectable" 2 "nvme_ns_write_uncorrectable" "February 2020" "libnvme Manual" +.SH NAME +nvme_ns_write_uncorrectable \- +.SH SYNOPSIS +.B "int" nvme_ns_write_uncorrectable +.BI "(nvme_ns_t " n "," +.BI "off_t " offset "," +.BI "size_t " count ");" +.SH ARGUMENTS +.IP "n" 12 +-- undescribed -- +.IP "offset" 12 +-- undescribed -- +.IP "count" 12 diff --git a/doc/man/nvme_ns_write_zeros.2 b/doc/man/nvme_ns_write_zeros.2 new file mode 100644 index 0000000000..6674ad1ebc --- /dev/null +++ b/doc/man/nvme_ns_write_zeros.2 @@ -0,0 +1,14 @@ +.TH "nvme_ns_write_zeros" 2 "nvme_ns_write_zeros" "February 2020" "libnvme Manual" +.SH NAME +nvme_ns_write_zeros \- +.SH SYNOPSIS +.B "int" nvme_ns_write_zeros +.BI "(nvme_ns_t " n "," +.BI "off_t " offset "," +.BI "size_t " count ");" +.SH ARGUMENTS +.IP "n" 12 +-- undescribed -- +.IP "offset" 12 +-- undescribed -- +.IP "count" 12 diff --git a/doc/man/nvme_open.2 b/doc/man/nvme_open.2 new file mode 100644 index 0000000000..c7ba11dd7d --- /dev/null +++ b/doc/man/nvme_open.2 @@ -0,0 +1,15 @@ +.TH "nvme_open" 2 "nvme_open" "February 2020" "libnvme Manual" +.SH NAME +nvme_open \- Open an nvme controller or namespace device +.SH SYNOPSIS +.B "int" nvme_open +.BI "(const char *" name ");" +.SH ARGUMENTS +.IP "name" 12 +The basename of the device to open +.SH "DESCRIPTION" +This will look for the handle in /dev/ and validate the name and filetype +match linux conventions. +.SH "RETURN" +A file descriptor for the device on a successful open, or -1 with +errno set otherwise. diff --git a/doc/man/nvme_path_get_ana_state.2 b/doc/man/nvme_path_get_ana_state.2 new file mode 100644 index 0000000000..99a6b79baa --- /dev/null +++ b/doc/man/nvme_path_get_ana_state.2 @@ -0,0 +1,8 @@ +.TH "nvme_path_get_ana_state" 2 "nvme_path_get_ana_state" "February 2020" "libnvme Manual" +.SH NAME +nvme_path_get_ana_state \- +.SH SYNOPSIS +.B "const char *" nvme_path_get_ana_state +.BI "(nvme_path_t " p ");" +.SH ARGUMENTS +.IP "p" 12 diff --git a/doc/man/nvme_path_get_name.2 b/doc/man/nvme_path_get_name.2 new file mode 100644 index 0000000000..c0e10c5dfa --- /dev/null +++ b/doc/man/nvme_path_get_name.2 @@ -0,0 +1,8 @@ +.TH "nvme_path_get_name" 2 "nvme_path_get_name" "February 2020" "libnvme Manual" +.SH NAME +nvme_path_get_name \- +.SH SYNOPSIS +.B "const char *" nvme_path_get_name +.BI "(nvme_path_t " p ");" +.SH ARGUMENTS +.IP "p" 12 diff --git a/doc/man/nvme_path_get_ns.2 b/doc/man/nvme_path_get_ns.2 new file mode 100644 index 0000000000..6b5da07335 --- /dev/null +++ b/doc/man/nvme_path_get_ns.2 @@ -0,0 +1,8 @@ +.TH "nvme_path_get_ns" 2 "nvme_path_get_ns" "February 2020" "libnvme Manual" +.SH NAME +nvme_path_get_ns \- +.SH SYNOPSIS +.B "nvme_ns_t" nvme_path_get_ns +.BI "(nvme_path_t " p ");" +.SH ARGUMENTS +.IP "p" 12 diff --git a/doc/man/nvme_path_get_subsystem.2 b/doc/man/nvme_path_get_subsystem.2 new file mode 100644 index 0000000000..17222ecdaa --- /dev/null +++ b/doc/man/nvme_path_get_subsystem.2 @@ -0,0 +1,8 @@ +.TH "nvme_path_get_subsystem" 2 "nvme_path_get_subsystem" "February 2020" "libnvme Manual" +.SH NAME +nvme_path_get_subsystem \- +.SH SYNOPSIS +.B "nvme_ctrl_t" nvme_path_get_subsystem +.BI "(nvme_path_t " p ");" +.SH ARGUMENTS +.IP "p" 12 diff --git a/doc/man/nvme_path_get_sysfs_dir.2 b/doc/man/nvme_path_get_sysfs_dir.2 new file mode 100644 index 0000000000..6d0dcd4430 --- /dev/null +++ b/doc/man/nvme_path_get_sysfs_dir.2 @@ -0,0 +1,8 @@ +.TH "nvme_path_get_sysfs_dir" 2 "nvme_path_get_sysfs_dir" "February 2020" "libnvme Manual" +.SH NAME +nvme_path_get_sysfs_dir \- +.SH SYNOPSIS +.B "const char *" nvme_path_get_sysfs_dir +.BI "(nvme_path_t " p ");" +.SH ARGUMENTS +.IP "p" 12 diff --git a/doc/man/nvme_paths_filter.2 b/doc/man/nvme_paths_filter.2 new file mode 100644 index 0000000000..737305c017 --- /dev/null +++ b/doc/man/nvme_paths_filter.2 @@ -0,0 +1,8 @@ +.TH "nvme_paths_filter" 2 "nvme_paths_filter" "February 2020" "libnvme Manual" +.SH NAME +nvme_paths_filter \- +.SH SYNOPSIS +.B "int" nvme_paths_filter +.BI "(const struct dirent *" d ");" +.SH ARGUMENTS +.IP "d" 12 diff --git a/doc/man/nvme_psd_power_scale.2 b/doc/man/nvme_psd_power_scale.2 new file mode 100644 index 0000000000..5261ebb222 --- /dev/null +++ b/doc/man/nvme_psd_power_scale.2 @@ -0,0 +1,9 @@ +.TH "nvme_psd_power_scale" 2 "nvme_psd_power_scale" "February 2020" "libnvme Manual" +.SH NAME +nvme_psd_power_scale \- power scale occupies the upper 3 bits +.SH SYNOPSIS +.B "unsigned" nvme_psd_power_scale +.BI "(__u8 " ps ");" +.SH ARGUMENTS +.IP "ps" 12 +-- undescribed -- diff --git a/doc/man/nvme_read.2 b/doc/man/nvme_read.2 new file mode 100644 index 0000000000..b0bed15125 --- /dev/null +++ b/doc/man/nvme_read.2 @@ -0,0 +1,55 @@ +.TH "nvme_read" 2 "nvme_read" "February 2020" "libnvme Manual" +.SH NAME +nvme_read \- Submit an nvme user read command +.SH SYNOPSIS +.B "int" nvme_read +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "__u64 " slba "," +.BI "__u16 " nlb "," +.BI "__u16 " control "," +.BI "__u8 " dsm "," +.BI "__u32 " reftag "," +.BI "__u16 " apptag "," +.BI "__u16 " appmask "," +.BI "__u32 " data_len "," +.BI "void *" data "," +.BI "__u32 " metadata_len "," +.BI "void *" metadata ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Namespace ID +.IP "slba" 12 +Starting logical block +.IP "nlb" 12 +-- undescribed -- +.IP "control" 12 +Command control flags, see \fIenum nvme_io_control_flags\fP. +.IP "dsm" 12 +Data set management attributes, see \fIenum nvme_io_dsm_flags\fP +.IP "reftag" 12 +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. +.IP "apptag" 12 +This field specifies the Application Tag Mask expected value. +Used only if the namespace is formatted to use end-to-end +protection information. +.IP "appmask" 12 +This field specifies the Application Tag expected value. Used +only if the namespace is formatted to use end-to-end protection +information. +.IP "data_len" 12 +Length of user buffer, \fIdata\fP, in bytes +.IP "data" 12 +Pointer to user address of the data buffer +metadata_len:Length of user buffer, \fImetadata\fP, in bytes +.IP "metadata_len" 12 +-- undescribed -- +.IP "metadata" 12 +Pointer to user address of the metadata buffer +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_refresh_topology.2 b/doc/man/nvme_refresh_topology.2 new file mode 100644 index 0000000000..9a4b34049d --- /dev/null +++ b/doc/man/nvme_refresh_topology.2 @@ -0,0 +1,9 @@ +.TH "nvme_refresh_topology" 2 "nvme_refresh_topology" "February 2020" "libnvme Manual" +.SH NAME +nvme_refresh_topology \- +.SH SYNOPSIS +.B "void" nvme_refresh_topology +.BI "(nvme_root_t " r ");" +.SH ARGUMENTS +.IP "r" 12 +-- undescribed -- diff --git a/doc/man/nvme_reset_topology.2 b/doc/man/nvme_reset_topology.2 new file mode 100644 index 0000000000..3a25e7e3d7 --- /dev/null +++ b/doc/man/nvme_reset_topology.2 @@ -0,0 +1,9 @@ +.TH "nvme_reset_topology" 2 "nvme_reset_topology" "February 2020" "libnvme Manual" +.SH NAME +nvme_reset_topology \- +.SH SYNOPSIS +.B "void" nvme_reset_topology +.BI "(nvme_root_t " r ");" +.SH ARGUMENTS +.IP "r" 12 +-- undescribed -- diff --git a/doc/man/nvme_resv_acquire.2 b/doc/man/nvme_resv_acquire.2 new file mode 100644 index 0000000000..b607dd2cf1 --- /dev/null +++ b/doc/man/nvme_resv_acquire.2 @@ -0,0 +1,35 @@ +.TH "nvme_resv_acquire" 2 "nvme_resv_acquire" "February 2020" "libnvme Manual" +.SH NAME +nvme_resv_acquire \- Send an nvme reservation acquire +.SH SYNOPSIS +.B "int" nvme_resv_acquire +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "enum nvme_reservation_rtype " rtype "," +.BI "enum nvme_reservation_racqa " racqa "," +.BI "bool " iekey "," +.BI "__u64 " crkey "," +.BI "__u64 " nrkey ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Namespace identifier +.IP "rtype" 12 +The type of reservation to be create, see \fIenum nvme_reservation_rtype\fP +.IP "racqa" 12 +The action that is performed by the command, see \fIenum nvme_reservation_racqa\fP +.IP "iekey" 12 +Set to ignore the existing key +.IP "crkey" 12 +The current reservation key associated with the host +.IP "nrkey" 12 +The reservation key to be unregistered from the namespace if +the action is preempt +.SH "DESCRIPTION" +The Reservation Acquire command is used to acquire a reservation on a +namespace, preempt a reservation held on a namespace, and abort a +reservation held on a namespace. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_resv_register.2 b/doc/man/nvme_resv_register.2 new file mode 100644 index 0000000000..fbe29c97e9 --- /dev/null +++ b/doc/man/nvme_resv_register.2 @@ -0,0 +1,34 @@ +.TH "nvme_resv_register" 2 "nvme_resv_register" "February 2020" "libnvme Manual" +.SH NAME +nvme_resv_register \- Send an nvme reservation register +.SH SYNOPSIS +.B "int" nvme_resv_register +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "enum nvme_reservation_rrega " rrega "," +.BI "enum nvme_reservation_cptpl " cptpl "," +.BI "bool " iekey "," +.BI "__u64 " crkey "," +.BI "__u64 " nrkey ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Namespace identifier +.IP "rrega" 12 +The registration action, see \fIenum nvme_reservation_rrega\fP +.IP "cptpl" 12 +Change persist through power loss, see \fIenum nvme_reservation_cptpl\fP +.IP "iekey" 12 +Set to ignore the existing key +.IP "crkey" 12 +The current reservation key associated with the host +.IP "nrkey" 12 +The new reservation key to be register if action is register or +replace +.SH "DESCRIPTION" +The Reservation Register command is used to register, unregister, or replace +a reservation key. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_resv_release.2 b/doc/man/nvme_resv_release.2 new file mode 100644 index 0000000000..748375dd3d --- /dev/null +++ b/doc/man/nvme_resv_release.2 @@ -0,0 +1,27 @@ +.TH "nvme_resv_release" 2 "nvme_resv_release" "February 2020" "libnvme Manual" +.SH NAME +nvme_resv_release \- Send an nvme reservation release +.SH SYNOPSIS +.B "int" nvme_resv_release +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "enum nvme_reservation_rtype " rtype "," +.BI "enum nvme_reservation_rrela " rrela "," +.BI "bool " iekey "," +.BI "__u64 " crkey ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Namespace identifier +.IP "rtype" 12 +The type of reservation to be create, see \fIenum nvme_reservation_rtype\fP +.IP "rrela" 12 +Reservation releast action, see \fIenum nvme_reservation_rrela\fP +.IP "iekey" 12 +Set to ignore the existing key +.IP "crkey" 12 +The current reservation key to release +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_resv_report.2 b/doc/man/nvme_resv_report.2 new file mode 100644 index 0000000000..7421b6fb03 --- /dev/null +++ b/doc/man/nvme_resv_report.2 @@ -0,0 +1,28 @@ +.TH "nvme_resv_report" 2 "nvme_resv_report" "February 2020" "libnvme Manual" +.SH NAME +nvme_resv_report \- Send an nvme reservation report +.SH SYNOPSIS +.B "int" nvme_resv_report +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "bool " eds "," +.BI "__u32 " len "," +.BI "struct nvme_reservation_status *" report ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Namespace identifier +.IP "eds" 12 +Request extended Data Structure +.IP "len" 12 +Number of bytes to request transfered with this command +.IP "report" 12 +The user space destination address to store the reservation report +.SH "DESCRIPTION" +Returns a Reservation Status data structure to memory that describes the +registration and reservation status of a namespace. See the defintion for +the returned structure, \fIstruct nvme_reservation_status\fP, for more details. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_sanitize_nvm.2 b/doc/man/nvme_sanitize_nvm.2 new file mode 100644 index 0000000000..3e1cf91aa1 --- /dev/null +++ b/doc/man/nvme_sanitize_nvm.2 @@ -0,0 +1,40 @@ +.TH "nvme_sanitize_nvm" 2 "nvme_sanitize_nvm" "February 2020" "libnvme Manual" +.SH NAME +nvme_sanitize_nvm \- Start a sanitize operation +.SH SYNOPSIS +.B "int" nvme_sanitize_nvm +.BI "(int " fd "," +.BI "enum nvme_sanitize_sanact " sanact "," +.BI "bool " ause "," +.BI "__u8 " owpass "," +.BI "bool " oipbp "," +.BI "bool " nodas "," +.BI "__u32 " ovrpat ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "sanact" 12 +Sanitize action, see \fIenum nvme_sanitize_sanact\fP +.IP "ause" 12 +Set to allow unrestriced sanitize exit +.IP "owpass" 12 +Overwrite pass count +.IP "oipbp" 12 +Set to overwrite invert pattern between passes +.IP "nodas" 12 +Set to not deallocate blocks after sanitizing +.IP "ovrpat" 12 +Overwrite pattern +.SH "DESCRIPTION" +A sanitize operation alters all user data in the NVM subsystem such that +recovery of any previous user data from any cache, the non-volatile media, +or any Controller Memory Buffer is not possible. + +The Sanitize command is used to start a sanitize operation or to recover +from a previously failed sanitize operation. The sanitize operation types +that may be supported are Block Erase, Crypto Erase, and Overwrite. All +sanitize operations are processed in the background, i.e., completion of the +sanitize command does not indicate completion of the sanitize operation. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_scan.2 b/doc/man/nvme_scan.2 new file mode 100644 index 0000000000..4ee2bace2f --- /dev/null +++ b/doc/man/nvme_scan.2 @@ -0,0 +1,6 @@ +.TH "nvme_scan" 2 "nvme_scan" "February 2020" "libnvme Manual" +.SH NAME +nvme_scan \- +.SH SYNOPSIS +.B "nvme_root_t" nvme_scan +.SH ARGUMENTS diff --git a/doc/man/nvme_scan_ctrl.2 b/doc/man/nvme_scan_ctrl.2 new file mode 100644 index 0000000000..260804b3a6 --- /dev/null +++ b/doc/man/nvme_scan_ctrl.2 @@ -0,0 +1,8 @@ +.TH "nvme_scan_ctrl" 2 "nvme_scan_ctrl" "February 2020" "libnvme Manual" +.SH NAME +nvme_scan_ctrl \- +.SH SYNOPSIS +.B "nvme_ctrl_t" nvme_scan_ctrl +.BI "(const char *" name ");" +.SH ARGUMENTS +.IP "name" 12 diff --git a/doc/man/nvme_scan_ctrl_namespace_paths.2 b/doc/man/nvme_scan_ctrl_namespace_paths.2 new file mode 100644 index 0000000000..78b95e3748 --- /dev/null +++ b/doc/man/nvme_scan_ctrl_namespace_paths.2 @@ -0,0 +1,11 @@ +.TH "nvme_scan_ctrl_namespace_paths" 2 "nvme_scan_ctrl_namespace_paths" "February 2020" "libnvme Manual" +.SH NAME +nvme_scan_ctrl_namespace_paths \- +.SH SYNOPSIS +.B "int" nvme_scan_ctrl_namespace_paths +.BI "(nvme_ctrl_t " c "," +.BI "struct dirent ***" namespaces ");" +.SH ARGUMENTS +.IP "c" 12 +-- undescribed -- +.IP "namespaces" 12 diff --git a/doc/man/nvme_scan_ctrl_namespaces.2 b/doc/man/nvme_scan_ctrl_namespaces.2 new file mode 100644 index 0000000000..b059979c6d --- /dev/null +++ b/doc/man/nvme_scan_ctrl_namespaces.2 @@ -0,0 +1,11 @@ +.TH "nvme_scan_ctrl_namespaces" 2 "nvme_scan_ctrl_namespaces" "February 2020" "libnvme Manual" +.SH NAME +nvme_scan_ctrl_namespaces \- +.SH SYNOPSIS +.B "int" nvme_scan_ctrl_namespaces +.BI "(nvme_ctrl_t " c "," +.BI "struct dirent ***" namespaces ");" +.SH ARGUMENTS +.IP "c" 12 +-- undescribed -- +.IP "namespaces" 12 diff --git a/doc/man/nvme_scan_filter.2 b/doc/man/nvme_scan_filter.2 new file mode 100644 index 0000000000..8e9e62e35c --- /dev/null +++ b/doc/man/nvme_scan_filter.2 @@ -0,0 +1,8 @@ +.TH "nvme_scan_filter" 2 "nvme_scan_filter" "February 2020" "libnvme Manual" +.SH NAME +nvme_scan_filter \- +.SH SYNOPSIS +.B "nvme_root_t" nvme_scan_filter +.BI "(nvme_scan_filter_t " f ");" +.SH ARGUMENTS +.IP "f" 12 diff --git a/doc/man/nvme_scan_subsystem_ctrls.2 b/doc/man/nvme_scan_subsystem_ctrls.2 new file mode 100644 index 0000000000..a596878804 --- /dev/null +++ b/doc/man/nvme_scan_subsystem_ctrls.2 @@ -0,0 +1,11 @@ +.TH "nvme_scan_subsystem_ctrls" 2 "nvme_scan_subsystem_ctrls" "February 2020" "libnvme Manual" +.SH NAME +nvme_scan_subsystem_ctrls \- +.SH SYNOPSIS +.B "int" nvme_scan_subsystem_ctrls +.BI "(nvme_subsystem_t " s "," +.BI "struct dirent ***" ctrls ");" +.SH ARGUMENTS +.IP "s" 12 +-- undescribed -- +.IP "ctrls" 12 diff --git a/doc/man/nvme_scan_subsystem_namespaces.2 b/doc/man/nvme_scan_subsystem_namespaces.2 new file mode 100644 index 0000000000..0e7a774565 --- /dev/null +++ b/doc/man/nvme_scan_subsystem_namespaces.2 @@ -0,0 +1,11 @@ +.TH "nvme_scan_subsystem_namespaces" 2 "nvme_scan_subsystem_namespaces" "February 2020" "libnvme Manual" +.SH NAME +nvme_scan_subsystem_namespaces \- +.SH SYNOPSIS +.B "int" nvme_scan_subsystem_namespaces +.BI "(nvme_subsystem_t " s "," +.BI "struct dirent ***" namespaces ");" +.SH ARGUMENTS +.IP "s" 12 +-- undescribed -- +.IP "namespaces" 12 diff --git a/doc/man/nvme_scan_subsystems.2 b/doc/man/nvme_scan_subsystems.2 new file mode 100644 index 0000000000..701660dddb --- /dev/null +++ b/doc/man/nvme_scan_subsystems.2 @@ -0,0 +1,8 @@ +.TH "nvme_scan_subsystems" 2 "nvme_scan_subsystems" "February 2020" "libnvme Manual" +.SH NAME +nvme_scan_subsystems \- +.SH SYNOPSIS +.B "int" nvme_scan_subsystems +.BI "(struct dirent ***" subsys ");" +.SH ARGUMENTS +.IP "subsys" 12 diff --git a/doc/man/nvme_security_receive.2 b/doc/man/nvme_security_receive.2 new file mode 100644 index 0000000000..8774e7a793 --- /dev/null +++ b/doc/man/nvme_security_receive.2 @@ -0,0 +1,39 @@ +.TH "nvme_security_receive" 2 "nvme_security_receive" "February 2020" "libnvme Manual" +.SH NAME +nvme_security_receive \- +.SH SYNOPSIS +.B "int" nvme_security_receive +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "__u8 " nssf "," +.BI "__u8 " spsp0 "," +.BI "__u8 " spsp1 "," +.BI "__u8 " secp "," +.BI "__u32 " al "," +.BI "__u32 " data_len "," +.BI "void *" data "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Namespace ID to issue security command on +.IP "nssf" 12 +NVMe Security Specific field +.IP "spsp0" 12 +Security Protocol Specific field +.IP "spsp1" 12 +Security Protocol Specific field +.IP "secp" 12 +Security Protocol +.IP "al" 12 +Protocol specific allocation length +.IP "data_len" 12 +Data length of the payload in bytes +.IP "data" 12 +Security data payload to send +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_security_send.2 b/doc/man/nvme_security_send.2 new file mode 100644 index 0000000000..8849171b7d --- /dev/null +++ b/doc/man/nvme_security_send.2 @@ -0,0 +1,48 @@ +.TH "nvme_security_send" 2 "nvme_security_send" "February 2020" "libnvme Manual" +.SH NAME +nvme_security_send \- +.SH SYNOPSIS +.B "int" nvme_security_send +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "__u8 " nssf "," +.BI "__u8 " spsp0 "," +.BI "__u8 " spsp1 "," +.BI "__u8 " secp "," +.BI "__u32 " tl "," +.BI "__u32 " data_len "," +.BI "void *" data "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Namespace ID to issue security command on +.IP "nssf" 12 +NVMe Security Specific field +.IP "spsp0" 12 +Security Protocol Specific field +.IP "spsp1" 12 +Security Protocol Specific field +.IP "secp" 12 +Security Protocol +.IP "tl" 12 +Protocol specific transfer length +.IP "data_len" 12 +Data length of the payload in bytes +.IP "data" 12 +Security data payload to send +.IP "result" 12 +The command completion result from CQE dword0 +.SH "DESCRIPTION" +The Security Send command is used to transfer security protocol data to the +controller. The data structure transferred to the controller as part of this +command contains security protocol specific commands to be performed by the +controller. The data structure transferred may also contain data or +parameters associated with the security protocol commands. + +The security data is protocol specific and is not defined by the NVMe +specification. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_set_attr.2 b/doc/man/nvme_set_attr.2 new file mode 100644 index 0000000000..677b801e60 --- /dev/null +++ b/doc/man/nvme_set_attr.2 @@ -0,0 +1,16 @@ +.TH "nvme_set_attr" 2 "nvme_set_attr" "February 2020" "libnvme Manual" +.SH NAME +nvme_set_attr \- +.SH SYNOPSIS +.B "int" nvme_set_attr +.BI "(const char *" dir "," +.BI "const char *" attr "," +.BI "const char *" value ");" +.SH ARGUMENTS +.IP "dir" 12 +-- undescribed -- +.IP "attr" 12 +-- undescribed -- +.IP "value" 12 +.SH "DESCRIPTION" +Return diff --git a/doc/man/nvme_set_features.2 b/doc/man/nvme_set_features.2 new file mode 100644 index 0000000000..267ee06bf1 --- /dev/null +++ b/doc/man/nvme_set_features.2 @@ -0,0 +1,42 @@ +.TH "nvme_set_features" 2 "nvme_set_features" "February 2020" "libnvme Manual" +.SH NAME +nvme_set_features \- Set a feature attribute +.SH SYNOPSIS +.B "int" nvme_set_features +.BI "(int " fd "," +.BI "__u8 " fid "," +.BI "__u32 " nsid "," +.BI "__u32 " cdw11 "," +.BI "__u32 " cdw12 "," +.BI "bool " save "," +.BI "__u8 " uuidx "," +.BI "__u32 " cdw15 "," +.BI "__u32 " data_len "," +.BI "void *" data "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "fid" 12 +Feature identifier +.IP "nsid" 12 +Namespace ID, if applicable +.IP "cdw11" 12 +Value to set the feature to +.IP "cdw12" 12 +Feature specific command dword12 field +.IP "save" 12 +Save value across power states +.IP "uuidx" 12 +UUID Index for differentiating vendor specific encoding +.IP "cdw15" 12 +-- undescribed -- +.IP "data_len" 12 +Length of feature data, if applicable, in bytes +.IP "data" 12 +User address of feature data, if applicable +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_set_features_arbitration.2 b/doc/man/nvme_set_features_arbitration.2 new file mode 100644 index 0000000000..1a688f3e47 --- /dev/null +++ b/doc/man/nvme_set_features_arbitration.2 @@ -0,0 +1,30 @@ +.TH "nvme_set_features_arbitration" 2 "nvme_set_features_arbitration" "February 2020" "libnvme Manual" +.SH NAME +nvme_set_features_arbitration \- +.SH SYNOPSIS +.B "int" nvme_set_features_arbitration +.BI "(int " fd "," +.BI "__u8 " ab "," +.BI "__u8 " lpw "," +.BI "__u8 " mpw "," +.BI "__u8 " hpw "," +.BI "bool " save "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "ab" 12 +-- undescribed -- +.IP "lpw" 12 +-- undescribed -- +.IP "mpw" 12 +-- undescribed -- +.IP "hpw" 12 +-- undescribed -- +.IP "save" 12 +Save value across power states +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_set_features_async_event.2 b/doc/man/nvme_set_features_async_event.2 new file mode 100644 index 0000000000..98cc6a8a41 --- /dev/null +++ b/doc/man/nvme_set_features_async_event.2 @@ -0,0 +1,21 @@ +.TH "nvme_set_features_async_event" 2 "nvme_set_features_async_event" "February 2020" "libnvme Manual" +.SH NAME +nvme_set_features_async_event \- +.SH SYNOPSIS +.B "int" nvme_set_features_async_event +.BI "(int " fd "," +.BI "__u32 " events "," +.BI "bool " save "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "events" 12 +-- undescribed -- +.IP "save" 12 +Save value across power states +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_set_features_auto_pst.2 b/doc/man/nvme_set_features_auto_pst.2 new file mode 100644 index 0000000000..40406f6f3b --- /dev/null +++ b/doc/man/nvme_set_features_auto_pst.2 @@ -0,0 +1,24 @@ +.TH "nvme_set_features_auto_pst" 2 "nvme_set_features_auto_pst" "February 2020" "libnvme Manual" +.SH NAME +nvme_set_features_auto_pst \- +.SH SYNOPSIS +.B "int" nvme_set_features_auto_pst +.BI "(int " fd "," +.BI "bool " apste "," +.BI "bool " save "," +.BI "struct nvme_feat_auto_pst *" apst "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "apste" 12 +-- undescribed -- +.IP "save" 12 +Save value across power states +.IP "apst" 12 +-- undescribed -- +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_set_features_endurance_evt_cfg.2 b/doc/man/nvme_set_features_endurance_evt_cfg.2 new file mode 100644 index 0000000000..4b56a97e06 --- /dev/null +++ b/doc/man/nvme_set_features_endurance_evt_cfg.2 @@ -0,0 +1,24 @@ +.TH "nvme_set_features_endurance_evt_cfg" 2 "nvme_set_features_endurance_evt_cfg" "February 2020" "libnvme Manual" +.SH NAME +nvme_set_features_endurance_evt_cfg \- +.SH SYNOPSIS +.B "int" nvme_set_features_endurance_evt_cfg +.BI "(int " fd "," +.BI "__u16 " endgid "," +.BI "__u8 " egwarn "," +.BI "bool " save "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "endgid" 12 +-- undescribed -- +.IP "egwarn" 12 +Flags to enable warning, see \fIenum nvme_eg_critical_warning_flags\fP +.IP "save" 12 +Save value across power states +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_set_features_err_recovery.2 b/doc/man/nvme_set_features_err_recovery.2 new file mode 100644 index 0000000000..5da3dc90b3 --- /dev/null +++ b/doc/man/nvme_set_features_err_recovery.2 @@ -0,0 +1,27 @@ +.TH "nvme_set_features_err_recovery" 2 "nvme_set_features_err_recovery" "February 2020" "libnvme Manual" +.SH NAME +nvme_set_features_err_recovery \- +.SH SYNOPSIS +.B "int" nvme_set_features_err_recovery +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "__u16 " tler "," +.BI "bool " dulbe "," +.BI "bool " save "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +-- undescribed -- +.IP "tler" 12 +-- undescribed -- +.IP "dulbe" 12 +-- undescribed -- +.IP "save" 12 +Save value across power states +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_set_features_hctm.2 b/doc/man/nvme_set_features_hctm.2 new file mode 100644 index 0000000000..a02f42f0b5 --- /dev/null +++ b/doc/man/nvme_set_features_hctm.2 @@ -0,0 +1,24 @@ +.TH "nvme_set_features_hctm" 2 "nvme_set_features_hctm" "February 2020" "libnvme Manual" +.SH NAME +nvme_set_features_hctm \- +.SH SYNOPSIS +.B "int" nvme_set_features_hctm +.BI "(int " fd "," +.BI "__u16 " tmt2 "," +.BI "__u16 " tmt1 "," +.BI "bool " save "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "tmt2" 12 +-- undescribed -- +.IP "tmt1" 12 +-- undescribed -- +.IP "save" 12 +Save value across power states +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_set_features_host_behavior.2 b/doc/man/nvme_set_features_host_behavior.2 new file mode 100644 index 0000000000..27534b5311 --- /dev/null +++ b/doc/man/nvme_set_features_host_behavior.2 @@ -0,0 +1,18 @@ +.TH "nvme_set_features_host_behavior" 2 "nvme_set_features_host_behavior" "February 2020" "libnvme Manual" +.SH NAME +nvme_set_features_host_behavior \- +.SH SYNOPSIS +.B "int" nvme_set_features_host_behavior +.BI "(int " fd "," +.BI "bool " save "," +.BI "struct nvme_feat_host_behavior *" data ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "save" 12 +Save value across power states +.IP "data" 12 +-- undescribed -- +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_set_features_host_id.2 b/doc/man/nvme_set_features_host_id.2 new file mode 100644 index 0000000000..b9ec66377e --- /dev/null +++ b/doc/man/nvme_set_features_host_id.2 @@ -0,0 +1,21 @@ +.TH "nvme_set_features_host_id" 2 "nvme_set_features_host_id" "February 2020" "libnvme Manual" +.SH NAME +nvme_set_features_host_id \- +.SH SYNOPSIS +.B "int" nvme_set_features_host_id +.BI "(int " fd "," +.BI "bool " exhid "," +.BI "bool " save "," +.BI "__u8 *" hostid ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "exhid" 12 +-- undescribed -- +.IP "save" 12 +Save value across power states +.IP "hostid" 12 +-- undescribed -- +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_set_features_irq_coalesce.2 b/doc/man/nvme_set_features_irq_coalesce.2 new file mode 100644 index 0000000000..89f87f54d5 --- /dev/null +++ b/doc/man/nvme_set_features_irq_coalesce.2 @@ -0,0 +1,24 @@ +.TH "nvme_set_features_irq_coalesce" 2 "nvme_set_features_irq_coalesce" "February 2020" "libnvme Manual" +.SH NAME +nvme_set_features_irq_coalesce \- +.SH SYNOPSIS +.B "int" nvme_set_features_irq_coalesce +.BI "(int " fd "," +.BI "__u8 " thr "," +.BI "__u8 " time "," +.BI "bool " save "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "thr" 12 +-- undescribed -- +.IP "time" 12 +-- undescribed -- +.IP "save" 12 +Save value across power states +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_set_features_irq_config.2 b/doc/man/nvme_set_features_irq_config.2 new file mode 100644 index 0000000000..a5fa413ef2 --- /dev/null +++ b/doc/man/nvme_set_features_irq_config.2 @@ -0,0 +1,24 @@ +.TH "nvme_set_features_irq_config" 2 "nvme_set_features_irq_config" "February 2020" "libnvme Manual" +.SH NAME +nvme_set_features_irq_config \- +.SH SYNOPSIS +.B "int" nvme_set_features_irq_config +.BI "(int " fd "," +.BI "__u16 " iv "," +.BI "bool " cd "," +.BI "bool " save "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "iv" 12 +-- undescribed -- +.IP "cd" 12 +-- undescribed -- +.IP "save" 12 +Save value across power states +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_set_features_lba_range.2 b/doc/man/nvme_set_features_lba_range.2 new file mode 100644 index 0000000000..c94f4720ad --- /dev/null +++ b/doc/man/nvme_set_features_lba_range.2 @@ -0,0 +1,27 @@ +.TH "nvme_set_features_lba_range" 2 "nvme_set_features_lba_range" "February 2020" "libnvme Manual" +.SH NAME +nvme_set_features_lba_range \- +.SH SYNOPSIS +.B "int" nvme_set_features_lba_range +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "__u32 " nr_ranges "," +.BI "bool " save "," +.BI "struct nvme_lba_range_type *" data "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +-- undescribed -- +.IP "nr_ranges" 12 +-- undescribed -- +.IP "save" 12 +Save value across power states +.IP "data" 12 +-- undescribed -- +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_set_features_lba_sts_interval.2 b/doc/man/nvme_set_features_lba_sts_interval.2 new file mode 100644 index 0000000000..03f1d35c9a --- /dev/null +++ b/doc/man/nvme_set_features_lba_sts_interval.2 @@ -0,0 +1,24 @@ +.TH "nvme_set_features_lba_sts_interval" 2 "nvme_set_features_lba_sts_interval" "February 2020" "libnvme Manual" +.SH NAME +nvme_set_features_lba_sts_interval \- +.SH SYNOPSIS +.B "int" nvme_set_features_lba_sts_interval +.BI "(int " fd "," +.BI "__u16 " lsiri "," +.BI "__u16 " lsipi "," +.BI "bool " save "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "lsiri" 12 +-- undescribed -- +.IP "lsipi" 12 +-- undescribed -- +.IP "save" 12 +Save value across power states +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_set_features_nopsc.2 b/doc/man/nvme_set_features_nopsc.2 new file mode 100644 index 0000000000..25723c1d52 --- /dev/null +++ b/doc/man/nvme_set_features_nopsc.2 @@ -0,0 +1,18 @@ +.TH "nvme_set_features_nopsc" 2 "nvme_set_features_nopsc" "February 2020" "libnvme Manual" +.SH NAME +nvme_set_features_nopsc \- +.SH SYNOPSIS +.B "int" nvme_set_features_nopsc +.BI "(int " fd "," +.BI "bool " noppme "," +.BI "bool " save "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +-- undescribed -- +.IP "noppme" 12 +-- undescribed -- +.IP "save" 12 +-- undescribed -- +.IP "result" 12 +-- undescribed -- diff --git a/doc/man/nvme_set_features_plm_config.2 b/doc/man/nvme_set_features_plm_config.2 new file mode 100644 index 0000000000..8e0c7d1f19 --- /dev/null +++ b/doc/man/nvme_set_features_plm_config.2 @@ -0,0 +1,27 @@ +.TH "nvme_set_features_plm_config" 2 "nvme_set_features_plm_config" "February 2020" "libnvme Manual" +.SH NAME +nvme_set_features_plm_config \- +.SH SYNOPSIS +.B "int" nvme_set_features_plm_config +.BI "(int " fd "," +.BI "bool " enable "," +.BI "__u16 " nvmsetid "," +.BI "bool " save "," +.BI "struct nvme_plm_config *" data "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "enable" 12 +-- undescribed -- +.IP "nvmsetid" 12 +-- undescribed -- +.IP "save" 12 +Save value across power states +.IP "data" 12 +-- undescribed -- +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_set_features_plm_window.2 b/doc/man/nvme_set_features_plm_window.2 new file mode 100644 index 0000000000..f329229906 --- /dev/null +++ b/doc/man/nvme_set_features_plm_window.2 @@ -0,0 +1,24 @@ +.TH "nvme_set_features_plm_window" 2 "nvme_set_features_plm_window" "February 2020" "libnvme Manual" +.SH NAME +nvme_set_features_plm_window \- +.SH SYNOPSIS +.B "int" nvme_set_features_plm_window +.BI "(int " fd "," +.BI "enum nvme_feat_plm_window_select " sel "," +.BI "__u16 " nvmsetid "," +.BI "bool " save "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "sel" 12 +-- undescribed -- +.IP "nvmsetid" 12 +-- undescribed -- +.IP "save" 12 +Save value across power states +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_set_features_power_mgmt.2 b/doc/man/nvme_set_features_power_mgmt.2 new file mode 100644 index 0000000000..f63c666422 --- /dev/null +++ b/doc/man/nvme_set_features_power_mgmt.2 @@ -0,0 +1,24 @@ +.TH "nvme_set_features_power_mgmt" 2 "nvme_set_features_power_mgmt" "February 2020" "libnvme Manual" +.SH NAME +nvme_set_features_power_mgmt \- +.SH SYNOPSIS +.B "int" nvme_set_features_power_mgmt +.BI "(int " fd "," +.BI "__u8 " ps "," +.BI "__u8 " wh "," +.BI "bool " save "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "ps" 12 +-- undescribed -- +.IP "wh" 12 +-- undescribed -- +.IP "save" 12 +Save value across power states +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_set_features_resv_mask.2 b/doc/man/nvme_set_features_resv_mask.2 new file mode 100644 index 0000000000..3b3842cbcb --- /dev/null +++ b/doc/man/nvme_set_features_resv_mask.2 @@ -0,0 +1,21 @@ +.TH "nvme_set_features_resv_mask" 2 "nvme_set_features_resv_mask" "February 2020" "libnvme Manual" +.SH NAME +nvme_set_features_resv_mask \- +.SH SYNOPSIS +.B "int" nvme_set_features_resv_mask +.BI "(int " fd "," +.BI "__u32 " mask "," +.BI "bool " save "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "mask" 12 +-- undescribed -- +.IP "save" 12 +Save value across power states +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_set_features_resv_persist.2 b/doc/man/nvme_set_features_resv_persist.2 new file mode 100644 index 0000000000..5a1e0e9996 --- /dev/null +++ b/doc/man/nvme_set_features_resv_persist.2 @@ -0,0 +1,21 @@ +.TH "nvme_set_features_resv_persist" 2 "nvme_set_features_resv_persist" "February 2020" "libnvme Manual" +.SH NAME +nvme_set_features_resv_persist \- +.SH SYNOPSIS +.B "int" nvme_set_features_resv_persist +.BI "(int " fd "," +.BI "bool " ptpl "," +.BI "bool " save "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "ptpl" 12 +-- undescribed -- +.IP "save" 12 +Save value across power states +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_set_features_rrl.2 b/doc/man/nvme_set_features_rrl.2 new file mode 100644 index 0000000000..997efaa0ef --- /dev/null +++ b/doc/man/nvme_set_features_rrl.2 @@ -0,0 +1,24 @@ +.TH "nvme_set_features_rrl" 2 "nvme_set_features_rrl" "February 2020" "libnvme Manual" +.SH NAME +nvme_set_features_rrl \- +.SH SYNOPSIS +.B "int" nvme_set_features_rrl +.BI "(int " fd "," +.BI "__u8 " rrl "," +.BI "__u16 " nvmsetid "," +.BI "bool " save "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "rrl" 12 +-- undescribed -- +.IP "nvmsetid" 12 +-- undescribed -- +.IP "save" 12 +Save value across power states +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_set_features_sanitize.2 b/doc/man/nvme_set_features_sanitize.2 new file mode 100644 index 0000000000..380408c27a --- /dev/null +++ b/doc/man/nvme_set_features_sanitize.2 @@ -0,0 +1,21 @@ +.TH "nvme_set_features_sanitize" 2 "nvme_set_features_sanitize" "February 2020" "libnvme Manual" +.SH NAME +nvme_set_features_sanitize \- +.SH SYNOPSIS +.B "int" nvme_set_features_sanitize +.BI "(int " fd "," +.BI "bool " nodrm "," +.BI "bool " save "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nodrm" 12 +-- undescribed -- +.IP "save" 12 +Save value across power states +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_set_features_sw_progress.2 b/doc/man/nvme_set_features_sw_progress.2 new file mode 100644 index 0000000000..3a4ba7b430 --- /dev/null +++ b/doc/man/nvme_set_features_sw_progress.2 @@ -0,0 +1,21 @@ +.TH "nvme_set_features_sw_progress" 2 "nvme_set_features_sw_progress" "February 2020" "libnvme Manual" +.SH NAME +nvme_set_features_sw_progress \- +.SH SYNOPSIS +.B "int" nvme_set_features_sw_progress +.BI "(int " fd "," +.BI "__u8 " pbslc "," +.BI "bool " save "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "pbslc" 12 +-- undescribed -- +.IP "save" 12 +Save value across power states +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_set_features_temp_thresh.2 b/doc/man/nvme_set_features_temp_thresh.2 new file mode 100644 index 0000000000..cec95565a7 --- /dev/null +++ b/doc/man/nvme_set_features_temp_thresh.2 @@ -0,0 +1,27 @@ +.TH "nvme_set_features_temp_thresh" 2 "nvme_set_features_temp_thresh" "February 2020" "libnvme Manual" +.SH NAME +nvme_set_features_temp_thresh \- +.SH SYNOPSIS +.B "int" nvme_set_features_temp_thresh +.BI "(int " fd "," +.BI "__u16 " tmpth "," +.BI "__u8 " tmpsel "," +.BI "enum nvme_feat_tmpthresh_thsel " thsel "," +.BI "bool " save "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "tmpth" 12 +-- undescribed -- +.IP "tmpsel" 12 +-- undescribed -- +.IP "thsel" 12 +-- undescribed -- +.IP "save" 12 +Save value across power states +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_set_features_timestamp.2 b/doc/man/nvme_set_features_timestamp.2 new file mode 100644 index 0000000000..0abf98cfae --- /dev/null +++ b/doc/man/nvme_set_features_timestamp.2 @@ -0,0 +1,18 @@ +.TH "nvme_set_features_timestamp" 2 "nvme_set_features_timestamp" "February 2020" "libnvme Manual" +.SH NAME +nvme_set_features_timestamp \- +.SH SYNOPSIS +.B "int" nvme_set_features_timestamp +.BI "(int " fd "," +.BI "bool " save "," +.BI "__u64 " timestamp ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "save" 12 +Save value across power states +.IP "timestamp" 12 +The current timestamp value to assign to this this feature +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_set_features_volatile_wc.2 b/doc/man/nvme_set_features_volatile_wc.2 new file mode 100644 index 0000000000..34425fb993 --- /dev/null +++ b/doc/man/nvme_set_features_volatile_wc.2 @@ -0,0 +1,21 @@ +.TH "nvme_set_features_volatile_wc" 2 "nvme_set_features_volatile_wc" "February 2020" "libnvme Manual" +.SH NAME +nvme_set_features_volatile_wc \- +.SH SYNOPSIS +.B "int" nvme_set_features_volatile_wc +.BI "(int " fd "," +.BI "bool " wce "," +.BI "bool " save "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "wce" 12 +-- undescribed -- +.IP "save" 12 +Save value across power states +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_set_features_write_atomic.2 b/doc/man/nvme_set_features_write_atomic.2 new file mode 100644 index 0000000000..0b1ffad110 --- /dev/null +++ b/doc/man/nvme_set_features_write_atomic.2 @@ -0,0 +1,21 @@ +.TH "nvme_set_features_write_atomic" 2 "nvme_set_features_write_atomic" "February 2020" "libnvme Manual" +.SH NAME +nvme_set_features_write_atomic \- +.SH SYNOPSIS +.B "int" nvme_set_features_write_atomic +.BI "(int " fd "," +.BI "bool " dn "," +.BI "bool " save "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "dn" 12 +-- undescribed -- +.IP "save" 12 +Save value across power states +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_set_features_write_protect.2 b/doc/man/nvme_set_features_write_protect.2 new file mode 100644 index 0000000000..b9be1290e6 --- /dev/null +++ b/doc/man/nvme_set_features_write_protect.2 @@ -0,0 +1,21 @@ +.TH "nvme_set_features_write_protect" 2 "nvme_set_features_write_protect" "February 2020" "libnvme Manual" +.SH NAME +nvme_set_features_write_protect \- +.SH SYNOPSIS +.B "int" nvme_set_features_write_protect +.BI "(int " fd "," +.BI "enum nvme_feat_nswpcfg_state " state "," +.BI "bool " save "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "state" 12 +-- undescribed -- +.IP "save" 12 +Save value across power states +.IP "result" 12 +The command completion result from CQE dword0 +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_set_property.2 b/doc/man/nvme_set_property.2 new file mode 100644 index 0000000000..307fc104c9 --- /dev/null +++ b/doc/man/nvme_set_property.2 @@ -0,0 +1,21 @@ +.TH "nvme_set_property" 2 "nvme_set_property" "February 2020" "libnvme Manual" +.SH NAME +nvme_set_property \- Set controller property +.SH SYNOPSIS +.B "int" nvme_set_property +.BI "(int " fd "," +.BI "int " offset "," +.BI "__u64 " value ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "offset" 12 +Property offset from the base to set +.IP "value" 12 +The value to set the property +.SH "DESCRIPTION" +This is an NVMe-over-Fabrics specific command, not applicable to PCIe. These +properties align to the PCI MMIO controller registers. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_setup_ctrl_list.2 b/doc/man/nvme_setup_ctrl_list.2 new file mode 100644 index 0000000000..53ff19555d --- /dev/null +++ b/doc/man/nvme_setup_ctrl_list.2 @@ -0,0 +1,15 @@ +.TH "nvme_setup_ctrl_list" 2 "nvme_setup_ctrl_list" "February 2020" "libnvme Manual" +.SH NAME +nvme_setup_ctrl_list \- +.SH SYNOPSIS +.B "void" nvme_setup_ctrl_list +.BI "(struct nvme_ctrl_list *" cntlist "," +.BI "__u16 " num_ctrls "," +.BI "__u16 *" ctrlist ");" +.SH ARGUMENTS +.IP "cntlist" 12 +-- undescribed -- +.IP "num_ctrls" 12 +-- undescribed -- +.IP "ctrlist" 12 +-- undescribed -- diff --git a/doc/man/nvme_setup_dsm_range.2 b/doc/man/nvme_setup_dsm_range.2 new file mode 100644 index 0000000000..9f7b9dc527 --- /dev/null +++ b/doc/man/nvme_setup_dsm_range.2 @@ -0,0 +1,26 @@ +.TH "nvme_setup_dsm_range" 2 "nvme_setup_dsm_range" "February 2020" "libnvme Manual" +.SH NAME +nvme_setup_dsm_range \- Constructs a data set range structure +.SH SYNOPSIS +.B "void" nvme_setup_dsm_range +.BI "(struct nvme_dsm_range *" dsm "," +.BI "__u32 *" ctx_attrs "," +.BI "__u32 *" llbas "," +.BI "__u64 *" slbas "," +.BI "__u16 " nr_ranges ");" +.SH ARGUMENTS +.IP "dsm" 12 +DSM range array +.IP "ctx_attrs" 12 +Array of context attributes +.IP "llbas" 12 +Array of length in logical blocks +.IP "slbas" 12 +Array of starting logical blocks +.IP "nr_ranges" 12 +The size of the dsm arrays +.SH "DESCRIPTION" +Each array must be the same size of size 'nr_ranges'. +.SH "RETURN" +The nvme command status if a response was received or -errno +otherwise. diff --git a/doc/man/nvme_setup_id_ns.2 b/doc/man/nvme_setup_id_ns.2 new file mode 100644 index 0000000000..ced1fa84da --- /dev/null +++ b/doc/man/nvme_setup_id_ns.2 @@ -0,0 +1,30 @@ +.TH "nvme_setup_id_ns" 2 "nvme_setup_id_ns" "February 2020" "libnvme Manual" +.SH NAME +nvme_setup_id_ns \- +.SH SYNOPSIS +.B "void" nvme_setup_id_ns +.BI "(struct nvme_id_ns *" ns "," +.BI "__u64 " nsze "," +.BI "__u64 " ncap "," +.BI "__u8 " flbas "," +.BI "__u8 " dps "," +.BI "__u8 " nmic "," +.BI "__u32 " anagrpid "," +.BI "__u16 " nvmsetid ");" +.SH ARGUMENTS +.IP "ns" 12 +-- undescribed -- +.IP "nsze" 12 +-- undescribed -- +.IP "ncap" 12 +-- undescribed -- +.IP "flbas" 12 +-- undescribed -- +.IP "dps" 12 +-- undescribed -- +.IP "nmic" 12 +-- undescribed -- +.IP "anagrpid" 12 +-- undescribed -- +.IP "nvmsetid" 12 +-- undescribed -- diff --git a/doc/man/nvme_status_to_errno.2 b/doc/man/nvme_status_to_errno.2 new file mode 100644 index 0000000000..aca2e93022 --- /dev/null +++ b/doc/man/nvme_status_to_errno.2 @@ -0,0 +1,16 @@ +.TH "nvme_status_to_errno" 2 "nvme_status_to_errno" "February 2020" "libnvme Manual" +.SH NAME +nvme_status_to_errno \- Converts nvme return status to errno +.SH SYNOPSIS +.B "__u8" nvme_status_to_errno +.BI "(int " status "," +.BI "bool " fabrics ");" +.SH ARGUMENTS +.IP "status" 12 +Return status from an nvme passthrough commmand +.IP "fabrics" 12 +true if given status is for fabrics +.SH "DESCRIPTION" +If status < 0, errno is already set. +.SH "RETURN" +Appropriate errno for the given nvme status diff --git a/doc/man/nvme_submit_admin_passthru.2 b/doc/man/nvme_submit_admin_passthru.2 new file mode 100644 index 0000000000..468540485c --- /dev/null +++ b/doc/man/nvme_submit_admin_passthru.2 @@ -0,0 +1,20 @@ +.TH "nvme_submit_admin_passthru" 2 "nvme_submit_admin_passthru" "February 2020" "libnvme Manual" +.SH NAME +nvme_submit_admin_passthru \- Submit an nvme passthrough admin command +.SH SYNOPSIS +.B "int" nvme_submit_admin_passthru +.BI "(int " fd "," +.BI "struct nvme_passthru_cmd *" cmd "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "cmd" 12 +The nvme admin command to send +.IP "result" 12 +Optional field to return the result from the CQE DW0 +.SH "DESCRIPTION" +Uses NVME_IOCTL_ADMIN_CMD for the ioctl request. +.SH "RETURN" +The nvme command status if a response was received or -1 +with errno set otherwise. diff --git a/doc/man/nvme_submit_admin_passthru64.2 b/doc/man/nvme_submit_admin_passthru64.2 new file mode 100644 index 0000000000..5763bfde14 --- /dev/null +++ b/doc/man/nvme_submit_admin_passthru64.2 @@ -0,0 +1,20 @@ +.TH "nvme_submit_admin_passthru64" 2 "nvme_submit_admin_passthru64" "February 2020" "libnvme Manual" +.SH NAME +nvme_submit_admin_passthru64 \- Submit a 64-bit nvme passthrough admin command +.SH SYNOPSIS +.B "int" nvme_submit_admin_passthru64 +.BI "(int " fd "," +.BI "struct nvme_passthru_cmd64 *" cmd "," +.BI "__u64 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "cmd" 12 +The nvme admin command to send +.IP "result" 12 +Optional field to return the result from the CQE DW0-1 +.SH "DESCRIPTION" +Uses NVME_IOCTL_ADMIN64_CMD for the ioctl request. +.SH "RETURN" +The nvme command status if a response was received or -1 +with errno set otherwise. diff --git a/doc/man/nvme_submit_io_passthru.2 b/doc/man/nvme_submit_io_passthru.2 new file mode 100644 index 0000000000..7c425b09c6 --- /dev/null +++ b/doc/man/nvme_submit_io_passthru.2 @@ -0,0 +1,20 @@ +.TH "nvme_submit_io_passthru" 2 "nvme_submit_io_passthru" "February 2020" "libnvme Manual" +.SH NAME +nvme_submit_io_passthru \- Submit an nvme passthrough command +.SH SYNOPSIS +.B "int" nvme_submit_io_passthru +.BI "(int " fd "," +.BI "struct nvme_passthru_cmd *" cmd "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "cmd" 12 +The nvme io command to send +.IP "result" 12 +Optional field to return the result from the CQE DW0 +.SH "DESCRIPTION" +Uses NVME_IOCTL_IO_CMD for the ioctl request. +.SH "RETURN" +The nvme command status if a response was received or -1 +with errno set otherwise. diff --git a/doc/man/nvme_submit_io_passthru64.2 b/doc/man/nvme_submit_io_passthru64.2 new file mode 100644 index 0000000000..9c40820121 --- /dev/null +++ b/doc/man/nvme_submit_io_passthru64.2 @@ -0,0 +1,20 @@ +.TH "nvme_submit_io_passthru64" 2 "nvme_submit_io_passthru64" "February 2020" "libnvme Manual" +.SH NAME +nvme_submit_io_passthru64 \- Submit a 64-bit nvme passthrough command +.SH SYNOPSIS +.B "int" nvme_submit_io_passthru64 +.BI "(int " fd "," +.BI "struct nvme_passthru_cmd64 *" cmd "," +.BI "__u64 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "cmd" 12 +The nvme io command to send +.IP "result" 12 +Optional field to return the result from the CQE DW0-1 +.SH "DESCRIPTION" +Uses NVME_IOCTL_IO64_CMD for the ioctl request. +.SH "RETURN" +The nvme command status if a response was received or -1 +with errno set otherwise. diff --git a/doc/man/nvme_subsys_filter.2 b/doc/man/nvme_subsys_filter.2 new file mode 100644 index 0000000000..272cd63722 --- /dev/null +++ b/doc/man/nvme_subsys_filter.2 @@ -0,0 +1,8 @@ +.TH "nvme_subsys_filter" 2 "nvme_subsys_filter" "February 2020" "libnvme Manual" +.SH NAME +nvme_subsys_filter \- +.SH SYNOPSIS +.B "int" nvme_subsys_filter +.BI "(const struct dirent *" d ");" +.SH ARGUMENTS +.IP "d" 12 diff --git a/doc/man/nvme_subsystem_first_ctrl.2 b/doc/man/nvme_subsystem_first_ctrl.2 new file mode 100644 index 0000000000..fd7f2b99f9 --- /dev/null +++ b/doc/man/nvme_subsystem_first_ctrl.2 @@ -0,0 +1,8 @@ +.TH "nvme_subsystem_first_ctrl" 2 "nvme_subsystem_first_ctrl" "February 2020" "libnvme Manual" +.SH NAME +nvme_subsystem_first_ctrl \- +.SH SYNOPSIS +.B "nvme_ctrl_t" nvme_subsystem_first_ctrl +.BI "(nvme_subsystem_t " s ");" +.SH ARGUMENTS +.IP "s" 12 diff --git a/doc/man/nvme_subsystem_first_ns.2 b/doc/man/nvme_subsystem_first_ns.2 new file mode 100644 index 0000000000..1045846e3b --- /dev/null +++ b/doc/man/nvme_subsystem_first_ns.2 @@ -0,0 +1,8 @@ +.TH "nvme_subsystem_first_ns" 2 "nvme_subsystem_first_ns" "February 2020" "libnvme Manual" +.SH NAME +nvme_subsystem_first_ns \- +.SH SYNOPSIS +.B "nvme_ns_t" nvme_subsystem_first_ns +.BI "(nvme_subsystem_t " s ");" +.SH ARGUMENTS +.IP "s" 12 diff --git a/doc/man/nvme_subsystem_for_each_ctrl.2 b/doc/man/nvme_subsystem_for_each_ctrl.2 new file mode 100644 index 0000000000..9a829004e4 --- /dev/null +++ b/doc/man/nvme_subsystem_for_each_ctrl.2 @@ -0,0 +1,12 @@ +.TH "nvme_subsystem_for_each_ctrl" 2 "nvme_subsystem_for_each_ctrl" "February 2020" "libnvme Manual" +.SH NAME +nvme_subsystem_for_each_ctrl \- +.SH SYNOPSIS +.B "nvme_subsystem_for_each_ctrl +.BI "(" s "," +.BI "" c ");" +.SH ARGUMENTS +.IP "s" 12 +-- undescribed -- +.IP "c" 12 +-- undescribed -- diff --git a/doc/man/nvme_subsystem_for_each_ctrl_safe.2 b/doc/man/nvme_subsystem_for_each_ctrl_safe.2 new file mode 100644 index 0000000000..44ea0d5a28 --- /dev/null +++ b/doc/man/nvme_subsystem_for_each_ctrl_safe.2 @@ -0,0 +1,15 @@ +.TH "nvme_subsystem_for_each_ctrl_safe" 2 "nvme_subsystem_for_each_ctrl_safe" "February 2020" "libnvme Manual" +.SH NAME +nvme_subsystem_for_each_ctrl_safe \- +.SH SYNOPSIS +.B "nvme_subsystem_for_each_ctrl_safe +.BI "(" s "," +.BI "" c "," +.BI "" _c ");" +.SH ARGUMENTS +.IP "s" 12 +-- undescribed -- +.IP "c" 12 +-- undescribed -- +.IP "_c" 12 +-- undescribed -- diff --git a/doc/man/nvme_subsystem_for_each_ns.2 b/doc/man/nvme_subsystem_for_each_ns.2 new file mode 100644 index 0000000000..6a0be80cdc --- /dev/null +++ b/doc/man/nvme_subsystem_for_each_ns.2 @@ -0,0 +1,12 @@ +.TH "nvme_subsystem_for_each_ns" 2 "nvme_subsystem_for_each_ns" "February 2020" "libnvme Manual" +.SH NAME +nvme_subsystem_for_each_ns \- +.SH SYNOPSIS +.B "nvme_subsystem_for_each_ns +.BI "(" s "," +.BI "" n ");" +.SH ARGUMENTS +.IP "s" 12 +-- undescribed -- +.IP "n" 12 +-- undescribed -- diff --git a/doc/man/nvme_subsystem_for_each_ns_safe.2 b/doc/man/nvme_subsystem_for_each_ns_safe.2 new file mode 100644 index 0000000000..e1cc8ff3ec --- /dev/null +++ b/doc/man/nvme_subsystem_for_each_ns_safe.2 @@ -0,0 +1,15 @@ +.TH "nvme_subsystem_for_each_ns_safe" 2 "nvme_subsystem_for_each_ns_safe" "February 2020" "libnvme Manual" +.SH NAME +nvme_subsystem_for_each_ns_safe \- +.SH SYNOPSIS +.B "nvme_subsystem_for_each_ns_safe +.BI "(" s "," +.BI "" n "," +.BI "" _n ");" +.SH ARGUMENTS +.IP "s" 12 +-- undescribed -- +.IP "n" 12 +-- undescribed -- +.IP "_n" 12 +-- undescribed -- diff --git a/doc/man/nvme_subsystem_get_name.2 b/doc/man/nvme_subsystem_get_name.2 new file mode 100644 index 0000000000..33cadbb39f --- /dev/null +++ b/doc/man/nvme_subsystem_get_name.2 @@ -0,0 +1,8 @@ +.TH "nvme_subsystem_get_name" 2 "nvme_subsystem_get_name" "February 2020" "libnvme Manual" +.SH NAME +nvme_subsystem_get_name \- +.SH SYNOPSIS +.B "const char *" nvme_subsystem_get_name +.BI "(nvme_subsystem_t " s ");" +.SH ARGUMENTS +.IP "s" 12 diff --git a/doc/man/nvme_subsystem_get_nqn.2 b/doc/man/nvme_subsystem_get_nqn.2 new file mode 100644 index 0000000000..43e2d7b6f4 --- /dev/null +++ b/doc/man/nvme_subsystem_get_nqn.2 @@ -0,0 +1,8 @@ +.TH "nvme_subsystem_get_nqn" 2 "nvme_subsystem_get_nqn" "February 2020" "libnvme Manual" +.SH NAME +nvme_subsystem_get_nqn \- +.SH SYNOPSIS +.B "const char *" nvme_subsystem_get_nqn +.BI "(nvme_subsystem_t " s ");" +.SH ARGUMENTS +.IP "s" 12 diff --git a/doc/man/nvme_subsystem_get_sysfs_dir.2 b/doc/man/nvme_subsystem_get_sysfs_dir.2 new file mode 100644 index 0000000000..9ed210401c --- /dev/null +++ b/doc/man/nvme_subsystem_get_sysfs_dir.2 @@ -0,0 +1,8 @@ +.TH "nvme_subsystem_get_sysfs_dir" 2 "nvme_subsystem_get_sysfs_dir" "February 2020" "libnvme Manual" +.SH NAME +nvme_subsystem_get_sysfs_dir \- +.SH SYNOPSIS +.B "const char *" nvme_subsystem_get_sysfs_dir +.BI "(nvme_subsystem_t " s ");" +.SH ARGUMENTS +.IP "s" 12 diff --git a/doc/man/nvme_subsystem_next_ctrl.2 b/doc/man/nvme_subsystem_next_ctrl.2 new file mode 100644 index 0000000000..fce9cf3cb8 --- /dev/null +++ b/doc/man/nvme_subsystem_next_ctrl.2 @@ -0,0 +1,11 @@ +.TH "nvme_subsystem_next_ctrl" 2 "nvme_subsystem_next_ctrl" "February 2020" "libnvme Manual" +.SH NAME +nvme_subsystem_next_ctrl \- +.SH SYNOPSIS +.B "nvme_ctrl_t" nvme_subsystem_next_ctrl +.BI "(nvme_subsystem_t " s "," +.BI "nvme_ctrl_t " c ");" +.SH ARGUMENTS +.IP "s" 12 +-- undescribed -- +.IP "c" 12 diff --git a/doc/man/nvme_subsystem_next_ns.2 b/doc/man/nvme_subsystem_next_ns.2 new file mode 100644 index 0000000000..7f453447d1 --- /dev/null +++ b/doc/man/nvme_subsystem_next_ns.2 @@ -0,0 +1,11 @@ +.TH "nvme_subsystem_next_ns" 2 "nvme_subsystem_next_ns" "February 2020" "libnvme Manual" +.SH NAME +nvme_subsystem_next_ns \- +.SH SYNOPSIS +.B "nvme_ns_t" nvme_subsystem_next_ns +.BI "(nvme_subsystem_t " s "," +.BI "nvme_ns_t " n ");" +.SH ARGUMENTS +.IP "s" 12 +-- undescribed -- +.IP "n" 12 diff --git a/doc/man/nvme_subsystem_reset.2 b/doc/man/nvme_subsystem_reset.2 new file mode 100644 index 0000000000..5ca788e242 --- /dev/null +++ b/doc/man/nvme_subsystem_reset.2 @@ -0,0 +1,14 @@ +.TH "nvme_subsystem_reset" 2 "nvme_subsystem_reset" "February 2020" "libnvme Manual" +.SH NAME +nvme_subsystem_reset \- Initiate a subsystem reset +.SH SYNOPSIS +.B "int" nvme_subsystem_reset +.BI "(int " fd ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.SH "DESCRIPTION" +This should only be sent to controller handles, not to namespaces. +.SH "RETURN" +Zero if a subsystem reset was initiated or -1 with errno set +otherwise. diff --git a/doc/man/nvme_unlink_ctrl.2 b/doc/man/nvme_unlink_ctrl.2 new file mode 100644 index 0000000000..6fa9407db0 --- /dev/null +++ b/doc/man/nvme_unlink_ctrl.2 @@ -0,0 +1,9 @@ +.TH "nvme_unlink_ctrl" 2 "nvme_unlink_ctrl" "February 2020" "libnvme Manual" +.SH NAME +nvme_unlink_ctrl \- +.SH SYNOPSIS +.B "void" nvme_unlink_ctrl +.BI "(struct nvme_ctrl *" c ");" +.SH ARGUMENTS +.IP "c" 12 +-- undescribed -- diff --git a/doc/man/nvme_verify.2 b/doc/man/nvme_verify.2 new file mode 100644 index 0000000000..5b02470c43 --- /dev/null +++ b/doc/man/nvme_verify.2 @@ -0,0 +1,43 @@ +.TH "nvme_verify" 2 "nvme_verify" "February 2020" "libnvme Manual" +.SH NAME +nvme_verify \- Send an nvme verify command +.SH SYNOPSIS +.B "int" nvme_verify +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "__u64 " slba "," +.BI "__u16 " nlb "," +.BI "__u16 " control "," +.BI "__u32 " reftag "," +.BI "__u16 " apptag "," +.BI "__u16 " appmask ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Namespace identifier +.IP "slba" 12 +Starting logical block +.IP "nlb" 12 +Number of logical blocks to verify (0's based value) +.IP "control" 12 +Command control flags, see \fIenum nvme_io_control_flags\fP. +.IP "reftag" 12 +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. +.IP "apptag" 12 +This field specifies the Application Tag Mask expected value. +Used only if the namespace is formatted to use end-to-end +protection information. +.IP "appmask" 12 +This field specifies the Application Tag expected value. Used +only if the namespace is formatted to use end-to-end protection +information. +.SH "DESCRIPTION" +The Verify command verifies integrity of stored information by reading data +and metadata, if applicable, for the LBAs indicated without transferring any +data or metadata to the host. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_virtual_mgmt.2 b/doc/man/nvme_virtual_mgmt.2 new file mode 100644 index 0000000000..bef9c6341f --- /dev/null +++ b/doc/man/nvme_virtual_mgmt.2 @@ -0,0 +1,35 @@ +.TH "nvme_virtual_mgmt" 2 "nvme_virtual_mgmt" "February 2020" "libnvme Manual" +.SH NAME +nvme_virtual_mgmt \- Virtualization resource management +.SH SYNOPSIS +.B "int" nvme_virtual_mgmt +.BI "(int " fd "," +.BI "enum nvme_virt_mgmt_act " act "," +.BI "enum nvme_virt_mgmt_rt " rt "," +.BI "__u16 " cntlid "," +.BI "__u16 " nr "," +.BI "__u32 *" result ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "act" 12 +Virtual resource action, see \fIenum nvme_virt_mgmt_act\fP +.IP "rt" 12 +Resource type to modify, see \fIenum nvme_virt_mgmt_rt\fP +.IP "cntlid" 12 +Controller id for which resources are bing modified +.IP "nr" 12 +Number of resources being allocated or assigned +.IP "result" 12 +If successful, the CQE dword0 +.SH "DESCRIPTION" +The Virtualization Management command is supported by primary controllers +that support the Virtualization Enhancements capability. This command is +used for several functions: + +- Modifying Flexible Resource allocation for the primary controller +- Assigning Flexible Resources for secondary controllers +- Setting the Online and Offline state for secondary controllers +.SH "RETURN" +The nvme command status if a response was received or -1 +with errno set otherwise. diff --git a/doc/man/nvme_write.2 b/doc/man/nvme_write.2 new file mode 100644 index 0000000000..55f3d0c53e --- /dev/null +++ b/doc/man/nvme_write.2 @@ -0,0 +1,58 @@ +.TH "nvme_write" 2 "nvme_write" "February 2020" "libnvme Manual" +.SH NAME +nvme_write \- Submit an nvme user write command +.SH SYNOPSIS +.B "int" nvme_write +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "__u64 " slba "," +.BI "__u16 " nlb "," +.BI "__u16 " control "," +.BI "__u8 " dsm "," +.BI "__u16 " dspec "," +.BI "__u32 " reftag "," +.BI "__u16 " apptag "," +.BI "__u16 " appmask "," +.BI "__u32 " data_len "," +.BI "void *" data "," +.BI "__u32 " metadata_len "," +.BI "void *" metadata ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Namespace ID +.IP "slba" 12 +Starting logical block +.IP "nlb" 12 +-- undescribed -- +.IP "control" 12 +Command control flags, see \fIenum nvme_io_control_flags\fP. +.IP "dsm" 12 +Data set management attributes, see \fIenum nvme_io_dsm_flags\fP +.IP "dspec" 12 +Directive specific command, eg: stream identifier +.IP "reftag" 12 +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. +.IP "apptag" 12 +This field specifies the Application Tag Mask expected value. +Used only if the namespace is formatted to use end-to-end +protection information. +.IP "appmask" 12 +This field specifies the Application Tag expected value. Used +only if the namespace is formatted to use end-to-end protection +information. +.IP "data_len" 12 +Length of user buffer, \fIdata\fP, in bytes +.IP "data" 12 +Pointer to user address of the data buffer +metadata_len:Length of user buffer, \fImetadata\fP, in bytes +.IP "metadata_len" 12 +-- undescribed -- +.IP "metadata" 12 +Pointer to user address of the metadata buffer +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_write_uncorrectable.2 b/doc/man/nvme_write_uncorrectable.2 new file mode 100644 index 0000000000..53755c5a32 --- /dev/null +++ b/doc/man/nvme_write_uncorrectable.2 @@ -0,0 +1,27 @@ +.TH "nvme_write_uncorrectable" 2 "nvme_write_uncorrectable" "February 2020" "libnvme Manual" +.SH NAME +nvme_write_uncorrectable \- Submit an nvme write uncorrectable command +.SH SYNOPSIS +.B "int" nvme_write_uncorrectable +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "__u64 " slba "," +.BI "__u16 " nlb ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Namespace identifier +.IP "slba" 12 +Starting logical block +.IP "nlb" 12 +Number of logical blocks to invalidate (0's based value) +.SH "DESCRIPTION" +The Write Uncorrectable command is used to mark a range of logical blocks as +invalid. When the specified logical block(s) are read after this operation, +a failure is returned with Unrecovered Read Error status. To clear the +invalid logical block status, a write operation on those logical blocks is +required. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvme_write_zeros.2 b/doc/man/nvme_write_zeros.2 new file mode 100644 index 0000000000..b37919a2ac --- /dev/null +++ b/doc/man/nvme_write_zeros.2 @@ -0,0 +1,44 @@ +.TH "nvme_write_zeros" 2 "nvme_write_zeros" "February 2020" "libnvme Manual" +.SH NAME +nvme_write_zeros \- Submit an nvme write zeroes command +.SH SYNOPSIS +.B "int" nvme_write_zeros +.BI "(int " fd "," +.BI "__u32 " nsid "," +.BI "__u64 " slba "," +.BI "__u16 " nlb "," +.BI "__u16 " control "," +.BI "__u32 " reftag "," +.BI "__u16 " apptag "," +.BI "__u16 " appmask ");" +.SH ARGUMENTS +.IP "fd" 12 +File descriptor of nvme device +.IP "nsid" 12 +Namespace identifier +.IP "slba" 12 +Starting logical block +.IP "nlb" 12 +Number of logical blocks to clear (0's based value) +.IP "control" 12 +Command control flags, see \fIenum nvme_io_control_flags\fP. +.IP "reftag" 12 +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. +.IP "apptag" 12 +This field specifies the Application Tag Mask expected value. +Used only if the namespace is formatted to use end-to-end +protection information. +.IP "appmask" 12 +This field specifies the Application Tag expected value. Used +only if the namespace is formatted to use end-to-end protection +information. +.SH "DESCRIPTION" +The Write Zeroes command is used to set a range of logical blocks to zero. +After successful completion of this command, the value returned by +subsequent reads of logical blocks in this range shall be all bytes cleared +to 0h until a write occurs to this LBA range. +.SH "RETURN" +The nvme command status if a response was received or -1 with errno +set otherwise. diff --git a/doc/man/nvmf_add_ctrl.2 b/doc/man/nvmf_add_ctrl.2 new file mode 100644 index 0000000000..61d54cb4e2 --- /dev/null +++ b/doc/man/nvmf_add_ctrl.2 @@ -0,0 +1,9 @@ +.TH "nvmf_add_ctrl" 2 "nvmf_add_ctrl" "February 2020" "libnvme Manual" +.SH NAME +nvmf_add_ctrl \- +.SH SYNOPSIS +.B "nvme_ctrl_t" nvmf_add_ctrl +.BI "(struct nvme_fabrics_config *" cfg ");" +.SH ARGUMENTS +.IP "cfg" 12 +-- undescribed -- diff --git a/doc/man/nvmf_add_ctrl_opts.2 b/doc/man/nvmf_add_ctrl_opts.2 new file mode 100644 index 0000000000..00094fc0e4 --- /dev/null +++ b/doc/man/nvmf_add_ctrl_opts.2 @@ -0,0 +1,9 @@ +.TH "nvmf_add_ctrl_opts" 2 "nvmf_add_ctrl_opts" "February 2020" "libnvme Manual" +.SH NAME +nvmf_add_ctrl_opts \- +.SH SYNOPSIS +.B "int" nvmf_add_ctrl_opts +.BI "(struct nvme_fabrics_config *" cfg ");" +.SH ARGUMENTS +.IP "cfg" 12 +-- undescribed -- diff --git a/doc/man/nvmf_adrfam_str.2 b/doc/man/nvmf_adrfam_str.2 new file mode 100644 index 0000000000..57aecef728 --- /dev/null +++ b/doc/man/nvmf_adrfam_str.2 @@ -0,0 +1,9 @@ +.TH "nvmf_adrfam_str" 2 "nvmf_adrfam_str" "February 2020" "libnvme Manual" +.SH NAME +nvmf_adrfam_str \- +.SH SYNOPSIS +.B "const char *" nvmf_adrfam_str +.BI "(__u8 " adrfam ");" +.SH ARGUMENTS +.IP "adrfam" 12 +-- undescribed -- diff --git a/doc/man/nvmf_cms_str.2 b/doc/man/nvmf_cms_str.2 new file mode 100644 index 0000000000..51f7214f63 --- /dev/null +++ b/doc/man/nvmf_cms_str.2 @@ -0,0 +1,9 @@ +.TH "nvmf_cms_str" 2 "nvmf_cms_str" "February 2020" "libnvme Manual" +.SH NAME +nvmf_cms_str \- +.SH SYNOPSIS +.B "const char *" nvmf_cms_str +.BI "(__u8 " cm ");" +.SH ARGUMENTS +.IP "cm" 12 +-- undescribed -- diff --git a/doc/man/nvmf_connect_disc_entry.2 b/doc/man/nvmf_connect_disc_entry.2 new file mode 100644 index 0000000000..1f07ece102 --- /dev/null +++ b/doc/man/nvmf_connect_disc_entry.2 @@ -0,0 +1,15 @@ +.TH "nvmf_connect_disc_entry" 2 "nvmf_connect_disc_entry" "February 2020" "libnvme Manual" +.SH NAME +nvmf_connect_disc_entry \- +.SH SYNOPSIS +.B "nvme_ctrl_t" nvmf_connect_disc_entry +.BI "(struct nvmf_disc_log_entry *" e "," +.BI "const struct nvme_fabrics_config *" defcfg "," +.BI "bool *" discover ");" +.SH ARGUMENTS +.IP "e" 12 +-- undescribed -- +.IP "defcfg" 12 +-- undescribed -- +.IP "discover" 12 +-- undescribed -- diff --git a/doc/man/nvmf_get_discovery_log.2 b/doc/man/nvmf_get_discovery_log.2 new file mode 100644 index 0000000000..55e9e62c94 --- /dev/null +++ b/doc/man/nvmf_get_discovery_log.2 @@ -0,0 +1,15 @@ +.TH "nvmf_get_discovery_log" 2 "nvmf_get_discovery_log" "February 2020" "libnvme Manual" +.SH NAME +nvmf_get_discovery_log \- +.SH SYNOPSIS +.B "int" nvmf_get_discovery_log +.BI "(nvme_ctrl_t " c "," +.BI "struct nvmf_discovery_log **" logp "," +.BI "int " max_retries ");" +.SH ARGUMENTS +.IP "c" 12 +-- undescribed -- +.IP "logp" 12 +-- undescribed -- +.IP "max_retries" 12 +-- undescribed -- diff --git a/doc/man/nvmf_hostid_from_file.2 b/doc/man/nvmf_hostid_from_file.2 new file mode 100644 index 0000000000..bf0132f9c1 --- /dev/null +++ b/doc/man/nvmf_hostid_from_file.2 @@ -0,0 +1,6 @@ +.TH "nvmf_hostid_from_file" 2 "nvmf_hostid_from_file" "February 2020" "libnvme Manual" +.SH NAME +nvmf_hostid_from_file \- +.SH SYNOPSIS +.B "char *" nvmf_hostid_from_file +.SH ARGUMENTS diff --git a/doc/man/nvmf_hostnqn_from_file.2 b/doc/man/nvmf_hostnqn_from_file.2 new file mode 100644 index 0000000000..0db3266486 --- /dev/null +++ b/doc/man/nvmf_hostnqn_from_file.2 @@ -0,0 +1,6 @@ +.TH "nvmf_hostnqn_from_file" 2 "nvmf_hostnqn_from_file" "February 2020" "libnvme Manual" +.SH NAME +nvmf_hostnqn_from_file \- +.SH SYNOPSIS +.B "char *" nvmf_hostnqn_from_file +.SH ARGUMENTS diff --git a/doc/man/nvmf_hostnqn_generate.2 b/doc/man/nvmf_hostnqn_generate.2 new file mode 100644 index 0000000000..59e6506999 --- /dev/null +++ b/doc/man/nvmf_hostnqn_generate.2 @@ -0,0 +1,6 @@ +.TH "nvmf_hostnqn_generate" 2 "nvmf_hostnqn_generate" "February 2020" "libnvme Manual" +.SH NAME +nvmf_hostnqn_generate \- +.SH SYNOPSIS +.B "char *" nvmf_hostnqn_generate +.SH ARGUMENTS diff --git a/doc/man/nvmf_prtype_str.2 b/doc/man/nvmf_prtype_str.2 new file mode 100644 index 0000000000..812a35e3e7 --- /dev/null +++ b/doc/man/nvmf_prtype_str.2 @@ -0,0 +1,9 @@ +.TH "nvmf_prtype_str" 2 "nvmf_prtype_str" "February 2020" "libnvme Manual" +.SH NAME +nvmf_prtype_str \- +.SH SYNOPSIS +.B "const char *" nvmf_prtype_str +.BI "(__u8 " prtype ");" +.SH ARGUMENTS +.IP "prtype" 12 +-- undescribed -- diff --git a/doc/man/nvmf_qptype_str.2 b/doc/man/nvmf_qptype_str.2 new file mode 100644 index 0000000000..61a524fac6 --- /dev/null +++ b/doc/man/nvmf_qptype_str.2 @@ -0,0 +1,9 @@ +.TH "nvmf_qptype_str" 2 "nvmf_qptype_str" "February 2020" "libnvme Manual" +.SH NAME +nvmf_qptype_str \- +.SH SYNOPSIS +.B "const char *" nvmf_qptype_str +.BI "(__u8 " qptype ");" +.SH ARGUMENTS +.IP "qptype" 12 +-- undescribed -- diff --git a/doc/man/nvmf_sectype_str.2 b/doc/man/nvmf_sectype_str.2 new file mode 100644 index 0000000000..1f6058fbcb --- /dev/null +++ b/doc/man/nvmf_sectype_str.2 @@ -0,0 +1,9 @@ +.TH "nvmf_sectype_str" 2 "nvmf_sectype_str" "February 2020" "libnvme Manual" +.SH NAME +nvmf_sectype_str \- +.SH SYNOPSIS +.B "const char *" nvmf_sectype_str +.BI "(__u8 " sectype ");" +.SH ARGUMENTS +.IP "sectype" 12 +-- undescribed -- diff --git a/doc/man/nvmf_subtype_str.2 b/doc/man/nvmf_subtype_str.2 new file mode 100644 index 0000000000..40cc97490e --- /dev/null +++ b/doc/man/nvmf_subtype_str.2 @@ -0,0 +1,9 @@ +.TH "nvmf_subtype_str" 2 "nvmf_subtype_str" "February 2020" "libnvme Manual" +.SH NAME +nvmf_subtype_str \- +.SH SYNOPSIS +.B "const char *" nvmf_subtype_str +.BI "(__u8 " subtype ");" +.SH ARGUMENTS +.IP "subtype" 12 +-- undescribed -- diff --git a/doc/man/nvmf_treq_str.2 b/doc/man/nvmf_treq_str.2 new file mode 100644 index 0000000000..4d5c292e37 --- /dev/null +++ b/doc/man/nvmf_treq_str.2 @@ -0,0 +1,9 @@ +.TH "nvmf_treq_str" 2 "nvmf_treq_str" "February 2020" "libnvme Manual" +.SH NAME +nvmf_treq_str \- +.SH SYNOPSIS +.B "const char *" nvmf_treq_str +.BI "(__u8 " treq ");" +.SH ARGUMENTS +.IP "treq" 12 +-- undescribed -- diff --git a/doc/man/nvmf_trtype_str.2 b/doc/man/nvmf_trtype_str.2 new file mode 100644 index 0000000000..afcff2f1be --- /dev/null +++ b/doc/man/nvmf_trtype_str.2 @@ -0,0 +1,9 @@ +.TH "nvmf_trtype_str" 2 "nvmf_trtype_str" "February 2020" "libnvme Manual" +.SH NAME +nvmf_trtype_str \- +.SH SYNOPSIS +.B "const char *" nvmf_trtype_str +.BI "(__u8 " trtype ");" +.SH ARGUMENTS +.IP "trtype" 12 +-- undescribed -- diff --git a/doc/man/struct nvme_aggregate_endurance_group_event.2 b/doc/man/struct nvme_aggregate_endurance_group_event.2 new file mode 100644 index 0000000000..0325867d69 --- /dev/null +++ b/doc/man/struct nvme_aggregate_endurance_group_event.2 @@ -0,0 +1,15 @@ +.TH "libnvme" 2 "struct nvme_aggregate_endurance_group_event" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_aggregate_endurance_group_event \- +.SH SYNOPSIS +struct nvme_aggregate_endurance_group_event { +.br +.BI " __le64 num_entries;" +.br +.BI " __le16 entries[];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_aggregate_predictable_lat_event.2 b/doc/man/struct nvme_aggregate_predictable_lat_event.2 new file mode 100644 index 0000000000..963591ed07 --- /dev/null +++ b/doc/man/struct nvme_aggregate_predictable_lat_event.2 @@ -0,0 +1,15 @@ +.TH "libnvme" 2 "struct nvme_aggregate_predictable_lat_event" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_aggregate_predictable_lat_event \- +.SH SYNOPSIS +struct nvme_aggregate_predictable_lat_event { +.br +.BI " __le64 num_entries;" +.br +.BI " __le16 entries[];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_ana_group_desc.2 b/doc/man/struct nvme_ana_group_desc.2 new file mode 100644 index 0000000000..5e5722e170 --- /dev/null +++ b/doc/man/struct nvme_ana_group_desc.2 @@ -0,0 +1,23 @@ +.TH "libnvme" 2 "struct nvme_ana_group_desc" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_ana_group_desc \- +.SH SYNOPSIS +struct nvme_ana_group_desc { +.br +.BI " __le32 grpid;" +.br +.BI " __le32 nnsids;" +.br +.BI " __le64 chgcnt;" +.br +.BI " __u8 state;" +.br +.BI " __u8 rsvd17[15];" +.br +.BI " __le32 nsids[];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_ana_log.2 b/doc/man/struct nvme_ana_log.2 new file mode 100644 index 0000000000..8d0176d412 --- /dev/null +++ b/doc/man/struct nvme_ana_log.2 @@ -0,0 +1,19 @@ +.TH "libnvme" 2 "struct nvme_ana_log" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_ana_log \- +.SH SYNOPSIS +struct nvme_ana_log { +.br +.BI " __le64 chgcnt;" +.br +.BI " __le16 ngrps;" +.br +.BI " __u8 rsvd10[6];" +.br +.BI " struct nvme_ana_group_desc descs[];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_cmd_effects_log.2 b/doc/man/struct nvme_cmd_effects_log.2 new file mode 100644 index 0000000000..0ddfb5511d --- /dev/null +++ b/doc/man/struct nvme_cmd_effects_log.2 @@ -0,0 +1,17 @@ +.TH "libnvme" 2 "struct nvme_cmd_effects_log" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_cmd_effects_log \- +.SH SYNOPSIS +struct nvme_cmd_effects_log { +.br +.BI " __le32 acs[256];" +.br +.BI " __le32 iocs[256];" +.br +.BI " __u8 resv[2048];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_ctrl_list.2 b/doc/man/struct nvme_ctrl_list.2 new file mode 100644 index 0000000000..70fc9e0e6f --- /dev/null +++ b/doc/man/struct nvme_ctrl_list.2 @@ -0,0 +1,15 @@ +.TH "libnvme" 2 "struct nvme_ctrl_list" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_ctrl_list \- @num; +.SH SYNOPSIS +struct nvme_ctrl_list { +.br +.BI " __le16 num;" +.br +.BI " __le16 identifier[NVME_ID_CTRL_LIST_MAX];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_dsm_range.2 b/doc/man/struct nvme_dsm_range.2 new file mode 100644 index 0000000000..ef9b4d0bb2 --- /dev/null +++ b/doc/man/struct nvme_dsm_range.2 @@ -0,0 +1,17 @@ +.TH "libnvme" 2 "struct nvme_dsm_range" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_dsm_range \- +.SH SYNOPSIS +struct nvme_dsm_range { +.br +.BI " __le32 cattr;" +.br +.BI " __le32 nlb;" +.br +.BI " __le64 slba;" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_eg_event_aggregate_log.2 b/doc/man/struct nvme_eg_event_aggregate_log.2 new file mode 100644 index 0000000000..15e19159c1 --- /dev/null +++ b/doc/man/struct nvme_eg_event_aggregate_log.2 @@ -0,0 +1,15 @@ +.TH "libnvme" 2 "struct nvme_eg_event_aggregate_log" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_eg_event_aggregate_log \- +.SH SYNOPSIS +struct nvme_eg_event_aggregate_log { +.br +.BI " __le64 nr_entries;" +.br +.BI " __le16 egids[];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_endurance_group_log.2 b/doc/man/struct nvme_endurance_group_log.2 new file mode 100644 index 0000000000..48e75e862a --- /dev/null +++ b/doc/man/struct nvme_endurance_group_log.2 @@ -0,0 +1,41 @@ +.TH "libnvme" 2 "struct nvme_endurance_group_log" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_endurance_group_log \- +.SH SYNOPSIS +struct nvme_endurance_group_log { +.br +.BI " __u8 critical_warning;" +.br +.BI " __u8 rsvd1[2];" +.br +.BI " __u8 avl_spare;" +.br +.BI " __u8 avl_spare_threshold;" +.br +.BI " __u8 percent_used;" +.br +.BI " __u8 rsvd6[26];" +.br +.BI " __u8 endurance_estimate[16];" +.br +.BI " __u8 data_units_read[16];" +.br +.BI " __u8 data_units_written[16];" +.br +.BI " __u8 media_units_written[16];" +.br +.BI " __u8 host_read_cmds[16];" +.br +.BI " __u8 host_write_cmds[16];" +.br +.BI " __u8 media_data_integrity_err[16];" +.br +.BI " __u8 num_err_info_log_entries[16];" +.br +.BI " __u8 rsvd160[352];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_error_log_page.2 b/doc/man/struct nvme_error_log_page.2 new file mode 100644 index 0000000000..48ee5cb256 --- /dev/null +++ b/doc/man/struct nvme_error_log_page.2 @@ -0,0 +1,37 @@ +.TH "libnvme" 2 "struct nvme_error_log_page" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_error_log_page \- +.SH SYNOPSIS +struct nvme_error_log_page { +.br +.BI " __le64 error_count;" +.br +.BI " __le16 sqid;" +.br +.BI " __le16 cmdid;" +.br +.BI " __le16 status_field;" +.br +.BI " __le16 parm_error_location;" +.br +.BI " __le64 lba;" +.br +.BI " __le32 nsid;" +.br +.BI " __u8 vs;" +.br +.BI " __u8 trtype;" +.br +.BI " __u8 resv[2];" +.br +.BI " __le64 cs;" +.br +.BI " __le16 trtype_spec_info;" +.br +.BI " __u8 resv2[22];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_fabrics_config.2 b/doc/man/struct nvme_fabrics_config.2 new file mode 100644 index 0000000000..ebc8f26055 --- /dev/null +++ b/doc/man/struct nvme_fabrics_config.2 @@ -0,0 +1,51 @@ +.TH "libnvme" 2 "struct nvme_fabrics_config" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_fabrics_config \- +.SH SYNOPSIS +struct nvme_fabrics_config { +.br +.BI " const char *transport;" +.br +.BI " const char *traddr;" +.br +.BI " const char *trsvcid;" +.br +.BI " const char *nqn;" +.br +.BI " const char *hostnqn;" +.br +.BI " const char *host_traddr;" +.br +.BI " const char *hostid;" +.br +.BI " int queue_size;" +.br +.BI " int nr_io_queues;" +.br +.BI " int reconnect_delay;" +.br +.BI " int ctrl_loss_tmo;" +.br +.BI " int keep_alive_tmo;" +.br +.BI " int nr_write_queues;" +.br +.BI " int nr_poll_queues;" +.br +.BI " int tos;" +.br +.BI " bool duplicate_connect;" +.br +.BI " bool disable_sqflow;" +.br +.BI " bool hdr_digest;" +.br +.BI " bool data_digest;" +.br +.BI " uint8_t rsvd[0x200];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_feat_auto_pst.2 b/doc/man/struct nvme_feat_auto_pst.2 new file mode 100644 index 0000000000..4642ceccc1 --- /dev/null +++ b/doc/man/struct nvme_feat_auto_pst.2 @@ -0,0 +1,13 @@ +.TH "libnvme" 2 "struct nvme_feat_auto_pst" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_feat_auto_pst \- +.SH SYNOPSIS +struct nvme_feat_auto_pst { +.br +.BI " __le64 apst_entry[32];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_feat_host_behavior.2 b/doc/man/struct nvme_feat_host_behavior.2 new file mode 100644 index 0000000000..5950a725ee --- /dev/null +++ b/doc/man/struct nvme_feat_host_behavior.2 @@ -0,0 +1,15 @@ +.TH "libnvme" 2 "struct nvme_feat_host_behavior" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_feat_host_behavior \- +.SH SYNOPSIS +struct nvme_feat_host_behavior { +.br +.BI " __u8 acre;" +.br +.BI " __u8 resv1[511];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_firmware_slot.2 b/doc/man/struct nvme_firmware_slot.2 new file mode 100644 index 0000000000..b98c8a2303 --- /dev/null +++ b/doc/man/struct nvme_firmware_slot.2 @@ -0,0 +1,19 @@ +.TH "libnvme" 2 "struct nvme_firmware_slot" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_firmware_slot \- +.SH SYNOPSIS +struct nvme_firmware_slot { +.br +.BI " __u8 afi;" +.br +.BI " __u8 resv[7];" +.br +.BI " struct nvme_frs frs[7];" +.br +.BI " __u8 resv2[448];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_frs.2 b/doc/man/struct nvme_frs.2 new file mode 100644 index 0000000000..7ee2e7062b --- /dev/null +++ b/doc/man/struct nvme_frs.2 @@ -0,0 +1,13 @@ +.TH "libnvme" 2 "struct nvme_frs" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_frs \- +.SH SYNOPSIS +struct nvme_frs { +.br +.BI " char frs[8];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_host_mem_buf_desc.2 b/doc/man/struct nvme_host_mem_buf_desc.2 new file mode 100644 index 0000000000..66bead31bb --- /dev/null +++ b/doc/man/struct nvme_host_mem_buf_desc.2 @@ -0,0 +1,17 @@ +.TH "libnvme" 2 "struct nvme_host_mem_buf_desc" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_host_mem_buf_desc \- +.SH SYNOPSIS +struct nvme_host_mem_buf_desc { +.br +.BI " __le64 addr;" +.br +.BI " __le32 size;" +.br +.BI " __u32 rsvd;" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_id_ctrl.2 b/doc/man/struct nvme_id_ctrl.2 new file mode 100644 index 0000000000..f3dab11b4c --- /dev/null +++ b/doc/man/struct nvme_id_ctrl.2 @@ -0,0 +1,455 @@ +.TH "libnvme" 2 "struct nvme_id_ctrl" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_id_ctrl \- Identify Controller data structure +.SH SYNOPSIS +struct nvme_id_ctrl { +.br +.BI " __le16 vid;" +.br +.BI " __le16 ssvid;" +.br +.BI " char sn[20];" +.br +.BI " char mn[40];" +.br +.BI " char fr[8];" +.br +.BI " __u8 rab;" +.br +.BI " __u8 ieee[3];" +.br +.BI " __u8 cmic;" +.br +.BI " __u8 mdts;" +.br +.BI " __le16 cntlid;" +.br +.BI " __le32 ver;" +.br +.BI " __le32 rtd3r;" +.br +.BI " __le32 rtd3e;" +.br +.BI " __le32 oaes;" +.br +.BI " __le32 ctratt;" +.br +.BI " __le16 rrls;" +.br +.BI " __u8 rsvd102[9];" +.br +.BI " __u8 cntrltype;" +.br +.BI " __u8 fguid[16];" +.br +.BI " __le16 crdt1;" +.br +.BI " __le16 crdt2;" +.br +.BI " __le16 crdt3;" +.br +.BI " __u8 rsvd134[119];" +.br +.BI " __u8 nvmsr;" +.br +.BI " __u8 vwci;" +.br +.BI " __u8 mec;" +.br +.BI " __le16 oacs;" +.br +.BI " __u8 acl;" +.br +.BI " __u8 aerl;" +.br +.BI " __u8 frmw;" +.br +.BI " __u8 lpa;" +.br +.BI " __u8 elpe;" +.br +.BI " __u8 npss;" +.br +.BI " __u8 avscc;" +.br +.BI " __u8 apsta;" +.br +.BI " __le16 wctemp;" +.br +.BI " __le16 cctemp;" +.br +.BI " __le16 mtfa;" +.br +.BI " __le32 hmpre;" +.br +.BI " __le32 hmmin;" +.br +.BI " __u8 tnvmcap[16];" +.br +.BI " __u8 unvmcap[16];" +.br +.BI " __le32 rpmbs;" +.br +.BI " __le16 edstt;" +.br +.BI " __u8 dsto;" +.br +.BI " __u8 fwug;" +.br +.BI " __le16 kas;" +.br +.BI " __le16 hctma;" +.br +.BI " __le16 mntmt;" +.br +.BI " __le16 mxtmt;" +.br +.BI " __le32 sanicap;" +.br +.BI " __le32 hmminds;" +.br +.BI " __le16 hmmaxd;" +.br +.BI " __le16 nsetidmax;" +.br +.BI " __le16 endgidmax;" +.br +.BI " __u8 anatt;" +.br +.BI " __u8 anacap;" +.br +.BI " __le32 anagrpmax;" +.br +.BI " __le32 nanagrpid;" +.br +.BI " __le32 pels;" +.br +.BI " __u8 rsvd356[156];" +.br +.BI " __u8 sqes;" +.br +.BI " __u8 cqes;" +.br +.BI " __le16 maxcmd;" +.br +.BI " __le32 nn;" +.br +.BI " __le16 oncs;" +.br +.BI " __le16 fuses;" +.br +.BI " __u8 fna;" +.br +.BI " __u8 vwc;" +.br +.BI " __le16 awun;" +.br +.BI " __le16 awupf;" +.br +.BI " __u8 nvscc;" +.br +.BI " __u8 nwpc;" +.br +.BI " __le16 acwu;" +.br +.BI " __u8 rsvd534[2];" +.br +.BI " __le32 sgls;" +.br +.BI " __le32 mnan;" +.br +.BI " __u8 rsvd544[224];" +.br +.BI " char subnqn[256];" +.br +.BI " __u8 rsvd1024[768];" +.br +.BI " __le32 ioccsz;" +.br +.BI " __le32 iorcsz;" +.br +.BI " __le16 icdoff;" +.br +.BI " __u8 fcatt;" +.br +.BI " __u8 msdbd;" +.br +.BI " __le16 ofcs;" +.br +.BI " __u8 rsvd1806[242];" +.br +.BI " struct nvme_id_psd psd[32];" +.br +.BI " __u8 vs[1024];" +.br +.BI " +}; +.br + +.SH Members +.IP "vid" 12 +PCI Vendor ID, the company vendor identifier that is assigned by +the PCI SIG. +.IP "ssvid" 12 +PCI Subsystem Vendor ID, the company vendor identifier that is +assigned by the PCI SIG for the subsystem. +.IP "sn" 12 +Serial Number in ascii +.IP "mn" 12 +Model Number in ascii +.IP "fr" 12 +Firmware Revision in ascii, the currently active firmware +revision for the NVM subsystem +.IP "rab" 12 +Recommended Arbitration Burst, reported as a power of two +.IP "ieee" 12 +IEEE assigned Organization Unique Identifier +.IP "cmic" 12 +Controller Multipath IO and Namespace Sharing Capabilities of +the controller and NVM subsystem. See \fIenum nvme_id_ctrl_cmic\fP. +.IP "mdts" 12 +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 +.IP "cntlid" 12 +Controller ID, the NVM subsystem unique controller identifier +associated with the controller. +.IP "ver" 12 +Version, this field contains the value reported in the Version +register, or property (see \fIenum nvme_registers\fP NVME_REG_VS). +.IP "rtd3r" 12 +RTD3 Resume Latency, the expected latency in microseconds to resume +from Runtime D3 +.IP "rtd3e" 12 +RTD3 Exit Latency, the typical latency in microseconds to enter +Runtime D3. +.IP "oaes" 12 +Optional Async Events Supported, see \fIenum\fP nvme_id_ctrl_oaes . +.IP "ctratt" 12 +Controller Attributes, see \fIenum\fP nvme_id_ctrl_ctratt +.IP "rrls" 12 +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. +.IP "cntrltype" 12 +Controller Type, see \fIenum nvme_id_ctrl_cntrltype\fP +.IP "fguid" 12 +FRU GUID, a 128-bit value that is globally unique for a given +Field Replaceable Unit +.IP "crdt1" 12 +Controller Retry Delay time in 100 millisecod units if CQE CRD +field is 1 +.IP "crdt2" 12 +Controller Retry Delay time in 100 millisecod units if CQE CRD +field is 2 +.IP "crdt3" 12 +Controller Retry Delay time in 100 millisecod units if CQE CRD +field is 3 +.IP "nvmsr" 12 +NVM Subsystem Report, see \fIenum nvme_id_ctrl_nvmsr\fP +.IP "vwci" 12 +VPD Write Cycle Information, see \fIenum nvme_id_ctrl_vwci\fP +.IP "mec" 12 +Management Endpoint Capabilities, see \fIenum nvme_id_ctrl_mec\fP +.IP "oacs" 12 +Optional Admin Command Support,the optional Admin commands and +features supported by the controller, see \fIenum nvme_id_ctrl_oacs\fP. +.IP "acl" 12 +Abort Command Limit, the maximum number of concurrently +executing Abort commands supported by the controller. This is a +0's based value. +.IP "aerl" 12 +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. +.IP "frmw" 12 +Firmware Updates indicates capabilities regarding firmware +updates. See \fIenum nvme_id_ctrl_frmw\fP. +.IP "lpa" 12 +Log Page Attributes, see \fIenum nvme_id_ctrl_lpa\fP. +.IP "elpe" 12 +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. +.IP "npss" 12 +Number of Power States Supported, the number of NVM Express +power states supported by the controller, indicating the number +of valid entries in \fIstruct nvme_id_ctrl\fP.psd. This is a 0's +based value. +.IP "avscc" 12 +Admin Vendor Specific Command Configuration, see \fIenum +nvme_id_ctrl_avscc\fP. +.IP "apsta" 12 +Autonomous Power State Transition Attributes, see \fIenum +nvme_id_ctrl_apsta\fP. +.IP "wctemp" 12 +Warning Composite Temperature Threshold indicates +the minimum Composite Temperature field value (see \fIstruct +nvme_smart_log\fP.critical_comp_time) that indicates an overheating +condition during which controller operation continues. +.IP "cctemp" 12 +Critical Composite Temperature Threshold, field indicates the +minimum Composite Temperature field value (see \fIstruct +nvme_smart_log\fP.critical_comp_time) that indicates a critical +overheating condition. +.IP "mtfa" 12 +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. +.IP "hmpre" 12 +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. +.IP "hmmin" 12 +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. +.IP "tnvmcap" 12 +Total NVM Capacity, the total NVM capacity in the NVM subsystem. +The value is in bytes. +.IP "unvmcap" 12 +Unallocated NVM Capacity, the unallocated NVM capacity in the +NVM subsystem. The value is in bytes. +\fIrpmbs\fP Replay Protected Memory Block Support, see \fIenum +nvme_id_ctrl_rpmbs\fP. +\fIedstt\fP Extended Device Self-test Time, if Device Self-test command is +supported (see \fIstruct nvme_id_ctrl\fP.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. +.IP "dsto" 12 +Device Self-test Options, see \fIenum nvme_id_ctrl_dsto\fP. +.IP "fwug" 12 +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 +.IP "kas" 12 +Keep Alive Support indicates the granularity of the Keep Alive +Timer in 100 millisecond units. +.IP "hctma" 12 +Host Controlled Thermal Management Attributes, see \fIenum nvme_id_ctrl_hctm\fP. +.IP "mntmt" 12 +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. +.IP "mxtmt" 12 +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. +.IP "sanicap" 12 +Sanitize Capabilities, see \fIenum nvme_id_ctrl_sanicap\fP +.IP "hmminds" 12 +Host Memory Buffer Minimum Descriptor Entry Size indicates the +minimum usable size of a Host Memory Buffer Descriptor Entry in +4 KiB units. +.IP "hmmaxd" 12 +Host Memory Maximum Descriptors Entries indicates the number of +usable Host Memory Buffer Descriptor Entries. +.IP "nsetidmax" 12 +NVM Set Identifier Maximum, defines the maximum value of a valid +NVM Set Identifier for any controller in the NVM subsystem. +.IP "endgidmax" 12 +Endurance Group Identifier Maximum, defines the maximum value of +a valid Endurance Group Identifier for any controller in the NVM +subsystem. +.IP "anatt" 12 +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. +.IP "anacap" 12 +Asymmetric Namespace Access Capabilities, see \fIenum +nvme_id_ctrl_anacap\fP. +.IP "anagrpmax" 12 +ANA Group Identifier Maximum indicates the maximum value of a +valid ANA Group Identifier for any controller in the NVM +subsystem. +.IP "nanagrpid" 12 +Number of ANA Group Identifiers indicates the number of ANA +groups supported by this controller. +.IP "pels" 12 +Persistent Event Log Size indicates the maximum reportable size +for the Persistent Event Log. +.IP "sqes" 12 +Submission Queue Entry Size, see \fIenum nvme_id_ctrl_sqes\fP. +.IP "cqes" 12 +Completion Queue Entry Size, see \fIenum nvme_id_ctrl_cqes\fP. +.IP "maxcmd" 12 +Maximum Outstanding Commands indicates the maximum number of +commands that the controller processes at one time for a +particular queue. +.IP "nn" 12 +Number of Namespaces indicates the maximum value of a valid +nsid for the NVM subsystem. If the MNAN (\fIstruct nvme_id_ctrl\fP.mnan +field is cleared to 0h, then this field also indicates the +maximum number of namespaces supported by the NVM. subsystem. +.IP "oncs" 12 +Optional NVM Command Support, see \fIenum nvme_id_ctrl_oncs\fP. +.IP "fuses" 12 +Fused Operation Support, see \fIenum nvme_id_ctrl_fuses\fP. +.IP "fna" 12 +Format NVM Attributes, see \fIenum nvme_id_ctrl_fna\fP. +.IP "vwc" 12 +Volatile Write Cache, see \fIenum nvme_id_ctrl_vwc\fP. +.IP "awun" 12 +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. +.IP "awupf" 12 +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. +.IP "nvscc" 12 +NVM Vendor Specific Command Configuration, see \fIenum +nvme_id_ctrl_nvscc\fP. +.IP "nwpc" 12 +Namespace Write Protection Capabilities, see \fIenum +nvme_id_ctrl_nwpc\fP. +.IP "acwu" 12 +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. +.IP "sgls" 12 +SGL Support, see \fIenum nvme_id_ctrl_sgls\fP +.IP "mnan" 12 +Maximum Number of Allowed Namespaces indicates the maximum +number of namespaces supported by the NVM subsystem. +.IP "subnqn" 12 +NVM Subsystem NVMe Qualified Name, UTF-8 null terminated string +.IP "ioccsz" 12 +I/O Queue Command Capsule Supported Size, defines the maximum +I/O command capsule size in 16 byte units. +.IP "iorcsz" 12 +I/O Queue Response Capsule Supported Size, defines the maximum +I/O response capsule size in 16 byte units. +.IP "icdoff" 12 +In Capsule Data Offset, defines the offset where data starts +within a capsule. This value is applicable to I/O Queues only. +.IP "fcatt" 12 +Fabrics Controller Attributes, see \fIenum nvme_id_ctrl_fcatt\fP. +.IP "msdbd" 12 +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. +.IP "ofcs" 12 +Optional Fabric Commands Support, see \fIenum nvme_id_ctrl_ofcs\fP. +.IP "psd" 12 +Power State Descriptors, see \fIstruct nvme_id_psd\fP. +.IP "vs" 12 +Vendor Specific diff --git a/doc/man/struct nvme_id_directives.2 b/doc/man/struct nvme_id_directives.2 new file mode 100644 index 0000000000..9381824497 --- /dev/null +++ b/doc/man/struct nvme_id_directives.2 @@ -0,0 +1,17 @@ +.TH "libnvme" 2 "struct nvme_id_directives" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_id_directives \- +.SH SYNOPSIS +struct nvme_id_directives { +.br +.BI " __u8 supported[32];" +.br +.BI " __u8 enabled[32];" +.br +.BI " __u8 rsvd64[4032];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_id_ns.2 b/doc/man/struct nvme_id_ns.2 new file mode 100644 index 0000000000..d4ea75884c --- /dev/null +++ b/doc/man/struct nvme_id_ns.2 @@ -0,0 +1,203 @@ +.TH "libnvme" 2 "struct nvme_id_ns" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_id_ns \- Identify Namespace data structure +.SH SYNOPSIS +struct nvme_id_ns { +.br +.BI " __le64 nsze;" +.br +.BI " __le64 ncap;" +.br +.BI " __le64 nuse;" +.br +.BI " __u8 nsfeat;" +.br +.BI " __u8 nlbaf;" +.br +.BI " __u8 flbas;" +.br +.BI " __u8 mc;" +.br +.BI " __u8 dpc;" +.br +.BI " __u8 dps;" +.br +.BI " __u8 nmic;" +.br +.BI " __u8 rescap;" +.br +.BI " __u8 fpi;" +.br +.BI " __u8 dlfeat;" +.br +.BI " __le16 nawun;" +.br +.BI " __le16 nawupf;" +.br +.BI " __le16 nacwu;" +.br +.BI " __le16 nabsn;" +.br +.BI " __le16 nabo;" +.br +.BI " __le16 nabspf;" +.br +.BI " __le16 noiob;" +.br +.BI " __u8 nvmcap[16];" +.br +.BI " __le16 npwg;" +.br +.BI " __le16 npwa;" +.br +.BI " __le16 npdg;" +.br +.BI " __le16 npda;" +.br +.BI " __le16 nows;" +.br +.BI " __u8 rsvd74[18];" +.br +.BI " __le32 anagrpid;" +.br +.BI " __u8 rsvd96[3];" +.br +.BI " __u8 nsattr;" +.br +.BI " __le16 nvmsetid;" +.br +.BI " __le16 endgid;" +.br +.BI " __u8 nguid[16];" +.br +.BI " __u8 eui64[8];" +.br +.BI " struct nvme_lbaf lbaf[16];" +.br +.BI " __u8 rsvd192[192];" +.br +.BI " __u8 vs[3712];" +.br +.BI " +}; +.br + +.SH Members +.IP "nsze" 12 +Namespace Size indicates the total size of the namespace in +logical blocks. The number of logical blocks is based on the +formatted LBA size. +.IP "ncap" 12 +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. +.IP "nuse" 12 +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. +.IP "nsfeat" 12 +Namespace Features, see \fIenum nvme_id_nsfeat\fP. +.IP "nlbaf" 12 +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 \fIstruct nvme_id_ns\fP.labf. +.IP "flbas" 12 +Formatted LBA Size, see \fIenum nvme_id_ns_flbas\fP. +.IP "mc" 12 +Metadata Capabilities, see \fIenum nvme_id_ns_mc\fP. +.IP "dpc" 12 +End-to-end Data Protection Capabilities, see \fIenum +nvme_id_ns_dpc\fP. +.IP "dps" 12 +End-to-end Data Protection Type Settings, see \fIenum +nvme_id_ns_dps\fP. +.IP "nmic" 12 +Namespace Multi-path I/O and Namespace Sharing Capabilities, see +\fIenum nvme_id_ns_nmic\fP. +.IP "rescap" 12 +Reservation Capabilities, see \fIenum nvme_id_ns_rescap\fP. +.IP "fpi" 12 +Format Progress Indicator, see \fIenum nvme_nd_ns_fpi\fP. +.IP "dlfeat" 12 +Deallocate Logical Block Features, see \fIenum nvme_id_ns_dlfeat\fP. +.IP "nawun" 12 +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. +.IP "nawupf" 12 +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. +.IP "nacwu" 12 +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. +.IP "nabsn" 12 +Namespace Atomic Boundary Size Normal indicates the atomic +boundary size for this namespace for the NAWUN value. This field +is specified in logical blocks. +.IP "nabo" 12 +Namespace Atomic Boundary Offset indicates the LBA on this +namespace where the first atomic boundary starts. +.IP "nabspf" 12 +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. +.IP "noiob" 12 +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. +.IP "nvmcap" 12 +NVM Capacity indicates the total size of the NVM allocated to +this namespace. The value is in bytes. +.IP "npwg" 12 +Namespace Preferred Write Granularity indicates the smallest +recommended write granularity in logical blocks for this +namespace. This is a 0's based value. +.IP "npwa" 12 +Namespace Preferred Write Alignment indicates the recommended +write alignment in logical blocks for this namespace. This is a +0's based value. +.IP "npdg" 12 +Namespace Preferred Deallocate Granularity indicates the +recommended granularity in logical blocks for the Dataset +Management command with the Attribute - Deallocate bit. +.IP "npda" 12 +Namespace Preferred Deallocate Alignment indicates the +recommended alignment in logical blocks for the Dataset +Management command with the Attribute - Deallocate bit +.IP "nows" 12 +Namespace Optimal Write Size indicates the size in logical blocks +for optimal write performance for this namespace. This is a 0's +based value. +.IP "anagrpid" 12 +ANA Group Identifier indicates the ANA Group Identifier of the +ANA group of which the namespace is a member. +.IP "nsattr" 12 +Namespace Attributes, see \fIenum nvme_id_ns_attr\fP. +.IP "nvmsetid" 12 +NVM Set Identifier indicates the NVM Set with which this +namespace is associated. +.IP "endgid" 12 +Endurance Group Identifier indicates the Endurance Group with +which this namespace is associated. +.IP "nguid" 12 +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 +.IP "eui64" 12 +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 +remains fixed throughout the life of the namespace and is +preserved across namespace and controller operations +.IP "lbaf" 12 +LBA Format, see \fIstruct nvme_lbaf\fP. +.IP "vs" 12 +Vendor Specific diff --git a/doc/man/struct nvme_id_ns_granularity_desc.2 b/doc/man/struct nvme_id_ns_granularity_desc.2 new file mode 100644 index 0000000000..7f099ed5a0 --- /dev/null +++ b/doc/man/struct nvme_id_ns_granularity_desc.2 @@ -0,0 +1,15 @@ +.TH "libnvme" 2 "struct nvme_id_ns_granularity_desc" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_id_ns_granularity_desc \- +.SH SYNOPSIS +struct nvme_id_ns_granularity_desc { +.br +.BI " __le64 namespace_size_granularity;" +.br +.BI " __le64 namespace_capacity_granularity;" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_id_ns_granularity_list.2 b/doc/man/struct nvme_id_ns_granularity_list.2 new file mode 100644 index 0000000000..d0ca8b99a9 --- /dev/null +++ b/doc/man/struct nvme_id_ns_granularity_list.2 @@ -0,0 +1,21 @@ +.TH "libnvme" 2 "struct nvme_id_ns_granularity_list" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_id_ns_granularity_list \- +.SH SYNOPSIS +struct nvme_id_ns_granularity_list { +.br +.BI " __le32 attributes;" +.br +.BI " __u8 num_descriptors;" +.br +.BI " __u8 rsvd[27];" +.br +.BI " struct nvme_id_ns_granularity_desc entry[NVME_ID_ND_DESCRIPTOR_MAX];" +.br +.BI " __u8 rsvd288[3808];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_id_nvmset_list.2 b/doc/man/struct nvme_id_nvmset_list.2 new file mode 100644 index 0000000000..6a9dc4a20a --- /dev/null +++ b/doc/man/struct nvme_id_nvmset_list.2 @@ -0,0 +1,19 @@ +.TH "libnvme" 2 "struct nvme_id_nvmset_list" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_id_nvmset_list \- @nid; +.SH SYNOPSIS +struct nvme_id_nvmset_list { +.br +.BI " __u8 nid;" +.br +.BI " __u8 rsvd1[127];" +.br +.BI " struct nvme_nvmset_attr ent[NVME_ID_NVMSET_LIST_MAX];" +.br +.BI " +}; +.br + +.SH Members +.IP "ent" 12 +; diff --git a/doc/man/struct nvme_id_psd.2 b/doc/man/struct nvme_id_psd.2 new file mode 100644 index 0000000000..d990aeb9e3 --- /dev/null +++ b/doc/man/struct nvme_id_psd.2 @@ -0,0 +1,92 @@ +.TH "libnvme" 2 "struct nvme_id_psd" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_id_psd \- +.SH SYNOPSIS +struct nvme_id_psd { +.br +.BI " __le16 mp;" +.br +.BI " __u8 rsvd2;" +.br +.BI " __u8 flags;" +.br +.BI " __le32 enlat;" +.br +.BI " __le32 exlat;" +.br +.BI " __u8 rrt;" +.br +.BI " __u8 rrl;" +.br +.BI " __u8 rwt;" +.br +.BI " __u8 rwl;" +.br +.BI " __le16 idlp;" +.br +.BI " __u8 ips;" +.br +.BI " __u8 rsvd19;" +.br +.BI " __le16 actp;" +.br +.BI " __u8 apw;" +.br +.BI " __u8 aps;" +.br +.BI " __u8 rsvd23[8];" +.br +.BI " +}; +.br + +.SH Members +.IP "mp" 12 +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 \fIenum nvme_psd_flags\fP). A value of 0 indicates +Maximum Power is not reported. +.IP "flags" 12 +Additional decoding flags, see \fIenum nvme_psd_flags\fP. +.IP "enlat" 12 +Entry Latency indicates the maximum latency in microseconds +associated with entering this power state. A value of 0 indicates +Entry Latency is not reported. +.IP "exlat" 12 +Exit Latency indicates the maximum latency in microseconds +associated with exiting this power state. A value of 0 indicates +Exit Latency is not reported. +.IP "rrt" 12 +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. +.IP "rrl" 12 +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. +.IP "rwt" 12 +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 +.IP "rwl" 12 +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 +.IP "idlp" 12 +Idle Power indicates the typical power consumed by the NVM +subsystem over 30 seconds in this power state when idle. +.IP "ips" 12 +Idle Power Scale indicates the scale for \fIstruct nvme_id_psd\fP.idlp, +see \fIenum nvme_psd_ps\fP for decoding this field. +.IP "actp" 12 +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. +.IP "apw" 12 +Active Power Workload indicates the workload used to calculate +maximum power for this power state. See \fIenum nvme_psd_workload\fP for +decoding this field. +.IP "aps" 12 +Active Power Scale indicates the scale for the \fIstruct +nvme_id_psd\fP.actp, see \fIenum nvme_psd_ps\fP for decoding this value. diff --git a/doc/man/struct nvme_id_uuid_list.2 b/doc/man/struct nvme_id_uuid_list.2 new file mode 100644 index 0000000000..75f2f917a8 --- /dev/null +++ b/doc/man/struct nvme_id_uuid_list.2 @@ -0,0 +1,15 @@ +.TH "libnvme" 2 "struct nvme_id_uuid_list" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_id_uuid_list \- +.SH SYNOPSIS +struct nvme_id_uuid_list { +.br +.BI " __u8 rsvd0[32];" +.br +.BI " struct nvme_id_uuid_list_entry entry[NVME_ID_UUID_LIST_MAX];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_id_uuid_list_entry.2 b/doc/man/struct nvme_id_uuid_list_entry.2 new file mode 100644 index 0000000000..e8d80ac756 --- /dev/null +++ b/doc/man/struct nvme_id_uuid_list_entry.2 @@ -0,0 +1,17 @@ +.TH "libnvme" 2 "struct nvme_id_uuid_list_entry" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_id_uuid_list_entry \- +.SH SYNOPSIS +struct nvme_id_uuid_list_entry { +.br +.BI " __u8 header;" +.br +.BI " __u8 rsvd1[15];" +.br +.BI " __u8 uuid[16];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_lba_range_type.2 b/doc/man/struct nvme_lba_range_type.2 new file mode 100644 index 0000000000..ec4d3da3e4 --- /dev/null +++ b/doc/man/struct nvme_lba_range_type.2 @@ -0,0 +1,13 @@ +.TH "libnvme" 2 "struct nvme_lba_range_type" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_lba_range_type \- +.SH SYNOPSIS +struct nvme_lba_range_type { +.br +.BI " struct nvme_lba_range_type_entry entry[NVME_FEAT_LBA_RANGE_MAX];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_lba_range_type_entry.2 b/doc/man/struct nvme_lba_range_type_entry.2 new file mode 100644 index 0000000000..f1cecdc9be --- /dev/null +++ b/doc/man/struct nvme_lba_range_type_entry.2 @@ -0,0 +1,25 @@ +.TH "libnvme" 2 "struct nvme_lba_range_type_entry" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_lba_range_type_entry \- +.SH SYNOPSIS +struct nvme_lba_range_type_entry { +.br +.BI " __u8 type;" +.br +.BI " __u8 attributes;" +.br +.BI " __u8 rsvd2[14];" +.br +.BI " __u64 slba;" +.br +.BI " __u64 nlb;" +.br +.BI " __u8 guid[16];" +.br +.BI " __u8 rsvd48[16];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_lba_rd.2 b/doc/man/struct nvme_lba_rd.2 new file mode 100644 index 0000000000..3aec3a5f18 --- /dev/null +++ b/doc/man/struct nvme_lba_rd.2 @@ -0,0 +1,17 @@ +.TH "libnvme" 2 "struct nvme_lba_rd" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_lba_rd \- +.SH SYNOPSIS +struct nvme_lba_rd { +.br +.BI " __le64 rslba;" +.br +.BI " __le32 rnlb;" +.br +.BI " __u8 rsvd12[4];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_lba_status.2 b/doc/man/struct nvme_lba_status.2 new file mode 100644 index 0000000000..7223af3074 --- /dev/null +++ b/doc/man/struct nvme_lba_status.2 @@ -0,0 +1,19 @@ +.TH "libnvme" 2 "struct nvme_lba_status" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_lba_status \- +.SH SYNOPSIS +struct nvme_lba_status { +.br +.BI " __le32 nlsd;" +.br +.BI " __u8 cmpc;" +.br +.BI " __u8 rsvd5[3];" +.br +.BI " struct nvme_lba_status_desc descs[];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_lba_status_desc.2 b/doc/man/struct nvme_lba_status_desc.2 new file mode 100644 index 0000000000..81973bf072 --- /dev/null +++ b/doc/man/struct nvme_lba_status_desc.2 @@ -0,0 +1,21 @@ +.TH "libnvme" 2 "struct nvme_lba_status_desc" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_lba_status_desc \- +.SH SYNOPSIS +struct nvme_lba_status_desc { +.br +.BI " __le64 dslba;" +.br +.BI " __le32 nlb;" +.br +.BI " __u8 rsvd12;" +.br +.BI " __u8 status;" +.br +.BI " __u8 rsvd14[2];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_lba_status_log.2 b/doc/man/struct nvme_lba_status_log.2 new file mode 100644 index 0000000000..32b53913f7 --- /dev/null +++ b/doc/man/struct nvme_lba_status_log.2 @@ -0,0 +1,23 @@ +.TH "libnvme" 2 "struct nvme_lba_status_log" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_lba_status_log \- +.SH SYNOPSIS +struct nvme_lba_status_log { +.br +.BI " __le32 lslplen;" +.br +.BI " __le32 nlslne;" +.br +.BI " __le32 estulb;" +.br +.BI " __u8 rsvd12[2];" +.br +.BI " __le16 lsgc;" +.br +.BI " struct nvme_lbas_ns_element elements[];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_lbaf.2 b/doc/man/struct nvme_lbaf.2 new file mode 100644 index 0000000000..7518de0035 --- /dev/null +++ b/doc/man/struct nvme_lbaf.2 @@ -0,0 +1,25 @@ +.TH "libnvme" 2 "struct nvme_lbaf" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_lbaf \- LBA Format Data Structure +.SH SYNOPSIS +struct nvme_lbaf { +.br +.BI " __le16 ms;" +.br +.BI " __u8 ds;" +.br +.BI " __u8 rp;" +.br +.BI " +}; +.br + +.SH Members +.IP "ms" 12 +Metadata Size indicates the number of metadata bytes provided per LBA +based on the LBA Data Size indicated. +.IP "ds" 12 +LBA Data Size indicates the LBA data size supported, reported as a +power of two. +.IP "rp" 12 +Relative Performance, see \fIenum nvme_lbaf_rp\fP. diff --git a/doc/man/struct nvme_lbas_ns_element.2 b/doc/man/struct nvme_lbas_ns_element.2 new file mode 100644 index 0000000000..005360628d --- /dev/null +++ b/doc/man/struct nvme_lbas_ns_element.2 @@ -0,0 +1,21 @@ +.TH "libnvme" 2 "struct nvme_lbas_ns_element" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_lbas_ns_element \- +.SH SYNOPSIS +struct nvme_lbas_ns_element { +.br +.BI " __le32 neid;" +.br +.BI " __le32 nrld;" +.br +.BI " __u8 ratype;" +.br +.BI " __u8 rsvd8[7];" +.br +.BI " struct nvme_lba_rd lba_rd[];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_mi_ctrl_heal_status.2 b/doc/man/struct nvme_mi_ctrl_heal_status.2 new file mode 100644 index 0000000000..97be2653c1 --- /dev/null +++ b/doc/man/struct nvme_mi_ctrl_heal_status.2 @@ -0,0 +1,25 @@ +.TH "libnvme" 2 "struct nvme_mi_ctrl_heal_status" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_mi_ctrl_heal_status \- +.SH SYNOPSIS +struct nvme_mi_ctrl_heal_status { +.br +.BI " __le16 ctlid;" +.br +.BI " __le16 csts;" +.br +.BI " __le16 ctemp;" +.br +.BI " __u8 pdlu;" +.br +.BI " __u8 spare;" +.br +.BI " __u8 cwarn;" +.br +.BI " __u8 rsvd9[7];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_mi_nvm_ss_health_status.2 b/doc/man/struct nvme_mi_nvm_ss_health_status.2 new file mode 100644 index 0000000000..60c8fc92ce --- /dev/null +++ b/doc/man/struct nvme_mi_nvm_ss_health_status.2 @@ -0,0 +1,23 @@ +.TH "libnvme" 2 "struct nvme_mi_nvm_ss_health_status" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_mi_nvm_ss_health_status \- +.SH SYNOPSIS +struct nvme_mi_nvm_ss_health_status { +.br +.BI " __u8 nss;" +.br +.BI " __u8 sw;" +.br +.BI " __u8 ctemp;" +.br +.BI " __u8 pdlu;" +.br +.BI " __le16 ccs;" +.br +.BI " __u8 rsvd8[2];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_mi_osc.2 b/doc/man/struct nvme_mi_osc.2 new file mode 100644 index 0000000000..b8a9b6a1be --- /dev/null +++ b/doc/man/struct nvme_mi_osc.2 @@ -0,0 +1,15 @@ +.TH "libnvme" 2 "struct nvme_mi_osc" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_mi_osc \- @type; @opc; +.SH SYNOPSIS +struct nvme_mi_osc { +.br +.BI " __u8 type;" +.br +.BI " __u8 opc;" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_mi_port_pcie.2 b/doc/man/struct nvme_mi_port_pcie.2 new file mode 100644 index 0000000000..5a57f97219 --- /dev/null +++ b/doc/man/struct nvme_mi_port_pcie.2 @@ -0,0 +1,25 @@ +.TH "libnvme" 2 "struct nvme_mi_port_pcie" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_mi_port_pcie \- +.SH SYNOPSIS +struct nvme_mi_port_pcie { +.br +.BI " __u8 mps;" +.br +.BI " __u8 sls;" +.br +.BI " __u8 cls;" +.br +.BI " __u8 mlw;" +.br +.BI " __u8 nlw;" +.br +.BI " __u8 pn;" +.br +.BI " __u8 rsvd14[18];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_mi_port_smb.2 b/doc/man/struct nvme_mi_port_smb.2 new file mode 100644 index 0000000000..d6ec195fbb --- /dev/null +++ b/doc/man/struct nvme_mi_port_smb.2 @@ -0,0 +1,23 @@ +.TH "libnvme" 2 "struct nvme_mi_port_smb" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_mi_port_smb \- +.SH SYNOPSIS +struct nvme_mi_port_smb { +.br +.BI " __u8 vpd_addr;" +.br +.BI " __u8 mvpd_freq;" +.br +.BI " __u8 mme_addr;" +.br +.BI " __u8 mme_freq;" +.br +.BI " __u8 nvmebm;" +.br +.BI " __u8 rsvd13[19];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_mi_read_ctrl_info.2 b/doc/man/struct nvme_mi_read_ctrl_info.2 new file mode 100644 index 0000000000..baa8497e5c --- /dev/null +++ b/doc/man/struct nvme_mi_read_ctrl_info.2 @@ -0,0 +1,29 @@ +.TH "libnvme" 2 "struct nvme_mi_read_ctrl_info" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_mi_read_ctrl_info \- @portid; @prii; @pri; @vid; @did; @ssvid; @ssid; +.SH SYNOPSIS +struct nvme_mi_read_ctrl_info { +.br +.BI " __u8 portid;" +.br +.BI " __u8 rsvd1[4];" +.br +.BI " __u8 prii;" +.br +.BI " __le16 pri;" +.br +.BI " __le16 vid;" +.br +.BI " __le16 did;" +.br +.BI " __le16 ssvid;" +.br +.BI " __le16 ssid;" +.br +.BI " __u8 rsvd16[16];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_mi_read_nvm_ss_info.2 b/doc/man/struct nvme_mi_read_nvm_ss_info.2 new file mode 100644 index 0000000000..2883b615a5 --- /dev/null +++ b/doc/man/struct nvme_mi_read_nvm_ss_info.2 @@ -0,0 +1,19 @@ +.TH "libnvme" 2 "struct nvme_mi_read_nvm_ss_info" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_mi_read_nvm_ss_info \- +.SH SYNOPSIS +struct nvme_mi_read_nvm_ss_info { +.br +.BI " __u8 nump;" +.br +.BI " __u8 mjr;" +.br +.BI " __u8 mnr;" +.br +.BI " __u8 rsvd3[29];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_mi_read_port_info.2 b/doc/man/struct nvme_mi_read_port_info.2 new file mode 100644 index 0000000000..fba36f9343 --- /dev/null +++ b/doc/man/struct nvme_mi_read_port_info.2 @@ -0,0 +1,31 @@ +.TH "libnvme" 2 "struct nvme_mi_read_port_info" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_mi_read_port_info \- +.SH SYNOPSIS +struct nvme_mi_read_port_info { +.br +.BI " __u8 portt;" +.br +.BI " __u8 rsvd1;" +.br +.BI " __le16 mmctptus;" +.br +.BI " __le32 meb;" +.br +.BI " union {" +.br +.BI " struct nvme_mi_port_pcie pcie;" +.br +.BI " struct nvme_mi_port_smb smb;" +.br +.BI " };" +.br +.BI " +}; +.br + +.SH Members +.IP "portt" 12 +\fImmctptus\fP; +.IP "{unnamed_union}" 12 +anonymous diff --git a/doc/man/struct nvme_mi_read_sc_list.2 b/doc/man/struct nvme_mi_read_sc_list.2 new file mode 100644 index 0000000000..7b0b924b91 --- /dev/null +++ b/doc/man/struct nvme_mi_read_sc_list.2 @@ -0,0 +1,15 @@ +.TH "libnvme" 2 "struct nvme_mi_read_sc_list" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_mi_read_sc_list \- +.SH SYNOPSIS +struct nvme_mi_read_sc_list { +.br +.BI " __le16 numcmd;" +.br +.BI " struct nvme_mi_osc cmds[];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_mi_vpd_hdr.2 b/doc/man/struct nvme_mi_vpd_hdr.2 new file mode 100644 index 0000000000..d337d7c642 --- /dev/null +++ b/doc/man/struct nvme_mi_vpd_hdr.2 @@ -0,0 +1,29 @@ +.TH "libnvme" 2 "struct nvme_mi_vpd_hdr" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_mi_vpd_hdr \- +.SH SYNOPSIS +struct nvme_mi_vpd_hdr { +.br +.BI " __u8 ipmiver;" +.br +.BI " __u8 iuaoff;" +.br +.BI " __u8 ciaoff;" +.br +.BI " __u8 biaoff;" +.br +.BI " __u8 piaoff;" +.br +.BI " __u8 mrioff;" +.br +.BI " __u8 rsvd6;" +.br +.BI " __u8 chchk;" +.br +.BI " __u8 vpd[];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_mi_vpd_mr_common.2 b/doc/man/struct nvme_mi_vpd_mr_common.2 new file mode 100644 index 0000000000..e1dbe16e0e --- /dev/null +++ b/doc/man/struct nvme_mi_vpd_mr_common.2 @@ -0,0 +1,33 @@ +.TH "libnvme" 2 "struct nvme_mi_vpd_mr_common" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_mi_vpd_mr_common \- @type; @rf; @rlen; @rchksum; @hchksum; @ppmra; @tmra; +.SH SYNOPSIS +struct nvme_mi_vpd_mr_common { +.br +.BI " __u8 type;" +.br +.BI " __u8 rf;" +.br +.BI " __u8 rlen;" +.br +.BI " __u8 rchksum;" +.br +.BI " __u8 hchksum;" +.br +.BI " union {" +.br +.BI " struct nvme_mi_vpd_mra nmra;" +.br +.BI " struct nvme_mi_vpd_ppmra ppmra;" +.br +.BI " struct nvme_mi_vpd_tra tmra;" +.br +.BI " };" +.br +.BI " +}; +.br + +.SH Members +.IP "{unnamed_union}" 12 +anonymous diff --git a/doc/man/struct nvme_mi_vpd_mra.2 b/doc/man/struct nvme_mi_vpd_mra.2 new file mode 100644 index 0000000000..185a6af7de --- /dev/null +++ b/doc/man/struct nvme_mi_vpd_mra.2 @@ -0,0 +1,43 @@ +.TH "libnvme" 2 "struct nvme_mi_vpd_mra" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_mi_vpd_mra \- @nmravn; @ff; @i18vpwr; @m18vpwr; @i33vpwr; @m33vpwr; @m33vapsr; @i5vapsr; @m5vapsr; @i12vapsr; @m12vapsr; @mtl; @tnvmcap[16]; +.SH SYNOPSIS +struct nvme_mi_vpd_mra { +.br +.BI " __u8 nmravn;" +.br +.BI " __u8 ff;" +.br +.BI " __u8 rsvd7[6];" +.br +.BI " __u8 i18vpwr;" +.br +.BI " __u8 m18vpwr;" +.br +.BI " __u8 i33vpwr;" +.br +.BI " __u8 m33vpwr;" +.br +.BI " __u8 rsvd17;" +.br +.BI " __u8 m33vapsr;" +.br +.BI " __u8 i5vapsr;" +.br +.BI " __u8 m5vapsr;" +.br +.BI " __u8 i12vapsr;" +.br +.BI " __u8 m12vapsr;" +.br +.BI " __u8 mtl;" +.br +.BI " __u8 tnvmcap[16];" +.br +.BI " __u8 rsvd37[27];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_mi_vpd_ppmra.2 b/doc/man/struct nvme_mi_vpd_ppmra.2 new file mode 100644 index 0000000000..3d1a4ebbd4 --- /dev/null +++ b/doc/man/struct nvme_mi_vpd_ppmra.2 @@ -0,0 +1,29 @@ +.TH "libnvme" 2 "struct nvme_mi_vpd_ppmra" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_mi_vpd_ppmra \- +.SH SYNOPSIS +struct nvme_mi_vpd_ppmra { +.br +.BI " __u8 nppmravn;" +.br +.BI " __u8 pn;" +.br +.BI " __u8 ppi;" +.br +.BI " __u8 ls;" +.br +.BI " __u8 mlw;" +.br +.BI " __u8 mctp;" +.br +.BI " __u8 refccap;" +.br +.BI " __u8 pi;" +.br +.BI " __u8 rsvd13[3];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_mi_vpd_telem.2 b/doc/man/struct nvme_mi_vpd_telem.2 new file mode 100644 index 0000000000..7d26464efe --- /dev/null +++ b/doc/man/struct nvme_mi_vpd_telem.2 @@ -0,0 +1,19 @@ +.TH "libnvme" 2 "struct nvme_mi_vpd_telem" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_mi_vpd_telem \- +.SH SYNOPSIS +struct nvme_mi_vpd_telem { +.br +.BI " __u8 type;" +.br +.BI " __u8 rev;" +.br +.BI " __u8 len;" +.br +.BI " __u8 data[0];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_mi_vpd_tra.2 b/doc/man/struct nvme_mi_vpd_tra.2 new file mode 100644 index 0000000000..bb59331589 --- /dev/null +++ b/doc/man/struct nvme_mi_vpd_tra.2 @@ -0,0 +1,19 @@ +.TH "libnvme" 2 "struct nvme_mi_vpd_tra" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_mi_vpd_tra \- +.SH SYNOPSIS +struct nvme_mi_vpd_tra { +.br +.BI " __u8 vn;" +.br +.BI " __u8 rsvd6;" +.br +.BI " __u8 ec;" +.br +.BI " struct nvme_mi_vpd_telem elems[0];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_ns_id_desc.2 b/doc/man/struct nvme_ns_id_desc.2 new file mode 100644 index 0000000000..b743b584ac --- /dev/null +++ b/doc/man/struct nvme_ns_id_desc.2 @@ -0,0 +1,28 @@ +.TH "libnvme" 2 "struct nvme_ns_id_desc" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_ns_id_desc \- +.SH SYNOPSIS +struct nvme_ns_id_desc { +.br +.BI " __u8 nidt;" +.br +.BI " __u8 nidl;" +.br +.BI " __le16 reserved;" +.br +.BI " __u8 nid[];" +.br +.BI " +}; +.br + +.SH Members +.IP "nidt" 12 +Namespace Identifier Type, see \fIenum nvme_ns_id_desc_nidt\fP +.IP "nidl" 12 +Namespace Identifier Length contains the length in bytes of the +\fIstruct nvme_id_ns\fP.nid. +.IP "nid" 12 +Namespace Identifier contains a value that is globally unique and +assigned to the namespace when the namespace is created. The length +is defined in \fIstruct nvme_id_ns\fP.nidl. diff --git a/doc/man/struct nvme_ns_list.2 b/doc/man/struct nvme_ns_list.2 new file mode 100644 index 0000000000..505f904199 --- /dev/null +++ b/doc/man/struct nvme_ns_list.2 @@ -0,0 +1,13 @@ +.TH "libnvme" 2 "struct nvme_ns_list" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_ns_list \- +.SH SYNOPSIS +struct nvme_ns_list { +.br +.BI " __le32 ns[NVME_ID_NS_LIST_MAX];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_nvmset_attr.2 b/doc/man/struct nvme_nvmset_attr.2 new file mode 100644 index 0000000000..6054d067e2 --- /dev/null +++ b/doc/man/struct nvme_nvmset_attr.2 @@ -0,0 +1,37 @@ +.TH "libnvme" 2 "struct nvme_nvmset_attr" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_nvmset_attr \- NVM Set Attributes Entry +.SH SYNOPSIS +struct nvme_nvmset_attr { +.br +.BI " __le16 id;" +.br +.BI " __le16 endurance_group_id;" +.br +.BI " __u8 rsvd4[4];" +.br +.BI " __le32 random_4k_read_typical;" +.br +.BI " __le32 opt_write_size;" +.br +.BI " __u8 total_nvmset_cap[16];" +.br +.BI " __u8 unalloc_nvmset_cap[16];" +.br +.BI " __u8 rsvd48[80];" +.br +.BI " +}; +.br + +.SH Members +.IP "id" 12 +NVM Set Identifier +.IP "endurance_group_id" 12 +Endurance Group Identifier +.IP "random_4k_read_typical" 12 +Random 4 KiB Read Typical indicates the typical +time to complete a 4 KiB random read in 100 +nanosecond units when the NVM Set is in a +Predictable Latency Mode Deterministic Window and +there is 1 outstanding command per NVM Set. diff --git a/doc/man/struct nvme_nvmset_predictable_lat_log.2 b/doc/man/struct nvme_nvmset_predictable_lat_log.2 new file mode 100644 index 0000000000..1819b1c44f --- /dev/null +++ b/doc/man/struct nvme_nvmset_predictable_lat_log.2 @@ -0,0 +1,39 @@ +.TH "libnvme" 2 "struct nvme_nvmset_predictable_lat_log" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_nvmset_predictable_lat_log \- +.SH SYNOPSIS +struct nvme_nvmset_predictable_lat_log { +.br +.BI " __u8 status;" +.br +.BI " __u8 rsvd1;" +.br +.BI " __le16 event_type;" +.br +.BI " __u8 rsvd4[28];" +.br +.BI " __le64 dtwin_rt;" +.br +.BI " __le64 dtwin_wt;" +.br +.BI " __le64 dtwin_tmax;" +.br +.BI " __le64 dtwin_tmin_hi;" +.br +.BI " __le64 dtwin_tmin_lo;" +.br +.BI " __u8 rsvd72[56];" +.br +.BI " __le64 dtwin_re;" +.br +.BI " __le64 dtwin_we;" +.br +.BI " __le64 dtwin_te;" +.br +.BI " __u8 rsvd152[360];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_passthru_cmd.2 b/doc/man/struct nvme_passthru_cmd.2 new file mode 100644 index 0000000000..b76b9c501e --- /dev/null +++ b/doc/man/struct nvme_passthru_cmd.2 @@ -0,0 +1,83 @@ +.TH "libnvme" 2 "struct nvme_passthru_cmd" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_passthru_cmd \- +.SH SYNOPSIS +struct nvme_passthru_cmd { +.br +.BI " __u8 opcode;" +.br +.BI " __u8 flags;" +.br +.BI " __u16 rsvd1;" +.br +.BI " __u32 nsid;" +.br +.BI " __u32 cdw2;" +.br +.BI " __u32 cdw3;" +.br +.BI " __u64 metadata;" +.br +.BI " __u64 addr;" +.br +.BI " __u32 metadata_len;" +.br +.BI " __u32 data_len;" +.br +.BI " __u32 cdw10;" +.br +.BI " __u32 cdw11;" +.br +.BI " __u32 cdw12;" +.br +.BI " __u32 cdw13;" +.br +.BI " __u32 cdw14;" +.br +.BI " __u32 cdw15;" +.br +.BI " __u32 timeout_ms;" +.br +.BI " __u32 result;" +.br +.BI " +}; +.br + +.SH Members +.IP "opcode" 12 +Operation code, see \fIenum nvme_io_opcodes\fP and \fIenum nvme_admin_opcodes\fP +.IP "flags" 12 +Not supported: intended for command flags (eg: SGL, FUSE) +.IP "rsvd1" 12 +Reserved for future use +.IP "nsid" 12 +Namespace Identifier, or Fabrics type +.IP "cdw2" 12 +Command Dword 2 (no spec defined use) +.IP "cdw3" 12 +Command Dword 3 (no spec defined use) +.IP "metadata" 12 +User space address to metadata buffer (NULL if not used) +.IP "addr" 12 +User space address to data buffer (NULL if not used) +.IP "metadata_len" 12 +Metadata buffer transfer length +.IP "data_len" 12 +Data buffer transfer length +.IP "cdw10" 12 +Command Dword 10 (command specific) +.IP "cdw11" 12 +Command Dword 11 (command specific) +.IP "cdw12" 12 +Command Dword 12 (command specific) +.IP "cdw13" 12 +Command Dword 13 (command specific) +.IP "cdw14" 12 +Command Dword 14 (command specific) +.IP "cdw15" 12 +Command Dword 15 (command specific) +.IP "timeout_ms" 12 +If non-zero, overrides system default timeout in milliseconds +.IP "result" 12 +Set on completion to the command's CQE DWORD 0 controller response diff --git a/doc/man/struct nvme_passthru_cmd64.2 b/doc/man/struct nvme_passthru_cmd64.2 new file mode 100644 index 0000000000..dd56d9a01c --- /dev/null +++ b/doc/man/struct nvme_passthru_cmd64.2 @@ -0,0 +1,87 @@ +.TH "libnvme" 2 "struct nvme_passthru_cmd64" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_passthru_cmd64 \- +.SH SYNOPSIS +struct nvme_passthru_cmd64 { +.br +.BI " __u8 opcode;" +.br +.BI " __u8 flags;" +.br +.BI " __u16 rsvd1;" +.br +.BI " __u32 nsid;" +.br +.BI " __u32 cdw2;" +.br +.BI " __u32 cdw3;" +.br +.BI " __u64 metadata;" +.br +.BI " __u64 addr;" +.br +.BI " __u32 metadata_len;" +.br +.BI " __u32 data_len;" +.br +.BI " __u32 cdw10;" +.br +.BI " __u32 cdw11;" +.br +.BI " __u32 cdw12;" +.br +.BI " __u32 cdw13;" +.br +.BI " __u32 cdw14;" +.br +.BI " __u32 cdw15;" +.br +.BI " __u32 timeout_ms;" +.br +.BI " __u32 rsvd2;" +.br +.BI " __u64 result;" +.br +.BI " +}; +.br + +.SH Members +.IP "opcode" 12 +Operation code, see \fIenum nvme_io_opcodes\fP and \fIenum nvme_admin_opcodes\fP +.IP "flags" 12 +Not supported: intended for command flags (eg: SGL, FUSE) +.IP "rsvd1" 12 +Reserved for future use +.IP "nsid" 12 +Namespace Identifier, or Fabrics type +.IP "cdw2" 12 +Command Dword 2 (no spec defined use) +.IP "cdw3" 12 +Command Dword 3 (no spec defined use) +.IP "metadata" 12 +User space address to metadata buffer (NULL if not used) +.IP "addr" 12 +User space address to data buffer (NULL if not used) +.IP "metadata_len" 12 +Metadata buffer transfer length +.IP "data_len" 12 +Data buffer transfer length +.IP "cdw10" 12 +Command Dword 10 (command specific) +.IP "cdw11" 12 +Command Dword 11 (command specific) +.IP "cdw12" 12 +Command Dword 12 (command specific) +.IP "cdw13" 12 +Command Dword 13 (command specific) +.IP "cdw14" 12 +Command Dword 14 (command specific) +.IP "cdw15" 12 +Command Dword 15 (command specific) +.IP "timeout_ms" 12 +If non-zero, overrides system default timeout in milliseconds +.IP "rsvd2" 12 +Reserved for future use (and fills an impicit struct pad +.IP "result" 12 +Set on completion to the command's CQE DWORD 0-1 controller response diff --git a/doc/man/struct nvme_persistent_event_log.2 b/doc/man/struct nvme_persistent_event_log.2 new file mode 100644 index 0000000000..2d9bb47522 --- /dev/null +++ b/doc/man/struct nvme_persistent_event_log.2 @@ -0,0 +1,43 @@ +.TH "libnvme" 2 "struct nvme_persistent_event_log" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_persistent_event_log \- +.SH SYNOPSIS +struct nvme_persistent_event_log { +.br +.BI " __u8 lid;" +.br +.BI " __u8 rsvd1[3];" +.br +.BI " __le32 ttl;" +.br +.BI " __u8 rv;" +.br +.BI " __u8 rsvd17;" +.br +.BI " __le16 lht;" +.br +.BI " __le64 ts;" +.br +.BI " __u8 poh[16];" +.br +.BI " __le64 pcc;" +.br +.BI " __le16 vid;" +.br +.BI " __le16 ssvid;" +.br +.BI " char sn[20];" +.br +.BI " char mn[40];" +.br +.BI " char subnqn[256];" +.br +.BI " __u8 rsvd372;" +.br +.BI " __u8 seb[32];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_plm_config.2 b/doc/man/struct nvme_plm_config.2 new file mode 100644 index 0000000000..f322ff5c03 --- /dev/null +++ b/doc/man/struct nvme_plm_config.2 @@ -0,0 +1,23 @@ +.TH "libnvme" 2 "struct nvme_plm_config" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_plm_config \- @ee; @dtwinrt; @dtwinwt; @dtwintt; +.SH SYNOPSIS +struct nvme_plm_config { +.br +.BI " __le16 ee;" +.br +.BI " __u8 rsvd2[30];" +.br +.BI " __le64 dtwinrt;" +.br +.BI " __le64 dtwinwt;" +.br +.BI " __le64 dtwintt;" +.br +.BI " __u8 rsvd56[456];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_primary_ctrl_cap.2 b/doc/man/struct nvme_primary_ctrl_cap.2 new file mode 100644 index 0000000000..18f2113f23 --- /dev/null +++ b/doc/man/struct nvme_primary_ctrl_cap.2 @@ -0,0 +1,47 @@ +.TH "libnvme" 2 "struct nvme_primary_ctrl_cap" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_primary_ctrl_cap \- +.SH SYNOPSIS +struct nvme_primary_ctrl_cap { +.br +.BI " __le16 cntlid;" +.br +.BI " __le16 portid;" +.br +.BI " __u8 crt;" +.br +.BI " __u8 rsvd5[27];" +.br +.BI " __le32 vqfrt;" +.br +.BI " __le32 vqrfa;" +.br +.BI " __le16 vqrfap;" +.br +.BI " __le16 vqprt;" +.br +.BI " __le16 vqfrsm;" +.br +.BI " __le16 vqgran;" +.br +.BI " __u8 rsvd48[16];" +.br +.BI " __le32 vifrt;" +.br +.BI " __le32 virfa;" +.br +.BI " __le16 virfap;" +.br +.BI " __le16 viprt;" +.br +.BI " __le16 vifrsm;" +.br +.BI " __le16 vigran;" +.br +.BI " __u8 rsvd80[4016];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_registered_ctrl.2 b/doc/man/struct nvme_registered_ctrl.2 new file mode 100644 index 0000000000..ff52acabd0 --- /dev/null +++ b/doc/man/struct nvme_registered_ctrl.2 @@ -0,0 +1,21 @@ +.TH "libnvme" 2 "struct nvme_registered_ctrl" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_registered_ctrl \- +.SH SYNOPSIS +struct nvme_registered_ctrl { +.br +.BI " __le16 cntlid;" +.br +.BI " __u8 rcsts;" +.br +.BI " __u8 rsvd3[5];" +.br +.BI " __le64 hostid;" +.br +.BI " __le64 rkey;" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_registered_ctrl_ext.2 b/doc/man/struct nvme_registered_ctrl_ext.2 new file mode 100644 index 0000000000..d686cd85fb --- /dev/null +++ b/doc/man/struct nvme_registered_ctrl_ext.2 @@ -0,0 +1,23 @@ +.TH "libnvme" 2 "struct nvme_registered_ctrl_ext" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_registered_ctrl_ext \- +.SH SYNOPSIS +struct nvme_registered_ctrl_ext { +.br +.BI " __le16 cntlid;" +.br +.BI " __u8 rcsts;" +.br +.BI " __u8 resv3[5];" +.br +.BI " __le64 rkey;" +.br +.BI " __u8 hostid[16];" +.br +.BI " __u8 resv32[32];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_reservation_status.2 b/doc/man/struct nvme_reservation_status.2 new file mode 100644 index 0000000000..02f877a2ea --- /dev/null +++ b/doc/man/struct nvme_reservation_status.2 @@ -0,0 +1,41 @@ +.TH "libnvme" 2 "struct nvme_reservation_status" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_reservation_status \- { +.SH SYNOPSIS +struct nvme_reservation_status { +.br +.BI " __le32 gen;" +.br +.BI " __u8 rtype;" +.br +.BI " __u8 regctl[2];" +.br +.BI " __u8 rsvd7[2];" +.br +.BI " __u8 ptpls;" +.br +.BI " __u8 rsvd10[14];" +.br +.BI " union {" +.br +.BI " struct {" +.br +.BI " __u8 resv24[40];" +.br +.BI " struct nvme_registered_ctrl_ext regctl_eds[0];" +.br +.BI " };" +.br +.BI " struct nvme_registered_ctrl regctl_ds[0];" +.br +.BI " };" +.br +.BI " +}; +.br + +.SH Members +.IP "{unnamed_union}" 12 +anonymous +.IP "{unnamed_struct}" 12 +anonymous diff --git a/doc/man/struct nvme_resv_notification_log.2 b/doc/man/struct nvme_resv_notification_log.2 new file mode 100644 index 0000000000..ecab19cbd1 --- /dev/null +++ b/doc/man/struct nvme_resv_notification_log.2 @@ -0,0 +1,23 @@ +.TH "libnvme" 2 "struct nvme_resv_notification_log" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_resv_notification_log \- +.SH SYNOPSIS +struct nvme_resv_notification_log { +.br +.BI " __le64 lpc;" +.br +.BI " __u8 rnlpt;" +.br +.BI " __u8 nalp;" +.br +.BI " __u8 rsvd9[2];" +.br +.BI " __le32 nsid;" +.br +.BI " __u8 rsvd16[48];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_sanitize_log_page.2 b/doc/man/struct nvme_sanitize_log_page.2 new file mode 100644 index 0000000000..09e523c19f --- /dev/null +++ b/doc/man/struct nvme_sanitize_log_page.2 @@ -0,0 +1,31 @@ +.TH "libnvme" 2 "struct nvme_sanitize_log_page" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_sanitize_log_page \- +.SH SYNOPSIS +struct nvme_sanitize_log_page { +.br +.BI " __le16 sprog;" +.br +.BI " __le16 sstat;" +.br +.BI " __le32 scdw10;" +.br +.BI " __le32 eto;" +.br +.BI " __le32 etbe;" +.br +.BI " __le32 etce;" +.br +.BI " __le32 etond;" +.br +.BI " __le32 etbend;" +.br +.BI " __le32 etcend;" +.br +.BI " __u8 rsvd32[480];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_secondary_ctrl.2 b/doc/man/struct nvme_secondary_ctrl.2 new file mode 100644 index 0000000000..c5c8163487 --- /dev/null +++ b/doc/man/struct nvme_secondary_ctrl.2 @@ -0,0 +1,27 @@ +.TH "libnvme" 2 "struct nvme_secondary_ctrl" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_secondary_ctrl \- +.SH SYNOPSIS +struct nvme_secondary_ctrl { +.br +.BI " __le16 scid;" +.br +.BI " __le16 pcid;" +.br +.BI " __u8 scs;" +.br +.BI " __u8 rsvd5[3];" +.br +.BI " __le16 vfn;" +.br +.BI " __le16 nvq;" +.br +.BI " __le16 nvi;" +.br +.BI " __u8 rsvd14[18];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_secondary_ctrl_list.2 b/doc/man/struct nvme_secondary_ctrl_list.2 new file mode 100644 index 0000000000..04e17eab04 --- /dev/null +++ b/doc/man/struct nvme_secondary_ctrl_list.2 @@ -0,0 +1,17 @@ +.TH "libnvme" 2 "struct nvme_secondary_ctrl_list" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_secondary_ctrl_list \- @num; +.SH SYNOPSIS +struct nvme_secondary_ctrl_list { +.br +.BI " __u8 num;" +.br +.BI " __u8 rsvd[31];" +.br +.BI " struct nvme_secondary_ctrl sc_entry[NVME_ID_SECONDARY_CTRL_MAX];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_self_test_log.2 b/doc/man/struct nvme_self_test_log.2 new file mode 100644 index 0000000000..677cd87323 --- /dev/null +++ b/doc/man/struct nvme_self_test_log.2 @@ -0,0 +1,19 @@ +.TH "libnvme" 2 "struct nvme_self_test_log" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_self_test_log \- +.SH SYNOPSIS +struct nvme_self_test_log { +.br +.BI " __u8 current_operation;" +.br +.BI " __u8 completion;" +.br +.BI " __u8 rsvd[2];" +.br +.BI " struct nvme_st_result result[NVME_LOG_ST_MAX_RESULTS];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_smart_log.2 b/doc/man/struct nvme_smart_log.2 new file mode 100644 index 0000000000..78dd11d788 --- /dev/null +++ b/doc/man/struct nvme_smart_log.2 @@ -0,0 +1,61 @@ +.TH "libnvme" 2 "struct nvme_smart_log" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_smart_log \- +.SH SYNOPSIS +struct nvme_smart_log { +.br +.BI " __u8 critical_warning;" +.br +.BI " __u8 temperature[2];" +.br +.BI " __u8 avail_spare;" +.br +.BI " __u8 spare_thresh;" +.br +.BI " __u8 percent_used;" +.br +.BI " __u8 endu_grp_crit_warn_sumry;" +.br +.BI " __u8 rsvd7[25];" +.br +.BI " __u8 data_units_read[16];" +.br +.BI " __u8 data_units_written[16];" +.br +.BI " __u8 host_reads[16];" +.br +.BI " __u8 host_writes[16];" +.br +.BI " __u8 ctrl_busy_time[16];" +.br +.BI " __u8 power_cycles[16];" +.br +.BI " __u8 power_on_hours[16];" +.br +.BI " __u8 unsafe_shutdowns[16];" +.br +.BI " __u8 media_errors[16];" +.br +.BI " __u8 num_err_log_entries[16];" +.br +.BI " __le32 warning_temp_time;" +.br +.BI " __le32 critical_comp_time;" +.br +.BI " __le16 temp_sensor[8];" +.br +.BI " __le32 thm_temp1_trans_count;" +.br +.BI " __le32 thm_temp2_trans_count;" +.br +.BI " __le32 thm_temp1_total_time;" +.br +.BI " __le32 thm_temp2_total_time;" +.br +.BI " __u8 rsvd232[280];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_st_result.2 b/doc/man/struct nvme_st_result.2 new file mode 100644 index 0000000000..afd33b203e --- /dev/null +++ b/doc/man/struct nvme_st_result.2 @@ -0,0 +1,31 @@ +.TH "libnvme" 2 "struct nvme_st_result" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_st_result \- +.SH SYNOPSIS +struct nvme_st_result { +.br +.BI " __u8 dsts;" +.br +.BI " __u8 seg;" +.br +.BI " __u8 vdi;" +.br +.BI " __u8 rsvd;" +.br +.BI " __le64 poh;" +.br +.BI " __le32 nsid;" +.br +.BI " __le64 flba;" +.br +.BI " __u8 sct;" +.br +.BI " __u8 sc;" +.br +.BI " __u8 vs[2];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_streams_directive_params.2 b/doc/man/struct nvme_streams_directive_params.2 new file mode 100644 index 0000000000..2f3edfbcbf --- /dev/null +++ b/doc/man/struct nvme_streams_directive_params.2 @@ -0,0 +1,31 @@ +.TH "libnvme" 2 "struct nvme_streams_directive_params" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_streams_directive_params \- +.SH SYNOPSIS +struct nvme_streams_directive_params { +.br +.BI " __le16 msl;" +.br +.BI " __le16 nssa;" +.br +.BI " __le16 nsso;" +.br +.BI " __u8 nssc;" +.br +.BI " __u8 rsvd[9];" +.br +.BI " __le32 sws;" +.br +.BI " __le16 sgs;" +.br +.BI " __le16 nsa;" +.br +.BI " __le16 nso;" +.br +.BI " __u8 rsvd2[6];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_streams_directive_status.2 b/doc/man/struct nvme_streams_directive_status.2 new file mode 100644 index 0000000000..af03551ab1 --- /dev/null +++ b/doc/man/struct nvme_streams_directive_status.2 @@ -0,0 +1,15 @@ +.TH "libnvme" 2 "struct nvme_streams_directive_status" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_streams_directive_status \- +.SH SYNOPSIS +struct nvme_streams_directive_status { +.br +.BI " __le16 osc;" +.br +.BI " __le16 sid[];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_telemetry_log.2 b/doc/man/struct nvme_telemetry_log.2 new file mode 100644 index 0000000000..6785c87aed --- /dev/null +++ b/doc/man/struct nvme_telemetry_log.2 @@ -0,0 +1,33 @@ +.TH "libnvme" 2 "struct nvme_telemetry_log" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_telemetry_log \- +.SH SYNOPSIS +struct nvme_telemetry_log { +.br +.BI " __u8 lpi;" +.br +.BI " __u8 rsvd[4];" +.br +.BI " __u8 ieee[3];" +.br +.BI " __le16 dalb1;" +.br +.BI " __le16 dalb2;" +.br +.BI " __le16 dalb3;" +.br +.BI " __u8 rsvd1[368];" +.br +.BI " __u8 ctrlavail;" +.br +.BI " __u8 ctrldgn;" +.br +.BI " __u8 rsnident[128];" +.br +.BI " __u8 telemetry_dataarea[];" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvme_timestamp.2 b/doc/man/struct nvme_timestamp.2 new file mode 100644 index 0000000000..cacee99951 --- /dev/null +++ b/doc/man/struct nvme_timestamp.2 @@ -0,0 +1,17 @@ +.TH "libnvme" 2 "struct nvme_timestamp" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvme_timestamp \- timestamp: +.SH SYNOPSIS +struct nvme_timestamp { +.br +.BI " __u8 timestamp[6];" +.br +.BI " __u8 attr;" +.br +.BI " __u8 rsvd;" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvmf_connect_data.2 b/doc/man/struct nvmf_connect_data.2 new file mode 100644 index 0000000000..9f2227c63f --- /dev/null +++ b/doc/man/struct nvmf_connect_data.2 @@ -0,0 +1,26 @@ +.TH "libnvme" 2 "struct nvmf_connect_data" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvmf_connect_data \- +.SH SYNOPSIS +struct nvmf_connect_data { +.br +.BI " __u8 hostid[16];" +.br +.BI " __le16 cntlid;" +.br +.BI " char resv4[238];" +.br +.BI " char subsysnqn[NVMF_NQN_FIELD_LEN];" +.br +.BI " char hostnqn[NVMF_NQN_FIELD_LEN];" +.br +.BI " char resv5[256];" +.br +.BI " +}; +.br + +.SH Members +.IP "cntlid" 12 +\fIsubsysnqn\fP +\fIhostnqn\fP diff --git a/doc/man/struct nvmf_disc_log_entry.2 b/doc/man/struct nvmf_disc_log_entry.2 new file mode 100644 index 0000000000..f1c2e461f1 --- /dev/null +++ b/doc/man/struct nvmf_disc_log_entry.2 @@ -0,0 +1,63 @@ +.TH "libnvme" 2 "struct nvmf_disc_log_entry" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvmf_disc_log_entry \- Discovery log page entry +.SH SYNOPSIS +struct nvmf_disc_log_entry { +.br +.BI " __u8 trtype;" +.br +.BI " __u8 adrfam;" +.br +.BI " __u8 subtype;" +.br +.BI " __u8 treq;" +.br +.BI " __le16 portid;" +.br +.BI " __le16 cntlid;" +.br +.BI " __le16 asqsz;" +.br +.BI " __u8 resv10[22];" +.br +.BI " char trsvcid[NVMF_TRSVCID_SIZE];" +.br +.BI " __u8 resv64[192];" +.br +.BI " char subnqn[NVMF_NQN_FIELD_LEN];" +.br +.BI " char traddr[NVMF_TRADDR_SIZE];" +.br +.BI " union tsas {" +.br +.BI " char common[NVMF_TSAS_SIZE];" +.br +.BI " struct rdma {" +.br +.BI " __u8 qptype;" +.br +.BI " __u8 prtype;" +.br +.BI " __u8 cms;" +.br +.BI " __u8 resv3[5];" +.br +.BI " __u16 pkey;" +.br +.BI " __u8 resv10[246];" +.br +.BI " } rdma;" +.br +.BI " struct tcp {" +.br +.BI " __u8 sectype;" +.br +.BI " } tcp;" +.br +.BI " } tsas;" +.br +.BI " +}; +.br + +.SH Members diff --git a/doc/man/struct nvmf_discovery_log.2 b/doc/man/struct nvmf_discovery_log.2 new file mode 100644 index 0000000000..ba22896a20 --- /dev/null +++ b/doc/man/struct nvmf_discovery_log.2 @@ -0,0 +1,21 @@ +.TH "libnvme" 2 "struct nvmf_discovery_log" "February 2020" "LIBNVME API Manual" LINUX +.SH NAME +struct nvmf_discovery_log \- +.SH SYNOPSIS +struct nvmf_discovery_log { +.br +.BI " __le64 genctr;" +.br +.BI " __le64 numrec;" +.br +.BI " __le16 recfmt;" +.br +.BI " __u8 resv14[1006];" +.br +.BI " struct nvmf_disc_log_entry entries[0];" +.br +.BI " +}; +.br + +.SH Members From e84081c9d80afb6cab43585f34d7926debd2f8f8 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Fri, 14 Feb 2020 15:20:13 -0800 Subject: [PATCH 0031/1564] Fill in more documentation details And start adding more cross references. Signed-off-by: Keith Busch --- examples/telemetry-listen.c | 5 +- src/nvme/fabrics.c | 20 +- src/nvme/fabrics.h | 71 ++--- src/nvme/ioctl.c | 4 +- src/nvme/ioctl.h | 514 ++++++++++++++++++------------------ src/nvme/tree.c | 3 + src/nvme/types.h | 472 ++++++++++++++++++++++++++++++--- src/nvme/util.c | 73 +++-- src/nvme/util.h | 195 +++++++------- 9 files changed, 867 insertions(+), 490 deletions(-) diff --git a/examples/telemetry-listen.c b/examples/telemetry-listen.c index 1bc250b537..7d1f260bda 100644 --- a/examples/telemetry-listen.c +++ b/examples/telemetry-listen.c @@ -38,11 +38,11 @@ static void save_telemetry(nvme_ctrl_t c) char buf[0x1000]; __u32 log_size; int ret, fd; - void *log; + struct nvme_telemetry_log *log; time_t s; /* Clear the log (rae == false) at the end to see new telemetry events later */ - ret = nvme_get_ctrl_telemetry(nvme_ctrl_get_fd(c), false, &log, &log_size); + ret = nvme_get_ctrl_telemetry(nvme_ctrl_get_fd(c), false, &log); if (ret) return; @@ -53,6 +53,7 @@ static void save_telemetry(nvme_ctrl_t c) free(log); return; } + log_size = (le16_to_cpu(log->dalb3) + 1) * NVME_LOG_TELEM_BLOCK_SIZE; fd = open(buf, O_CREAT|O_WRONLY, S_IRUSR|S_IRGRP); if (fd < 0) { diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 9744f03775..836e4634f8 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -44,7 +44,6 @@ static int add_bool_argument(char **argstr, char *tok, bool arg) if (!arg) return 0; - if (asprintf(&nstr, "%s,%s", *argstr, tok) < 0) { errno = ENOMEM; return -1; @@ -55,19 +54,19 @@ static int add_bool_argument(char **argstr, char *tok, bool arg) return 0; } -static int add_int_argument(char **argstr, char *tok, int arg, - bool allow_zero) +static int add_int_argument(char **argstr, char *tok, int arg, bool allow_zero) { char *nstr; - if ((arg && !allow_zero) || (arg != -1 && allow_zero)) { - if (asprintf(&nstr, "%s,%s=%d", *argstr, tok, arg) < 0) { - errno = ENOMEM; - return -1; - } - free(*argstr); - *argstr = nstr; + if (arg < 0 || (!arg && !allow_zero)) + return 0; + if (asprintf(&nstr, "%s,%s=%d", *argstr, tok, arg) < 0) { + errno = ENOMEM; + return -1; } + free(*argstr); + *argstr = nstr; + return 0; } @@ -83,6 +82,7 @@ static int add_argument(char **argstr, const char *tok, const char *arg) } free(*argstr); *argstr = nstr; + return 0; } diff --git a/src/nvme/fabrics.h b/src/nvme/fabrics.h index 8af57bcc20..1ca4eb53e8 100644 --- a/src/nvme/fabrics.h +++ b/src/nvme/fabrics.h @@ -64,78 +64,61 @@ struct nvme_fabrics_config { /** * nvmf_add_ctrl_opts() - + * @cfg: + * + * Return: */ int nvmf_add_ctrl_opts(struct nvme_fabrics_config *cfg); /** * nvmf_add_ctrl() - + * @cfg: + * + * Return: */ nvme_ctrl_t nvmf_add_ctrl(struct nvme_fabrics_config *cfg); /** * nvmf_get_discovery_log() - + * @c: + * @logp: + * @max_retries: + * + * Return: */ int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, int max_retries); /** - * nvmf_hostnqn_generate() - + * nvmf_hostnqn_generate() - Generate a machine specific host nqn + * Returns: An nvm namespace qualifieid name string based on the machine + * identifier, or NULL if not successful. */ char *nvmf_hostnqn_generate(); /** - * nvmf_hostnqn_from_file() - + * nvmf_hostnqn_from_file() - Reads the host nvm qualified name from the config + * default location in /etc/nvme/ + * Return: The host nqn, or NULL if unsuccessful. If found, the caller + * is responsible to free the string. */ char *nvmf_hostnqn_from_file(); /** - * nvmf_hostid_from_file() - + * nvmf_hostid_from_file() - Reads the host identifier from the config default + * location in /etc/nvme/. + * Return: The host identifier, or NULL if unsuccessful. If found, the caller + * is responsible to free the string. */ char *nvmf_hostid_from_file(); -/** - * nvmf_trtype_str() - - */ -const char *nvmf_trtype_str(__u8 trtype); - -/** - * nvmf_adrfam_str() - - */ -const char *nvmf_adrfam_str(__u8 adrfam); - -/** - * nvmf_subtype_str() - - */ -const char *nvmf_subtype_str(__u8 subtype); - -/** - * nvmf_treq_str() - - */ -const char *nvmf_treq_str(__u8 treq); - -/** - * nvmf_sectype_str() - - */ -const char *nvmf_sectype_str(__u8 sectype); - -/** - * nvmf_prtype_str() - - */ -const char *nvmf_prtype_str(__u8 prtype); - -/** - * nvmf_qptype_str() - - */ -const char *nvmf_qptype_str(__u8 qptype); - -/** - * nvmf_cms_str() - - */ -const char *nvmf_cms_str(__u8 cm); - - /** * nvmf_connect_disc_entry() - + * @e: + * @defcfg: + * @discover: + * + * Return: */ nvme_ctrl_t nvmf_connect_disc_entry(struct nvmf_disc_log_entry *e, const struct nvme_fabrics_config *defcfg, bool *discover); diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 0f0a8dd0ab..3b9f035d77 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -1428,7 +1428,7 @@ int nvme_directive_recv_stream_allocate(int fd, __u32 nsid, __u16 nsr, int nvme_set_property(int fd, int offset, __u64 value) { - __u32 cdw10 = is_64bit_reg(offset); + __u32 cdw10 = nvme_is_64bit_reg(offset); struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_fabrics, @@ -1444,7 +1444,7 @@ int nvme_set_property(int fd, int offset, __u64 value) int nvme_get_property(int fd, int offset, __u64 *value) { - __u32 cdw10 = is_64bit_reg(offset); + __u32 cdw10 = nvme_is_64bit_reg(offset); struct nvme_passthru_cmd64 cmd = { .opcode = nvme_admin_fabrics, diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 57e1c84f2b..c96c24d85d 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -126,8 +126,8 @@ struct nvme_passthru_cmd64 { * * Uses NVME_IOCTL_ADMIN64_CMD for the ioctl request. * - * Return: The nvme command status if a response was received or -1 - * with errno set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_submit_admin_passthru64(int fd, struct nvme_passthru_cmd64 *cmd, __u64 *result); @@ -159,8 +159,8 @@ int nvme_submit_admin_passthru64(int fd, struct nvme_passthru_cmd64 *cmd, * * Known values for @opcode are defined in &enum nvme_admin_opcode. * - * Return: The nvme command status if a response was received or -1 - * with errno set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_admin_passthru64(int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, @@ -176,8 +176,8 @@ int nvme_admin_passthru64(int fd, __u8 opcode, __u8 flags, __u16 rsvd, * * Uses NVME_IOCTL_ADMIN_CMD for the ioctl request. * - * Return: The nvme command status if a response was received or -1 - * with errno set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_submit_admin_passthru(int fd, struct nvme_passthru_cmd *cmd, __u32 *result); @@ -209,8 +209,8 @@ int nvme_submit_admin_passthru(int fd, struct nvme_passthru_cmd *cmd, * * Known values for @opcode are defined in &enum nvme_admin_opcode. * - * Return: The nvme command status if a response was received or -1 - * with errno set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_admin_passthru(int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, @@ -226,8 +226,8 @@ int nvme_admin_passthru(int fd, __u8 opcode, __u8 flags, __u16 rsvd, * * Uses NVME_IOCTL_IO64_CMD for the ioctl request. * - * Return: The nvme command status if a response was received or -1 - * with errno set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_submit_io_passthru64(int fd, struct nvme_passthru_cmd64 *cmd, __u64 *result); @@ -259,8 +259,8 @@ int nvme_submit_io_passthru64(int fd, struct nvme_passthru_cmd64 *cmd, * * Known values for @opcode are defined in &enum nvme_io_opcode. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_io_passthru64(int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, @@ -277,8 +277,8 @@ int nvme_io_passthru64(int fd, __u8 opcode, __u8 flags, __u16 rsvd, * * Uses NVME_IOCTL_IO_CMD for the ioctl request. * - * Return: The nvme command status if a response was received or -1 - * with errno set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_submit_io_passthru(int fd, struct nvme_passthru_cmd *cmd, __u32 *result); @@ -310,8 +310,8 @@ int nvme_submit_io_passthru(int fd, struct nvme_passthru_cmd *cmd, * * Known values for @opcode are defined in &enum nvme_io_opcode. * - * Return: The nvme command status if a response was received or -1 - * with errno set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_io_passthru(int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, @@ -361,10 +361,6 @@ int nvme_ns_rescan(int fd); */ int nvme_get_nsid(int fd); -/** - * DOC: NVMe Admin command enums - */ - /** * enum nvme_admin_opcode - Known NVMe admin opcodes * @nvme_admin_delete_sq: @@ -770,8 +766,8 @@ enum nvme_virt_mgmt_rt { * The Identify command returns a data buffer that describes information about * the NVM subsystem, the controller or the namespace(s). * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify(int fd, enum nvme_identify_cns cns, __u32 nsid, __u16 cntid, __u16 nvmsetid, __u8 uuidx, void *data); @@ -785,8 +781,8 @@ int nvme_identify(int fd, enum nvme_identify_cns cns, __u32 nsid, * * See &struct nvme_id_ctrl for details on the data returned. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_ctrl(int fd, struct nvme_id_ctrl *id); @@ -807,8 +803,8 @@ int nvme_identify_ctrl(int fd, struct nvme_id_ctrl *id); * * See &struct nvme_id_ns for details on the structure returned. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_ns(int fd, __u32 nsid, struct nvme_id_ns *ns); @@ -819,8 +815,8 @@ int nvme_identify_ns(int fd, __u32 nsid, struct nvme_id_ns *ns); * @nsid: Namespace to identify * @ns: User space destination address to transfer the data * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_allocated_ns(int fd, __u32 nsid, struct nvme_id_ns *ns); @@ -836,8 +832,8 @@ int nvme_identify_allocated_ns(int fd, __u32 nsid, struct nvme_id_ns *ns); * * See &struct nvme_ns_list for the definition of the returned structure. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_active_ns_list(int fd, __u32 nsid, struct nvme_ns_list *list); @@ -853,8 +849,8 @@ int nvme_identify_active_ns_list(int fd, __u32 nsid, struct nvme_ns_list *list); * * See &struct nvme_ns_list for the definition of the returned structure. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_allocated_ns_list(int fd, __u32 nsid, struct nvme_ns_list *list); @@ -871,8 +867,8 @@ int nvme_identify_allocated_ns_list(int fd, __u32 nsid, * * See &struct nvme_ctrl_list for a definition of the structure returned. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_ctrl_list(int fd, __u16 cntid, struct nvme_ctrl_list *ctrlist); @@ -890,7 +886,8 @@ int nvme_identify_ctrl_list(int fd, __u16 cntid, * * See &struct nvme_ctrl_list for a definition of the structure returned. * - * Return: The nvme command status if a response was received or -1 + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 */ int nvme_identify_nsid_ctrl_list(int fd, __u32 nsid, __u16 cntid, struct nvme_ctrl_list *ctrlist); @@ -909,8 +906,8 @@ int nvme_identify_nsid_ctrl_list(int fd, __u32 nsid, __u16 cntid, * * See &struct nvme_ns_id_desc for the definition of the returned structure. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_ns_descs(int fd, __u32 nsid, struct nvme_ns_id_desc *descs); @@ -927,8 +924,8 @@ int nvme_identify_ns_descs(int fd, __u32 nsid, struct nvme_ns_id_desc *descs); * * See &struct nvme_id_nvmset_list for the defintion of the returned structure. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_nvmset_list(int fd, __u16 nvmsetid, struct nvme_id_nvmset_list *nvmset); @@ -942,8 +939,8 @@ int nvme_identify_nvmset_list(int fd, __u16 nvmsetid, * * See &struct nvme_primary_ctrl_cap for the defintion of the returned structure, @cap. * - * Return: The nvme command status if a response was received or -1 - * with errno set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_primary_ctrl(int fd, __u16 cntid, struct nvme_primary_ctrl_cap *cap); @@ -962,8 +959,8 @@ int nvme_identify_primary_ctrl(int fd, __u16 cntid, * See &struct nvme_secondary_ctrls_list for a defintion of the returned * structure. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_secondary_ctrl_list(int fd, __u16 cntid, struct nvme_secondary_ctrl_list *list); @@ -981,8 +978,8 @@ int nvme_identify_secondary_ctrl_list(int fd, __u16 cntid, * See &struct nvme_id_ns_granularity_list for the definition of the returned * structure. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_ns_granularity(int fd, struct nvme_id_ns_granularity_list *list); @@ -996,8 +993,8 @@ int nvme_identify_ns_granularity(int fd, struct nvme_id_ns_granularity_list *lis * * See &struct nvme_id_uuid_list for the definition of the returned structure. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_uuid(int fd, struct nvme_id_uuid_list *list); @@ -1014,8 +1011,8 @@ int nvme_identify_uuid(int fd, struct nvme_id_uuid_list *list); * @len: Length of provided user buffer to hold the log data in bytes * @log: User space destination address to transfer the data * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, __u8 lsp, __u16 lsi, bool rae, __u8 uuidx, __u32 len, void *log); @@ -1031,8 +1028,8 @@ int nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, * that completed with error, or may report an error that is not specific to a * particular command. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_error(int fd, unsigned nr_entries, bool rae, struct nvme_error_log_page *log); @@ -1051,8 +1048,8 @@ int nvme_get_log_error(int fd, unsigned nr_entries, bool rae, * requesting the log page on a per namespace basis, as indicated by bit 0 of * the LPA field in the Identify Controller data structure. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_smart(int fd, __u32 nsid, bool rae, struct nvme_smart_log *log); @@ -1066,8 +1063,8 @@ int nvme_get_log_smart(int fd, __u32 nsid, bool rae, struct nvme_smart_log *log) * firmware slot supported. The firmware revision is indicated as an ASCII * string. The log page also indicates the active slot number. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_fw_slot(int fd, bool rae, struct nvme_firmware_slot *log); @@ -1081,8 +1078,8 @@ int nvme_get_log_fw_slot(int fd, bool rae, struct nvme_firmware_slot *log); * that have changed since the last time the namespace was identified, been * added, or deleted. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_changed_ns_list(int fd, bool rae, struct nvme_ns_list *log); @@ -1094,8 +1091,8 @@ int nvme_get_log_changed_ns_list(int fd, bool rae, struct nvme_ns_list *log); * This log page is used to describe the commands that the controller supports * and the effects of those commands on the state of the NVM subsystem. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_cmd_effects(int fd, struct nvme_cmd_effects_log *log); @@ -1109,8 +1106,8 @@ int nvme_get_log_cmd_effects(int fd, struct nvme_cmd_effects_log *log); * the percent complete of that operation, and the results of the previous 20 * self-test operations. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_device_self_test(int fd, struct nvme_self_test_log *log); @@ -1129,8 +1126,8 @@ int nvme_get_log_create_telemetry_host(int fd, struct nvme_telemetry_log *log); * Retreives 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 or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_telemetry_host(int fd, __u64 offset, __u32 len, void *log); @@ -1158,8 +1155,8 @@ int nvme_get_log_telemetry_ctrl(int fd, bool rae, __u64 offset, __u32 len, * generated when an entry for an Endurance Group is newly added to this log * page. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_endurance_group(int fd, __u16 endgid, struct nvme_endurance_group_log *log); @@ -1169,8 +1166,8 @@ int nvme_get_log_endurance_group(int fd, __u16 endgid, * @fd: * @nvmsetid: * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_predictable_lat_nvmset(int fd, __u16 nvmsetid, struct nvme_nvmset_predictable_lat_log *log); @@ -1205,8 +1202,8 @@ enum nvme_log_ana_lsp { * * See &struct nvme_ana_rsp_hdr for the defintion of the returned structure. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_ana(int fd, enum nvme_log_ana_lsp lsp, bool rae, __u64 offset, __u32 len, void *log); @@ -1248,8 +1245,8 @@ int nvme_get_log_endurance_grp_evt(int fd, bool rae, __u32 offset, __u32 len, * Supported only by fabrics discovery controllers, returning discovery * records. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_discovery(int fd, bool rae, __u32 offset, __u32 len, void *log); @@ -1270,8 +1267,8 @@ int nvme_get_log_reservation(int fd, bool rae, * The Sanitize Status log page is used to report sanitize operation time * estimates and information about the most recent sanitize operation. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_sanitize(int fd, bool rae, struct nvme_sanitize_log_page *log); @@ -1290,8 +1287,8 @@ int nvme_get_log_sanitize(int fd, bool rae, * @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 or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features(int fd, __u8 fid, __u32 nsid, __u32 cdw11, __u32 cdw12, bool save, __u8 uuidx, __u32 cdw15, __u32 data_len, @@ -1303,8 +1300,8 @@ int nvme_set_features(int fd, __u8 fid, __u32 nsid, __u32 cdw11, __u32 cdw12, * @save: Save value across power states * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_arbitration(int fd, __u8 ab, __u8 lpw, __u8 mpw, __u8 hpw, bool save, __u32 *result); @@ -1315,8 +1312,8 @@ int nvme_set_features_arbitration(int fd, __u8 ab, __u8 lpw, __u8 mpw, * @save: Save value across power states * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_power_mgmt(int fd, __u8 ps, __u8 wh, bool save, __u32 *result); @@ -1327,8 +1324,8 @@ int nvme_set_features_power_mgmt(int fd, __u8 ps, __u8 wh, bool save, * @save: Save value across power states * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_lba_range(int fd, __u32 nsid, __u32 nr_ranges, bool save, struct nvme_lba_range_type *data, __u32 *result); @@ -1348,8 +1345,8 @@ enum nvme_feat_tmpthresh_thsel { * @save: Save value across power states * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_temp_thresh(int fd, __u16 tmpth, __u8 tmpsel, enum nvme_feat_tmpthresh_thsel thsel, @@ -1361,8 +1358,8 @@ int nvme_set_features_temp_thresh(int fd, __u16 tmpth, __u8 tmpsel, * @save: Save value across power states * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_err_recovery(int fd, __u32 nsid, __u16 tler, bool dulbe, bool save, __u32 *result); @@ -1374,8 +1371,8 @@ int nvme_set_features_err_recovery(int fd, __u32 nsid, __u16 tler, * @save: Save value across power states * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_volatile_wc(int fd, bool wce, bool save, __u32 *result); @@ -1386,8 +1383,8 @@ int nvme_set_features_volatile_wc(int fd, bool wce, bool save, * @save: Save value across power states * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_irq_coalesce(int fd, __u8 thr, __u8 time, bool save, __u32 *result); @@ -1398,8 +1395,8 @@ int nvme_set_features_irq_coalesce(int fd, __u8 thr, __u8 time, * @save: Save value across power states * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_irq_config(int fd, __u16 iv, bool cd, bool save, __u32 *result); @@ -1411,8 +1408,8 @@ int nvme_set_features_irq_config(int fd, __u16 iv, bool cd, bool save, * @save: Save value across power states * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_write_atomic(int fd, bool dn, bool save, __u32 *result); @@ -1443,8 +1440,8 @@ enum nvme_features_async_event_config_flags { * @save: Save value across power states * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_async_event(int fd, __u32 events, bool save, __u32 *result); @@ -1456,8 +1453,8 @@ int nvme_set_features_async_event(int fd, __u32 events, bool save, * @save: Save value across power states * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_auto_pst(int fd, bool apste, bool save, struct nvme_feat_auto_pst *apst, @@ -1469,8 +1466,8 @@ int nvme_set_features_auto_pst(int fd, bool apste, bool save, * @save: Save value across power states * @timestamp: The current timestamp value to assign to this this feature * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_timestamp(int fd, bool save, __u64 timestamp); @@ -1481,8 +1478,8 @@ int nvme_set_features_timestamp(int fd, bool save, __u64 timestamp); * @save: Save value across power states * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_hctm(int fd, __u16 tmt2, __u16 tmt1, bool save, __u32 *result); @@ -1498,8 +1495,8 @@ int nvme_set_features_nopsc(int fd, bool noppme, bool save, __u32 *result); * @save: Save value across power states * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_rrl(int fd, __u8 rrl, __u16 nvmsetid, bool save, __u32 *result); @@ -1510,8 +1507,8 @@ int nvme_set_features_rrl(int fd, __u8 rrl, __u16 nvmsetid, bool save, * @save: Save value across power states * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_plm_config(int fd, bool enable, __u16 nvmsetid, bool save, struct nvme_plm_config *data, @@ -1531,8 +1528,8 @@ enum nvme_feat_plm_window_select { * @save: Save value across power states * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_plm_window(int fd, enum nvme_feat_plm_window_select sel, __u16 nvmsetid, bool save, __u32 *result); @@ -1544,8 +1541,8 @@ int nvme_set_features_plm_window(int fd, enum nvme_feat_plm_window_select sel, * @save: Save value across power states * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_lba_sts_interval(int fd, __u16 lsiri, __u16 lsipi, bool save, __u32 *result); @@ -1556,8 +1553,8 @@ int nvme_set_features_lba_sts_interval(int fd, __u16 lsiri, __u16 lsipi, * @fd: File descriptor of nvme device * @save: Save value across power states * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_host_behavior(int fd, bool save, struct nvme_feat_host_behavior *data); @@ -1568,8 +1565,8 @@ int nvme_set_features_host_behavior(int fd, bool save, * @save: Save value across power states * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_sanitize(int fd, bool nodrm, bool save, __u32 *result); @@ -1581,8 +1578,8 @@ int nvme_set_features_sanitize(int fd, bool nodrm, bool save, __u32 *result); * @save: Save value across power states * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_endurance_evt_cfg(int fd, __u16 endgid, __u8 egwarn, bool save, __u32 *result); @@ -1593,8 +1590,8 @@ int nvme_set_features_endurance_evt_cfg(int fd, __u16 endgid, __u8 egwarn, * @save: Save value across power states * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_sw_progress(int fd, __u8 pbslc, bool save, __u32 *result); @@ -1606,8 +1603,8 @@ int nvme_set_features_sw_progress(int fd, __u8 pbslc, bool save, * @save: Save value across power states * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_host_id(int fd, bool exhid, bool save, __u8 *hostid); @@ -1626,8 +1623,8 @@ enum nvme_feat_resv_notify_flags { * @save: Save value across power states * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_resv_mask(int fd, __u32 mask, bool save, __u32 *result); @@ -1637,8 +1634,8 @@ int nvme_set_features_resv_mask(int fd, __u32 mask, bool save, __u32 *result); * @save: Save value across power states * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_resv_persist(int fd, bool ptpl, bool save, __u32 *result); @@ -1662,8 +1659,8 @@ enum nvme_feat_nswpcfg_state { * @save: Save value across power states * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_write_protect(int fd, enum nvme_feat_nswpcfg_state state, bool save, __u32 *result); @@ -1680,8 +1677,8 @@ int nvme_set_features_write_protect(int fd, enum nvme_feat_nswpcfg_state state, * @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 or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features(int fd, enum nvme_features_id fid, __u32 nsid, enum nvme_get_features_sel sel, __u32 cdw11, __u8 uuidx, @@ -1693,8 +1690,8 @@ int nvme_get_features(int fd, enum nvme_features_id fid, __u32 nsid, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_arbitration(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1705,8 +1702,8 @@ int nvme_get_features_arbitration(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_power_mgmt(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1717,8 +1714,8 @@ int nvme_get_features_power_mgmt(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_lba_range(int fd, enum nvme_get_features_sel sel, struct nvme_lba_range_type *data, @@ -1730,8 +1727,8 @@ int nvme_get_features_lba_range(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_temp_thresh(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1742,8 +1739,8 @@ int nvme_get_features_temp_thresh(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_err_recovery(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1754,8 +1751,8 @@ int nvme_get_features_err_recovery(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_volatile_wc(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1766,8 +1763,8 @@ int nvme_get_features_volatile_wc(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_num_queues(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1778,8 +1775,8 @@ int nvme_get_features_num_queues(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_irq_coalesce(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1790,8 +1787,8 @@ int nvme_get_features_irq_coalesce(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_irq_config(int fd, enum nvme_get_features_sel sel, __u16 iv, __u32 *result); @@ -1802,8 +1799,8 @@ int nvme_get_features_irq_config(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_write_atomic(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1814,8 +1811,8 @@ int nvme_get_features_write_atomic(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_async_event(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1826,8 +1823,8 @@ int nvme_get_features_async_event(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_auto_pst(int fd, enum nvme_get_features_sel sel, struct nvme_feat_auto_pst *apst, __u32 *result); @@ -1838,8 +1835,8 @@ int nvme_get_features_auto_pst(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_host_mem_buf(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1850,8 +1847,8 @@ int nvme_get_features_host_mem_buf(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_timestamp(int fd, enum nvme_get_features_sel sel, struct nvme_timestamp *ts); @@ -1862,8 +1859,8 @@ int nvme_get_features_timestamp(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_kato(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1873,8 +1870,8 @@ int nvme_get_features_kato(int fd, enum nvme_get_features_sel sel, __u32 *result * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_hctm(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1884,8 +1881,8 @@ int nvme_get_features_hctm(int fd, enum nvme_get_features_sel sel, __u32 *result * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_nopsc(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1895,8 +1892,8 @@ int nvme_get_features_nopsc(int fd, enum nvme_get_features_sel sel, __u32 *resul * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_rrl(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1906,8 +1903,8 @@ int nvme_get_features_rrl(int fd, enum nvme_get_features_sel sel, __u32 *result) * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_plm_config(int fd, enum nvme_get_features_sel sel, __u16 nvmsetid, struct nvme_plm_config *data, @@ -1919,8 +1916,8 @@ int nvme_get_features_plm_config(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_plm_window(int fd, enum nvme_get_features_sel sel, __u16 nvmsetid, __u32 *result); @@ -1931,8 +1928,8 @@ int nvme_get_features_plm_window(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_lba_sts_interval(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1943,8 +1940,8 @@ int nvme_get_features_lba_sts_interval(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_host_behavior(int fd, enum nvme_get_features_sel sel, struct nvme_feat_host_behavior *data, @@ -1956,8 +1953,8 @@ int nvme_get_features_host_behavior(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_sanitize(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1968,8 +1965,8 @@ int nvme_get_features_sanitize(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_endurance_event_cfg(int fd, enum nvme_get_features_sel sel, __u16 endgid, __u32 *result); @@ -1980,8 +1977,8 @@ int nvme_get_features_endurance_event_cfg(int fd, enum nvme_get_features_sel sel * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_sw_progress(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1992,8 +1989,8 @@ int nvme_get_features_sw_progress(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_host_id(int fd, enum nvme_get_features_sel sel, bool exhid, __u32 len, __u8 *hostid); @@ -2004,8 +2001,8 @@ int nvme_get_features_host_id(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_resv_mask(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -2016,8 +2013,8 @@ int nvme_get_features_resv_mask(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_resv_persist(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -2029,8 +2026,8 @@ int nvme_get_features_resv_persist(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_write_protect(int fd, __u32 nsid, enum nvme_get_features_sel sel, @@ -2054,8 +2051,8 @@ int nvme_get_features_write_protect(int fd, __u32 nsid, * size. A low level format may destroy all data and metadata associated with * all namespaces or only the specific namespace associated with the command * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_format_nvm(int fd, __u32 nsid, __u8 lbaf, enum nvme_cmd_format_mset mset, @@ -2083,8 +2080,8 @@ int nvme_ns_mgmt(int fd, __u32 nsid, enum nvme_ns_mgmt_sel sel, * attached to any controller. Use the nvme_ns_attach_ctrls() to assign the * namespace to one or more controllers. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * 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_create(int fd, struct nvme_id_ns *ns, __u32 *nsid, __u32 timeout); @@ -2098,8 +2095,8 @@ int nvme_ns_mgmt_create(int fd, struct nvme_id_ns *ns, __u32 *nsid, * controller. Use the nvme_ns_detach_ctrls() first if the namespace is still * attached. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * 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_delete(int fd, __u32 nsid); @@ -2122,12 +2119,12 @@ int nvme_ns_attach(int fd, __u32 nsid, enum nvme_ns_attach_sel sel, int nvme_ns_attach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist); /** - * nvme_ns_dettach_ctrls() - + * nvme_ns_detach_ctrls() - * @fd: File descriptor of nvme device - * @nsid: Namespace ID to dettach + * @nsid: Namespace ID to detach * @ctrlist: Controller list to modify attachment state of nsid */ -int nvme_ns_dettach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist); +int nvme_ns_detach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist); /** * nvme_fw_download() - Download part or all of a firmware image to the @@ -2150,8 +2147,8 @@ int nvme_ns_dettach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist); * Download command. Use the nvme_fw_commit() to activate a newly downloaded * image. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_fw_download(int fd, __u32 offset, __u32 data_len, void *data); @@ -2165,8 +2162,9 @@ int nvme_fw_download(int fd, __u32 offset, __u32 data_len, void *data); * The Firmware Commit command is used to modify the firmware image or Boot * Partitions. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. The command status response may specify additional + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. The command status + * response may specify additional * reset actions required to complete the commit process. */ int nvme_fw_commit(int fd, __u8 slot, enum nvme_fw_commit_ca action, bool bpid); @@ -2193,8 +2191,8 @@ int nvme_fw_commit(int fd, __u8 slot, enum nvme_fw_commit_ca action, bool bpid); * The security data is protocol specific and is not defined by the NVMe * specification. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_security_send(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, __u8 secp, __u32 tl, __u32 data_len, void *data, @@ -2213,8 +2211,8 @@ int nvme_security_send(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, * @data: Security data payload to send * @result: The command completion result from CQE dword0 * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * 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(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, __u8 secp, __u32 al, __u32 data_len, @@ -2234,8 +2232,8 @@ int nvme_security_receive(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, * The Get LBA Status command requests information about Potentially * Unrecoverable LBAs. Refer to the specification for action type descriptions. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_lba_status(int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl, enum nvme_lba_status_atype atype, @@ -2259,8 +2257,8 @@ int nvme_get_lba_status(int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl, * * See the NVMe specification for more information. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_directive_send(int fd, __u32 nsid, __u16 dspec, enum nvme_directive_send_doper doper, @@ -2272,8 +2270,8 @@ int nvme_directive_send(int fd, __u32 nsid, __u16 dspec, * @fd: File descriptor of nvme device * @nsid: Namespace ID * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_directive_send_id_endir(int fd, __u32 nsid, bool endir, enum nvme_directive_dtype dtype, @@ -2284,8 +2282,8 @@ int nvme_directive_send_id_endir(int fd, __u32 nsid, bool endir, * @fd: File descriptor of nvme device * @nsid: Namespace ID * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_directive_send_stream_release_identifier(int fd, __u32 nsid, __u16 stream_id); @@ -2295,8 +2293,8 @@ int nvme_directive_send_stream_release_identifier(int fd, __u32 nsid, * @fd: File descriptor of nvme device * @nsid: Namespace ID * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_directive_send_stream_release_resource(int fd, __u32 nsid); @@ -2312,8 +2310,8 @@ int nvme_directive_send_stream_release_resource(int fd, __u32 nsid); * @data: Usespace address of data payload in bytes * @result: If successful, the CQE dword0 value * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_directive_recv(int fd, __u32 nsid, __u16 dspec, enum nvme_directive_receive_doper doper, @@ -2325,8 +2323,8 @@ int nvme_directive_recv(int fd, __u32 nsid, __u16 dspec, * @fd: File descriptor of nvme device * @nsid: Namespace ID * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_directive_recv_identify_parameters(int fd, __u32 nsid, struct nvme_id_directives *id); @@ -2336,8 +2334,8 @@ int nvme_directive_recv_identify_parameters(int fd, __u32 nsid, * @fd: File descriptor of nvme device * @nsid: Namespace ID * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_directive_recv_stream_parameters(int fd, __u32 nsid, struct nvme_streams_directive_params *parms); @@ -2347,8 +2345,8 @@ int nvme_directive_recv_stream_parameters(int fd, __u32 nsid, * @fd: File descriptor of nvme device * @nsid: Namespace ID * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_directive_recv_stream_status(int fd, __u32 nsid, unsigned nr_entries, struct nvme_streams_directive_status *id); @@ -2358,8 +2356,8 @@ int nvme_directive_recv_stream_status(int fd, __u32 nsid, unsigned nr_entries, * @fd: File descriptor of nvme device * @nsid: Namespace ID * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_directive_recv_stream_allocate(int fd, __u32 nsid, __u16 nsr, __u32 *result); @@ -2391,8 +2389,8 @@ enum nvme_fctype { * This is an NVMe-over-Fabrics specific command, not applicable to PCIe. These * properties align to the PCI MMIO controller registers. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_property(int fd, int offset, __u64 value); @@ -2405,8 +2403,8 @@ int nvme_set_property(int fd, int offset, __u64 value); * This is an NVMe-over-Fabrics specific command, not applicable to PCIe. These * properties align to the PCI MMIO controller registers. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_property(int fd, int offset, __u64 *value); @@ -2430,8 +2428,8 @@ int nvme_get_property(int fd, int offset, __u64 *value); * sanitize operations are processed in the background, i.e., completion of the * sanitize command does not indicate completion of the sanitize operation. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_sanitize_nvm(int fd, enum nvme_sanitize_sanact sanact, bool ause, __u8 owpass, bool oipbp, bool nodas, __u32 ovrpat); @@ -2453,8 +2451,8 @@ int nvme_sanitize_nvm(int fd, enum nvme_sanitize_sanact sanact, bool ause, * 0xffffffff to test all namespaces. All other values tests a specific * namespace, if present. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_dev_self_test(int fd, __u32 nsid, enum nvme_dst_stc stc); @@ -2475,17 +2473,13 @@ int nvme_dev_self_test(int fd, __u32 nsid, enum nvme_dst_stc stc); * - Assigning Flexible Resources for secondary controllers * - Setting the Online and Offline state for secondary controllers * - * Return: The nvme command status if a response was received or -1 - * with errno set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_virtual_mgmt(int fd, enum nvme_virt_mgmt_act act, enum nvme_virt_mgmt_rt rt, __u16 cntlid, __u16 nr, __u32 *result); -/** - * DOC: NVMe IO command - */ - /** * enum nvme_io_opcode - * @nvme_cmd_flush: @@ -2524,8 +2518,8 @@ enum nvme_io_opcode { * The Flush command is used to request that the contents of volatile write * cache be made non-volatile. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_flush(int fd, __u32 nsid); @@ -2609,8 +2603,8 @@ enum nvme_io_dsm_flags { * metadata_len:Length of user buffer, @metadata, in bytes * @metadata: Pointer to user address of the metadata buffer * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_read(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u8 dsm, __u32 reftag, __u16 apptag, __u16 appmask, @@ -2639,8 +2633,8 @@ int nvme_read(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, * metadata_len:Length of user buffer, @metadata, in bytes * @metadata: Pointer to user address of the metadata buffer * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_write(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u8 dsm, __u16 dspec, __u32 reftag, __u16 apptag, @@ -2668,8 +2662,8 @@ int nvme_write(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, * metadata_len:Length of user buffer, @metadata, in bytes * @metadata: Pointer to user address of the metadata buffer * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_compare(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 reftag, __u16 apptag, __u16 appmask, __u32 data_len, @@ -2697,8 +2691,8 @@ int nvme_compare(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, * subsequent reads of logical blocks in this range shall be all bytes cleared * to 0h until a write occurs to this LBA range. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_write_zeros(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 reftag, __u16 apptag, __u16 appmask); @@ -2716,8 +2710,8 @@ int nvme_write_zeros(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, * invalid logical block status, a write operation on those logical blocks is * required. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_write_uncorrectable(int fd, __u32 nsid, __u64 slba, __u16 nlb); @@ -2742,8 +2736,8 @@ int nvme_write_uncorrectable(int fd, __u32 nsid, __u64 slba, __u16 nlb); * and metadata, if applicable, for the LBAs indicated without transferring any * data or metadata to the host. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_verify(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 reftag, __u16 apptag, __u16 appmask); @@ -2774,8 +2768,8 @@ enum nvme_dsm_attributes { * to optimize performance and reliability, and may be used to * deallocate/unmap/trim those logical blocks. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_dsm(int fd, __u32 nsid, __u32 attrs, __u16 nr_ranges, struct nvme_dsm_range *dsm); @@ -2825,8 +2819,8 @@ enum nvme_reservation_racqa { * namespace, preempt a reservation held on a namespace, and abort a * reservation held on a namespace. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_resv_acquire(int fd, __u32 nsid, enum nvme_reservation_rtype rtype, enum nvme_reservation_racqa racqa, bool iekey, @@ -2870,8 +2864,8 @@ enum nvme_reservation_cptpl { * The Reservation Register command is used to register, unregister, or replace * a reservation key. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_resv_register(int fd, __u32 nsid, enum nvme_reservation_rrega rrega, enum nvme_reservation_cptpl cptpl, bool iekey, @@ -2896,8 +2890,8 @@ enum nvme_reservation_rrela { * @iekey: Set to ignore the existing key * @crkey: The current reservation key to release * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_resv_release(int fd, __u32 nsid, enum nvme_reservation_rtype rtype, enum nvme_reservation_rrela rrela, bool iekey, @@ -2915,8 +2909,8 @@ int nvme_resv_release(int fd, __u32 nsid, enum nvme_reservation_rtype rtype, * registration and reservation status of a namespace. See the defintion for * the returned structure, &struct nvme_reservation_status, for more details. * - * Return: The nvme command status if a response was received or -1 with errno - * set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_resv_report(int fd, __u32 nsid, bool eds, __u32 len, struct nvme_reservation_status *report); diff --git a/src/nvme/tree.c b/src/nvme/tree.c index f4218a398a..05bfe74b3b 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -23,6 +23,9 @@ #include "filters.h" #include "util.h" +/* XXX: Make a place for private declarations */ +extern int nvme_set_attr(const char *dir, const char *attr, const char *value); + struct nvme_path { struct list_node entry; struct list_node nentry; diff --git a/src/nvme/types.h b/src/nvme/types.h index cc139c4fef..02b3a6dc5e 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -22,30 +22,55 @@ #define __force #endif +/** + * cpu_to_le16() - + * @x: 16-bit CPU value to turn to little endian. + */ static inline __le16 cpu_to_le16(uint16_t x) { return (__force __le16)htole16(x); } +/** + * cpu_to_le32() - + * @x: 32-bit CPU value to turn little endian. + */ static inline __le32 cpu_to_le32(uint32_t x) { return (__force __le32)htole32(x); } +/** + * cpu_to_le64() - + * @x: 64-bit CPU value to turn little endian. + */ static inline __le64 cpu_to_le64(uint64_t x) { return (__force __le64)htole64(x); } +/** + * le16_to_cpu() - + * @x: 16-bit little endian value to turn to CPU. + */ static inline uint16_t le16_to_cpu(__le16 x) { return le16toh((__force __u16)x); } +/** + * le32_to_cpu() - + * @x: 32-bit little endian value to turn to CPU. + */ static inline uint32_t le32_to_cpu(__le32 x) { - return le32toh((__force __u32)x); } + return le32toh((__force __u32)x); +} +/** + * le64_to_cpu() - + * @x: 64-bit little endian value to turn to CPU. + */ static inline uint64_t le64_to_cpu(__le64 x) { return le64toh((__force __u64)x); @@ -77,8 +102,12 @@ static inline uint64_t le64_to_cpu(__le64 x) * lba range type * @NVME_LOG_ST_MAX_RESULTS: The largest possible self test result index in the * device self test 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 + * @NVME_NQN_LENGTH: Max length for NVMe Qualified Name. + * @NVMF_TRADDR_SIZE: + * @NVMF_TSAS_SIZE: */ enum nvme_constants { NVME_NSID_ALL = 0xffffffff, @@ -97,7 +126,11 @@ enum nvme_constants { NVME_ID_ND_DESCRIPTOR_MAX = 16, NVME_FEAT_LBA_RANGE_MAX = 64, NVME_LOG_ST_MAX_RESULTS = 20, + NVME_LOG_TELEM_BLOCK_SIZE = 512, NVME_DSM_MAX_RANGES = 256, + NVME_NQN_LENGTH = 256, + NVMF_TRADDR_SIZE = 256, + NVMF_TSAS_SIZE = 256, }; /** @@ -208,7 +241,8 @@ enum { }; /** - * is_64bit_reg() - Checks if offset of the controller register is 64bit or not. + * nvme_is_64bit_reg() - Checks if offset of the controller register is a know + * 64bit value. * @offset: Offset of controller register field in bytes * * This function does not care about transport so that the offset is not going @@ -218,7 +252,7 @@ enum { * * Returns true if given offset is 64bit register, otherwise it returns false. */ -static inline bool is_64bit_reg(__u32 offset) +static inline bool nvme_is_64bit_reg(__u32 offset) { switch (offset) { case NVME_REG_CAP: @@ -619,7 +653,7 @@ struct nvme_id_ctrl { __le32 sgls; __le32 mnan; __u8 rsvd544[224]; - char subnqn[256]; + char subnqn[NVME_NQN_LENGTH]; __u8 rsvd1024[768]; /* Fabrics Only */ @@ -2189,7 +2223,7 @@ struct nvme_persistent_event_log { __le16 ssvid; char sn[20]; char mn[40]; - char subnqn[256]; + char subnqn[NVME_NQN_LENGTH]; __u8 rsvd372; __u8 seb[32]; }; @@ -2771,14 +2805,9 @@ enum nvme_subsys_type { #define NVME_DISC_SUBSYS_NAME "nqn.2014-08.org.nvmexpress.discovery" #define NVME_RDMA_IP_PORT 4420 -/* NQN names in commands fields specified one size */ -#define NVMF_NQN_FIELD_LEN 256 - /* However the max length of a qualified name is another size */ #define NVMF_NQN_SIZE 223 #define NVMF_TRSVCID_SIZE 32 -#define NVMF_TRADDR_SIZE 256 -#define NVMF_TSAS_SIZE 256 /** * struct nvmf_disc_log_entry - Discovery log page entry @@ -2810,7 +2839,7 @@ struct nvmf_disc_log_entry { __u8 resv10[22]; char trsvcid[NVMF_TRSVCID_SIZE]; __u8 resv64[192]; - char subnqn[NVMF_NQN_FIELD_LEN]; + char subnqn[NVME_NQN_LENGTH]; char traddr[NVMF_TRADDR_SIZE]; union tsas { char common[NVMF_TSAS_SIZE]; @@ -2949,8 +2978,8 @@ struct nvmf_connect_data { __u8 hostid[16]; __le16 cntlid; char resv4[238]; - char subsysnqn[NVMF_NQN_FIELD_LEN]; - char hostnqn[NVMF_NQN_FIELD_LEN]; + char subsysnqn[NVME_NQN_LENGTH]; + char hostnqn[NVME_NQN_LENGTH]; char resv5[256]; }; @@ -3267,14 +3296,14 @@ struct nvme_mi_vpd_tra { /** * struct nvme_mi_vpd_mr_common - - * @type; - * @rf; - * @rlen; - * @rchksum; - * @hchksum; -nmra; - * @ppmra; - * @tmra; + * @type: + * @rf: + * @rlen: + * @rchksum: + * @hchksum: + * @nmra: + * @ppmra: + * @tmra: */ struct nvme_mi_vpd_mr_common { __u8 type; @@ -3314,21 +3343,374 @@ struct nvme_mi_vpd_hdr { }; /** - * enum - - */ -enum { + * enum nvme_status_code - Defines all parts of the nvme status field: status + * code, status code type, and additional flags. + * @NVME_SCT_MASK: Mask to get the value of the Status Code Type + * @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_SC_MASK: Mask to get the value of the status code. + * @NVME_SC_SUCCESS: Successful Completion: The command + * completed without error. + * @NVME_SC_INVALID_OPCODE: Invalid Command Opcode: A reserved coded + * 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. + * @NVME_SC_CMDID_CONFLICT: Command ID Conflict: The command + * 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. + * @NVME_SC_POWER_LOSS: Commands Aborted due to Power Loss + * 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. + * @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. + * @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. + * @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. + * @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. + * @NVME_SC_INVALID_NS: Invalid Namespace or Format: The + * 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. + * @NVME_SC_SGL_INVALID_LAST: Invalid SGL Segment Descriptor: The + * 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. + * @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. + * @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. + * @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. + * @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. + * @NVME_SC_AWU_EXCEEDED: Atomic Write Unit Exceeded: The length + * 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. + * @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. + * @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. + * @NVME_SC_KAT_EXPIRED: Keep Alive Timer Expired: The Keep Alive + * Timer expired. + * @NVME_SC_KAT_INVALID: Keep Alive Timeout Invalid: The Keep + * 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. + * @NVME_SC_SANITIZE_FAILED: Sanitize Failed: The most recent sanitize + * 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. + * @NVME_SC_SGL_INVALID_GRANULARITY: SGL Data Block Granularity Invalid: The + * 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. + * @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. + * @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. + * @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. + * @NVME_SC_LBA_RANGE: LBA Out of Range: The command references + * 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. + * @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. + * @NVME_SC_RESERVATION_CONFLICT: Reservation Conflict: The command was + * 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. + * @NVME_SC_CQ_INVALID: Completion Queue Invalid: The Completion + * 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 + * part of the command. An invalid queue + * identifier is one that is currently in + * 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. + * @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. + * @NVME_SC_ABORT_MISSING: Abort Command is missing: The abort + * command is missing. + * @NVME_SC_ASYNC_LIMIT: Asynchronous Event Request Limit + * 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. + * @NVME_SC_FIRMWARE_IMAGE: Invalid Firmware Image: The firmware + * 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. + * @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. + * @NVME_SC_INVALID_FORMAT: Invalid Format: The LBA Format specified + * 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. + * @NVME_SC_INVALID_QUEUE: Invalid Queue Deletion: Invalid I/O + * Completion Queue specified to delete. + * @NVME_SC_FEATURE_NOT_SAVEABLE: Feature Identifier Not Saveable: The + * 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. + * @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. + * @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. + * @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. + * @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. + * @NVME_SC_FW_ACTIVATE_PROHIBITED: Firmware Activation Prohibited: The image + * 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. + * @NVME_SC_NS_INSUFFICIENT_CAP: Namespace Insufficient Capacity: Creating + * 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. + * @NVME_SC_NS_ALREADY_ATTACHED: Namespace Already Attached: The + * 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. + * @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. + * @NVME_SC_THIN_PROV_NOT_SUPP: Thin Provisioning Not Supported: Thin + * provisioning is not supported by the + * controller. + * @NVME_SC_CTRL_LIST_INVALID: Controller List Invalid: The controller + * list provided contains invalid controller + * ids. + * @NVME_SC_SELF_TEST_IN_PROGRESS: Device Self-test In Progress: + * @NVME_SC_BP_WRITE_PROHIBITED: Boot Partition Write Prohibited: The + * 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 + * @NVME_SC_ANA_GROUP_ID_INVALID: ANA Group Identifier Invalid + * @NVME_SC_ANA_ATTACH_FAILED: ANA Attach Failed + * @NVME_SC_BAD_ATTRIBUTES: Conflicting Dataset Management Attributes + * @NVME_SC_INVALID_PI: Invalid Protection Information + * @NVME_SC_READ_ONLY: Attempted Write to Read Only Range + * @NVME_SC_CONNECT_FORMAT: Incompatible Format: The NVM subsystem + * 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. + * @NVME_SC_CONNECT_INVALID_PARAM: Connect Invalid Parameters: One or more + * of the command parameters. + * @NVME_SC_CONNECT_RESTART_DISC: Connect Restart Discovery: The NVM + * 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 + * @NVME_SC_DISCONNECT_INVALID_QTYPE: Invalid Queue Type: The command was sent + * on the wrong queue type. + * @NVME_SC_DISCOVERY_RESTART: Discover Restart: The snapshot of the + * 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. + * @NVME_SC_WRITE_FAULT: Write Fault: The write data could not be + * committed to the media. + * @NVME_SC_READ_ERROR: Unrecovered Read Error: The read data + * 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. + * @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. + * @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. + * @NVME_SC_COMPARE_FAILED: Compare Failure: The command failed due + * 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. + * @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. + * @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. + * @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. + * @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. + * @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. + * @NVME_SC_CTRL_PATH_ERROR: Controller Pathing Error: A pathing error + * was detected by the controller. + * @NVME_SC_HOST_PATH_ERROR: Host Pathing Error: A pathing error was + * detected by the host. + * @NVME_SC_CMD_ABORTED_BY_HOST: Command Aborted By Host: The command was + * aborted as a result of host action. + * @NVME_SC_CRD: Mask to get value of Command Retry Delay + * 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. + * @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. + */ +enum nvme_status_field { /* - * Status code type + * Status Code Type indicators */ + NVME_SCT_MASK = 0x700, NVME_SCT_GENERIC = 0x000, NVME_SCT_CMD_SPECIFIC = 0x100, NVME_SCT_MEDIA = 0x200, NVME_SCT_PATH = 0x300, NVME_SCT_VS = 0x700, - NVME_SCT_MASK = 0x700, /* - * Generic Command Status: + * Status Code inidicators + */ + NVME_SC_MASK = 0xff, + + /* + * Generic Command Status Codes: */ NVME_SC_SUCCESS = 0x0, NVME_SC_INVALID_OPCODE = 0x1, @@ -3353,7 +3735,6 @@ enum { NVME_SC_AWU_EXCEEDED = 0x14, NVME_SC_OP_DENIED = 0x15, NVME_SC_SGL_INVALID_OFFSET = 0x16, - NVME_SC_HOSTID_FORMAT = 0x18, NVME_SC_KAT_EXPIRED = 0x19, NVME_SC_KAT_INVALID = 0x1a, @@ -3365,7 +3746,6 @@ enum { NVME_SC_NS_WRITE_PROTECTED = 0x20, NVME_SC_CMD_INTERRUPTED = 0x21, NVME_SC_TRAN_TPORT_ERROR = 0x22, - NVME_SC_LBA_RANGE = 0x80, NVME_SC_CAP_EXCEEDED = 0x81, NVME_SC_NS_NOT_READY = 0x82, @@ -3373,7 +3753,7 @@ enum { NVME_SC_FORMAT_IN_PROGRESS = 0x84, /* - * Command Specific Status: + * Command Specific Status Codes: */ NVME_SC_CQ_INVALID = 0x00, NVME_SC_QID_INVALID = 0x01, @@ -3429,7 +3809,6 @@ enum { NVME_SC_CONNECT_RESTART_DISC = 0x83, NVME_SC_CONNECT_INVALID_HOST = 0x84, NVME_SC_DISCONNECT_INVALID_QTYPE= 0x85, - NVME_SC_DISCOVERY_RESTART = 0x90, NVME_SC_AUTH_REQUIRED = 0x91, @@ -3452,25 +3831,40 @@ enum { NVME_SC_ANA_PERSISTENT_LOSS = 0x01, NVME_SC_ANA_INACCESSIBLE = 0x02, NVME_SC_ANA_TRANSITION = 0x03, - NVME_SC_CTRL_PATH_ERROR = 0x60, - NVME_SC_HOST_PATH_ERROR = 0x70, NVME_SC_CMD_ABORTED_BY_HOST = 0x71, /* - * Status code mask - */ - NVME_SC_MASK = 0xff, - - /* - * Additional status info + * Additional status field flags */ NVME_SC_CRD = 0x1800, NVME_SC_MORE = 0x2000, NVME_SC_DNR = 0x4000, }; +/** + * nvme_status_code_type() - Returns the NVMe Status Code Type + * @status_field: The NVMe Completion Queue Entry's Status Field + * + * See &enum nvme_status_field + */ +static inline __u16 nvme_status_code_type(__u16 status_field) +{ + return status_field & NVME_SCT_MASK; +} + +/** + * nvme_status_code() - Returns the NVMe Status Code + * @status_field: The NVMe Completion Queue Entry's Status Field + * + * See &enum nvme_status_field + */ +static inline __u16 nvme_status_code(__u16 status_field) +{ + return status_field & NVME_SCT_MASK; +} + #define NVME_MAJOR(ver) ((ver) >> 16) #define NVME_MINOR(ver) (((ver) >> 8) & 0xff) #define NVME_TERTIARY(ver) ((ver) & 0xff) diff --git a/src/nvme/util.c b/src/nvme/util.c index 8acaa6d13d..86a2ad0ef1 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -7,7 +7,6 @@ * Chaitanya Kulkarni */ -#include #include #include #include @@ -16,7 +15,6 @@ #include #include -#include #include #include #include @@ -24,7 +22,6 @@ #include #include "filters.h" -#include "ioctl.h" #include "util.h" #include "tree.h" @@ -138,17 +135,15 @@ static inline __u8 nvme_fabrics_status_to_errno(__u16 status) __u8 nvme_status_to_errno(int status, bool fabrics) { - __u16 sc, sct; + __u16 sc; if (!status) return 0; if (status < 0) return errno; - sc = status & NVME_SC_MASK; - sct = status & NVME_SCT_MASK; - - switch (sct) { + sc = nvme_status_code(status); + switch (nvme_status_code_type(status)) { case NVME_SCT_GENERIC: return nvme_generic_status_to_errno(sc); case NVME_SCT_CMD_SPECIFIC: @@ -156,10 +151,6 @@ __u8 nvme_status_to_errno(int status, bool fabrics) return nvme_fabrics_status_to_errno(sc); return nvme_cmd_specific_status_to_errno(sc); default: - /* - * Media, integrity related status, and the others will be - * mapped to EIO. - */ return EIO; } } @@ -282,14 +273,14 @@ int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, } static int nvme_get_telemetry_log(int fd, bool create, bool ctrl, bool rae, - void **buf, __u32 *log_size) + struct nvme_telemetry_log **buf) { - static const __u32 xfer = 512; + static const __u32 xfer = NVME_LOG_TELEM_BLOCK_SIZE; struct nvme_telemetry_log *telem; + enum nvme_cmd_get_log_lid lid; + void *log, *tmp; __u32 size; - __u8 lid; - void *log; int err; log = malloc(xfer); @@ -314,47 +305,47 @@ static int nvme_get_telemetry_log(int fd, bool create, bool ctrl, bool rae, telem = log; if (ctrl && !telem->ctrlavail) { - size = xfer; - goto done; + *buf = log; + return 0; } - size = (le16_to_cpu(telem->dalb3) * xfer) + xfer; - log = realloc(log, size); - if (!log) { + /* dalb3 >= dalb2 >= dalb1 */ + size = (le16_to_cpu(telem->dalb3) + 1) * xfer; + tmp = realloc(log, size); + if (!tmp) { errno = ENOMEM; err = -1; goto free; } + log = tmp; err = nvme_get_log_page(fd, NVME_NSID_NONE, lid, rae, size, (void *)log); - if (err) - goto free; -done: - *log_size = size; - *buf = log; - return 0; + if (!err) { + *buf = log; + return 0; + } free: free(log); return err; } -int nvme_get_ctrl_telemetry(int fd, bool rae, void **buf, __u32 *log_size) +int nvme_get_ctrl_telemetry(int fd, bool rae, struct nvme_telemetry_log **log) { - return nvme_get_telemetry_log(fd, false, true, rae, buf, log_size); + return nvme_get_telemetry_log(fd, false, true, rae, log); } -int nvme_get_host_telemetry(int fd, void **buf, __u32 *log_size) +int nvme_get_host_telemetry(int fd, struct nvme_telemetry_log **log) { - return nvme_get_telemetry_log(fd, false, false, false, buf, log_size); + return nvme_get_telemetry_log(fd, false, false, false, log); } -int nvme_get_new_host_telemetry(int fd, void **buf, __u32 *log_size) +int nvme_get_new_host_telemetry(int fd, struct nvme_telemetry_log **log) { - return nvme_get_telemetry_log(fd, true, false, false, buf, log_size); + return nvme_get_telemetry_log(fd, true, false, false, log); } -void nvme_setup_dsm_range(struct nvme_dsm_range *dsm, __u32 *ctx_attrs, - __u32 *llbas, __u64 *slbas, __u16 nr_ranges) +void nvme_init_dsm_range(struct nvme_dsm_range *dsm, __u32 *ctx_attrs, + __u32 *llbas, __u64 *slbas, __u16 nr_ranges) { int i; @@ -365,7 +356,7 @@ void nvme_setup_dsm_range(struct nvme_dsm_range *dsm, __u32 *ctx_attrs, } } -void nvme_setup_id_ns(struct nvme_id_ns *ns, __u64 nsze, __u64 ncap, __u8 flbas, +void nvme_init_id_ns(struct nvme_id_ns *ns, __u64 nsze, __u64 ncap, __u8 flbas, __u8 dps, __u8 nmic, __u32 anagrpid, __u16 nvmsetid) { memset(ns, 0, sizeof(*ns)); @@ -378,7 +369,7 @@ void nvme_setup_id_ns(struct nvme_id_ns *ns, __u64 nsze, __u64 ncap, __u8 flbas, ns->nvmsetid = cpu_to_le16(nvmsetid); } -void nvme_setup_ctrl_list(struct nvme_ctrl_list *cntlist, __u16 num_ctrls, +void nvme_init_ctrl_list(struct nvme_ctrl_list *cntlist, __u16 num_ctrls, __u16 *ctrlist) { int i; @@ -397,7 +388,7 @@ static int nvme_ns_attachment(int fd, __u32 nsid, __u16 num_ctrls, if (attach) sel = NVME_NS_ATTACH_SEL_CTRL_ATTACH; - nvme_setup_ctrl_list(&cntlist, num_ctrls, ctrlist); + nvme_init_ctrl_list(&cntlist, num_ctrls, ctrlist); return nvme_ns_attach(fd, nsid, sel, &cntlist); } @@ -419,10 +410,8 @@ int nvme_get_ana_log_len(int fd, size_t *analen) int ret; ret = nvme_identify_ctrl(fd, &ctrl); - if (ret) { - errno = nvme_status_to_errno(ret, false); - return -1; - } + if (ret) + return ret; *analen = sizeof(struct nvme_ana_log) + le32_to_cpu(ctrl.nanagrpid) * sizeof(struct nvme_ana_group_desc) + diff --git a/src/nvme/util.h b/src/nvme/util.h index bed6396d66..c980322504 100644 --- a/src/nvme/util.h +++ b/src/nvme/util.h @@ -9,138 +9,159 @@ #ifndef _LIBNVME_UTIL_H #define _LIBNVME_UTIL_H -#include -#include - #include "ioctl.h" /** * nvme_status_to_errno() - Converts nvme return status to errno - * @status: Return status from an nvme passthrough commmand - * @fabrics: true if given status is for fabrics - * - * If status < 0, errno is already set. + * @status: Return status from an nvme passthrough commmand + * @fabrics: Set to true if &status is to a fabrics target. * - * Return: Appropriate errno for the given nvme status + * Return: An errno representing the nvme status if it is an nvme status field, + * or unchanged status is < 0 since errno is already set. */ __u8 nvme_status_to_errno(int status, bool fabrics); /** * nvme_fw_download_seq() - - * @fd: - * @size: - * @xfer: - * @offset: - * @buf: + * @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 + * @buf: Address of buffer containing all or part of the firmware image. * - * Return: + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_fw_download_seq(int fd, __u32 size, __u32 xfer, __u32 offset, void *buf); /** * nvme_get_ctrl_telemetry() - - * @fd: - * @rae: - * @buf: - * @log_size: + * @fd: File descriptor of nvme device + * @rae: Retain asynchronous events + * @log: On success, set to the value of the allocated and retreived log. * - * Returns: + * The total size allocated can be calculated as: + * (&struct nvme_telemetry_log.dalb3 + 1) * %NVME_LOG_TELEM_BLOCK_SIZE. + * + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ -int nvme_get_ctrl_telemetry(int fd, bool rae, void **buf, __u32 *log_size); +int nvme_get_ctrl_telemetry(int fd, bool rae, struct nvme_telemetry_log **log); /** * nvme_get_host_telemetry() - - * @fd: - * @buf: - * @log_size: + * @fd: File descriptor of nvme device + * @log: On success, set to the value of the allocated and retreived log. + * + * The total size allocated can be calculated as: + * (&struct nvme_telemetry_log.dalb3 + 1) * %NVME_LOG_TELEM_BLOCK_SIZE. * - * Returns: + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ -int nvme_get_host_telemetry(int fd, void **buf, __u32 *log_size); +int nvme_get_host_telemetry(int fd, struct nvme_telemetry_log **log); /** * nvme_get_new_host_telemetry() - - * @fd: - * @buf: - * @log_size: + * @fd: File descriptor of nvme device + * @log: On success, set to the value of the allocated and retreived log. * - * Returns: + * The total size allocated can be calculated as: + * (&struct nvme_telemetry_log.dalb3 + 1) * %NVME_LOG_TELEM_BLOCK_SIZE. + * + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ -int nvme_get_new_host_telemetry(int fd, void **buf, __u32 *log_size); +int nvme_get_new_host_telemetry(int fd, struct nvme_telemetry_log **log); /** - * nvme_setup_id_ns() - - * @ns: - * @nsze: - * @ncap: - * @flbas: - * @dps: - * @nmic: - * @anagrpid: - * @nvmsetid: + * nvme_init_id_ns() - Initialize an Identify Namepsace structure for creation. + * @ns: Address of the Identify Namespace structure to initialize + * @nsze: Namespace size + * @ncap: namespace capacity + * @flbas: formatted logical block size settings + * @dps: Data protection settings + * @nmic: Namespace sharing capabilities + * @anagrpid: ANA group identifier + * @nvmsetid: NVM Set identifer + * + * This is intended to be used with a namespace management "create", see + * &nvme_ns_mgmt_create(). */ -void nvme_setup_id_ns(struct nvme_id_ns *ns, __u64 nsze, __u64 ncap, __u8 flbas, - __u8 dps, __u8 nmic, __u32 anagrpid, __u16 nvmsetid); +void nvme_init_id_ns(struct nvme_id_ns *ns, __u64 nsze, __u64 ncap, __u8 flbas, + __u8 dps, __u8 nmic, __u32 anagrpid, __u16 nvmsetid); /** - * nvme_setup_ctrl_list() - - * @cntlist: - * @num_ctrls: - * @ctrlist: + * nvme_init_ctrl_list() - Initialize an nvme_ctrl_list structure from an array. + * @cntlist: The controller list structure to initialize + * @num_ctrls: The number of controllers in the array, &ctrlist. + * @ctrlist: An array of controller identifiers in CPU native endian. + * + * This is intended to be used with any command that takes a controller list + * argument. See &nvme_ns_attach_ctrls() and &nvme_ns_detach(). */ -void nvme_setup_ctrl_list(struct nvme_ctrl_list *cntlist, __u16 num_ctrls, - __u16 *ctrlist); +void nvme_init_ctrl_list(struct nvme_ctrl_list *cntlist, __u16 num_ctrls, + __u16 *ctrlist); /** - * nvme_dsm_range() - Constructs a data set range structure + * nvme_init_dsm_range() - Constructs a data set range structure * @dsm: DSM range array * @ctx_attrs: Array of context attributes * @llbas: Array of length in logical blocks * @slbas: Array of starting logical blocks * @nr_ranges: The size of the dsm arrays * - * Each array must be the same size of size 'nr_ranges'. + * Each array must be the same size of size 'nr_ranges'. This is intended to be + * used with constructing a payload for &nvme_dsm(). * * Return: The nvme command status if a response was received or -errno * otherwise. */ -void nvme_setup_dsm_range(struct nvme_dsm_range *dsm, __u32 *ctx_attrs, +void nvme_init_dsm_range(struct nvme_dsm_range *dsm, __u32 *ctx_attrs, __u32 *llbas, __u64 *slbas, __u16 nr_ranges); /** * __nvme_get_log_page() - - * @fd: - * @nsid: - * @log_id: - * @rae: - * @xfer_len: Max partial log transfer size to request while splitting - * @data_len: - * @data: + * @fd: File descriptor of nvme device + * @nsid: Namespace Identifier, if applicable. + * @log_id: Log Identifier, see &enum nvme_cmd_get_log_lid. + * @rae: Retain asynchronous events + * @xfer_len: Max log transfer size per request to split the total. + * @data_len: Total length of the log to transfer. + * @data: User address of at least &data_len to store the log. + * + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int __nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, - __u32 xfer_len, __u32 data_len, void *data); + __u32 xfer_len, __u32 data_len, void *data); /** * nvme_get_log_page() - - * @fd: - * @nsid: - * @log_id: - * @rae: - * @data_len: - * @data: + * @fd: File descriptor of nvme device + * @nsid: Namespace Identifier, if applicable. + * @log_id: Log Identifier, see &enum nvme_cmd_get_log_lid. + * @rae: Retain asynchronous events + * @data_len: Total length of the log to transfer. + * @data: User address of at least &data_len to store the log. + * + * Calls __nvme_get_log_page() with a default 4k transfer length, as that is + * guarnateed by the protocol to be a safe transfer size. * - * Calls __nvme_get_log_page() with a default 4k transfer length. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, - __u32 data_len, void *data); + __u32 data_len, void *data); /** * nvme_get_ana_log_len() - Retreive size of the current ANA log * @fd: File descriptor of nvme device * @analen: Pointer to where the length will be set on success * - * Return: 0 on success, -1 otherwise with errno set + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_ana_log_len(int fd, size_t *analen); @@ -151,8 +172,8 @@ int nvme_get_ana_log_len(int fd, size_t *analen); * @num_ctrls: Number of controllers in ctrlist * @ctrlist: List of controller IDs to perform the attach action * - * Return: The nvme command status if a response was received or -1 - * with errno set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_namespace_attach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist); @@ -163,37 +184,39 @@ int nvme_namespace_attach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrl * @num_ctrls: Number of controllers in ctrlist * @ctrlist: List of controller IDs to perform the detach action * - * Return: The nvme command status if a response was received or -1 - * with errno set otherwise. + * Return: The nvme command status if a response was received (see &enum + * nvme_status_field) or -1 with errno set otherwise. */ int nvme_namespace_detach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist); /** * nvme_get_feature_length() - Retreive the command payload length for a * specific feature identifier - * @fid: - * @cdw11: - * @len: + * @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) + * @len: On success, set to this features payload length in bytes. * - * Return: 0 on success, -1 with errno set otherwise + * Return: 0 on success, -1 with errno set to EINVAL if the function did not + * recognize &fid. */ int nvme_get_feature_length(int fid, __u32 cdw11, __u32 *len); /** * nvme_get_directive_receive_length() - - * @dtype: Directive type, see &enum nvme_directive_dtype - * @doper: Directive receive operation, see &enum nvme_directive_receive_doper - * @len: Address to save the payload length of the directive in bytes on - * a successful decode + * @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. * - * Return: 0 on success, -1 with errno set to EINVAL. + * Return: 0 on success, -1 with errno set to EINVAL if the function did not + * recognize &dtype or &doper. */ int nvme_get_directive_receive_length(enum nvme_directive_dtype dtype, enum nvme_directive_receive_doper doper, __u32 *len); /** * nvme_open() - Open an nvme controller or namespace device - * @name: The basename of the device to open + * @name: The basename of the device to open * * This will look for the handle in /dev/ and validate the name and filetype * match linux conventions. @@ -203,14 +226,4 @@ int nvme_get_directive_receive_length(enum nvme_directive_dtype dtype, */ int nvme_open(const char *name); -/** - * nvme_set_attr() - - * @dir: - * @attr: - * @value: - * - * Return - */ -int nvme_set_attr(const char *dir, const char *attr, const char *value); - #endif /* _LIBNVME_UTIL_H */ From 8c92b6d3286179e719d4d0f2f1ec4e089b16d7c2 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Fri, 14 Feb 2020 15:57:31 -0800 Subject: [PATCH 0032/1564] Update .gitignore Update ccan artifacts to their correct directory. Signed-off-by: Keith Busch --- .gitignore | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 8ff3e73c89..37f41682a9 100644 --- a/.gitignore +++ b/.gitignore @@ -15,8 +15,8 @@ examples/display-columnar examples/telemetry-listen examples/discover-loop -src/ccan/config.h -src/ccan/tools/configurator/configurator +ccan/config.h +ccan/tools/configurator/configurator config-host.h config-host.mak From 147f49f1261c055a84839fce0bc1eb50905a9044 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Sat, 15 Feb 2020 10:25:47 -0800 Subject: [PATCH 0033/1564] Integration fixes Fix up inconsistencies and missing features discovered while integrating with nvme-cli. Signed-off-by: Keith Busch --- src/nvme/ioctl.c | 4 +- src/nvme/ioctl.h | 11 +++-- src/nvme/types.h | 110 ++++++++++++++++++++++++++--------------------- src/nvme/util.c | 2 +- 4 files changed, 72 insertions(+), 55 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 3b9f035d77..28aee2d3cf 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -904,7 +904,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) { - return __nvme_set_features(fd, NVME_FEAT_RESV_PERSIST, !!ptpl, save, + return __nvme_set_features(fd, NVME_FEAT_FID_RESV_PERSIST, !!ptpl, save, result); } @@ -1122,7 +1122,7 @@ int nvme_get_features_resv_mask(int fd, enum nvme_get_features_sel sel, int nvme_get_features_resv_persist(int fd, enum nvme_get_features_sel sel, __u32 *result) { - return __nvme_get_features(fd, NVME_FEAT_RESV_PERSIST, sel, result); + return __nvme_get_features(fd, NVME_FEAT_FID_RESV_PERSIST, sel, result); } int nvme_get_features_write_protect(int fd, __u32 nsid, diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index c96c24d85d..fe4d664a65 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -20,6 +20,9 @@ #ifndef _UAPI_LINUX_NVME_IOCTL_H #define _UAPI_LINUX_NVME_IOCTL_H +#ifndef _LINUX_NVME_IOCTL_H +#define _LINUX_NVME_IOCTL_H + /** * struct nvme_passthru_cmd - * @opcode: Operation code, see &enum nvme_io_opcodes and &enum nvme_admin_opcodes @@ -117,6 +120,8 @@ struct nvme_passthru_cmd64 { #endif /* _UAPI_LINUX_NVME_IOCTL_H */ +#endif /* _LINUX_NVME_IOCTL_H */ + /** * nvme_submit_admin_passthru64() - Submit a 64-bit nvme passthrough admin * command @@ -526,7 +531,7 @@ enum nvme_cmd_get_log_lid { * @NVME_FEAT_FID_SW_PROGRESS: * @NVME_FEAT_FID_HOST_ID: * @NVME_FEAT_FID_RESV_MASK: - * @NVME_FEAT_RESV_PERSIST: + * @NVME_FEAT_FID_RESV_PERSIST: * @NVME_FEAT_FID_WRITE_PROTECT: */ enum nvme_features_id { @@ -557,7 +562,7 @@ enum nvme_features_id { NVME_FEAT_FID_SW_PROGRESS = 0x80, NVME_FEAT_FID_HOST_ID = 0x81, NVME_FEAT_FID_RESV_MASK = 0x82, - NVME_FEAT_RESV_PERSIST = 0x83, + NVME_FEAT_FID_RESV_PERSIST = 0x83, NVME_FEAT_FID_WRITE_PROTECT = 0x84, }; @@ -2409,7 +2414,7 @@ int nvme_set_property(int fd, int offset, __u64 value); int nvme_get_property(int fd, int offset, __u64 *value); /** - * nvme_sanitize() - Start a sanitize operation + * nvme_sanitize_nvme() - Start a sanitize operation * @fd: File descriptor of nvme device * @sanact: Sanitize action, see &enum nvme_sanitize_sanact * @ause: Set to allow unrestriced sanitize exit diff --git a/src/nvme/types.h b/src/nvme/types.h index 02b3a6dc5e..88ccb9c98a 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -131,12 +131,14 @@ enum nvme_constants { NVME_NQN_LENGTH = 256, NVMF_TRADDR_SIZE = 256, NVMF_TSAS_SIZE = 256, + NVME_NIDT_EUI64_LEN = 8, + NVME_NIDT_NGUID_LEN = 16, }; /** - * enum nvme_registers - The nvme controller registers for all transports. This - * is the layout of BAR0/1 for PCIe, and properties for - * fabrics. + * enum nvme_register_offsets - The nvme controller registers for all transports. This + * 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 @@ -162,7 +164,7 @@ enum nvme_constants { * @NVME_REG_PMRMSC: Persistent Memory Region Controller Memory Space Control * @NVME_REG_DBS: SQ 0 Tail Doorbell */ -enum nvme_registers { +enum nvme_register_offsets { NVME_REG_CAP = 0x0000, NVME_REG_VS = 0x0008, NVME_REG_INTMS = 0x000c, @@ -1852,24 +1854,16 @@ enum { NVME_SMART_EGCW_RO = 1 << 3, }; -/** - * struct nvme_frs - - * @frs: - */ -struct nvme_frs { - char frs[8]; -}; - /** * struct nvme_firmware_slot - * @afi: * @frs: */ struct nvme_firmware_slot { - __u8 afi; - __u8 resv[7]; - struct nvme_frs frs[7]; - __u8 resv2[448]; + __u8 afi; + __u8 resv[7]; + char frs[7][8]; + __u8 resv2[448]; }; /** @@ -1941,6 +1935,7 @@ struct nvme_st_result { * @NVME_ST_RESULT_ABORTED_UNKNOWN: * @NVME_ST_RESULT_ABORTED_SANITIZE: * @NVME_ST_RESULT_NOT_USED: + * @NVME_ST_RESULT_NOT_MASK: */ enum { NVME_ST_RESULT_NO_ERR = 0x0, @@ -1954,20 +1949,22 @@ enum { NVME_ST_RESULT_ABORTED_UNKNOWN = 0x8, NVME_ST_RESULT_ABORTED_SANITIZE = 0x9, NVME_ST_RESULT_NOT_USED = 0xf, + NVME_ST_RESULT_NOT_MASK = 0xf, }; /** * enum - - * @NVME_ST_OPERATION_NONE: - * @NVME_ST_OPERATION_SHORT: - * @NVME_ST_OPERATION_EXTENDED: - * @NVME_ST_OPERATION_VS: + * @NVME_ST_CODE_NONE: + * @NVME_ST_CODE_SHORT: + * @NVME_ST_CODE_EXTENDED: + * @NVME_ST_CODE_VS: */ enum { - NVME_ST_OPERATION_NONE = 0x0, - NVME_ST_OPERATION_SHORT = 0x1, - NVME_ST_OPERATION_EXTENDED = 0x2, - NVME_ST_OPERATION_VS = 0xe, + NVME_ST_CODE_SHIFT = 4, + NVME_ST_CODE_RESRVED = 0x0, + NVME_ST_CODE_SHORT = 0x1, + NVME_ST_CODE_EXTENDED = 0x2, + NVME_ST_CODE_VS = 0xe, }; /** @@ -2165,14 +2162,14 @@ struct nvme_ana_group_desc { }; /** - * enum - + * 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 { +enum nvme_ana_state { NVME_ANA_STATE_OPTIMIZED = 0x1, NVME_ANA_STATE_NONOPTIMIZED = 0x2, NVME_ANA_STATE_INACCESSIBLE = 0x3, @@ -2347,19 +2344,24 @@ struct nvme_sanitize_log_page { }; /** - * enum - - * @NVME_SANITIZE_SSTAT_NEVER_SANITIZED: - * @NVME_SANITIZE_SSTAT_COMPLETE_SUCCESS: - * @NVME_SANITIZE_SSTAT_IN_PROGESS: - * @NVME_SANITIZE_SSTAT_COMPLETED_FAILED: - * @NVME_SANITIZE_SSTAT_ND_COMPLETE_SUCCESS: + * enum nvme_sanitize_sstat - + * @NVME_SANITIZE_SSTAT_STATUS_MASK: + * @NVME_SANITIZE_SSTAT_STATUS_NEVER_SANITIZED: + * @NVME_SANITIZE_SSTAT_STATUS_COMPLETE_SUCCESS: + * @NVME_SANITIZE_SSTAT_STATUS_IN_PROGESS: + * @NVME_SANITIZE_SSTAT_STATUS_COMPLETED_FAILED: + * @NVME_SANITIZE_SSTAT_STATUS_ND_COMPLETE_SUCCESS: */ -enum { - NVME_SANITIZE_SSTAT_NEVER_SANITIZED = 0, - NVME_SANITIZE_SSTAT_COMPLETE_SUCCESS = 1, - NVME_SANITIZE_SSTAT_IN_PROGESS = 2, - NVME_SANITIZE_SSTAT_COMPLETED_FAILED = 3, - NVME_SANITIZE_SSTAT_ND_COMPLETE_SUCCESS = 4, +enum nvme_sanitize_sstat { + NVME_SANITIZE_SSTAT_STATUS_MASK = 0x7, + NVME_SANITIZE_SSTAT_STATUS_NEVER_SANITIZED = 0, + NVME_SANITIZE_SSTAT_STATUS_COMPLETE_SUCCESS = 1, + NVME_SANITIZE_SSTAT_STATUS_IN_PROGESS = 2, + NVME_SANITIZE_SSTAT_STATUS_COMPLETED_FAILED = 3, + NVME_SANITIZE_SSTAT_STATUS_ND_COMPLETE_SUCCESS = 4, + NVME_SANITIZE_SSTAT_COMPLETED_PASSES_MASK = 0xf8, + NVME_SANITIZE_SSTAT_COMPLETED_PASSES_SHIFT = 3, + NVME_SANITIZE_SSTAT_GLOBAL_DATA_ERASED = 1 << 8, }; /** @@ -3343,8 +3345,8 @@ struct nvme_mi_vpd_hdr { }; /** - * enum nvme_status_code - Defines all parts of the nvme status field: status - * code, status code type, and additional flags. + * enum nvme_status_field - Defines all parts of the nvme status field: status + * code, status code type, and additional flags. * @NVME_SCT_MASK: Mask to get the value of the Status Code Type * @NVME_SCT_GENERIC: Generic errors applicable to multiple opcodes * @NVME_SCT_CMD_SPECIFIC: Errors associated to a specific opcode @@ -3355,13 +3357,16 @@ struct nvme_mi_vpd_hdr { * @NVME_SC_SUCCESS: Successful Completion: The command * 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. * @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 @@ -3387,11 +3392,14 @@ struct nvme_mi_vpd_hdr { * 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 @@ -3415,7 +3423,8 @@ struct nvme_mi_vpd_hdr { * 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 @@ -3443,9 +3452,11 @@ struct nvme_mi_vpd_hdr { * @NVME_SC_KAT_INVALID: Keep Alive Timeout Invalid: The Keep * 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 @@ -3698,6 +3709,7 @@ enum nvme_status_field { * Status Code Type indicators */ NVME_SCT_MASK = 0x700, + NVME_SCT_SHIFT = 0x700, NVME_SCT_GENERIC = 0x000, NVME_SCT_CMD_SPECIFIC = 0x100, NVME_SCT_MEDIA = 0x200, diff --git a/src/nvme/util.c b/src/nvme/util.c index 86a2ad0ef1..8461e6a3ae 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -461,7 +461,7 @@ int nvme_get_feature_length(int fid, __u32 cdw11, __u32 *len) case NVME_FEAT_FID_ENDURANCE_EVT_CFG: case NVME_FEAT_FID_SW_PROGRESS: case NVME_FEAT_FID_RESV_MASK: - case NVME_FEAT_RESV_PERSIST: + case NVME_FEAT_FID_RESV_PERSIST: case NVME_FEAT_FID_WRITE_PROTECT: *len = 0; break; From 6aa114f8a58222d38bfc9e083e804f1b50ad7401 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Sat, 15 Feb 2020 10:31:51 -0800 Subject: [PATCH 0034/1564] Fix typo in comments Signed-off-by: Keith Busch --- src/nvme/ioctl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index fe4d664a65..6e315fe906 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -2414,7 +2414,7 @@ int nvme_set_property(int fd, int offset, __u64 value); int nvme_get_property(int fd, int offset, __u64 *value); /** - * nvme_sanitize_nvme() - Start a sanitize operation + * nvme_sanitize_nvm() - Start a sanitize operation * @fd: File descriptor of nvme device * @sanact: Sanitize action, see &enum nvme_sanitize_sanact * @ause: Set to allow unrestriced sanitize exit From c28880070c0fb520d9e623b93eb99a4e99666637 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Sun, 16 Feb 2020 19:03:32 -0800 Subject: [PATCH 0035/1564] Testing rst html options Signed-off-by: Keith Busch --- doc/conf.py | 21 +- doc/libnvme.rst | 7077 ++++++++++++++++++++++++---------------------- src/nvme/types.h | 73 +- 3 files changed, 3778 insertions(+), 3393 deletions(-) diff --git a/doc/conf.py b/doc/conf.py index 745075b25c..c1233e91c2 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -47,9 +47,26 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = 'alabaster' +#html_theme = 'alabaster' # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] +html_static_path = ['sphinx-static'] +html_context = { + 'css_files': [ + '_static/theme_overrides.css', + ], +} + +html_use_smartypants = False +pygments_style = 'sphinx' + +htmlhelp_basename = 'libnvme' + +try: + import sphinx_rtd_theme + html_theme = 'sphinx_rtd_theme' + html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] +except ImportError: + sys.stderr.write('Warning: The Sphinx \'sphinx_rtd_theme\' HTML theme was not found. Make sure you have the theme installed to produce pretty HTML output. Falling back to the default theme.\n') diff --git a/doc/libnvme.rst b/doc/libnvme.rst index 7a18d40a4e..e6493348fa 100644 --- a/doc/libnvme.rst +++ b/doc/libnvme.rst @@ -1,263 +1,5 @@ -.. c:type:: struct nvme_fabrics_config - - -**Definition** - -:: - - struct nvme_fabrics_config { - const char *transport; - const char *traddr; - const char *trsvcid; - const char *nqn; - const char *hostnqn; - const char *host_traddr; - const char *hostid; - int queue_size; - int nr_io_queues; - int reconnect_delay; - int ctrl_loss_tmo; - int keep_alive_tmo; - int nr_write_queues; - int nr_poll_queues; - int tos; - bool duplicate_connect; - bool disable_sqflow; - bool hdr_digest; - bool data_digest; - uint8_t rsvd[0x200]; - }; - -**Members** - - - -.. c:function:: int nvmf_add_ctrl_opts (struct nvme_fabrics_config * cfg) - - -**Parameters** - -``struct nvme_fabrics_config * cfg`` - *undescribed* - - -.. c:function:: nvme_ctrl_t nvmf_add_ctrl (struct nvme_fabrics_config * cfg) - - -**Parameters** - -``struct nvme_fabrics_config * cfg`` - *undescribed* - - -.. c:function:: int nvmf_get_discovery_log (nvme_ctrl_t c, struct nvmf_discovery_log ** logp, int max_retries) - - -**Parameters** - -``nvme_ctrl_t c`` - *undescribed* - -``struct nvmf_discovery_log ** logp`` - *undescribed* - -``int max_retries`` - *undescribed* - - -.. c:function:: char * nvmf_hostnqn_generate () - - -**Parameters** - - -.. c:function:: char * nvmf_hostnqn_from_file () - - -**Parameters** - - -.. c:function:: char * nvmf_hostid_from_file () - - -**Parameters** - - -.. c:function:: const char * nvmf_trtype_str (__u8 trtype) - - -**Parameters** - -``__u8 trtype`` - *undescribed* - - -.. c:function:: const char * nvmf_adrfam_str (__u8 adrfam) - - -**Parameters** - -``__u8 adrfam`` - *undescribed* - - -.. c:function:: const char * nvmf_subtype_str (__u8 subtype) - - -**Parameters** - -``__u8 subtype`` - *undescribed* - - -.. c:function:: const char * nvmf_treq_str (__u8 treq) - - -**Parameters** - -``__u8 treq`` - *undescribed* - - -.. c:function:: const char * nvmf_sectype_str (__u8 sectype) - - -**Parameters** - -``__u8 sectype`` - *undescribed* - - -.. c:function:: const char * nvmf_prtype_str (__u8 prtype) - - -**Parameters** - -``__u8 prtype`` - *undescribed* - - -.. c:function:: const char * nvmf_qptype_str (__u8 qptype) - - -**Parameters** - -``__u8 qptype`` - *undescribed* - - -.. c:function:: const char * nvmf_cms_str (__u8 cm) - - -**Parameters** - -``__u8 cm`` - *undescribed* - - -.. c:function:: nvme_ctrl_t nvmf_connect_disc_entry (struct nvmf_disc_log_entry * e, const struct nvme_fabrics_config * defcfg, bool * discover) - - -**Parameters** - -``struct nvmf_disc_log_entry * e`` - *undescribed* - -``const struct nvme_fabrics_config * defcfg`` - *undescribed* - -``bool * discover`` - *undescribed* - - -.. c:function:: int nvme_namespace_filter (const struct dirent * d) - - -**Parameters** - -``const struct dirent * d`` - - -.. c:function:: int nvme_paths_filter (const struct dirent * d) - - -**Parameters** - -``const struct dirent * d`` - - -.. c:function:: int nvme_ctrls_filter (const struct dirent * d) - - -**Parameters** - -``const struct dirent * d`` - - -.. c:function:: int nvme_subsys_filter (const struct dirent * d) - - -**Parameters** - -``const struct dirent * d`` - - -.. c:function:: int nvme_scan_subsystems (struct dirent *** subsys) - - -**Parameters** - -``struct dirent *** subsys`` - - -.. c:function:: int nvme_scan_subsystem_ctrls (nvme_subsystem_t s, struct dirent *** ctrls) - - -**Parameters** - -``nvme_subsystem_t s`` - *undescribed* - -``struct dirent *** ctrls`` - - -.. c:function:: int nvme_scan_subsystem_namespaces (nvme_subsystem_t s, struct dirent *** namespaces) - - -**Parameters** - -``nvme_subsystem_t s`` - *undescribed* - -``struct dirent *** namespaces`` - - -.. c:function:: int nvme_scan_ctrl_namespace_paths (nvme_ctrl_t c, struct dirent *** namespaces) - - -**Parameters** - -``nvme_ctrl_t c`` - *undescribed* - -``struct dirent *** namespaces`` - - -.. c:function:: int nvme_scan_ctrl_namespaces (nvme_ctrl_t c, struct dirent *** namespaces) - - -**Parameters** - -``nvme_ctrl_t c`` - *undescribed* - -``struct dirent *** namespaces`` - - - - .. c:type:: struct nvme_passthru_cmd @@ -457,8 +199,8 @@ Uses NVME_IOCTL_ADMIN64_CMD for the ioctl request. **Return** -The nvme command status if a response was received or -1 - with errno set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_admin_passthru64 (int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, __u32 data_len, void * data, __u32 metadata_len, void * metadata, __u32 timeout_ms, __u64 * result) @@ -533,8 +275,8 @@ Known values for **opcode** are defined in :c:type:`enum nvme_admin_opcode `) or -1 with errno set otherwise. .. c:function:: int nvme_submit_admin_passthru (int fd, struct nvme_passthru_cmd * cmd, __u32 * result) @@ -558,8 +300,8 @@ Uses NVME_IOCTL_ADMIN_CMD for the ioctl request. **Return** -The nvme command status if a response was received or -1 - with errno set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_admin_passthru (int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, __u32 data_len, void * data, __u32 metadata_len, void * metadata, __u32 timeout_ms, __u32 * result) @@ -634,8 +376,8 @@ Known values for **opcode** are defined in :c:type:`enum nvme_admin_opcode `) or -1 with errno set otherwise. .. c:function:: int nvme_submit_io_passthru64 (int fd, struct nvme_passthru_cmd64 * cmd, __u64 * result) @@ -659,8 +401,8 @@ Uses NVME_IOCTL_IO64_CMD for the ioctl request. **Return** -The nvme command status if a response was received or -1 - with errno set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_io_passthru64 (int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, __u32 data_len, void * data, __u32 metadata_len, void * metadata, __u32 timeout_ms, __u64 * result) @@ -735,8 +477,8 @@ Known values for **opcode** are defined in :c:type:`enum nvme_io_opcode `) or -1 with errno set otherwise. .. c:function:: int nvme_submit_io_passthru (int fd, struct nvme_passthru_cmd * cmd, __u32 * result) @@ -760,8 +502,8 @@ Uses NVME_IOCTL_IO_CMD for the ioctl request. **Return** -The nvme command status if a response was received or -1 - with errno set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_io_passthru (int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, __u32 data_len, void * data, __u32 metadata_len, void * metadata, __u32 timeout_ms, __u32 * result) @@ -836,8 +578,8 @@ Known values for **opcode** are defined in :c:type:`enum nvme_io_opcode `) or -1 with errno set otherwise. .. c:function:: int nvme_subsystem_reset (int fd) @@ -914,9 +656,6 @@ The namespace identifier if a succecssful or -1 with errno set otherwise. -**NVMe Admin command enums** - - .. c:type:: enum nvme_admin_opcode @@ -1510,8 +1249,8 @@ the NVM subsystem, the controller or the namespace(s). **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_identify_ctrl (int fd, struct nvme_id_ctrl * id) @@ -1535,8 +1274,8 @@ See :c:type:`struct nvme_id_ctrl ` for details on the data returne **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_identify_ns (int fd, __u32 nsid, struct nvme_id_ns * ns) @@ -1569,8 +1308,8 @@ See :c:type:`struct nvme_id_ns ` for details on the structure return **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_identify_allocated_ns (int fd, __u32 nsid, struct nvme_id_ns * ns) @@ -1590,8 +1329,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_identify_active_ns_list (int fd, __u32 nsid, struct nvme_ns_list * list) @@ -1619,8 +1358,8 @@ See :c:type:`struct nvme_ns_list ` for the definition of the retur **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_identify_allocated_ns_list (int fd, __u32 nsid, struct nvme_ns_list * list) @@ -1648,8 +1387,8 @@ See :c:type:`struct nvme_ns_list ` for the definition of the retur **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_identify_ctrl_list (int fd, __u16 cntid, struct nvme_ctrl_list * ctrlist) @@ -1677,8 +1416,8 @@ See :c:type:`struct nvme_ctrl_list ` for a definition of the str **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_identify_nsid_ctrl_list (int fd, __u32 nsid, __u16 cntid, struct nvme_ctrl_list * ctrlist) @@ -1708,7 +1447,8 @@ See :c:type:`struct nvme_ctrl_list ` for a definition of the str **Return** -The nvme command status if a response was received or -1 +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 .. c:function:: int nvme_identify_ns_descs (int fd, __u32 nsid, struct nvme_ns_id_desc * descs) @@ -1738,8 +1478,8 @@ See :c:type:`struct nvme_ns_id_desc ` for the definition of the **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_identify_nvmset_list (int fd, __u16 nvmsetid, struct nvme_id_nvmset_list * nvmset) @@ -1768,8 +1508,8 @@ See :c:type:`struct nvme_id_nvmset_list ` for the defintion **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_identify_primary_ctrl (int fd, __u16 cntid, struct nvme_primary_ctrl_cap * cap) @@ -1792,8 +1532,8 @@ See :c:type:`struct nvme_primary_ctrl_cap ` for the defin **Return** -The nvme command status if a response was received or -1 - with errno set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_identify_secondary_ctrl_list (int fd, __u16 cntid, struct nvme_secondary_ctrl_list * list) @@ -1823,8 +1563,8 @@ structure. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_identify_ns_granularity (int fd, struct nvme_id_ns_granularity_list * list) @@ -1850,8 +1590,8 @@ structure. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_identify_uuid (int fd, struct nvme_id_uuid_list * list) @@ -1875,8 +1615,8 @@ See :c:type:`struct nvme_id_uuid_list ` for the definition of **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_log (int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, __u8 lsp, __u16 lsi, bool rae, __u8 uuidx, __u32 len, void * log) @@ -1917,8 +1657,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_log_error (int fd, unsigned nr_entries, bool rae, struct nvme_error_log_page * log) @@ -1947,8 +1687,8 @@ particular command. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_log_smart (int fd, __u32 nsid, bool rae, struct nvme_smart_log * log) @@ -1980,8 +1720,8 @@ the LPA field in the Identify Controller data structure. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_log_fw_slot (int fd, bool rae, struct nvme_firmware_slot * log) @@ -2007,8 +1747,8 @@ string. The log page also indicates the active slot number. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_log_changed_ns_list (int fd, bool rae, struct nvme_ns_list * log) @@ -2034,8 +1774,8 @@ added, or deleted. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_log_cmd_effects (int fd, struct nvme_cmd_effects_log * log) @@ -2057,8 +1797,8 @@ and the effects of those commands on the state of the NVM subsystem. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_log_device_self_test (int fd, struct nvme_self_test_log * log) @@ -2081,8 +1821,8 @@ self-test operations. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_log_create_telemetry_host (int fd, struct nvme_telemetry_log * log) @@ -2121,8 +1861,8 @@ using the previously existing capture. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_log_telemetry_ctrl (int fd, bool rae, __u64 offset, __u32 len, void * log) @@ -2171,8 +1911,8 @@ page. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_log_predictable_lat_nvmset (int fd, __u16 nvmsetid, struct nvme_nvmset_predictable_lat_log * log) @@ -2190,8 +1930,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_log_predictable_lat_event (int fd, bool rae, __u32 offset, __u32 len, void * log) @@ -2248,8 +1988,8 @@ See :c:type:`struct nvme_ana_rsp_hdr ` for the defintion of th **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_log_ana_groups (int fd, bool rae, __u32 len, struct nvme_ana_group_desc * log) @@ -2343,8 +2083,8 @@ records. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_log_reservation (int fd, bool rae, struct nvme_resv_notification_log * log) @@ -2383,8 +2123,8 @@ estimates and information about the most recent sanitize operation. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features (int fd, __u8 fid, __u32 nsid, __u32 cdw11, __u32 cdw12, bool save, __u8 uuidx, __u32 cdw15, __u32 data_len, void * data, __u32 * result) @@ -2428,8 +2168,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_arbitration (int fd, __u8 ab, __u8 lpw, __u8 mpw, __u8 hpw, bool save, __u32 * result) @@ -2460,8 +2200,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_power_mgmt (int fd, __u8 ps, __u8 wh, bool save, __u32 * result) @@ -2486,8 +2226,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_lba_range (int fd, __u32 nsid, __u32 nr_ranges, bool save, struct nvme_lba_range_type * data, __u32 * result) @@ -2515,8 +2255,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. @@ -2558,8 +2298,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_err_recovery (int fd, __u32 nsid, __u16 tler, bool dulbe, bool save, __u32 * result) @@ -2587,8 +2327,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_volatile_wc (int fd, bool wce, bool save, __u32 * result) @@ -2610,8 +2350,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_irq_coalesce (int fd, __u8 thr, __u8 time, bool save, __u32 * result) @@ -2636,8 +2376,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_irq_config (int fd, __u16 iv, bool cd, bool save, __u32 * result) @@ -2662,8 +2402,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_write_atomic (int fd, bool dn, bool save, __u32 * result) @@ -2685,8 +2425,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. @@ -2758,8 +2498,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_auto_pst (int fd, bool apste, bool save, struct nvme_feat_auto_pst * apst, __u32 * result) @@ -2784,8 +2524,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_timestamp (int fd, bool save, __u64 timestamp) @@ -2804,8 +2544,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_hctm (int fd, __u16 tmt2, __u16 tmt1, bool save, __u32 * result) @@ -2830,8 +2570,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_nopsc (int fd, bool noppme, bool save, __u32 * result) @@ -2874,8 +2614,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_plm_config (int fd, bool enable, __u16 nvmsetid, bool save, struct nvme_plm_config * data, __u32 * result) @@ -2903,8 +2643,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. @@ -2943,8 +2683,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_lba_sts_interval (int fd, __u16 lsiri, __u16 lsipi, bool save, __u32 * result) @@ -2969,8 +2709,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_host_behavior (int fd, bool save, struct nvme_feat_host_behavior * data) @@ -2989,8 +2729,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_sanitize (int fd, bool nodrm, bool save, __u32 * result) @@ -3012,8 +2752,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_endurance_evt_cfg (int fd, __u16 endgid, __u8 egwarn, bool save, __u32 * result) @@ -3038,8 +2778,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_sw_progress (int fd, __u8 pbslc, bool save, __u32 * result) @@ -3061,8 +2801,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_host_id (int fd, bool exhid, bool save, __u8 * hostid) @@ -3084,8 +2824,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_resv_mask (int fd, __u32 mask, bool save, __u32 * result) @@ -3107,8 +2847,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_resv_persist (int fd, bool ptpl, bool save, __u32 * result) @@ -3130,8 +2870,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. @@ -3173,8 +2913,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features (int fd, enum nvme_features_id fid, __u32 nsid, enum nvme_get_features_sel sel, __u32 cdw11, __u8 uuidx, __u32 data_len, void * data, __u32 * result) @@ -3212,8 +2952,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_arbitration (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3232,8 +2972,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_power_mgmt (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3252,8 +2992,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_lba_range (int fd, enum nvme_get_features_sel sel, struct nvme_lba_range_type * data, __u32 * result) @@ -3275,8 +3015,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_temp_thresh (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3295,8 +3035,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_err_recovery (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3315,8 +3055,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_volatile_wc (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3335,8 +3075,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_num_queues (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3355,8 +3095,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_irq_coalesce (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3375,8 +3115,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_irq_config (int fd, enum nvme_get_features_sel sel, __u16 iv, __u32 * result) @@ -3398,8 +3138,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_write_atomic (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3418,8 +3158,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_async_event (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3438,8 +3178,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_auto_pst (int fd, enum nvme_get_features_sel sel, struct nvme_feat_auto_pst * apst, __u32 * result) @@ -3461,8 +3201,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_host_mem_buf (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3481,8 +3221,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_timestamp (int fd, enum nvme_get_features_sel sel, struct nvme_timestamp * ts) @@ -3501,8 +3241,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_kato (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3521,8 +3261,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_hctm (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3541,8 +3281,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_nopsc (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3561,8 +3301,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_rrl (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3581,8 +3321,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_plm_config (int fd, enum nvme_get_features_sel sel, __u16 nvmsetid, struct nvme_plm_config * data, __u32 * result) @@ -3607,8 +3347,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_plm_window (int fd, enum nvme_get_features_sel sel, __u16 nvmsetid, __u32 * result) @@ -3630,8 +3370,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_lba_sts_interval (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3650,8 +3390,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_host_behavior (int fd, enum nvme_get_features_sel sel, struct nvme_feat_host_behavior * data, __u32 * result) @@ -3673,8 +3413,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_sanitize (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3693,8 +3433,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_endurance_event_cfg (int fd, enum nvme_get_features_sel sel, __u16 endgid, __u32 * result) @@ -3716,8 +3456,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_sw_progress (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3736,8 +3476,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_host_id (int fd, enum nvme_get_features_sel sel, bool exhid, __u32 len, __u8 * hostid) @@ -3762,8 +3502,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_resv_mask (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3782,8 +3522,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_resv_persist (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3802,8 +3542,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_write_protect (int fd, __u32 nsid, enum nvme_get_features_sel sel, __u32 * result) @@ -3825,8 +3565,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_format_nvm (int fd, __u32 nsid, __u8 lbaf, enum nvme_cmd_format_mset mset, enum nvme_cmd_format_pi pi, enum nvme_cmd_format_pil pil, enum nvme_cmd_format_ses ses, __u32 timeout) @@ -3869,8 +3609,8 @@ all namespaces or only the specific namespace associated with the command **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_ns_mgmt (int fd, __u32 nsid, enum nvme_ns_mgmt_sel sel, struct nvme_id_ns * ns, __u32 * result, __u32 timeout) @@ -3923,8 +3663,8 @@ namespace to one or more controllers. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_ns_mgmt_delete (int fd, __u32 nsid) @@ -3946,8 +3686,8 @@ attached. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_ns_attach (int fd, __u32 nsid, enum nvme_ns_attach_sel sel, struct nvme_ctrl_list * ctrlist) @@ -3984,7 +3724,7 @@ The nvme command status if a response was received or -1 with errno Controller list to modify attachment state of nsid -.. c:function:: int nvme_ns_dettach_ctrls (int fd, __u32 nsid, struct nvme_ctrl_list * ctrlist) +.. c:function:: int nvme_ns_detach_ctrls (int fd, __u32 nsid, struct nvme_ctrl_list * ctrlist) **Parameters** @@ -3993,7 +3733,7 @@ The nvme command status if a response was received or -1 with errno File descriptor of nvme device ``__u32 nsid`` - Namespace ID to dettach + Namespace ID to detach ``struct nvme_ctrl_list * ctrlist`` Controller list to modify attachment state of nsid @@ -4034,8 +3774,8 @@ image. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_fw_commit (int fd, __u8 slot, enum nvme_fw_commit_ca action, bool bpid) @@ -4063,8 +3803,9 @@ Partitions. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. The command status response may specify additional +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. The command status + response may specify additional reset actions required to complete the commit process. @@ -4116,8 +3857,8 @@ specification. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_security_receive (int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, __u8 secp, __u32 al, __u32 data_len, void * data, __u32 * result) @@ -4157,8 +3898,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_lba_status (int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl, enum nvme_lba_status_atype atype, struct nvme_lba_status * lbas) @@ -4196,8 +3937,8 @@ Unrecoverable LBAs. Refer to the specification for action type descriptions. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_directive_send (int fd, __u32 nsid, __u16 dspec, enum nvme_directive_send_doper doper, enum nvme_directive_dtype dtype, __u32 cdw12, __u32 data_len, void * data, __u32 * result) @@ -4243,8 +3984,8 @@ See the NVMe specification for more information. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_directive_send_id_endir (int fd, __u32 nsid, bool endir, enum nvme_directive_dtype dtype, struct nvme_id_directives * id) @@ -4269,8 +4010,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_directive_send_stream_release_identifier (int fd, __u32 nsid, __u16 stream_id) @@ -4289,8 +4030,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_directive_send_stream_release_resource (int fd, __u32 nsid) @@ -4306,8 +4047,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_directive_recv (int fd, __u32 nsid, __u16 dspec, enum nvme_directive_receive_doper doper, enum nvme_directive_dtype dtype, __u32 cdw12, __u32 data_len, void * data, __u32 * result) @@ -4345,8 +4086,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_directive_recv_identify_parameters (int fd, __u32 nsid, struct nvme_id_directives * id) @@ -4365,8 +4106,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_directive_recv_stream_parameters (int fd, __u32 nsid, struct nvme_streams_directive_params * parms) @@ -4385,8 +4126,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_directive_recv_stream_status (int fd, __u32 nsid, unsigned nr_entries, struct nvme_streams_directive_status * id) @@ -4408,8 +4149,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_directive_recv_stream_allocate (int fd, __u32 nsid, __u16 nsr, __u32 * result) @@ -4431,8 +4172,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. @@ -4483,8 +4224,8 @@ properties align to the PCI MMIO controller registers. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_property (int fd, int offset, __u64 * value) @@ -4509,8 +4250,8 @@ properties align to the PCI MMIO controller registers. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_sanitize_nvm (int fd, enum nvme_sanitize_sanact sanact, bool ause, __u8 owpass, bool oipbp, bool nodas, __u32 ovrpat) @@ -4554,8 +4295,8 @@ sanitize command does not indicate completion of the sanitize operation. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_dev_self_test (int fd, __u32 nsid, enum nvme_dst_stc stc) @@ -4588,8 +4329,8 @@ namespace, if present. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_virtual_mgmt (int fd, enum nvme_virt_mgmt_act act, enum nvme_virt_mgmt_rt rt, __u16 cntlid, __u16 nr, __u32 * result) @@ -4628,11 +4369,8 @@ used for several functions: **Return** -The nvme command status if a response was received or -1 - with errno set otherwise. - - -**NVMe IO command** +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. @@ -4698,8 +4436,8 @@ cache be made non-volatile. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. @@ -4841,8 +4579,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_write (int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u8 dsm, __u16 dspec, __u32 reftag, __u16 apptag, __u16 appmask, __u32 data_len, void * data, __u32 metadata_len, void * metadata) @@ -4902,8 +4640,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_compare (int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 reftag, __u16 apptag, __u16 appmask, __u32 data_len, void * data, __u32 metadata_len, void * metadata) @@ -4957,8 +4695,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_write_zeros (int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 reftag, __u16 apptag, __u16 appmask) @@ -5006,8 +4744,8 @@ to 0h until a write occurs to this LBA range. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_write_uncorrectable (int fd, __u32 nsid, __u64 slba, __u16 nlb) @@ -5038,8 +4776,8 @@ required. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_verify (int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 reftag, __u16 apptag, __u16 appmask) @@ -5086,8 +4824,8 @@ data or metadata to the host. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. @@ -5139,8 +4877,8 @@ deallocate/unmap/trim those logical blocks. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. @@ -5222,8 +4960,8 @@ reservation held on a namespace. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. @@ -5295,8 +5033,8 @@ a reservation key. **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. @@ -5339,8 +5077,8 @@ The nvme command status if a response was received or -1 with errno **Return** -The nvme command status if a response was received or -1 with errno - set otherwise. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_resv_report (int fd, __u32 nsid, bool eds, __u32 len, struct nvme_reservation_status * report) @@ -5372,25 +5110,225 @@ the returned structure, :c:type:`struct nvme_reservation_status `) or -1 with errno set otherwise. -.. c:function:: nvme_subsystem_t nvme_first_subsystem (nvme_root_t r) +.. c:function:: int nvme_namespace_filter (const struct dirent * d) **Parameters** -``nvme_root_t r`` +``const struct dirent * d`` -.. c:function:: nvme_subsystem_t nvme_next_subsystem (nvme_root_t r, nvme_subsystem_t s) +.. c:function:: int nvme_paths_filter (const struct dirent * d) **Parameters** -``nvme_root_t r`` - *undescribed* +``const struct dirent * d`` + + +.. c:function:: int nvme_ctrls_filter (const struct dirent * d) + + +**Parameters** + +``const struct dirent * d`` + + +.. c:function:: int nvme_subsys_filter (const struct dirent * d) + + +**Parameters** + +``const struct dirent * d`` + + +.. c:function:: int nvme_scan_subsystems (struct dirent *** subsys) + + +**Parameters** + +``struct dirent *** subsys`` + + +.. c:function:: int nvme_scan_subsystem_ctrls (nvme_subsystem_t s, struct dirent *** ctrls) + + +**Parameters** + +``nvme_subsystem_t s`` + *undescribed* + +``struct dirent *** ctrls`` + + +.. c:function:: int nvme_scan_subsystem_namespaces (nvme_subsystem_t s, struct dirent *** namespaces) + + +**Parameters** + +``nvme_subsystem_t s`` + *undescribed* + +``struct dirent *** namespaces`` + + +.. c:function:: int nvme_scan_ctrl_namespace_paths (nvme_ctrl_t c, struct dirent *** namespaces) + + +**Parameters** + +``nvme_ctrl_t c`` + *undescribed* + +``struct dirent *** namespaces`` + + +.. c:function:: int nvme_scan_ctrl_namespaces (nvme_ctrl_t c, struct dirent *** namespaces) + + +**Parameters** + +``nvme_ctrl_t c`` + *undescribed* + +``struct dirent *** namespaces`` + + + + +.. c:type:: struct nvme_fabrics_config + + +**Definition** + +:: + + struct nvme_fabrics_config { + const char *transport; + const char *traddr; + const char *trsvcid; + const char *nqn; + const char *hostnqn; + const char *host_traddr; + const char *hostid; + int queue_size; + int nr_io_queues; + int reconnect_delay; + int ctrl_loss_tmo; + int keep_alive_tmo; + int nr_write_queues; + int nr_poll_queues; + int tos; + bool duplicate_connect; + bool disable_sqflow; + bool hdr_digest; + bool data_digest; + uint8_t rsvd[0x200]; + }; + +**Members** + + + +.. c:function:: int nvmf_add_ctrl_opts (struct nvme_fabrics_config * cfg) + + +**Parameters** + +``struct nvme_fabrics_config * cfg`` + + +.. c:function:: nvme_ctrl_t nvmf_add_ctrl (struct nvme_fabrics_config * cfg) + + +**Parameters** + +``struct nvme_fabrics_config * cfg`` + + +.. c:function:: int nvmf_get_discovery_log (nvme_ctrl_t c, struct nvmf_discovery_log ** logp, int max_retries) + + +**Parameters** + +``nvme_ctrl_t c`` + *undescribed* + +``struct nvmf_discovery_log ** logp`` + *undescribed* + +``int max_retries`` + + +.. c:function:: char * nvmf_hostnqn_generate () + + Generate a machine specific host nqn + +**Parameters** + +**Return** + +An nvm namespace qualifieid name string based on the machine + identifier, or NULL if not successful. + + +.. c:function:: char * nvmf_hostnqn_from_file () + + Reads the host nvm qualified name from the config default location in /etc/nvme/ + +**Parameters** + +**Return** + +The host nqn, or NULL if unsuccessful. If found, the caller + is responsible to free the string. + + +.. c:function:: char * nvmf_hostid_from_file () + + Reads the host identifier from the config default location in /etc/nvme/. + +**Parameters** + +**Return** + +The host identifier, or NULL if unsuccessful. If found, the caller + is responsible to free the string. + + +.. c:function:: nvme_ctrl_t nvmf_connect_disc_entry (struct nvmf_disc_log_entry * e, const struct nvme_fabrics_config * defcfg, bool * discover) + + +**Parameters** + +``struct nvmf_disc_log_entry * e`` + *undescribed* + +``const struct nvme_fabrics_config * defcfg`` + *undescribed* + +``bool * discover`` + + +.. c:function:: nvme_subsystem_t nvme_first_subsystem (nvme_root_t r) + + +**Parameters** + +``nvme_root_t r`` + + +.. c:function:: nvme_subsystem_t nvme_next_subsystem (nvme_root_t r, nvme_subsystem_t s) + + +**Parameters** + +``nvme_root_t r`` + *undescribed* ``nvme_subsystem_t s`` @@ -6104,2467 +6042,2554 @@ The nvme command status if a response was received or -1 with errno ``const char * attr`` +.. c:function:: __u8 nvme_status_to_errno (int status, bool fabrics) + Converts nvme return status to errno -.. c:type:: enum nvme_constants +**Parameters** - A place to stash various constant nvme values +``int status`` + Return status from an nvme passthrough commmand -**Constants** +``bool fabrics`` + Set to true if :c:type:`status` is to a fabrics target. -``NVME_NSID_ALL`` - A broadcast value that is used to specify all - namespaces +**Return** -``NVME_NSID_NONE`` - The invalid namespace id, for when the nsid - parameter is not used in a command +An errno representing the nvme status if it is an nvme status field, + or unchanged status is < 0 since errno is already set. -``NVME_UUID_NONE`` - Use to omit the uuid command parameter -``NVME_CNTLID_NONE`` - Use to omit the cntlid command parameter +.. c:function:: int nvme_fw_download_seq (int fd, __u32 size, __u32 xfer, __u32 offset, void * buf) -``NVME_NVMSETID_NONE`` - Use to omit the nvmsetid command parameter -``NVME_LOG_LSP_NONE`` - Use to omit the log lsp command parameter +**Parameters** -``NVME_LOG_LSI_NONE`` - Use to omit the log lsi command parameter +``int fd`` + File descriptor of nvme device -``NVME_IDENTIFY_DATA_SIZE`` - The transfer size for nvme identify commands +``__u32 size`` + Total size of the firmware image to transfer -``NVME_ID_NVMSET_LIST_MAX`` - The largest possible nvmset index in identify - nvmeset +``__u32 xfer`` + Maximum size to send with each partial transfer -``NVME_ID_UUID_LIST_MAX`` - The largest possible uuid index in identify - uuid list +``__u32 offset`` + Starting offset to send with this firmware downlaod -``NVME_ID_CTRL_LIST_MAX`` - The largest possible controller index in - identify controller list +``void * buf`` + Address of buffer containing all or part of the firmware image. -``NVME_ID_NS_LIST_MAX`` - The largest possible namespace index in - identify namespace list +**Return** -``NVME_ID_SECONDARY_CTRL_MAX`` - The largest possible secondary controller index - in identify secondary controller +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. -``NVME_ID_ND_DESCRIPTOR_MAX`` - *undescribed* -``NVME_FEAT_LBA_RANGE_MAX`` - The largest possible LBA range index in feature - lba range type +.. c:function:: int nvme_get_ctrl_telemetry (int fd, bool rae, struct nvme_telemetry_log ** log) -``NVME_LOG_ST_MAX_RESULTS`` - The largest possible self test result index in the - device self test log -``NVME_DSM_MAX_RANGES`` - The largest possible range index in a data-set - management command +**Parameters** +``int fd`` + File descriptor of nvme device +``bool rae`` + Retain asynchronous events +``struct nvme_telemetry_log ** log`` + On success, set to the value of the allocated and retreived log. -.. c:type:: enum nvme_registers - - The nvme controller registers for all transports. This is the layout of BAR0/1 for PCIe, and properties for fabrics. - -**Constants** - -``NVME_REG_CAP`` - Controller Capabilities +**Description** -``NVME_REG_VS`` - Version +The total size allocated can be calculated as: + (:c:type:`struct nvme_telemetry_log `.dalb3 + 1) * ``NVME_LOG_TELEM_BLOCK_SIZE``. -``NVME_REG_INTMS`` - Interrupt Mask Set +**Return** -``NVME_REG_INTMC`` - Interrupt Mask Clear +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. -``NVME_REG_CC`` - Controller Configuration -``NVME_REG_CSTS`` - Controller Status +.. c:function:: int nvme_get_host_telemetry (int fd, struct nvme_telemetry_log ** log) -``NVME_REG_NSSR`` - NVM Subsystem Reset -``NVME_REG_AQA`` - Admin Queue Attributes +**Parameters** -``NVME_REG_ASQ`` - Admin SQ Base Address +``int fd`` + File descriptor of nvme device -``NVME_REG_ACQ`` - Admin CQ Base Address +``struct nvme_telemetry_log ** log`` + On success, set to the value of the allocated and retreived log. -``NVME_REG_CMBLOC`` - Controller Memory Buffer Location +**Description** -``NVME_REG_CMBSZ`` - Controller Memory Buffer Size +The total size allocated can be calculated as: + (:c:type:`struct nvme_telemetry_log `.dalb3 + 1) * ``NVME_LOG_TELEM_BLOCK_SIZE``. -``NVME_REG_BPINFO`` - Boot Partition Information +**Return** -``NVME_REG_BPRSEL`` - Boot Partition Read Select +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. -``NVME_REG_BPMBL`` - Boot Partition Memory Buffer Location -``NVME_REG_CMBMSC`` - Controller Memory Buffer Memory Space Control +.. c:function:: int nvme_get_new_host_telemetry (int fd, struct nvme_telemetry_log ** log) -``NVME_REG_CMBSTS`` - Controller Memory Buffer Status -``NVME_REG_PMRCAP`` - Persistent Memory Capabilities +**Parameters** -``NVME_REG_PMRCTL`` - Persistent Memory Region Control +``int fd`` + File descriptor of nvme device -``NVME_REG_PMRSTS`` - Persistent Memory Region Status +``struct nvme_telemetry_log ** log`` + On success, set to the value of the allocated and retreived log. -``NVME_REG_PMREBS`` - Persistent Memory Region Elasticity Buffer Size +**Description** -``NVME_REG_PMRSWTP`` - Memory Region Sustained Write Throughput +The total size allocated can be calculated as: + (:c:type:`struct nvme_telemetry_log `.dalb3 + 1) * ``NVME_LOG_TELEM_BLOCK_SIZE``. -``NVME_REG_PMRMSC`` - Persistent Memory Region Controller Memory Space Control +**Return** -``NVME_REG_DBS`` - SQ 0 Tail Doorbell +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: bool is_64bit_reg (__u32 offset) +.. c:function:: void nvme_init_id_ns (struct nvme_id_ns * ns, __u64 nsze, __u64 ncap, __u8 flbas, __u8 dps, __u8 nmic, __u32 anagrpid, __u16 nvmsetid) - Checks if offset of the controller register is 64bit or not. + Initialize an Identify Namepsace structure for creation. **Parameters** -``__u32 offset`` - Offset of controller register field in bytes - -**Description** +``struct nvme_id_ns * ns`` + Address of the Identify Namespace structure to initialize -This function does not care about transport so that the offset is not going -to be checked inside of this function for the unsupported fields in a -specific transport. For example, BPMBL(Boot Partition Memory Buffer -Location) register is not supported by fabrics, but it can be chcked here. +``__u64 nsze`` + Namespace size -Returns true if given offset is 64bit register, otherwise it returns false. +``__u64 ncap`` + namespace capacity +``__u8 flbas`` + formatted logical block size settings +``__u8 dps`` + Data protection settings +``__u8 nmic`` + Namespace sharing capabilities -.. c:type:: enum nvme_psd_flags +``__u32 anagrpid`` + ANA group identifier - Possible flag values in nvme power state descriptor +``__u16 nvmsetid`` + NVM Set identifer -**Constants** +**Description** -``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. +This is intended to be used with a namespace management "create", see +:c:type:`nvme_ns_mgmt_create`(). -``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. +.. c:function:: void nvme_init_ctrl_list (struct nvme_ctrl_list * cntlist, __u16 num_ctrls, __u16 * ctrlist) + Initialize an nvme_ctrl_list structure from an array. +**Parameters** -.. c:type:: enum nvme_psd_ps +``struct nvme_ctrl_list * cntlist`` + The controller list structure to initialize - Known values for :c:type:`struct nvme_psd ` #ips and #aps. Use with nvme_psd_power_scale() to extract the power scale field to match this enum. NVME_PSD_IPS_100_MICRO_WATT: 0.0001 watt scale NVME_PSD_IPS_10_MILLI_WATT: 0.01 watt scale +``__u16 num_ctrls`` + The number of controllers in the array, :c:type:`ctrlist`. -**Constants** +``__u16 * ctrlist`` + An array of controller identifiers in CPU native endian. -``NVME_PSD_PS_100_MICRO_WATT`` - *undescribed* +**Description** -``NVME_PSD_PS_10_MILLI_WATT`` - *undescribed* +This is intended to be used with any command that takes a controller list +argument. See :c:type:`nvme_ns_attach_ctrls`() and :c:type:`nvme_ns_detach`(). -.. c:function:: unsigned nvme_psd_power_scale (__u8 ps) +.. c:function:: void nvme_init_dsm_range (struct nvme_dsm_range * dsm, __u32 * ctx_attrs, __u32 * llbas, __u64 * slbas, __u16 nr_ranges) - power scale occupies the upper 3 bits + Constructs a data set range structure **Parameters** -``__u8 ps`` - *undescribed* +``struct nvme_dsm_range * dsm`` + DSM range array +``__u32 * ctx_attrs`` + Array of context attributes +``__u32 * llbas`` + Array of length in logical blocks +``__u64 * slbas`` + Array of starting logical blocks -.. c:type:: enum nvme_psd_workload +``__u16 nr_ranges`` + The size of the dsm arrays - Specifies a workload hint in the Power Management Feature (see :c:type:`struct nvme_psd `.apw) to inform the NVM subsystem or indicate the conditions for the active power level. +**Description** -**Constants** +Each array must be the same size of size 'nr_ranges'. This is intended to be +used with constructing a payload for :c:type:`nvme_dsm`(). -``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. +**Return** -``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 - NVM subsystem are idle. The submission queue(s) - should be sufficiently large allowing the host to - ensure there are multiple commands pending at all - times during the workload. +The nvme command status if a response was received or -errno + otherwise. +.. c:function:: int __nvme_get_log_page (int fd, __u32 nsid, __u8 log_id, bool rae, __u32 xfer_len, __u32 data_len, void * data) -.. c:type:: struct nvme_id_psd +**Parameters** +``int fd`` + File descriptor of nvme device -**Definition** +``__u32 nsid`` + Namespace Identifier, if applicable. -:: +``__u8 log_id`` + Log Identifier, see :c:type:`enum nvme_cmd_get_log_lid `. - struct nvme_id_psd { - __le16 mp; - __u8 rsvd2; - __u8 flags; - __le32 enlat; - __le32 exlat; - __u8 rrt; - __u8 rrl; - __u8 rwt; - __u8 rwl; - __le16 idlp; - __u8 ips; - __u8 rsvd19; - __le16 actp; - __u8 apw; - __u8 aps; - __u8 rsvd23[8]; - }; +``bool rae`` + Retain asynchronous events -**Members** +``__u32 xfer_len`` + Max log transfer size per request to split the total. -``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 :c:type:`enum nvme_psd_flags `). A value of 0 indicates - Maximum Power is not reported. +``__u32 data_len`` + Total length of the log to transfer. -``flags`` - Additional decoding flags, see :c:type:`enum nvme_psd_flags `. +``void * data`` + User address of at least :c:type:`data_len` to store the log. -``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. +**Return** -``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. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. -``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. +.. c:function:: int nvme_get_log_page (int fd, __u32 nsid, __u8 log_id, bool rae, __u32 data_len, void * data) -``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 -``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 +**Parameters** -``idlp`` - Idle Power indicates the typical power consumed by the NVM - subsystem over 30 seconds in this power state when idle. +``int fd`` + File descriptor of nvme device -``ips`` - Idle Power Scale indicates the scale for :c:type:`struct nvme_id_psd `.idlp, - see :c:type:`enum nvme_psd_ps ` for decoding this field. +``__u32 nsid`` + Namespace Identifier, if applicable. -``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. +``__u8 log_id`` + Log Identifier, see :c:type:`enum nvme_cmd_get_log_lid `. -``apw`` - Active Power Workload indicates the workload used to calculate - maximum power for this power state. See :c:type:`enum nvme_psd_workload ` for - decoding this field. +``bool rae`` + Retain asynchronous events -``aps`` - Active Power Scale indicates the scale for the :c:type:`struct - nvme_id_psd `.actp, see :c:type:`enum nvme_psd_ps ` for decoding this value. +``__u32 data_len`` + Total length of the log to transfer. +``void * data`` + User address of at least :c:type:`data_len` to store the log. +**Description** +Calls __nvme_get_log_page() with a default 4k transfer length, as that is +guarnateed by the protocol to be a safe transfer size. +**Return** -.. c:type:: struct nvme_id_ctrl +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. - Identify Controller data structure -**Definition** +.. c:function:: int nvme_get_ana_log_len (int fd, size_t * analen) -:: + Retreive size of the current ANA log - struct nvme_id_ctrl { - __le16 vid; - __le16 ssvid; - char sn[20]; - char mn[40]; - char fr[8]; - __u8 rab; - __u8 ieee[3]; - __u8 cmic; - __u8 mdts; - __le16 cntlid; - __le32 ver; - __le32 rtd3r; - __le32 rtd3e; - __le32 oaes; - __le32 ctratt; - __le16 rrls; - __u8 rsvd102[9]; - __u8 cntrltype; - __u8 fguid[16]; - __le16 crdt1; - __le16 crdt2; - __le16 crdt3; - __u8 rsvd134[119]; - __u8 nvmsr; - __u8 vwci; - __u8 mec; - __le16 oacs; - __u8 acl; - __u8 aerl; - __u8 frmw; - __u8 lpa; - __u8 elpe; - __u8 npss; - __u8 avscc; - __u8 apsta; - __le16 wctemp; - __le16 cctemp; - __le16 mtfa; - __le32 hmpre; - __le32 hmmin; - __u8 tnvmcap[16]; - __u8 unvmcap[16]; - __le32 rpmbs; - __le16 edstt; - __u8 dsto; - __u8 fwug; - __le16 kas; - __le16 hctma; - __le16 mntmt; - __le16 mxtmt; - __le32 sanicap; - __le32 hmminds; - __le16 hmmaxd; - __le16 nsetidmax; - __le16 endgidmax; - __u8 anatt; - __u8 anacap; - __le32 anagrpmax; - __le32 nanagrpid; - __le32 pels; - __u8 rsvd356[156]; - __u8 sqes; - __u8 cqes; - __le16 maxcmd; - __le32 nn; - __le16 oncs; - __le16 fuses; - __u8 fna; - __u8 vwc; - __le16 awun; - __le16 awupf; - __u8 nvscc; - __u8 nwpc; - __le16 acwu; - __u8 rsvd534[2]; - __le32 sgls; - __le32 mnan; - __u8 rsvd544[224]; - char subnqn[256]; - __u8 rsvd1024[768]; - __le32 ioccsz; - __le32 iorcsz; - __le16 icdoff; - __u8 fcatt; - __u8 msdbd; - __le16 ofcs; - __u8 rsvd1806[242]; - struct nvme_id_psd psd[32]; - __u8 vs[1024]; - }; +**Parameters** -**Members** +``int fd`` + File descriptor of nvme device -``vid`` - PCI Vendor ID, the company vendor identifier that is assigned by - the PCI SIG. +``size_t * analen`` + Pointer to where the length will be set on success -``ssvid`` - PCI Subsystem Vendor ID, the company vendor identifier that is - assigned by the PCI SIG for the subsystem. +**Return** -``sn`` - Serial Number in ascii +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. -``mn`` - Model Number in ascii -``fr`` - Firmware Revision in ascii, the currently active firmware - revision for the NVM subsystem +.. c:function:: int nvme_namespace_attach_ctrls (int fd, __u32 nsid, __u16 num_ctrls, __u16 * ctrlist) -``rab`` - Recommended Arbitration Burst, reported as a power of two + Attach namespace to controller(s) -``ieee`` - IEEE assigned Organization Unique Identifier +**Parameters** -``cmic`` - Controller Multipath IO and Namespace Sharing Capabilities of - the controller and NVM subsystem. See :c:type:`enum nvme_id_ctrl_cmic `. +``int fd`` + File descriptor of nvme device -``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 +``__u32 nsid`` + Namespace ID to attach -``cntlid`` - Controller ID, the NVM subsystem unique controller identifier - associated with the controller. +``__u16 num_ctrls`` + Number of controllers in ctrlist -``ver`` - Version, this field contains the value reported in the Version - register, or property (see :c:type:`enum nvme_registers ` ``NVME_REG_VS``). +``__u16 * ctrlist`` + List of controller IDs to perform the attach action -``rtd3r`` - RTD3 Resume Latency, the expected latency in microseconds to resume - from Runtime D3 +**Return** -``rtd3e`` - RTD3 Exit Latency, the typical latency in microseconds to enter - Runtime D3. +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. -``oaes`` - Optional Async Events Supported, see **enum** nvme_id_ctrl_oaes . -``ctratt`` - Controller Attributes, see **enum** nvme_id_ctrl_ctratt +.. c:function:: int nvme_namespace_detach_ctrls (int fd, __u32 nsid, __u16 num_ctrls, __u16 * ctrlist) -``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. + Detach namespace from controller(s) -``cntrltype`` - Controller Type, see :c:type:`enum nvme_id_ctrl_cntrltype ` +**Parameters** -``fguid`` - FRU GUID, a 128-bit value that is globally unique for a given - Field Replaceable Unit +``int fd`` + File descriptor of nvme device -``crdt1`` - Controller Retry Delay time in 100 millisecod units if CQE CRD - field is 1 +``__u32 nsid`` + Namespace ID to detach -``crdt2`` - Controller Retry Delay time in 100 millisecod units if CQE CRD - field is 2 +``__u16 num_ctrls`` + Number of controllers in ctrlist -``crdt3`` - Controller Retry Delay time in 100 millisecod units if CQE CRD - field is 3 +``__u16 * ctrlist`` + List of controller IDs to perform the detach action -``nvmsr`` - NVM Subsystem Report, see :c:type:`enum nvme_id_ctrl_nvmsr ` +**Return** -``vwci`` - VPD Write Cycle Information, see :c:type:`enum nvme_id_ctrl_vwci ` +The nvme command status if a response was received (see :c:type:`enum + nvme_status_field `) or -1 with errno set otherwise. -``mec`` - Management Endpoint Capabilities, see :c:type:`enum nvme_id_ctrl_mec ` -``oacs`` - Optional Admin Command Support,the optional Admin commands and - features supported by the controller, see :c:type:`enum nvme_id_ctrl_oacs `. +.. c:function:: int nvme_get_feature_length (int fid, __u32 cdw11, __u32 * len) -``acl`` - Abort Command Limit, the maximum number of concurrently - executing Abort commands supported by the controller. This is a - 0's based value. + Retreive the command payload length for a specific feature identifier -``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. +**Parameters** -``frmw`` - Firmware Updates indicates capabilities regarding firmware - updates. See :c:type:`enum nvme_id_ctrl_frmw `. +``int fid`` + Feature identifier, see :c:type:`enum nvme_features_id `. -``lpa`` - Log Page Attributes, see :c:type:`enum nvme_id_ctrl_lpa `. +``__u32 cdw11`` + The cdw11 value may affect the transfer (only known fid is + ``NVME_FEAT_FID_HOST_ID``) -``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. +``__u32 * len`` + On success, set to this features payload length in bytes. -``npss`` - Number of Power States Supported, the number of NVM Express - power states supported by the controller, indicating the number - of valid entries in :c:type:`struct nvme_id_ctrl `.psd. This is a 0's - based value. +**Return** -``avscc`` - Admin Vendor Specific Command Configuration, see :c:type:`enum - nvme_id_ctrl_avscc `. +0 on success, -1 with errno set to EINVAL if the function did not + recognize :c:type:`fid`. -``apsta`` - Autonomous Power State Transition Attributes, see :c:type:`enum - nvme_id_ctrl_apsta `. -``wctemp`` - Warning Composite Temperature Threshold indicates - the minimum Composite Temperature field value (see :c:type:`struct - nvme_smart_log `.critical_comp_time) that indicates an overheating - condition during which controller operation continues. +.. c:function:: int nvme_get_directive_receive_length (enum nvme_directive_dtype dtype, enum nvme_directive_receive_doper doper, __u32 * len) -``cctemp`` - Critical Composite Temperature Threshold, field indicates the - minimum Composite Temperature field value (see :c:type:`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. +**Parameters** + +``enum nvme_directive_dtype dtype`` + Directive type, see :c:type:`enum nvme_directive_dtype ` + +``enum nvme_directive_receive_doper doper`` + Directive receive operation, see :c:type:`enum nvme_directive_receive_doper ` + +``__u32 * len`` + On success, set to this directives payload length in bytes. + +**Return** + +0 on success, -1 with errno set to EINVAL if the function did not + recognize :c:type:`dtype` or :c:type:`doper`. + + +.. c:function:: int nvme_open (const char * name) + + Open an nvme controller or namespace device + +**Parameters** + +``const char * name`` + The basename of the device to open + +**Description** + +This will look for the handle in /dev/ and validate the name and filetype +match linux conventions. + +**Return** + +A file descriptor for the device on a successful open, or -1 with + errno set otherwise. + + +.. c:function:: __le16 cpu_to_le16 (uint16_t x) + + +**Parameters** + +``uint16_t x`` + 16-bit CPU value to turn to little endian. + + +.. c:function:: __le32 cpu_to_le32 (uint32_t x) + + +**Parameters** + +``uint32_t x`` + 32-bit CPU value to turn little endian. + + +.. c:function:: __le64 cpu_to_le64 (uint64_t x) + + +**Parameters** + +``uint64_t x`` + 64-bit CPU value to turn little endian. + + +.. c:function:: uint16_t le16_to_cpu (__le16 x) + + +**Parameters** + +``__le16 x`` + 16-bit little endian value to turn to CPU. + + +.. c:function:: uint32_t le32_to_cpu (__le32 x) + + +**Parameters** + +``__le32 x`` + 32-bit little endian value to turn to CPU. + + +.. c:function:: uint64_t le64_to_cpu (__le64 x) + + +**Parameters** + +``__le64 x`` + 64-bit little endian value to turn to CPU. + + + + +.. c:type:: enum nvme_constants + + A place to stash various constant nvme values + +**Constants** + +``NVME_NSID_ALL`` + A broadcast value that is used to specify all + namespaces + +``NVME_NSID_NONE`` + The invalid namespace id, for when the nsid + parameter is not used in a command + +``NVME_UUID_NONE`` + Use to omit the uuid command parameter + +``NVME_CNTLID_NONE`` + Use to omit the cntlid command parameter + +``NVME_NVMSETID_NONE`` + Use to omit the nvmsetid command parameter + +``NVME_LOG_LSP_NONE`` + Use to omit the log lsp command parameter + +``NVME_LOG_LSI_NONE`` + Use to omit the log lsi command parameter + +``NVME_IDENTIFY_DATA_SIZE`` + The transfer size for nvme identify commands + +``NVME_ID_NVMSET_LIST_MAX`` + The largest possible nvmset index in identify + nvmeset + +``NVME_ID_UUID_LIST_MAX`` + The largest possible uuid index in identify + uuid list + +``NVME_ID_CTRL_LIST_MAX`` + The largest possible controller index in + identify controller list -``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. +``NVME_ID_NS_LIST_MAX`` + The largest possible namespace index in + identify namespace list -``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. +``NVME_ID_SECONDARY_CTRL_MAX`` + The largest possible secondary controller index + in identify secondary controller -``tnvmcap`` - Total NVM Capacity, the total NVM capacity in the NVM subsystem. - The value is in bytes. +``NVME_ID_ND_DESCRIPTOR_MAX`` + *undescribed* -``unvmcap`` - Unallocated NVM Capacity, the unallocated NVM capacity in the - NVM subsystem. The value is in bytes. - **rpmbs** Replay Protected Memory Block Support, see :c:type:`enum - nvme_id_ctrl_rpmbs `. - **edstt** Extended Device Self-test Time, if Device Self-test command is - supported (see :c:type:`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. +``NVME_FEAT_LBA_RANGE_MAX`` + The largest possible LBA range index in feature + lba range type -``dsto`` - Device Self-test Options, see :c:type:`enum nvme_id_ctrl_dsto `. +``NVME_LOG_ST_MAX_RESULTS`` + The largest possible self test result index in the + device self test log -``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 +``NVME_LOG_TELEM_BLOCK_SIZE`` + Specification defined size of Telemetry Data Blocks -``kas`` - Keep Alive Support indicates the granularity of the Keep Alive - Timer in 100 millisecond units. +``NVME_DSM_MAX_RANGES`` + The largest possible range index in a data-set + management command -``hctma`` - Host Controlled Thermal Management Attributes, see :c:type:`enum nvme_id_ctrl_hctm `. +``NVME_NQN_LENGTH`` + Max length for NVMe Qualified Name. -``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. +``NVMF_TRADDR_SIZE`` + *undescribed* -``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. +``NVMF_TSAS_SIZE`` + *undescribed* -``sanicap`` - Sanitize Capabilities, see :c:type:`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. -``hmmaxd`` - Host Memory Maximum Descriptors Entries indicates the number of - 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. +.. c:type:: enum nvme_registers -``endgidmax`` - Endurance Group Identifier Maximum, defines the maximum value of - a valid Endurance Group Identifier for any controller in the NVM - subsystem. + The nvme controller registers for all transports. This is the layout of BAR0/1 for PCIe, and properties for fabrics. -``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. +**Constants** -``anacap`` - Asymmetric Namespace Access Capabilities, see :c:type:`enum - nvme_id_ctrl_anacap `. +``NVME_REG_CAP`` + Controller Capabilities -``anagrpmax`` - ANA Group Identifier Maximum indicates the maximum value of a - valid ANA Group Identifier for any controller in the NVM - subsystem. +``NVME_REG_VS`` + Version -``nanagrpid`` - Number of ANA Group Identifiers indicates the number of ANA - groups supported by this controller. +``NVME_REG_INTMS`` + Interrupt Mask Set -``pels`` - Persistent Event Log Size indicates the maximum reportable size - for the Persistent Event Log. +``NVME_REG_INTMC`` + Interrupt Mask Clear -``sqes`` - Submission Queue Entry Size, see :c:type:`enum nvme_id_ctrl_sqes `. +``NVME_REG_CC`` + Controller Configuration -``cqes`` - Completion Queue Entry Size, see :c:type:`enum nvme_id_ctrl_cqes `. +``NVME_REG_CSTS`` + Controller Status -``maxcmd`` - Maximum Outstanding Commands indicates the maximum number of - commands that the controller processes at one time for a - particular queue. +``NVME_REG_NSSR`` + NVM Subsystem Reset -``nn`` - Number of Namespaces indicates the maximum value of a valid - nsid for the NVM subsystem. If the MNAN (:c:type:`struct nvme_id_ctrl `.mnan - field is cleared to 0h, then this field also indicates the - maximum number of namespaces supported by the NVM. subsystem. +``NVME_REG_AQA`` + Admin Queue Attributes -``oncs`` - Optional NVM Command Support, see :c:type:`enum nvme_id_ctrl_oncs `. +``NVME_REG_ASQ`` + Admin SQ Base Address -``fuses`` - Fused Operation Support, see :c:type:`enum nvme_id_ctrl_fuses `. +``NVME_REG_ACQ`` + Admin CQ Base Address -``fna`` - Format NVM Attributes, see :c:type:`enum nvme_id_ctrl_fna `. +``NVME_REG_CMBLOC`` + Controller Memory Buffer Location -``vwc`` - Volatile Write Cache, see :c:type:`enum nvme_id_ctrl_vwc `. +``NVME_REG_CMBSZ`` + Controller Memory Buffer Size -``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. +``NVME_REG_BPINFO`` + Boot Partition Information -``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. +``NVME_REG_BPRSEL`` + Boot Partition Read Select -``nvscc`` - NVM Vendor Specific Command Configuration, see :c:type:`enum - nvme_id_ctrl_nvscc `. +``NVME_REG_BPMBL`` + Boot Partition Memory Buffer Location -``nwpc`` - Namespace Write Protection Capabilities, see :c:type:`enum - nvme_id_ctrl_nwpc `. +``NVME_REG_CMBMSC`` + Controller Memory Buffer Memory Space Control -``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. +``NVME_REG_CMBSTS`` + Controller Memory Buffer Status -``sgls`` - SGL Support, see :c:type:`enum nvme_id_ctrl_sgls ` +``NVME_REG_PMRCAP`` + Persistent Memory Capabilities -``mnan`` - Maximum Number of Allowed Namespaces indicates the maximum - number of namespaces supported by the NVM subsystem. +``NVME_REG_PMRCTL`` + Persistent Memory Region Control -``subnqn`` - NVM Subsystem NVMe Qualified Name, UTF-8 null terminated string +``NVME_REG_PMRSTS`` + Persistent Memory Region Status -``ioccsz`` - I/O Queue Command Capsule Supported Size, defines the maximum - I/O command capsule size in 16 byte units. +``NVME_REG_PMREBS`` + Persistent Memory Region Elasticity Buffer Size -``iorcsz`` - I/O Queue Response Capsule Supported Size, defines the maximum - I/O response capsule size in 16 byte units. +``NVME_REG_PMRSWTP`` + Memory Region Sustained Write Throughput -``icdoff`` - In Capsule Data Offset, defines the offset where data starts - within a capsule. This value is applicable to I/O Queues only. +``NVME_REG_PMRMSC`` + Persistent Memory Region Controller Memory Space Control -``fcatt`` - Fabrics Controller Attributes, see :c:type:`enum nvme_id_ctrl_fcatt `. +``NVME_REG_DBS`` + SQ 0 Tail Doorbell -``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. -``ofcs`` - Optional Fabric Commands Support, see :c:type:`enum nvme_id_ctrl_ofcs `. +.. c:function:: bool nvme_is_64bit_reg (__u32 offset) -``psd`` - Power State Descriptors, see :c:type:`struct nvme_id_psd `. + Checks if offset of the controller register is a know 64bit value. -``vs`` - Vendor Specific +**Parameters** + +``__u32 offset`` + Offset of controller register field in bytes +**Description** +This function does not care about transport so that the offset is not going +to be checked inside of this function for the unsupported fields in a +specific transport. For example, BPMBL(Boot Partition Memory Buffer +Location) register is not supported by fabrics, but it can be chcked here. +Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: enum nvme_id_ctrl_cmic -**Constants** +.. c:type:: enum nvme_psd_flags -``NVME_CTRL_CMIC_MULTI_PORT`` - *undescribed* + Possible flag values in nvme power state descriptor -``NVME_CTRL_CMIC_MULTI_CTRL`` - *undescribed* +**Constants** -``NVME_CTRL_CMIC_MULTI_SRIOV`` - *undescribed* +``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. -``NVME_CTRL_CMIC_MULTI_ANA_REPORTING`` - *undescribed* +``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. -.. c:type:: enum nvme_id_ctrl_oaes +.. c:type:: enum nvme_psd_ps - The typical latency in microseconds to enter Runtime D3 + Known values for :c:type:`struct nvme_psd ` #ips and #aps. Use with nvme_psd_power_scale() to extract the power scale field to match this enum. NVME_PSD_IPS_100_MICRO_WATT: 0.0001 watt scale NVME_PSD_IPS_10_MILLI_WATT: 0.01 watt scale **Constants** -``NVME_CTRL_OAES_NA`` +``NVME_PSD_PS_100_MICRO_WATT`` *undescribed* -``NVME_CTRL_OAES_FA`` +``NVME_PSD_PS_10_MILLI_WATT`` *undescribed* -``NVME_CTRL_OAES_ANA`` - *undescribed* -``NVME_CTRL_OAES_PLEA`` - *undescribed* +.. c:function:: unsigned nvme_psd_power_scale (__u8 ps) -``NVME_CTRL_OAES_LBAS`` - : + power scale occupies the upper 3 bits -``NVME_CTRL_OAES_EGE`` +**Parameters** + +``__u8 ps`` *undescribed* -.. c:type:: enum nvme_id_ctrl_ctratt +.. c:type:: enum nvme_psd_workload + Specifies a workload hint in the Power Management Feature (see :c:type:`struct nvme_psd `.apw) to inform the NVM subsystem or indicate the conditions for the active power level. **Constants** -``NVME_CTRL_CTRATT_128_ID`` - *undescribed* +``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. -``NVME_CTRL_CTRATT_NON_OP_PSP`` - *undescribed* +``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 + NVM subsystem are idle. The submission queue(s) + should be sufficiently large allowing the host to + ensure there are multiple commands pending at all + times during the workload. -``NVME_CTRL_CTRATT_NVM_SETS`` - *undescribed* -``NVME_CTRL_CTRATT_READ_RECV_LVLS`` - *undescribed* -``NVME_CTRL_CTRATT_ENDURANCE_GROUPS`` - *undescribed* -``NVME_CTRL_CTRATT_PREDICTABLE_LAT`` - *undescribed* +.. c:type:: struct nvme_id_psd -``NVME_CTRL_CTRATT_TBKAS`` - *undescribed* -``NVME_CTRL_CTRATT_NAMESPACE_GRANULARITY`` - *undescribed* +**Definition** -``NVME_CTRL_CTRATT_SQ_ASSOCIATIONS`` - *undescribed* +:: -``NVME_CTRL_CTRATT_UUID_LIST`` - *undescribed* + struct nvme_id_psd { + __le16 mp; + __u8 rsvd2; + __u8 flags; + __le32 enlat; + __le32 exlat; + __u8 rrt; + __u8 rrl; + __u8 rwt; + __u8 rwl; + __le16 idlp; + __u8 ips; + __u8 rsvd19; + __le16 actp; + __u8 apw; + __u8 aps; + __u8 rsvd23[8]; + }; +**Members** +``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 :c:type:`enum nvme_psd_flags `). A value of 0 indicates + Maximum Power is not reported. +``flags`` + Additional decoding flags, see :c:type:`enum nvme_psd_flags `. -.. c:type:: enum nvme_id_ctrl_cntrltype +``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. +``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. -**Constants** +``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. -``NVME_CTRL_CNTRLTYPE_IO`` - *undescribed* +``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. -``NVME_CTRL_CNTRLTYPE_DISCOVERY`` - *undescribed* +``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 -``NVME_CTRL_CNTRLTYPE_ADMIN`` - *undescribed* +``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 +``idlp`` + Idle Power indicates the typical power consumed by the NVM + subsystem over 30 seconds in this power state when idle. +``ips`` + Idle Power Scale indicates the scale for :c:type:`struct nvme_id_psd `.idlp, + see :c:type:`enum nvme_psd_ps ` for decoding this field. +``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. -.. c:type:: enum nvme_id_ctrl_nvmsr +``apw`` + Active Power Workload indicates the workload used to calculate + maximum power for this power state. See :c:type:`enum nvme_psd_workload ` for + decoding this field. - This field reports information associated with the NVM Subsystem, see :c:type:`struct nvme_id_ctrl `.nvmsr. +``aps`` + Active Power Scale indicates the scale for the :c:type:`struct + nvme_id_psd `.actp, see :c:type:`enum nvme_psd_ps ` for decoding this value. -**Constants** -``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. -``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. +.. c:type:: struct nvme_id_ctrl + Identify Controller data structure -.. c:type:: enum nvme_id_ctrl_vwci +**Definition** + +:: + + struct nvme_id_ctrl { + __le16 vid; + __le16 ssvid; + char sn[20]; + char mn[40]; + char fr[8]; + __u8 rab; + __u8 ieee[3]; + __u8 cmic; + __u8 mdts; + __le16 cntlid; + __le32 ver; + __le32 rtd3r; + __le32 rtd3e; + __le32 oaes; + __le32 ctratt; + __le16 rrls; + __u8 rsvd102[9]; + __u8 cntrltype; + __u8 fguid[16]; + __le16 crdt1; + __le16 crdt2; + __le16 crdt3; + __u8 rsvd134[119]; + __u8 nvmsr; + __u8 vwci; + __u8 mec; + __le16 oacs; + __u8 acl; + __u8 aerl; + __u8 frmw; + __u8 lpa; + __u8 elpe; + __u8 npss; + __u8 avscc; + __u8 apsta; + __le16 wctemp; + __le16 cctemp; + __le16 mtfa; + __le32 hmpre; + __le32 hmmin; + __u8 tnvmcap[16]; + __u8 unvmcap[16]; + __le32 rpmbs; + __le16 edstt; + __u8 dsto; + __u8 fwug; + __le16 kas; + __le16 hctma; + __le16 mntmt; + __le16 mxtmt; + __le32 sanicap; + __le32 hmminds; + __le16 hmmaxd; + __le16 nsetidmax; + __le16 endgidmax; + __u8 anatt; + __u8 anacap; + __le32 anagrpmax; + __le32 nanagrpid; + __le32 pels; + __u8 rsvd356[156]; + __u8 sqes; + __u8 cqes; + __le16 maxcmd; + __le32 nn; + __le16 oncs; + __le16 fuses; + __u8 fna; + __u8 vwc; + __le16 awun; + __le16 awupf; + __u8 nvscc; + __u8 nwpc; + __le16 acwu; + __u8 rsvd534[2]; + __le32 sgls; + __le32 mnan; + __u8 rsvd544[224]; + char subnqn[NVME_NQN_LENGTH]; + __u8 rsvd1024[768]; + __le32 ioccsz; + __le32 iorcsz; + __le16 icdoff; + __u8 fcatt; + __u8 msdbd; + __le16 ofcs; + __u8 rsvd1806[242]; + struct nvme_id_psd psd[32]; + __u8 vs[1024]; + }; - This field indicates information about remaining number of times that VPD contents are able to be updated using the VPD Write command, see :c:type:`struct nvme_id_ctrl `.vwci. +**Members** -**Constants** +``vid`` + PCI Vendor ID, the company vendor identifier that is assigned by + the PCI SIG. -``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. +``ssvid`` + PCI Subsystem Vendor ID, the company vendor identifier that is + assigned by the PCI SIG for the subsystem. -``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. +``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 -.. c:type:: enum nvme_id_ctrl_mec +``ieee`` + IEEE assigned Organization Unique Identifier - Flags indicatings the capabilities of the Management Endpoint in the Controller, :c:type:`struct nvme_id_ctrl `.mec. +``cmic`` + Controller Multipath IO and Namespace Sharing Capabilities of + the controller and NVM subsystem. See :c:type:`enum nvme_id_ctrl_cmic `. -**Constants** +``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 -``NVME_CTRL_MEC_SMBUSME`` - If set, then the NVM Subsystem contains a Management - Endpoint on an SMBus/I2C port. +``cntlid`` + Controller ID, the NVM subsystem unique controller identifier + associated with the controller. -``NVME_CTRL_MEC_PCIEME`` - If set, then the NVM Subsystem contains a Management - Endpoint on a PCIe port. +``ver`` + Version, this field contains the value reported in the Version + register, or property (see :c:type:`enum nvme_registers ` ``NVME_REG_VS``). +``rtd3r`` + RTD3 Resume Latency, the expected latency in microseconds to resume + from Runtime D3 +``rtd3e`` + RTD3 Exit Latency, the typical latency in microseconds to enter + Runtime D3. +``oaes`` + Optional Async Events Supported, see **enum** nvme_id_ctrl_oaes . -.. c:type:: enum nvme_id_ctrl_oacs +``ctratt`` + Controller Attributes, see **enum** nvme_id_ctrl_ctratt - Flags indicating the optional Admin commands and features supported by the controller, see :c:type:`struct nvme_id_ctrl `.oacs. +``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. -**Constants** +``cntrltype`` + Controller Type, see :c:type:`enum nvme_id_ctrl_cntrltype ` -``NVME_CTRL_OACS_SECURITY`` - If set, then the controller supports the - Security Send and Security Receive commands. +``fguid`` + FRU GUID, a 128-bit value that is globally unique for a given + Field Replaceable Unit -``NVME_CTRL_OACS_FORMAT`` - If set then the controller supports the Format - NVM command. +``crdt1`` + Controller Retry Delay time in 100 millisecod units if CQE CRD + field is 1 -``NVME_CTRL_OACS_FW`` - If set, then the controller supports the - Firmware Commit and Firmware Image Download commands. +``crdt2`` + Controller Retry Delay time in 100 millisecod units if CQE CRD + field is 2 -``NVME_CTRL_OACS_NS_MGMT`` - If set, then the controller supports the - Namespace Management capability +``crdt3`` + Controller Retry Delay time in 100 millisecod units if CQE CRD + field is 3 -``NVME_CTRL_OACS_SELF_TEST`` - If set, then the controller supports the Device - Self-test command. +``nvmsr`` + NVM Subsystem Report, see :c:type:`enum nvme_id_ctrl_nvmsr ` -``NVME_CTRL_OACS_DIRECTIVES`` - If set, then the controller supports Directives - and the Directive Send and Directive Receive - commands. +``vwci`` + VPD Write Cycle Information, see :c:type:`enum nvme_id_ctrl_vwci ` -``NVME_CTRL_OACS_NVME_MI`` - If set, then the controller supports the NVMe-MI - Send and NVMe-MI Receive commands. +``mec`` + Management Endpoint Capabilities, see :c:type:`enum nvme_id_ctrl_mec ` -``NVME_CTRL_OACS_VIRT_MGMT`` - If set, then the controller supports the - Virtualization Management command. +``oacs`` + Optional Admin Command Support,the optional Admin commands and + features supported by the controller, see :c:type:`enum nvme_id_ctrl_oacs `. -``NVME_CTRL_OACS_DBBUF_CFG`` - If set, then the controller supports the - Doorbell Buffer Config command. +``acl`` + Abort Command Limit, the maximum number of concurrently + executing Abort commands supported by the controller. This is a + 0's based value. -``NVME_CTRL_OACS_LBA_STATUS`` - If set, then the controller supports the Get LBA - Status capability. +``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. +``frmw`` + Firmware Updates indicates capabilities regarding firmware + updates. See :c:type:`enum nvme_id_ctrl_frmw `. +``lpa`` + Log Page Attributes, see :c:type:`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. -.. c:type:: enum nvme_id_ctrl_frmw +``npss`` + Number of Power States Supported, the number of NVM Express + power states supported by the controller, indicating the number + of valid entries in :c:type:`struct nvme_id_ctrl `.psd. This is a 0's + based value. - Flags and values indicates capabilities regarding firmware updates from :c:type:`struct nvme_id_ctrl `.frmw. +``avscc`` + Admin Vendor Specific Command Configuration, see :c:type:`enum + nvme_id_ctrl_avscc `. -**Constants** +``apsta`` + Autonomous Power State Transition Attributes, see :c:type:`enum + nvme_id_ctrl_apsta `. -``NVME_CTRL_FRMW_1ST_RO`` - If set, the first firmware slot is readonly +``wctemp`` + Warning Composite Temperature Threshold indicates + the minimum Composite Temperature field value (see :c:type:`struct + nvme_smart_log `.critical_comp_time) that indicates an overheating + condition during which controller operation continues. -``NVME_CTRL_FRMW_NR_SLOTS`` - Mask to get the value of the number of - firmware slots that the controller supports. +``cctemp`` + Critical Composite Temperature Threshold, field indicates the + minimum Composite Temperature field value (see :c:type:`struct + nvme_smart_log `.critical_comp_time) that indicates a critical + overheating condition. -``NVME_CTRL_FRMW_FW_ACT_NO_RESET`` - If set, the controller supports firmware +``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. +``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. +``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. +``tnvmcap`` + Total NVM Capacity, the total NVM capacity in the NVM subsystem. + The value is in bytes. -.. c:type:: enum nvme_id_ctrl_lpa - - Flags indicating optional attributes for log pages that are accessed via the Get Log Page command. - -**Constants** - -``NVME_CTRL_LPA_SMART_PER_NS`` - *undescribed* - -``NVME_CTRL_LPA_CMD_EFFECTS`` - *undescribed* - -``NVME_CTRL_LPA_EXTENDED`` - *undescribed* - -``NVME_CTRL_LPA_TELEMETRY`` - *undescribed* - -``NVME_CTRL_LPA_PERSETENT_EVENT`` - *undescribed* - - - - -.. c:type:: enum nvme_id_ctrl_avscc - - Flags indicating the configuration settings for Admin Vendor Specific command handling. - -**Constants** - -``NVME_CTRL_AVSCC_AVS`` - If set, all Admin Vendor Specific Commands use the - optional vendor specific command format with NDT and - NDM fields. - - - - -.. c:type:: enum nvme_id_ctrl_apsta - - Flags indicating the attributes of the autonomous power state transition feature. - -**Constants** - -``NVME_CTRL_APSTA_APST`` - If set, then the controller supports autonomous power - state transitions. - - - - -.. c:type:: enum nvme_id_ctrl_rpmbs - - This field indicates if the controller supports one or more Replay Protected Memory Blocks, from :c:type:`struct nvme_id_ctrl `.rpmbs. - -**Constants** - -``NVME_CTRL_RPMBS_NR_UNITS`` - Mask to get the value of the Number of RPMB Units +``unvmcap`` + Unallocated NVM Capacity, the unallocated NVM capacity in the + NVM subsystem. The value is in bytes. + **rpmbs** Replay Protected Memory Block Support, see :c:type:`enum + nvme_id_ctrl_rpmbs `. + **edstt** Extended Device Self-test Time, if Device Self-test command is + supported (see :c:type:`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. -``NVME_CTRL_RPMBS_AUTH_METHOD`` - Mask to get the value of the Authentication Method +``dsto`` + Device Self-test Options, see :c:type:`enum nvme_id_ctrl_dsto `. -``NVME_CTRL_RPMBS_TOTAL_SIZE`` - Mask to get the value of Total Size +``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 -``NVME_CTRL_RPMBS_ACCESS_SIZE`` - Mask to get the value of Access Size +``kas`` + Keep Alive Support indicates the granularity of the Keep Alive + Timer in 100 millisecond units. +``hctma`` + Host Controlled Thermal Management Attributes, see :c:type:`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. +``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. -.. c:type:: enum nvme_id_ctrl_dsto +``sanicap`` + Sanitize Capabilities, see :c:type:`enum nvme_id_ctrl_sanicap ` - Flags indicating the optional Device Self-test command or operation behaviors supported by the controller or NVM subsystem. +``hmminds`` + Host Memory Buffer Minimum Descriptor Entry Size indicates the + minimum usable size of a Host Memory Buffer Descriptor Entry in + 4 KiB units. -**Constants** +``hmmaxd`` + Host Memory Maximum Descriptors Entries indicates the number of + usable Host Memory Buffer Descriptor Entries. -``NVME_CTRL_DSTO_ONE_DST`` - If set, then the NVM subsystem supports only one - device self-test operation in progress at a time. +``nsetidmax`` + NVM Set Identifier Maximum, defines the maximum value of a valid + 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. +``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. +``anacap`` + Asymmetric Namespace Access Capabilities, see :c:type:`enum + nvme_id_ctrl_anacap `. -.. c:type:: enum nvme_id_ctrl_hctm +``anagrpmax`` + ANA Group Identifier Maximum indicates the maximum value of a + valid ANA Group Identifier for any controller in the NVM + subsystem. - Flags indicate the attributes of the host controlled thermal management feature +``nanagrpid`` + Number of ANA Group Identifiers indicates the number of ANA + groups supported by this controller. -**Constants** +``pels`` + Persistent Event Log Size indicates the maximum reportable size + for the Persistent Event Log. -``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``. +``sqes`` + Submission Queue Entry Size, see :c:type:`enum nvme_id_ctrl_sqes `. +``cqes`` + Completion Queue Entry Size, see :c:type:`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. +``nn`` + Number of Namespaces indicates the maximum value of a valid + nsid for the NVM subsystem. If the MNAN (:c:type:`struct nvme_id_ctrl `.mnan + field is cleared to 0h, then this field also indicates the + maximum number of namespaces supported by the NVM. subsystem. -.. c:type:: enum nvme_id_ctrl_sanicap +``oncs`` + Optional NVM Command Support, see :c:type:`enum nvme_id_ctrl_oncs `. - Indicates attributes for sanitize operations. +``fuses`` + Fused Operation Support, see :c:type:`enum nvme_id_ctrl_fuses `. -**Constants** +``fna`` + Format NVM Attributes, see :c:type:`enum nvme_id_ctrl_fna `. -``NVME_CTRL_SANICAP_CES`` - Crypto Erase Support. If set, then the - controller supports the Crypto Erase sanitize operation. +``vwc`` + Volatile Write Cache, see :c:type:`enum nvme_id_ctrl_vwc `. -``NVME_CTRL_SANICAP_BES`` - Block Erase Support. If set, then the controller - supports the Block Erase sanitize operation. +``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. -``NVME_CTRL_SANICAP_OWS`` - Overwrite Support. If set, then the controller - supports the Overwrite sanitize operation. +``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. -``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. +``nvscc`` + NVM Vendor Specific Command Configuration, see :c:type:`enum + nvme_id_ctrl_nvscc `. -``NVME_CTRL_SANICAP_NODMMAS`` - No-Deallocate Modifies Media After Sanitize, - mask to extract value. +``nwpc`` + Namespace Write Protection Capabilities, see :c:type:`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. +``sgls`` + SGL Support, see :c:type:`enum nvme_id_ctrl_sgls ` +``mnan`` + Maximum Number of Allowed Namespaces indicates the maximum + number of namespaces supported by the NVM subsystem. -.. c:type:: enum nvme_id_ctrl_anacap +``subnqn`` + NVM Subsystem NVMe Qualified Name, UTF-8 null terminated string - This field indicates the capabilities associated with Asymmetric Namespace Access Reporting. +``ioccsz`` + I/O Queue Command Capsule Supported Size, defines the maximum + I/O command capsule size in 16 byte units. -**Constants** +``iorcsz`` + I/O Queue Response Capsule Supported Size, defines the maximum + I/O response capsule size in 16 byte units. -``NVME_CTRL_ANACAP_OPT`` - If set, then the controller is able to - report ANA Optimized state. +``icdoff`` + In Capsule Data Offset, defines the offset where data starts + within a capsule. This value is applicable to I/O Queues only. -``NVME_CTRL_ANACAP_NON_OPT`` - If set, then the controller is able to - report ANA Non-Optimized state. +``fcatt`` + Fabrics Controller Attributes, see :c:type:`enum nvme_id_ctrl_fcatt `. -``NVME_CTRL_ANACAP_INACCESSIBLE`` - If set, then the controller is able to - report ANA Inaccessible state. +``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. -``NVME_CTRL_ANACAP_PERSISTENT_LOSS`` - If set, then the controller is able to - report ANA Persistent Loss state. +``ofcs`` + Optional Fabric Commands Support, see :c:type:`enum nvme_id_ctrl_ofcs `. -``NVME_CTRL_ANACAP_CHANGE`` - If set, then the controller is able to - report ANA Change state. +``psd`` + Power State Descriptors, see :c:type:`struct nvme_id_psd `. -``NVME_CTRL_ANACAP_GRPID_NO_CHG`` - If set, then the ANAGRPID field in the - Identify Namespace data structure - (:c:type:`struct nvme_id_ns `.anagrpid), does not - change while the namespace is attached to - any controller. +``vs`` + Vendor Specific -``NVME_CTRL_ANACAP_GRPID_MGMT`` - If set, then the controller supports a - non-zero value in the ANAGRPID field of - the Namespace Management command. -.. c:type:: enum nvme_id_ctrl_sqes +.. c:type:: enum nvme_id_ctrl_cmic - Defines the required and maximum Submission Queue entry size when using the NVM Command Set. **Constants** -``NVME_CTRL_SQES_MIN`` - Mask to get the value of the required Submission Queue - 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. +``NVME_CTRL_CMIC_MULTI_PORT`` + *undescribed* +``NVME_CTRL_CMIC_MULTI_CTRL`` + *undescribed* +``NVME_CTRL_CMIC_MULTI_SRIOV`` + *undescribed* +``NVME_CTRL_CMIC_MULTI_ANA_REPORTING`` + *undescribed* -.. c:type:: enum - Defines the required and maximum Completion Queue entry size when using the NVM Command Set. -**Constants** -``NVME_CTRL_CQES_MIN`` - Mask to get the value of the required Completion Queue - Entry size when using the NVM Command Set. +.. c:type:: enum nvme_id_ctrl_oaes -``NVME_CTRL_CQES_MAX`` - Mask to get the value of the maximum Completion Queue - entry size when using the NVM Command Set. + The typical latency in microseconds to enter Runtime D3 +**Constants** +``NVME_CTRL_OAES_NA`` + *undescribed* +``NVME_CTRL_OAES_FA`` + *undescribed* -.. c:type:: enum nvme_id_ctrl_oncs +``NVME_CTRL_OAES_ANA`` + *undescribed* - This field indicates the optional NVM commands and features supported by the controller. +``NVME_CTRL_OAES_PLEA`` + *undescribed* -**Constants** +``NVME_CTRL_OAES_LBAS`` + : -``NVME_CTRL_ONCS_COMPARE`` - If set, then the controller supports - the Compare command. +``NVME_CTRL_OAES_EGE`` + *undescribed* -``NVME_CTRL_ONCS_WRITE_UNCORRECTABLE`` - If set, then the controller supports - the Write Uncorrectable command. -``NVME_CTRL_ONCS_DSM`` - If set, then the controller supports - the Dataset Management command. -``NVME_CTRL_ONCS_WRITE_ZEROES`` - If set, then the controller supports - 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. +.. c:type:: enum nvme_id_ctrl_ctratt -``NVME_CTRL_ONCS_RESERVATIONS`` - If set, then the controller supports - reservations. -``NVME_CTRL_ONCS_TIMESTAMP`` - If set, then the controller supports - the Timestamp feature. +**Constants** -``NVME_CTRL_ONCS_VERIFY`` - If set, then the controller supports - the Verify command. +``NVME_CTRL_CTRATT_128_ID`` + *undescribed* + +``NVME_CTRL_CTRATT_NON_OP_PSP`` + *undescribed* + +``NVME_CTRL_CTRATT_NVM_SETS`` + *undescribed* +``NVME_CTRL_CTRATT_READ_RECV_LVLS`` + *undescribed* +``NVME_CTRL_CTRATT_ENDURANCE_GROUPS`` + *undescribed* +``NVME_CTRL_CTRATT_PREDICTABLE_LAT`` + *undescribed* -.. c:type:: enum nvme_id_ctrl_fuses +``NVME_CTRL_CTRATT_TBKAS`` + *undescribed* - This field indicates the fused operations that the controller supports. +``NVME_CTRL_CTRATT_NAMESPACE_GRANULARITY`` + *undescribed* -**Constants** +``NVME_CTRL_CTRATT_SQ_ASSOCIATIONS`` + *undescribed* -``NVME_CTRL_FUSES_COMPARE_AND_WRITE`` - If set, then the controller supports the - Compare and Write fused operation. +``NVME_CTRL_CTRATT_UUID_LIST`` + *undescribed* -.. c:type:: enum nvme_id_ctrl_fna +.. c:type:: enum nvme_id_ctrl_cntrltype - This field indicates attributes for the Format NVM command. **Constants** -``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. +``NVME_CTRL_CNTRLTYPE_IO`` + *undescribed* -``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_CNTRLTYPE_DISCOVERY`` + *undescribed* -``NVME_CTRL_FNA_CRYPTO_ERASE`` - If set, then cryptographic erase is - supported. If cleared, then cryptographic - erase is not supported. +``NVME_CTRL_CNTRLTYPE_ADMIN`` + *undescribed* -.. c:type:: enum nvme_id_ctrl_vwc +.. c:type:: enum nvme_id_ctrl_nvmsr + This field reports information associated with the NVM Subsystem, see :c:type:`struct nvme_id_ctrl `.nvmsr. **Constants** -``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``. +``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. -``NVME_CTRL_VWC_FLUSH`` - Mask to get the value of the flush command behavior. +``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. -.. c:type:: enum nvme_id_ctrl_nvscc +.. c:type:: enum nvme_id_ctrl_vwci - This field indicates the configuration settings for NVM Vendor Specific command handling. + This field indicates information about remaining number of times that VPD contents are able to be updated using the VPD Write command, see :c:type:`struct nvme_id_ctrl `.vwci. **Constants** -``NVME_CTRL_NVSCC_FMT`` - If set, all NVM Vendor Specific Commands use the - format format with NDT and NDM fields. +``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. +``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. -.. c:type:: enum nvme_id_ctrl_nwpc - This field indicates the optional namespace write protection capabilities supported by the controller. +.. c:type:: enum nvme_id_ctrl_mec -**Constants** + Flags indicatings the capabilities of the Management Endpoint in the Controller, :c:type:`struct nvme_id_ctrl `.mec. -``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. +**Constants** -``NVME_CTRL_NWPC_WRITE_PROTECT_POWER_CYCLE`` - If set, then the controller - supports the Write Protect Until - Power Cycle state. +``NVME_CTRL_MEC_SMBUSME`` + If set, then the NVM Subsystem contains a Management + Endpoint on an SMBus/I2C port. -``NVME_CTRL_NWPC_WRITE_PROTECT_PERMANENT`` - If set, then the controller - supports the Permanent Write - Protect state. +``NVME_CTRL_MEC_PCIEME`` + If set, then the NVM Subsystem contains a Management + Endpoint on a PCIe port. -.. c:type:: enum nvme_id_ctrl_sgls +.. c:type:: enum nvme_id_ctrl_oacs - This field indicates if SGLs are supported for the NVM Command Set and the particular SGL types supported. + Flags indicating the optional Admin commands and features supported by the controller, see :c:type:`struct nvme_id_ctrl `.oacs. **Constants** -``NVME_CTRL_SGLS_SUPPORTED`` - *undescribed* - -``NVME_CTRL_SGLS_KEYED`` - *undescribed* +``NVME_CTRL_OACS_SECURITY`` + If set, then the controller supports the + Security Send and Security Receive commands. -``NVME_CTRL_SGLS_BIT_BUCKET`` - *undescribed* +``NVME_CTRL_OACS_FORMAT`` + If set then the controller supports the Format + NVM command. -``NVME_CTRL_SGLS_MPTR_BYTE_ALIGNED`` - *undescribed* +``NVME_CTRL_OACS_FW`` + If set, then the controller supports the + Firmware Commit and Firmware Image Download commands. -``NVME_CTRL_SGLS_OVERSIZE`` - *undescribed* +``NVME_CTRL_OACS_NS_MGMT`` + If set, then the controller supports the + Namespace Management capability -``NVME_CTRL_SGLS_MPTR_SGL`` - *undescribed* +``NVME_CTRL_OACS_SELF_TEST`` + If set, then the controller supports the Device + Self-test command. -``NVME_CTRL_SGLS_OFFSET`` - *undescribed* +``NVME_CTRL_OACS_DIRECTIVES`` + If set, then the controller supports Directives + and the Directive Send and Directive Receive + commands. -``NVME_CTRL_SGLS_TPORT`` - *undescribed* +``NVME_CTRL_OACS_NVME_MI`` + If set, then the controller supports the NVMe-MI + Send and NVMe-MI Receive commands. +``NVME_CTRL_OACS_VIRT_MGMT`` + If set, then the controller supports the + Virtualization Management command. +``NVME_CTRL_OACS_DBBUF_CFG`` + If set, then the controller supports the + Doorbell Buffer Config command. +``NVME_CTRL_OACS_LBA_STATUS`` + If set, then the controller supports the Get LBA + Status capability. -.. c:type:: enum nvme_id_ctrl_fcatt - This field indicates attributes of the controller that are specific to NVMe over Fabrics. -**Constants** -``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. +.. c:type:: enum nvme_id_ctrl_frmw + Flags and values indicates capabilities regarding firmware updates from :c:type:`struct nvme_id_ctrl `.frmw. +**Constants** +``NVME_CTRL_FRMW_1ST_RO`` + If set, the first firmware slot is readonly -.. c:type:: enum nvme_id_ctrl_ofcs +``NVME_CTRL_FRMW_NR_SLOTS`` + Mask to get the value of the number of + firmware slots that the controller supports. - Indicate whether the controller supports optional fabric commands. +``NVME_CTRL_FRMW_FW_ACT_NO_RESET`` + If set, the controller supports firmware + activation without a reset. -**Constants** -``NVME_CTRL_OFCS_DISCONNECT`` - If set, then the controller supports the - Disconnect command and deletion of individual - I/O Queues. +.. c:type:: enum nvme_id_ctrl_lpa + Flags indicating optional attributes for log pages that are accessed via the Get Log Page command. -.. c:type:: struct nvme_lbaf +**Constants** - LBA Format Data Structure +``NVME_CTRL_LPA_SMART_PER_NS`` + *undescribed* -**Definition** +``NVME_CTRL_LPA_CMD_EFFECTS`` + *undescribed* -:: +``NVME_CTRL_LPA_EXTENDED`` + *undescribed* - struct nvme_lbaf { - __le16 ms; - __u8 ds; - __u8 rp; - }; +``NVME_CTRL_LPA_TELEMETRY`` + *undescribed* -**Members** +``NVME_CTRL_LPA_PERSETENT_EVENT`` + *undescribed* -``ms`` - Metadata Size indicates the number of metadata bytes provided per LBA - based on the LBA Data Size indicated. -``ds`` - LBA Data Size indicates the LBA data size supported, reported as a - power of two. -``rp`` - Relative Performance, see :c:type:`enum nvme_lbaf_rp `. +.. c:type:: enum nvme_id_ctrl_avscc + Flags indicating the configuration settings for Admin Vendor Specific command handling. +**Constants** +``NVME_CTRL_AVSCC_AVS`` + If set, all Admin Vendor Specific Commands use the + optional vendor specific command format with NDT and + NDM fields. -.. c:type:: enum nvme_lbaf_rp - This field indicates the relative performance of the LBA format indicated relative to other LBA formats supported by the controller. -**Constants** -``NVME_LBAF_RP_BEST`` - Best performance +.. c:type:: enum nvme_id_ctrl_apsta -``NVME_LBAF_RP_BETTER`` - Better performance + Flags indicating the attributes of the autonomous power state transition feature. -``NVME_LBAF_RP_GOOD`` - Good performance +**Constants** -``NVME_LBAF_RP_DEGRADED`` - Degraded performance +``NVME_CTRL_APSTA_APST`` + If set, then the controller supports autonomous power + state transitions. -``NVME_LBAF_RP_MASK`` - Mask to get the relative performance value from the - field +.. c:type:: enum nvme_id_ctrl_rpmbs -.. c:type:: struct nvme_id_ns + This field indicates if the controller supports one or more Replay Protected Memory Blocks, from :c:type:`struct nvme_id_ctrl `.rpmbs. - Identify Namespace data structure +**Constants** -**Definition** +``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 - struct nvme_id_ns { - __le64 nsze; - __le64 ncap; - __le64 nuse; - __u8 nsfeat; - __u8 nlbaf; - __u8 flbas; - __u8 mc; - __u8 dpc; - __u8 dps; - __u8 nmic; - __u8 rescap; - __u8 fpi; - __u8 dlfeat; - __le16 nawun; - __le16 nawupf; - __le16 nacwu; - __le16 nabsn; - __le16 nabo; - __le16 nabspf; - __le16 noiob; - __u8 nvmcap[16]; - __le16 npwg; - __le16 npwa; - __le16 npdg; - __le16 npda; - __le16 nows; - __u8 rsvd74[18]; - __le32 anagrpid; - __u8 rsvd96[3]; - __u8 nsattr; - __le16 nvmsetid; - __le16 endgid; - __u8 nguid[16]; - __u8 eui64[8]; - struct nvme_lbaf lbaf[16]; - __u8 rsvd192[192]; - __u8 vs[3712]; - }; +``NVME_CTRL_RPMBS_TOTAL_SIZE`` + Mask to get the value of Total Size -**Members** +``NVME_CTRL_RPMBS_ACCESS_SIZE`` + Mask to get the value of Access Size -``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. -``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. -``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. -``nsfeat`` - Namespace Features, see :c:type:`enum nvme_id_nsfeat `. +.. c:type:: enum nvme_id_ctrl_dsto -``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 :c:type:`struct nvme_id_ns `.labf. + Flags indicating the optional Device Self-test command or operation behaviors supported by the controller or NVM subsystem. -``flbas`` - Formatted LBA Size, see :c:type:`enum nvme_id_ns_flbas `. +**Constants** -``mc`` - Metadata Capabilities, see :c:type:`enum nvme_id_ns_mc `. +``NVME_CTRL_DSTO_ONE_DST`` + If set, then the NVM subsystem supports only one + device self-test operation in progress at a time. -``dpc`` - End-to-end Data Protection Capabilities, see :c:type:`enum - nvme_id_ns_dpc `. -``dps`` - End-to-end Data Protection Type Settings, see :c:type:`enum - nvme_id_ns_dps `. -``nmic`` - Namespace Multi-path I/O and Namespace Sharing Capabilities, see - :c:type:`enum nvme_id_ns_nmic `. -``rescap`` - Reservation Capabilities, see :c:type:`enum nvme_id_ns_rescap `. +.. c:type:: enum nvme_id_ctrl_hctm -``fpi`` - Format Progress Indicator, see :c:type:`enum nvme_nd_ns_fpi `. + Flags indicate the attributes of the host controlled thermal management feature -``dlfeat`` - Deallocate Logical Block Features, see :c:type:`enum nvme_id_ns_dlfeat `. +**Constants** -``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. +``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``. -``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. -``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. -``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. -``nabo`` - Namespace Atomic Boundary Offset indicates the LBA on this - namespace where the first atomic boundary starts. +.. c:type:: enum nvme_id_ctrl_sanicap -``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. + Indicates attributes for sanitize operations. -``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. +**Constants** -``nvmcap`` - NVM Capacity indicates the total size of the NVM allocated to - this namespace. The value is in bytes. +``NVME_CTRL_SANICAP_CES`` + Crypto Erase Support. If set, then the + controller supports the Crypto Erase sanitize operation. -``npwg`` - Namespace Preferred Write Granularity indicates the smallest - recommended write granularity in logical blocks for this - namespace. This is a 0's based value. +``NVME_CTRL_SANICAP_BES`` + Block Erase Support. If set, then the controller + supports the Block Erase sanitize operation. -``npwa`` - Namespace Preferred Write Alignment indicates the recommended - write alignment in logical blocks for this namespace. This is a - 0's based value. +``NVME_CTRL_SANICAP_OWS`` + Overwrite Support. If set, then the controller + supports the Overwrite sanitize operation. -``npdg`` - Namespace Preferred Deallocate Granularity indicates the - recommended granularity in logical blocks for the Dataset - Management command with the Attribute - Deallocate bit. +``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. -``npda`` - Namespace Preferred Deallocate Alignment indicates the - recommended alignment in logical blocks for the Dataset - Management command with the Attribute - Deallocate bit +``NVME_CTRL_SANICAP_NODMMAS`` + No-Deallocate Modifies Media After Sanitize, + mask to extract value. -``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. -``anagrpid`` - ANA Group Identifier indicates the ANA Group Identifier of the - ANA group of which the namespace is a member. -``nsattr`` - Namespace Attributes, see :c:type:`enum nvme_id_ns_attr `. -``nvmsetid`` - NVM Set Identifier indicates the NVM Set with which this - namespace is associated. +.. c:type:: enum nvme_id_ctrl_anacap -``endgid`` - Endurance Group Identifier indicates the Endurance Group with - which this namespace is associated. + This field indicates the capabilities associated with Asymmetric Namespace Access Reporting. -``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 +**Constants** -``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 - remains fixed throughout the life of the namespace and is - preserved across namespace and controller operations +``NVME_CTRL_ANACAP_OPT`` + If set, then the controller is able to + report ANA Optimized state. -``lbaf`` - LBA Format, see :c:type:`struct nvme_lbaf `. +``NVME_CTRL_ANACAP_NON_OPT`` + If set, then the controller is able to + report ANA Non-Optimized state. -``vs`` - Vendor Specific +``NVME_CTRL_ANACAP_INACCESSIBLE`` + If set, then the controller is able to + 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. +``NVME_CTRL_ANACAP_GRPID_NO_CHG`` + If set, then the ANAGRPID field in the + Identify Namespace data structure + (:c:type:`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. -.. c:type:: enum nvme_id_nsfeat - This field defines features of the namespace. -**Constants** -``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. +.. c:type:: enum nvme_id_ctrl_sqes -``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. + Defines the required and maximum Submission Queue entry size when using the NVM Command Set. -``NVME_NS_FEAT_DULBE`` - If set, indicates that the controller supports the - 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. +**Constants** -``NVME_NS_FEAT_ID_REUSE`` - *undescribed* +``NVME_CTRL_SQES_MIN`` + Mask to get the value of the required Submission Queue + Entry size when using the NVM Command Set. -``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 +``NVME_CTRL_SQES_MAX`` + Mask to get the value of the maximum Submission Queue + entry size when using the NVM Command Set. -.. c:type:: enum nvme_id_ns_flbas +.. c:type:: enum - This field indicates the LBA data size & metadata size combination that the namespace has been formatted with + Defines the required and maximum Completion Queue entry size when using the NVM Command Set. **Constants** -``NVME_NS_FLBAS_LBA_MASK`` - Mask to get the index of one of the 16 supported - LBA Formats indicated in :c:type:`struct nvme_id_ns `.lbaf. +``NVME_CTRL_CQES_MIN`` + Mask to get the value of the required Completion Queue + Entry size when using the NVM Command Set. -``NVME_NS_FLBAS_META_EXT`` - Applicable only if format contains metadata. If - this bit is set, indicates that the metadata is - transferred at the end of the data LBA, creating an - extended data LBA. If cleared, indicates that all - of the metadata for a command is transferred as a - separate contiguous buffer of data. +``NVME_CTRL_CQES_MAX`` + Mask to get the value of the maximum Completion Queue + entry size when using the NVM Command Set. -.. c:type:: enum nvme_id_ns_mc +.. c:type:: enum nvme_id_ctrl_oncs - This field indicates the capabilities for metadata. + This field indicates the optional NVM commands and features supported by the controller. **Constants** -``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. - -``NVME_NS_MC_SEPARATE`` - If set, indicates that the namespace supports the - metadata being transferred as part of an extended data LBA. +``NVME_CTRL_ONCS_COMPARE`` + If set, then the controller supports + the Compare command. +``NVME_CTRL_ONCS_WRITE_UNCORRECTABLE`` + If set, then the controller supports + the Write Uncorrectable command. +``NVME_CTRL_ONCS_DSM`` + If set, then the controller supports + the Dataset Management command. +``NVME_CTRL_ONCS_WRITE_ZEROES`` + If set, then the controller supports + the Write Zeroes command. -.. c:type:: enum nvme_id_ns_dpc +``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. - This field indicates the capabilities for the end-to-end data protection feature. +``NVME_CTRL_ONCS_RESERVATIONS`` + If set, then the controller supports + reservations. -**Constants** +``NVME_CTRL_ONCS_TIMESTAMP`` + If set, then the controller supports + the Timestamp feature. -``NVME_NS_DPC_PI_TYPE1`` - If set, indicates that the namespace supports - Protection Information Type 1. +``NVME_CTRL_ONCS_VERIFY`` + If set, then the controller supports + the Verify command. -``NVME_NS_DPC_PI_TYPE2`` - If set, indicates that the namespace supports - Protection Information Type 2. -``NVME_NS_DPC_PI_TYPE3`` - If set, indicates that the namespace supports - 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. -``NVME_NS_DPC_PI_LAST`` - If set, indicates that the namespace supports - protection information transferred as the last eight - bytes of metadata. +.. c:type:: enum nvme_id_ctrl_fuses + This field indicates the fused operations that the controller supports. +**Constants** +``NVME_CTRL_FUSES_COMPARE_AND_WRITE`` + If set, then the controller supports the + Compare and Write fused operation. -.. c:type:: enum nvme_id_ns_dps - This field indicates the Type settings for the end-to-end data protection feature. -**Constants** -``NVME_NS_DPS_PI_NONE`` - Protection information is not enabled +.. c:type:: enum nvme_id_ctrl_fna -``NVME_NS_DPS_PI_TYPE1`` - Protection information is enabled, Type 1 + This field indicates attributes for the Format NVM command. -``NVME_NS_DPS_PI_TYPE2`` - Protection information is enabled, Type 2 +**Constants** -``NVME_NS_DPS_PI_TYPE3`` - Protection information is enabled, Type 3 +``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. -``NVME_NS_DPS_PI_MASK`` - Mask to get the value of the PI type +``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_NS_DPS_PI_FIRST`` - If set, indicates that the protection information, if - enabled, is transferred as the first eight bytes of - metadata. +``NVME_CTRL_FNA_CRYPTO_ERASE`` + If set, then cryptographic erase is + supported. If cleared, then cryptographic + erase is not supported. -.. c:type:: enum nvme_id_ns_nmic +.. c:type:: enum nvme_id_ctrl_vwc - This field specifies multi-path I/O and namespace sharing capabilities of the namespace. **Constants** -``NVME_NS_NMIC_SHARED`` - If set, then the namespace may be attached to two or - more controllers in the NVM subsystem concurrently +``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``. +``NVME_CTRL_VWC_FLUSH`` + Mask to get the value of the flush command behavior. -.. c:type:: enum nvme_id_ns_rescap - This field indicates the reservation capabilities of the namespace. +.. c:type:: enum nvme_id_ctrl_nvscc + + This field indicates the configuration settings for NVM Vendor Specific command handling. **Constants** -``NVME_NS_RESCAP_PTPL`` - If set, indicates that the namespace supports the - Persist Through Power Loss capability. +``NVME_CTRL_NVSCC_FMT`` + If set, all NVM Vendor Specific Commands use the + format format with NDT and NDM fields. -``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. -``NVME_NS_RESCAP_EARO`` - If set, indicates that the namespace supports the - Exclusive Access - Registrants Only reservation type. +.. c:type:: enum nvme_id_ctrl_nwpc -``NVME_NS_RESCAP_WEAR`` - If set, indicates that the namespace supports the - Write Exclusive - All Registrants reservation type. + This field indicates the optional namespace write protection capabilities supported by the controller. -``NVME_NS_RESCAP_EAAR`` - If set, indicates that the namespace supports the - Exclusive Access - All Registrants reservation type. +**Constants** -``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. +``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. + +``NVME_CTRL_NWPC_WRITE_PROTECT_POWER_CYCLE`` + If set, then the controller + 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. -.. c:type:: enum nvme_nd_ns_fpi +.. c:type:: enum nvme_id_ctrl_sgls - If a format operation is in progress, this field indicates the percentage of the namespace that remains to be formatted. + This field indicates if SGLs are supported for the NVM Command Set and the particular SGL types supported. **Constants** -``NVME_NS_FPI_REMAINING`` - Mask to get the format percent remaining value +``NVME_CTRL_SGLS_SUPPORTED`` + *undescribed* -``NVME_NS_FPI_SUPPORTED`` - If set, indicates that the namespace supports the - Format Progress Indicator defined for the field. +``NVME_CTRL_SGLS_KEYED`` + *undescribed* +``NVME_CTRL_SGLS_BIT_BUCKET`` + *undescribed* +``NVME_CTRL_SGLS_MPTR_BYTE_ALIGNED`` + *undescribed* +``NVME_CTRL_SGLS_OVERSIZE`` + *undescribed* -.. c:type:: enum nvme_id_ns_dlfeat +``NVME_CTRL_SGLS_MPTR_SGL`` + *undescribed* - This field indicates information about features that affect deallocating logical blocks for this namespace. +``NVME_CTRL_SGLS_OFFSET`` + *undescribed* -**Constants** +``NVME_CTRL_SGLS_TPORT`` + *undescribed* -``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. +.. c:type:: enum nvme_id_ctrl_fcatt -``NVME_NS_DLFEAT_WRITE_ZEROES`` - If set, indicates that the controller supports - the Deallocate bit in the Write Zeroes command - for this namespace. + This field indicates attributes of the controller that are specific to NVMe over Fabrics. -``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 +**Constants** + +``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. -.. c:type:: enum nvme_id_ns_attr +.. c:type:: enum nvme_id_ctrl_ofcs - Specifies attributes of the namespace. + Indicate whether the controller supports optional fabric commands. **Constants** -``NVME_NS_NSATTR_WRITE_PROTECTED`` - If set, then the namespace is currently - write protected and all write access to the - namespace shall fail. +``NVME_CTRL_OFCS_DISCONNECT`` + If set, then the controller supports the + Disconnect command and deletion of individual + I/O Queues. -.. c:type:: struct nvme_ns_id_desc +.. c:type:: struct nvme_lbaf + LBA Format Data Structure **Definition** :: - struct nvme_ns_id_desc { - __u8 nidt; - __u8 nidl; - __le16 reserved; - __u8 nid[]; + struct nvme_lbaf { + __le16 ms; + __u8 ds; + __u8 rp; }; **Members** -``nidt`` - Namespace Identifier Type, see :c:type:`enum nvme_ns_id_desc_nidt ` +``ms`` + Metadata Size indicates the number of metadata bytes provided per LBA + based on the LBA Data Size indicated. -``nidl`` - Namespace Identifier Length contains the length in bytes of the - :c:type:`struct nvme_id_ns `.nid. +``ds`` + LBA Data Size indicates the LBA data size supported, reported as a + power of two. -``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 :c:type:`struct nvme_id_ns `.nidl. +``rp`` + Relative Performance, see :c:type:`enum nvme_lbaf_rp `. -.. c:type:: enum nvme_ns_id_desc_nidt +.. c:type:: enum nvme_lbaf_rp - Known namespace identifier types + This field indicates the relative performance of the LBA format indicated relative to other LBA formats supported by the controller. **Constants** -``NVME_NIDT_EUI64`` - IEEE Extended Unique Identifier, the NID field contains a - copy of the EUI64 field in the struct nvme_id_ns.eui64. +``NVME_LBAF_RP_BEST`` + Best performance -``NVME_NIDT_NGUID`` - Namespace Globally Unique Identifier, the NID field - contains a copy of the NGUID field in struct nvme_id_ns.nguid. +``NVME_LBAF_RP_BETTER`` + Better performance -``NVME_NIDT_UUID`` - The NID field contains a 128-bit Universally Unique - Identifier (UUID) as specified in RFC 4122. +``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 -.. c:type:: struct nvme_nvmset_attr - NVM Set Attributes Entry +.. c:type:: struct nvme_id_ns + + Identify Namespace data structure **Definition** :: - struct nvme_nvmset_attr { - __le16 id; - __le16 endurance_group_id; - __u8 rsvd4[4]; - __le32 random_4k_read_typical; - __le32 opt_write_size; - __u8 total_nvmset_cap[16]; - __u8 unalloc_nvmset_cap[16]; - __u8 rsvd48[80]; + struct nvme_id_ns { + __le64 nsze; + __le64 ncap; + __le64 nuse; + __u8 nsfeat; + __u8 nlbaf; + __u8 flbas; + __u8 mc; + __u8 dpc; + __u8 dps; + __u8 nmic; + __u8 rescap; + __u8 fpi; + __u8 dlfeat; + __le16 nawun; + __le16 nawupf; + __le16 nacwu; + __le16 nabsn; + __le16 nabo; + __le16 nabspf; + __le16 noiob; + __u8 nvmcap[16]; + __le16 npwg; + __le16 npwa; + __le16 npdg; + __le16 npda; + __le16 nows; + __u8 rsvd74[18]; + __le32 anagrpid; + __u8 rsvd96[3]; + __u8 nsattr; + __le16 nvmsetid; + __le16 endgid; + __u8 nguid[16]; + __u8 eui64[8]; + struct nvme_lbaf lbaf[16]; + __u8 rsvd192[192]; + __u8 vs[3712]; }; **Members** -``id`` - NVM Set Identifier +``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. -``endurance_group_id`` - Endurance Group Identifier +``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. -``random_4k_read_typical`` - Random 4 KiB Read Typical indicates the typical - time to complete a 4 KiB random read in 100 - nanosecond units when the NVM Set is in a - Predictable Latency Mode Deterministic Window and - there is 1 outstanding command per NVM Set. +``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. +``nsfeat`` + Namespace Features, see :c:type:`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 :c:type:`struct nvme_id_ns `.labf. +``flbas`` + Formatted LBA Size, see :c:type:`enum nvme_id_ns_flbas `. +``mc`` + Metadata Capabilities, see :c:type:`enum nvme_id_ns_mc `. +``dpc`` + End-to-end Data Protection Capabilities, see :c:type:`enum + nvme_id_ns_dpc `. -.. c:type:: struct nvme_id_nvmset_list +``dps`` + End-to-end Data Protection Type Settings, see :c:type:`enum + nvme_id_ns_dps `. - **nid**; +``nmic`` + Namespace Multi-path I/O and Namespace Sharing Capabilities, see + :c:type:`enum nvme_id_ns_nmic `. -**Definition** +``rescap`` + Reservation Capabilities, see :c:type:`enum nvme_id_ns_rescap `. -:: +``fpi`` + Format Progress Indicator, see :c:type:`enum nvme_nd_ns_fpi `. - struct nvme_id_nvmset_list { - __u8 nid; - __u8 rsvd1[127]; - struct nvme_nvmset_attr ent[NVME_ID_NVMSET_LIST_MAX]; - }; +``dlfeat`` + Deallocate Logical Block Features, see :c:type:`enum nvme_id_ns_dlfeat `. -**Members** +``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. -``ent`` - ; +``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. +``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. +``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. +``nabo`` + Namespace Atomic Boundary Offset indicates the LBA on this + 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. -.. c:type:: struct nvme_id_ns_granularity_desc +``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. +``nvmcap`` + NVM Capacity indicates the total size of the NVM allocated to + this namespace. The value is in bytes. -**Definition** +``npwg`` + Namespace Preferred Write Granularity indicates the smallest + 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. - struct nvme_id_ns_granularity_desc { - __le64 namespace_size_granularity; - __le64 namespace_capacity_granularity; - }; +``npdg`` + Namespace Preferred Deallocate Granularity indicates the + recommended granularity in logical blocks for the Dataset + Management command with the Attribute - Deallocate bit. -**Members** +``npda`` + Namespace Preferred Deallocate Alignment indicates the + 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. +``anagrpid`` + ANA Group Identifier indicates the ANA Group Identifier of the + ANA group of which the namespace is a member. +``nsattr`` + Namespace Attributes, see :c:type:`enum nvme_id_ns_attr `. +``nvmsetid`` + NVM Set Identifier indicates the NVM Set with which this + namespace is associated. -.. c:type:: struct nvme_id_ns_granularity_list +``endgid`` + Endurance Group Identifier indicates the Endurance Group with + 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 -**Definition** +``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 + remains fixed throughout the life of the namespace and is + preserved across namespace and controller operations -:: +``lbaf`` + LBA Format, see :c:type:`struct nvme_lbaf `. - struct nvme_id_ns_granularity_list { - __le32 attributes; - __u8 num_descriptors; - __u8 rsvd[27]; - struct nvme_id_ns_granularity_desc entry[NVME_ID_ND_DESCRIPTOR_MAX]; - __u8 rsvd288[3808]; - }; +``vs`` + Vendor Specific -**Members** +.. c:type:: enum nvme_id_nsfeat -.. c:type:: struct nvme_id_uuid_list_entry + This field defines features of the namespace. +**Constants** -**Definition** +``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. -:: +``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. - struct nvme_id_uuid_list_entry { - __u8 header; - __u8 rsvd1[15]; - __u8 uuid[16]; - }; +``NVME_NS_FEAT_DULBE`` + If set, indicates that the controller supports the + 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. -**Members** +``NVME_NS_FEAT_ID_REUSE`` + *undescribed* +``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 -.. c:type:: enum +.. c:type:: enum nvme_id_ns_flbas + This field indicates the LBA data size & metadata size combination that the namespace has been formatted with **Constants** -``NVME_ID_UUID_HDR_ASSOCIATION_MASK`` - *undescribed* +``NVME_NS_FLBAS_LBA_MASK`` + Mask to get the index of one of the 16 supported + LBA Formats indicated in :c:type:`struct nvme_id_ns `.lbaf. -``NVME_ID_UUID_ASSOCIATION_NONE`` - *undescribed* +``NVME_NS_FLBAS_META_EXT`` + Applicable only if format contains metadata. If + this bit is set, indicates that the metadata is + transferred at the end of the data LBA, creating an + extended data LBA. If cleared, indicates that all + of the metadata for a command is transferred as a + separate contiguous buffer of data. -``NVME_ID_UUID_ASSOCIATION_VENDOR`` - *undescribed* -``NVME_ID_UUID_ASSOCIATION_SUBSYSTEM_VENDOR`` - *undescribed* +.. c:type:: enum nvme_id_ns_mc + This field indicates the capabilities for metadata. -.. c:type:: struct nvme_id_uuid_list +**Constants** +``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. -**Definition** +``NVME_NS_MC_SEPARATE`` + If set, indicates that the namespace supports the + metadata being transferred as part of an extended data LBA. -:: - struct nvme_id_uuid_list { - __u8 rsvd0[32]; - struct nvme_id_uuid_list_entry entry[NVME_ID_UUID_LIST_MAX]; - }; -**Members** +.. c:type:: enum nvme_id_ns_dpc + This field indicates the capabilities for the end-to-end data protection feature. +**Constants** +``NVME_NS_DPC_PI_TYPE1`` + If set, indicates that the namespace supports + Protection Information Type 1. -.. c:type:: struct nvme_ctrl_list +``NVME_NS_DPC_PI_TYPE2`` + If set, indicates that the namespace supports + Protection Information Type 2. - **num**; +``NVME_NS_DPC_PI_TYPE3`` + If set, indicates that the namespace supports + Protection Information Type 3. -**Definition** +``NVME_NS_DPC_PI_FIRST`` + If set, indicates that the namespace supports + 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. - struct nvme_ctrl_list { - __le16 num; - __le16 identifier[NVME_ID_CTRL_LIST_MAX]; - }; -**Members** +.. c:type:: enum nvme_id_ns_dps + This field indicates the Type settings for the end-to-end data protection feature. +**Constants** -.. c:type:: struct nvme_ns_list +``NVME_NS_DPS_PI_NONE`` + Protection information is not enabled +``NVME_NS_DPS_PI_TYPE1`` + Protection information is enabled, Type 1 -**Definition** +``NVME_NS_DPS_PI_TYPE2`` + Protection information is enabled, Type 2 -:: +``NVME_NS_DPS_PI_TYPE3`` + Protection information is enabled, Type 3 - struct nvme_ns_list { - __le32 ns[NVME_ID_NS_LIST_MAX]; - }; +``NVME_NS_DPS_PI_MASK`` + Mask to get the value of the PI type -**Members** +``NVME_NS_DPS_PI_FIRST`` + If set, indicates that the protection information, if + enabled, is transferred as the first eight bytes of + metadata. +.. c:type:: enum nvme_id_ns_nmic -.. c:type:: struct nvme_primary_ctrl_cap + This field specifies multi-path I/O and namespace sharing capabilities of the namespace. +**Constants** -**Definition** +``NVME_NS_NMIC_SHARED`` + If set, then the namespace may be attached to two or + more controllers in the NVM subsystem concurrently -:: - struct nvme_primary_ctrl_cap { - __le16 cntlid; - __le16 portid; - __u8 crt; - __u8 rsvd5[27]; - __le32 vqfrt; - __le32 vqrfa; - __le16 vqrfap; - __le16 vqprt; - __le16 vqfrsm; - __le16 vqgran; - __u8 rsvd48[16]; - __le32 vifrt; - __le32 virfa; - __le16 virfap; - __le16 viprt; - __le16 vifrsm; - __le16 vigran; - __u8 rsvd80[4016]; - }; -**Members** +.. c:type:: enum nvme_id_ns_rescap + This field indicates the reservation capabilities of the namespace. +**Constants** +``NVME_NS_RESCAP_PTPL`` + If set, indicates that the namespace supports the + Persist Through Power Loss capability. -.. c:type:: struct nvme_secondary_ctrl +``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. -**Definition** +``NVME_NS_RESCAP_WERO`` + If set, indicates that the namespace supports the + Write Exclusive - Registrants Only reservation type. -:: +``NVME_NS_RESCAP_EARO`` + If set, indicates that the namespace supports the + Exclusive Access - Registrants Only reservation type. - struct nvme_secondary_ctrl { - __le16 scid; - __le16 pcid; - __u8 scs; - __u8 rsvd5[3]; - __le16 vfn; - __le16 nvq; - __le16 nvi; - __u8 rsvd14[18]; - }; +``NVME_NS_RESCAP_WEAR`` + If set, indicates that the namespace supports the + Write Exclusive - All Registrants reservation type. -**Members** +``NVME_NS_RESCAP_EAAR`` + If set, indicates that the namespace supports the + 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. -.. c:type:: struct nvme_secondary_ctrl_list +.. c:type:: enum nvme_nd_ns_fpi - **num**; + If a format operation is in progress, this field indicates the percentage of the namespace that remains to be formatted. -**Definition** +**Constants** -:: +``NVME_NS_FPI_REMAINING`` + Mask to get the format percent remaining value - struct nvme_secondary_ctrl_list { - __u8 num; - __u8 rsvd[31]; - struct nvme_secondary_ctrl sc_entry[NVME_ID_SECONDARY_CTRL_MAX]; - }; +``NVME_NS_FPI_SUPPORTED`` + If set, indicates that the namespace supports the + Format Progress Indicator defined for the field. -**Members** +.. c:type:: enum nvme_id_ns_dlfeat + This field indicates information about features that affect deallocating logical blocks for this namespace. -.. c:type:: struct nvme_error_log_page +**Constants** +``NVME_NS_DLFEAT_RB`` + Mask to get the value of the read behavior -**Definition** +``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. - struct nvme_error_log_page { - __le64 error_count; - __le16 sqid; - __le16 cmdid; - __le16 status_field; - __le16 parm_error_location; - __le64 lba; - __le32 nsid; - __u8 vs; - __u8 trtype; - __u8 resv[2]; - __le64 cs; - __le16 trtype_spec_info; - __u8 resv2[22]; - }; +``NVME_NS_DLFEAT_RB_ALL_FS`` + A deallocated logical block returns all bytes + set to FFh. -**Members** +``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 -.. c:type:: enum +.. c:type:: enum nvme_id_ns_attr + Specifies attributes of the namespace. **Constants** -``NVME_ERR_PEL_BYTE_MASK`` - *undescribed* - -``NVME_ERR_PEL_BIT_MASK`` - *undescribed* +``NVME_NS_NSATTR_WRITE_PROTECTED`` + If set, then the namespace is currently + write protected and all write access to the + namespace shall fail. -.. c:type:: struct nvme_smart_log +.. c:type:: struct nvme_ns_id_desc **Definition** :: - struct nvme_smart_log { - __u8 critical_warning; - __u8 temperature[2]; - __u8 avail_spare; - __u8 spare_thresh; - __u8 percent_used; - __u8 endu_grp_crit_warn_sumry; - __u8 rsvd7[25]; - __u8 data_units_read[16]; - __u8 data_units_written[16]; - __u8 host_reads[16]; - __u8 host_writes[16]; - __u8 ctrl_busy_time[16]; - __u8 power_cycles[16]; - __u8 power_on_hours[16]; - __u8 unsafe_shutdowns[16]; - __u8 media_errors[16]; - __u8 num_err_log_entries[16]; - __le32 warning_temp_time; - __le32 critical_comp_time; - __le16 temp_sensor[8]; - __le32 thm_temp1_trans_count; - __le32 thm_temp2_trans_count; - __le32 thm_temp1_total_time; - __le32 thm_temp2_total_time; - __u8 rsvd232[280]; + struct nvme_ns_id_desc { + __u8 nidt; + __u8 nidl; + __le16 reserved; + __u8 nid[]; }; **Members** +``nidt`` + Namespace Identifier Type, see :c:type:`enum nvme_ns_id_desc_nidt ` +``nidl`` + Namespace Identifier Length contains the length in bytes of the + :c:type:`struct nvme_id_ns `.nid. +``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 :c:type:`struct nvme_id_ns `.nidl. -.. c:type:: enum - - -**Constants** - -``NVME_SMART_CRIT_SPARE`` - *undescribed* - -``NVME_SMART_CRIT_TEMPERATURE`` - *undescribed* - -``NVME_SMART_CRIT_DEGRADED`` - *undescribed* - -``NVME_SMART_CRIT_MEDIA`` - *undescribed* - -``NVME_SMART_CRIT_VOLATILE_MEMORY`` - *undescribed* - -``NVME_SMART_CRIT_PMR_RO`` - *undescribed* - -.. c:type:: enum +.. c:type:: enum nvme_ns_id_desc_nidt + Known namespace identifier types **Constants** -``NVME_SMART_EGCW_SPARE`` - *undescribed* +``NVME_NIDT_EUI64`` + IEEE Extended Unique Identifier, the NID field contains a + copy of the EUI64 field in the struct nvme_id_ns.eui64. -``NVME_SMART_EGCW_DEGRADED`` - *undescribed* +``NVME_NIDT_NGUID`` + Namespace Globally Unique Identifier, the NID field + contains a copy of the NGUID field in struct nvme_id_ns.nguid. -``NVME_SMART_EGCW_RO`` - *undescribed* +``NVME_NIDT_UUID`` + The NID field contains a 128-bit Universally Unique + Identifier (UUID) as specified in RFC 4122. -.. c:type:: struct nvme_frs +.. c:type:: struct nvme_nvmset_attr + NVM Set Attributes Entry **Definition** :: - struct nvme_frs { - char frs[8]; + struct nvme_nvmset_attr { + __le16 id; + __le16 endurance_group_id; + __u8 rsvd4[4]; + __le32 random_4k_read_typical; + __le32 opt_write_size; + __u8 total_nvmset_cap[16]; + __u8 unalloc_nvmset_cap[16]; + __u8 rsvd48[80]; }; **Members** +``id`` + NVM Set Identifier + +``endurance_group_id`` + Endurance Group Identifier + +``random_4k_read_typical`` + Random 4 KiB Read Typical indicates the typical + time to complete a 4 KiB random read in 100 + nanosecond units when the NVM Set is in a + Predictable Latency Mode Deterministic Window and + there is 1 outstanding command per NVM Set. -.. c:type:: struct nvme_firmware_slot +.. c:type:: struct nvme_id_nvmset_list + + **nid**; **Definition** :: - struct nvme_firmware_slot { - __u8 afi; - __u8 resv[7]; - struct nvme_frs frs[7]; - __u8 resv2[448]; + struct nvme_id_nvmset_list { + __u8 nid; + __u8 rsvd1[127]; + struct nvme_nvmset_attr ent[NVME_ID_NVMSET_LIST_MAX]; }; **Members** +``ent`` + ; + -.. c:type:: struct nvme_cmd_effects_log +.. c:type:: struct nvme_id_ns_granularity_desc **Definition** :: - struct nvme_cmd_effects_log { - __le32 acs[256]; - __le32 iocs[256]; - __u8 resv[2048]; + struct nvme_id_ns_granularity_desc { + __le64 namespace_size_granularity; + __le64 namespace_capacity_granularity; }; **Members** @@ -8573,53 +8598,38 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: enum - - -**Constants** - -``NVME_CMD_EFFECTS_CSUPP`` - *undescribed* +.. c:type:: struct nvme_id_ns_granularity_list -``NVME_CMD_EFFECTS_LBCC`` - *undescribed* -``NVME_CMD_EFFECTS_NCC`` - *undescribed* +**Definition** -``NVME_CMD_EFFECTS_NIC`` - *undescribed* +:: -``NVME_CMD_EFFECTS_CCC`` - *undescribed* + struct nvme_id_ns_granularity_list { + __le32 attributes; + __u8 num_descriptors; + __u8 rsvd[27]; + struct nvme_id_ns_granularity_desc entry[NVME_ID_ND_DESCRIPTOR_MAX]; + __u8 rsvd288[3808]; + }; -``NVME_CMD_EFFECTS_CSE_MASK`` - *undescribed* +**Members** -``NVME_CMD_EFFECTS_UUID_SEL`` - *undescribed* -.. c:type:: struct nvme_st_result +.. c:type:: struct nvme_id_uuid_list_entry **Definition** :: - struct nvme_st_result { - __u8 dsts; - __u8 seg; - __u8 vdi; - __u8 rsvd; - __le64 poh; - __le32 nsid; - __le64 flba; - __u8 sct; - __u8 sc; - __u8 vs[2]; + struct nvme_id_uuid_list_entry { + __u8 header; + __u8 rsvd1[15]; + __u8 uuid[16]; }; **Members** @@ -8633,94 +8643,101 @@ Returns true if given offset is 64bit register, otherwise it returns false. **Constants** -``NVME_ST_RESULT_NO_ERR`` +``NVME_ID_UUID_HDR_ASSOCIATION_MASK`` *undescribed* -``NVME_ST_RESULT_ABORTED`` +``NVME_ID_UUID_ASSOCIATION_NONE`` *undescribed* -``NVME_ST_RESULT_CLR`` +``NVME_ID_UUID_ASSOCIATION_VENDOR`` *undescribed* -``NVME_ST_RESULT_NS_REMOVED`` +``NVME_ID_UUID_ASSOCIATION_SUBSYSTEM_VENDOR`` *undescribed* -``NVME_ST_RESULT_ABORTED_FORMAT`` - *undescribed* -``NVME_ST_RESULT_FATAL_ERR`` - *undescribed* -``NVME_ST_RESULT_UNKNOWN_SEG_FAIL`` - *undescribed* -``NVME_ST_RESULT_KNOWN_SEG_FAIL`` - *undescribed* +.. c:type:: struct nvme_id_uuid_list -``NVME_ST_RESULT_ABORTED_UNKNOWN`` - *undescribed* -``NVME_ST_RESULT_ABORTED_SANITIZE`` - *undescribed* +**Definition** -``NVME_ST_RESULT_NOT_USED`` - *undescribed* +:: + struct nvme_id_uuid_list { + __u8 rsvd0[32]; + struct nvme_id_uuid_list_entry entry[NVME_ID_UUID_LIST_MAX]; + }; +**Members** -.. c:type:: enum -**Constants** -``NVME_ST_OPERATION_NONE`` - *undescribed* +.. c:type:: struct nvme_ctrl_list -``NVME_ST_OPERATION_SHORT`` - *undescribed* + **num**; -``NVME_ST_OPERATION_EXTENDED`` - *undescribed* +**Definition** -``NVME_ST_OPERATION_VS`` - *undescribed* +:: + + struct nvme_ctrl_list { + __le16 num; + __le16 identifier[NVME_ID_CTRL_LIST_MAX]; + }; +**Members** -.. c:type:: enum -**Constants** +.. c:type:: struct nvme_ns_list -``NVME_ST_VALID_DIAG_INFO_NSID`` - *undescribed* -``NVME_ST_VALID_DIAG_INFO_FLBA`` - *undescribed* +**Definition** -``NVME_ST_VALID_DIAG_INFO_SCT`` - *undescribed* +:: -``NVME_ST_VALID_DIAG_INFO_SC`` - *undescribed* + struct nvme_ns_list { + __le32 ns[NVME_ID_NS_LIST_MAX]; + }; + +**Members** -.. c:type:: struct nvme_self_test_log + +.. c:type:: struct nvme_primary_ctrl_cap **Definition** :: - struct nvme_self_test_log { - __u8 current_operation; - __u8 completion; - __u8 rsvd[2]; - struct nvme_st_result result[NVME_LOG_ST_MAX_RESULTS]; + struct nvme_primary_ctrl_cap { + __le16 cntlid; + __le16 portid; + __u8 crt; + __u8 rsvd5[27]; + __le32 vqfrt; + __le32 vqrfa; + __le16 vqrfap; + __le16 vqprt; + __le16 vqfrsm; + __le16 vqgran; + __u8 rsvd48[16]; + __le32 vifrt; + __le32 virfa; + __le16 virfap; + __le16 viprt; + __le16 vifrsm; + __le16 vigran; + __u8 rsvd80[4016]; }; **Members** @@ -8729,25 +8746,22 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: struct nvme_telemetry_log +.. c:type:: struct nvme_secondary_ctrl **Definition** :: - struct nvme_telemetry_log { - __u8 lpi; - __u8 rsvd[4]; - __u8 ieee[3]; - __le16 dalb1; - __le16 dalb2; - __le16 dalb3; - __u8 rsvd1[368]; - __u8 ctrlavail; - __u8 ctrldgn; - __u8 rsnident[128]; - __u8 telemetry_dataarea[]; + struct nvme_secondary_ctrl { + __le16 scid; + __le16 pcid; + __u8 scs; + __u8 rsvd5[3]; + __le16 vfn; + __le16 nvq; + __le16 nvi; + __u8 rsvd14[18]; }; **Members** @@ -8756,29 +8770,18 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: struct nvme_endurance_group_log +.. c:type:: struct nvme_secondary_ctrl_list + **num**; **Definition** :: - struct nvme_endurance_group_log { - __u8 critical_warning; - __u8 rsvd1[2]; - __u8 avl_spare; - __u8 avl_spare_threshold; - __u8 percent_used; - __u8 rsvd6[26]; - __u8 endurance_estimate[16]; - __u8 data_units_read[16]; - __u8 data_units_written[16]; - __u8 media_units_written[16]; - __u8 host_read_cmds[16]; - __u8 host_write_cmds[16]; - __u8 media_data_integrity_err[16]; - __u8 num_err_info_log_entries[16]; - __u8 rsvd160[352]; + struct nvme_secondary_ctrl_list { + __u8 num; + __u8 rsvd[31]; + struct nvme_secondary_ctrl sc_entry[NVME_ID_SECONDARY_CTRL_MAX]; }; **Members** @@ -8787,63 +8790,82 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: enum nvme_eg_critical_warning_flags - +.. c:type:: struct nvme_error_log_page -**Constants** -``NVME_EG_CRITICAL_WARNING_SPARE`` - *undescribed* +**Definition** -``NVME_EG_CRITICAL_WARNING_DEGRADED`` - *undescribed* +:: -``NVME_EG_CRITICAL_WARNING_READ_ONLY`` - *undescribed* + struct nvme_error_log_page { + __le64 error_count; + __le16 sqid; + __le16 cmdid; + __le16 status_field; + __le16 parm_error_location; + __le64 lba; + __le32 nsid; + __u8 vs; + __u8 trtype; + __u8 rsvd[2]; + __le64 cs; + __le16 trtype_spec_info; + __u8 rsvd2[22]; + }; +**Members** -.. c:type:: struct nvme_aggregate_endurance_group_event -**Definition** +.. c:type:: enum -:: - struct nvme_aggregate_endurance_group_event { - __le64 num_entries; - __le16 entries[]; - }; +**Constants** -**Members** +``NVME_ERR_PEL_BYTE_MASK`` + *undescribed* +``NVME_ERR_PEL_BIT_MASK`` + *undescribed* -.. c:type:: struct nvme_nvmset_predictable_lat_log +.. c:type:: struct nvme_smart_log **Definition** :: - struct nvme_nvmset_predictable_lat_log { - __u8 status; - __u8 rsvd1; - __le16 event_type; - __u8 rsvd4[28]; - __le64 dtwin_rt; - __le64 dtwin_wt; - __le64 dtwin_tmax; - __le64 dtwin_tmin_hi; - __le64 dtwin_tmin_lo; - __u8 rsvd72[56]; - __le64 dtwin_re; - __le64 dtwin_we; - __le64 dtwin_te; - __u8 rsvd152[360]; + struct nvme_smart_log { + __u8 critical_warning; + __u8 temperature[2]; + __u8 avail_spare; + __u8 spare_thresh; + __u8 percent_used; + __u8 endu_grp_crit_warn_sumry; + __u8 rsvd7[25]; + __u8 data_units_read[16]; + __u8 data_units_written[16]; + __u8 host_reads[16]; + __u8 host_writes[16]; + __u8 ctrl_busy_time[16]; + __u8 power_cycles[16]; + __u8 power_on_hours[16]; + __u8 unsafe_shutdowns[16]; + __u8 media_errors[16]; + __u8 num_err_log_entries[16]; + __le32 warning_temp_time; + __le32 critical_comp_time; + __le16 temp_sensor[8]; + __le32 thm_temp1_trans_count; + __le32 thm_temp2_trans_count; + __le32 thm_temp1_total_time; + __le32 thm_temp2_total_time; + __u8 rsvd232[280]; }; **Members** @@ -8857,13 +8879,22 @@ Returns true if given offset is 64bit register, otherwise it returns false. **Constants** -``NVME_NVMSET_PL_STATUS_DISABLED`` +``NVME_SMART_CRIT_SPARE`` *undescribed* -``NVME_NVMSET_PL_STATUS_DTWIN`` +``NVME_SMART_CRIT_TEMPERATURE`` *undescribed* -``NVME_NVMSET_PL_STATUS_NDWIN`` +``NVME_SMART_CRIT_DEGRADED`` + *undescribed* + +``NVME_SMART_CRIT_MEDIA`` + *undescribed* + +``NVME_SMART_CRIT_VOLATILE_MEMORY`` + *undescribed* + +``NVME_SMART_CRIT_PMR_RO`` *undescribed* @@ -8874,34 +8905,47 @@ Returns true if given offset is 64bit register, otherwise it returns false. **Constants** -``NVME_NVMSET_PL_EVENT_DTWIN_READ_WARN`` +``NVME_SMART_EGCW_SPARE`` *undescribed* -``NVME_NVMSET_PL_EVENT_DTWIN_WRITE_WARN`` +``NVME_SMART_EGCW_DEGRADED`` *undescribed* -``NVME_NVMSET_PL_EVENT_DTWIN_TIME_WARN`` - *undescribed* +``NVME_SMART_EGCW_RO`` + *undescribed* + + + + +.. c:type:: struct nvme_frs + + +**Definition** + +:: + + struct nvme_frs { + char frs[8]; + }; -``NVME_NVMSET_PL_EVENT_DTWIN_EXCEEDED`` - *undescribed* +**Members** -``NVME_NVMSET_PL_EVENT_DTWIN_EXCURSION`` - *undescribed* -.. c:type:: struct nvme_aggregate_predictable_lat_event +.. c:type:: struct nvme_firmware_slot **Definition** :: - struct nvme_aggregate_predictable_lat_event { - __le64 num_entries; - __le16 entries[]; + struct nvme_firmware_slot { + __u8 afi; + __u8 rsvd[7]; + struct nvme_frs frs[7]; + __u8 rsvd2[448]; }; **Members** @@ -8910,20 +8954,17 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: struct nvme_ana_group_desc +.. c:type:: struct nvme_cmd_effects_log **Definition** :: - struct nvme_ana_group_desc { - __le32 grpid; - __le32 nnsids; - __le64 chgcnt; - __u8 state; - __u8 rsvd17[15]; - __le32 nsids[]; + struct nvme_cmd_effects_log { + __le32 acs[256]; + __le32 iocs[256]; + __u8 rsvd[2048]; }; **Members** @@ -8937,68 +8978,48 @@ Returns true if given offset is 64bit register, otherwise it returns false. **Constants** -``NVME_ANA_STATE_OPTIMIZED`` +``NVME_CMD_EFFECTS_CSUPP`` *undescribed* -``NVME_ANA_STATE_NONOPTIMIZED`` +``NVME_CMD_EFFECTS_LBCC`` *undescribed* -``NVME_ANA_STATE_INACCESSIBLE`` +``NVME_CMD_EFFECTS_NCC`` *undescribed* -``NVME_ANA_STATE_PERSISTENT_LOSS`` +``NVME_CMD_EFFECTS_NIC`` *undescribed* -``NVME_ANA_STATE_CHANGE`` +``NVME_CMD_EFFECTS_CCC`` *undescribed* +``NVME_CMD_EFFECTS_CSE_MASK`` + *undescribed* - - -.. c:type:: struct nvme_ana_log - - -**Definition** - -:: - - struct nvme_ana_log { - __le64 chgcnt; - __le16 ngrps; - __u8 rsvd10[6]; - struct nvme_ana_group_desc descs[]; - }; - -**Members** - +``NVME_CMD_EFFECTS_UUID_SEL`` + *undescribed* -.. c:type:: struct nvme_persistent_event_log +.. c:type:: struct nvme_st_result **Definition** :: - struct nvme_persistent_event_log { - __u8 lid; - __u8 rsvd1[3]; - __le32 ttl; - __u8 rv; - __u8 rsvd17; - __le16 lht; - __le64 ts; - __u8 poh[16]; - __le64 pcc; - __le16 vid; - __le16 ssvid; - char sn[20]; - char mn[40]; - char subnqn[256]; - __u8 rsvd372; - __u8 seb[32]; + struct nvme_st_result { + __u8 dsts; + __u8 seg; + __u8 vdi; + __u8 rsvd; + __le64 poh; + __le32 nsid; + __le64 flba; + __u8 sct; + __u8 sc; + __u8 vs[2]; }; **Members** @@ -9007,92 +9028,99 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: struct nvme_lba_rd - +.. c:type:: enum -**Definition** -:: +**Constants** - struct nvme_lba_rd { - __le64 rslba; - __le32 rnlb; - __u8 rsvd12[4]; - }; +``NVME_ST_RESULT_NO_ERR`` + *undescribed* -**Members** +``NVME_ST_RESULT_ABORTED`` + *undescribed* +``NVME_ST_RESULT_CLR`` + *undescribed* +``NVME_ST_RESULT_NS_REMOVED`` + *undescribed* +``NVME_ST_RESULT_ABORTED_FORMAT`` + *undescribed* +``NVME_ST_RESULT_FATAL_ERR`` + *undescribed* -.. c:type:: struct nvme_lbas_ns_element +``NVME_ST_RESULT_UNKNOWN_SEG_FAIL`` + *undescribed* +``NVME_ST_RESULT_KNOWN_SEG_FAIL`` + *undescribed* -**Definition** +``NVME_ST_RESULT_ABORTED_UNKNOWN`` + *undescribed* -:: +``NVME_ST_RESULT_ABORTED_SANITIZE`` + *undescribed* - struct nvme_lbas_ns_element { - __le32 neid; - __le32 nrld; - __u8 ratype; - __u8 rsvd8[7]; - struct nvme_lba_rd lba_rd[]; - }; +``NVME_ST_RESULT_NOT_USED`` + *undescribed* -**Members** +.. c:type:: enum -.. c:type:: enum nvme_lba_status_atype +**Constants** +``NVME_ST_OPERATION_NONE`` + *undescribed* -**Constants** +``NVME_ST_OPERATION_SHORT`` + *undescribed* -``NVME_LBA_STATUS_ATYPE_SCAN_UNTRACKED`` +``NVME_ST_OPERATION_EXTENDED`` *undescribed* -``NVME_LBA_STATUS_ATYPE_SCAN_TRACKED`` +``NVME_ST_OPERATION_VS`` *undescribed* -.. c:type:: struct nvme_lba_status_log +.. c:type:: enum -**Definition** +**Constants** -:: +``NVME_ST_VALID_DIAG_INFO_NSID`` + *undescribed* - struct nvme_lba_status_log { - __le32 lslplen; - __le32 nlslne; - __le32 estulb; - __u8 rsvd12[2]; - __le16 lsgc; - struct nvme_lbas_ns_element elements[]; - }; +``NVME_ST_VALID_DIAG_INFO_FLBA`` + *undescribed* -**Members** +``NVME_ST_VALID_DIAG_INFO_SCT`` + *undescribed* +``NVME_ST_VALID_DIAG_INFO_SC`` + *undescribed* -.. c:type:: struct nvme_eg_event_aggregate_log +.. c:type:: struct nvme_self_test_log **Definition** :: - struct nvme_eg_event_aggregate_log { - __le64 nr_entries; - __le16 egids[]; + struct nvme_self_test_log { + __u8 current_operation; + __u8 completion; + __u8 rsvd[2]; + struct nvme_st_result result[NVME_LOG_ST_MAX_RESULTS]; }; **Members** @@ -9101,66 +9129,100 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: struct nvme_resv_notification_log +.. c:type:: struct nvme_telemetry_log + Retrieve internal data specific to the manufacturer. **Definition** :: - struct nvme_resv_notification_log { - __le64 lpc; - __u8 rnlpt; - __u8 nalp; - __u8 rsvd9[2]; - __le32 nsid; - __u8 rsvd16[48]; + struct nvme_telemetry_log { + __u8 lpi; + __u8 rsvd[4]; + __u8 ieee[3]; + __le16 dalb1; + __le16 dalb2; + __le16 dalb3; + __u8 rsvd1[368]; + __u8 ctrlavail; + __u8 ctrldgn; + __u8 rsnident[128]; + __u8 data_area[]; }; **Members** +``lpi`` + Log Identifier, either #NVME_LOG_LID_TELEMETRY_HOST or + #NVME_LOG_LID_TELEMETRY_CTRL +``ieee`` + IEEE OUI Identifier is the Organization Unique Identifier (OUI) + 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. +``dalb3`` + Telemetry Controller-Initiated Data Area 1 Last Block is + the value of the last block in this area. -.. c:type:: enum +``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. +``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 . -**Constants** +``rsnident`` + Reason Identifieris a vendor specific identifier that describes + the operating conditions of the controller at the time of + capture. -``NVME_RESV_NOTIFY_RNLPT_EMPTY`` - *undescribed* +``data_area`` + Telemetry data blocks, vendor specific information data. -``NVME_RESV_NOTIFY_RNLPT_REGISTRATION_PREEMPTED`` - *undescribed* -``NVME_RESV_NOTIFY_RNLPT_RESERVATION_RELEASED`` - *undescribed* +**Description** -``NVME_RESV_NOTIFY_RNLPT_RESERVATION_PREEMPTED`` - *undescribed* +This log consists of a header describing the log and zero or more Telemetry +Data Blocks. All Telemetry Data Blocks are ``NVME_LOG_TELEM_BLOCK_SIZE``, 512 +bytes, in size. This log captures the controller’s internal state. -.. c:type:: struct nvme_sanitize_log_page +.. c:type:: struct nvme_endurance_group_log **Definition** :: - struct nvme_sanitize_log_page { - __le16 sprog; - __le16 sstat; - __le32 scdw10; - __le32 eto; - __le32 etbe; - __le32 etce; - __le32 etond; - __le32 etbend; - __le32 etcend; - __u8 rsvd32[480]; + struct nvme_endurance_group_log { + __u8 critical_warning; + __u8 rsvd1[2]; + __u8 avl_spare; + __u8 avl_spare_threshold; + __u8 percent_used; + __u8 rsvd6[26]; + __u8 endurance_estimate[16]; + __u8 data_units_read[16]; + __u8 data_units_written[16]; + __u8 media_units_written[16]; + __u8 host_read_cmds[16]; + __u8 host_write_cmds[16]; + __u8 media_data_integrity_err[16]; + __u8 num_err_info_log_entries[16]; + __u8 rsvd160[352]; }; **Members** @@ -9169,42 +9231,33 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: enum +.. c:type:: enum nvme_eg_critical_warning_flags **Constants** -``NVME_SANITIZE_SSTAT_NEVER_SANITIZED`` - *undescribed* - -``NVME_SANITIZE_SSTAT_COMPLETE_SUCCESS`` - *undescribed* - -``NVME_SANITIZE_SSTAT_IN_PROGESS`` +``NVME_EG_CRITICAL_WARNING_SPARE`` *undescribed* -``NVME_SANITIZE_SSTAT_COMPLETED_FAILED`` +``NVME_EG_CRITICAL_WARNING_DEGRADED`` *undescribed* -``NVME_SANITIZE_SSTAT_ND_COMPLETE_SUCCESS`` +``NVME_EG_CRITICAL_WARNING_READ_ONLY`` *undescribed* -.. c:type:: struct nvme_lba_status_desc +.. c:type:: struct nvme_aggregate_endurance_group_event **Definition** :: - struct nvme_lba_status_desc { - __le64 dslba; - __le32 nlb; - __u8 rsvd12; - __u8 status; - __u8 rsvd14[2]; + struct nvme_aggregate_endurance_group_event { + __le64 num_entries; + __le16 entries[]; }; **Members** @@ -9213,18 +9266,28 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: struct nvme_lba_status +.. c:type:: struct nvme_nvmset_predictable_lat_log **Definition** :: - struct nvme_lba_status { - __le32 nlsd; - __u8 cmpc; - __u8 rsvd5[3]; - struct nvme_lba_status_desc descs[]; + struct nvme_nvmset_predictable_lat_log { + __u8 status; + __u8 rsvd1; + __le16 event_type; + __u8 rsvd4[28]; + __le64 dtwin_rt; + __le64 dtwin_wt; + __le64 dtwin_tmax; + __le64 dtwin_tmin_hi; + __le64 dtwin_tmin_lo; + __u8 rsvd72[56]; + __le64 dtwin_re; + __le64 dtwin_we; + __le64 dtwin_te; + __u8 rsvd152[360]; }; **Members** @@ -9233,35 +9296,56 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: struct nvme_feat_auto_pst +.. c:type:: enum -**Definition** +**Constants** -:: +``NVME_NVMSET_PL_STATUS_DISABLED`` + *undescribed* - struct nvme_feat_auto_pst { - __le64 apst_entry[32]; - }; +``NVME_NVMSET_PL_STATUS_DTWIN`` + *undescribed* -**Members** +``NVME_NVMSET_PL_STATUS_NDWIN`` + *undescribed* +.. c:type:: enum -.. c:type:: struct nvme_timestamp - timestamp: +**Constants** + +``NVME_NVMSET_PL_EVENT_DTWIN_READ_WARN`` + *undescribed* + +``NVME_NVMSET_PL_EVENT_DTWIN_WRITE_WARN`` + *undescribed* + +``NVME_NVMSET_PL_EVENT_DTWIN_TIME_WARN`` + *undescribed* + +``NVME_NVMSET_PL_EVENT_DTWIN_EXCEEDED`` + *undescribed* + +``NVME_NVMSET_PL_EVENT_DTWIN_EXCURSION`` + *undescribed* + + + + +.. c:type:: struct nvme_aggregate_predictable_lat_event + **Definition** :: - struct nvme_timestamp { - __u8 timestamp[6]; - __u8 attr; - __u8 rsvd; + struct nvme_aggregate_predictable_lat_event { + __le64 num_entries; + __le16 entries[]; }; **Members** @@ -9270,21 +9354,20 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: struct nvme_lba_range_type_entry +.. c:type:: struct nvme_ana_group_desc **Definition** :: - struct nvme_lba_range_type_entry { - __u8 type; - __u8 attributes; - __u8 rsvd2[14]; - __u64 slba; - __u64 nlb; - __u8 guid[16]; - __u8 rsvd48[16]; + struct nvme_ana_group_desc { + __le32 grpid; + __le32 nnsids; + __le64 chgcnt; + __u8 state; + __u8 rsvd17[15]; + __le32 nsids[]; }; **Members** @@ -9298,39 +9381,68 @@ Returns true if given offset is 64bit register, otherwise it returns false. **Constants** -``NVME_LBART_TYPE_GP`` +``NVME_ANA_STATE_OPTIMIZED`` *undescribed* -``NVME_LBART_TYPE_FS`` +``NVME_ANA_STATE_NONOPTIMIZED`` *undescribed* -``NVME_LBART_TYPE_RAID`` +``NVME_ANA_STATE_INACCESSIBLE`` *undescribed* -``NVME_LBART_TYPE_CACHE`` +``NVME_ANA_STATE_PERSISTENT_LOSS`` *undescribed* -``NVME_LBART_TYPE_SWAP`` +``NVME_ANA_STATE_CHANGE`` *undescribed* -``NVME_LBART_ATTRIB_TEMP`` - *undescribed* -``NVME_LBART_ATTRIB_HIDE`` - *undescribed* +.. c:type:: struct nvme_ana_log + + +**Definition** + +:: + + struct nvme_ana_log { + __le64 chgcnt; + __le16 ngrps; + __u8 rsvd10[6]; + struct nvme_ana_group_desc descs[]; + }; + +**Members** + -.. c:type:: struct nvme_lba_range_type + + +.. c:type:: struct nvme_persistent_event_log **Definition** :: - struct nvme_lba_range_type { - struct nvme_lba_range_type_entry entry[NVME_FEAT_LBA_RANGE_MAX]; + struct nvme_persistent_event_log { + __u8 lid; + __u8 rsvd1[3]; + __le32 ttl; + __u8 rv; + __u8 rsvd17; + __le16 lht; + __le64 ts; + __u8 poh[16]; + __le64 pcc; + __le16 vid; + __le16 ssvid; + char sn[20]; + char mn[40]; + char subnqn[NVME_NQN_LENGTH]; + __u8 rsvd372; + __u8 seb[32]; }; **Members** @@ -9339,21 +9451,17 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: struct nvme_plm_config +.. c:type:: struct nvme_lba_rd - **ee**; **dtwinrt**; **dtwinwt**; **dtwintt**; **Definition** :: - struct nvme_plm_config { - __le16 ee; - __u8 rsvd2[30]; - __le64 dtwinrt; - __le64 dtwinwt; - __le64 dtwintt; - __u8 rsvd56[456]; + struct nvme_lba_rd { + __le64 rslba; + __le32 rnlb; + __u8 rsvd12[4]; }; **Members** @@ -9362,16 +9470,19 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: struct nvme_feat_host_behavior +.. c:type:: struct nvme_lbas_ns_element **Definition** :: - struct nvme_feat_host_behavior { - __u8 acre; - __u8 resv1[511]; + struct nvme_lbas_ns_element { + __le32 neid; + __le32 nrld; + __u8 ratype; + __u8 rsvd8[7]; + struct nvme_lba_rd lba_rd[]; }; **Members** @@ -9380,28 +9491,34 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: enum +.. c:type:: enum nvme_lba_status_atype **Constants** -``NVME_ENABLE_ACRE`` +``NVME_LBA_STATUS_ATYPE_SCAN_UNTRACKED`` *undescribed* +``NVME_LBA_STATUS_ATYPE_SCAN_TRACKED`` + *undescribed* -.. c:type:: struct nvme_dsm_range + +.. c:type:: struct nvme_lba_status_log **Definition** :: - struct nvme_dsm_range { - __le32 cattr; - __le32 nlb; - __le64 slba; + struct nvme_lba_status_log { + __le32 lslplen; + __le32 nlslne; + __le32 estulb; + __u8 rsvd12[2]; + __le16 lsgc; + struct nvme_lbas_ns_element elements[]; }; **Members** @@ -9410,19 +9527,16 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: struct nvme_registered_ctrl +.. c:type:: struct nvme_eg_event_aggregate_log **Definition** :: - struct nvme_registered_ctrl { - __le16 cntlid; - __u8 rcsts; - __u8 rsvd3[5]; - __le64 hostid; - __le64 rkey; + struct nvme_eg_event_aggregate_log { + __le64 nr_entries; + __le16 egids[]; }; **Members** @@ -9431,20 +9545,20 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: struct nvme_registered_ctrl_ext +.. c:type:: struct nvme_resv_notification_log **Definition** :: - struct nvme_registered_ctrl_ext { - __le16 cntlid; - __u8 rcsts; - __u8 resv3[5]; - __le64 rkey; - __u8 hostid[16]; - __u8 resv32[32]; + struct nvme_resv_notification_log { + __le64 lpc; + __u8 rnlpt; + __u8 nalp; + __u8 rsvd9[2]; + __le32 nsid; + __u8 rsvd16[48]; }; **Members** @@ -9453,78 +9567,88 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: struct nvme_reservation_status +.. c:type:: enum - { -**Definition** +**Constants** -:: +``NVME_RESV_NOTIFY_RNLPT_EMPTY`` + *undescribed* - struct nvme_reservation_status { - __le32 gen; - __u8 rtype; - __u8 regctl[2]; - __u8 rsvd7[2]; - __u8 ptpls; - __u8 rsvd10[14]; - union { - struct { - __u8 resv24[40]; - struct nvme_registered_ctrl_ext regctl_eds[0]; - }; - struct nvme_registered_ctrl regctl_ds[0]; - }; +``NVME_RESV_NOTIFY_RNLPT_REGISTRATION_PREEMPTED`` + *undescribed* + +``NVME_RESV_NOTIFY_RNLPT_RESERVATION_RELEASED`` + *undescribed* + +``NVME_RESV_NOTIFY_RNLPT_RESERVATION_PREEMPTED`` + *undescribed* + + + + +.. c:type:: struct nvme_sanitize_log_page + + +**Definition** + +:: + + struct nvme_sanitize_log_page { + __le16 sprog; + __le16 sstat; + __le32 scdw10; + __le32 eto; + __le32 etbe; + __le32 etce; + __le32 etond; + __le32 etbend; + __le32 etcend; + __u8 rsvd32[480]; }; **Members** -``{unnamed_union}`` - anonymous - -``{unnamed_struct}`` - anonymous +.. c:type:: enum -.. c:type:: struct nvme_streams_directive_params +**Constants** -**Definition** +``NVME_SANITIZE_SSTAT_NEVER_SANITIZED`` + *undescribed* -:: +``NVME_SANITIZE_SSTAT_COMPLETE_SUCCESS`` + *undescribed* - struct nvme_streams_directive_params { - __le16 msl; - __le16 nssa; - __le16 nsso; - __u8 nssc; - __u8 rsvd[9]; - __le32 sws; - __le16 sgs; - __le16 nsa; - __le16 nso; - __u8 rsvd2[6]; - }; +``NVME_SANITIZE_SSTAT_IN_PROGESS`` + *undescribed* -**Members** +``NVME_SANITIZE_SSTAT_COMPLETED_FAILED`` + *undescribed* +``NVME_SANITIZE_SSTAT_ND_COMPLETE_SUCCESS`` + *undescribed* -.. c:type:: struct nvme_streams_directive_status +.. c:type:: struct nvme_lba_status_desc **Definition** :: - struct nvme_streams_directive_status { - __le16 osc; - __le16 sid[]; + struct nvme_lba_status_desc { + __le64 dslba; + __le32 nlb; + __u8 rsvd12; + __u8 status; + __u8 rsvd14[2]; }; **Members** @@ -9533,17 +9657,18 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: struct nvme_id_directives +.. c:type:: struct nvme_lba_status **Definition** :: - struct nvme_id_directives { - __u8 supported[32]; - __u8 enabled[32]; - __u8 rsvd64[4032]; + struct nvme_lba_status { + __le32 nlsd; + __u8 cmpc; + __u8 rsvd5[3]; + struct nvme_lba_status_desc descs[]; }; **Members** @@ -9552,31 +9677,35 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: enum +.. c:type:: struct nvme_feat_auto_pst -**Constants** +**Definition** -``NVME_ID_DIR_ID_BIT`` - *undescribed* +:: -``NVME_ID_DIR_SD_BIT`` - *undescribed* + struct nvme_feat_auto_pst { + __le64 apst_entry[32]; + }; +**Members** -.. c:type:: struct nvme_host_mem_buf_desc +.. c:type:: struct nvme_timestamp + + timestamp: + **Definition** :: - struct nvme_host_mem_buf_desc { - __le64 addr; - __le32 size; - __u32 rsvd; + struct nvme_timestamp { + __u8 timestamp[6]; + __u8 attr; + __u8 rsvd; }; **Members** @@ -9585,170 +9714,138 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: enum nvme_ae_type - +.. c:type:: struct nvme_lba_range_type_entry -**Constants** -``NVME_AER_ERROR`` - *undescribed* +**Definition** -``NVME_AER_SMART`` - *undescribed* +:: -``NVME_AER_NOTICE`` - *undescribed* + struct nvme_lba_range_type_entry { + __u8 type; + __u8 attributes; + __u8 rsvd2[14]; + __u64 slba; + __u64 nlb; + __u8 guid[16]; + __u8 rsvd48[16]; + }; -``NVME_AER_CSS`` - *undescribed* +**Members** -``NVME_AER_VS`` - *undescribed* -.. c:type:: enum nvme_ae_info_error +.. c:type:: enum **Constants** -``NVME_AER_ERROR_INVALID_DB_REG`` +``NVME_LBART_TYPE_GP`` *undescribed* -``NVME_AER_ERROR_INVALID_DB_VAL`` +``NVME_LBART_TYPE_FS`` *undescribed* -``NVME_AER_ERROR_DIAG_FAILURE`` +``NVME_LBART_TYPE_RAID`` *undescribed* -``NVME_AER_ERROR_PERSISTENT_INTERNAL_ERROR`` +``NVME_LBART_TYPE_CACHE`` *undescribed* -``NVME_AER_ERROR_TRANSIENT_INTERNAL_ERROR`` +``NVME_LBART_TYPE_SWAP`` *undescribed* -``NVME_AER_ERROR_FW_IMAGE_LOAD_ERROR`` +``NVME_LBART_ATTRIB_TEMP`` *undescribed* +``NVME_LBART_ATTRIB_HIDE`` + *undescribed* -.. c:type:: enum nvme_ae_info_smart - -**Constants** +.. c:type:: struct nvme_lba_range_type -``NVME_AER_SMART_SUBSYSTEM_RELIABILITY`` - *undescribed* -``NVME_AER_SMART_TEMPERATURE_THRESHOLD`` - *undescribed* +**Definition** -``NVME_AER_SMART_SPARE_THRESHOLD`` - *undescribed* +:: + struct nvme_lba_range_type { + struct nvme_lba_range_type_entry entry[NVME_FEAT_LBA_RANGE_MAX]; + }; +**Members** -.. c:type:: enum nvme_ae_info_css_nvm -**Constants** -``NVME_AER_CSS_NVM_RESERVATION`` - *undescribed* +.. c:type:: struct nvme_plm_config -``NVME_AER_CSS_NVM_SANITIZE_COMPLETED`` - *undescribed* + **ee**; **dtwinrt**; **dtwinwt**; **dtwintt**; -``NVME_AER_CSS_NVM_UNEXPECTED_SANITIZE_DEALLOC`` - *undescribed* +**Definition** +:: + struct nvme_plm_config { + __le16 ee; + __u8 rsvd2[30]; + __le64 dtwinrt; + __le64 dtwinwt; + __le64 dtwintt; + __u8 rsvd56[456]; + }; +**Members** -.. c:type:: enum nvme_ae_info_notice -**Constants** -``NVME_AER_NOTICE_NS_CHANGED`` - *undescribed* -``NVME_AER_NOTICE_FW_ACT_STARTING`` - *undescribed* +.. c:type:: struct nvme_feat_host_behavior -``NVME_AER_NOTICE_TELEMETRY`` - *undescribed* -``NVME_AER_NOTICE_ANA`` - *undescribed* +**Definition** -``NVME_AER_NOTICE_PL_EVENT`` - *undescribed* +:: -``NVME_AER_NOTICE_LBA_STATUS_ALERT`` - *undescribed* + struct nvme_feat_host_behavior { + __u8 acre; + __u8 rsvd1[511]; + }; -``NVME_AER_NOTICE_EG_EVENT`` - *undescribed* +**Members** -``NVME_AER_NOTICE_DISC_CHANGED`` - *undescribed* -.. c:type:: enum nvme_subsys_type +.. c:type:: enum **Constants** -``NVME_NQN_DISC`` - Discovery type target subsystem - -``NVME_NQN_NVME`` - NVME type target subsystem +``NVME_ENABLE_ACRE`` + *undescribed* -.. c:type:: struct nvmf_disc_log_entry +.. c:type:: struct nvme_dsm_range - Discovery log page entry **Definition** :: - struct nvmf_disc_log_entry { - __u8 trtype; - __u8 adrfam; - __u8 subtype; - __u8 treq; - __le16 portid; - __le16 cntlid; - __le16 asqsz; - __u8 resv10[22]; - char trsvcid[NVMF_TRSVCID_SIZE]; - __u8 resv64[192]; - char subnqn[NVMF_NQN_FIELD_LEN]; - char traddr[NVMF_TRADDR_SIZE]; - union tsas { - char common[NVMF_TSAS_SIZE]; - struct rdma { - __u8 qptype; - __u8 prtype; - __u8 cms; - __u8 resv3[5]; - __u16 pkey; - __u8 resv10[246]; - } rdma; - struct tcp { - __u8 sectype; - } tcp; - } tsas; + struct nvme_dsm_range { + __le32 cattr; + __le32 nlb; + __le64 slba; }; **Members** @@ -9757,125 +9854,144 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: enum +.. c:type:: struct nvme_registered_ctrl - Transport Type codes for Discovery Log Page entry TRTYPE field -**Constants** +**Definition** -``NVMF_TRTYPE_UNSPECIFIED`` - Not indicated +:: + + struct nvme_registered_ctrl { + __le16 cntlid; + __u8 rcsts; + __u8 rsvd3[5]; + __le64 hostid; + __le64 rkey; + }; + +**Members** -``NVMF_TRTYPE_RDMA`` - RDMA -``NVMF_TRTYPE_FC`` - Fibre Channel -``NVMF_TRTYPE_TCP`` - TCP -``NVMF_TRTYPE_LOOP`` - Reserved for host usage -``NVMF_TRTYPE_MAX`` - *undescribed* +.. c:type:: struct nvme_registered_ctrl_ext +**Definition** +:: -.. c:type:: enum + struct nvme_registered_ctrl_ext { + __le16 cntlid; + __u8 rcsts; + __u8 rsvd3[5]; + __le64 rkey; + __u8 hostid[16]; + __u8 rsvd32[32]; + }; - Address Family codes for Discovery Log Page entry ADRFAM field +**Members** -**Constants** -``NVMF_ADDR_FAMILY_PCI`` - PCIe -``NVMF_ADDR_FAMILY_IP4`` - IPv4 -``NVMF_ADDR_FAMILY_IP6`` - IPv6 -``NVMF_ADDR_FAMILY_IB`` - InfiniBand +.. c:type:: struct nvme_reservation_status -``NVMF_ADDR_FAMILY_FC`` - Fibre Channel + { +**Definition** +:: + struct nvme_reservation_status { + __le32 gen; + __u8 rtype; + __u8 regctl[2]; + __u8 rsvd7[2]; + __u8 ptpls; + __u8 rsvd10[14]; + union { + struct { + __u8 rsvd24[40]; + struct nvme_registered_ctrl_ext regctl_eds[0]; + }; + struct nvme_registered_ctrl regctl_ds[0]; + }; + }; -.. c:type:: enum +**Members** - Transport Requirements codes for Discovery Log Page entry TREQ field +``{unnamed_union}`` + anonymous -**Constants** +``{unnamed_struct}`` + anonymous -``NVMF_TREQ_NOT_SPECIFIED`` - Not specified -``NVMF_TREQ_REQUIRED`` - Required -``NVMF_TREQ_NOT_REQUIRED`` - Not Required -``NVMF_TREQ_DISABLE_SQFLOW`` - SQ flow control disable supported +.. c:type:: struct nvme_streams_directive_params +**Definition** -.. c:type:: enum +:: - RDMA QP Service Type codes for Discovery Log Page entry TSAS RDMA_QPTYPE field + struct nvme_streams_directive_params { + __le16 msl; + __le16 nssa; + __le16 nsso; + __u8 nssc; + __u8 rsvd[9]; + __le32 sws; + __le16 sgs; + __le16 nsa; + __le16 nso; + __u8 rsvd2[6]; + }; -**Constants** +**Members** -``NVMF_RDMA_QPTYPE_CONNECTED`` - Reliable Connected -``NVMF_RDMA_QPTYPE_DATAGRAM`` - Reliable Datagram +.. c:type:: struct nvme_streams_directive_status -.. c:type:: enum - RDMA Provider Type codes for Discovery Log Page entry TSAS RDMA_PRTYPE field +**Definition** -**Constants** +:: -``NVMF_RDMA_PRTYPE_NOT_SPECIFIED`` - No Provider Specified + struct nvme_streams_directive_status { + __le16 osc; + __le16 sid[]; + }; -``NVMF_RDMA_PRTYPE_IB`` - InfiniBand +**Members** -``NVMF_RDMA_PRTYPE_ROCE`` - InfiniBand RoCE -``NVMF_RDMA_PRTYPE_ROCEV2`` - InfiniBand RoCEV2 -``NVMF_RDMA_PRTYPE_IWARP`` - iWARP +.. c:type:: struct nvme_id_directives -.. c:type:: enum +**Definition** - RDMA Connection Management Service Type codes for Discovery Log Page entry TSAS RDMA_CMS field +:: -**Constants** + struct nvme_id_directives { + __u8 supported[32]; + __u8 enabled[32]; + __u8 rsvd64[4032]; + }; + +**Members** -``NVMF_RDMA_CMS_RDMA_CM`` - Sockets based endpoint addressing @@ -9885,28 +10001,26 @@ Returns true if given offset is 64bit register, otherwise it returns false. **Constants** -``NVMF_TCP_SECTYPE_NONE`` - No Security +``NVME_ID_DIR_ID_BIT`` + *undescribed* -``NVMF_TCP_SECTYPE_TLS`` - Transport Layer Security +``NVME_ID_DIR_SD_BIT`` + *undescribed* -.. c:type:: struct nvmf_discovery_log +.. c:type:: struct nvme_host_mem_buf_desc **Definition** :: - struct nvmf_discovery_log { - __le64 genctr; - __le64 numrec; - __le16 recfmt; - __u8 resv14[1006]; - struct nvmf_disc_log_entry entries[0]; + struct nvme_host_mem_buf_desc { + __le64 addr; + __le32 size; + __u32 rsvd; }; **Members** @@ -9915,164 +10029,170 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: struct nvmf_connect_data +.. c:type:: enum nvme_ae_type -**Definition** +**Constants** -:: +``NVME_AER_ERROR`` + *undescribed* - struct nvmf_connect_data { - __u8 hostid[16]; - __le16 cntlid; - char resv4[238]; - char subsysnqn[NVMF_NQN_FIELD_LEN]; - char hostnqn[NVMF_NQN_FIELD_LEN]; - char resv5[256]; - }; +``NVME_AER_SMART`` + *undescribed* -**Members** +``NVME_AER_NOTICE`` + *undescribed* -``cntlid`` - **subsysnqn** - **hostnqn** +``NVME_AER_CSS`` + *undescribed* +``NVME_AER_VS`` + *undescribed* -.. c:type:: struct nvme_mi_read_nvm_ss_info +.. c:type:: enum nvme_ae_info_error -**Definition** +**Constants** -:: +``NVME_AER_ERROR_INVALID_DB_REG`` + *undescribed* - struct nvme_mi_read_nvm_ss_info { - __u8 nump; - __u8 mjr; - __u8 mnr; - __u8 rsvd3[29]; - }; +``NVME_AER_ERROR_INVALID_DB_VAL`` + *undescribed* -**Members** +``NVME_AER_ERROR_DIAG_FAILURE`` + *undescribed* +``NVME_AER_ERROR_PERSISTENT_INTERNAL_ERROR`` + *undescribed* +``NVME_AER_ERROR_TRANSIENT_INTERNAL_ERROR`` + *undescribed* +``NVME_AER_ERROR_FW_IMAGE_LOAD_ERROR`` + *undescribed* -.. c:type:: struct nvme_mi_port_pcie -**Definition** +.. c:type:: enum nvme_ae_info_smart -:: - struct nvme_mi_port_pcie { - __u8 mps; - __u8 sls; - __u8 cls; - __u8 mlw; - __u8 nlw; - __u8 pn; - __u8 rsvd14[18]; - }; +**Constants** -**Members** +``NVME_AER_SMART_SUBSYSTEM_RELIABILITY`` + *undescribed* +``NVME_AER_SMART_TEMPERATURE_THRESHOLD`` + *undescribed* +``NVME_AER_SMART_SPARE_THRESHOLD`` + *undescribed* -.. c:type:: struct nvme_mi_port_smb +.. c:type:: enum nvme_ae_info_css_nvm -**Definition** -:: +**Constants** - struct nvme_mi_port_smb { - __u8 vpd_addr; - __u8 mvpd_freq; - __u8 mme_addr; - __u8 mme_freq; - __u8 nvmebm; - __u8 rsvd13[19]; - }; +``NVME_AER_CSS_NVM_RESERVATION`` + *undescribed* -**Members** +``NVME_AER_CSS_NVM_SANITIZE_COMPLETED`` + *undescribed* +``NVME_AER_CSS_NVM_UNEXPECTED_SANITIZE_DEALLOC`` + *undescribed* -.. c:type:: struct nvme_mi_read_port_info +.. c:type:: enum nvme_ae_info_notice -**Definition** +**Constants** -:: +``NVME_AER_NOTICE_NS_CHANGED`` + *undescribed* - struct nvme_mi_read_port_info { - __u8 portt; - __u8 rsvd1; - __le16 mmctptus; - __le32 meb; - union { - struct nvme_mi_port_pcie pcie; - struct nvme_mi_port_smb smb; - }; - }; +``NVME_AER_NOTICE_FW_ACT_STARTING`` + *undescribed* -**Members** +``NVME_AER_NOTICE_TELEMETRY`` + *undescribed* -``portt`` - **mmctptus**; +``NVME_AER_NOTICE_ANA`` + *undescribed* -``{unnamed_union}`` - anonymous +``NVME_AER_NOTICE_PL_EVENT`` + *undescribed* +``NVME_AER_NOTICE_LBA_STATUS_ALERT`` + *undescribed* +``NVME_AER_NOTICE_EG_EVENT`` + *undescribed* +``NVME_AER_NOTICE_DISC_CHANGED`` + *undescribed* -.. c:type:: struct nvme_mi_read_ctrl_info - **portid**; **prii**; **pri**; **vid**; **did**; **ssvid**; **ssid**; -**Definition** +.. c:type:: enum nvme_subsys_type -:: - struct nvme_mi_read_ctrl_info { - __u8 portid; - __u8 rsvd1[4]; - __u8 prii; - __le16 pri; - __le16 vid; - __le16 did; - __le16 ssvid; - __le16 ssid; - __u8 rsvd16[16]; - }; +**Constants** -**Members** +``NVME_NQN_DISC`` + Discovery type target subsystem +``NVME_NQN_NVME`` + NVME type target subsystem -.. c:type:: struct nvme_mi_osc +.. c:type:: struct nvmf_disc_log_entry - **type**; **opc**; + Discovery log page entry **Definition** :: - struct nvme_mi_osc { - __u8 type; - __u8 opc; + struct nvmf_disc_log_entry { + __u8 trtype; + __u8 adrfam; + __u8 subtype; + __u8 treq; + __le16 portid; + __le16 cntlid; + __le16 asqsz; + __u8 rsvd10[22]; + char trsvcid[NVMF_TRSVCID_SIZE]; + __u8 rsvd64[192]; + char subnqn[NVME_NQN_LENGTH]; + char traddr[NVMF_TRADDR_SIZE]; + union tsas { + char common[NVMF_TSAS_SIZE]; + struct rdma { + __u8 qptype; + __u8 prtype; + __u8 cms; + __u8 rsvd3[5]; + __u16 pkey; + __u8 rsvd10[246]; + } rdma; + struct tcp { + __u8 sectype; + } tcp; + } tsas; }; **Members** @@ -10081,182 +10201,156 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: struct nvme_mi_read_sc_list +.. c:type:: enum + Transport Type codes for Discovery Log Page entry TRTYPE field -**Definition** +**Constants** -:: +``NVMF_TRTYPE_UNSPECIFIED`` + Not indicated - struct nvme_mi_read_sc_list { - __le16 numcmd; - struct nvme_mi_osc cmds[]; - }; +``NVMF_TRTYPE_RDMA`` + RDMA -**Members** +``NVMF_TRTYPE_FC`` + Fibre Channel +``NVMF_TRTYPE_TCP`` + TCP +``NVMF_TRTYPE_LOOP`` + Reserved for host usage +``NVMF_TRTYPE_MAX`` + *undescribed* -.. c:type:: struct nvme_mi_nvm_ss_health_status -**Definition** +.. c:type:: enum -:: + Address Family codes for Discovery Log Page entry ADRFAM field - struct nvme_mi_nvm_ss_health_status { - __u8 nss; - __u8 sw; - __u8 ctemp; - __u8 pdlu; - __le16 ccs; - __u8 rsvd8[2]; - }; +**Constants** -**Members** +``NVMF_ADDR_FAMILY_PCI`` + PCIe + +``NVMF_ADDR_FAMILY_IP4`` + IPv4 + +``NVMF_ADDR_FAMILY_IP6`` + IPv6 + +``NVMF_ADDR_FAMILY_IB`` + InfiniBand +``NVMF_ADDR_FAMILY_FC`` + Fibre Channel .. c:type:: enum + Transport Requirements codes for Discovery Log Page entry TREQ field **Constants** -``NVME_MI_CCS_RDY`` - *undescribed* +``NVMF_TREQ_NOT_SPECIFIED`` + Not specified -``NVME_MI_CSS_CFS`` - *undescribed* +``NVMF_TREQ_REQUIRED`` + Required -``NVME_MI_CSS_SHST`` - *undescribed* +``NVMF_TREQ_NOT_REQUIRED`` + Not Required -``NVME_MI_CSS_NSSRO`` - *undescribed* +``NVMF_TREQ_DISABLE_SQFLOW`` + SQ flow control disable supported -``NVME_MI_CSS_CECO`` - *undescribed* -``NVME_MI_CSS_NAC`` - *undescribed* -``NVME_MI_CSS_FA`` - *undescribed* -``NVME_MI_CSS_CSTS`` - *undescribed* +.. c:type:: enum -``NVME_MI_CSS_CTEMP`` - *undescribed* + RDMA QP Service Type codes for Discovery Log Page entry TSAS RDMA_QPTYPE field -``NVME_MI_CSS_PDLU`` - *undescribed* +**Constants** -``NVME_MI_CSS_SPARE`` - *undescribed* +``NVMF_RDMA_QPTYPE_CONNECTED`` + Reliable Connected -``NVME_MI_CSS_CCWARN`` - *undescribed* +``NVMF_RDMA_QPTYPE_DATAGRAM`` + Reliable Datagram -.. c:type:: struct nvme_mi_ctrl_heal_status +.. c:type:: enum + RDMA Provider Type codes for Discovery Log Page entry TSAS RDMA_PRTYPE field -**Definition** +**Constants** -:: +``NVMF_RDMA_PRTYPE_NOT_SPECIFIED`` + No Provider Specified - struct nvme_mi_ctrl_heal_status { - __le16 ctlid; - __le16 csts; - __le16 ctemp; - __u8 pdlu; - __u8 spare; - __u8 cwarn; - __u8 rsvd9[7]; - }; +``NVMF_RDMA_PRTYPE_IB`` + InfiniBand -**Members** +``NVMF_RDMA_PRTYPE_ROCE`` + InfiniBand RoCE +``NVMF_RDMA_PRTYPE_ROCEV2`` + InfiniBand RoCEV2 + +``NVMF_RDMA_PRTYPE_IWARP`` + iWARP .. c:type:: enum + RDMA Connection Management Service Type codes for Discovery Log Page entry TSAS RDMA_CMS field **Constants** -``NVME_MI_CSTS_RDY`` - *undescribed* - -``NVME_MI_CSTS_CFS`` - *undescribed* - -``NVME_MI_CSTS_SHST`` - *undescribed* - -``NVME_MI_CSTS_NSSRO`` - *undescribed* +``NVMF_RDMA_CMS_RDMA_CM`` + Sockets based endpoint addressing -``NVME_MI_CSTS_CECO`` - *undescribed* -``NVME_MI_CSTS_NAC`` - *undescribed* -``NVME_MI_CSTS_FA`` - *undescribed* -``NVME_MI_CWARN_ST`` - *undescribed* +.. c:type:: enum -``NVME_MI_CWARN_TAUT`` - *undescribed* -``NVME_MI_CWARN_RD`` - *undescribed* +**Constants** -``NVME_MI_CWARN_RO`` - *undescribed* +``NVMF_TCP_SECTYPE_NONE`` + No Security -``NVME_MI_CWARN_VMBF`` - *undescribed* +``NVMF_TCP_SECTYPE_TLS`` + Transport Layer Security -.. c:type:: struct nvme_mi_vpd_mra +.. c:type:: struct nvmf_discovery_log - **nmravn**; **ff**; **i18vpwr**; **m18vpwr**; **i33vpwr**; **m33vpwr**; **m33vapsr**; **i5vapsr**; **m5vapsr**; **i12vapsr**; **m12vapsr**; **mtl**; **tnvmcap**[16]; **Definition** :: - struct nvme_mi_vpd_mra { - __u8 nmravn; - __u8 ff; - __u8 rsvd7[6]; - __u8 i18vpwr; - __u8 m18vpwr; - __u8 i33vpwr; - __u8 m33vpwr; - __u8 rsvd17; - __u8 m33vapsr; - __u8 i5vapsr; - __u8 m5vapsr; - __u8 i12vapsr; - __u8 m12vapsr; - __u8 mtl; - __u8 tnvmcap[16]; - __u8 rsvd37[27]; + struct nvmf_discovery_log { + __le64 genctr; + __le64 numrec; + __le16 recfmt; + __u8 rsvd14[1006]; + struct nvmf_disc_log_entry entries[0]; }; **Members** @@ -10265,43 +10359,44 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: struct nvme_mi_vpd_ppmra +.. c:type:: struct nvmf_connect_data **Definition** -:: - - struct nvme_mi_vpd_ppmra { - __u8 nppmravn; - __u8 pn; - __u8 ppi; - __u8 ls; - __u8 mlw; - __u8 mctp; - __u8 refccap; - __u8 pi; - __u8 rsvd13[3]; +:: + + struct nvmf_connect_data { + __u8 hostid[16]; + __le16 cntlid; + char rsvd4[238]; + char subsysnqn[NVME_NQN_LENGTH]; + char hostnqn[NVME_NQN_LENGTH]; + char rsvd5[256]; }; **Members** +``cntlid`` + **subsysnqn** + **hostnqn** + -.. c:type:: struct nvme_mi_vpd_telem +.. c:type:: struct nvme_mi_read_nvm_ss_info **Definition** :: - struct nvme_mi_vpd_telem { - __u8 type; - __u8 rev; - __u8 len; - __u8 data[0]; + struct nvme_mi_read_nvm_ss_info { + __u8 nump; + __u8 mjr; + __u8 mnr; + __u8 rsvd3[29]; }; **Members** @@ -10310,47 +10405,43 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: enum - - -**Constants** - -``NVME_MI_ELEM_EED`` - *undescribed* +.. c:type:: struct nvme_mi_port_pcie -``NVME_MI_ELEM_USCE`` - *undescribed* -``NVME_MI_ELEM_ECED`` - *undescribed* +**Definition** -``NVME_MI_ELEM_LED`` - *undescribed* +:: -``NVME_MI_ELEM_SMBMED`` - *undescribed* + struct nvme_mi_port_pcie { + __u8 mps; + __u8 sls; + __u8 cls; + __u8 mlw; + __u8 nlw; + __u8 pn; + __u8 rsvd14[18]; + }; -``NVME_MI_ELEM_PCIESED`` - *undescribed* +**Members** -``NVME_MI_ELEM_NVMED`` - *undescribed* -.. c:type:: struct nvme_mi_vpd_tra +.. c:type:: struct nvme_mi_port_smb **Definition** :: - struct nvme_mi_vpd_tra { - __u8 vn; - __u8 rsvd6; - __u8 ec; - struct nvme_mi_vpd_telem elems[0]; + struct nvme_mi_port_smb { + __u8 vpd_addr; + __u8 mvpd_freq; + __u8 mme_addr; + __u8 mme_freq; + __u8 nvmebm; + __u8 rsvd13[19]; }; **Members** @@ -10359,29 +10450,29 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: struct nvme_mi_vpd_mr_common +.. c:type:: struct nvme_mi_read_port_info - **type**; **rf**; **rlen**; **rchksum**; **hchksum**; **ppmra**; **tmra**; **Definition** :: - struct nvme_mi_vpd_mr_common { - __u8 type; - __u8 rf; - __u8 rlen; - __u8 rchksum; - __u8 hchksum; + struct nvme_mi_read_port_info { + __u8 portt; + __u8 rsvd1; + __le16 mmctptus; + __le32 meb; union { - struct nvme_mi_vpd_mra nmra; - struct nvme_mi_vpd_ppmra ppmra; - struct nvme_mi_vpd_tra tmra; + struct nvme_mi_port_pcie pcie; + struct nvme_mi_port_smb smb; }; }; **Members** +``portt`` + **mmctptus**; + ``{unnamed_union}`` anonymous @@ -10389,23 +10480,24 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: struct nvme_mi_vpd_hdr +.. c:type:: struct nvme_mi_read_ctrl_info + **portid**; **prii**; **pri**; **vid**; **did**; **ssvid**; **ssid**; **Definition** :: - struct nvme_mi_vpd_hdr { - __u8 ipmiver; - __u8 iuaoff; - __u8 ciaoff; - __u8 biaoff; - __u8 piaoff; - __u8 mrioff; - __u8 rsvd6; - __u8 chchk; - __u8 vpd[]; + struct nvme_mi_read_ctrl_info { + __u8 portid; + __u8 rsvd1[4]; + __u8 prii; + __le16 pri; + __le16 vid; + __le16 did; + __le16 ssvid; + __le16 ssid; + __u8 rsvd16[16]; }; **Members** @@ -10414,703 +10506,960 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: enum +.. c:type:: struct nvme_mi_osc + **type**; **opc**; -**Constants** +**Definition** -``NVME_SCT_GENERIC`` - *undescribed* +:: -``NVME_SCT_CMD_SPECIFIC`` - *undescribed* + struct nvme_mi_osc { + __u8 type; + __u8 opc; + }; -``NVME_SCT_MEDIA`` - *undescribed* +**Members** -``NVME_SCT_PATH`` - *undescribed* -``NVME_SCT_VS`` - *undescribed* -``NVME_SCT_MASK`` - *undescribed* -``NVME_SC_SUCCESS`` - *undescribed* -``NVME_SC_INVALID_OPCODE`` - *undescribed* +.. c:type:: struct nvme_mi_read_sc_list -``NVME_SC_INVALID_FIELD`` - *undescribed* -``NVME_SC_CMDID_CONFLICT`` - *undescribed* +**Definition** -``NVME_SC_DATA_XFER_ERROR`` - *undescribed* +:: -``NVME_SC_POWER_LOSS`` - *undescribed* + struct nvme_mi_read_sc_list { + __le16 numcmd; + struct nvme_mi_osc cmds[]; + }; -``NVME_SC_INTERNAL`` - *undescribed* +**Members** -``NVME_SC_ABORT_REQ`` - *undescribed* -``NVME_SC_ABORT_QUEUE`` - *undescribed* -``NVME_SC_FUSED_FAIL`` - *undescribed* -``NVME_SC_FUSED_MISSING`` - *undescribed* -``NVME_SC_INVALID_NS`` - *undescribed* +.. c:type:: struct nvme_mi_nvm_ss_health_status -``NVME_SC_CMD_SEQ_ERROR`` - *undescribed* -``NVME_SC_SGL_INVALID_LAST`` - *undescribed* +**Definition** -``NVME_SC_SGL_INVALID_COUNT`` - *undescribed* +:: -``NVME_SC_SGL_INVALID_DATA`` - *undescribed* + struct nvme_mi_nvm_ss_health_status { + __u8 nss; + __u8 sw; + __u8 ctemp; + __u8 pdlu; + __le16 ccs; + __u8 rsvd8[2]; + }; -``NVME_SC_SGL_INVALID_METADATA`` - *undescribed* +**Members** -``NVME_SC_SGL_INVALID_TYPE`` - *undescribed* -``NVME_SC_CMB_INVALID_USE`` - *undescribed* -``NVME_SC_PRP_INVALID_OFFSET`` - *undescribed* -``NVME_SC_AWU_EXCEEDED`` - *undescribed* -``NVME_SC_OP_DENIED`` - *undescribed* +.. c:type:: enum -``NVME_SC_SGL_INVALID_OFFSET`` - *undescribed* -``NVME_SC_HOSTID_FORMAT`` - *undescribed* +**Constants** -``NVME_SC_KAT_EXPIRED`` +``NVME_MI_CCS_RDY`` *undescribed* -``NVME_SC_KAT_INVALID`` +``NVME_MI_CSS_CFS`` *undescribed* -``NVME_SC_CMD_ABORTED_PREMEPT`` +``NVME_MI_CSS_SHST`` *undescribed* -``NVME_SC_SANITIZE_FAILED`` +``NVME_MI_CSS_NSSRO`` *undescribed* -``NVME_SC_SANITIZE_IN_PROGRESS`` +``NVME_MI_CSS_CECO`` *undescribed* -``NVME_SC_SGL_INVALID_GRANULARITY`` +``NVME_MI_CSS_NAC`` *undescribed* -``NVME_SC_CMD_IN_CMBQ_NOT_SUPP`` +``NVME_MI_CSS_FA`` *undescribed* -``NVME_SC_NS_WRITE_PROTECTED`` +``NVME_MI_CSS_CSTS`` *undescribed* -``NVME_SC_CMD_INTERRUPTED`` +``NVME_MI_CSS_CTEMP`` *undescribed* -``NVME_SC_TRAN_TPORT_ERROR`` +``NVME_MI_CSS_PDLU`` *undescribed* -``NVME_SC_LBA_RANGE`` +``NVME_MI_CSS_SPARE`` *undescribed* -``NVME_SC_CAP_EXCEEDED`` +``NVME_MI_CSS_CCWARN`` *undescribed* -``NVME_SC_NS_NOT_READY`` - *undescribed* -``NVME_SC_RESERVATION_CONFLICT`` - *undescribed* -``NVME_SC_FORMAT_IN_PROGRESS`` - *undescribed* -``NVME_SC_CQ_INVALID`` - *undescribed* +.. c:type:: struct nvme_mi_ctrl_heal_status + + +**Definition** + +:: + + struct nvme_mi_ctrl_heal_status { + __le16 ctlid; + __le16 csts; + __le16 ctemp; + __u8 pdlu; + __u8 spare; + __u8 cwarn; + __u8 rsvd9[7]; + }; + +**Members** + + -``NVME_SC_QID_INVALID`` - *undescribed* -``NVME_SC_QUEUE_SIZE`` - *undescribed* -``NVME_SC_ABORT_LIMIT`` - *undescribed* +.. c:type:: enum -``NVME_SC_ABORT_MISSING`` - *undescribed* -``NVME_SC_ASYNC_LIMIT`` - *undescribed* +**Constants** -``NVME_SC_FIRMWARE_SLOT`` +``NVME_MI_CSTS_RDY`` *undescribed* -``NVME_SC_FIRMWARE_IMAGE`` +``NVME_MI_CSTS_CFS`` *undescribed* -``NVME_SC_INVALID_VECTOR`` +``NVME_MI_CSTS_SHST`` *undescribed* -``NVME_SC_INVALID_LOG_PAGE`` +``NVME_MI_CSTS_NSSRO`` *undescribed* -``NVME_SC_INVALID_FORMAT`` +``NVME_MI_CSTS_CECO`` *undescribed* -``NVME_SC_FW_NEEDS_CONV_RESET`` +``NVME_MI_CSTS_NAC`` *undescribed* -``NVME_SC_INVALID_QUEUE`` +``NVME_MI_CSTS_FA`` *undescribed* -``NVME_SC_FEATURE_NOT_SAVEABLE`` +``NVME_MI_CWARN_ST`` *undescribed* -``NVME_SC_FEATURE_NOT_CHANGEABLE`` +``NVME_MI_CWARN_TAUT`` *undescribed* -``NVME_SC_FEATURE_NOT_PER_NS`` +``NVME_MI_CWARN_RD`` *undescribed* -``NVME_SC_FW_NEEDS_SUBSYS_RESET`` +``NVME_MI_CWARN_RO`` *undescribed* -``NVME_SC_FW_NEEDS_RESET`` +``NVME_MI_CWARN_VMBF`` *undescribed* -``NVME_SC_FW_NEEDS_MAX_TIME`` - *undescribed* -``NVME_SC_FW_ACTIVATE_PROHIBITED`` - *undescribed* -``NVME_SC_OVERLAPPING_RANGE`` - *undescribed* -``NVME_SC_NS_INSUFFICIENT_CAP`` - *undescribed* +.. c:type:: struct nvme_mi_vpd_mra -``NVME_SC_NS_ID_UNAVAILABLE`` - *undescribed* + **nmravn**; **ff**; **i18vpwr**; **m18vpwr**; **i33vpwr**; **m33vpwr**; **m33vapsr**; **i5vapsr**; **m5vapsr**; **i12vapsr**; **m12vapsr**; **mtl**; **tnvmcap**[16]; -``NVME_SC_NS_ALREADY_ATTACHED`` - *undescribed* +**Definition** -``NVME_SC_NS_IS_PRIVATE`` - *undescribed* +:: -``NVME_SC_NS_NOT_ATTACHED`` - *undescribed* + struct nvme_mi_vpd_mra { + __u8 nmravn; + __u8 ff; + __u8 rsvd7[6]; + __u8 i18vpwr; + __u8 m18vpwr; + __u8 i33vpwr; + __u8 m33vpwr; + __u8 rsvd17; + __u8 m33vapsr; + __u8 i5vapsr; + __u8 m5vapsr; + __u8 i12vapsr; + __u8 m12vapsr; + __u8 mtl; + __u8 tnvmcap[16]; + __u8 rsvd37[27]; + }; -``NVME_SC_THIN_PROV_NOT_SUPP`` - *undescribed* +**Members** -``NVME_SC_CTRL_LIST_INVALID`` - *undescribed* -``NVME_SC_SELF_TEST_IN_PROGRESS`` - *undescribed* -``NVME_SC_BP_WRITE_PROHIBITED`` - *undescribed* -``NVME_SC_INVALID_CTRL_ID`` - *undescribed* -``NVME_SC_INVALID_SEC_CTRL_STATE`` - *undescribed* +.. c:type:: struct nvme_mi_vpd_ppmra -``NVME_SC_INVALID_CTRL_RESOURCES`` - *undescribed* -``NVME_SC_INVALID_RESOURCE_ID`` - *undescribed* +**Definition** -``NVME_SC_PMR_SAN_PROHIBITED`` - *undescribed* +:: -``NVME_SC_ANA_GROUP_ID_INVALID`` - *undescribed* + struct nvme_mi_vpd_ppmra { + __u8 nppmravn; + __u8 pn; + __u8 ppi; + __u8 ls; + __u8 mlw; + __u8 mctp; + __u8 refccap; + __u8 pi; + __u8 rsvd13[3]; + }; -``NVME_SC_ANA_ATTACH_FAILED`` - *undescribed* +**Members** -``NVME_SC_BAD_ATTRIBUTES`` - *undescribed* -``NVME_SC_INVALID_PI`` - *undescribed* -``NVME_SC_READ_ONLY`` - *undescribed* -``NVME_SC_CONNECT_FORMAT`` - *undescribed* -``NVME_SC_CONNECT_CTRL_BUSY`` - *undescribed* +.. c:type:: struct nvme_mi_vpd_telem -``NVME_SC_CONNECT_INVALID_PARAM`` - *undescribed* -``NVME_SC_CONNECT_RESTART_DISC`` - *undescribed* +**Definition** -``NVME_SC_CONNECT_INVALID_HOST`` - *undescribed* +:: -``NVME_SC_DISCONNECT_INVALID_QTYPE`` - *undescribed* + struct nvme_mi_vpd_telem { + __u8 type; + __u8 rev; + __u8 len; + __u8 data[0]; + }; -``NVME_SC_DISCOVERY_RESTART`` - *undescribed* +**Members** -``NVME_SC_AUTH_REQUIRED`` - *undescribed* -``NVME_SC_WRITE_FAULT`` - *undescribed* -``NVME_SC_READ_ERROR`` - *undescribed* -``NVME_SC_GUARD_CHECK`` - *undescribed* -``NVME_SC_APPTAG_CHECK`` - *undescribed* +.. c:type:: enum -``NVME_SC_REFTAG_CHECK`` - *undescribed* -``NVME_SC_COMPARE_FAILED`` - *undescribed* +**Constants** -``NVME_SC_ACCESS_DENIED`` +``NVME_MI_ELEM_EED`` *undescribed* -``NVME_SC_UNWRITTEN_BLOCK`` +``NVME_MI_ELEM_USCE`` *undescribed* -``NVME_SC_ANA_INTERNAL_PATH_ERROR`` +``NVME_MI_ELEM_ECED`` *undescribed* -``NVME_SC_ANA_PERSISTENT_LOSS`` +``NVME_MI_ELEM_LED`` *undescribed* -``NVME_SC_ANA_INACCESSIBLE`` +``NVME_MI_ELEM_SMBMED`` *undescribed* -``NVME_SC_ANA_TRANSITION`` +``NVME_MI_ELEM_PCIESED`` *undescribed* -``NVME_SC_CTRL_PATH_ERROR`` +``NVME_MI_ELEM_NVMED`` *undescribed* -``NVME_SC_HOST_PATH_ERROR`` - *undescribed* -``NVME_SC_CMD_ABORTED_BY_HOST`` - *undescribed* -``NVME_SC_MASK`` - *undescribed* -``NVME_SC_CRD`` - *undescribed* +.. c:type:: struct nvme_mi_vpd_tra -``NVME_SC_MORE`` - *undescribed* -``NVME_SC_DNR`` - *undescribed* +**Definition** +:: -.. c:function:: __u8 nvme_status_to_errno (int status, bool fabrics) + struct nvme_mi_vpd_tra { + __u8 vn; + __u8 rsvd6; + __u8 ec; + struct nvme_mi_vpd_telem elems[0]; + }; - Converts nvme return status to errno +**Members** -**Parameters** -``int status`` - Return status from an nvme passthrough commmand -``bool fabrics`` - true if given status is for fabrics -**Description** -If status < 0, errno is already set. +.. c:type:: struct nvme_mi_vpd_mr_common -**Return** -Appropriate errno for the given nvme status +**Definition** +:: -.. c:function:: int nvme_fw_download_seq (int fd, __u32 size, __u32 xfer, __u32 offset, void * buf) + struct nvme_mi_vpd_mr_common { + __u8 type; + __u8 rf; + __u8 rlen; + __u8 rchksum; + __u8 hchksum; + union { + struct nvme_mi_vpd_mra nmra; + struct nvme_mi_vpd_ppmra ppmra; + struct nvme_mi_vpd_tra tmra; + }; + }; +**Members** -**Parameters** +``{unnamed_union}`` + anonymous -``int fd`` - *undescribed* -``__u32 size`` - *undescribed* -``__u32 xfer`` - *undescribed* -``__u32 offset`` - *undescribed* -``void * buf`` +.. c:type:: struct nvme_mi_vpd_hdr -.. c:function:: int nvme_get_ctrl_telemetry (int fd, bool rae, void ** buf, __u32 * log_size) +**Definition** +:: -**Parameters** + struct nvme_mi_vpd_hdr { + __u8 ipmiver; + __u8 iuaoff; + __u8 ciaoff; + __u8 biaoff; + __u8 piaoff; + __u8 mrioff; + __u8 rsvd6; + __u8 chchk; + __u8 vpd[]; + }; -``int fd`` - *undescribed* +**Members** -``bool rae`` - *undescribed* -``void ** buf`` - *undescribed* -``__u32 * log_size`` -.. c:function:: int nvme_get_host_telemetry (int fd, void ** buf, __u32 * log_size) +.. c:type:: enum nvme_status_field + Defines all parts of the nvme status field: status code, status code type, and additional flags. -**Parameters** +**Constants** + +``NVME_SCT_MASK`` + Mask to get the value of the Status Code Type -``int fd`` - *undescribed* +``NVME_SCT_GENERIC`` + Generic errors applicable to multiple opcodes -``void ** buf`` - *undescribed* +``NVME_SCT_CMD_SPECIFIC`` + Errors associated to a specific opcode -``__u32 * log_size`` +``NVME_SCT_MEDIA`` + Errors associated with media and data integrity +``NVME_SCT_PATH`` + Errors associated with the paths connection -.. c:function:: int nvme_get_new_host_telemetry (int fd, void ** buf, __u32 * log_size) +``NVME_SCT_VS`` + Vendor specific errors +``NVME_SC_MASK`` + Mask to get the value of the status code. -**Parameters** +``NVME_SC_SUCCESS`` + Successful Completion: The command + completed without error. -``int fd`` - *undescribed* +``NVME_SC_INVALID_OPCODE`` + Invalid Command Opcode: A reserved coded + value or an unsupported value in the command opcode field. -``void ** buf`` - *undescribed* +``NVME_SC_INVALID_FIELD`` + Invalid Field in Command: A reserved + coded value or an unsupported value in a defined field. -``__u32 * log_size`` +``NVME_SC_CMDID_CONFLICT`` + Command ID Conflict: The command + 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. -.. c:function:: void nvme_setup_id_ns (struct nvme_id_ns * ns, __u64 nsze, __u64 ncap, __u8 flbas, __u8 dps, __u8 nmic, __u32 anagrpid, __u16 nvmsetid) +``NVME_SC_POWER_LOSS`` + Commands Aborted due to Power Loss + 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. -**Parameters** +``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. -``struct nvme_id_ns * ns`` - *undescribed* +``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. -``__u64 nsze`` - *undescribed* +``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. -``__u64 ncap`` - *undescribed* +``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. -``__u8 flbas`` - *undescribed* +``NVME_SC_INVALID_NS`` + Invalid Namespace or Format: The + namespace or the format of that namespace is invalid. -``__u8 dps`` - *undescribed* +``NVME_SC_CMD_SEQ_ERROR`` + Command Sequence Error: The command was + aborted due to a protocol violation in a multi-command sequence. -``__u8 nmic`` - *undescribed* +``NVME_SC_SGL_INVALID_LAST`` + Invalid SGL Segment Descriptor: The + command includes an invalid SGL Last Segment or SGL Segment descriptor. -``__u32 anagrpid`` - *undescribed* +``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. -``__u16 nvmsetid`` - *undescribed* +``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. +``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. -.. c:function:: void nvme_setup_ctrl_list (struct nvme_ctrl_list * cntlist, __u16 num_ctrls, __u16 * ctrlist) +``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. +``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. -**Parameters** +``NVME_SC_PRP_INVALID_OFFSET`` + PRP Offset Invalid: The Offset field for + a PRP entry is invalid. -``struct nvme_ctrl_list * cntlist`` - *undescribed* +``NVME_SC_AWU_EXCEEDED`` + Atomic Write Unit Exceeded: The length + specified exceeds the atomic write unit size. -``__u16 num_ctrls`` - *undescribed* +``NVME_SC_OP_DENIED`` + Operation Denied: The command was denied + due to lack of access rights. Refer to + the appropriate security specification. -``__u16 * ctrlist`` - *undescribed* +``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. +``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. -.. c:function:: void nvme_setup_dsm_range (struct nvme_dsm_range * dsm, __u32 * ctx_attrs, __u32 * llbas, __u64 * slbas, __u16 nr_ranges) +``NVME_SC_KAT_EXPIRED`` + Keep Alive Timer Expired: The Keep Alive + Timer expired. - Constructs a data set range structure +``NVME_SC_KAT_INVALID`` + Keep Alive Timeout Invalid: The Keep + Alive Timeout value specified is invalid. -**Parameters** +``NVME_SC_CMD_ABORTED_PREMEPT`` + Command Aborted due to Preempt and Abort: + The command was aborted due to a Reservation Acquire command. -``struct nvme_dsm_range * dsm`` - DSM range array +``NVME_SC_SANITIZE_FAILED`` + Sanitize Failed: The most recent sanitize + operation failed and no recovery action has been successfully completed. -``__u32 * ctx_attrs`` - Array of context attributes +``NVME_SC_SANITIZE_IN_PROGRESS`` + Sanitize In Progress: The requested + function (e.g., command) is prohibited + while a sanitize operation is in + progress. -``__u32 * llbas`` - Array of length in logical blocks +``NVME_SC_SGL_INVALID_GRANULARITY`` + SGL Data Block Granularity Invalid: The + Address alignment or Length granularity + for an SGL Data Block descriptor is + invalid. -``__u64 * slbas`` - Array of starting logical blocks +``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. -``__u16 nr_ranges`` - The size of the dsm arrays +``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. -**Description** +``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. -Each array must be the same size of size 'nr_ranges'. +``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. -**Return** +``NVME_SC_LBA_RANGE`` + LBA Out of Range: The command references + an LBA that exceeds the size of the namespace. -The nvme command status if a response was received or -errno - otherwise. +``NVME_SC_CAP_EXCEEDED`` + Capacity Exceeded: Execution of the + 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. -.. c:function:: int __nvme_get_log_page (int fd, __u32 nsid, __u8 log_id, bool rae, __u32 xfer_len, __u32 data_len, void * data) +``NVME_SC_RESERVATION_CONFLICT`` + Reservation Conflict: The command was + 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. -**Parameters** +``NVME_SC_CQ_INVALID`` + Completion Queue Invalid: The Completion + Queue identifier specified in the command + does not exist. -``int fd`` - *undescribed* +``NVME_SC_QID_INVALID`` + Invalid Queue Identifier: The creation of + the I/O Completion Queue failed due to an + invalid queue identifier specified as + part of the command. An invalid queue + identifier is one that is currently in + use or one that is outside the range + supported by the controller. -``__u32 nsid`` - *undescribed* +``NVME_SC_QUEUE_SIZE`` + Invalid Queue Size: The host attempted to + create an I/O Completion Queue with an + invalid number of entries. -``__u8 log_id`` - *undescribed* +``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. -``bool rae`` - *undescribed* +``NVME_SC_ABORT_MISSING`` + Abort Command is missing: The abort + command is missing. -``__u32 xfer_len`` - Max partial log transfer size to request while splitting +``NVME_SC_ASYNC_LIMIT`` + Asynchronous Event Request Limit + Exceeded: The number of concurrently + outstanding Asynchronous Event Request + commands has been exceeded. -``__u32 data_len`` - *undescribed* +``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. -``void * data`` - *undescribed* +``NVME_SC_FIRMWARE_IMAGE`` + Invalid Firmware Image: The firmware + 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. -.. c:function:: int nvme_get_log_page (int fd, __u32 nsid, __u8 log_id, bool rae, __u32 data_len, void * data) +``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. +``NVME_SC_INVALID_FORMAT`` + Invalid Format: The LBA Format specified + is not supported. -**Parameters** +``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. -``int fd`` - *undescribed* +``NVME_SC_INVALID_QUEUE`` + Invalid Queue Deletion: Invalid I/O + Completion Queue specified to delete. -``__u32 nsid`` - *undescribed* +``NVME_SC_FEATURE_NOT_SAVEABLE`` + Feature Identifier Not Saveable: The + Feature Identifier specified does not + support a saveable value. -``__u8 log_id`` - *undescribed* +``NVME_SC_FEATURE_NOT_CHANGEABLE`` + Feature Not Changeable: The Feature + Identifier is not able to be changed. -``bool rae`` - *undescribed* +``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. -``__u32 data_len`` - *undescribed* +``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. -``void * data`` +``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. -**Description** +``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. -Calls __nvme_get_log_page() with a default 4k transfer length. +``NVME_SC_FW_ACTIVATE_PROHIBITED`` + Firmware Activation Prohibited: The image + 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. -.. c:function:: int nvme_get_ana_log_len (int fd, size_t * analen) +``NVME_SC_NS_INSUFFICIENT_CAP`` + Namespace Insufficient Capacity: Creating + the namespace requires more free space + than is currently available. - Retreive size of the current ANA log +``NVME_SC_NS_ID_UNAVAILABLE`` + Namespace Identifier Unavailable: The + number of namespaces supported has been + exceeded. -**Parameters** +``NVME_SC_NS_ALREADY_ATTACHED`` + Namespace Already Attached: The + controller is already attached to the + namespace specified. -``int fd`` - File descriptor of nvme device +``NVME_SC_NS_IS_PRIVATE`` + Namespace Is Private: The namespace is + private and is already attached to one + controller. -``size_t * analen`` - Pointer to where the length will be set on success +``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. -**Return** +``NVME_SC_THIN_PROV_NOT_SUPP`` + Thin Provisioning Not Supported: Thin + provisioning is not supported by the + controller. -0 on success, -1 otherwise with errno set +``NVME_SC_CTRL_LIST_INVALID`` + Controller List Invalid: The controller + list provided contains invalid controller + ids. +``NVME_SC_SELF_TEST_IN_PROGRESS`` + Device Self-test In Progress: -.. c:function:: int nvme_namespace_attach_ctrls (int fd, __u32 nsid, __u16 num_ctrls, __u16 * ctrlist) +``NVME_SC_BP_WRITE_PROHIBITED`` + Boot Partition Write Prohibited: The + command is trying to modify a locked Boot + Partition. - Attach namespace to controller(s) +``NVME_SC_INVALID_CTRL_ID`` + Invalid Controller Identifier: -**Parameters** +``NVME_SC_INVALID_SEC_CTRL_STATE`` + Invalid Secondary Controller State -``int fd`` - File descriptor of nvme device +``NVME_SC_INVALID_CTRL_RESOURCES`` + Invalid Number of Controller Resources -``__u32 nsid`` - Namespace ID to attach +``NVME_SC_INVALID_RESOURCE_ID`` + Invalid Resource Identifier -``__u16 num_ctrls`` - Number of controllers in ctrlist +``NVME_SC_PMR_SAN_PROHIBITED`` + Sanitize Prohibited While Persistent + Memory Region is Enabled -``__u16 * ctrlist`` - List of controller IDs to perform the attach action +``NVME_SC_ANA_GROUP_ID_INVALID`` + ANA Group Identifier Invalid -**Return** +``NVME_SC_ANA_ATTACH_FAILED`` + ANA Attach Failed -The nvme command status if a response was received or -1 - with errno set otherwise. +``NVME_SC_BAD_ATTRIBUTES`` + Conflicting Dataset Management Attributes +``NVME_SC_INVALID_PI`` + Invalid Protection Information -.. c:function:: int nvme_namespace_detach_ctrls (int fd, __u32 nsid, __u16 num_ctrls, __u16 * ctrlist) +``NVME_SC_READ_ONLY`` + Attempted Write to Read Only Range - Detach namespace from controller(s) +``NVME_SC_CONNECT_FORMAT`` + Incompatible Format: The NVM subsystem + does not support the record format + specified by the host. -**Parameters** +``NVME_SC_CONNECT_CTRL_BUSY`` + Controller Busy: The controller is + already associated with a host. -``int fd`` - File descriptor of nvme device +``NVME_SC_CONNECT_INVALID_PARAM`` + Connect Invalid Parameters: One or more + of the command parameters. -``__u32 nsid`` - Namespace ID to detach +``NVME_SC_CONNECT_RESTART_DISC`` + Connect Restart Discovery: The NVM + subsystem requested is not available. -``__u16 num_ctrls`` - Number of controllers in ctrlist +``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 -``__u16 * ctrlist`` - List of controller IDs to perform the detach action +``NVME_SC_DISCONNECT_INVALID_QTYPE`` + Invalid Queue Type: The command was sent + on the wrong queue type. -**Return** +``NVME_SC_DISCOVERY_RESTART`` + Discover Restart: The snapshot of the + records is now invalid or out of date. -The nvme command status if a response was received or -1 - with errno set otherwise. +``NVME_SC_AUTH_REQUIRED`` + Authentication Required: NVMe in-band + 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. -.. c:function:: int nvme_get_feature_length (int fid, __u32 cdw11, __u32 * len) +``NVME_SC_READ_ERROR`` + Unrecovered Read Error: The read data + could not be recovered from the media. - Retreive the command payload length for a specific feature identifier +``NVME_SC_GUARD_CHECK`` + End-to-end Guard Check Error: The command + was aborted due to an end-to-end guard + check failure. -**Parameters** +``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. -``int fid`` - *undescribed* +``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. -``__u32 cdw11`` - *undescribed* +``NVME_SC_COMPARE_FAILED`` + Compare Failure: The command failed due + to a miscompare during a Compare command. -``__u32 * len`` +``NVME_SC_ACCESS_DENIED`` + Access Denied: Access to the namespace + and/or LBA range is denied due to lack of + access rights. -**Return** +``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. -0 on success, -1 with errno set otherwise +``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. +``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. -.. c:function:: int nvme_get_directive_receive_length (enum nvme_directive_dtype dtype, enum nvme_directive_receive_doper doper, __u32 * len) +``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. +``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. -**Parameters** +``NVME_SC_CTRL_PATH_ERROR`` + Controller Pathing Error: A pathing error + was detected by the controller. -``enum nvme_directive_dtype dtype`` - Directive type, see :c:type:`enum nvme_directive_dtype ` +``NVME_SC_HOST_PATH_ERROR`` + Host Pathing Error: A pathing error was + detected by the host. -``enum nvme_directive_receive_doper doper`` - Directive receive operation, see :c:type:`enum nvme_directive_receive_doper ` +``NVME_SC_CMD_ABORTED_BY_HOST`` + Command Aborted By Host: The command was + aborted as a result of host action. -``__u32 * len`` - Address to save the payload length of the directive in bytes on - a successful decode +``NVME_SC_CRD`` + Mask to get value of Command Retry Delay + index -**Return** +``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. -0 on success, -1 with errno set to EINVAL. +``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. -.. c:function:: int nvme_open (const char * name) +.. c:function:: __u16 nvme_status_code_type (__u16 status_field) - Open an nvme controller or namespace device + Returns the NVMe Status Code Type **Parameters** -``const char * name`` - The basename of the device to open +``__u16 status_field`` + The NVMe Completion Queue Entry's Status Field **Description** -This will look for the handle in /dev/ and validate the name and filetype -match linux conventions. - -**Return** - -A file descriptor for the device on a successful open, or -1 with - errno set otherwise. +See :c:type:`enum nvme_status_field ` -.. c:function:: int nvme_set_attr (const char * dir, const char * attr, const char * value) +.. c:function:: __u16 nvme_status_code (__u16 status_field) + Returns the NVMe Status Code **Parameters** -``const char * dir`` - *undescribed* - -``const char * attr`` - *undescribed* - -``const char * value`` +``__u16 status_field`` + The NVMe Completion Queue Entry's Status Field **Description** -Return +See :c:type:`enum nvme_status_field ` diff --git a/src/nvme/types.h b/src/nvme/types.h index 02b3a6dc5e..3a15c2fae0 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -1752,10 +1752,10 @@ struct nvme_error_log_page { __le32 nsid; __u8 vs; __u8 trtype; - __u8 resv[2]; + __u8 rsvd[2]; __le64 cs; __le16 trtype_spec_info; - __u8 resv2[22]; + __u8 rsvd2[22]; }; /** @@ -1867,9 +1867,9 @@ struct nvme_frs { */ struct nvme_firmware_slot { __u8 afi; - __u8 resv[7]; + __u8 rsvd[7]; struct nvme_frs frs[7]; - __u8 resv2[448]; + __u8 rsvd2[448]; }; /** @@ -1880,7 +1880,7 @@ struct nvme_firmware_slot { struct nvme_cmd_effects_log { __le32 acs[256]; __le32 iocs[256]; - __u8 resv[2048]; + __u8 rsvd[2048]; }; /** @@ -1999,16 +1999,35 @@ struct nvme_self_test_log { } __attribute__((packed)); /** - * struct nvme_telemetry_log - - * @lpi: - * @ieee: - * @dalb1: - * @dalb2: - * @dalb3: - * @ctrlavail: - * @ctrldgn: - * @rsnident: - * @telemetry_dataarea: + * struct nvme_telemetry_log - Retrieve internal data specific to the + * manufacturer. + * @lpi: Log Identifier, either #NVME_LOG_LID_TELEMETRY_HOST or + * #NVME_LOG_LID_TELEMETRY_CTRL + * @ieee: IEEE OUI Identifier is the Organization Unique Identifier (OUI) + * 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. + * @dalb3: Telemetry Controller-Initiated Data Area 1 Last Block is + * 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. + * @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. + * @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. + * @data_area: Telemetry data blocks, vendor specific information data. + * + * This log consists of a header describing the log and zero or more Telemetry + * Data Blocks. All Telemetry Data Blocks are %NVME_LOG_TELEM_BLOCK_SIZE, 512 + * bytes, in size. This log captures the controller’s internal state. */ struct nvme_telemetry_log { __u8 lpi; @@ -2021,7 +2040,7 @@ struct nvme_telemetry_log { __u8 ctrlavail; __u8 ctrldgn; __u8 rsnident[128]; - __u8 telemetry_dataarea[]; + __u8 data_area[]; }; /** @@ -2476,7 +2495,7 @@ struct nvme_plm_config { */ struct nvme_feat_host_behavior { __u8 acre; - __u8 resv1[511]; + __u8 rsvd1[511]; }; /** @@ -2524,10 +2543,10 @@ struct nvme_registered_ctrl { struct nvme_registered_ctrl_ext { __le16 cntlid; __u8 rcsts; - __u8 resv3[5]; + __u8 rsvd3[5]; __le64 rkey; __u8 hostid[16]; - __u8 resv32[32]; + __u8 rsvd32[32]; }; /** @@ -2548,7 +2567,7 @@ struct nvme_reservation_status { __u8 rsvd10[14]; union { struct { - __u8 resv24[40]; + __u8 rsvd24[40]; struct nvme_registered_ctrl_ext regctl_eds[0]; }; struct nvme_registered_ctrl regctl_ds[0]; @@ -2836,9 +2855,9 @@ struct nvmf_disc_log_entry { __le16 portid; __le16 cntlid; __le16 asqsz; - __u8 resv10[22]; + __u8 rsvd10[22]; char trsvcid[NVMF_TRSVCID_SIZE]; - __u8 resv64[192]; + __u8 rsvd64[192]; char subnqn[NVME_NQN_LENGTH]; char traddr[NVMF_TRADDR_SIZE]; union tsas { @@ -2847,9 +2866,9 @@ struct nvmf_disc_log_entry { __u8 qptype; __u8 prtype; __u8 cms; - __u8 resv3[5]; + __u8 rsvd3[5]; __u16 pkey; - __u8 resv10[246]; + __u8 rsvd10[246]; } rdma; struct tcp { __u8 sectype; @@ -2963,7 +2982,7 @@ struct nvmf_discovery_log { __le64 genctr; __le64 numrec; __le16 recfmt; - __u8 resv14[1006]; + __u8 rsvd14[1006]; struct nvmf_disc_log_entry entries[0]; }; @@ -2977,10 +2996,10 @@ struct nvmf_discovery_log { struct nvmf_connect_data { __u8 hostid[16]; __le16 cntlid; - char resv4[238]; + char rsvd4[238]; char subsysnqn[NVME_NQN_LENGTH]; char hostnqn[NVME_NQN_LENGTH]; - char resv5[256]; + char rsvd5[256]; }; /** From 667ba8f9fc9051e08167d1c214ebfa708348d4f0 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Mon, 17 Feb 2020 12:32:58 -0800 Subject: [PATCH 0036/1564] Fix split line documentation The documentation parser won't recognize the desired link nmae if enum and the name are on separate lines. Signed-off-by: Keith Busch --- src/nvme/ioctl.h | 529 ++++++++++++++++++++++++----------------------- src/nvme/types.h | 2 +- src/nvme/util.h | 36 ++-- 3 files changed, 285 insertions(+), 282 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 6e315fe906..838d15ce75 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -131,8 +131,8 @@ struct nvme_passthru_cmd64 { * * Uses NVME_IOCTL_ADMIN64_CMD for the ioctl request. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_submit_admin_passthru64(int fd, struct nvme_passthru_cmd64 *cmd, __u64 *result); @@ -164,8 +164,8 @@ int nvme_submit_admin_passthru64(int fd, struct nvme_passthru_cmd64 *cmd, * * Known values for @opcode are defined in &enum nvme_admin_opcode. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_admin_passthru64(int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, @@ -181,8 +181,8 @@ int nvme_admin_passthru64(int fd, __u8 opcode, __u8 flags, __u16 rsvd, * * Uses NVME_IOCTL_ADMIN_CMD for the ioctl request. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_submit_admin_passthru(int fd, struct nvme_passthru_cmd *cmd, __u32 *result); @@ -214,8 +214,8 @@ int nvme_submit_admin_passthru(int fd, struct nvme_passthru_cmd *cmd, * * Known values for @opcode are defined in &enum nvme_admin_opcode. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_admin_passthru(int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, @@ -231,8 +231,8 @@ int nvme_admin_passthru(int fd, __u8 opcode, __u8 flags, __u16 rsvd, * * Uses NVME_IOCTL_IO64_CMD for the ioctl request. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_submit_io_passthru64(int fd, struct nvme_passthru_cmd64 *cmd, __u64 *result); @@ -264,8 +264,8 @@ int nvme_submit_io_passthru64(int fd, struct nvme_passthru_cmd64 *cmd, * * Known values for @opcode are defined in &enum nvme_io_opcode. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_io_passthru64(int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, @@ -282,8 +282,8 @@ int nvme_io_passthru64(int fd, __u8 opcode, __u8 flags, __u16 rsvd, * * Uses NVME_IOCTL_IO_CMD for the ioctl request. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_submit_io_passthru(int fd, struct nvme_passthru_cmd *cmd, __u32 *result); @@ -315,8 +315,8 @@ int nvme_submit_io_passthru(int fd, struct nvme_passthru_cmd *cmd, * * Known values for @opcode are defined in &enum nvme_io_opcode. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_io_passthru(int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, @@ -771,8 +771,8 @@ enum nvme_virt_mgmt_rt { * The Identify command returns a data buffer that describes information about * the NVM subsystem, the controller or the namespace(s). * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify(int fd, enum nvme_identify_cns cns, __u32 nsid, __u16 cntid, __u16 nvmsetid, __u8 uuidx, void *data); @@ -786,8 +786,8 @@ int nvme_identify(int fd, enum nvme_identify_cns cns, __u32 nsid, * * See &struct nvme_id_ctrl for details on the data returned. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_ctrl(int fd, struct nvme_id_ctrl *id); @@ -808,8 +808,8 @@ int nvme_identify_ctrl(int fd, struct nvme_id_ctrl *id); * * See &struct nvme_id_ns for details on the structure returned. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_ns(int fd, __u32 nsid, struct nvme_id_ns *ns); @@ -820,8 +820,8 @@ int nvme_identify_ns(int fd, __u32 nsid, struct nvme_id_ns *ns); * @nsid: Namespace to identify * @ns: User space destination address to transfer the data * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_allocated_ns(int fd, __u32 nsid, struct nvme_id_ns *ns); @@ -837,8 +837,8 @@ int nvme_identify_allocated_ns(int fd, __u32 nsid, struct nvme_id_ns *ns); * * See &struct nvme_ns_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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_active_ns_list(int fd, __u32 nsid, struct nvme_ns_list *list); @@ -854,8 +854,8 @@ int nvme_identify_active_ns_list(int fd, __u32 nsid, struct nvme_ns_list *list); * * See &struct nvme_ns_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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_allocated_ns_list(int fd, __u32 nsid, struct nvme_ns_list *list); @@ -872,8 +872,8 @@ int nvme_identify_allocated_ns_list(int fd, __u32 nsid, * * See &struct nvme_ctrl_list for a definition of the structure returned. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_ctrl_list(int fd, __u16 cntid, struct nvme_ctrl_list *ctrlist); @@ -891,8 +891,8 @@ int nvme_identify_ctrl_list(int fd, __u16 cntid, * * See &struct nvme_ctrl_list for a definition of the structure returned. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 */ int nvme_identify_nsid_ctrl_list(int fd, __u32 nsid, __u16 cntid, struct nvme_ctrl_list *ctrlist); @@ -911,8 +911,8 @@ int nvme_identify_nsid_ctrl_list(int fd, __u32 nsid, __u16 cntid, * * See &struct nvme_ns_id_desc for the definition of the returned structure. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_ns_descs(int fd, __u32 nsid, struct nvme_ns_id_desc *descs); @@ -929,8 +929,8 @@ int nvme_identify_ns_descs(int fd, __u32 nsid, struct nvme_ns_id_desc *descs); * * See &struct nvme_id_nvmset_list 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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_nvmset_list(int fd, __u16 nvmsetid, struct nvme_id_nvmset_list *nvmset); @@ -944,8 +944,8 @@ int nvme_identify_nvmset_list(int fd, __u16 nvmsetid, * * See &struct nvme_primary_ctrl_cap for the defintion 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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_primary_ctrl(int fd, __u16 cntid, struct nvme_primary_ctrl_cap *cap); @@ -964,8 +964,8 @@ int nvme_identify_primary_ctrl(int fd, __u16 cntid, * See &struct nvme_secondary_ctrls_list for a 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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_secondary_ctrl_list(int fd, __u16 cntid, struct nvme_secondary_ctrl_list *list); @@ -983,8 +983,8 @@ int nvme_identify_secondary_ctrl_list(int fd, __u16 cntid, * See &struct nvme_id_ns_granularity_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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_ns_granularity(int fd, struct nvme_id_ns_granularity_list *list); @@ -998,26 +998,26 @@ int nvme_identify_ns_granularity(int fd, struct nvme_id_ns_granularity_list *lis * * See &struct nvme_id_uuid_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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_uuid(int fd, struct nvme_id_uuid_list *list); /** * nvme_get_log() - NVMe Admin Get Log command - * @fd: File descriptor of nvme device - * @lid: Log page identifier, see &enum nvme_cmd_get_log_lid for known values - * @nsid: Namespace identifier, if applicable - * @lpo: Log page offset for partial log transfers - * @lsp: Log specific field - * @lsi: Endurance group information - * @rae: Retain asynchronous events - * @uuidx: UUID selection, if supported - * @len: Length of provided user buffer to hold the log data in bytes - * @log: User space destination address to transfer the data - * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * @fd: File descriptor of nvme device + * @lid: Log page identifier, see &enum nvme_cmd_get_log_lid for known values + * @nsid: Namespace identifier, if applicable + * @lpo: Log page offset for partial log transfers + * @lsp: Log specific field + * @lsi: Endurance group information + * @rae: Retain asynchronous events + * @uuidx: UUID selection, if supported + * @len: Length of provided user buffer to hold the log data in bytes + * @log: User space destination address to transfer the data + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, __u8 lsp, __u16 lsi, bool rae, __u8 uuidx, __u32 len, void *log); @@ -1033,8 +1033,8 @@ int nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, * that completed with error, or may report an error that is not specific to a * particular command. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_error(int fd, unsigned nr_entries, bool rae, struct nvme_error_log_page *log); @@ -1053,8 +1053,8 @@ int nvme_get_log_error(int fd, unsigned nr_entries, bool rae, * requesting the log page on a per namespace basis, as indicated by bit 0 of * the LPA field in the Identify Controller data structure. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_smart(int fd, __u32 nsid, bool rae, struct nvme_smart_log *log); @@ -1068,8 +1068,8 @@ int nvme_get_log_smart(int fd, __u32 nsid, bool rae, struct nvme_smart_log *log) * firmware slot supported. The firmware revision is indicated as an ASCII * string. The log page also indicates the active slot number. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_fw_slot(int fd, bool rae, struct nvme_firmware_slot *log); @@ -1083,8 +1083,8 @@ int nvme_get_log_fw_slot(int fd, bool rae, struct nvme_firmware_slot *log); * that have changed since the last time the namespace was identified, been * added, or deleted. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_changed_ns_list(int fd, bool rae, struct nvme_ns_list *log); @@ -1096,8 +1096,8 @@ int nvme_get_log_changed_ns_list(int fd, bool rae, struct nvme_ns_list *log); * This log page is used to describe the commands that the controller supports * and the effects of those commands on the state of the NVM subsystem. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_cmd_effects(int fd, struct nvme_cmd_effects_log *log); @@ -1111,8 +1111,8 @@ int nvme_get_log_cmd_effects(int fd, struct nvme_cmd_effects_log *log); * the percent complete of that operation, and the results of the previous 20 * self-test operations. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_device_self_test(int fd, struct nvme_self_test_log *log); @@ -1131,8 +1131,8 @@ int nvme_get_log_create_telemetry_host(int fd, struct nvme_telemetry_log *log); * Retreives the Telemetry Host-Initiated log page at the requested offset * using the previously existing capture. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_telemetry_host(int fd, __u64 offset, __u32 len, void *log); @@ -1160,8 +1160,8 @@ int nvme_get_log_telemetry_ctrl(int fd, bool rae, __u64 offset, __u32 len, * generated when an entry for an Endurance Group is newly added to this log * page. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_endurance_group(int fd, __u16 endgid, struct nvme_endurance_group_log *log); @@ -1171,8 +1171,8 @@ int nvme_get_log_endurance_group(int fd, __u16 endgid, * @fd: * @nvmsetid: * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_predictable_lat_nvmset(int fd, __u16 nvmsetid, struct nvme_nvmset_predictable_lat_log *log); @@ -1186,7 +1186,9 @@ int nvme_get_log_predictable_lat_event(int fd, bool rae, __u32 offset, __u32 len, void *log); /** - * + * enum nvme_log_ana_lsp - + * @NVME_LOG_ANA_LSP_RGO_NAMESPACES: + * @NVME_LOG_ANA_LSP_RGO_GROUPS_ONLY: */ enum nvme_log_ana_lsp { NVME_LOG_ANA_LSP_RGO_NAMESPACES = 0, @@ -1207,8 +1209,8 @@ enum nvme_log_ana_lsp { * * See &struct nvme_ana_rsp_hdr 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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_ana(int fd, enum nvme_log_ana_lsp lsp, bool rae, __u64 offset, __u32 len, void *log); @@ -1250,8 +1252,8 @@ int nvme_get_log_endurance_grp_evt(int fd, bool rae, __u32 offset, __u32 len, * Supported only by fabrics discovery controllers, returning discovery * records. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_discovery(int fd, bool rae, __u32 offset, __u32 len, void *log); @@ -1272,8 +1274,8 @@ int nvme_get_log_reservation(int fd, bool rae, * The Sanitize Status log page is used to report sanitize operation time * estimates and information about the most recent sanitize operation. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_sanitize(int fd, bool rae, struct nvme_sanitize_log_page *log); @@ -1292,8 +1294,8 @@ int nvme_get_log_sanitize(int fd, bool rae, * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features(int fd, __u8 fid, __u32 nsid, __u32 cdw11, __u32 cdw12, bool save, __u8 uuidx, __u32 cdw15, __u32 data_len, @@ -1305,8 +1307,8 @@ int nvme_set_features(int fd, __u8 fid, __u32 nsid, __u32 cdw11, __u32 cdw12, * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_arbitration(int fd, __u8 ab, __u8 lpw, __u8 mpw, __u8 hpw, bool save, __u32 *result); @@ -1317,8 +1319,8 @@ int nvme_set_features_arbitration(int fd, __u8 ab, __u8 lpw, __u8 mpw, * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_power_mgmt(int fd, __u8 ps, __u8 wh, bool save, __u32 *result); @@ -1329,8 +1331,8 @@ int nvme_set_features_power_mgmt(int fd, __u8 ps, __u8 wh, bool save, * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_lba_range(int fd, __u32 nsid, __u32 nr_ranges, bool save, struct nvme_lba_range_type *data, __u32 *result); @@ -1350,8 +1352,8 @@ enum nvme_feat_tmpthresh_thsel { * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_temp_thresh(int fd, __u16 tmpth, __u8 tmpsel, enum nvme_feat_tmpthresh_thsel thsel, @@ -1363,8 +1365,8 @@ int nvme_set_features_temp_thresh(int fd, __u16 tmpth, __u8 tmpsel, * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_err_recovery(int fd, __u32 nsid, __u16 tler, bool dulbe, bool save, __u32 *result); @@ -1376,8 +1378,8 @@ int nvme_set_features_err_recovery(int fd, __u32 nsid, __u16 tler, * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_volatile_wc(int fd, bool wce, bool save, __u32 *result); @@ -1388,8 +1390,8 @@ int nvme_set_features_volatile_wc(int fd, bool wce, bool save, * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_irq_coalesce(int fd, __u8 thr, __u8 time, bool save, __u32 *result); @@ -1400,8 +1402,8 @@ int nvme_set_features_irq_coalesce(int fd, __u8 thr, __u8 time, * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_irq_config(int fd, __u16 iv, bool cd, bool save, __u32 *result); @@ -1413,8 +1415,8 @@ int nvme_set_features_irq_config(int fd, __u16 iv, bool cd, bool save, * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_write_atomic(int fd, bool dn, bool save, __u32 *result); @@ -1445,8 +1447,8 @@ enum nvme_features_async_event_config_flags { * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_async_event(int fd, __u32 events, bool save, __u32 *result); @@ -1458,8 +1460,8 @@ int nvme_set_features_async_event(int fd, __u32 events, bool save, * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_auto_pst(int fd, bool apste, bool save, struct nvme_feat_auto_pst *apst, @@ -1471,8 +1473,8 @@ int nvme_set_features_auto_pst(int fd, bool apste, bool save, * @save: Save value across power states * @timestamp: The current timestamp value to assign to this this feature * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_timestamp(int fd, bool save, __u64 timestamp); @@ -1483,8 +1485,8 @@ int nvme_set_features_timestamp(int fd, bool save, __u64 timestamp); * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_hctm(int fd, __u16 tmt2, __u16 tmt1, bool save, __u32 *result); @@ -1500,8 +1502,8 @@ int nvme_set_features_nopsc(int fd, bool noppme, bool save, __u32 *result); * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_rrl(int fd, __u8 rrl, __u16 nvmsetid, bool save, __u32 *result); @@ -1512,8 +1514,8 @@ int nvme_set_features_rrl(int fd, __u8 rrl, __u16 nvmsetid, bool save, * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_plm_config(int fd, bool enable, __u16 nvmsetid, bool save, struct nvme_plm_config *data, @@ -1533,8 +1535,8 @@ enum nvme_feat_plm_window_select { * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_plm_window(int fd, enum nvme_feat_plm_window_select sel, __u16 nvmsetid, bool save, __u32 *result); @@ -1546,8 +1548,8 @@ int nvme_set_features_plm_window(int fd, enum nvme_feat_plm_window_select sel, * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_lba_sts_interval(int fd, __u16 lsiri, __u16 lsipi, bool save, __u32 *result); @@ -1558,8 +1560,8 @@ int nvme_set_features_lba_sts_interval(int fd, __u16 lsiri, __u16 lsipi, * @fd: File descriptor of nvme device * @save: Save value across power states * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_host_behavior(int fd, bool save, struct nvme_feat_host_behavior *data); @@ -1570,8 +1572,8 @@ int nvme_set_features_host_behavior(int fd, bool save, * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_sanitize(int fd, bool nodrm, bool save, __u32 *result); @@ -1583,8 +1585,8 @@ int nvme_set_features_sanitize(int fd, bool nodrm, bool save, __u32 *result); * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_endurance_evt_cfg(int fd, __u16 endgid, __u8 egwarn, bool save, __u32 *result); @@ -1595,8 +1597,8 @@ int nvme_set_features_endurance_evt_cfg(int fd, __u16 endgid, __u8 egwarn, * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_sw_progress(int fd, __u8 pbslc, bool save, __u32 *result); @@ -1608,8 +1610,8 @@ int nvme_set_features_sw_progress(int fd, __u8 pbslc, bool save, * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_host_id(int fd, bool exhid, bool save, __u8 *hostid); @@ -1628,8 +1630,8 @@ enum nvme_feat_resv_notify_flags { * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_resv_mask(int fd, __u32 mask, bool save, __u32 *result); @@ -1639,8 +1641,8 @@ int nvme_set_features_resv_mask(int fd, __u32 mask, bool save, __u32 *result); * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_resv_persist(int fd, bool ptpl, bool save, __u32 *result); @@ -1664,8 +1666,8 @@ enum nvme_feat_nswpcfg_state { * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_write_protect(int fd, enum nvme_feat_nswpcfg_state state, bool save, __u32 *result); @@ -1673,7 +1675,7 @@ int nvme_set_features_write_protect(int fd, enum nvme_feat_nswpcfg_state state, /** * nvme_get_features() - Retrieve a feature attribute * @fd: File descriptor of nvme device - * @fid: Feature identifier + * @fid: Feature identifier, see &enum nvme_features_id * @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 @@ -1682,8 +1684,8 @@ int nvme_set_features_write_protect(int fd, enum nvme_feat_nswpcfg_state state, * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features(int fd, enum nvme_features_id fid, __u32 nsid, enum nvme_get_features_sel sel, __u32 cdw11, __u8 uuidx, @@ -1695,8 +1697,8 @@ int nvme_get_features(int fd, enum nvme_features_id fid, __u32 nsid, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_arbitration(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1707,8 +1709,8 @@ int nvme_get_features_arbitration(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_power_mgmt(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1719,8 +1721,8 @@ int nvme_get_features_power_mgmt(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_lba_range(int fd, enum nvme_get_features_sel sel, struct nvme_lba_range_type *data, @@ -1732,8 +1734,8 @@ int nvme_get_features_lba_range(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_temp_thresh(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1744,8 +1746,8 @@ int nvme_get_features_temp_thresh(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_err_recovery(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1756,8 +1758,8 @@ int nvme_get_features_err_recovery(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_volatile_wc(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1768,8 +1770,8 @@ int nvme_get_features_volatile_wc(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_num_queues(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1780,8 +1782,8 @@ int nvme_get_features_num_queues(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_irq_coalesce(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1792,8 +1794,8 @@ int nvme_get_features_irq_coalesce(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_irq_config(int fd, enum nvme_get_features_sel sel, __u16 iv, __u32 *result); @@ -1804,8 +1806,8 @@ int nvme_get_features_irq_config(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_write_atomic(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1816,8 +1818,8 @@ int nvme_get_features_write_atomic(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_async_event(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1828,8 +1830,8 @@ int nvme_get_features_async_event(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_auto_pst(int fd, enum nvme_get_features_sel sel, struct nvme_feat_auto_pst *apst, __u32 *result); @@ -1840,8 +1842,8 @@ int nvme_get_features_auto_pst(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_host_mem_buf(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1852,8 +1854,8 @@ int nvme_get_features_host_mem_buf(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_timestamp(int fd, enum nvme_get_features_sel sel, struct nvme_timestamp *ts); @@ -1864,8 +1866,8 @@ int nvme_get_features_timestamp(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_kato(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1875,8 +1877,8 @@ int nvme_get_features_kato(int fd, enum nvme_get_features_sel sel, __u32 *result * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_hctm(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1886,8 +1888,8 @@ int nvme_get_features_hctm(int fd, enum nvme_get_features_sel sel, __u32 *result * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_nopsc(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1897,8 +1899,8 @@ int nvme_get_features_nopsc(int fd, enum nvme_get_features_sel sel, __u32 *resul * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_rrl(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1908,8 +1910,8 @@ int nvme_get_features_rrl(int fd, enum nvme_get_features_sel sel, __u32 *result) * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_plm_config(int fd, enum nvme_get_features_sel sel, __u16 nvmsetid, struct nvme_plm_config *data, @@ -1921,8 +1923,8 @@ int nvme_get_features_plm_config(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_plm_window(int fd, enum nvme_get_features_sel sel, __u16 nvmsetid, __u32 *result); @@ -1933,8 +1935,8 @@ int nvme_get_features_plm_window(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_lba_sts_interval(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1945,8 +1947,8 @@ int nvme_get_features_lba_sts_interval(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_host_behavior(int fd, enum nvme_get_features_sel sel, struct nvme_feat_host_behavior *data, @@ -1958,8 +1960,8 @@ int nvme_get_features_host_behavior(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_sanitize(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1970,8 +1972,8 @@ int nvme_get_features_sanitize(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_endurance_event_cfg(int fd, enum nvme_get_features_sel sel, __u16 endgid, __u32 *result); @@ -1982,8 +1984,8 @@ int nvme_get_features_endurance_event_cfg(int fd, enum nvme_get_features_sel sel * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_sw_progress(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1994,8 +1996,8 @@ int nvme_get_features_sw_progress(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_host_id(int fd, enum nvme_get_features_sel sel, bool exhid, __u32 len, __u8 *hostid); @@ -2006,8 +2008,8 @@ int nvme_get_features_host_id(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_resv_mask(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -2018,8 +2020,8 @@ int nvme_get_features_resv_mask(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_resv_persist(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -2031,8 +2033,8 @@ int nvme_get_features_resv_persist(int fd, enum nvme_get_features_sel sel, * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel * @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. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_write_protect(int fd, __u32 nsid, enum nvme_get_features_sel sel, @@ -2056,8 +2058,8 @@ int nvme_get_features_write_protect(int fd, __u32 nsid, * size. A low level format may destroy all data and metadata associated with * all namespaces or only the specific namespace associated with the command * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_format_nvm(int fd, __u32 nsid, __u8 lbaf, enum nvme_cmd_format_mset mset, @@ -2085,8 +2087,8 @@ int nvme_ns_mgmt(int fd, __u32 nsid, enum nvme_ns_mgmt_sel sel, * attached to any controller. Use the nvme_ns_attach_ctrls() to assign the * namespace to one or more controllers. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * 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_create(int fd, struct nvme_id_ns *ns, __u32 *nsid, __u32 timeout); @@ -2100,8 +2102,8 @@ int nvme_ns_mgmt_create(int fd, struct nvme_id_ns *ns, __u32 *nsid, * controller. Use the nvme_ns_detach_ctrls() first if the namespace is still * attached. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * 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_delete(int fd, __u32 nsid); @@ -2152,8 +2154,8 @@ int nvme_ns_detach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist); * Download command. Use the nvme_fw_commit() to activate a newly downloaded * image. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_fw_download(int fd, __u32 offset, __u32 data_len, void *data); @@ -2167,8 +2169,9 @@ int nvme_fw_download(int fd, __u32 offset, __u32 data_len, void *data); * The Firmware Commit command is used to modify the firmware image or Boot * Partitions. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. The command status + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. The command + * status * response may specify additional * reset actions required to complete the commit process. */ @@ -2196,8 +2199,8 @@ int nvme_fw_commit(int fd, __u8 slot, enum nvme_fw_commit_ca action, bool bpid); * The security data is protocol specific and is not defined by the NVMe * specification. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_security_send(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, __u8 secp, __u32 tl, __u32 data_len, void *data, @@ -2216,8 +2219,8 @@ int nvme_security_send(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, * @data: Security data payload to send * @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. + * 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(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, __u8 secp, __u32 al, __u32 data_len, @@ -2237,8 +2240,8 @@ int nvme_security_receive(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, * The Get LBA Status command requests information about Potentially * Unrecoverable LBAs. Refer to the specification for action type descriptions. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_lba_status(int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl, enum nvme_lba_status_atype atype, @@ -2262,8 +2265,8 @@ int nvme_get_lba_status(int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl, * * See the NVMe specification for more information. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_directive_send(int fd, __u32 nsid, __u16 dspec, enum nvme_directive_send_doper doper, @@ -2275,8 +2278,8 @@ int nvme_directive_send(int fd, __u32 nsid, __u16 dspec, * @fd: File descriptor of nvme device * @nsid: Namespace ID * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_directive_send_id_endir(int fd, __u32 nsid, bool endir, enum nvme_directive_dtype dtype, @@ -2287,8 +2290,8 @@ int nvme_directive_send_id_endir(int fd, __u32 nsid, bool endir, * @fd: File descriptor of nvme device * @nsid: Namespace ID * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_directive_send_stream_release_identifier(int fd, __u32 nsid, __u16 stream_id); @@ -2298,8 +2301,8 @@ int nvme_directive_send_stream_release_identifier(int fd, __u32 nsid, * @fd: File descriptor of nvme device * @nsid: Namespace ID * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_directive_send_stream_release_resource(int fd, __u32 nsid); @@ -2315,8 +2318,8 @@ int nvme_directive_send_stream_release_resource(int fd, __u32 nsid); * @data: Usespace address of data payload in bytes * @result: If successful, the CQE dword0 value * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_directive_recv(int fd, __u32 nsid, __u16 dspec, enum nvme_directive_receive_doper doper, @@ -2328,8 +2331,8 @@ int nvme_directive_recv(int fd, __u32 nsid, __u16 dspec, * @fd: File descriptor of nvme device * @nsid: Namespace ID * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_directive_recv_identify_parameters(int fd, __u32 nsid, struct nvme_id_directives *id); @@ -2339,8 +2342,8 @@ int nvme_directive_recv_identify_parameters(int fd, __u32 nsid, * @fd: File descriptor of nvme device * @nsid: Namespace ID * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_directive_recv_stream_parameters(int fd, __u32 nsid, struct nvme_streams_directive_params *parms); @@ -2350,8 +2353,8 @@ int nvme_directive_recv_stream_parameters(int fd, __u32 nsid, * @fd: File descriptor of nvme device * @nsid: Namespace ID * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_directive_recv_stream_status(int fd, __u32 nsid, unsigned nr_entries, struct nvme_streams_directive_status *id); @@ -2361,8 +2364,8 @@ int nvme_directive_recv_stream_status(int fd, __u32 nsid, unsigned nr_entries, * @fd: File descriptor of nvme device * @nsid: Namespace ID * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_directive_recv_stream_allocate(int fd, __u32 nsid, __u16 nsr, __u32 *result); @@ -2394,8 +2397,8 @@ enum nvme_fctype { * This is an NVMe-over-Fabrics specific command, not applicable to PCIe. These * properties align to the PCI MMIO controller registers. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_property(int fd, int offset, __u64 value); @@ -2408,8 +2411,8 @@ int nvme_set_property(int fd, int offset, __u64 value); * This is an NVMe-over-Fabrics specific command, not applicable to PCIe. These * properties align to the PCI MMIO controller registers. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_property(int fd, int offset, __u64 *value); @@ -2433,8 +2436,8 @@ int nvme_get_property(int fd, int offset, __u64 *value); * sanitize operations are processed in the background, i.e., completion of the * sanitize command does not indicate completion of the sanitize operation. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_sanitize_nvm(int fd, enum nvme_sanitize_sanact sanact, bool ause, __u8 owpass, bool oipbp, bool nodas, __u32 ovrpat); @@ -2456,8 +2459,8 @@ int nvme_sanitize_nvm(int fd, enum nvme_sanitize_sanact sanact, bool ause, * 0xffffffff to test all namespaces. All other values tests a specific * namespace, if present. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_dev_self_test(int fd, __u32 nsid, enum nvme_dst_stc stc); @@ -2478,8 +2481,8 @@ int nvme_dev_self_test(int fd, __u32 nsid, enum nvme_dst_stc stc); * - Assigning Flexible Resources for secondary controllers * - Setting the Online and Offline state for secondary controllers * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_virtual_mgmt(int fd, enum nvme_virt_mgmt_act act, enum nvme_virt_mgmt_rt rt, __u16 cntlid, __u16 nr, @@ -2523,8 +2526,8 @@ enum nvme_io_opcode { * The Flush command is used to request that the contents of volatile write * cache be made non-volatile. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_flush(int fd, __u32 nsid); @@ -2608,8 +2611,8 @@ enum nvme_io_dsm_flags { * metadata_len:Length of user buffer, @metadata, in bytes * @metadata: Pointer to user address of the metadata buffer * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_read(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u8 dsm, __u32 reftag, __u16 apptag, __u16 appmask, @@ -2638,8 +2641,8 @@ int nvme_read(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, * metadata_len:Length of user buffer, @metadata, in bytes * @metadata: Pointer to user address of the metadata buffer * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_write(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u8 dsm, __u16 dspec, __u32 reftag, __u16 apptag, @@ -2667,8 +2670,8 @@ int nvme_write(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, * metadata_len:Length of user buffer, @metadata, in bytes * @metadata: Pointer to user address of the metadata buffer * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_compare(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 reftag, __u16 apptag, __u16 appmask, __u32 data_len, @@ -2696,8 +2699,8 @@ int nvme_compare(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, * subsequent reads of logical blocks in this range shall be all bytes cleared * to 0h until a write occurs to this LBA range. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_write_zeros(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 reftag, __u16 apptag, __u16 appmask); @@ -2715,8 +2718,8 @@ int nvme_write_zeros(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, * invalid logical block status, a write operation on those logical blocks is * required. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_write_uncorrectable(int fd, __u32 nsid, __u64 slba, __u16 nlb); @@ -2741,8 +2744,8 @@ int nvme_write_uncorrectable(int fd, __u32 nsid, __u64 slba, __u16 nlb); * and metadata, if applicable, for the LBAs indicated without transferring any * data or metadata to the host. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_verify(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 reftag, __u16 apptag, __u16 appmask); @@ -2773,8 +2776,8 @@ enum nvme_dsm_attributes { * to optimize performance and reliability, and may be used to * deallocate/unmap/trim those logical blocks. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_dsm(int fd, __u32 nsid, __u32 attrs, __u16 nr_ranges, struct nvme_dsm_range *dsm); @@ -2824,8 +2827,8 @@ enum nvme_reservation_racqa { * namespace, preempt a reservation held on a namespace, and abort a * reservation held on a namespace. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_resv_acquire(int fd, __u32 nsid, enum nvme_reservation_rtype rtype, enum nvme_reservation_racqa racqa, bool iekey, @@ -2869,8 +2872,8 @@ enum nvme_reservation_cptpl { * The Reservation Register command is used to register, unregister, or replace * a reservation key. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_resv_register(int fd, __u32 nsid, enum nvme_reservation_rrega rrega, enum nvme_reservation_cptpl cptpl, bool iekey, @@ -2895,8 +2898,8 @@ enum nvme_reservation_rrela { * @iekey: Set to ignore the existing key * @crkey: The current reservation key to release * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_resv_release(int fd, __u32 nsid, enum nvme_reservation_rtype rtype, enum nvme_reservation_rrela rrela, bool iekey, @@ -2914,8 +2917,8 @@ int nvme_resv_release(int fd, __u32 nsid, enum nvme_reservation_rtype rtype, * registration and reservation status of a namespace. See the defintion for * the returned structure, &struct nvme_reservation_status, for more details. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum */ int nvme_resv_report(int fd, __u32 nsid, bool eds, __u32 len, struct nvme_reservation_status *report); diff --git a/src/nvme/types.h b/src/nvme/types.h index 75a220d118..98eda65886 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -2330,7 +2330,7 @@ struct nvme_resv_notification_log { * @NVME_RESV_NOTIFY_RNLPT_RESERVATION_RELEASED: * @NVME_RESV_NOTIFY_RNLPT_RESERVATION_PREEMPTED: */ -enum nvme_resv_notify_rnlpt {{ +enum nvme_resv_notify_rnlpt { NVME_RESV_NOTIFY_RNLPT_EMPTY = 0, NVME_RESV_NOTIFY_RNLPT_REGISTRATION_PREEMPTED = 1, NVME_RESV_NOTIFY_RNLPT_RESERVATION_RELEASED = 2, diff --git a/src/nvme/util.h b/src/nvme/util.h index c980322504..62298c0af2 100644 --- a/src/nvme/util.h +++ b/src/nvme/util.h @@ -29,8 +29,8 @@ __u8 nvme_status_to_errno(int status, bool fabrics); * @offset: Starting offset to send with this firmware downlaod * @buf: Address of buffer containing all or part of the firmware image. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_fw_download_seq(int fd, __u32 size, __u32 xfer, __u32 offset, void *buf); @@ -44,8 +44,8 @@ int nvme_fw_download_seq(int fd, __u32 size, __u32 xfer, __u32 offset, * The total size allocated can be calculated as: * (&struct nvme_telemetry_log.dalb3 + 1) * %NVME_LOG_TELEM_BLOCK_SIZE. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_ctrl_telemetry(int fd, bool rae, struct nvme_telemetry_log **log); @@ -57,8 +57,8 @@ int nvme_get_ctrl_telemetry(int fd, bool rae, struct nvme_telemetry_log **log); * The total size allocated can be calculated as: * (&struct nvme_telemetry_log.dalb3 + 1) * %NVME_LOG_TELEM_BLOCK_SIZE. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_host_telemetry(int fd, struct nvme_telemetry_log **log); @@ -70,8 +70,8 @@ int nvme_get_host_telemetry(int fd, struct nvme_telemetry_log **log); * The total size allocated can be calculated as: * (&struct nvme_telemetry_log.dalb3 + 1) * %NVME_LOG_TELEM_BLOCK_SIZE. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_new_host_telemetry(int fd, struct nvme_telemetry_log **log); @@ -131,8 +131,8 @@ void nvme_init_dsm_range(struct nvme_dsm_range *dsm, __u32 *ctx_attrs, * @data_len: Total length of the log to transfer. * @data: User address of at least &data_len to store the log. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int __nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, __u32 xfer_len, __u32 data_len, void *data); @@ -149,8 +149,8 @@ int __nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, * Calls __nvme_get_log_page() with a default 4k transfer length, as that is * guarnateed by the protocol to be a safe transfer size. * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, __u32 data_len, void *data); @@ -160,8 +160,8 @@ int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, * @fd: File descriptor of nvme device * @analen: Pointer to where the length will be set on success * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_ana_log_len(int fd, size_t *analen); @@ -172,8 +172,8 @@ int nvme_get_ana_log_len(int fd, size_t *analen); * @num_ctrls: Number of controllers in ctrlist * @ctrlist: List of controller IDs to perform the attach action * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_namespace_attach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist); @@ -184,8 +184,8 @@ int nvme_namespace_attach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrl * @num_ctrls: Number of controllers in ctrlist * @ctrlist: List of controller IDs to perform the detach action * - * Return: The nvme command status if a response was received (see &enum - * nvme_status_field) or -1 with errno set otherwise. + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_namespace_detach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist); From 67b83776315efaff096a77a9ff2ba1c14051f7b2 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Sat, 15 Feb 2020 11:53:38 -0800 Subject: [PATCH 0037/1564] Fix install make targets The makefile needs to be updated to reflect the current layout after shuffling some things around, Signed-off-by: Keith Busch --- .gitignore | 2 ++ Makefile | 17 ++++++++++------- src/Makefile | 20 +++----------------- 3 files changed, 15 insertions(+), 24 deletions(-) diff --git a/.gitignore b/.gitignore index 37f41682a9..c874c37600 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,8 @@ a.out *.a *.so.* +libnvme.pc + test/test test/cpp diff --git a/Makefile b/Makefile index 32bc5afca1..030f9abf05 100644 --- a/Makefile +++ b/Makefile @@ -31,19 +31,22 @@ ifneq ($(MAKECMDGOALS),clean) include config-host.mak endif +SED_PROCESS = \ + $(SED) -e "s%@prefix@%$(prefix)%g" \ + -e "s%@libdir@%$(libdir)%g" \ + -e "s%@includedir@%$(includedir)%g" \ + -e "s%@NAME@%$(NAME)%g" \ + -e "s%@VERSION@%$(VERSION)%g" \ + $< >$@ + %.pc: %.pc.in config-host.mak $(SPECFILE) - sed -e "s%@prefix@%$(prefix)%g" \ - -e "s%@libdir@%$(libdir)%g" \ - -e "s%@includedir@%$(includedir)%g" \ - -e "s%@NAME@%$(NAME)%g" \ - -e "s%@VERSION@%$(VERSION)%g" \ - $< >$@ + $(SED_PROCESS) install: $(NAME).pc @$(MAKE) -C src install prefix=$(DESTDIR)$(prefix) includedir=$(DESTDIR)$(includedir) libdir=$(DESTDIR)$(libdir) $(INSTALL) -D -m 644 $(NAME).pc $(DESTDIR)$(libdir)/pkgconfig/$(NAME).pc $(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man2 - $(INSTALL) -m 644 man/*.2 $(DESTDIR)$(mandir)/man2 + $(INSTALL) -m 644 doc/man/*.2 $(DESTDIR)$(mandir)/man2 install-tests: @$(MAKE) -C test install prefix=$(DESTDIR)$(prefix) datadir=$(DESTDIR)$(datadir) diff --git a/src/Makefile b/src/Makefile index 541a8167fc..2434f17ccb 100644 --- a/src/Makefile +++ b/src/Makefile @@ -24,17 +24,6 @@ micro=1 libname=$(soname).$(minor).$(micro) all_targets += $(NAME).a -SED_PROCESS = \ - $(SED) -e "s%@prefix@%$(prefix)%g" \ - -e "s%@libdir@%$(libdir)%g" \ - -e "s%@includedir@%$(includedir)%g" \ - -e "s%@NAME@%$(NAME)%g" \ - -e "s%@VERSION@%$(VERSION)%g" \ - $< >$@ - -%.pc: %.pc.in Makefile - $(SED_PROCESS) - ifeq ($(ENABLE_SHARED),1) all_targets += $(libname) endif @@ -77,12 +66,9 @@ libnvme.a: $(libnvme_objs) $(libccan_objs) $(libname): $(libnvme_sobjs) $(libccan_sobjs) libnvme.map $(QUIET_CC)$(CC) $(SO_CFLAGS) -Wl,--version-script=libnvme.map -Wl,-soname=$(soname) -o $@ $(libnvme_sobjs) $(libccan_sobjs) $(LINK_FLAGS) -install: $(all_targets) $(NAME).pc - for i in $(libnvme_api); do \ - $(INSTALL) -D -m 644 ${i} $(includedir)/${i} - done +install: $(all_targets) $(INSTALL) -D -m 644 libnvme.a $(libdir)/libnvme.a - $(INSTALL) -D -m 644 $(NAME).pc $(DESTDIR)$(libdir)/pkgconfig/$(NAME).pc + for i in $(libnvme_api); do $(INSTALL) -D -m 644 $$i $(includedir)/$$i; done ifeq ($(ENABLE_SHARED),1) $(INSTALL) -D -m 755 $(libname) $(libdir)/$(libname) ln -sf $(libname) $(libdir)/$(soname) @@ -93,7 +79,7 @@ $(libnvme_objs): $(libnvme_api) $(libnvme_private) $(libccan_objs): $(libccan_headers) $(CCANDIR)config.h clean: - rm -f $(all_targets) $(libnvme_objs) $(libnvme_sobjs) $(libccan_objs) $(libccan_sobjs) $(soname).new $(NAME).pc + rm -f $(all_targets) $(libnvme_objs) $(libnvme_sobjs) $(libccan_objs) $(libccan_sobjs) $(soname).new rm -f $(CCANDIR)config.h rm -f $(CCANDIR)tools/configurator/configurator rm -f *.so* *.a *.o From dac8cc72072388bd56ad12b1d9613657aef1e87a Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Mon, 17 Feb 2020 13:01:07 -0800 Subject: [PATCH 0038/1564] Fix status code mask Signed-off-by: Keith Busch --- src/nvme/types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nvme/types.h b/src/nvme/types.h index 98eda65886..2ff2812059 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -3893,7 +3893,7 @@ static inline __u16 nvme_status_code_type(__u16 status_field) */ static inline __u16 nvme_status_code(__u16 status_field) { - return status_field & NVME_SCT_MASK; + return status_field & NVME_SC_MASK; } #define NVME_MAJOR(ver) ((ver) >> 16) From 13bba202c167c804134586a271084547fe60a1c8 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Tue, 18 Feb 2020 14:33:01 -0800 Subject: [PATCH 0039/1564] Typo fixes Signed-off-by: Keith Busch --- src/nvme/types.h | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/nvme/types.h b/src/nvme/types.h index 2ff2812059..fb22071efd 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -1935,7 +1935,7 @@ struct nvme_st_result { * @NVME_ST_RESULT_ABORTED_UNKNOWN: * @NVME_ST_RESULT_ABORTED_SANITIZE: * @NVME_ST_RESULT_NOT_USED: - * @NVME_ST_RESULT_NOT_MASK: + * @NVME_ST_RESULT_MASK: */ enum { NVME_ST_RESULT_NO_ERR = 0x0, @@ -1949,7 +1949,7 @@ enum { NVME_ST_RESULT_ABORTED_UNKNOWN = 0x8, NVME_ST_RESULT_ABORTED_SANITIZE = 0x9, NVME_ST_RESULT_NOT_USED = 0xf, - NVME_ST_RESULT_NOT_MASK = 0xf, + NVME_ST_RESULT_MASK = 0xf, }; /** @@ -2412,12 +2412,22 @@ struct nvme_lba_status { /** * struct nvme_feat_auto_pst - - * @apst_entry: + * @apst_entry: See &enum nvme_apst_entry */ struct nvme_feat_auto_pst { __le64 apst_entry[32]; }; +/** + * enum nvme_apst_entry - + */ +enum nvme_apst_entry { + NVME_APST_ENTRY_ITPS_MASK = 0xf8, + NVME_APST_ENTRY_ITPS_SHIFT = 3, + NVME_APST_ENTRY_ITPT_MASK = 0xffffff00, + NVME_APST_ENTRY_ITPT_SHIFT = 8, +}; + /** * struct nvme_timestamp - * timestamp: @@ -2985,7 +2995,7 @@ struct nvmf_discovery_log { __le64 numrec; __le16 recfmt; __u8 rsvd14[1006]; - struct nvmf_disc_log_entry entries[0]; + struct nvmf_disc_log_entry entries[]; }; /** @@ -3617,7 +3627,8 @@ struct nvme_mi_vpd_hdr { * 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 + * 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 From 0d6fed7ac54d254580ba45796fad49f41986fd41 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Sat, 22 Feb 2020 14:08:21 -0800 Subject: [PATCH 0040/1564] Move feature field decoding to utilitiies Export a more coder friendly way to decode complex status fields than the mask+shift macros. Signed-off-by: Keith Busch --- src/nvme/ioctl.h | 4 +- src/nvme/types.h | 108 ------------------ src/nvme/util.c | 283 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 285 insertions(+), 110 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 838d15ce75..57ff36c4e4 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -550,8 +550,8 @@ enum nvme_features_id { NVME_FEAT_FID_HOST_MEM_BUF = 0x0d, NVME_FEAT_FID_TIMESTAMP = 0x0e, NVME_FEAT_FID_KATO = 0x0f, - NVME_FEAT_FID_HCTM = 0X10, - NVME_FEAT_FID_NOPSC = 0X11, + NVME_FEAT_FID_HCTM = 0x10, + NVME_FEAT_FID_NOPSC = 0x11, NVME_FEAT_FID_RRL = 0x12, NVME_FEAT_FID_PLM_CONFIG = 0x13, NVME_FEAT_FID_PLM_WINDOW = 0x14, diff --git a/src/nvme/types.h b/src/nvme/types.h index fb22071efd..1039a87628 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -2586,114 +2586,6 @@ struct nvme_reservation_status { }; }; -enum { - NVME_FEAT_ARB_BURST_MASK = 0x00000007, - NVME_FEAT_ARB_LPW_MASK = 0x0000ff00, - NVME_FEAT_ARB_MPW_MASK = 0x00ff0000, - NVME_FEAT_ARB_HPW_MASK = 0xff000000, - NVME_FEAT_PM_PS_MASK = 0x0000001f, - NVME_FEAT_PM_WH_MASK = 0x000000e0, - NVME_FEAT_LBAR_NR_MASK = 0x0000003f, - NVME_FEAT_TT_TMPTH_MASK = 0x0000ffff, - NVME_FEAT_TT_TMPSEL_MASK = 0x000f0000, - NVME_FEAT_TT_THSEL_MASK = 0x00300000, - NVME_FEAT_ER_TLER_MASK = 0x0000ffff, - NVME_FEAT_ER_DULBE_MASK = 0x00010000, - NVME_FEAT_VWC_WCE_MASK = 0x00000001, - NVME_FEAT_NRQS_NSQR_MASK = 0x0000ffff, - NVME_FEAT_NRQS_NCQR_MASK = 0xffff0000, - NVME_FEAT_ICOAL_THR_MASK = 0x000000ff, - NVME_FEAT_ICOAL_TIME_MASK = 0x0000ff00, - NVME_FEAT_ICFG_IV_MASK = 0x0000ffff, - NVME_FEAT_ICFG_CD_MASK = 0x00010000, - NVME_FEAT_WA_DN_MASK = 0x00000001, - NVME_FEAT_AE_SMART_MASK = 0x000000ff, - NVME_FEAT_AE_NAN_MASK = 0x00000100, - NVME_FEAT_AE_FW_MASK = 0x00000200, - NVME_FEAT_AE_TELEM_MASK = 0x00000400, - NVME_FEAT_AE_ANA_MASK = 0x00000800, - NVME_FEAT_AE_PLA_MASK = 0x00001000, - NVME_FEAT_AE_LBAS_MASK = 0x00002000, - NVME_FEAT_AE_EGA_MASK = 0x00004000, - NVME_FEAT_APST_APSTE_MASK = 0x00000001, - NVME_FEAT_HMEM_EHM_MASK = 0x00000001, - NVME_FEAT_TS_SYNCH_MASK = 0x00000001, - NVME_FEAT_TS_ORIGIN_MASK = 0x0000000e, - NVME_FEAT_TS_ORIGIN_CLR = 0x00000001, - NVME_FEAT_TS_ORIGIN_SF = 0x00000002, - NVME_FEAT_HCTM_TMT2_MASK = 0x0000ffff, - NVME_FEAT_HCTM_TMT1_MASK = 0xffff0000, - NVME_FEAT_NOPS_NOPPME_MASK = 0x00000001, - NVME_FEAT_RRL_RRL_MASK = 0x000000ff, - NVME_FEAT_PLM_PLME_MASK = 0x00000001, - NVME_FEAT_PLMW_WS_MASK = 0x00000007, - NVME_FEAT_LBAS_LSIRI_MASK = 0x0000ffff, - NVME_FEAT_LBAS_LSIPI_MASK = 0xffff0000, - NVME_FEAT_SC_NODRM_MASK = 0x00000001, - NVME_FEAT_EG_ENDGID_MASK = 0x0000ffff, - NVME_FEAT_EG_EGCW_MASK = 0x00ff0000, - NVME_FEAT_SPM_PBSLC_MASK = 0x000000ff, - NVME_FEAT_HOSTID_EXHID_MASK = 0x00000001, - NVME_FEAT_RM_REGPRE_MASK = 0x00000002, - NVME_FEAT_RM_RESREL_MASK = 0x00000004, - NVME_FEAT_RM_RESPRE_MASK = 0x00000008, - NVME_FEAT_RP_PTPL_MASK = 0x00000001, - NVME_FEAT_WP_WPS_MASK = 0x00000007, -}; - -#define shift(v, s, m) ((v & m) >> s) - -#define NVME_FEAT_ARB_BURST(v) shift(v, 0, NVME_FEAT_ARB_BURST_MASK) -#define NVME_FEAT_ARB_LPW(v) shift(v, 8, NVME_FEAT_ARB_LPW_MASK) -#define NVME_FEAT_ARB_MPW(v) shift(v, 16, NVME_FEAT_ARB_MPW_MASK) -#define NVME_FEAT_ARB_HPW(v) shift(v, 24, NVME_FEAT_ARB_HPW_MASK) -#define NVME_FEAT_PM_PS(v) shift(v, 0, NVME_FEAT_PM_PS_MASK) -#define NVME_FEAT_PM_WH(v) shift(v, 5, NVME_FEAT_PM_WH_MASK) -#define NVME_FEAT_LBAR_NR(v) shift(v, 0, NVME_FEAT_LBAR_NR_MASK) -#define NVME_FEAT_TT_TMPTH(v) shift(v, 0, NVME_FEAT_TT_TMPTH_MASK) -#define NVME_FEAT_TT_TMPSEL(v) shift(v, 16, NVME_FEAT_TT_TMPSEL_MASK) -#define NVME_FEAT_TT_THSEL(v) shift(v, 20, NVME_FEAT_TT_THSEL_MASK) -#define NVME_FEAT_ER_TLER(v) shift(v, 0, NVME_FEAT_ER_TLER_MASK) -#define NVME_FEAT_ER_DULBE(v) shift(v, 16, NVME_FEAT_ER_DULBE_MASK) -#define NVME_FEAT_VWC_WCE(v) shift(v, 0, NVME_FEAT_VWC_WCE_MASK) -#define NVME_FEAT_NRQS_NSQR(v) shift(v, 0, NVME_FEAT_NRQS_NSQR_MASK) -#define NVME_FEAT_NRQS_NCQR(v) shift(v, 16, NVME_FEAT_NRQS_NCQR_MASK) -#define NVME_FEAT_ICOAL_THR(v) shift(v, 0, NVME_FEAT_ICOAL_THR_MASK) -#define NVME_FEAT_ICOAL_TIME(v) shift(v, 8, NVME_FEAT_ICOAL_TIME_MASK) -#define NVME_FEAT_ICFG_IV(v) shift(v, 0, NVME_FEAT_ICFG_IV_MASK) -#define NVME_FEAT_ICFG_CD(v) shift(v, 16, NVME_FEAT_ICFG_CD_MASK) -#define NVME_FEAT_WA_DN(v) shift(v, 0, NVME_FEAT_WA_DN_MASK) -#define NVME_FEAT_AE_SMART(v) shift(v, 0, NVME_FEAT_AE_SMART_MASK) -#define NVME_FEAT_AE_NAN(v) shift(v, 8, NVME_FEAT_AE_NAN_MASK) -#define NVME_FEAT_AE_FW(v) shift(v, 9, NVME_FEAT_AE_FW_MASK) -#define NVME_FEAT_AE_TELEM(v) shift(v, 10, NVME_FEAT_AE_TELEM_MASK) -#define NVME_FEAT_AE_ANA(v) shift(v, 11, NVME_FEAT_AE_ANA_MASK) -#define NVME_FEAT_AE_PLA(v) shift(v, 12, NVME_FEAT_AE_PLA_MASK) -#define NVME_FEAT_AE_LBAS(v) shift(v, 13, NVME_FEAT_AE_LBAS_MASK) -#define NVME_FEAT_AE_EGA(v) shift(v, 14, NVME_FEAT_AE_EGA_MASK) -#define NVME_FEAT_APST_APSTE(v) shift(v, 0, NVME_FEAT_APST_APSTE_MASK) -#define NVME_FEAT_HMEM_EHM(v) shift(v, 0, NVME_FEAT_HMEM_EHM_MASK) -#define NVME_FEAT_TS_SYNC(v) shift(v, 0, NVME_FEAT_TS_SYNCH_MASK) -#define NVME_FEAT_TS_ORIGIN(v) shift(v, 1, NVME_FEAT_TS_ORIGIN_MASK) -#define NVME_FEAT_HCTM_TMT2(v) shift(v, 0, NVME_FEAT_HCTM_TMT2_MASK) -#define NVME_FEAT_HCTM_TMT1(v) shift(v, 16, NVME_FEAT_HCTM_TMT1_MASK) -#define NVME_FEAT_NOPS_NOPPME(v) shift(v, 0, NVME_FEAT_NOPS_NOPPME_MASK) -#define NVME_FEAT_RRL_RRL(v) shift(v, 0, NVME_FEAT_RRL_RRL_MASK) -#define NVME_FEAT_PLM_PLME(v) shift(v, 0, NVME_FEAT_PLM_PLME_MASK) -#define NVME_FEAT_PLMW_WS(v) shift(v, 0, NVME_FEAT_PLMW_WS_MASK) -#define NVME_FEAT_LBAS_LSIRI(v) shift(v, 0, NVME_FEAT_LBAS_LSIRI_MASK) -#define NVME_FEAT_LBAS_LSIPI(v) shift(v, 16, NVME_FEAT_LBAS_LSIPI_MASK) -#define NVME_FEAT_SC_NODRM(v) shift(v, 0, NVME_FEAT_SC_NODRM_MASK) -#define NVME_FEAT_EG_ENDGID(v) shift(v, 0, NVME_FEAT_EG_ENDGID_MASK) -#define NVME_FEAT_EG_EGCW(v) shift(v, 16, NVME_FEAT_EG_EGCW_MASK) -#define NVME_FEAT_SPM_PBSLC(v) shift(v, 0, NVME_FEAT_SPM_PBSLC_MASK) -#define NVME_FEAT_HOSTID_EXHID(v) shift(v, 0, NVME_FEAT_HOSTID_EXHID_MASK) -#define NVME_FEAT_RM_REGPRE(v) shift(v, 1, NVME_FEAT_RM_REGPRE_MASK) -#define NVME_FEAT_RM_RESREL(v) shift(v, 2, NVME_FEAT_RM_RESREL_MASK) -#define NVME_FEAT_RM_RESPRE(v) shift(v, 3, NVME_FEAT_RM_RESPRE_MASK) -#define NVME_FEAT_RP_PTPL(v) shift(v, 0, NVME_FEAT_RP_PTPL_MASK) -#define NVME_FEAT_WP_WPS(v) shift(v, 0, NVME_FEAT_WP_WPS_MASK) - /** * struct nvme_streams_directive_params - */ diff --git a/src/nvme/util.c b/src/nvme/util.c index 8461e6a3ae..90e990256f 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -588,3 +588,286 @@ char *nvme_get_path_attr(nvme_path_t p, const char *attr) { return nvme_get_attr(nvme_path_get_sysfs_dir(p), attr); } + +enum { + NVME_FEAT_ARB_BURST_MASK = 0x00000007, + NVME_FEAT_ARB_LPW_MASK = 0x0000ff00, + NVME_FEAT_ARB_MPW_MASK = 0x00ff0000, + NVME_FEAT_ARB_HPW_MASK = 0xff000000, + NVME_FEAT_PM_PS_MASK = 0x0000001f, + NVME_FEAT_PM_WH_MASK = 0x000000e0, + NVME_FEAT_LBAR_NR_MASK = 0x0000003f, + NVME_FEAT_TT_TMPTH_MASK = 0x0000ffff, + NVME_FEAT_TT_TMPSEL_MASK = 0x000f0000, + NVME_FEAT_TT_THSEL_MASK = 0x00300000, + NVME_FEAT_ER_TLER_MASK = 0x0000ffff, + NVME_FEAT_ER_DULBE_MASK = 0x00010000, + NVME_FEAT_VWC_WCE_MASK = 0x00000001, + NVME_FEAT_NRQS_NSQR_MASK = 0x0000ffff, + NVME_FEAT_NRQS_NCQR_MASK = 0xffff0000, + NVME_FEAT_ICOAL_THR_MASK = 0x000000ff, + NVME_FEAT_ICOAL_TIME_MASK = 0x0000ff00, + NVME_FEAT_ICFG_IV_MASK = 0x0000ffff, + NVME_FEAT_ICFG_CD_MASK = 0x00010000, + NVME_FEAT_WA_DN_MASK = 0x00000001, + NVME_FEAT_AE_SMART_MASK = 0x000000ff, + NVME_FEAT_AE_NAN_MASK = 0x00000100, + NVME_FEAT_AE_FW_MASK = 0x00000200, + NVME_FEAT_AE_TELEM_MASK = 0x00000400, + NVME_FEAT_AE_ANA_MASK = 0x00000800, + NVME_FEAT_AE_PLA_MASK = 0x00001000, + NVME_FEAT_AE_LBAS_MASK = 0x00002000, + NVME_FEAT_AE_EGA_MASK = 0x00004000, + NVME_FEAT_APST_APSTE_MASK = 0x00000001, + NVME_FEAT_HMEM_EHM_MASK = 0x00000001, + NVME_FEAT_HCTM_TMT2_MASK = 0x0000ffff, + NVME_FEAT_HCTM_TMT1_MASK = 0xffff0000, + NVME_FEAT_NOPS_NOPPME_MASK = 0x00000001, + NVME_FEAT_RRL_RRL_MASK = 0x000000ff, + NVME_FEAT_PLM_PLME_MASK = 0x00000001, + NVME_FEAT_PLMW_WS_MASK = 0x00000007, + NVME_FEAT_LBAS_LSIRI_MASK = 0x0000ffff, + NVME_FEAT_LBAS_LSIPI_MASK = 0xffff0000, + NVME_FEAT_SC_NODRM_MASK = 0x00000001, + NVME_FEAT_EG_ENDGID_MASK = 0x0000ffff, + NVME_FEAT_EG_EGCW_MASK = 0x00ff0000, + NVME_FEAT_SPM_PBSLC_MASK = 0x000000ff, + NVME_FEAT_HOSTID_EXHID_MASK = 0x00000001, + NVME_FEAT_RM_REGPRE_MASK = 0x00000002, + NVME_FEAT_RM_RESREL_MASK = 0x00000004, + NVME_FEAT_RM_RESPRE_MASK = 0x00000008, + NVME_FEAT_RP_PTPL_MASK = 0x00000001, + NVME_FEAT_WP_WPS_MASK = 0x00000007, +}; + +#define shift(v, s, m) ((v & m) >> s) + +#define NVME_FEAT_ARB_BURST(v) shift(v, 0, NVME_FEAT_ARB_BURST_MASK) +#define NVME_FEAT_ARB_LPW(v) shift(v, 8, NVME_FEAT_ARB_LPW_MASK) +#define NVME_FEAT_ARB_MPW(v) shift(v, 16, NVME_FEAT_ARB_MPW_MASK) +#define NVME_FEAT_ARB_HPW(v) shift(v, 24, NVME_FEAT_ARB_HPW_MASK) + +void nvme_feature_decode_arbitration(__u32 value, __u8 *ab, __u8 *lpw, + __u8 *mpw, __u8 *hpw) +{ + *ab = NVME_FEAT_ARB_BURST(value); + *lpw = NVME_FEAT_ARB_LPW(value); + *mpw = NVME_FEAT_ARB_MPW(value); + *hpw = NVME_FEAT_ARB_HPW(value); +}; + +#define NVME_FEAT_PM_PS(v) shift(v, 0, NVME_FEAT_PM_PS_MASK) +#define NVME_FEAT_PM_WH(v) shift(v, 5, NVME_FEAT_PM_WH_MASK) + +void nvme_feature_decode_power_mgmt(__u32 value, __u8 *ps, __u8 *wh) +{ + *ps = NVME_FEAT_PM_PS(value); + *wh = NVME_FEAT_PM_WH(value); +} + +#define NVME_FEAT_LBAR_NR(v) shift(v, 0, NVME_FEAT_LBAR_NR_MASK) + +void nvme_feature_decode_lba_range(__u32 value, __u8 *num) +{ + *num = NVME_FEAT_LBAR_NR(value); +} + +#define NVME_FEAT_TT_TMPTH(v) shift(v, 0, NVME_FEAT_TT_TMPTH_MASK) +#define NVME_FEAT_TT_TMPSEL(v) shift(v, 16, NVME_FEAT_TT_TMPSEL_MASK) +#define NVME_FEAT_TT_THSEL(v) shift(v, 20, NVME_FEAT_TT_THSEL_MASK) + +void nvme_feature_decode_temp_threshold(__u32 value, __u16 *tmpth, __u8 *tmpsel, __u8 *thsel) +{ + *tmpth = NVME_FEAT_TT_TMPTH(value); + *tmpsel = NVME_FEAT_TT_TMPSEL(value); + *thsel = NVME_FEAT_TT_THSEL(value); +} + +#define NVME_FEAT_ER_TLER(v) shift(v, 0, NVME_FEAT_ER_TLER_MASK) +#define NVME_FEAT_ER_DULBE(v) shift(v, 16, NVME_FEAT_ER_DULBE_MASK) + +void nvme_feature_decode_error_recovery(__u32 value, __u16 *tler, bool *dulbe) +{ + *tler = NVME_FEAT_ER_TLER(value); + *dulbe = NVME_FEAT_ER_DULBE(value); +} + +#define NVME_FEAT_VWC_WCE(v) shift(v, 0, NVME_FEAT_VWC_WCE_MASK) + +void nvme_feature_decode_volatile_write_cache(__u32 value, bool *wce) +{ + *wce = NVME_FEAT_VWC_WCE(value); +} + +#define NVME_FEAT_NRQS_NSQR(v) shift(v, 0, NVME_FEAT_NRQS_NSQR_MASK) +#define NVME_FEAT_NRQS_NCQR(v) shift(v, 16, NVME_FEAT_NRQS_NCQR_MASK) + +void nvme_feature_decode_number_of_queues(__u32 value, __u16 *nsqr, __u16 *ncqr) +{ + *nsqr = NVME_FEAT_NRQS_NSQR(value); + *ncqr = NVME_FEAT_NRQS_NCQR(value); +} + +#define NVME_FEAT_ICOAL_THR(v) shift(v, 0, NVME_FEAT_ICOAL_THR_MASK) +#define NVME_FEAT_ICOAL_TIME(v) shift(v, 8, NVME_FEAT_ICOAL_TIME_MASK) + +void nvme_feature_decode_interrupt_coalescing(__u32 value, __u8 *thr, __u8 *time) +{ + *thr = NVME_FEAT_ICOAL_THR(value); + *time = NVME_FEAT_ICOAL_TIME(value); +} + +#define NVME_FEAT_ICFG_IV(v) shift(v, 0, NVME_FEAT_ICFG_IV_MASK) +#define NVME_FEAT_ICFG_CD(v) shift(v, 16, NVME_FEAT_ICFG_CD_MASK) + +void nvme_feature_decode_interrupt_config(__u32 value, __u16 *iv, bool *cd) +{ + *iv = NVME_FEAT_ICFG_IV(value); + *cd = NVME_FEAT_ICFG_CD(value); +} + +#define NVME_FEAT_WA_DN(v) shift(v, 0, NVME_FEAT_WA_DN_MASK) + +void nvme_feature_decode_write_atomicity(__u32 value, bool *dn) +{ + *dn = NVME_FEAT_WA_DN(value); +} + +#define NVME_FEAT_AE_SMART(v) shift(v, 0, NVME_FEAT_AE_SMART_MASK) +#define NVME_FEAT_AE_NAN(v) shift(v, 8, NVME_FEAT_AE_NAN_MASK) +#define NVME_FEAT_AE_FW(v) shift(v, 9, NVME_FEAT_AE_FW_MASK) +#define NVME_FEAT_AE_TELEM(v) shift(v, 10, NVME_FEAT_AE_TELEM_MASK) +#define NVME_FEAT_AE_ANA(v) shift(v, 11, NVME_FEAT_AE_ANA_MASK) +#define NVME_FEAT_AE_PLA(v) shift(v, 12, NVME_FEAT_AE_PLA_MASK) +#define NVME_FEAT_AE_LBAS(v) shift(v, 13, NVME_FEAT_AE_LBAS_MASK) +#define NVME_FEAT_AE_EGA(v) shift(v, 14, NVME_FEAT_AE_EGA_MASK) + +void nvme_feature_decode_async_event_config(__u32 value, __u8 *smart, + bool *nan, bool *fw, bool *telem, bool *ana, bool *pla, bool *lbas, + bool *ega) +{ + *smart = NVME_FEAT_AE_SMART(value); + *nan = NVME_FEAT_AE_NAN(value); + *fw = NVME_FEAT_AE_FW(value); + *telem = NVME_FEAT_AE_TELEM(value); + *ana = NVME_FEAT_AE_ANA(value); + *pla = NVME_FEAT_AE_PLA(value); + *lbas = NVME_FEAT_AE_LBAS(value); + *ega = NVME_FEAT_AE_EGA(value); +} + +#define NVME_FEAT_APST_APSTE(v) shift(v, 0, NVME_FEAT_APST_APSTE_MASK) + +void nvme_feature_decode_auto_power_state(__u32 value, bool *apste) +{ + *apste = NVME_FEAT_APST_APSTE(value); +} + +#define NVME_FEAT_HMEM_EHM(v) shift(v, 0, NVME_FEAT_HMEM_EHM_MASK) + +void nvme_feature_decode_host_memory_buffer(__u32 value, bool *ehm) +{ + *ehm = NVME_FEAT_HMEM_EHM(value); +} + +#define NVME_FEAT_HCTM_TMT2(v) shift(v, 0, NVME_FEAT_HCTM_TMT2_MASK) +#define NVME_FEAT_HCTM_TMT1(v) shift(v, 16, NVME_FEAT_HCTM_TMT1_MASK) + +void nvme_feature_decode_host_thermal_mgmt(__u32 value, __u16 *tmt2, __u16 *tmt1) +{ + *tmt2 = NVME_FEAT_HCTM_TMT2(value); + *tmt1 = NVME_FEAT_HCTM_TMT1(value); +} + +#define NVME_FEAT_NOPS_NOPPME(v) shift(v, 0, NVME_FEAT_NOPS_NOPPME_MASK) + +void nvme_feature_decode_non_op_power_config(__u32 value, bool *noppme) +{ + *noppme = NVME_FEAT_NOPS_NOPPME(value); +} + +#define NVME_FEAT_RRL_RRL(v) shift(v, 0, NVME_FEAT_RRL_RRL_MASK) + +void nvme_feature_decode_read_recovery_level_config(__u32 value, __u8 *rrl) +{ + *rrl = NVME_FEAT_RRL_RRL(value); +} + +#define NVME_FEAT_PLM_PLME(v) shift(v, 0, NVME_FEAT_PLM_PLME_MASK) + +void nvme_feature_decode_predictable_latency_mode_config(__u32 value, bool *plme) +{ + *plme = NVME_FEAT_PLM_PLME(value); +} + +#define NVME_FEAT_PLMW_WS(v) shift(v, 0, NVME_FEAT_PLMW_WS_MASK) + +void nvme_feature_decode_predictable_latency_mode_window(__u32 value, __u8 *ws) +{ + *ws = NVME_FEAT_PLMW_WS(value); +} + +#define NVME_FEAT_LBAS_LSIRI(v) shift(v, 0, NVME_FEAT_LBAS_LSIRI_MASK) +#define NVME_FEAT_LBAS_LSIPI(v) shift(v, 16, NVME_FEAT_LBAS_LSIPI_MASK) + +void nvme_feature_decode_lba_status_attributes(__u32 value, __u16 *lsiri, __u16 *lsipi) +{ + *lsiri = NVME_FEAT_LBAS_LSIRI(value); + *lsipi = NVME_FEAT_LBAS_LSIPI(value); +} + +#define NVME_FEAT_SC_NODRM(v) shift(v, 0, NVME_FEAT_SC_NODRM_MASK) + +void nvme_feature_decode_sanitize_config(__u32 value, bool *nodrm) +{ + *nodrm = NVME_FEAT_SC_NODRM(value); +} + +#define NVME_FEAT_EG_ENDGID(v) shift(v, 0, NVME_FEAT_EG_ENDGID_MASK) +#define NVME_FEAT_EG_EGCW(v) shift(v, 16, NVME_FEAT_EG_EGCW_MASK) + +void nvme_feature_decode_endurance_group_event_config(__u32 value, + __u16 *endgid, __u8 *endgcw) +{ + *endgid = NVME_FEAT_EG_ENDGID(value); + *endgcw = NVME_FEAT_EG_EGCW(value); +} + +#define NVME_FEAT_SPM_PBSLC(v) shift(v, 0, NVME_FEAT_SPM_PBSLC_MASK) + +void nvme_feature_decode_software_progress_marker(__u32 value, __u8 *pbslc) +{ + *pbslc = NVME_FEAT_SPM_PBSLC(value); +} + +#define NVME_FEAT_HOSTID_EXHID(v) shift(v, 0, NVME_FEAT_HOSTID_EXHID_MASK) + +void nvme_feature_decode_host_identifier(__u32 value, bool *exhid) +{ + *exhid = NVME_FEAT_HOSTID_EXHID(value); +} + +#define NVME_FEAT_RM_REGPRE(v) shift(v, 1, NVME_FEAT_RM_REGPRE_MASK) +#define NVME_FEAT_RM_RESREL(v) shift(v, 2, NVME_FEAT_RM_RESREL_MASK) +#define NVME_FEAT_RM_RESPRE(v) shift(v, 3, NVME_FEAT_RM_RESPRE_MASK) + +void nvme_feature_decode_reservation_notification(__u32 value, bool *regpre, bool *resrel, bool *respre) +{ + *regpre = NVME_FEAT_RM_REGPRE(value); + *resrel = NVME_FEAT_RM_RESREL(value); + *respre = NVME_FEAT_RM_RESPRE(value); +} + +#define NVME_FEAT_RP_PTPL(v) shift(v, 0, NVME_FEAT_RP_PTPL_MASK) + +void nvme_feature_decode_reservation_persistance(__u32 value, bool *ptpl) +{ + *ptpl = NVME_FEAT_RP_PTPL(value); +} + +#define NVME_FEAT_WP_WPS(v) shift(v, 0, NVME_FEAT_WP_WPS_MASK) + +void nvme_feature_decode_namespace_write_protect(__u32 value, __u8 *wps) +{ + *wps = NVME_FEAT_WP_WPS(value); +} From 91fd58d5ad37fae8e0b56630a425d3d78f0922d7 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Sat, 22 Feb 2020 14:09:38 -0800 Subject: [PATCH 0041/1564] Fix double free discover log Signed-off-by: Keith Busch --- src/nvme/fabrics.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 836e4634f8..bf0ae67547 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -303,7 +303,6 @@ int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, numrec = le64_to_cpu(log->numrec); genctr = le64_to_cpu(log->genctr); - free(log); if (numrec == 0) { *logp = log; return 0; @@ -312,6 +311,7 @@ int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, size = sizeof(struct nvmf_discovery_log) + sizeof(struct nvmf_disc_log_entry) * (numrec); + free(log); log = malloc(size); if (!log) { errno = ENOMEM; From 1d70e4f70b170e3b80500f4b0d47283052b13e34 Mon Sep 17 00:00:00 2001 From: "Simon A. F. Lund" Date: Wed, 26 Feb 2020 21:04:24 +0100 Subject: [PATCH 0042/1564] Fix dependency on systemd When libsystemd is not installed on the system, then the pkg-config check would still be true when systemd itself is on the system. Also, when the library is unavailable then the hard-coded "-lsystemd" would cause the build to fail. The following changes fix that. * configure: changed check from "systemd" to the library "libsystemd" * examples/Makefile: Replaced hard-coded "-lsystemd" with "${LDFLAGS}" as defined by "config-host.mak" in examples/Makefile * src/Makefile: added include of "config-host.mak", removed hard-coded "-lsystemd", "-lsystemd" will trickle in from LDFLAGS Signed-off-by: Simon A. F. Lund --- configure | 2 +- examples/Makefile | 4 ++-- src/Makefile | 6 +++++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/configure b/configure index 0d6ebc6da9..9e63d9e2c9 100755 --- a/configure +++ b/configure @@ -186,7 +186,7 @@ print_config "libuuid" "${libuuid}" ########################################## # check for SystemD systemd="no" -pkg-config --exists systemd --atleast-version=232 +pkg-config --exists libsystemd --atleast-version=232 if [ $? -eq 0 ]; then systemd="yes" fi diff --git a/examples/Makefile b/examples/Makefile index 8cb7ded58d..3731d4ac27 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -1,5 +1,5 @@ CFLAGS ?= -g -O2 -override CFLAGS += -Wall -D_GNU_SOURCE -L../src/ -I../src/ -lsystemd +override CFLAGS += -Wall -D_GNU_SOURCE -L../src/ -I../src/ include ../Makefile.quiet @@ -12,7 +12,7 @@ all_targets += telemetry-listen display-tree display-columnar discover-loop all: $(all_targets) %: %.c - $(QUIET_CC)$(CC) $(CFLAGS) -o $@ $< -lnvme + $(QUIET_CC)$(CC) $(CFLAGS) -o $@ $< -lnvme ${LDFLAGS} clean: rm -f $(all_targets) diff --git a/src/Makefile b/src/Makefile index 2434f17ccb..8977e72a62 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,6 +2,10 @@ NAME=libnvme SPECFILE=$(NAME).spec VERSION=$(shell awk '/Version:/ { print $$2 }' $(SPECFILE)) +ifneq ($(MAKECMDGOALS),clean) +include ../config-host.mak +endif + prefix ?= /usr includedir ?= $(prefix)/include libdir ?= $(prefix)/lib @@ -12,7 +16,7 @@ CFLAGS ?= -g -fomit-frame-pointer -O2 -I/usr/include -Invme/ -I$(CCANDIR) -inclu override CFLAGS += -Wall -fPIC SO_CFLAGS=-shared $(CFLAGS) L_CFLAGS=$(CFLAGS) -LINK_FLAGS= -L /usr/lib64 -lsystemd +LINK_FLAGS= -L /usr/lib64 LINK_FLAGS+=$(LDFLAGS) ENABLE_SHARED ?= 1 SED ?= sed From 1f5a21a89c373ebcd11e57999a1ceb3cae41c29b Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 27 Feb 2020 10:21:30 -0800 Subject: [PATCH 0043/1564] Fill out additional documentation fields Signed-off-by: Keith Busch --- doc/libnvme.rst | 7559 ++++++++++++++++++++++---------------------- src/nvme/fabrics.h | 49 +- src/nvme/ioctl.h | 258 +- src/nvme/tree.h | 22 + src/nvme/types.h | 15 +- src/nvme/util.h | 28 +- 6 files changed, 4034 insertions(+), 3897 deletions(-) diff --git a/doc/libnvme.rst b/doc/libnvme.rst index e6493348fa..d52462fd5a 100644 --- a/doc/libnvme.rst +++ b/doc/libnvme.rst @@ -1,3 +1,87 @@ +.. c:function:: int nvme_namespace_filter (const struct dirent * d) + + +**Parameters** + +``const struct dirent * d`` + + +.. c:function:: int nvme_paths_filter (const struct dirent * d) + + +**Parameters** + +``const struct dirent * d`` + + +.. c:function:: int nvme_ctrls_filter (const struct dirent * d) + + +**Parameters** + +``const struct dirent * d`` + + +.. c:function:: int nvme_subsys_filter (const struct dirent * d) + + +**Parameters** + +``const struct dirent * d`` + + +.. c:function:: int nvme_scan_subsystems (struct dirent *** subsys) + + +**Parameters** + +``struct dirent *** subsys`` + + +.. c:function:: int nvme_scan_subsystem_ctrls (nvme_subsystem_t s, struct dirent *** ctrls) + + +**Parameters** + +``nvme_subsystem_t s`` + *undescribed* + +``struct dirent *** ctrls`` + + +.. c:function:: int nvme_scan_subsystem_namespaces (nvme_subsystem_t s, struct dirent *** namespaces) + + +**Parameters** + +``nvme_subsystem_t s`` + *undescribed* + +``struct dirent *** namespaces`` + + +.. c:function:: int nvme_scan_ctrl_namespace_paths (nvme_ctrl_t c, struct dirent *** namespaces) + + +**Parameters** + +``nvme_ctrl_t c`` + *undescribed* + +``struct dirent *** namespaces`` + + +.. c:function:: int nvme_scan_ctrl_namespaces (nvme_ctrl_t c, struct dirent *** namespaces) + + +**Parameters** + +``nvme_ctrl_t c`` + *undescribed* + +``struct dirent *** namespaces`` + + .. c:type:: struct nvme_passthru_cmd @@ -199,8 +283,8 @@ Uses NVME_IOCTL_ADMIN64_CMD for the ioctl request. **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_admin_passthru64 (int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, __u32 data_len, void * data, __u32 metadata_len, void * metadata, __u32 timeout_ms, __u64 * result) @@ -275,8 +359,8 @@ Known values for **opcode** are defined in :c:type:`enum nvme_admin_opcode `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_submit_admin_passthru (int fd, struct nvme_passthru_cmd * cmd, __u32 * result) @@ -300,8 +384,8 @@ Uses NVME_IOCTL_ADMIN_CMD for the ioctl request. **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_admin_passthru (int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, __u32 data_len, void * data, __u32 metadata_len, void * metadata, __u32 timeout_ms, __u32 * result) @@ -376,8 +460,8 @@ Known values for **opcode** are defined in :c:type:`enum nvme_admin_opcode `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_submit_io_passthru64 (int fd, struct nvme_passthru_cmd64 * cmd, __u64 * result) @@ -401,8 +485,8 @@ Uses NVME_IOCTL_IO64_CMD for the ioctl request. **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_io_passthru64 (int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, __u32 data_len, void * data, __u32 metadata_len, void * metadata, __u32 timeout_ms, __u64 * result) @@ -477,8 +561,8 @@ Known values for **opcode** are defined in :c:type:`enum nvme_io_opcode `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_submit_io_passthru (int fd, struct nvme_passthru_cmd * cmd, __u32 * result) @@ -502,8 +586,8 @@ Uses NVME_IOCTL_IO_CMD for the ioctl request. **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_io_passthru (int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, __u32 data_len, void * data, __u32 metadata_len, void * metadata, __u32 timeout_ms, __u32 * result) @@ -578,8 +662,8 @@ Known values for **opcode** are defined in :c:type:`enum nvme_io_opcode `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_subsystem_reset (int fd) @@ -598,7 +682,7 @@ This should only be sent to controller handles, not to namespaces. **Return** Zero if a subsystem reset was initiated or -1 with errno set - otherwise. +otherwise. .. c:function:: int nvme_ctrl_reset (int fd) @@ -616,7 +700,7 @@ This should only be sent to controller handles, not to namespaces. **Return** -Zero if a reset was initiated or -1 with errno set otherwise. +0 if a reset was initiated or -1 with errno set otherwise. .. c:function:: int nvme_ns_rescan (int fd) @@ -634,7 +718,7 @@ This should only be sent to controller handles, not to namespaces. **Return** -Zero if a rescan was initiated or -1 with errno set otherwise. +0 if a rescan was initiated or -1 with errno set otherwise. .. c:function:: int nvme_get_nsid (int fd) @@ -653,7 +737,7 @@ This should only be sent to namespace handles, not to controllers. **Return** The namespace identifier if a succecssful or -1 with errno set - otherwise. +otherwise. @@ -946,7 +1030,7 @@ The namespace identifier if a succecssful or -1 with errno set ``NVME_FEAT_FID_RESV_MASK`` *undescribed* -``NVME_FEAT_RESV_PERSIST`` +``NVME_FEAT_FID_RESV_PERSIST`` *undescribed* ``NVME_FEAT_FID_WRITE_PROTECT`` @@ -1249,8 +1333,8 @@ the NVM subsystem, the controller or the namespace(s). **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_identify_ctrl (int fd, struct nvme_id_ctrl * id) @@ -1274,8 +1358,8 @@ See :c:type:`struct nvme_id_ctrl ` for details on the data returne **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_identify_ns (int fd, __u32 nsid, struct nvme_id_ns * ns) @@ -1308,8 +1392,8 @@ See :c:type:`struct nvme_id_ns ` for details on the structure return **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_identify_allocated_ns (int fd, __u32 nsid, struct nvme_id_ns * ns) @@ -1329,8 +1413,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_identify_active_ns_list (int fd, __u32 nsid, struct nvme_ns_list * list) @@ -1358,8 +1442,8 @@ See :c:type:`struct nvme_ns_list ` for the definition of the retur **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_identify_allocated_ns_list (int fd, __u32 nsid, struct nvme_ns_list * list) @@ -1387,8 +1471,8 @@ See :c:type:`struct nvme_ns_list ` for the definition of the retur **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_identify_ctrl_list (int fd, __u16 cntid, struct nvme_ctrl_list * ctrlist) @@ -1416,8 +1500,8 @@ See :c:type:`struct nvme_ctrl_list ` for a definition of the str **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_identify_nsid_ctrl_list (int fd, __u32 nsid, __u16 cntid, struct nvme_ctrl_list * ctrlist) @@ -1447,8 +1531,8 @@ See :c:type:`struct nvme_ctrl_list ` for a definition of the str **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 .. c:function:: int nvme_identify_ns_descs (int fd, __u32 nsid, struct nvme_ns_id_desc * descs) @@ -1478,8 +1562,8 @@ See :c:type:`struct nvme_ns_id_desc ` for the definition of the **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_identify_nvmset_list (int fd, __u16 nvmsetid, struct nvme_id_nvmset_list * nvmset) @@ -1508,8 +1592,8 @@ See :c:type:`struct nvme_id_nvmset_list ` for the defintion **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_identify_primary_ctrl (int fd, __u16 cntid, struct nvme_primary_ctrl_cap * cap) @@ -1532,8 +1616,8 @@ See :c:type:`struct nvme_primary_ctrl_cap ` for the defin **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_identify_secondary_ctrl_list (int fd, __u16 cntid, struct nvme_secondary_ctrl_list * list) @@ -1563,8 +1647,8 @@ structure. **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_identify_ns_granularity (int fd, struct nvme_id_ns_granularity_list * list) @@ -1590,8 +1674,8 @@ structure. **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_identify_uuid (int fd, struct nvme_id_uuid_list * list) @@ -1615,8 +1699,8 @@ See :c:type:`struct nvme_id_uuid_list ` for the definition of **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_log (int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, __u8 lsp, __u16 lsi, bool rae, __u8 uuidx, __u32 len, void * log) @@ -1657,8 +1741,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_log_error (int fd, unsigned nr_entries, bool rae, struct nvme_error_log_page * log) @@ -1687,8 +1771,8 @@ particular command. **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_log_smart (int fd, __u32 nsid, bool rae, struct nvme_smart_log * log) @@ -1720,8 +1804,8 @@ the LPA field in the Identify Controller data structure. **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_log_fw_slot (int fd, bool rae, struct nvme_firmware_slot * log) @@ -1747,8 +1831,8 @@ string. The log page also indicates the active slot number. **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_log_changed_ns_list (int fd, bool rae, struct nvme_ns_list * log) @@ -1774,8 +1858,8 @@ added, or deleted. **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_log_cmd_effects (int fd, struct nvme_cmd_effects_log * log) @@ -1797,8 +1881,8 @@ and the effects of those commands on the state of the NVM subsystem. **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_log_device_self_test (int fd, struct nvme_self_test_log * log) @@ -1821,8 +1905,8 @@ self-test operations. **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_log_create_telemetry_host (int fd, struct nvme_telemetry_log * log) @@ -1861,8 +1945,8 @@ using the previously existing capture. **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_log_telemetry_ctrl (int fd, bool rae, __u64 offset, __u32 len, void * log) @@ -1911,8 +1995,8 @@ page. **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_log_predictable_lat_nvmset (int fd, __u16 nvmsetid, struct nvme_nvmset_predictable_lat_log * log) @@ -1930,8 +2014,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_log_predictable_lat_event (int fd, bool rae, __u32 offset, __u32 len, void * log) @@ -1955,6 +2039,20 @@ The nvme command status if a response was received (see :c:type:`enum *undescribed* + + +.. c:type:: enum nvme_log_ana_lsp + + +**Constants** + +``NVME_LOG_ANA_LSP_RGO_NAMESPACES`` + *undescribed* + +``NVME_LOG_ANA_LSP_RGO_GROUPS_ONLY`` + *undescribed* + + .. c:function:: int nvme_get_log_ana (int fd, enum nvme_log_ana_lsp lsp, bool rae, __u64 offset, __u32 len, void * log) @@ -1988,8 +2086,8 @@ See :c:type:`struct nvme_ana_rsp_hdr ` for the defintion of th **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_log_ana_groups (int fd, bool rae, __u32 len, struct nvme_ana_group_desc * log) @@ -2083,8 +2181,8 @@ records. **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_log_reservation (int fd, bool rae, struct nvme_resv_notification_log * log) @@ -2123,8 +2221,8 @@ estimates and information about the most recent sanitize operation. **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features (int fd, __u8 fid, __u32 nsid, __u32 cdw11, __u32 cdw12, bool save, __u8 uuidx, __u32 cdw15, __u32 data_len, void * data, __u32 * result) @@ -2168,8 +2266,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_arbitration (int fd, __u8 ab, __u8 lpw, __u8 mpw, __u8 hpw, bool save, __u32 * result) @@ -2200,8 +2298,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_power_mgmt (int fd, __u8 ps, __u8 wh, bool save, __u32 * result) @@ -2226,8 +2324,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_lba_range (int fd, __u32 nsid, __u32 nr_ranges, bool save, struct nvme_lba_range_type * data, __u32 * result) @@ -2255,8 +2353,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. @@ -2298,8 +2396,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_err_recovery (int fd, __u32 nsid, __u16 tler, bool dulbe, bool save, __u32 * result) @@ -2327,8 +2425,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_volatile_wc (int fd, bool wce, bool save, __u32 * result) @@ -2350,8 +2448,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_irq_coalesce (int fd, __u8 thr, __u8 time, bool save, __u32 * result) @@ -2376,8 +2474,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_irq_config (int fd, __u16 iv, bool cd, bool save, __u32 * result) @@ -2402,8 +2500,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_write_atomic (int fd, bool dn, bool save, __u32 * result) @@ -2425,8 +2523,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. @@ -2498,8 +2596,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_auto_pst (int fd, bool apste, bool save, struct nvme_feat_auto_pst * apst, __u32 * result) @@ -2524,8 +2622,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_timestamp (int fd, bool save, __u64 timestamp) @@ -2544,8 +2642,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_hctm (int fd, __u16 tmt2, __u16 tmt1, bool save, __u32 * result) @@ -2570,8 +2668,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_nopsc (int fd, bool noppme, bool save, __u32 * result) @@ -2614,8 +2712,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_plm_config (int fd, bool enable, __u16 nvmsetid, bool save, struct nvme_plm_config * data, __u32 * result) @@ -2643,8 +2741,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. @@ -2683,8 +2781,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_lba_sts_interval (int fd, __u16 lsiri, __u16 lsipi, bool save, __u32 * result) @@ -2709,8 +2807,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_host_behavior (int fd, bool save, struct nvme_feat_host_behavior * data) @@ -2729,8 +2827,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_sanitize (int fd, bool nodrm, bool save, __u32 * result) @@ -2752,8 +2850,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_endurance_evt_cfg (int fd, __u16 endgid, __u8 egwarn, bool save, __u32 * result) @@ -2778,8 +2876,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_sw_progress (int fd, __u8 pbslc, bool save, __u32 * result) @@ -2801,8 +2899,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_host_id (int fd, bool exhid, bool save, __u8 * hostid) @@ -2824,8 +2922,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_resv_mask (int fd, __u32 mask, bool save, __u32 * result) @@ -2847,8 +2945,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_set_features_resv_persist (int fd, bool ptpl, bool save, __u32 * result) @@ -2870,8 +2968,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. @@ -2913,8 +3011,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features (int fd, enum nvme_features_id fid, __u32 nsid, enum nvme_get_features_sel sel, __u32 cdw11, __u8 uuidx, __u32 data_len, void * data, __u32 * result) @@ -2927,7 +3025,7 @@ The nvme command status if a response was received (see :c:type:`enum File descriptor of nvme device ``enum nvme_features_id fid`` - Feature identifier + Feature identifier, see :c:type:`enum nvme_features_id ` ``__u32 nsid`` Namespace ID, if applicable @@ -2952,8 +3050,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_arbitration (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -2972,8 +3070,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_power_mgmt (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -2992,8 +3090,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_lba_range (int fd, enum nvme_get_features_sel sel, struct nvme_lba_range_type * data, __u32 * result) @@ -3015,8 +3113,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_temp_thresh (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3035,8 +3133,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_err_recovery (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3055,8 +3153,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_volatile_wc (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3075,8 +3173,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_num_queues (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3095,8 +3193,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_irq_coalesce (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3115,8 +3213,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_irq_config (int fd, enum nvme_get_features_sel sel, __u16 iv, __u32 * result) @@ -3138,8 +3236,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_write_atomic (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3158,8 +3256,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_async_event (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3178,8 +3276,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_auto_pst (int fd, enum nvme_get_features_sel sel, struct nvme_feat_auto_pst * apst, __u32 * result) @@ -3201,8 +3299,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_host_mem_buf (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3221,8 +3319,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_timestamp (int fd, enum nvme_get_features_sel sel, struct nvme_timestamp * ts) @@ -3241,8 +3339,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_kato (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3261,8 +3359,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_hctm (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3281,8 +3379,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_nopsc (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3301,8 +3399,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_rrl (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3321,8 +3419,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_plm_config (int fd, enum nvme_get_features_sel sel, __u16 nvmsetid, struct nvme_plm_config * data, __u32 * result) @@ -3347,8 +3445,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_plm_window (int fd, enum nvme_get_features_sel sel, __u16 nvmsetid, __u32 * result) @@ -3370,8 +3468,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_lba_sts_interval (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3390,8 +3488,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_host_behavior (int fd, enum nvme_get_features_sel sel, struct nvme_feat_host_behavior * data, __u32 * result) @@ -3413,8 +3511,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_sanitize (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3433,8 +3531,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_endurance_event_cfg (int fd, enum nvme_get_features_sel sel, __u16 endgid, __u32 * result) @@ -3456,8 +3554,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_sw_progress (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3476,8 +3574,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_host_id (int fd, enum nvme_get_features_sel sel, bool exhid, __u32 len, __u8 * hostid) @@ -3502,8 +3600,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_resv_mask (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3522,8 +3620,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_resv_persist (int fd, enum nvme_get_features_sel sel, __u32 * result) @@ -3542,8 +3640,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_features_write_protect (int fd, __u32 nsid, enum nvme_get_features_sel sel, __u32 * result) @@ -3565,8 +3663,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_format_nvm (int fd, __u32 nsid, __u8 lbaf, enum nvme_cmd_format_mset mset, enum nvme_cmd_format_pi pi, enum nvme_cmd_format_pil pil, enum nvme_cmd_format_ses ses, __u32 timeout) @@ -3609,8 +3707,8 @@ all namespaces or only the specific namespace associated with the command **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_ns_mgmt (int fd, __u32 nsid, enum nvme_ns_mgmt_sel sel, struct nvme_id_ns * ns, __u32 * result, __u32 timeout) @@ -3663,8 +3761,8 @@ namespace to one or more controllers. **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_ns_mgmt_delete (int fd, __u32 nsid) @@ -3686,8 +3784,8 @@ attached. **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_ns_attach (int fd, __u32 nsid, enum nvme_ns_attach_sel sel, struct nvme_ctrl_list * ctrlist) @@ -3774,8 +3872,8 @@ image. **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_fw_commit (int fd, __u8 slot, enum nvme_fw_commit_ca action, bool bpid) @@ -3803,8 +3901,9 @@ Partitions. **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. The command status +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. The command + status response may specify additional reset actions required to complete the commit process. @@ -3857,8 +3956,8 @@ specification. **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_security_receive (int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, __u8 secp, __u32 al, __u32 data_len, void * data, __u32 * result) @@ -3898,8 +3997,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_lba_status (int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl, enum nvme_lba_status_atype atype, struct nvme_lba_status * lbas) @@ -3937,8 +4036,8 @@ Unrecoverable LBAs. Refer to the specification for action type descriptions. **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_directive_send (int fd, __u32 nsid, __u16 dspec, enum nvme_directive_send_doper doper, enum nvme_directive_dtype dtype, __u32 cdw12, __u32 data_len, void * data, __u32 * result) @@ -3984,8 +4083,8 @@ See the NVMe specification for more information. **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_directive_send_id_endir (int fd, __u32 nsid, bool endir, enum nvme_directive_dtype dtype, struct nvme_id_directives * id) @@ -4010,8 +4109,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_directive_send_stream_release_identifier (int fd, __u32 nsid, __u16 stream_id) @@ -4030,8 +4129,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_directive_send_stream_release_resource (int fd, __u32 nsid) @@ -4047,8 +4146,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_directive_recv (int fd, __u32 nsid, __u16 dspec, enum nvme_directive_receive_doper doper, enum nvme_directive_dtype dtype, __u32 cdw12, __u32 data_len, void * data, __u32 * result) @@ -4086,8 +4185,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_directive_recv_identify_parameters (int fd, __u32 nsid, struct nvme_id_directives * id) @@ -4106,8 +4205,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_directive_recv_stream_parameters (int fd, __u32 nsid, struct nvme_streams_directive_params * parms) @@ -4126,8 +4225,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_directive_recv_stream_status (int fd, __u32 nsid, unsigned nr_entries, struct nvme_streams_directive_status * id) @@ -4149,8 +4248,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_directive_recv_stream_allocate (int fd, __u32 nsid, __u16 nsr, __u32 * result) @@ -4172,8 +4271,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. @@ -4224,8 +4323,8 @@ properties align to the PCI MMIO controller registers. **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_get_property (int fd, int offset, __u64 * value) @@ -4250,8 +4349,8 @@ properties align to the PCI MMIO controller registers. **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_sanitize_nvm (int fd, enum nvme_sanitize_sanact sanact, bool ause, __u8 owpass, bool oipbp, bool nodas, __u32 ovrpat) @@ -4295,8 +4394,8 @@ sanitize command does not indicate completion of the sanitize operation. **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_dev_self_test (int fd, __u32 nsid, enum nvme_dst_stc stc) @@ -4329,8 +4428,8 @@ namespace, if present. **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_virtual_mgmt (int fd, enum nvme_virt_mgmt_act act, enum nvme_virt_mgmt_rt rt, __u16 cntlid, __u16 nr, __u32 * result) @@ -4369,8 +4468,8 @@ used for several functions: **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. @@ -4436,8 +4535,8 @@ cache be made non-volatile. **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. @@ -4579,8 +4678,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_write (int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u8 dsm, __u16 dspec, __u32 reftag, __u16 apptag, __u16 appmask, __u32 data_len, void * data, __u32 metadata_len, void * metadata) @@ -4640,8 +4739,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_compare (int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 reftag, __u16 apptag, __u16 appmask, __u32 data_len, void * data, __u32 metadata_len, void * metadata) @@ -4695,8 +4794,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_write_zeros (int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 reftag, __u16 apptag, __u16 appmask) @@ -4744,8 +4843,8 @@ to 0h until a write occurs to this LBA range. **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_write_uncorrectable (int fd, __u32 nsid, __u64 slba, __u16 nlb) @@ -4776,8 +4875,8 @@ required. **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_verify (int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 reftag, __u16 apptag, __u16 appmask) @@ -4824,8 +4923,8 @@ data or metadata to the host. **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. @@ -4877,8 +4976,8 @@ deallocate/unmap/trim those logical blocks. **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. @@ -4960,8 +5059,8 @@ reservation held on a namespace. **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. @@ -5033,8 +5132,8 @@ a reservation key. **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. @@ -5077,8 +5176,8 @@ The nvme command status if a response was received (see :c:type:`enum **Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. .. c:function:: int nvme_resv_report (int fd, __u32 nsid, bool eds, __u32 len, struct nvme_reservation_status * report) @@ -5110,414 +5209,214 @@ the returned structure, :c:type:`struct nvme_reservation_status `) or -1 with errno set otherwise. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_namespace_filter (const struct dirent * d) +.. c:function:: nvme_subsystem_t nvme_first_subsystem (nvme_root_t r) **Parameters** -``const struct dirent * d`` +``nvme_root_t r`` -.. c:function:: int nvme_paths_filter (const struct dirent * d) +.. c:function:: nvme_subsystem_t nvme_next_subsystem (nvme_root_t r, nvme_subsystem_t s) **Parameters** -``const struct dirent * d`` +``nvme_root_t r`` + *undescribed* + +``nvme_subsystem_t s`` -.. c:function:: int nvme_ctrls_filter (const struct dirent * d) +.. c:function:: nvme_ns_t nvme_ctrl_first_ns (nvme_ctrl_t c) **Parameters** -``const struct dirent * d`` +``nvme_ctrl_t c`` -.. c:function:: int nvme_subsys_filter (const struct dirent * d) +.. c:function:: nvme_ns_t nvme_ctrl_next_ns (nvme_ctrl_t c, nvme_ns_t n) **Parameters** -``const struct dirent * d`` +``nvme_ctrl_t c`` + *undescribed* +``nvme_ns_t n`` -.. c:function:: int nvme_scan_subsystems (struct dirent *** subsys) + +.. c:function:: nvme_path_t nvme_ctrl_first_path (nvme_ctrl_t c) **Parameters** -``struct dirent *** subsys`` +``nvme_ctrl_t c`` -.. c:function:: int nvme_scan_subsystem_ctrls (nvme_subsystem_t s, struct dirent *** ctrls) +.. c:function:: nvme_path_t nvme_ctrl_next_path (nvme_ctrl_t c, nvme_path_t p) **Parameters** -``nvme_subsystem_t s`` +``nvme_ctrl_t c`` *undescribed* -``struct dirent *** ctrls`` +``nvme_path_t p`` -.. c:function:: int nvme_scan_subsystem_namespaces (nvme_subsystem_t s, struct dirent *** namespaces) +.. c:function:: nvme_ctrl_t nvme_subsystem_first_ctrl (nvme_subsystem_t s) **Parameters** ``nvme_subsystem_t s`` - *undescribed* - -``struct dirent *** namespaces`` -.. c:function:: int nvme_scan_ctrl_namespace_paths (nvme_ctrl_t c, struct dirent *** namespaces) +.. c:function:: nvme_ctrl_t nvme_subsystem_next_ctrl (nvme_subsystem_t s, nvme_ctrl_t c) **Parameters** -``nvme_ctrl_t c`` +``nvme_subsystem_t s`` *undescribed* -``struct dirent *** namespaces`` +``nvme_ctrl_t c`` -.. c:function:: int nvme_scan_ctrl_namespaces (nvme_ctrl_t c, struct dirent *** namespaces) +.. c:function:: nvme_ns_t nvme_subsystem_first_ns (nvme_subsystem_t s) **Parameters** -``nvme_ctrl_t c`` - *undescribed* - -``struct dirent *** namespaces`` - - +``nvme_subsystem_t s`` -.. c:type:: struct nvme_fabrics_config +.. c:function:: nvme_ns_t nvme_subsystem_next_ns (nvme_subsystem_t s, nvme_ns_t n) -**Definition** +**Parameters** -:: +``nvme_subsystem_t s`` + *undescribed* - struct nvme_fabrics_config { - const char *transport; - const char *traddr; - const char *trsvcid; - const char *nqn; - const char *hostnqn; - const char *host_traddr; - const char *hostid; - int queue_size; - int nr_io_queues; - int reconnect_delay; - int ctrl_loss_tmo; - int keep_alive_tmo; - int nr_write_queues; - int nr_poll_queues; - int tos; - bool duplicate_connect; - bool disable_sqflow; - bool hdr_digest; - bool data_digest; - uint8_t rsvd[0x200]; - }; +``nvme_ns_t n`` -**Members** +.. c:function:: nvme_for_each_subsystem_safe ( r, s, _s) -.. c:function:: int nvmf_add_ctrl_opts (struct nvme_fabrics_config * cfg) +**Parameters** +``r`` + *undescribed* -**Parameters** +``s`` + *undescribed* -``struct nvme_fabrics_config * cfg`` +``_s`` + *undescribed* -.. c:function:: nvme_ctrl_t nvmf_add_ctrl (struct nvme_fabrics_config * cfg) +.. c:function:: nvme_for_each_subsystem ( r, s) **Parameters** -``struct nvme_fabrics_config * cfg`` +``r`` + *undescribed* + +``s`` + *undescribed* -.. c:function:: int nvmf_get_discovery_log (nvme_ctrl_t c, struct nvmf_discovery_log ** logp, int max_retries) +.. c:function:: nvme_subsystem_for_each_ctrl_safe ( s, c, _c) **Parameters** -``nvme_ctrl_t c`` +``s`` *undescribed* -``struct nvmf_discovery_log ** logp`` +``c`` *undescribed* -``int max_retries`` +``_c`` + *undescribed* -.. c:function:: char * nvmf_hostnqn_generate () +.. c:function:: nvme_subsystem_for_each_ctrl ( s, c) - Generate a machine specific host nqn **Parameters** -**Return** +``s`` + *undescribed* -An nvm namespace qualifieid name string based on the machine - identifier, or NULL if not successful. +``c`` + *undescribed* -.. c:function:: char * nvmf_hostnqn_from_file () +.. c:function:: nvme_ctrl_for_each_ns_safe ( c, n, _n) - Reads the host nvm qualified name from the config default location in /etc/nvme/ **Parameters** -**Return** +``c`` + *undescribed* -The host nqn, or NULL if unsuccessful. If found, the caller - is responsible to free the string. +``n`` + *undescribed* +``_n`` + *undescribed* -.. c:function:: char * nvmf_hostid_from_file () - Reads the host identifier from the config default location in /etc/nvme/. +.. c:function:: nvme_ctrl_for_each_ns ( c, n) + **Parameters** -**Return** +``c`` + *undescribed* -The host identifier, or NULL if unsuccessful. If found, the caller - is responsible to free the string. +``n`` + *undescribed* -.. c:function:: nvme_ctrl_t nvmf_connect_disc_entry (struct nvmf_disc_log_entry * e, const struct nvme_fabrics_config * defcfg, bool * discover) +.. c:function:: nvme_ctrl_for_each_path_safe ( c, p, _p) **Parameters** -``struct nvmf_disc_log_entry * e`` +``c`` *undescribed* -``const struct nvme_fabrics_config * defcfg`` +``p`` *undescribed* -``bool * discover`` +``_p`` + *undescribed* -.. c:function:: nvme_subsystem_t nvme_first_subsystem (nvme_root_t r) +.. c:function:: nvme_ctrl_for_each_path ( c, p) **Parameters** -``nvme_root_t r`` +``c`` + *undescribed* +``p`` + *undescribed* -.. c:function:: nvme_subsystem_t nvme_next_subsystem (nvme_root_t r, nvme_subsystem_t s) - -**Parameters** - -``nvme_root_t r`` - *undescribed* - -``nvme_subsystem_t s`` - - -.. c:function:: nvme_ns_t nvme_ctrl_first_ns (nvme_ctrl_t c) - - -**Parameters** - -``nvme_ctrl_t c`` - - -.. c:function:: nvme_ns_t nvme_ctrl_next_ns (nvme_ctrl_t c, nvme_ns_t n) - - -**Parameters** - -``nvme_ctrl_t c`` - *undescribed* - -``nvme_ns_t n`` - - -.. c:function:: nvme_path_t nvme_ctrl_first_path (nvme_ctrl_t c) - - -**Parameters** - -``nvme_ctrl_t c`` - - -.. c:function:: nvme_path_t nvme_ctrl_next_path (nvme_ctrl_t c, nvme_path_t p) - - -**Parameters** - -``nvme_ctrl_t c`` - *undescribed* - -``nvme_path_t p`` - - -.. c:function:: nvme_ctrl_t nvme_subsystem_first_ctrl (nvme_subsystem_t s) - - -**Parameters** - -``nvme_subsystem_t s`` - - -.. c:function:: nvme_ctrl_t nvme_subsystem_next_ctrl (nvme_subsystem_t s, nvme_ctrl_t c) - - -**Parameters** - -``nvme_subsystem_t s`` - *undescribed* - -``nvme_ctrl_t c`` - - -.. c:function:: nvme_ns_t nvme_subsystem_first_ns (nvme_subsystem_t s) - - -**Parameters** - -``nvme_subsystem_t s`` - - -.. c:function:: nvme_ns_t nvme_subsystem_next_ns (nvme_subsystem_t s, nvme_ns_t n) - - -**Parameters** - -``nvme_subsystem_t s`` - *undescribed* - -``nvme_ns_t n`` - - -.. c:function:: nvme_for_each_subsystem_safe ( r, s, _s) - - -**Parameters** - -``r`` - *undescribed* - -``s`` - *undescribed* - -``_s`` - *undescribed* - - -.. c:function:: nvme_for_each_subsystem ( r, s) - - -**Parameters** - -``r`` - *undescribed* - -``s`` - *undescribed* - - -.. c:function:: nvme_subsystem_for_each_ctrl_safe ( s, c, _c) - - -**Parameters** - -``s`` - *undescribed* - -``c`` - *undescribed* - -``_c`` - *undescribed* - - -.. c:function:: nvme_subsystem_for_each_ctrl ( s, c) - - -**Parameters** - -``s`` - *undescribed* - -``c`` - *undescribed* - - -.. c:function:: nvme_ctrl_for_each_ns_safe ( c, n, _n) - - -**Parameters** - -``c`` - *undescribed* - -``n`` - *undescribed* - -``_n`` - *undescribed* - - -.. c:function:: nvme_ctrl_for_each_ns ( c, n) - - -**Parameters** - -``c`` - *undescribed* - -``n`` - *undescribed* - - -.. c:function:: nvme_ctrl_for_each_path_safe ( c, p, _p) - - -**Parameters** - -``c`` - *undescribed* - -``p`` - *undescribed* - -``_p`` - *undescribed* - - -.. c:function:: nvme_ctrl_for_each_path ( c, p) - - -**Parameters** - -``c`` - *undescribed* - -``p`` - *undescribed* - - -.. c:function:: nvme_subsystem_for_each_ns_safe ( s, n, _n) +.. c:function:: nvme_subsystem_for_each_ns_safe ( s, n, _n) **Parameters** @@ -6042,2598 +5941,2648 @@ The host identifier, or NULL if unsuccessful. If found, the caller ``const char * attr`` -.. c:function:: __u8 nvme_status_to_errno (int status, bool fabrics) +.. c:function:: __le16 cpu_to_le16 (uint16_t x) - Converts nvme return status to errno **Parameters** -``int status`` - Return status from an nvme passthrough commmand +``uint16_t x`` + 16-bit CPU value to turn to little endian. -``bool fabrics`` - Set to true if :c:type:`status` is to a fabrics target. -**Return** +.. c:function:: __le32 cpu_to_le32 (uint32_t x) -An errno representing the nvme status if it is an nvme status field, - or unchanged status is < 0 since errno is already set. +**Parameters** -.. c:function:: int nvme_fw_download_seq (int fd, __u32 size, __u32 xfer, __u32 offset, void * buf) +``uint32_t x`` + 32-bit CPU value to turn little endian. -**Parameters** +.. c:function:: __le64 cpu_to_le64 (uint64_t x) -``int fd`` - File descriptor of nvme device -``__u32 size`` - Total size of the firmware image to transfer +**Parameters** -``__u32 xfer`` - Maximum size to send with each partial transfer +``uint64_t x`` + 64-bit CPU value to turn little endian. -``__u32 offset`` - Starting offset to send with this firmware downlaod -``void * buf`` - Address of buffer containing all or part of the firmware image. +.. c:function:: uint16_t le16_to_cpu (__le16 x) -**Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +**Parameters** + +``__le16 x`` + 16-bit little endian value to turn to CPU. -.. c:function:: int nvme_get_ctrl_telemetry (int fd, bool rae, struct nvme_telemetry_log ** log) +.. c:function:: uint32_t le32_to_cpu (__le32 x) **Parameters** -``int fd`` - File descriptor of nvme device +``__le32 x`` + 32-bit little endian value to turn to CPU. -``bool rae`` - Retain asynchronous events -``struct nvme_telemetry_log ** log`` - On success, set to the value of the allocated and retreived log. +.. c:function:: uint64_t le64_to_cpu (__le64 x) -**Description** -The total size allocated can be calculated as: - (:c:type:`struct nvme_telemetry_log `.dalb3 + 1) * ``NVME_LOG_TELEM_BLOCK_SIZE``. +**Parameters** -**Return** +``__le64 x`` + 64-bit little endian value to turn to CPU. -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_host_telemetry (int fd, struct nvme_telemetry_log ** log) +.. c:type:: enum nvme_constants -**Parameters** + A place to stash various constant nvme values -``int fd`` - File descriptor of nvme device +**Constants** -``struct nvme_telemetry_log ** log`` - On success, set to the value of the allocated and retreived log. - -**Description** +``NVME_NSID_ALL`` + A broadcast value that is used to specify all + namespaces -The total size allocated can be calculated as: - (:c:type:`struct nvme_telemetry_log `.dalb3 + 1) * ``NVME_LOG_TELEM_BLOCK_SIZE``. +``NVME_NSID_NONE`` + The invalid namespace id, for when the nsid + parameter is not used in a command -**Return** +``NVME_UUID_NONE`` + Use to omit the uuid command parameter -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +``NVME_CNTLID_NONE`` + Use to omit the cntlid command parameter +``NVME_NVMSETID_NONE`` + Use to omit the nvmsetid command parameter -.. c:function:: int nvme_get_new_host_telemetry (int fd, struct nvme_telemetry_log ** log) +``NVME_LOG_LSP_NONE`` + Use to omit the log lsp command parameter +``NVME_LOG_LSI_NONE`` + Use to omit the log lsi command parameter -**Parameters** +``NVME_IDENTIFY_DATA_SIZE`` + The transfer size for nvme identify commands -``int fd`` - File descriptor of nvme device +``NVME_ID_NVMSET_LIST_MAX`` + The largest possible nvmset index in identify + nvmeset -``struct nvme_telemetry_log ** log`` - On success, set to the value of the allocated and retreived log. +``NVME_ID_UUID_LIST_MAX`` + The largest possible uuid index in identify + uuid list -**Description** +``NVME_ID_CTRL_LIST_MAX`` + The largest possible controller index in + identify controller list -The total size allocated can be calculated as: - (:c:type:`struct nvme_telemetry_log `.dalb3 + 1) * ``NVME_LOG_TELEM_BLOCK_SIZE``. +``NVME_ID_NS_LIST_MAX`` + The largest possible namespace index in + identify namespace list -**Return** +``NVME_ID_SECONDARY_CTRL_MAX`` + The largest possible secondary controller index + in identify secondary controller -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +``NVME_ID_ND_DESCRIPTOR_MAX`` + *undescribed* +``NVME_FEAT_LBA_RANGE_MAX`` + The largest possible LBA range index in feature + lba range type -.. c:function:: void nvme_init_id_ns (struct nvme_id_ns * ns, __u64 nsze, __u64 ncap, __u8 flbas, __u8 dps, __u8 nmic, __u32 anagrpid, __u16 nvmsetid) +``NVME_LOG_ST_MAX_RESULTS`` + The largest possible self test result index in the + device self test log - Initialize an Identify Namepsace structure for creation. +``NVME_LOG_TELEM_BLOCK_SIZE`` + Specification defined size of Telemetry Data Blocks -**Parameters** +``NVME_DSM_MAX_RANGES`` + The largest possible range index in a data-set + management command -``struct nvme_id_ns * ns`` - Address of the Identify Namespace structure to initialize +``NVME_NQN_LENGTH`` + Max length for NVMe Qualified Name. -``__u64 nsze`` - Namespace size +``NVMF_TRADDR_SIZE`` + *undescribed* -``__u64 ncap`` - namespace capacity +``NVMF_TSAS_SIZE`` + *undescribed* -``__u8 flbas`` - formatted logical block size settings +``NVME_NIDT_EUI64_LEN`` + *undescribed* -``__u8 dps`` - Data protection settings +``NVME_NIDT_NGUID_LEN`` + *undescribed* -``__u8 nmic`` - Namespace sharing capabilities -``__u32 anagrpid`` - ANA group identifier -``__u16 nvmsetid`` - NVM Set identifer -**Description** +.. c:type:: enum nvme_register_offsets -This is intended to be used with a namespace management "create", see -:c:type:`nvme_ns_mgmt_create`(). + The nvme controller registers for all transports. This is the layout of BAR0/1 for PCIe, and properties for fabrics. +**Constants** -.. c:function:: void nvme_init_ctrl_list (struct nvme_ctrl_list * cntlist, __u16 num_ctrls, __u16 * ctrlist) +``NVME_REG_CAP`` + Controller Capabilities - Initialize an nvme_ctrl_list structure from an array. +``NVME_REG_VS`` + Version -**Parameters** +``NVME_REG_INTMS`` + Interrupt Mask Set -``struct nvme_ctrl_list * cntlist`` - The controller list structure to initialize +``NVME_REG_INTMC`` + Interrupt Mask Clear -``__u16 num_ctrls`` - The number of controllers in the array, :c:type:`ctrlist`. +``NVME_REG_CC`` + Controller Configuration -``__u16 * ctrlist`` - An array of controller identifiers in CPU native endian. +``NVME_REG_CSTS`` + Controller Status -**Description** +``NVME_REG_NSSR`` + NVM Subsystem Reset -This is intended to be used with any command that takes a controller list -argument. See :c:type:`nvme_ns_attach_ctrls`() and :c:type:`nvme_ns_detach`(). +``NVME_REG_AQA`` + Admin Queue Attributes +``NVME_REG_ASQ`` + Admin SQ Base Address -.. c:function:: void nvme_init_dsm_range (struct nvme_dsm_range * dsm, __u32 * ctx_attrs, __u32 * llbas, __u64 * slbas, __u16 nr_ranges) +``NVME_REG_ACQ`` + Admin CQ Base Address - Constructs a data set range structure +``NVME_REG_CMBLOC`` + Controller Memory Buffer Location -**Parameters** +``NVME_REG_CMBSZ`` + Controller Memory Buffer Size -``struct nvme_dsm_range * dsm`` - DSM range array +``NVME_REG_BPINFO`` + Boot Partition Information -``__u32 * ctx_attrs`` - Array of context attributes +``NVME_REG_BPRSEL`` + Boot Partition Read Select -``__u32 * llbas`` - Array of length in logical blocks +``NVME_REG_BPMBL`` + Boot Partition Memory Buffer Location -``__u64 * slbas`` - Array of starting logical blocks +``NVME_REG_CMBMSC`` + Controller Memory Buffer Memory Space Control -``__u16 nr_ranges`` - The size of the dsm arrays +``NVME_REG_CMBSTS`` + Controller Memory Buffer Status -**Description** +``NVME_REG_PMRCAP`` + Persistent Memory Capabilities -Each array must be the same size of size 'nr_ranges'. This is intended to be -used with constructing a payload for :c:type:`nvme_dsm`(). +``NVME_REG_PMRCTL`` + Persistent Memory Region Control -**Return** +``NVME_REG_PMRSTS`` + Persistent Memory Region Status -The nvme command status if a response was received or -errno - otherwise. +``NVME_REG_PMREBS`` + Persistent Memory Region Elasticity Buffer Size +``NVME_REG_PMRSWTP`` + Memory Region Sustained Write Throughput -.. c:function:: int __nvme_get_log_page (int fd, __u32 nsid, __u8 log_id, bool rae, __u32 xfer_len, __u32 data_len, void * data) +``NVME_REG_PMRMSC`` + Persistent Memory Region Controller Memory Space Control +``NVME_REG_DBS`` + SQ 0 Tail Doorbell -**Parameters** -``int fd`` - File descriptor of nvme device +.. c:function:: bool nvme_is_64bit_reg (__u32 offset) -``__u32 nsid`` - Namespace Identifier, if applicable. + Checks if offset of the controller register is a know 64bit value. -``__u8 log_id`` - Log Identifier, see :c:type:`enum nvme_cmd_get_log_lid `. +**Parameters** -``bool rae`` - Retain asynchronous events +``__u32 offset`` + Offset of controller register field in bytes -``__u32 xfer_len`` - Max log transfer size per request to split the total. +**Description** -``__u32 data_len`` - Total length of the log to transfer. +This function does not care about transport so that the offset is not going +to be checked inside of this function for the unsupported fields in a +specific transport. For example, BPMBL(Boot Partition Memory Buffer +Location) register is not supported by fabrics, but it can be chcked here. -``void * data`` - User address of at least :c:type:`data_len` to store the log. +Returns true if given offset is 64bit register, otherwise it returns false. -**Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_log_page (int fd, __u32 nsid, __u8 log_id, bool rae, __u32 data_len, void * data) +.. c:type:: enum nvme_psd_flags + Possible flag values in nvme power state descriptor -**Parameters** +**Constants** -``int fd`` - File descriptor of nvme device +``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. -``__u32 nsid`` - Namespace Identifier, if applicable. +``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. -``__u8 log_id`` - Log Identifier, see :c:type:`enum nvme_cmd_get_log_lid `. -``bool rae`` - Retain asynchronous events -``__u32 data_len`` - Total length of the log to transfer. -``void * data`` - User address of at least :c:type:`data_len` to store the log. +.. c:type:: enum nvme_psd_ps -**Description** + Known values for :c:type:`struct nvme_psd ` ``ips`` and ``aps``. Use with nvme_psd_power_scale() to extract the power scale field to match this enum. NVME_PSD_IPS_100_MICRO_WATT: 0.0001 watt scale NVME_PSD_IPS_10_MILLI_WATT: 0.01 watt scale -Calls __nvme_get_log_page() with a default 4k transfer length, as that is -guarnateed by the protocol to be a safe transfer size. +**Constants** -**Return** +``NVME_PSD_PS_100_MICRO_WATT`` + *undescribed* -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +``NVME_PSD_PS_10_MILLI_WATT`` + *undescribed* -.. c:function:: int nvme_get_ana_log_len (int fd, size_t * analen) +.. c:function:: unsigned nvme_psd_power_scale (__u8 ps) - Retreive size of the current ANA log + power scale occupies the upper 3 bits **Parameters** -``int fd`` - File descriptor of nvme device +``__u8 ps`` + *undescribed* -``size_t * analen`` - Pointer to where the length will be set on success -**Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +.. c:type:: enum nvme_psd_workload -.. c:function:: int nvme_namespace_attach_ctrls (int fd, __u32 nsid, __u16 num_ctrls, __u16 * ctrlist) + Specifies a workload hint in the Power Management Feature (see :c:type:`struct nvme_psd `.apw) to inform the NVM subsystem or indicate the conditions for the active power level. - Attach namespace to controller(s) +**Constants** -**Parameters** - -``int fd`` - File descriptor of nvme device +``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. -``__u32 nsid`` - Namespace ID to attach +``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 + NVM subsystem are idle. The submission queue(s) + should be sufficiently large allowing the host to + ensure there are multiple commands pending at all + times during the workload. -``__u16 num_ctrls`` - Number of controllers in ctrlist -``__u16 * ctrlist`` - List of controller IDs to perform the attach action -**Return** -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +.. c:type:: struct nvme_id_psd -.. c:function:: int nvme_namespace_detach_ctrls (int fd, __u32 nsid, __u16 num_ctrls, __u16 * ctrlist) +**Definition** - Detach namespace from controller(s) +:: -**Parameters** + struct nvme_id_psd { + __le16 mp; + __u8 rsvd2; + __u8 flags; + __le32 enlat; + __le32 exlat; + __u8 rrt; + __u8 rrl; + __u8 rwt; + __u8 rwl; + __le16 idlp; + __u8 ips; + __u8 rsvd19; + __le16 actp; + __u8 apw; + __u8 aps; + __u8 rsvd23[8]; + }; -``int fd`` - File descriptor of nvme device +**Members** -``__u32 nsid`` - Namespace ID to detach +``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 :c:type:`enum nvme_psd_flags `). A value of 0 indicates + Maximum Power is not reported. -``__u16 num_ctrls`` - Number of controllers in ctrlist +``flags`` + Additional decoding flags, see :c:type:`enum nvme_psd_flags `. -``__u16 * ctrlist`` - List of controller IDs to perform the detach action +``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. -**Return** +``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. -The nvme command status if a response was received (see :c:type:`enum - nvme_status_field `) or -1 with errno set otherwise. +``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. -.. c:function:: int nvme_get_feature_length (int fid, __u32 cdw11, __u32 * len) +``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 - Retreive the command payload length for a specific feature identifier +``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 -**Parameters** +``idlp`` + Idle Power indicates the typical power consumed by the NVM + subsystem over 30 seconds in this power state when idle. -``int fid`` - Feature identifier, see :c:type:`enum nvme_features_id `. +``ips`` + Idle Power Scale indicates the scale for :c:type:`struct nvme_id_psd `.idlp, + see :c:type:`enum nvme_psd_ps ` for decoding this field. -``__u32 cdw11`` - The cdw11 value may affect the transfer (only known fid is - ``NVME_FEAT_FID_HOST_ID``) +``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. -``__u32 * len`` - On success, set to this features payload length in bytes. +``apw`` + Active Power Workload indicates the workload used to calculate + maximum power for this power state. See :c:type:`enum nvme_psd_workload ` for + decoding this field. -**Return** +``aps`` + Active Power Scale indicates the scale for the :c:type:`struct + nvme_id_psd `.actp, see :c:type:`enum nvme_psd_ps ` for decoding this value. -0 on success, -1 with errno set to EINVAL if the function did not - recognize :c:type:`fid`. -.. c:function:: int nvme_get_directive_receive_length (enum nvme_directive_dtype dtype, enum nvme_directive_receive_doper doper, __u32 * len) -**Parameters** +.. c:type:: struct nvme_id_ctrl -``enum nvme_directive_dtype dtype`` - Directive type, see :c:type:`enum nvme_directive_dtype ` + Identify Controller data structure -``enum nvme_directive_receive_doper doper`` - Directive receive operation, see :c:type:`enum nvme_directive_receive_doper ` +**Definition** -``__u32 * len`` - On success, set to this directives payload length in bytes. +:: -**Return** + struct nvme_id_ctrl { + __le16 vid; + __le16 ssvid; + char sn[20]; + char mn[40]; + char fr[8]; + __u8 rab; + __u8 ieee[3]; + __u8 cmic; + __u8 mdts; + __le16 cntlid; + __le32 ver; + __le32 rtd3r; + __le32 rtd3e; + __le32 oaes; + __le32 ctratt; + __le16 rrls; + __u8 rsvd102[9]; + __u8 cntrltype; + __u8 fguid[16]; + __le16 crdt1; + __le16 crdt2; + __le16 crdt3; + __u8 rsvd134[119]; + __u8 nvmsr; + __u8 vwci; + __u8 mec; + __le16 oacs; + __u8 acl; + __u8 aerl; + __u8 frmw; + __u8 lpa; + __u8 elpe; + __u8 npss; + __u8 avscc; + __u8 apsta; + __le16 wctemp; + __le16 cctemp; + __le16 mtfa; + __le32 hmpre; + __le32 hmmin; + __u8 tnvmcap[16]; + __u8 unvmcap[16]; + __le32 rpmbs; + __le16 edstt; + __u8 dsto; + __u8 fwug; + __le16 kas; + __le16 hctma; + __le16 mntmt; + __le16 mxtmt; + __le32 sanicap; + __le32 hmminds; + __le16 hmmaxd; + __le16 nsetidmax; + __le16 endgidmax; + __u8 anatt; + __u8 anacap; + __le32 anagrpmax; + __le32 nanagrpid; + __le32 pels; + __u8 rsvd356[156]; + __u8 sqes; + __u8 cqes; + __le16 maxcmd; + __le32 nn; + __le16 oncs; + __le16 fuses; + __u8 fna; + __u8 vwc; + __le16 awun; + __le16 awupf; + __u8 nvscc; + __u8 nwpc; + __le16 acwu; + __u8 rsvd534[2]; + __le32 sgls; + __le32 mnan; + __u8 rsvd544[224]; + char subnqn[NVME_NQN_LENGTH]; + __u8 rsvd1024[768]; + __le32 ioccsz; + __le32 iorcsz; + __le16 icdoff; + __u8 fcatt; + __u8 msdbd; + __le16 ofcs; + __u8 rsvd1806[242]; + struct nvme_id_psd psd[32]; + __u8 vs[1024]; + }; -0 on success, -1 with errno set to EINVAL if the function did not - recognize :c:type:`dtype` or :c:type:`doper`. +**Members** +``vid`` + PCI Vendor ID, the company vendor identifier that is assigned by + the PCI SIG. -.. c:function:: int nvme_open (const char * name) +``ssvid`` + PCI Subsystem Vendor ID, the company vendor identifier that is + assigned by the PCI SIG for the subsystem. - Open an nvme controller or namespace device +``sn`` + Serial Number in ascii -**Parameters** +``mn`` + Model Number in ascii -``const char * name`` - The basename of the device to open +``fr`` + Firmware Revision in ascii, the currently active firmware + revision for the NVM subsystem -**Description** +``rab`` + Recommended Arbitration Burst, reported as a power of two -This will look for the handle in /dev/ and validate the name and filetype -match linux conventions. +``ieee`` + IEEE assigned Organization Unique Identifier -**Return** +``cmic`` + Controller Multipath IO and Namespace Sharing Capabilities of + the controller and NVM subsystem. See :c:type:`enum nvme_id_ctrl_cmic `. -A file descriptor for the device on a successful open, or -1 with - errno set otherwise. +``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 +``cntlid`` + Controller ID, the NVM subsystem unique controller identifier + associated with the controller. -.. c:function:: __le16 cpu_to_le16 (uint16_t x) +``ver`` + Version, this field contains the value reported in the Version + register, or property (see :c:type:`enum nvme_registers ` ``NVME_REG_VS``). +``rtd3r`` + RTD3 Resume Latency, the expected latency in microseconds to resume + from Runtime D3 -**Parameters** +``rtd3e`` + RTD3 Exit Latency, the typical latency in microseconds to enter + Runtime D3. -``uint16_t x`` - 16-bit CPU value to turn to little endian. +``oaes`` + Optional Async Events Supported, see **enum** nvme_id_ctrl_oaes . +``ctratt`` + Controller Attributes, see **enum** nvme_id_ctrl_ctratt -.. c:function:: __le32 cpu_to_le32 (uint32_t x) +``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. +``cntrltype`` + Controller Type, see :c:type:`enum nvme_id_ctrl_cntrltype ` -**Parameters** +``fguid`` + FRU GUID, a 128-bit value that is globally unique for a given + Field Replaceable Unit -``uint32_t x`` - 32-bit CPU value to turn little endian. +``crdt1`` + Controller Retry Delay time in 100 millisecod units if CQE CRD + field is 1 +``crdt2`` + Controller Retry Delay time in 100 millisecod units if CQE CRD + field is 2 -.. c:function:: __le64 cpu_to_le64 (uint64_t x) +``crdt3`` + Controller Retry Delay time in 100 millisecod units if CQE CRD + field is 3 +``nvmsr`` + NVM Subsystem Report, see :c:type:`enum nvme_id_ctrl_nvmsr ` -**Parameters** +``vwci`` + VPD Write Cycle Information, see :c:type:`enum nvme_id_ctrl_vwci ` -``uint64_t x`` - 64-bit CPU value to turn little endian. +``mec`` + Management Endpoint Capabilities, see :c:type:`enum nvme_id_ctrl_mec ` +``oacs`` + Optional Admin Command Support,the optional Admin commands and + features supported by the controller, see :c:type:`enum nvme_id_ctrl_oacs `. -.. c:function:: uint16_t le16_to_cpu (__le16 x) +``acl`` + Abort Command Limit, the maximum number of concurrently + 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. -**Parameters** +``frmw`` + Firmware Updates indicates capabilities regarding firmware + updates. See :c:type:`enum nvme_id_ctrl_frmw `. -``__le16 x`` - 16-bit little endian value to turn to CPU. +``lpa`` + Log Page Attributes, see :c:type:`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. -.. c:function:: uint32_t le32_to_cpu (__le32 x) +``npss`` + Number of Power States Supported, the number of NVM Express + power states supported by the controller, indicating the number + of valid entries in :c:type:`struct nvme_id_ctrl `.psd. This is a 0's + based value. +``avscc`` + Admin Vendor Specific Command Configuration, see + :c:type:`enum nvme_id_ctrl_avscc `. -**Parameters** +``apsta`` + Autonomous Power State Transition Attributes, see + :c:type:`enum nvme_id_ctrl_apsta `. -``__le32 x`` - 32-bit little endian value to turn to CPU. +``wctemp`` + Warning Composite Temperature Threshold indicates + the minimum Composite Temperature field value (see :c:type:`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 :c:type:`struct + nvme_smart_log `.critical_comp_time) that indicates a critical + overheating condition. -.. c:function:: uint64_t le64_to_cpu (__le64 x) +``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. +``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. -**Parameters** +``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. -``__le64 x`` - 64-bit little endian value to turn to CPU. +``tnvmcap`` + Total NVM Capacity, the total NVM capacity in the NVM subsystem. + 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 + :c:type:`enum nvme_id_ctrl_rpmbs `. + **edstt** Extended Device Self-test Time, if Device Self-test command is + supported (see :c:type:`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 :c:type:`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 -.. c:type:: enum nvme_constants +``kas`` + Keep Alive Support indicates the granularity of the Keep Alive + Timer in 100 millisecond units. - A place to stash various constant nvme values +``hctma`` + Host Controlled Thermal Management Attributes, see :c:type:`enum nvme_id_ctrl_hctm `. -**Constants** +``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``. -``NVME_NSID_ALL`` - A broadcast value that is used to specify all - namespaces +``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``. -``NVME_NSID_NONE`` - The invalid namespace id, for when the nsid - parameter is not used in a command +``sanicap`` + Sanitize Capabilities, see :c:type:`enum nvme_id_ctrl_sanicap ` -``NVME_UUID_NONE`` - Use to omit the uuid command parameter +``hmminds`` + Host Memory Buffer Minimum Descriptor Entry Size indicates the + minimum usable size of a Host Memory Buffer Descriptor Entry in + 4 KiB units. -``NVME_CNTLID_NONE`` - Use to omit the cntlid command parameter +``hmmaxd`` + Host Memory Maximum Descriptors Entries indicates the number of + usable Host Memory Buffer Descriptor Entries. -``NVME_NVMSETID_NONE`` - Use to omit the nvmsetid command parameter +``nsetidmax`` + NVM Set Identifier Maximum, defines the maximum value of a valid + NVM Set Identifier for any controller in the NVM subsystem. -``NVME_LOG_LSP_NONE`` - Use to omit the log lsp command parameter +``endgidmax`` + Endurance Group Identifier Maximum, defines the maximum value of + a valid Endurance Group Identifier for any controller in the NVM + subsystem. -``NVME_LOG_LSI_NONE`` - Use to omit the log lsi command parameter +``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. -``NVME_IDENTIFY_DATA_SIZE`` - The transfer size for nvme identify commands +``anacap`` + Asymmetric Namespace Access Capabilities, see + :c:type:`enum nvme_id_ctrl_anacap `. -``NVME_ID_NVMSET_LIST_MAX`` - The largest possible nvmset index in identify - nvmeset +``anagrpmax`` + ANA Group Identifier Maximum indicates the maximum value of a + valid ANA Group Identifier for any controller in the NVM + subsystem. -``NVME_ID_UUID_LIST_MAX`` - The largest possible uuid index in identify - uuid list +``nanagrpid`` + Number of ANA Group Identifiers indicates the number of ANA + groups supported by this controller. -``NVME_ID_CTRL_LIST_MAX`` - The largest possible controller index in - identify controller list +``pels`` + Persistent Event Log Size indicates the maximum reportable size + for the Persistent Event Log. -``NVME_ID_NS_LIST_MAX`` - The largest possible namespace index in - identify namespace list +``sqes`` + Submission Queue Entry Size, see :c:type:`enum nvme_id_ctrl_sqes `. -``NVME_ID_SECONDARY_CTRL_MAX`` - The largest possible secondary controller index - in identify secondary controller +``cqes`` + Completion Queue Entry Size, see :c:type:`enum nvme_id_ctrl_cqes `. -``NVME_ID_ND_DESCRIPTOR_MAX`` - *undescribed* +``maxcmd`` + Maximum Outstanding Commands indicates the maximum number of + commands that the controller processes at one time for a + particular queue. -``NVME_FEAT_LBA_RANGE_MAX`` - The largest possible LBA range index in feature - lba range type +``nn`` + Number of Namespaces indicates the maximum value of a valid + nsid for the NVM subsystem. If the MNAN (:c:type:`struct nvme_id_ctrl `.mnan + field is cleared to 0h, then this field also indicates the + maximum number of namespaces supported by the NVM. subsystem. -``NVME_LOG_ST_MAX_RESULTS`` - The largest possible self test result index in the - device self test log +``oncs`` + Optional NVM Command Support, see :c:type:`enum nvme_id_ctrl_oncs `. -``NVME_LOG_TELEM_BLOCK_SIZE`` - Specification defined size of Telemetry Data Blocks +``fuses`` + Fused Operation Support, see :c:type:`enum nvme_id_ctrl_fuses `. -``NVME_DSM_MAX_RANGES`` - The largest possible range index in a data-set - management command +``fna`` + Format NVM Attributes, see :c:type:`enum nvme_id_ctrl_fna `. -``NVME_NQN_LENGTH`` - Max length for NVMe Qualified Name. - -``NVMF_TRADDR_SIZE`` - *undescribed* +``vwc`` + Volatile Write Cache, see :c:type:`enum nvme_id_ctrl_vwc `. -``NVMF_TSAS_SIZE`` - *undescribed* +``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. +``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. +``nvscc`` + NVM Vendor Specific Command Configuration, see + :c:type:`enum nvme_id_ctrl_nvscc `. +``nwpc`` + Namespace Write Protection Capabilities, see + :c:type:`enum nvme_id_ctrl_nwpc `. -.. c:type:: enum nvme_registers +``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. - The nvme controller registers for all transports. This is the layout of BAR0/1 for PCIe, and properties for fabrics. +``sgls`` + SGL Support, see :c:type:`enum nvme_id_ctrl_sgls ` -**Constants** +``mnan`` + Maximum Number of Allowed Namespaces indicates the maximum + number of namespaces supported by the NVM subsystem. -``NVME_REG_CAP`` - Controller Capabilities +``subnqn`` + NVM Subsystem NVMe Qualified Name, UTF-8 null terminated string -``NVME_REG_VS`` - Version +``ioccsz`` + I/O Queue Command Capsule Supported Size, defines the maximum + I/O command capsule size in 16 byte units. -``NVME_REG_INTMS`` - Interrupt Mask Set +``iorcsz`` + I/O Queue Response Capsule Supported Size, defines the maximum + I/O response capsule size in 16 byte units. -``NVME_REG_INTMC`` - Interrupt Mask Clear +``icdoff`` + In Capsule Data Offset, defines the offset where data starts + within a capsule. This value is applicable to I/O Queues only. -``NVME_REG_CC`` - Controller Configuration +``fcatt`` + Fabrics Controller Attributes, see :c:type:`enum nvme_id_ctrl_fcatt `. -``NVME_REG_CSTS`` - Controller Status +``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. -``NVME_REG_NSSR`` - NVM Subsystem Reset +``ofcs`` + Optional Fabric Commands Support, see :c:type:`enum nvme_id_ctrl_ofcs `. -``NVME_REG_AQA`` - Admin Queue Attributes +``psd`` + Power State Descriptors, see :c:type:`struct nvme_id_psd `. -``NVME_REG_ASQ`` - Admin SQ Base Address +``vs`` + Vendor Specific -``NVME_REG_ACQ`` - Admin CQ Base Address -``NVME_REG_CMBLOC`` - Controller Memory Buffer Location -``NVME_REG_CMBSZ`` - Controller Memory Buffer Size -``NVME_REG_BPINFO`` - Boot Partition Information -``NVME_REG_BPRSEL`` - Boot Partition Read Select +.. c:type:: enum nvme_id_ctrl_cmic -``NVME_REG_BPMBL`` - Boot Partition Memory Buffer Location -``NVME_REG_CMBMSC`` - Controller Memory Buffer Memory Space Control +**Constants** -``NVME_REG_CMBSTS`` - Controller Memory Buffer Status +``NVME_CTRL_CMIC_MULTI_PORT`` + *undescribed* -``NVME_REG_PMRCAP`` - Persistent Memory Capabilities +``NVME_CTRL_CMIC_MULTI_CTRL`` + *undescribed* -``NVME_REG_PMRCTL`` - Persistent Memory Region Control +``NVME_CTRL_CMIC_MULTI_SRIOV`` + *undescribed* -``NVME_REG_PMRSTS`` - Persistent Memory Region Status +``NVME_CTRL_CMIC_MULTI_ANA_REPORTING`` + *undescribed* -``NVME_REG_PMREBS`` - Persistent Memory Region Elasticity Buffer Size -``NVME_REG_PMRSWTP`` - Memory Region Sustained Write Throughput -``NVME_REG_PMRMSC`` - Persistent Memory Region Controller Memory Space Control -``NVME_REG_DBS`` - SQ 0 Tail Doorbell +.. c:type:: enum nvme_id_ctrl_oaes + The typical latency in microseconds to enter Runtime D3 -.. c:function:: bool nvme_is_64bit_reg (__u32 offset) +**Constants** - Checks if offset of the controller register is a know 64bit value. +``NVME_CTRL_OAES_NA`` + *undescribed* -**Parameters** +``NVME_CTRL_OAES_FA`` + *undescribed* -``__u32 offset`` - Offset of controller register field in bytes +``NVME_CTRL_OAES_ANA`` + *undescribed* -**Description** +``NVME_CTRL_OAES_PLEA`` + *undescribed* -This function does not care about transport so that the offset is not going -to be checked inside of this function for the unsupported fields in a -specific transport. For example, BPMBL(Boot Partition Memory Buffer -Location) register is not supported by fabrics, but it can be chcked here. +``NVME_CTRL_OAES_LBAS`` + : -Returns true if given offset is 64bit register, otherwise it returns false. +``NVME_CTRL_OAES_EGE`` + *undescribed* -.. c:type:: enum nvme_psd_flags +.. c:type:: enum nvme_id_ctrl_ctratt - Possible flag values in nvme power state descriptor **Constants** -``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. - -``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. +``NVME_CTRL_CTRATT_128_ID`` + *undescribed* +``NVME_CTRL_CTRATT_NON_OP_PSP`` + *undescribed* +``NVME_CTRL_CTRATT_NVM_SETS`` + *undescribed* +``NVME_CTRL_CTRATT_READ_RECV_LVLS`` + *undescribed* -.. c:type:: enum nvme_psd_ps +``NVME_CTRL_CTRATT_ENDURANCE_GROUPS`` + *undescribed* - Known values for :c:type:`struct nvme_psd ` #ips and #aps. Use with nvme_psd_power_scale() to extract the power scale field to match this enum. NVME_PSD_IPS_100_MICRO_WATT: 0.0001 watt scale NVME_PSD_IPS_10_MILLI_WATT: 0.01 watt scale +``NVME_CTRL_CTRATT_PREDICTABLE_LAT`` + *undescribed* -**Constants** +``NVME_CTRL_CTRATT_TBKAS`` + *undescribed* -``NVME_PSD_PS_100_MICRO_WATT`` +``NVME_CTRL_CTRATT_NAMESPACE_GRANULARITY`` *undescribed* -``NVME_PSD_PS_10_MILLI_WATT`` +``NVME_CTRL_CTRATT_SQ_ASSOCIATIONS`` *undescribed* +``NVME_CTRL_CTRATT_UUID_LIST`` + *undescribed* -.. c:function:: unsigned nvme_psd_power_scale (__u8 ps) - power scale occupies the upper 3 bits -**Parameters** -``__u8 ps`` - *undescribed* +.. c:type:: enum nvme_id_ctrl_cntrltype +**Constants** +``NVME_CTRL_CNTRLTYPE_IO`` + *undescribed* -.. c:type:: enum nvme_psd_workload +``NVME_CTRL_CNTRLTYPE_DISCOVERY`` + *undescribed* - Specifies a workload hint in the Power Management Feature (see :c:type:`struct nvme_psd `.apw) to inform the NVM subsystem or indicate the conditions for the active power level. +``NVME_CTRL_CNTRLTYPE_ADMIN`` + *undescribed* -**Constants** -``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. -``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 - NVM subsystem are idle. The submission queue(s) - should be sufficiently large allowing the host to - ensure there are multiple commands pending at all - times during the workload. +.. c:type:: enum nvme_id_ctrl_nvmsr + This field reports information associated with the NVM Subsystem, see :c:type:`struct nvme_id_ctrl `.nvmsr. +**Constants** -.. c:type:: struct nvme_id_psd +``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. +``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. -**Definition** -:: - struct nvme_id_psd { - __le16 mp; - __u8 rsvd2; - __u8 flags; - __le32 enlat; - __le32 exlat; - __u8 rrt; - __u8 rrl; - __u8 rwt; - __u8 rwl; - __le16 idlp; - __u8 ips; - __u8 rsvd19; - __le16 actp; - __u8 apw; - __u8 aps; - __u8 rsvd23[8]; - }; -**Members** +.. c:type:: enum nvme_id_ctrl_vwci -``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 :c:type:`enum nvme_psd_flags `). A value of 0 indicates - Maximum Power is not reported. + This field indicates information about remaining number of times that VPD contents are able to be updated using the VPD Write command, see :c:type:`struct nvme_id_ctrl `.vwci. -``flags`` - Additional decoding flags, see :c:type:`enum nvme_psd_flags `. +**Constants** -``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. +``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. -``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. +``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. -``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. -``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 -``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 +.. c:type:: enum nvme_id_ctrl_mec -``idlp`` - Idle Power indicates the typical power consumed by the NVM - subsystem over 30 seconds in this power state when idle. + Flags indicatings the capabilities of the Management Endpoint in the Controller, :c:type:`struct nvme_id_ctrl `.mec. -``ips`` - Idle Power Scale indicates the scale for :c:type:`struct nvme_id_psd `.idlp, - see :c:type:`enum nvme_psd_ps ` for decoding this field. +**Constants** -``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. +``NVME_CTRL_MEC_SMBUSME`` + If set, then the NVM Subsystem contains a Management + Endpoint on an SMBus/I2C port. -``apw`` - Active Power Workload indicates the workload used to calculate - maximum power for this power state. See :c:type:`enum nvme_psd_workload ` for - decoding this field. +``NVME_CTRL_MEC_PCIEME`` + If set, then the NVM Subsystem contains a Management + Endpoint on a PCIe port. -``aps`` - Active Power Scale indicates the scale for the :c:type:`struct - nvme_id_psd `.actp, see :c:type:`enum nvme_psd_ps ` for decoding this value. +.. c:type:: enum nvme_id_ctrl_oacs + Flags indicating the optional Admin commands and features supported by the controller, see :c:type:`struct nvme_id_ctrl `.oacs. -.. c:type:: struct nvme_id_ctrl +**Constants** - Identify Controller data structure +``NVME_CTRL_OACS_SECURITY`` + If set, then the controller supports the + Security Send and Security Receive commands. -**Definition** +``NVME_CTRL_OACS_FORMAT`` + If set then the controller supports the Format + NVM command. -:: +``NVME_CTRL_OACS_FW`` + If set, then the controller supports the + Firmware Commit and Firmware Image Download commands. - struct nvme_id_ctrl { - __le16 vid; - __le16 ssvid; - char sn[20]; - char mn[40]; - char fr[8]; - __u8 rab; - __u8 ieee[3]; - __u8 cmic; - __u8 mdts; - __le16 cntlid; - __le32 ver; - __le32 rtd3r; - __le32 rtd3e; - __le32 oaes; - __le32 ctratt; - __le16 rrls; - __u8 rsvd102[9]; - __u8 cntrltype; - __u8 fguid[16]; - __le16 crdt1; - __le16 crdt2; - __le16 crdt3; - __u8 rsvd134[119]; - __u8 nvmsr; - __u8 vwci; - __u8 mec; - __le16 oacs; - __u8 acl; - __u8 aerl; - __u8 frmw; - __u8 lpa; - __u8 elpe; - __u8 npss; - __u8 avscc; - __u8 apsta; - __le16 wctemp; - __le16 cctemp; - __le16 mtfa; - __le32 hmpre; - __le32 hmmin; - __u8 tnvmcap[16]; - __u8 unvmcap[16]; - __le32 rpmbs; - __le16 edstt; - __u8 dsto; - __u8 fwug; - __le16 kas; - __le16 hctma; - __le16 mntmt; - __le16 mxtmt; - __le32 sanicap; - __le32 hmminds; - __le16 hmmaxd; - __le16 nsetidmax; - __le16 endgidmax; - __u8 anatt; - __u8 anacap; - __le32 anagrpmax; - __le32 nanagrpid; - __le32 pels; - __u8 rsvd356[156]; - __u8 sqes; - __u8 cqes; - __le16 maxcmd; - __le32 nn; - __le16 oncs; - __le16 fuses; - __u8 fna; - __u8 vwc; - __le16 awun; - __le16 awupf; - __u8 nvscc; - __u8 nwpc; - __le16 acwu; - __u8 rsvd534[2]; - __le32 sgls; - __le32 mnan; - __u8 rsvd544[224]; - char subnqn[NVME_NQN_LENGTH]; - __u8 rsvd1024[768]; - __le32 ioccsz; - __le32 iorcsz; - __le16 icdoff; - __u8 fcatt; - __u8 msdbd; - __le16 ofcs; - __u8 rsvd1806[242]; - struct nvme_id_psd psd[32]; - __u8 vs[1024]; - }; +``NVME_CTRL_OACS_NS_MGMT`` + If set, then the controller supports the + Namespace Management capability -**Members** +``NVME_CTRL_OACS_SELF_TEST`` + If set, then the controller supports the Device + Self-test command. -``vid`` - PCI Vendor ID, the company vendor identifier that is assigned by - the PCI SIG. +``NVME_CTRL_OACS_DIRECTIVES`` + If set, then the controller supports Directives + and the Directive Send and Directive Receive + commands. -``ssvid`` - PCI Subsystem Vendor ID, the company vendor identifier that is - assigned by the PCI SIG for the subsystem. +``NVME_CTRL_OACS_NVME_MI`` + If set, then the controller supports the NVMe-MI + Send and NVMe-MI Receive commands. -``sn`` - Serial Number in ascii +``NVME_CTRL_OACS_VIRT_MGMT`` + If set, then the controller supports the + Virtualization Management command. -``mn`` - Model Number in ascii +``NVME_CTRL_OACS_DBBUF_CFG`` + If set, then the controller supports the + Doorbell Buffer Config command. -``fr`` - Firmware Revision in ascii, the currently active firmware - revision for the NVM subsystem +``NVME_CTRL_OACS_LBA_STATUS`` + If set, then the controller supports the Get LBA + Status capability. -``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 :c:type:`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 +.. c:type:: enum nvme_id_ctrl_frmw -``cntlid`` - Controller ID, the NVM subsystem unique controller identifier - associated with the controller. + Flags and values indicates capabilities regarding firmware updates from :c:type:`struct nvme_id_ctrl `.frmw. -``ver`` - Version, this field contains the value reported in the Version - register, or property (see :c:type:`enum nvme_registers ` ``NVME_REG_VS``). +**Constants** -``rtd3r`` - RTD3 Resume Latency, the expected latency in microseconds to resume - from Runtime D3 +``NVME_CTRL_FRMW_1ST_RO`` + If set, the first firmware slot is readonly -``rtd3e`` - RTD3 Exit Latency, the typical latency in microseconds to enter - Runtime D3. +``NVME_CTRL_FRMW_NR_SLOTS`` + Mask to get the value of the number of + firmware slots that the controller supports. -``oaes`` - Optional Async Events Supported, see **enum** nvme_id_ctrl_oaes . +``NVME_CTRL_FRMW_FW_ACT_NO_RESET`` + If set, the controller supports firmware + activation without a reset. -``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. -``cntrltype`` - Controller Type, see :c:type:`enum nvme_id_ctrl_cntrltype ` -``fguid`` - FRU GUID, a 128-bit value that is globally unique for a given - Field Replaceable Unit +.. c:type:: enum nvme_id_ctrl_lpa -``crdt1`` - Controller Retry Delay time in 100 millisecod units if CQE CRD - field is 1 + Flags indicating optional attributes for log pages that are accessed via the Get Log Page command. -``crdt2`` - Controller Retry Delay time in 100 millisecod units if CQE CRD - field is 2 +**Constants** -``crdt3`` - Controller Retry Delay time in 100 millisecod units if CQE CRD - field is 3 +``NVME_CTRL_LPA_SMART_PER_NS`` + *undescribed* -``nvmsr`` - NVM Subsystem Report, see :c:type:`enum nvme_id_ctrl_nvmsr ` +``NVME_CTRL_LPA_CMD_EFFECTS`` + *undescribed* -``vwci`` - VPD Write Cycle Information, see :c:type:`enum nvme_id_ctrl_vwci ` +``NVME_CTRL_LPA_EXTENDED`` + *undescribed* -``mec`` - Management Endpoint Capabilities, see :c:type:`enum nvme_id_ctrl_mec ` +``NVME_CTRL_LPA_TELEMETRY`` + *undescribed* -``oacs`` - Optional Admin Command Support,the optional Admin commands and - features supported by the controller, see :c:type:`enum nvme_id_ctrl_oacs `. +``NVME_CTRL_LPA_PERSETENT_EVENT`` + *undescribed* -``acl`` - Abort Command Limit, the maximum number of concurrently - 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. -``frmw`` - Firmware Updates indicates capabilities regarding firmware - updates. See :c:type:`enum nvme_id_ctrl_frmw `. -``lpa`` - Log Page Attributes, see :c:type:`enum nvme_id_ctrl_lpa `. +.. c:type:: enum nvme_id_ctrl_avscc -``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. + Flags indicating the configuration settings for Admin Vendor Specific command handling. -``npss`` - Number of Power States Supported, the number of NVM Express - power states supported by the controller, indicating the number - of valid entries in :c:type:`struct nvme_id_ctrl `.psd. This is a 0's - based value. +**Constants** -``avscc`` - Admin Vendor Specific Command Configuration, see :c:type:`enum - nvme_id_ctrl_avscc `. +``NVME_CTRL_AVSCC_AVS`` + If set, all Admin Vendor Specific Commands use the + optional vendor specific command format with NDT and + NDM fields. -``apsta`` - Autonomous Power State Transition Attributes, see :c:type:`enum - nvme_id_ctrl_apsta `. -``wctemp`` - Warning Composite Temperature Threshold indicates - the minimum Composite Temperature field value (see :c:type:`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 :c:type:`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. +.. c:type:: enum nvme_id_ctrl_apsta -``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. + Flags indicating the attributes of the autonomous power state transition feature. -``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. +**Constants** + +``NVME_CTRL_APSTA_APST`` + If set, then the controller supports autonomous power + state transitions. + + + + +.. c:type:: enum nvme_id_ctrl_rpmbs + + This field indicates if the controller supports one or more Replay Protected Memory Blocks, from :c:type:`struct nvme_id_ctrl `.rpmbs. + +**Constants** + +``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_ACCESS_SIZE`` + Mask to get the value of Access Size + + + + +.. c:type:: enum nvme_id_ctrl_dsto + + Flags indicating the optional Device Self-test command or operation behaviors supported by the controller or NVM subsystem. + +**Constants** + +``NVME_CTRL_DSTO_ONE_DST`` + If set, then the NVM subsystem supports only one + device self-test operation in progress at a time. + + + + +.. c:type:: enum nvme_id_ctrl_hctm + + Flags indicate the attributes of the host controlled thermal management feature + +**Constants** + +``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``. + + + + +.. c:type:: enum nvme_id_ctrl_sanicap + + Indicates attributes for sanitize operations. + +**Constants** + +``NVME_CTRL_SANICAP_CES`` + Crypto Erase Support. If set, then the + 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. + +``NVME_CTRL_SANICAP_OWS`` + Overwrite Support. If set, then the controller + 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. + +``NVME_CTRL_SANICAP_NODMMAS`` + No-Deallocate Modifies Media After Sanitize, + mask to extract value. -``tnvmcap`` - Total NVM Capacity, the total NVM capacity in the NVM subsystem. - 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 :c:type:`enum - nvme_id_ctrl_rpmbs `. - **edstt** Extended Device Self-test Time, if Device Self-test command is - supported (see :c:type:`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 :c:type:`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 +.. c:type:: enum nvme_id_ctrl_anacap -``kas`` - Keep Alive Support indicates the granularity of the Keep Alive - Timer in 100 millisecond units. + This field indicates the capabilities associated with Asymmetric Namespace Access Reporting. -``hctma`` - Host Controlled Thermal Management Attributes, see :c:type:`enum nvme_id_ctrl_hctm `. +**Constants** -``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. +``NVME_CTRL_ANACAP_OPT`` + If set, then the controller is able to + report ANA Optimized state. -``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. +``NVME_CTRL_ANACAP_NON_OPT`` + If set, then the controller is able to + report ANA Non-Optimized state. -``sanicap`` - Sanitize Capabilities, see :c:type:`enum nvme_id_ctrl_sanicap ` +``NVME_CTRL_ANACAP_INACCESSIBLE`` + If set, then the controller is able to + report ANA Inaccessible state. -``hmminds`` - Host Memory Buffer Minimum Descriptor Entry Size indicates the - minimum usable size of a Host Memory Buffer Descriptor Entry in - 4 KiB units. +``NVME_CTRL_ANACAP_PERSISTENT_LOSS`` + If set, then the controller is able to + report ANA Persistent Loss state. -``hmmaxd`` - Host Memory Maximum Descriptors Entries indicates the number of - usable Host Memory Buffer Descriptor Entries. +``NVME_CTRL_ANACAP_CHANGE`` + If set, then the controller is able to + report ANA Change state. -``nsetidmax`` - NVM Set Identifier Maximum, defines the maximum value of a valid - NVM Set Identifier for any controller in the NVM subsystem. +``NVME_CTRL_ANACAP_GRPID_NO_CHG`` + If set, then the ANAGRPID field in the + Identify Namespace data structure + (:c:type:`struct nvme_id_ns `.anagrpid), does not + change while the namespace is attached to + any controller. -``endgidmax`` - Endurance Group Identifier Maximum, defines the maximum value of - a valid Endurance Group Identifier for any controller in the NVM - subsystem. +``NVME_CTRL_ANACAP_GRPID_MGMT`` + If set, then the controller supports a + non-zero value in the ANAGRPID field of + the Namespace Management command. -``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. -``anacap`` - Asymmetric Namespace Access Capabilities, see :c:type:`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. -``nanagrpid`` - Number of ANA Group Identifiers indicates the number of ANA - groups supported by this controller. +.. c:type:: enum nvme_id_ctrl_sqes -``pels`` - Persistent Event Log Size indicates the maximum reportable size - for the Persistent Event Log. + Defines the required and maximum Submission Queue entry size when using the NVM Command Set. -``sqes`` - Submission Queue Entry Size, see :c:type:`enum nvme_id_ctrl_sqes `. +**Constants** -``cqes`` - Completion Queue Entry Size, see :c:type:`enum nvme_id_ctrl_cqes `. +``NVME_CTRL_SQES_MIN`` + Mask to get the value of the required Submission Queue + Entry size when using the NVM Command Set. -``maxcmd`` - Maximum Outstanding Commands indicates the maximum number of - commands that the controller processes at one time for a - particular queue. +``NVME_CTRL_SQES_MAX`` + Mask to get the value of the maximum Submission Queue + entry size when using the NVM Command Set. -``nn`` - Number of Namespaces indicates the maximum value of a valid - nsid for the NVM subsystem. If the MNAN (:c:type:`struct nvme_id_ctrl `.mnan - field is cleared to 0h, then this field also indicates the - maximum number of namespaces supported by the NVM. subsystem. -``oncs`` - Optional NVM Command Support, see :c:type:`enum nvme_id_ctrl_oncs `. -``fuses`` - Fused Operation Support, see :c:type:`enum nvme_id_ctrl_fuses `. -``fna`` - Format NVM Attributes, see :c:type:`enum nvme_id_ctrl_fna `. +.. c:type:: enum -``vwc`` - Volatile Write Cache, see :c:type:`enum nvme_id_ctrl_vwc `. + Defines the required and maximum Completion Queue entry size when using the NVM Command Set. -``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. +**Constants** -``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. +``NVME_CTRL_CQES_MIN`` + Mask to get the value of the required Completion Queue + Entry size when using the NVM Command Set. -``nvscc`` - NVM Vendor Specific Command Configuration, see :c:type:`enum - nvme_id_ctrl_nvscc `. +``NVME_CTRL_CQES_MAX`` + Mask to get the value of the maximum Completion Queue + entry size when using the NVM Command Set. -``nwpc`` - Namespace Write Protection Capabilities, see :c:type:`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. -``sgls`` - SGL Support, see :c:type:`enum nvme_id_ctrl_sgls ` -``mnan`` - Maximum Number of Allowed Namespaces indicates the maximum - number of namespaces supported by the NVM subsystem. +.. c:type:: enum nvme_id_ctrl_oncs -``subnqn`` - NVM Subsystem NVMe Qualified Name, UTF-8 null terminated string + This field indicates the optional NVM commands and features supported by the controller. -``ioccsz`` - I/O Queue Command Capsule Supported Size, defines the maximum - I/O command capsule size in 16 byte units. +**Constants** -``iorcsz`` - I/O Queue Response Capsule Supported Size, defines the maximum - I/O response capsule size in 16 byte units. +``NVME_CTRL_ONCS_COMPARE`` + If set, then the controller supports + the Compare command. -``icdoff`` - In Capsule Data Offset, defines the offset where data starts - within a capsule. This value is applicable to I/O Queues only. +``NVME_CTRL_ONCS_WRITE_UNCORRECTABLE`` + If set, then the controller supports + the Write Uncorrectable command. -``fcatt`` - Fabrics Controller Attributes, see :c:type:`enum nvme_id_ctrl_fcatt `. +``NVME_CTRL_ONCS_DSM`` + If set, then the controller supports + the Dataset Management command. -``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. +``NVME_CTRL_ONCS_WRITE_ZEROES`` + If set, then the controller supports + the Write Zeroes command. -``ofcs`` - Optional Fabric Commands Support, see :c:type:`enum nvme_id_ctrl_ofcs `. +``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. -``psd`` - Power State Descriptors, see :c:type:`struct nvme_id_psd `. +``NVME_CTRL_ONCS_RESERVATIONS`` + If set, then the controller supports + reservations. -``vs`` - Vendor Specific +``NVME_CTRL_ONCS_TIMESTAMP`` + If set, then the controller supports + the Timestamp feature. +``NVME_CTRL_ONCS_VERIFY`` + If set, then the controller supports + the Verify command. -.. c:type:: enum nvme_id_ctrl_cmic +.. c:type:: enum nvme_id_ctrl_fuses + This field indicates the fused operations that the controller supports. **Constants** -``NVME_CTRL_CMIC_MULTI_PORT`` - *undescribed* +``NVME_CTRL_FUSES_COMPARE_AND_WRITE`` + If set, then the controller supports the + Compare and Write fused operation. -``NVME_CTRL_CMIC_MULTI_CTRL`` - *undescribed* -``NVME_CTRL_CMIC_MULTI_SRIOV`` - *undescribed* -``NVME_CTRL_CMIC_MULTI_ANA_REPORTING`` - *undescribed* + +.. c:type:: enum nvme_id_ctrl_fna + + This field indicates attributes for the Format NVM command. + +**Constants** + +``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. + +``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. -.. c:type:: enum nvme_id_ctrl_oaes +.. c:type:: enum nvme_id_ctrl_vwc - The typical latency in microseconds to enter Runtime D3 **Constants** -``NVME_CTRL_OAES_NA`` - *undescribed* - -``NVME_CTRL_OAES_FA`` - *undescribed* - -``NVME_CTRL_OAES_ANA`` - *undescribed* - -``NVME_CTRL_OAES_PLEA`` - *undescribed* - -``NVME_CTRL_OAES_LBAS`` - : +``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``. -``NVME_CTRL_OAES_EGE`` - *undescribed* +``NVME_CTRL_VWC_FLUSH`` + Mask to get the value of the flush command behavior. -.. c:type:: enum nvme_id_ctrl_ctratt +.. c:type:: enum nvme_id_ctrl_nvscc + This field indicates the configuration settings for NVM Vendor Specific command handling. **Constants** -``NVME_CTRL_CTRATT_128_ID`` - *undescribed* +``NVME_CTRL_NVSCC_FMT`` + If set, all NVM Vendor Specific Commands use the + format format with NDT and NDM fields. -``NVME_CTRL_CTRATT_NON_OP_PSP`` - *undescribed* -``NVME_CTRL_CTRATT_NVM_SETS`` - *undescribed* -``NVME_CTRL_CTRATT_READ_RECV_LVLS`` - *undescribed* -``NVME_CTRL_CTRATT_ENDURANCE_GROUPS`` - *undescribed* +.. c:type:: enum nvme_id_ctrl_nwpc -``NVME_CTRL_CTRATT_PREDICTABLE_LAT`` - *undescribed* + This field indicates the optional namespace write protection capabilities supported by the controller. -``NVME_CTRL_CTRATT_TBKAS`` - *undescribed* +**Constants** -``NVME_CTRL_CTRATT_NAMESPACE_GRANULARITY`` - *undescribed* +``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. -``NVME_CTRL_CTRATT_SQ_ASSOCIATIONS`` - *undescribed* +``NVME_CTRL_NWPC_WRITE_PROTECT_POWER_CYCLE`` + If set, then the controller + supports the Write Protect Until + Power Cycle state. -``NVME_CTRL_CTRATT_UUID_LIST`` - *undescribed* +``NVME_CTRL_NWPC_WRITE_PROTECT_PERMANENT`` + If set, then the controller + supports the Permanent Write + Protect state. -.. c:type:: enum nvme_id_ctrl_cntrltype +.. c:type:: enum nvme_id_ctrl_sgls + This field indicates if SGLs are supported for the NVM Command Set and the particular SGL types supported. **Constants** -``NVME_CTRL_CNTRLTYPE_IO`` +``NVME_CTRL_SGLS_SUPPORTED`` *undescribed* -``NVME_CTRL_CNTRLTYPE_DISCOVERY`` +``NVME_CTRL_SGLS_KEYED`` *undescribed* -``NVME_CTRL_CNTRLTYPE_ADMIN`` +``NVME_CTRL_SGLS_BIT_BUCKET`` *undescribed* +``NVME_CTRL_SGLS_MPTR_BYTE_ALIGNED`` + *undescribed* +``NVME_CTRL_SGLS_OVERSIZE`` + *undescribed* +``NVME_CTRL_SGLS_MPTR_SGL`` + *undescribed* -.. c:type:: enum nvme_id_ctrl_nvmsr - - This field reports information associated with the NVM Subsystem, see :c:type:`struct nvme_id_ctrl `.nvmsr. - -**Constants** - -``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. +``NVME_CTRL_SGLS_OFFSET`` + *undescribed* -``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. +``NVME_CTRL_SGLS_TPORT`` + *undescribed* -.. c:type:: enum nvme_id_ctrl_vwci +.. c:type:: enum nvme_id_ctrl_fcatt - This field indicates information about remaining number of times that VPD contents are able to be updated using the VPD Write command, see :c:type:`struct nvme_id_ctrl `.vwci. + This field indicates attributes of the controller that are specific to NVMe over Fabrics. **Constants** -``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. - -``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. +``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. -.. c:type:: enum nvme_id_ctrl_mec +.. c:type:: enum nvme_id_ctrl_ofcs - Flags indicatings the capabilities of the Management Endpoint in the Controller, :c:type:`struct nvme_id_ctrl `.mec. + Indicate whether the controller supports optional fabric commands. **Constants** -``NVME_CTRL_MEC_SMBUSME`` - If set, then the NVM Subsystem contains a Management - Endpoint on an SMBus/I2C port. - -``NVME_CTRL_MEC_PCIEME`` - If set, then the NVM Subsystem contains a Management - Endpoint on a PCIe port. - - - +``NVME_CTRL_OFCS_DISCONNECT`` + If set, then the controller supports the + Disconnect command and deletion of individual + I/O Queues. -.. c:type:: enum nvme_id_ctrl_oacs - Flags indicating the optional Admin commands and features supported by the controller, see :c:type:`struct nvme_id_ctrl `.oacs. -**Constants** -``NVME_CTRL_OACS_SECURITY`` - If set, then the controller supports the - Security Send and Security Receive commands. +.. c:type:: struct nvme_lbaf -``NVME_CTRL_OACS_FORMAT`` - If set then the controller supports the Format - NVM command. + LBA Format Data Structure -``NVME_CTRL_OACS_FW`` - If set, then the controller supports the - Firmware Commit and Firmware Image Download commands. +**Definition** -``NVME_CTRL_OACS_NS_MGMT`` - If set, then the controller supports the - Namespace Management capability +:: -``NVME_CTRL_OACS_SELF_TEST`` - If set, then the controller supports the Device - Self-test command. + struct nvme_lbaf { + __le16 ms; + __u8 ds; + __u8 rp; + }; -``NVME_CTRL_OACS_DIRECTIVES`` - If set, then the controller supports Directives - and the Directive Send and Directive Receive - commands. +**Members** -``NVME_CTRL_OACS_NVME_MI`` - If set, then the controller supports the NVMe-MI - Send and NVMe-MI Receive commands. +``ms`` + Metadata Size indicates the number of metadata bytes provided per LBA + based on the LBA Data Size indicated. -``NVME_CTRL_OACS_VIRT_MGMT`` - If set, then the controller supports the - Virtualization Management command. +``ds`` + LBA Data Size indicates the LBA data size supported, reported as a + power of two. -``NVME_CTRL_OACS_DBBUF_CFG`` - If set, then the controller supports the - Doorbell Buffer Config command. +``rp`` + Relative Performance, see :c:type:`enum nvme_lbaf_rp `. -``NVME_CTRL_OACS_LBA_STATUS`` - If set, then the controller supports the Get LBA - Status capability. -.. c:type:: enum nvme_id_ctrl_frmw +.. c:type:: enum nvme_lbaf_rp - Flags and values indicates capabilities regarding firmware updates from :c:type:`struct nvme_id_ctrl `.frmw. + This field indicates the relative performance of the LBA format indicated relative to other LBA formats supported by the controller. **Constants** -``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. - -``NVME_CTRL_FRMW_FW_ACT_NO_RESET`` - If set, the controller supports firmware - activation without a reset. - +``NVME_LBAF_RP_BEST`` + Best performance +``NVME_LBAF_RP_BETTER`` + Better performance +``NVME_LBAF_RP_GOOD`` + Good performance -.. c:type:: enum nvme_id_ctrl_lpa +``NVME_LBAF_RP_DEGRADED`` + Degraded performance - Flags indicating optional attributes for log pages that are accessed via the Get Log Page command. +``NVME_LBAF_RP_MASK`` + Mask to get the relative performance value from the + field -**Constants** -``NVME_CTRL_LPA_SMART_PER_NS`` - *undescribed* -``NVME_CTRL_LPA_CMD_EFFECTS`` - *undescribed* -``NVME_CTRL_LPA_EXTENDED`` - *undescribed* +.. c:type:: struct nvme_id_ns -``NVME_CTRL_LPA_TELEMETRY`` - *undescribed* + Identify Namespace data structure -``NVME_CTRL_LPA_PERSETENT_EVENT`` - *undescribed* +**Definition** +:: + struct nvme_id_ns { + __le64 nsze; + __le64 ncap; + __le64 nuse; + __u8 nsfeat; + __u8 nlbaf; + __u8 flbas; + __u8 mc; + __u8 dpc; + __u8 dps; + __u8 nmic; + __u8 rescap; + __u8 fpi; + __u8 dlfeat; + __le16 nawun; + __le16 nawupf; + __le16 nacwu; + __le16 nabsn; + __le16 nabo; + __le16 nabspf; + __le16 noiob; + __u8 nvmcap[16]; + __le16 npwg; + __le16 npwa; + __le16 npdg; + __le16 npda; + __le16 nows; + __u8 rsvd74[18]; + __le32 anagrpid; + __u8 rsvd96[3]; + __u8 nsattr; + __le16 nvmsetid; + __le16 endgid; + __u8 nguid[16]; + __u8 eui64[8]; + struct nvme_lbaf lbaf[16]; + __u8 rsvd192[192]; + __u8 vs[3712]; + }; +**Members** -.. c:type:: enum nvme_id_ctrl_avscc +``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. - Flags indicating the configuration settings for Admin Vendor Specific command handling. +``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. -**Constants** +``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. -``NVME_CTRL_AVSCC_AVS`` - If set, all Admin Vendor Specific Commands use the - optional vendor specific command format with NDT and - NDM fields. +``nsfeat`` + Namespace Features, see :c:type:`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 :c:type:`struct nvme_id_ns `.labf. +``flbas`` + Formatted LBA Size, see :c:type:`enum nvme_id_ns_flbas `. +``mc`` + Metadata Capabilities, see :c:type:`enum nvme_id_ns_mc `. -.. c:type:: enum nvme_id_ctrl_apsta +``dpc`` + End-to-end Data Protection Capabilities, see + :c:type:`enum nvme_id_ns_dpc `. - Flags indicating the attributes of the autonomous power state transition feature. +``dps`` + End-to-end Data Protection Type Settings, see + :c:type:`enum nvme_id_ns_dps `. -**Constants** +``nmic`` + Namespace Multi-path I/O and Namespace Sharing Capabilities, see + :c:type:`enum nvme_id_ns_nmic `. -``NVME_CTRL_APSTA_APST`` - If set, then the controller supports autonomous power - state transitions. +``rescap`` + Reservation Capabilities, see :c:type:`enum nvme_id_ns_rescap `. +``fpi`` + Format Progress Indicator, see :c:type:`enum nvme_nd_ns_fpi `. +``dlfeat`` + Deallocate Logical Block Features, see :c:type:`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. -.. c:type:: enum nvme_id_ctrl_rpmbs +``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. - This field indicates if the controller supports one or more Replay Protected Memory Blocks, from :c:type:`struct nvme_id_ctrl `.rpmbs. +``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. -**Constants** +``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. -``NVME_CTRL_RPMBS_NR_UNITS`` - Mask to get the value of the Number of RPMB Units +``nabo`` + Namespace Atomic Boundary Offset indicates the LBA on this + namespace where the first atomic boundary starts. -``NVME_CTRL_RPMBS_AUTH_METHOD`` - Mask to get the value of the Authentication Method +``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. -``NVME_CTRL_RPMBS_TOTAL_SIZE`` - Mask to get the value of Total Size +``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. -``NVME_CTRL_RPMBS_ACCESS_SIZE`` - Mask to get the value of Access Size +``nvmcap`` + NVM Capacity indicates the total size of the NVM allocated to + 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. +``npwa`` + Namespace Preferred Write Alignment indicates the recommended + 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. -.. c:type:: enum nvme_id_ctrl_dsto +``npda`` + Namespace Preferred Deallocate Alignment indicates the + recommended alignment in logical blocks for the Dataset + Management command with the Attribute - Deallocate bit - Flags indicating the optional Device Self-test command or operation behaviors supported by the controller or NVM subsystem. +``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. -**Constants** +``anagrpid`` + ANA Group Identifier indicates the ANA Group Identifier of the + ANA group of which the namespace is a member. -``NVME_CTRL_DSTO_ONE_DST`` - If set, then the NVM subsystem supports only one - device self-test operation in progress at a time. +``nsattr`` + Namespace Attributes, see :c:type:`enum nvme_id_ns_attr `. +``nvmsetid`` + NVM Set Identifier indicates the NVM Set with which this + namespace is associated. +``endgid`` + Endurance Group Identifier indicates the Endurance Group with + 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 -.. c:type:: enum nvme_id_ctrl_hctm +``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 + remains fixed throughout the life of the namespace and is + preserved across namespace and controller operations - Flags indicate the attributes of the host controlled thermal management feature +``lbaf`` + LBA Format, see :c:type:`struct nvme_lbaf `. -**Constants** +``vs`` + Vendor Specific -``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``. -.. c:type:: enum nvme_id_ctrl_sanicap +.. c:type:: enum nvme_id_nsfeat - Indicates attributes for sanitize operations. + This field defines features of the namespace. **Constants** -``NVME_CTRL_SANICAP_CES`` - Crypto Erase Support. If set, then the - controller supports the Crypto Erase sanitize operation. +``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. -``NVME_CTRL_SANICAP_BES`` - Block Erase Support. If set, then the controller - supports the Block Erase sanitize operation. +``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. -``NVME_CTRL_SANICAP_OWS`` - Overwrite Support. If set, then the controller - supports the Overwrite sanitize operation. +``NVME_NS_FEAT_DULBE`` + If set, indicates that the controller supports the + 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. -``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. +``NVME_NS_FEAT_ID_REUSE`` + *undescribed* -``NVME_CTRL_SANICAP_NODMMAS`` - No-Deallocate Modifies Media After Sanitize, - mask to extract value. +``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 -.. c:type:: enum nvme_id_ctrl_anacap +.. c:type:: enum nvme_id_ns_flbas - This field indicates the capabilities associated with Asymmetric Namespace Access Reporting. + This field indicates the LBA data size & metadata size combination that the namespace has been formatted with **Constants** -``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. - -``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. - -``NVME_CTRL_ANACAP_GRPID_NO_CHG`` - If set, then the ANAGRPID field in the - Identify Namespace data structure - (:c:type:`struct nvme_id_ns `.anagrpid), does not - change while the namespace is attached to - any controller. +``NVME_NS_FLBAS_LBA_MASK`` + Mask to get the index of one of the 16 supported + LBA Formats indicated in :c:type:`struct nvme_id_ns `.lbaf. -``NVME_CTRL_ANACAP_GRPID_MGMT`` - If set, then the controller supports a - non-zero value in the ANAGRPID field of - the Namespace Management command. +``NVME_NS_FLBAS_META_EXT`` + Applicable only if format contains metadata. If + this bit is set, indicates that the metadata is + transferred at the end of the data LBA, creating an + extended data LBA. If cleared, indicates that all + of the metadata for a command is transferred as a + separate contiguous buffer of data. -.. c:type:: enum nvme_id_ctrl_sqes +.. c:type:: enum nvme_id_ns_mc - Defines the required and maximum Submission Queue entry size when using the NVM Command Set. + This field indicates the capabilities for metadata. **Constants** -``NVME_CTRL_SQES_MIN`` - Mask to get the value of the required Submission Queue - Entry size when using the NVM Command Set. +``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. -``NVME_CTRL_SQES_MAX`` - Mask to get the value of the maximum Submission Queue - entry size when using the NVM Command Set. +``NVME_NS_MC_SEPARATE`` + If set, indicates that the namespace supports the + metadata being transferred as part of an extended data LBA. -.. c:type:: enum +.. c:type:: enum nvme_id_ns_dpc - Defines the required and maximum Completion Queue entry size when using the NVM Command Set. + This field indicates the capabilities for the end-to-end data protection feature. **Constants** -``NVME_CTRL_CQES_MIN`` - Mask to get the value of the required Completion Queue - Entry size when using the NVM Command Set. +``NVME_NS_DPC_PI_TYPE1`` + If set, indicates that the namespace supports + Protection Information Type 1. -``NVME_CTRL_CQES_MAX`` - Mask to get the value of the maximum Completion Queue - entry size when using the NVM Command Set. +``NVME_NS_DPC_PI_TYPE2`` + If set, indicates that the namespace supports + Protection Information Type 2. +``NVME_NS_DPC_PI_TYPE3`` + If set, indicates that the namespace supports + 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. +``NVME_NS_DPC_PI_LAST`` + If set, indicates that the namespace supports + protection information transferred as the last eight + bytes of metadata. -.. c:type:: enum nvme_id_ctrl_oncs - This field indicates the optional NVM commands and features supported by the controller. -**Constants** -``NVME_CTRL_ONCS_COMPARE`` - If set, then the controller supports - the Compare command. +.. c:type:: enum nvme_id_ns_dps -``NVME_CTRL_ONCS_WRITE_UNCORRECTABLE`` - If set, then the controller supports - the Write Uncorrectable command. + This field indicates the Type settings for the end-to-end data protection feature. -``NVME_CTRL_ONCS_DSM`` - If set, then the controller supports - the Dataset Management command. +**Constants** -``NVME_CTRL_ONCS_WRITE_ZEROES`` - If set, then the controller supports - the Write Zeroes command. +``NVME_NS_DPS_PI_NONE`` + Protection information is not enabled -``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. +``NVME_NS_DPS_PI_TYPE1`` + Protection information is enabled, Type 1 -``NVME_CTRL_ONCS_RESERVATIONS`` - If set, then the controller supports - reservations. +``NVME_NS_DPS_PI_TYPE2`` + Protection information is enabled, Type 2 -``NVME_CTRL_ONCS_TIMESTAMP`` - If set, then the controller supports - the Timestamp feature. +``NVME_NS_DPS_PI_TYPE3`` + Protection information is enabled, Type 3 -``NVME_CTRL_ONCS_VERIFY`` - If set, then the controller supports - the Verify command. +``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. -.. c:type:: enum nvme_id_ctrl_fuses +.. c:type:: enum nvme_id_ns_nmic - This field indicates the fused operations that the controller supports. + This field specifies multi-path I/O and namespace sharing capabilities of the namespace. **Constants** -``NVME_CTRL_FUSES_COMPARE_AND_WRITE`` - If set, then the controller supports the - Compare and Write fused operation. +``NVME_NS_NMIC_SHARED`` + If set, then the namespace may be attached to two or + more controllers in the NVM subsystem concurrently -.. c:type:: enum nvme_id_ctrl_fna +.. c:type:: enum nvme_id_ns_rescap - This field indicates attributes for the Format NVM command. + This field indicates the reservation capabilities of the namespace. **Constants** -``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. +``NVME_NS_RESCAP_PTPL`` + If set, indicates that the namespace supports the + Persist Through Power Loss capability. -``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_NS_RESCAP_WE`` + If set, indicates that the namespace supports the + Write Exclusive reservation type. -``NVME_CTRL_FNA_CRYPTO_ERASE`` - If set, then cryptographic erase is - supported. If cleared, then cryptographic - erase is not supported. +``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. +``NVME_NS_RESCAP_EARO`` + If set, indicates that the namespace supports the + Exclusive Access - Registrants Only reservation type. +``NVME_NS_RESCAP_WEAR`` + If set, indicates that the namespace supports the + Write Exclusive - All Registrants reservation type. -.. c:type:: enum nvme_id_ctrl_vwc +``NVME_NS_RESCAP_EAAR`` + If set, indicates that the namespace supports the + 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. -**Constants** -``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``. -``NVME_CTRL_VWC_FLUSH`` - Mask to get the value of the flush command behavior. +.. c:type:: 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. +**Constants** -.. c:type:: enum nvme_id_ctrl_nvscc +``NVME_NS_FPI_REMAINING`` + Mask to get the format percent remaining value - This field indicates the configuration settings for NVM Vendor Specific command handling. +``NVME_NS_FPI_SUPPORTED`` + If set, indicates that the namespace supports the + Format Progress Indicator defined for the field. -**Constants** -``NVME_CTRL_NVSCC_FMT`` - If set, all NVM Vendor Specific Commands use the - format format with NDT and NDM fields. +.. c:type:: enum nvme_id_ns_dlfeat + This field indicates information about features that affect deallocating logical blocks for this namespace. -.. c:type:: enum nvme_id_ctrl_nwpc +**Constants** - This field indicates the optional namespace write protection capabilities supported by the controller. +``NVME_NS_DLFEAT_RB`` + Mask to get the value of the read behavior -**Constants** +``NVME_NS_DLFEAT_RB_NR`` + Read behvaior is not reported -``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. +``NVME_NS_DLFEAT_RB_ALL_0S`` + A deallocated logical block returns all bytes + cleared to 0h. -``NVME_CTRL_NWPC_WRITE_PROTECT_POWER_CYCLE`` - If set, then the controller - supports the Write Protect Until - Power Cycle state. +``NVME_NS_DLFEAT_RB_ALL_FS`` + A deallocated logical block returns all bytes + set to FFh. -``NVME_CTRL_NWPC_WRITE_PROTECT_PERMANENT`` - If set, then the controller - supports the Permanent Write - Protect state. +``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 -.. c:type:: enum nvme_id_ctrl_sgls - This field indicates if SGLs are supported for the NVM Command Set and the particular SGL types supported. +.. c:type:: enum nvme_id_ns_attr -**Constants** + Specifies attributes of the namespace. -``NVME_CTRL_SGLS_SUPPORTED`` - *undescribed* +**Constants** -``NVME_CTRL_SGLS_KEYED`` - *undescribed* +``NVME_NS_NSATTR_WRITE_PROTECTED`` + If set, then the namespace is currently + write protected and all write access to the + namespace shall fail. -``NVME_CTRL_SGLS_BIT_BUCKET`` - *undescribed* -``NVME_CTRL_SGLS_MPTR_BYTE_ALIGNED`` - *undescribed* -``NVME_CTRL_SGLS_OVERSIZE`` - *undescribed* -``NVME_CTRL_SGLS_MPTR_SGL`` - *undescribed* +.. c:type:: struct nvme_ns_id_desc -``NVME_CTRL_SGLS_OFFSET`` - *undescribed* -``NVME_CTRL_SGLS_TPORT`` - *undescribed* +**Definition** +:: + struct nvme_ns_id_desc { + __u8 nidt; + __u8 nidl; + __le16 reserved; + __u8 nid[]; + }; +**Members** -.. c:type:: enum nvme_id_ctrl_fcatt +``nidt`` + Namespace Identifier Type, see :c:type:`enum nvme_ns_id_desc_nidt ` - This field indicates attributes of the controller that are specific to NVMe over Fabrics. +``nidl`` + Namespace Identifier Length contains the length in bytes of the + :c:type:`struct nvme_id_ns `.nid. -**Constants** +``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 :c:type:`struct nvme_id_ns `.nidl. -``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. -.. c:type:: enum nvme_id_ctrl_ofcs +.. c:type:: enum nvme_ns_id_desc_nidt - Indicate whether the controller supports optional fabric commands. + Known namespace identifier types **Constants** -``NVME_CTRL_OFCS_DISCONNECT`` - If set, then the controller supports the - Disconnect command and deletion of individual - I/O Queues. +``NVME_NIDT_EUI64`` + IEEE Extended Unique Identifier, the NID field contains a + 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. +``NVME_NIDT_UUID`` + The NID field contains a 128-bit Universally Unique + Identifier (UUID) as specified in RFC 4122. -.. c:type:: struct nvme_lbaf - LBA Format Data Structure +.. c:type:: struct nvme_nvmset_attr + + NVM Set Attributes Entry **Definition** :: - struct nvme_lbaf { - __le16 ms; - __u8 ds; - __u8 rp; + struct nvme_nvmset_attr { + __le16 id; + __le16 endurance_group_id; + __u8 rsvd4[4]; + __le32 random_4k_read_typical; + __le32 opt_write_size; + __u8 total_nvmset_cap[16]; + __u8 unalloc_nvmset_cap[16]; + __u8 rsvd48[80]; }; **Members** -``ms`` - Metadata Size indicates the number of metadata bytes provided per LBA - based on the LBA Data Size indicated. +``id`` + NVM Set Identifier -``ds`` - LBA Data Size indicates the LBA data size supported, reported as a - power of two. +``endurance_group_id`` + Endurance Group Identifier -``rp`` - Relative Performance, see :c:type:`enum nvme_lbaf_rp `. +``random_4k_read_typical`` + Random 4 KiB Read Typical indicates the typical + time to complete a 4 KiB random read in 100 + nanosecond units when the NVM Set is in a + Predictable Latency Mode Deterministic Window and + there is 1 outstanding command per NVM Set. -.. c:type:: enum nvme_lbaf_rp +.. c:type:: struct nvme_id_nvmset_list - This field indicates the relative performance of the LBA format indicated relative to other LBA formats supported by the controller. + **nid**; -**Constants** +**Definition** -``NVME_LBAF_RP_BEST`` - Best performance +:: -``NVME_LBAF_RP_BETTER`` - Better performance + struct nvme_id_nvmset_list { + __u8 nid; + __u8 rsvd1[127]; + struct nvme_nvmset_attr ent[NVME_ID_NVMSET_LIST_MAX]; + }; -``NVME_LBAF_RP_GOOD`` - Good performance +**Members** -``NVME_LBAF_RP_DEGRADED`` - Degraded performance +``ent`` + ; -``NVME_LBAF_RP_MASK`` - Mask to get the relative performance value from the - field -.. c:type:: struct nvme_id_ns +.. c:type:: struct nvme_id_ns_granularity_desc - Identify Namespace data structure **Definition** :: - struct nvme_id_ns { - __le64 nsze; - __le64 ncap; - __le64 nuse; - __u8 nsfeat; - __u8 nlbaf; - __u8 flbas; - __u8 mc; - __u8 dpc; - __u8 dps; - __u8 nmic; - __u8 rescap; - __u8 fpi; - __u8 dlfeat; - __le16 nawun; - __le16 nawupf; - __le16 nacwu; - __le16 nabsn; - __le16 nabo; - __le16 nabspf; - __le16 noiob; - __u8 nvmcap[16]; - __le16 npwg; - __le16 npwa; - __le16 npdg; - __le16 npda; - __le16 nows; - __u8 rsvd74[18]; - __le32 anagrpid; - __u8 rsvd96[3]; - __u8 nsattr; - __le16 nvmsetid; - __le16 endgid; - __u8 nguid[16]; - __u8 eui64[8]; - struct nvme_lbaf lbaf[16]; - __u8 rsvd192[192]; - __u8 vs[3712]; + struct nvme_id_ns_granularity_desc { + __le64 namespace_size_granularity; + __le64 namespace_capacity_granularity; }; **Members** -``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. -``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. -``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. -``nsfeat`` - Namespace Features, see :c:type:`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 :c:type:`struct nvme_id_ns `.labf. +.. c:type:: struct nvme_id_ns_granularity_list -``flbas`` - Formatted LBA Size, see :c:type:`enum nvme_id_ns_flbas `. -``mc`` - Metadata Capabilities, see :c:type:`enum nvme_id_ns_mc `. +**Definition** -``dpc`` - End-to-end Data Protection Capabilities, see :c:type:`enum - nvme_id_ns_dpc `. +:: -``dps`` - End-to-end Data Protection Type Settings, see :c:type:`enum - nvme_id_ns_dps `. + struct nvme_id_ns_granularity_list { + __le32 attributes; + __u8 num_descriptors; + __u8 rsvd[27]; + struct nvme_id_ns_granularity_desc entry[NVME_ID_ND_DESCRIPTOR_MAX]; + __u8 rsvd288[3808]; + }; -``nmic`` - Namespace Multi-path I/O and Namespace Sharing Capabilities, see - :c:type:`enum nvme_id_ns_nmic `. +**Members** -``rescap`` - Reservation Capabilities, see :c:type:`enum nvme_id_ns_rescap `. -``fpi`` - Format Progress Indicator, see :c:type:`enum nvme_nd_ns_fpi `. -``dlfeat`` - Deallocate Logical Block Features, see :c:type:`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. -``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. +.. c:type:: struct nvme_id_uuid_list_entry -``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. -``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. +**Definition** -``nabo`` - Namespace Atomic Boundary Offset indicates the LBA on this - 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. + struct nvme_id_uuid_list_entry { + __u8 header; + __u8 rsvd1[15]; + __u8 uuid[16]; + }; -``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. +**Members** -``nvmcap`` - NVM Capacity indicates the total size of the NVM allocated to - 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. -``npwa`` - Namespace Preferred Write Alignment indicates the recommended - 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. -``npda`` - Namespace Preferred Deallocate Alignment indicates the - recommended alignment in logical blocks for the Dataset - Management command with the Attribute - Deallocate bit +.. c:type:: enum + + +**Constants** + +``NVME_ID_UUID_HDR_ASSOCIATION_MASK`` + *undescribed* + +``NVME_ID_UUID_ASSOCIATION_NONE`` + *undescribed* -``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. +``NVME_ID_UUID_ASSOCIATION_VENDOR`` + *undescribed* -``anagrpid`` - ANA Group Identifier indicates the ANA Group Identifier of the - ANA group of which the namespace is a member. +``NVME_ID_UUID_ASSOCIATION_SUBSYSTEM_VENDOR`` + *undescribed* -``nsattr`` - Namespace Attributes, see :c:type:`enum nvme_id_ns_attr `. -``nvmsetid`` - NVM Set Identifier indicates the NVM Set with which this - namespace is associated. -``endgid`` - Endurance Group Identifier indicates the Endurance Group with - 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 +.. c:type:: struct nvme_id_uuid_list -``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 - remains fixed throughout the life of the namespace and is - preserved across namespace and controller operations -``lbaf`` - LBA Format, see :c:type:`struct nvme_lbaf `. +**Definition** -``vs`` - Vendor Specific +:: + struct nvme_id_uuid_list { + __u8 rsvd0[32]; + struct nvme_id_uuid_list_entry entry[NVME_ID_UUID_LIST_MAX]; + }; +**Members** -.. c:type:: enum nvme_id_nsfeat - This field defines features of the namespace. -**Constants** +.. c:type:: struct nvme_ctrl_list -``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. + **num**; -``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. +**Definition** -``NVME_NS_FEAT_DULBE`` - If set, indicates that the controller supports the - 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. +:: -``NVME_NS_FEAT_ID_REUSE`` - *undescribed* + struct nvme_ctrl_list { + __le16 num; + __le16 identifier[NVME_ID_CTRL_LIST_MAX]; + }; -``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 +**Members** -.. c:type:: enum nvme_id_ns_flbas - This field indicates the LBA data size & metadata size combination that the namespace has been formatted with +.. c:type:: struct nvme_ns_list -**Constants** -``NVME_NS_FLBAS_LBA_MASK`` - Mask to get the index of one of the 16 supported - LBA Formats indicated in :c:type:`struct nvme_id_ns `.lbaf. +**Definition** -``NVME_NS_FLBAS_META_EXT`` - Applicable only if format contains metadata. If - this bit is set, indicates that the metadata is - transferred at the end of the data LBA, creating an - extended data LBA. If cleared, indicates that all - of the metadata for a command is transferred as a - separate contiguous buffer of data. +:: + struct nvme_ns_list { + __le32 ns[NVME_ID_NS_LIST_MAX]; + }; +**Members** -.. c:type:: enum nvme_id_ns_mc - This field indicates the capabilities for metadata. -**Constants** -``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. +.. c:type:: struct nvme_primary_ctrl_cap -``NVME_NS_MC_SEPARATE`` - If set, indicates that the namespace supports the - metadata being transferred as part of an extended data LBA. +**Definition** + +:: + struct nvme_primary_ctrl_cap { + __le16 cntlid; + __le16 portid; + __u8 crt; + __u8 rsvd5[27]; + __le32 vqfrt; + __le32 vqrfa; + __le16 vqrfap; + __le16 vqprt; + __le16 vqfrsm; + __le16 vqgran; + __u8 rsvd48[16]; + __le32 vifrt; + __le32 virfa; + __le16 virfap; + __le16 viprt; + __le16 vifrsm; + __le16 vigran; + __u8 rsvd80[4016]; + }; +**Members** -.. c:type:: enum nvme_id_ns_dpc - This field indicates the capabilities for the end-to-end data protection feature. -**Constants** -``NVME_NS_DPC_PI_TYPE1`` - If set, indicates that the namespace supports - Protection Information Type 1. -``NVME_NS_DPC_PI_TYPE2`` - If set, indicates that the namespace supports - Protection Information Type 2. +.. c:type:: struct nvme_secondary_ctrl -``NVME_NS_DPC_PI_TYPE3`` - If set, indicates that the namespace supports - 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. +**Definition** -``NVME_NS_DPC_PI_LAST`` - If set, indicates that the namespace supports - protection information transferred as the last eight - bytes of metadata. +:: + struct nvme_secondary_ctrl { + __le16 scid; + __le16 pcid; + __u8 scs; + __u8 rsvd5[3]; + __le16 vfn; + __le16 nvq; + __le16 nvi; + __u8 rsvd14[18]; + }; +**Members** -.. c:type:: enum nvme_id_ns_dps - This field indicates the Type settings for the end-to-end data protection feature. -**Constants** -``NVME_NS_DPS_PI_NONE`` - Protection information is not enabled +.. c:type:: struct nvme_secondary_ctrl_list -``NVME_NS_DPS_PI_TYPE1`` - Protection information is enabled, Type 1 + **num**; -``NVME_NS_DPS_PI_TYPE2`` - Protection information is enabled, Type 2 +**Definition** -``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 + struct nvme_secondary_ctrl_list { + __u8 num; + __u8 rsvd[31]; + struct nvme_secondary_ctrl sc_entry[NVME_ID_SECONDARY_CTRL_MAX]; + }; -``NVME_NS_DPS_PI_FIRST`` - If set, indicates that the protection information, if - enabled, is transferred as the first eight bytes of - metadata. +**Members** -.. c:type:: enum nvme_id_ns_nmic - This field specifies multi-path I/O and namespace sharing capabilities of the namespace. +.. c:type:: struct nvme_error_log_page -**Constants** -``NVME_NS_NMIC_SHARED`` - If set, then the namespace may be attached to two or - more controllers in the NVM subsystem concurrently +**Definition** +:: + struct nvme_error_log_page { + __le64 error_count; + __le16 sqid; + __le16 cmdid; + __le16 status_field; + __le16 parm_error_location; + __le64 lba; + __le32 nsid; + __u8 vs; + __u8 trtype; + __u8 rsvd[2]; + __le64 cs; + __le16 trtype_spec_info; + __u8 rsvd2[22]; + }; +**Members** -.. c:type:: enum nvme_id_ns_rescap - This field indicates the reservation capabilities of the namespace. -**Constants** -``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. +.. c:type:: enum -``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. +**Constants** -``NVME_NS_RESCAP_EARO`` - If set, indicates that the namespace supports the - Exclusive Access - Registrants Only reservation type. +``NVME_ERR_PEL_BYTE_MASK`` + *undescribed* -``NVME_NS_RESCAP_WEAR`` - If set, indicates that the namespace supports the - Write Exclusive - All Registrants reservation type. +``NVME_ERR_PEL_BIT_MASK`` + *undescribed* -``NVME_NS_RESCAP_EAAR`` - If set, indicates that the namespace supports the - 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. +.. c:type:: struct nvme_smart_log -.. c:type:: enum nvme_nd_ns_fpi +**Definition** - If a format operation is in progress, this field indicates the percentage of the namespace that remains to be formatted. +:: -**Constants** + struct nvme_smart_log { + __u8 critical_warning; + __u8 temperature[2]; + __u8 avail_spare; + __u8 spare_thresh; + __u8 percent_used; + __u8 endu_grp_crit_warn_sumry; + __u8 rsvd7[25]; + __u8 data_units_read[16]; + __u8 data_units_written[16]; + __u8 host_reads[16]; + __u8 host_writes[16]; + __u8 ctrl_busy_time[16]; + __u8 power_cycles[16]; + __u8 power_on_hours[16]; + __u8 unsafe_shutdowns[16]; + __u8 media_errors[16]; + __u8 num_err_log_entries[16]; + __le32 warning_temp_time; + __le32 critical_comp_time; + __le16 temp_sensor[8]; + __le32 thm_temp1_trans_count; + __le32 thm_temp2_trans_count; + __le32 thm_temp1_total_time; + __le32 thm_temp2_total_time; + __u8 rsvd232[280]; + }; -``NVME_NS_FPI_REMAINING`` - Mask to get the format percent remaining value +**Members** -``NVME_NS_FPI_SUPPORTED`` - If set, indicates that the namespace supports the - Format Progress Indicator defined for the field. -.. c:type:: enum nvme_id_ns_dlfeat +.. c:type:: enum - This field indicates information about features that affect deallocating logical blocks for this namespace. **Constants** -``NVME_NS_DLFEAT_RB`` - Mask to get the value of the read behavior +``NVME_SMART_CRIT_SPARE`` + *undescribed* -``NVME_NS_DLFEAT_RB_NR`` - Read behvaior is not reported +``NVME_SMART_CRIT_TEMPERATURE`` + *undescribed* -``NVME_NS_DLFEAT_RB_ALL_0S`` - A deallocated logical block returns all bytes - cleared to 0h. +``NVME_SMART_CRIT_DEGRADED`` + *undescribed* -``NVME_NS_DLFEAT_RB_ALL_FS`` - A deallocated logical block returns all bytes - set to FFh. +``NVME_SMART_CRIT_MEDIA`` + *undescribed* -``NVME_NS_DLFEAT_WRITE_ZEROES`` - If set, indicates that the controller supports - the Deallocate bit in the Write Zeroes command - for this namespace. +``NVME_SMART_CRIT_VOLATILE_MEMORY`` + *undescribed* -``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 +``NVME_SMART_CRIT_PMR_RO`` + *undescribed* -.. c:type:: enum nvme_id_ns_attr +.. c:type:: enum - Specifies attributes of the namespace. **Constants** -``NVME_NS_NSATTR_WRITE_PROTECTED`` - If set, then the namespace is currently - write protected and all write access to the - namespace shall fail. +``NVME_SMART_EGCW_SPARE`` + *undescribed* + +``NVME_SMART_EGCW_DEGRADED`` + *undescribed* +``NVME_SMART_EGCW_RO`` + *undescribed* -.. c:type:: struct nvme_ns_id_desc + +.. c:type:: struct nvme_firmware_slot **Definition** :: - struct nvme_ns_id_desc { - __u8 nidt; - __u8 nidl; - __le16 reserved; - __u8 nid[]; + struct nvme_firmware_slot { + __u8 afi; + __u8 resv[7]; + char frs[7][8]; + __u8 resv2[448]; }; **Members** -``nidt`` - Namespace Identifier Type, see :c:type:`enum nvme_ns_id_desc_nidt ` - -``nidl`` - Namespace Identifier Length contains the length in bytes of the - :c:type:`struct nvme_id_ns `.nid. - -``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 :c:type:`struct nvme_id_ns `.nidl. +.. c:type:: struct nvme_cmd_effects_log -.. c:type:: enum nvme_ns_id_desc_nidt - Known namespace identifier types +**Definition** -**Constants** +:: -``NVME_NIDT_EUI64`` - IEEE Extended Unique Identifier, the NID field contains a - copy of the EUI64 field in the struct nvme_id_ns.eui64. + struct nvme_cmd_effects_log { + __le32 acs[256]; + __le32 iocs[256]; + __u8 rsvd[2048]; + }; -``NVME_NIDT_NGUID`` - Namespace Globally Unique Identifier, the NID field - contains a copy of the NGUID field in struct nvme_id_ns.nguid. +**Members** -``NVME_NIDT_UUID`` - The NID field contains a 128-bit Universally Unique - Identifier (UUID) as specified in RFC 4122. -.. c:type:: struct nvme_nvmset_attr +.. c:type:: enum - NVM Set Attributes Entry -**Definition** +**Constants** -:: +``NVME_CMD_EFFECTS_CSUPP`` + *undescribed* - struct nvme_nvmset_attr { - __le16 id; - __le16 endurance_group_id; - __u8 rsvd4[4]; - __le32 random_4k_read_typical; - __le32 opt_write_size; - __u8 total_nvmset_cap[16]; - __u8 unalloc_nvmset_cap[16]; - __u8 rsvd48[80]; - }; +``NVME_CMD_EFFECTS_LBCC`` + *undescribed* -**Members** +``NVME_CMD_EFFECTS_NCC`` + *undescribed* -``id`` - NVM Set Identifier +``NVME_CMD_EFFECTS_NIC`` + *undescribed* -``endurance_group_id`` - Endurance Group Identifier +``NVME_CMD_EFFECTS_CCC`` + *undescribed* -``random_4k_read_typical`` - Random 4 KiB Read Typical indicates the typical - time to complete a 4 KiB random read in 100 - nanosecond units when the NVM Set is in a - Predictable Latency Mode Deterministic Window and - there is 1 outstanding command per NVM Set. +``NVME_CMD_EFFECTS_CSE_MASK`` + *undescribed* +``NVME_CMD_EFFECTS_UUID_SEL`` + *undescribed* -.. c:type:: struct nvme_id_nvmset_list +.. c:type:: struct nvme_st_result - **nid**; **Definition** :: - struct nvme_id_nvmset_list { - __u8 nid; - __u8 rsvd1[127]; - struct nvme_nvmset_attr ent[NVME_ID_NVMSET_LIST_MAX]; + struct nvme_st_result { + __u8 dsts; + __u8 seg; + __u8 vdi; + __u8 rsvd; + __le64 poh; + __le32 nsid; + __le64 flba; + __u8 sct; + __u8 sc; + __u8 vs[2]; }; **Members** -``ent`` - ; - -.. c:type:: struct nvme_id_ns_granularity_desc - +.. c:type:: enum -**Definition** -:: +**Constants** - struct nvme_id_ns_granularity_desc { - __le64 namespace_size_granularity; - __le64 namespace_capacity_granularity; - }; +``NVME_ST_RESULT_NO_ERR`` + *undescribed* -**Members** +``NVME_ST_RESULT_ABORTED`` + *undescribed* +``NVME_ST_RESULT_CLR`` + *undescribed* +``NVME_ST_RESULT_NS_REMOVED`` + *undescribed* +``NVME_ST_RESULT_ABORTED_FORMAT`` + *undescribed* +``NVME_ST_RESULT_FATAL_ERR`` + *undescribed* -.. c:type:: struct nvme_id_ns_granularity_list +``NVME_ST_RESULT_UNKNOWN_SEG_FAIL`` + *undescribed* +``NVME_ST_RESULT_KNOWN_SEG_FAIL`` + *undescribed* -**Definition** +``NVME_ST_RESULT_ABORTED_UNKNOWN`` + *undescribed* -:: +``NVME_ST_RESULT_ABORTED_SANITIZE`` + *undescribed* - struct nvme_id_ns_granularity_list { - __le32 attributes; - __u8 num_descriptors; - __u8 rsvd[27]; - struct nvme_id_ns_granularity_desc entry[NVME_ID_ND_DESCRIPTOR_MAX]; - __u8 rsvd288[3808]; - }; +``NVME_ST_RESULT_NOT_USED`` + *undescribed* -**Members** +``NVME_ST_RESULT_MASK`` + *undescribed* +.. c:type:: enum -.. c:type:: struct nvme_id_uuid_list_entry +**Constants** -**Definition** +``NVME_ST_CODE_SHIFT`` + *undescribed* -:: +``NVME_ST_CODE_RESRVED`` + *undescribed* - struct nvme_id_uuid_list_entry { - __u8 header; - __u8 rsvd1[15]; - __u8 uuid[16]; - }; +``NVME_ST_CODE_SHORT`` + *undescribed* -**Members** +``NVME_ST_CODE_EXTENDED`` + *undescribed* +``NVME_ST_CODE_VS`` + *undescribed* @@ -8643,31 +8592,33 @@ Returns true if given offset is 64bit register, otherwise it returns false. **Constants** -``NVME_ID_UUID_HDR_ASSOCIATION_MASK`` +``NVME_ST_VALID_DIAG_INFO_NSID`` *undescribed* -``NVME_ID_UUID_ASSOCIATION_NONE`` +``NVME_ST_VALID_DIAG_INFO_FLBA`` *undescribed* -``NVME_ID_UUID_ASSOCIATION_VENDOR`` +``NVME_ST_VALID_DIAG_INFO_SCT`` *undescribed* -``NVME_ID_UUID_ASSOCIATION_SUBSYSTEM_VENDOR`` +``NVME_ST_VALID_DIAG_INFO_SC`` *undescribed* -.. c:type:: struct nvme_id_uuid_list +.. c:type:: struct nvme_self_test_log **Definition** :: - struct nvme_id_uuid_list { - __u8 rsvd0[32]; - struct nvme_id_uuid_list_entry entry[NVME_ID_UUID_LIST_MAX]; + struct nvme_self_test_log { + __u8 current_operation; + __u8 completion; + __u8 rsvd[2]; + struct nvme_st_result result[NVME_LOG_ST_MAX_RESULTS]; }; **Members** @@ -8676,68 +8627,100 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: struct nvme_ctrl_list +.. c:type:: struct nvme_telemetry_log - **num**; + Retrieve internal data specific to the manufacturer. **Definition** :: - struct nvme_ctrl_list { - __le16 num; - __le16 identifier[NVME_ID_CTRL_LIST_MAX]; + struct nvme_telemetry_log { + __u8 lpi; + __u8 rsvd1[4]; + __u8 ieee[3]; + __le16 dalb1; + __le16 dalb2; + __le16 dalb3; + __u8 rsvd14[368]; + __u8 ctrlavail; + __u8 ctrldgn; + __u8 rsnident[128]; + __u8 data_area[]; }; **Members** +``lpi`` + Log Identifier, either ``NVME_LOG_LID_TELEMETRY_HOST`` or + ``NVME_LOG_LID_TELEMETRY_CTRL`` +``ieee`` + IEEE OUI Identifier is the Organization Unique Identifier (OUI) + 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. +``dalb3`` + Telemetry Controller-Initiated Data Area 1 Last Block is + the value of the last block in this area. -.. c:type:: struct nvme_ns_list +``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. +``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 . -**Definition** +``rsnident`` + Reason Identifieris 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. - struct nvme_ns_list { - __le32 ns[NVME_ID_NS_LIST_MAX]; - }; -**Members** +**Description** +This log consists of a header describing the log and zero or more Telemetry +Data Blocks. All Telemetry Data Blocks are ``NVME_LOG_TELEM_BLOCK_SIZE``, 512 +bytes, in size. This log captures the controller’s internal state. -.. c:type:: struct nvme_primary_ctrl_cap +.. c:type:: struct nvme_endurance_group_log **Definition** :: - struct nvme_primary_ctrl_cap { - __le16 cntlid; - __le16 portid; - __u8 crt; - __u8 rsvd5[27]; - __le32 vqfrt; - __le32 vqrfa; - __le16 vqrfap; - __le16 vqprt; - __le16 vqfrsm; - __le16 vqgran; - __u8 rsvd48[16]; - __le32 vifrt; - __le32 virfa; - __le16 virfap; - __le16 viprt; - __le16 vifrsm; - __le16 vigran; - __u8 rsvd80[4016]; + struct nvme_endurance_group_log { + __u8 critical_warning; + __u8 rsvd1[2]; + __u8 avl_spare; + __u8 avl_spare_threshold; + __u8 percent_used; + __u8 rsvd6[26]; + __u8 endurance_estimate[16]; + __u8 data_units_read[16]; + __u8 data_units_written[16]; + __u8 media_units_written[16]; + __u8 host_read_cmds[16]; + __u8 host_write_cmds[16]; + __u8 media_data_integrity_err[16]; + __u8 num_err_info_log_entries[16]; + __u8 rsvd160[352]; }; **Members** @@ -8746,42 +8729,33 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: struct nvme_secondary_ctrl - +.. c:type:: enum nvme_eg_critical_warning_flags -**Definition** -:: +**Constants** - struct nvme_secondary_ctrl { - __le16 scid; - __le16 pcid; - __u8 scs; - __u8 rsvd5[3]; - __le16 vfn; - __le16 nvq; - __le16 nvi; - __u8 rsvd14[18]; - }; +``NVME_EG_CRITICAL_WARNING_SPARE`` + *undescribed* -**Members** +``NVME_EG_CRITICAL_WARNING_DEGRADED`` + *undescribed* +``NVME_EG_CRITICAL_WARNING_READ_ONLY`` + *undescribed* -.. c:type:: struct nvme_secondary_ctrl_list +.. c:type:: struct nvme_aggregate_endurance_group_event - **num**; **Definition** :: - struct nvme_secondary_ctrl_list { - __u8 num; - __u8 rsvd[31]; - struct nvme_secondary_ctrl sc_entry[NVME_ID_SECONDARY_CTRL_MAX]; + struct nvme_aggregate_endurance_group_event { + __le64 num_entries; + __le16 entries[]; }; **Members** @@ -8790,27 +8764,28 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: struct nvme_error_log_page +.. c:type:: struct nvme_nvmset_predictable_lat_log **Definition** :: - struct nvme_error_log_page { - __le64 error_count; - __le16 sqid; - __le16 cmdid; - __le16 status_field; - __le16 parm_error_location; - __le64 lba; - __le32 nsid; - __u8 vs; - __u8 trtype; - __u8 rsvd[2]; - __le64 cs; - __le16 trtype_spec_info; - __u8 rsvd2[22]; + struct nvme_nvmset_predictable_lat_log { + __u8 status; + __u8 rsvd1; + __le16 event_type; + __u8 rsvd4[28]; + __le64 dtwin_rt; + __le64 dtwin_wt; + __le64 dtwin_tmax; + __le64 dtwin_tmin_hi; + __le64 dtwin_tmin_lo; + __u8 rsvd72[56]; + __le64 dtwin_re; + __le64 dtwin_we; + __le64 dtwin_te; + __u8 rsvd152[360]; }; **Members** @@ -8824,48 +8799,73 @@ Returns true if given offset is 64bit register, otherwise it returns false. **Constants** -``NVME_ERR_PEL_BYTE_MASK`` +``NVME_NVMSET_PL_STATUS_DISABLED`` *undescribed* -``NVME_ERR_PEL_BIT_MASK`` +``NVME_NVMSET_PL_STATUS_DTWIN`` + *undescribed* + +``NVME_NVMSET_PL_STATUS_NDWIN`` *undescribed* -.. c:type:: struct nvme_smart_log +.. c:type:: enum + + +**Constants** + +``NVME_NVMSET_PL_EVENT_DTWIN_READ_WARN`` + *undescribed* + +``NVME_NVMSET_PL_EVENT_DTWIN_WRITE_WARN`` + *undescribed* + +``NVME_NVMSET_PL_EVENT_DTWIN_TIME_WARN`` + *undescribed* + +``NVME_NVMSET_PL_EVENT_DTWIN_EXCEEDED`` + *undescribed* + +``NVME_NVMSET_PL_EVENT_DTWIN_EXCURSION`` + *undescribed* + + + + +.. c:type:: struct nvme_aggregate_predictable_lat_event **Definition** :: - struct nvme_smart_log { - __u8 critical_warning; - __u8 temperature[2]; - __u8 avail_spare; - __u8 spare_thresh; - __u8 percent_used; - __u8 endu_grp_crit_warn_sumry; - __u8 rsvd7[25]; - __u8 data_units_read[16]; - __u8 data_units_written[16]; - __u8 host_reads[16]; - __u8 host_writes[16]; - __u8 ctrl_busy_time[16]; - __u8 power_cycles[16]; - __u8 power_on_hours[16]; - __u8 unsafe_shutdowns[16]; - __u8 media_errors[16]; - __u8 num_err_log_entries[16]; - __le32 warning_temp_time; - __le32 critical_comp_time; - __le16 temp_sensor[8]; - __le32 thm_temp1_trans_count; - __le32 thm_temp2_trans_count; - __le32 thm_temp1_total_time; - __le32 thm_temp2_total_time; - __u8 rsvd232[280]; + struct nvme_aggregate_predictable_lat_event { + __le64 num_entries; + __le16 entries[]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_ana_group_desc + + +**Definition** + +:: + + struct nvme_ana_group_desc { + __le32 grpid; + __le32 nnsids; + __le64 chgcnt; + __u8 state; + __u8 rsvd17[15]; + __le32 nsids[]; }; **Members** @@ -8874,58 +8874,73 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: enum +.. c:type:: enum nvme_ana_state **Constants** -``NVME_SMART_CRIT_SPARE`` +``NVME_ANA_STATE_OPTIMIZED`` *undescribed* -``NVME_SMART_CRIT_TEMPERATURE`` +``NVME_ANA_STATE_NONOPTIMIZED`` *undescribed* -``NVME_SMART_CRIT_DEGRADED`` +``NVME_ANA_STATE_INACCESSIBLE`` *undescribed* -``NVME_SMART_CRIT_MEDIA`` +``NVME_ANA_STATE_PERSISTENT_LOSS`` *undescribed* -``NVME_SMART_CRIT_VOLATILE_MEMORY`` +``NVME_ANA_STATE_CHANGE`` *undescribed* -``NVME_SMART_CRIT_PMR_RO`` - *undescribed* +.. c:type:: struct nvme_ana_log -.. c:type:: enum +**Definition** -**Constants** +:: -``NVME_SMART_EGCW_SPARE`` - *undescribed* + struct nvme_ana_log { + __le64 chgcnt; + __le16 ngrps; + __u8 rsvd10[6]; + struct nvme_ana_group_desc descs[]; + }; -``NVME_SMART_EGCW_DEGRADED`` - *undescribed* +**Members** -``NVME_SMART_EGCW_RO`` - *undescribed* -.. c:type:: struct nvme_frs +.. c:type:: struct nvme_persistent_event_log **Definition** :: - struct nvme_frs { - char frs[8]; + struct nvme_persistent_event_log { + __u8 lid; + __u8 rsvd1[3]; + __le32 ttl; + __u8 rv; + __u8 rsvd17; + __le16 lht; + __le64 ts; + __u8 poh[16]; + __le64 pcc; + __le16 vid; + __le16 ssvid; + char sn[20]; + char mn[40]; + char subnqn[NVME_NQN_LENGTH]; + __u8 rsvd372; + __u8 seb[32]; }; **Members** @@ -8934,18 +8949,17 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: struct nvme_firmware_slot +.. c:type:: struct nvme_lba_rd **Definition** :: - struct nvme_firmware_slot { - __u8 afi; - __u8 rsvd[7]; - struct nvme_frs frs[7]; - __u8 rsvd2[448]; + struct nvme_lba_rd { + __le64 rslba; + __le32 rnlb; + __u8 rsvd12[4]; }; **Members** @@ -8954,17 +8968,19 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: struct nvme_cmd_effects_log +.. c:type:: struct nvme_lbas_ns_element **Definition** :: - struct nvme_cmd_effects_log { - __le32 acs[256]; - __le32 iocs[256]; - __u8 rsvd[2048]; + struct nvme_lbas_ns_element { + __le32 neid; + __le32 nrld; + __u8 ratype; + __u8 rsvd8[7]; + struct nvme_lba_rd lba_rd[]; }; **Members** @@ -8973,53 +8989,52 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: enum +.. c:type:: enum nvme_lba_status_atype **Constants** -``NVME_CMD_EFFECTS_CSUPP`` +``NVME_LBA_STATUS_ATYPE_SCAN_UNTRACKED`` *undescribed* -``NVME_CMD_EFFECTS_LBCC`` +``NVME_LBA_STATUS_ATYPE_SCAN_TRACKED`` *undescribed* -``NVME_CMD_EFFECTS_NCC`` - *undescribed* -``NVME_CMD_EFFECTS_NIC`` - *undescribed* -``NVME_CMD_EFFECTS_CCC`` - *undescribed* -``NVME_CMD_EFFECTS_CSE_MASK`` - *undescribed* +.. c:type:: struct nvme_lba_status_log -``NVME_CMD_EFFECTS_UUID_SEL`` - *undescribed* +**Definition** + +:: + + struct nvme_lba_status_log { + __le32 lslplen; + __le32 nlslne; + __le32 estulb; + __u8 rsvd12[2]; + __le16 lsgc; + struct nvme_lbas_ns_element elements[]; + }; + +**Members** -.. c:type:: struct nvme_st_result + + +.. c:type:: struct nvme_eg_event_aggregate_log **Definition** :: - struct nvme_st_result { - __u8 dsts; - __u8 seg; - __u8 vdi; - __u8 rsvd; - __le64 poh; - __le32 nsid; - __le64 flba; - __u8 sct; - __u8 sc; - __u8 vs[2]; + struct nvme_eg_event_aggregate_log { + __le64 nr_entries; + __le16 egids[]; }; **Members** @@ -9028,236 +9043,205 @@ Returns true if given offset is 64bit register, otherwise it returns false. -.. c:type:: enum +.. c:type:: struct nvme_resv_notification_log -**Constants** +**Definition** -``NVME_ST_RESULT_NO_ERR`` - *undescribed* +:: -``NVME_ST_RESULT_ABORTED`` - *undescribed* + struct nvme_resv_notification_log { + __le64 lpc; + __u8 rnlpt; + __u8 nalp; + __u8 rsvd9[2]; + __le32 nsid; + __u8 rsvd16[48]; + }; -``NVME_ST_RESULT_CLR`` - *undescribed* +**Members** -``NVME_ST_RESULT_NS_REMOVED`` - *undescribed* +``rnlpt`` + See :c:type:`enum nvme_resv_notify_rnlpt `. -``NVME_ST_RESULT_ABORTED_FORMAT`` - *undescribed* -``NVME_ST_RESULT_FATAL_ERR`` - *undescribed* -``NVME_ST_RESULT_UNKNOWN_SEG_FAIL`` - *undescribed* -``NVME_ST_RESULT_KNOWN_SEG_FAIL`` + +.. c:type:: enum nvme_resv_notify_rnlpt + + +**Constants** + +``NVME_RESV_NOTIFY_RNLPT_EMPTY`` *undescribed* -``NVME_ST_RESULT_ABORTED_UNKNOWN`` +``NVME_RESV_NOTIFY_RNLPT_REGISTRATION_PREEMPTED`` *undescribed* -``NVME_ST_RESULT_ABORTED_SANITIZE`` +``NVME_RESV_NOTIFY_RNLPT_RESERVATION_RELEASED`` *undescribed* -``NVME_ST_RESULT_NOT_USED`` +``NVME_RESV_NOTIFY_RNLPT_RESERVATION_PREEMPTED`` *undescribed* -.. c:type:: enum +.. c:type:: struct nvme_sanitize_log_page -**Constants** +**Definition** -``NVME_ST_OPERATION_NONE`` - *undescribed* +:: -``NVME_ST_OPERATION_SHORT`` - *undescribed* + struct nvme_sanitize_log_page { + __le16 sprog; + __le16 sstat; + __le32 scdw10; + __le32 eto; + __le32 etbe; + __le32 etce; + __le32 etond; + __le32 etbend; + __le32 etcend; + __u8 rsvd32[480]; + }; -``NVME_ST_OPERATION_EXTENDED`` - *undescribed* +**Members** -``NVME_ST_OPERATION_VS`` - *undescribed* -.. c:type:: enum +.. c:type:: enum nvme_sanitize_sstat **Constants** -``NVME_ST_VALID_DIAG_INFO_NSID`` +``NVME_SANITIZE_SSTAT_STATUS_MASK`` *undescribed* -``NVME_ST_VALID_DIAG_INFO_FLBA`` +``NVME_SANITIZE_SSTAT_STATUS_NEVER_SANITIZED`` *undescribed* -``NVME_ST_VALID_DIAG_INFO_SCT`` +``NVME_SANITIZE_SSTAT_STATUS_COMPLETE_SUCCESS`` *undescribed* -``NVME_ST_VALID_DIAG_INFO_SC`` +``NVME_SANITIZE_SSTAT_STATUS_IN_PROGESS`` *undescribed* +``NVME_SANITIZE_SSTAT_STATUS_COMPLETED_FAILED`` + *undescribed* +``NVME_SANITIZE_SSTAT_STATUS_ND_COMPLETE_SUCCESS`` + *undescribed* +``NVME_SANITIZE_SSTAT_COMPLETED_PASSES_MASK`` + *undescribed* -.. c:type:: struct nvme_self_test_log - - -**Definition** - -:: - - struct nvme_self_test_log { - __u8 current_operation; - __u8 completion; - __u8 rsvd[2]; - struct nvme_st_result result[NVME_LOG_ST_MAX_RESULTS]; - }; - -**Members** +``NVME_SANITIZE_SSTAT_COMPLETED_PASSES_SHIFT`` + *undescribed* +``NVME_SANITIZE_SSTAT_GLOBAL_DATA_ERASED`` + *undescribed* -.. c:type:: struct nvme_telemetry_log +.. c:type:: struct nvme_lba_status_desc - Retrieve internal data specific to the manufacturer. **Definition** :: - struct nvme_telemetry_log { - __u8 lpi; - __u8 rsvd[4]; - __u8 ieee[3]; - __le16 dalb1; - __le16 dalb2; - __le16 dalb3; - __u8 rsvd1[368]; - __u8 ctrlavail; - __u8 ctrldgn; - __u8 rsnident[128]; - __u8 data_area[]; + struct nvme_lba_status_desc { + __le64 dslba; + __le32 nlb; + __u8 rsvd12; + __u8 status; + __u8 rsvd14[2]; }; **Members** -``lpi`` - Log Identifier, either #NVME_LOG_LID_TELEMETRY_HOST or - #NVME_LOG_LID_TELEMETRY_CTRL -``ieee`` - IEEE OUI Identifier is the Organization Unique Identifier (OUI) - 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. -``dalb3`` - Telemetry Controller-Initiated Data Area 1 Last Block is - the value of the last block in this area. -``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. +.. c:type:: struct nvme_lba_status -``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. +**Definition** -``data_area`` - Telemetry data blocks, vendor specific information data. +:: + struct nvme_lba_status { + __le32 nlsd; + __u8 cmpc; + __u8 rsvd5[3]; + struct nvme_lba_status_desc descs[]; + }; -**Description** +**Members** -This log consists of a header describing the log and zero or more Telemetry -Data Blocks. All Telemetry Data Blocks are ``NVME_LOG_TELEM_BLOCK_SIZE``, 512 -bytes, in size. This log captures the controller’s internal state. -.. c:type:: struct nvme_endurance_group_log +.. c:type:: struct nvme_feat_auto_pst **Definition** :: - struct nvme_endurance_group_log { - __u8 critical_warning; - __u8 rsvd1[2]; - __u8 avl_spare; - __u8 avl_spare_threshold; - __u8 percent_used; - __u8 rsvd6[26]; - __u8 endurance_estimate[16]; - __u8 data_units_read[16]; - __u8 data_units_written[16]; - __u8 media_units_written[16]; - __u8 host_read_cmds[16]; - __u8 host_write_cmds[16]; - __u8 media_data_integrity_err[16]; - __u8 num_err_info_log_entries[16]; - __u8 rsvd160[352]; + struct nvme_feat_auto_pst { + __le64 apst_entry[32]; }; **Members** +``apst_entry`` + See :c:type:`enum nvme_apst_entry ` -.. c:type:: enum nvme_eg_critical_warning_flags + +.. c:type:: enum nvme_apst_entry **Constants** -``NVME_EG_CRITICAL_WARNING_SPARE`` +``NVME_APST_ENTRY_ITPS_MASK`` *undescribed* -``NVME_EG_CRITICAL_WARNING_DEGRADED`` +``NVME_APST_ENTRY_ITPS_SHIFT`` *undescribed* -``NVME_EG_CRITICAL_WARNING_READ_ONLY`` +``NVME_APST_ENTRY_ITPT_MASK`` *undescribed* +``NVME_APST_ENTRY_ITPT_SHIFT`` + *undescribed* -.. c:type:: struct nvme_aggregate_endurance_group_event +.. c:type:: struct nvme_timestamp + + timestamp: **Definition** :: - struct nvme_aggregate_endurance_group_event { - __le64 num_entries; - __le16 entries[]; + struct nvme_timestamp { + __u8 timestamp[6]; + __u8 attr; + __u8 rsvd; }; **Members** @@ -9266,28 +9250,21 @@ bytes, in size. This log captures the controller’s internal state. -.. c:type:: struct nvme_nvmset_predictable_lat_log +.. c:type:: struct nvme_lba_range_type_entry **Definition** :: - struct nvme_nvmset_predictable_lat_log { - __u8 status; - __u8 rsvd1; - __le16 event_type; - __u8 rsvd4[28]; - __le64 dtwin_rt; - __le64 dtwin_wt; - __le64 dtwin_tmax; - __le64 dtwin_tmin_hi; - __le64 dtwin_tmin_lo; - __u8 rsvd72[56]; - __le64 dtwin_re; - __le64 dtwin_we; - __le64 dtwin_te; - __u8 rsvd152[360]; + struct nvme_lba_range_type_entry { + __u8 type; + __u8 attributes; + __u8 rsvd2[14]; + __u64 slba; + __u64 nlb; + __u8 guid[16]; + __u8 rsvd48[16]; }; **Members** @@ -9301,51 +9278,62 @@ bytes, in size. This log captures the controller’s internal state. **Constants** -``NVME_NVMSET_PL_STATUS_DISABLED`` +``NVME_LBART_TYPE_GP`` *undescribed* -``NVME_NVMSET_PL_STATUS_DTWIN`` +``NVME_LBART_TYPE_FS`` *undescribed* -``NVME_NVMSET_PL_STATUS_NDWIN`` +``NVME_LBART_TYPE_RAID`` *undescribed* +``NVME_LBART_TYPE_CACHE`` + *undescribed* +``NVME_LBART_TYPE_SWAP`` + *undescribed* +``NVME_LBART_ATTRIB_TEMP`` + *undescribed* -.. c:type:: enum +``NVME_LBART_ATTRIB_HIDE`` + *undescribed* -**Constants** -``NVME_NVMSET_PL_EVENT_DTWIN_READ_WARN`` - *undescribed* -``NVME_NVMSET_PL_EVENT_DTWIN_WRITE_WARN`` - *undescribed* +.. c:type:: struct nvme_lba_range_type -``NVME_NVMSET_PL_EVENT_DTWIN_TIME_WARN`` - *undescribed* -``NVME_NVMSET_PL_EVENT_DTWIN_EXCEEDED`` - *undescribed* +**Definition** -``NVME_NVMSET_PL_EVENT_DTWIN_EXCURSION`` - *undescribed* +:: + + struct nvme_lba_range_type { + struct nvme_lba_range_type_entry entry[NVME_FEAT_LBA_RANGE_MAX]; + }; +**Members** -.. c:type:: struct nvme_aggregate_predictable_lat_event +.. c:type:: struct nvme_plm_config + + **ee**; **dtwinrt**; **dtwinwt**; **dtwintt**; + **Definition** :: - struct nvme_aggregate_predictable_lat_event { - __le64 num_entries; - __le16 entries[]; + struct nvme_plm_config { + __le16 ee; + __u8 rsvd2[30]; + __le64 dtwinrt; + __le64 dtwinwt; + __le64 dtwintt; + __u8 rsvd56[456]; }; **Members** @@ -9354,20 +9342,16 @@ bytes, in size. This log captures the controller’s internal state. -.. c:type:: struct nvme_ana_group_desc +.. c:type:: struct nvme_feat_host_behavior **Definition** :: - struct nvme_ana_group_desc { - __le32 grpid; - __le32 nnsids; - __le64 chgcnt; - __u8 state; - __u8 rsvd17[15]; - __le32 nsids[]; + struct nvme_feat_host_behavior { + __u8 acre; + __u8 rsvd1[511]; }; **Members** @@ -9381,36 +9365,44 @@ bytes, in size. This log captures the controller’s internal state. **Constants** -``NVME_ANA_STATE_OPTIMIZED`` +``NVME_ENABLE_ACRE`` *undescribed* -``NVME_ANA_STATE_NONOPTIMIZED`` - *undescribed* -``NVME_ANA_STATE_INACCESSIBLE`` - *undescribed* -``NVME_ANA_STATE_PERSISTENT_LOSS`` - *undescribed* -``NVME_ANA_STATE_CHANGE`` - *undescribed* +.. c:type:: struct nvme_dsm_range +**Definition** +:: + + struct nvme_dsm_range { + __le32 cattr; + __le32 nlb; + __le64 slba; + }; + +**Members** -.. c:type:: struct nvme_ana_log + + + + +.. c:type:: struct nvme_registered_ctrl **Definition** :: - struct nvme_ana_log { - __le64 chgcnt; - __le16 ngrps; - __u8 rsvd10[6]; - struct nvme_ana_group_desc descs[]; + struct nvme_registered_ctrl { + __le16 cntlid; + __u8 rcsts; + __u8 rsvd3[5]; + __le64 hostid; + __le64 rkey; }; **Members** @@ -9419,30 +9411,82 @@ bytes, in size. This log captures the controller’s internal state. -.. c:type:: struct nvme_persistent_event_log +.. c:type:: struct nvme_registered_ctrl_ext **Definition** :: - struct nvme_persistent_event_log { - __u8 lid; - __u8 rsvd1[3]; - __le32 ttl; - __u8 rv; - __u8 rsvd17; - __le16 lht; - __le64 ts; - __u8 poh[16]; - __le64 pcc; - __le16 vid; - __le16 ssvid; - char sn[20]; - char mn[40]; - char subnqn[NVME_NQN_LENGTH]; - __u8 rsvd372; - __u8 seb[32]; + struct nvme_registered_ctrl_ext { + __le16 cntlid; + __u8 rcsts; + __u8 rsvd3[5]; + __le64 rkey; + __u8 hostid[16]; + __u8 rsvd32[32]; + }; + +**Members** + + + + + +.. c:type:: struct nvme_reservation_status + + { + +**Definition** + +:: + + struct nvme_reservation_status { + __le32 gen; + __u8 rtype; + __u8 regctl[2]; + __u8 rsvd7[2]; + __u8 ptpls; + __u8 rsvd10[14]; + union { + struct { + __u8 rsvd24[40]; + struct nvme_registered_ctrl_ext regctl_eds[0]; + }; + struct nvme_registered_ctrl regctl_ds[0]; + }; + }; + +**Members** + +``{unnamed_union}`` + anonymous + +``{unnamed_struct}`` + anonymous + + + + + +.. c:type:: struct nvme_streams_directive_params + + +**Definition** + +:: + + struct nvme_streams_directive_params { + __le16 msl; + __le16 nssa; + __le16 nsso; + __u8 nssc; + __u8 rsvd[9]; + __le32 sws; + __le16 sgs; + __le16 nsa; + __le16 nso; + __u8 rsvd2[6]; }; **Members** @@ -9451,17 +9495,16 @@ bytes, in size. This log captures the controller’s internal state. -.. c:type:: struct nvme_lba_rd +.. c:type:: struct nvme_streams_directive_status **Definition** :: - struct nvme_lba_rd { - __le64 rslba; - __le32 rnlb; - __u8 rsvd12[4]; + struct nvme_streams_directive_status { + __le16 osc; + __le16 sid[]; }; **Members** @@ -9470,19 +9513,17 @@ bytes, in size. This log captures the controller’s internal state. -.. c:type:: struct nvme_lbas_ns_element +.. c:type:: struct nvme_id_directives **Definition** :: - struct nvme_lbas_ns_element { - __le32 neid; - __le32 nrld; - __u8 ratype; - __u8 rsvd8[7]; - struct nvme_lba_rd lba_rd[]; + struct nvme_id_directives { + __u8 supported[32]; + __u8 enabled[32]; + __u8 rsvd64[4032]; }; **Members** @@ -9491,34 +9532,31 @@ bytes, in size. This log captures the controller’s internal state. -.. c:type:: enum nvme_lba_status_atype +.. c:type:: enum **Constants** -``NVME_LBA_STATUS_ATYPE_SCAN_UNTRACKED`` +``NVME_ID_DIR_ID_BIT`` *undescribed* -``NVME_LBA_STATUS_ATYPE_SCAN_TRACKED`` +``NVME_ID_DIR_SD_BIT`` *undescribed* -.. c:type:: struct nvme_lba_status_log +.. c:type:: struct nvme_host_mem_buf_desc **Definition** :: - struct nvme_lba_status_log { - __le32 lslplen; - __le32 nlslne; - __le32 estulb; - __u8 rsvd12[2]; - __le16 lsgc; - struct nvme_lbas_ns_element elements[]; + struct nvme_host_mem_buf_desc { + __le64 addr; + __le32 size; + __u32 rsvd; }; **Members** @@ -9527,128 +9565,170 @@ bytes, in size. This log captures the controller’s internal state. -.. c:type:: struct nvme_eg_event_aggregate_log +.. c:type:: enum nvme_ae_type -**Definition** +**Constants** -:: +``NVME_AER_ERROR`` + *undescribed* - struct nvme_eg_event_aggregate_log { - __le64 nr_entries; - __le16 egids[]; - }; +``NVME_AER_SMART`` + *undescribed* -**Members** +``NVME_AER_NOTICE`` + *undescribed* +``NVME_AER_CSS`` + *undescribed* +``NVME_AER_VS`` + *undescribed* -.. c:type:: struct nvme_resv_notification_log +.. c:type:: enum nvme_ae_info_error -**Definition** -:: +**Constants** - struct nvme_resv_notification_log { - __le64 lpc; - __u8 rnlpt; - __u8 nalp; - __u8 rsvd9[2]; - __le32 nsid; - __u8 rsvd16[48]; - }; +``NVME_AER_ERROR_INVALID_DB_REG`` + *undescribed* -**Members** +``NVME_AER_ERROR_INVALID_DB_VAL`` + *undescribed* + +``NVME_AER_ERROR_DIAG_FAILURE`` + *undescribed* +``NVME_AER_ERROR_PERSISTENT_INTERNAL_ERROR`` + *undescribed* +``NVME_AER_ERROR_TRANSIENT_INTERNAL_ERROR`` + *undescribed* +``NVME_AER_ERROR_FW_IMAGE_LOAD_ERROR`` + *undescribed* -.. c:type:: enum + + +.. c:type:: enum nvme_ae_info_smart **Constants** -``NVME_RESV_NOTIFY_RNLPT_EMPTY`` +``NVME_AER_SMART_SUBSYSTEM_RELIABILITY`` *undescribed* -``NVME_RESV_NOTIFY_RNLPT_REGISTRATION_PREEMPTED`` +``NVME_AER_SMART_TEMPERATURE_THRESHOLD`` *undescribed* -``NVME_RESV_NOTIFY_RNLPT_RESERVATION_RELEASED`` +``NVME_AER_SMART_SPARE_THRESHOLD`` *undescribed* -``NVME_RESV_NOTIFY_RNLPT_RESERVATION_PREEMPTED`` - *undescribed* +.. c:type:: enum nvme_ae_info_css_nvm -.. c:type:: struct nvme_sanitize_log_page +**Constants** -**Definition** +``NVME_AER_CSS_NVM_RESERVATION`` + *undescribed* -:: +``NVME_AER_CSS_NVM_SANITIZE_COMPLETED`` + *undescribed* + +``NVME_AER_CSS_NVM_UNEXPECTED_SANITIZE_DEALLOC`` + *undescribed* - struct nvme_sanitize_log_page { - __le16 sprog; - __le16 sstat; - __le32 scdw10; - __le32 eto; - __le32 etbe; - __le32 etce; - __le32 etond; - __le32 etbend; - __le32 etcend; - __u8 rsvd32[480]; - }; -**Members** +.. c:type:: enum nvme_ae_info_notice +**Constants** -.. c:type:: enum +``NVME_AER_NOTICE_NS_CHANGED`` + *undescribed* +``NVME_AER_NOTICE_FW_ACT_STARTING`` + *undescribed* -**Constants** +``NVME_AER_NOTICE_TELEMETRY`` + *undescribed* -``NVME_SANITIZE_SSTAT_NEVER_SANITIZED`` +``NVME_AER_NOTICE_ANA`` *undescribed* -``NVME_SANITIZE_SSTAT_COMPLETE_SUCCESS`` +``NVME_AER_NOTICE_PL_EVENT`` *undescribed* -``NVME_SANITIZE_SSTAT_IN_PROGESS`` +``NVME_AER_NOTICE_LBA_STATUS_ALERT`` *undescribed* -``NVME_SANITIZE_SSTAT_COMPLETED_FAILED`` +``NVME_AER_NOTICE_EG_EVENT`` *undescribed* -``NVME_SANITIZE_SSTAT_ND_COMPLETE_SUCCESS`` +``NVME_AER_NOTICE_DISC_CHANGED`` *undescribed* -.. c:type:: struct nvme_lba_status_desc +.. c:type:: enum nvme_subsys_type + + +**Constants** + +``NVME_NQN_DISC`` + Discovery type target subsystem + +``NVME_NQN_NVME`` + NVME type target subsystem + + +.. c:type:: struct nvmf_disc_log_entry + + Discovery log page entry + **Definition** :: - struct nvme_lba_status_desc { - __le64 dslba; - __le32 nlb; - __u8 rsvd12; - __u8 status; - __u8 rsvd14[2]; + struct nvmf_disc_log_entry { + __u8 trtype; + __u8 adrfam; + __u8 subtype; + __u8 treq; + __le16 portid; + __le16 cntlid; + __le16 asqsz; + __u8 rsvd10[22]; + char trsvcid[NVMF_TRSVCID_SIZE]; + __u8 rsvd64[192]; + char subnqn[NVME_NQN_LENGTH]; + char traddr[NVMF_TRADDR_SIZE]; + union tsas { + char common[NVMF_TSAS_SIZE]; + struct rdma { + __u8 qptype; + __u8 prtype; + __u8 cms; + __u8 rsvd3[5]; + __u16 pkey; + __u8 rsvd10[246]; + } rdma; + struct tcp { + __u8 sectype; + } tcp; + } tsas; }; **Members** @@ -9657,147 +9737,156 @@ bytes, in size. This log captures the controller’s internal state. -.. c:type:: struct nvme_lba_status +.. c:type:: enum + Transport Type codes for Discovery Log Page entry TRTYPE field -**Definition** +**Constants** -:: +``NVMF_TRTYPE_UNSPECIFIED`` + Not indicated - struct nvme_lba_status { - __le32 nlsd; - __u8 cmpc; - __u8 rsvd5[3]; - struct nvme_lba_status_desc descs[]; - }; +``NVMF_TRTYPE_RDMA`` + RDMA -**Members** +``NVMF_TRTYPE_FC`` + Fibre Channel +``NVMF_TRTYPE_TCP`` + TCP +``NVMF_TRTYPE_LOOP`` + Reserved for host usage +``NVMF_TRTYPE_MAX`` + *undescribed* -.. c:type:: struct nvme_feat_auto_pst -**Definition** +.. c:type:: enum -:: + Address Family codes for Discovery Log Page entry ADRFAM field - struct nvme_feat_auto_pst { - __le64 apst_entry[32]; - }; +**Constants** -**Members** +``NVMF_ADDR_FAMILY_PCI`` + PCIe + +``NVMF_ADDR_FAMILY_IP4`` + IPv4 +``NVMF_ADDR_FAMILY_IP6`` + IPv6 +``NVMF_ADDR_FAMILY_IB`` + InfiniBand +``NVMF_ADDR_FAMILY_FC`` + Fibre Channel -.. c:type:: struct nvme_timestamp - timestamp: -**Definition** +.. c:type:: enum -:: + Transport Requirements codes for Discovery Log Page entry TREQ field - struct nvme_timestamp { - __u8 timestamp[6]; - __u8 attr; - __u8 rsvd; - }; +**Constants** -**Members** +``NVMF_TREQ_NOT_SPECIFIED`` + Not specified +``NVMF_TREQ_REQUIRED`` + Required +``NVMF_TREQ_NOT_REQUIRED`` + Not Required +``NVMF_TREQ_DISABLE_SQFLOW`` + SQ flow control disable supported -.. c:type:: struct nvme_lba_range_type_entry -**Definition** +.. c:type:: enum -:: + RDMA QP Service Type codes for Discovery Log Page entry TSAS RDMA_QPTYPE field - struct nvme_lba_range_type_entry { - __u8 type; - __u8 attributes; - __u8 rsvd2[14]; - __u64 slba; - __u64 nlb; - __u8 guid[16]; - __u8 rsvd48[16]; - }; +**Constants** -**Members** +``NVMF_RDMA_QPTYPE_CONNECTED`` + Reliable Connected +``NVMF_RDMA_QPTYPE_DATAGRAM`` + Reliable Datagram .. c:type:: enum + RDMA Provider Type codes for Discovery Log Page entry TSAS RDMA_PRTYPE field **Constants** -``NVME_LBART_TYPE_GP`` - *undescribed* +``NVMF_RDMA_PRTYPE_NOT_SPECIFIED`` + No Provider Specified -``NVME_LBART_TYPE_FS`` - *undescribed* +``NVMF_RDMA_PRTYPE_IB`` + InfiniBand -``NVME_LBART_TYPE_RAID`` - *undescribed* +``NVMF_RDMA_PRTYPE_ROCE`` + InfiniBand RoCE -``NVME_LBART_TYPE_CACHE`` - *undescribed* +``NVMF_RDMA_PRTYPE_ROCEV2`` + InfiniBand RoCEV2 -``NVME_LBART_TYPE_SWAP`` - *undescribed* +``NVMF_RDMA_PRTYPE_IWARP`` + iWARP -``NVME_LBART_ATTRIB_TEMP`` - *undescribed* -``NVME_LBART_ATTRIB_HIDE`` - *undescribed* +.. c:type:: enum + RDMA Connection Management Service Type codes for Discovery Log Page entry TSAS RDMA_CMS field -.. c:type:: struct nvme_lba_range_type +**Constants** +``NVMF_RDMA_CMS_RDMA_CM`` + Sockets based endpoint addressing -**Definition** -:: - struct nvme_lba_range_type { - struct nvme_lba_range_type_entry entry[NVME_FEAT_LBA_RANGE_MAX]; - }; -**Members** +.. c:type:: enum +**Constants** +``NVMF_TCP_SECTYPE_NONE`` + No Security +``NVMF_TCP_SECTYPE_TLS`` + Transport Layer Security -.. c:type:: struct nvme_plm_config - **ee**; **dtwinrt**; **dtwinwt**; **dtwintt**; + + +.. c:type:: struct nvmf_discovery_log + **Definition** :: - struct nvme_plm_config { - __le16 ee; - __u8 rsvd2[30]; - __le64 dtwinrt; - __le64 dtwinwt; - __le64 dtwintt; - __u8 rsvd56[456]; + struct nvmf_discovery_log { + __le64 genctr; + __le64 numrec; + __le16 recfmt; + __u8 rsvd14[1006]; + struct nvmf_disc_log_entry entries[]; }; **Members** @@ -9806,46 +9895,44 @@ bytes, in size. This log captures the controller’s internal state. -.. c:type:: struct nvme_feat_host_behavior +.. c:type:: struct nvmf_connect_data **Definition** :: - struct nvme_feat_host_behavior { - __u8 acre; - __u8 rsvd1[511]; + struct nvmf_connect_data { + __u8 hostid[16]; + __le16 cntlid; + char rsvd4[238]; + char subsysnqn[NVME_NQN_LENGTH]; + char hostnqn[NVME_NQN_LENGTH]; + char rsvd5[256]; }; **Members** +``cntlid`` + **subsysnqn** + **hostnqn** -.. c:type:: enum - - -**Constants** - -``NVME_ENABLE_ACRE`` - *undescribed* - - - -.. c:type:: struct nvme_dsm_range +.. c:type:: struct nvme_mi_read_nvm_ss_info **Definition** :: - struct nvme_dsm_range { - __le32 cattr; - __le32 nlb; - __le64 slba; + struct nvme_mi_read_nvm_ss_info { + __u8 nump; + __u8 mjr; + __u8 mnr; + __u8 rsvd3[29]; }; **Members** @@ -9854,19 +9941,21 @@ bytes, in size. This log captures the controller’s internal state. -.. c:type:: struct nvme_registered_ctrl +.. c:type:: struct nvme_mi_port_pcie **Definition** :: - struct nvme_registered_ctrl { - __le16 cntlid; - __u8 rcsts; - __u8 rsvd3[5]; - __le64 hostid; - __le64 rkey; + struct nvme_mi_port_pcie { + __u8 mps; + __u8 sls; + __u8 cls; + __u8 mlw; + __u8 nlw; + __u8 pn; + __u8 rsvd14[18]; }; **Members** @@ -9875,20 +9964,20 @@ bytes, in size. This log captures the controller’s internal state. -.. c:type:: struct nvme_registered_ctrl_ext +.. c:type:: struct nvme_mi_port_smb **Definition** :: - struct nvme_registered_ctrl_ext { - __le16 cntlid; - __u8 rcsts; - __u8 rsvd3[5]; - __le64 rkey; - __u8 hostid[16]; - __u8 rsvd32[32]; + struct nvme_mi_port_smb { + __u8 vpd_addr; + __u8 mvpd_freq; + __u8 mme_addr; + __u8 mme_freq; + __u8 nvmebm; + __u8 rsvd13[19]; }; **Members** @@ -9897,60 +9986,54 @@ bytes, in size. This log captures the controller’s internal state. -.. c:type:: struct nvme_reservation_status +.. c:type:: struct nvme_mi_read_port_info - { **Definition** :: - struct nvme_reservation_status { - __le32 gen; - __u8 rtype; - __u8 regctl[2]; - __u8 rsvd7[2]; - __u8 ptpls; - __u8 rsvd10[14]; + struct nvme_mi_read_port_info { + __u8 portt; + __u8 rsvd1; + __le16 mmctptus; + __le32 meb; union { - struct { - __u8 rsvd24[40]; - struct nvme_registered_ctrl_ext regctl_eds[0]; - }; - struct nvme_registered_ctrl regctl_ds[0]; + struct nvme_mi_port_pcie pcie; + struct nvme_mi_port_smb smb; }; }; **Members** -``{unnamed_union}`` - anonymous +``portt`` + **mmctptus**; -``{unnamed_struct}`` +``{unnamed_union}`` anonymous -.. c:type:: struct nvme_streams_directive_params +.. c:type:: struct nvme_mi_read_ctrl_info + **portid**; **prii**; **pri**; **vid**; **did**; **ssvid**; **ssid**; **Definition** :: - struct nvme_streams_directive_params { - __le16 msl; - __le16 nssa; - __le16 nsso; - __u8 nssc; - __u8 rsvd[9]; - __le32 sws; - __le16 sgs; - __le16 nsa; - __le16 nso; - __u8 rsvd2[6]; + struct nvme_mi_read_ctrl_info { + __u8 portid; + __u8 rsvd1[4]; + __u8 prii; + __le16 pri; + __le16 vid; + __le16 did; + __le16 ssvid; + __le16 ssid; + __u8 rsvd16[16]; }; **Members** @@ -9959,16 +10042,17 @@ bytes, in size. This log captures the controller’s internal state. -.. c:type:: struct nvme_streams_directive_status +.. c:type:: struct nvme_mi_osc + **type**; **opc**; **Definition** :: - struct nvme_streams_directive_status { - __le16 osc; - __le16 sid[]; + struct nvme_mi_osc { + __u8 type; + __u8 opc; }; **Members** @@ -9977,17 +10061,16 @@ bytes, in size. This log captures the controller’s internal state. -.. c:type:: struct nvme_id_directives +.. c:type:: struct nvme_mi_read_sc_list **Definition** :: - struct nvme_id_directives { - __u8 supported[32]; - __u8 enabled[32]; - __u8 rsvd64[4032]; + struct nvme_mi_read_sc_list { + __le16 numcmd; + struct nvme_mi_osc cmds[]; }; **Members** @@ -9996,31 +10079,20 @@ bytes, in size. This log captures the controller’s internal state. -.. c:type:: enum - - -**Constants** - -``NVME_ID_DIR_ID_BIT`` - *undescribed* - -``NVME_ID_DIR_SD_BIT`` - *undescribed* - - - - -.. c:type:: struct nvme_host_mem_buf_desc +.. c:type:: struct nvme_mi_nvm_ss_health_status **Definition** :: - struct nvme_host_mem_buf_desc { - __le64 addr; - __le32 size; - __u32 rsvd; + struct nvme_mi_nvm_ss_health_status { + __u8 nss; + __u8 sw; + __u8 ctemp; + __u8 pdlu; + __le16 ccs; + __u8 rsvd8[2]; }; **Members** @@ -10029,170 +10101,167 @@ bytes, in size. This log captures the controller’s internal state. -.. c:type:: enum nvme_ae_type +.. c:type:: enum **Constants** -``NVME_AER_ERROR`` +``NVME_MI_CCS_RDY`` *undescribed* -``NVME_AER_SMART`` +``NVME_MI_CSS_CFS`` *undescribed* -``NVME_AER_NOTICE`` +``NVME_MI_CSS_SHST`` *undescribed* -``NVME_AER_CSS`` +``NVME_MI_CSS_NSSRO`` *undescribed* -``NVME_AER_VS`` +``NVME_MI_CSS_CECO`` *undescribed* +``NVME_MI_CSS_NAC`` + *undescribed* - - -.. c:type:: enum nvme_ae_info_error - - -**Constants** - -``NVME_AER_ERROR_INVALID_DB_REG`` +``NVME_MI_CSS_FA`` *undescribed* -``NVME_AER_ERROR_INVALID_DB_VAL`` +``NVME_MI_CSS_CSTS`` *undescribed* -``NVME_AER_ERROR_DIAG_FAILURE`` +``NVME_MI_CSS_CTEMP`` *undescribed* -``NVME_AER_ERROR_PERSISTENT_INTERNAL_ERROR`` +``NVME_MI_CSS_PDLU`` *undescribed* -``NVME_AER_ERROR_TRANSIENT_INTERNAL_ERROR`` +``NVME_MI_CSS_SPARE`` *undescribed* -``NVME_AER_ERROR_FW_IMAGE_LOAD_ERROR`` +``NVME_MI_CSS_CCWARN`` *undescribed* -.. c:type:: enum nvme_ae_info_smart +.. c:type:: struct nvme_mi_ctrl_heal_status -**Constants** +**Definition** -``NVME_AER_SMART_SUBSYSTEM_RELIABILITY`` - *undescribed* +:: -``NVME_AER_SMART_TEMPERATURE_THRESHOLD`` - *undescribed* + struct nvme_mi_ctrl_heal_status { + __le16 ctlid; + __le16 csts; + __le16 ctemp; + __u8 pdlu; + __u8 spare; + __u8 cwarn; + __u8 rsvd9[7]; + }; -``NVME_AER_SMART_SPARE_THRESHOLD`` - *undescribed* +**Members** -.. c:type:: enum nvme_ae_info_css_nvm + +.. c:type:: enum **Constants** -``NVME_AER_CSS_NVM_RESERVATION`` +``NVME_MI_CSTS_RDY`` *undescribed* -``NVME_AER_CSS_NVM_SANITIZE_COMPLETED`` +``NVME_MI_CSTS_CFS`` *undescribed* -``NVME_AER_CSS_NVM_UNEXPECTED_SANITIZE_DEALLOC`` +``NVME_MI_CSTS_SHST`` *undescribed* +``NVME_MI_CSTS_NSSRO`` + *undescribed* - - -.. c:type:: enum nvme_ae_info_notice - - -**Constants** - -``NVME_AER_NOTICE_NS_CHANGED`` +``NVME_MI_CSTS_CECO`` *undescribed* -``NVME_AER_NOTICE_FW_ACT_STARTING`` +``NVME_MI_CSTS_NAC`` *undescribed* -``NVME_AER_NOTICE_TELEMETRY`` +``NVME_MI_CSTS_FA`` *undescribed* -``NVME_AER_NOTICE_ANA`` +``NVME_MI_CWARN_ST`` *undescribed* -``NVME_AER_NOTICE_PL_EVENT`` +``NVME_MI_CWARN_TAUT`` *undescribed* -``NVME_AER_NOTICE_LBA_STATUS_ALERT`` +``NVME_MI_CWARN_RD`` *undescribed* -``NVME_AER_NOTICE_EG_EVENT`` +``NVME_MI_CWARN_RO`` *undescribed* -``NVME_AER_NOTICE_DISC_CHANGED`` +``NVME_MI_CWARN_VMBF`` *undescribed* -.. c:type:: enum nvme_subsys_type +.. c:type:: struct nvme_mi_vpd_mra + **nmravn**; **ff**; **i18vpwr**; **m18vpwr**; **i33vpwr**; **m33vpwr**; **m33vapsr**; **i5vapsr**; **m5vapsr**; **i12vapsr**; **m12vapsr**; **mtl**; **tnvmcap**[16]; -**Constants** +**Definition** -``NVME_NQN_DISC`` - Discovery type target subsystem +:: -``NVME_NQN_NVME`` - NVME type target subsystem + struct nvme_mi_vpd_mra { + __u8 nmravn; + __u8 ff; + __u8 rsvd7[6]; + __u8 i18vpwr; + __u8 m18vpwr; + __u8 i33vpwr; + __u8 m33vpwr; + __u8 rsvd17; + __u8 m33vapsr; + __u8 i5vapsr; + __u8 m5vapsr; + __u8 i12vapsr; + __u8 m12vapsr; + __u8 mtl; + __u8 tnvmcap[16]; + __u8 rsvd37[27]; + }; +**Members** -.. c:type:: struct nvmf_disc_log_entry - Discovery log page entry + +.. c:type:: struct nvme_mi_vpd_ppmra + **Definition** :: - struct nvmf_disc_log_entry { - __u8 trtype; - __u8 adrfam; - __u8 subtype; - __u8 treq; - __le16 portid; - __le16 cntlid; - __le16 asqsz; - __u8 rsvd10[22]; - char trsvcid[NVMF_TRSVCID_SIZE]; - __u8 rsvd64[192]; - char subnqn[NVME_NQN_LENGTH]; - char traddr[NVMF_TRADDR_SIZE]; - union tsas { - char common[NVMF_TSAS_SIZE]; - struct rdma { - __u8 qptype; - __u8 prtype; - __u8 cms; - __u8 rsvd3[5]; - __u16 pkey; - __u8 rsvd10[246]; - } rdma; - struct tcp { - __u8 sectype; - } tcp; - } tsas; + struct nvme_mi_vpd_ppmra { + __u8 nppmravn; + __u8 pn; + __u8 ppi; + __u8 ls; + __u8 mlw; + __u8 mctp; + __u8 refccap; + __u8 pi; + __u8 rsvd13[3]; }; **Members** @@ -10201,1265 +10270,1315 @@ bytes, in size. This log captures the controller’s internal state. -.. c:type:: enum - - Transport Type codes for Discovery Log Page entry TRTYPE field - -**Constants** +.. c:type:: struct nvme_mi_vpd_telem -``NVMF_TRTYPE_UNSPECIFIED`` - Not indicated -``NVMF_TRTYPE_RDMA`` - RDMA +**Definition** -``NVMF_TRTYPE_FC`` - Fibre Channel +:: -``NVMF_TRTYPE_TCP`` - TCP + struct nvme_mi_vpd_telem { + __u8 type; + __u8 rev; + __u8 len; + __u8 data[0]; + }; -``NVMF_TRTYPE_LOOP`` - Reserved for host usage +**Members** -``NVMF_TRTYPE_MAX`` - *undescribed* .. c:type:: enum - Address Family codes for Discovery Log Page entry ADRFAM field **Constants** -``NVMF_ADDR_FAMILY_PCI`` - PCIe +``NVME_MI_ELEM_EED`` + *undescribed* -``NVMF_ADDR_FAMILY_IP4`` - IPv4 +``NVME_MI_ELEM_USCE`` + *undescribed* -``NVMF_ADDR_FAMILY_IP6`` - IPv6 +``NVME_MI_ELEM_ECED`` + *undescribed* -``NVMF_ADDR_FAMILY_IB`` - InfiniBand +``NVME_MI_ELEM_LED`` + *undescribed* -``NVMF_ADDR_FAMILY_FC`` - Fibre Channel +``NVME_MI_ELEM_SMBMED`` + *undescribed* +``NVME_MI_ELEM_PCIESED`` + *undescribed* +``NVME_MI_ELEM_NVMED`` + *undescribed* -.. c:type:: enum - Transport Requirements codes for Discovery Log Page entry TREQ field -**Constants** +.. c:type:: struct nvme_mi_vpd_tra -``NVMF_TREQ_NOT_SPECIFIED`` - Not specified -``NVMF_TREQ_REQUIRED`` - Required +**Definition** -``NVMF_TREQ_NOT_REQUIRED`` - Not Required +:: -``NVMF_TREQ_DISABLE_SQFLOW`` - SQ flow control disable supported + struct nvme_mi_vpd_tra { + __u8 vn; + __u8 rsvd6; + __u8 ec; + struct nvme_mi_vpd_telem elems[0]; + }; +**Members** -.. c:type:: enum - RDMA QP Service Type codes for Discovery Log Page entry TSAS RDMA_QPTYPE field -**Constants** +.. c:type:: struct nvme_mi_vpd_mr_common -``NVMF_RDMA_QPTYPE_CONNECTED`` - Reliable Connected -``NVMF_RDMA_QPTYPE_DATAGRAM`` - Reliable Datagram +**Definition** + +:: + + struct nvme_mi_vpd_mr_common { + __u8 type; + __u8 rf; + __u8 rlen; + __u8 rchksum; + __u8 hchksum; + union { + struct nvme_mi_vpd_mra nmra; + struct nvme_mi_vpd_ppmra ppmra; + struct nvme_mi_vpd_tra tmra; + }; + }; + +**Members** +``{unnamed_union}`` + anonymous -.. c:type:: enum - RDMA Provider Type codes for Discovery Log Page entry TSAS RDMA_PRTYPE field -**Constants** +.. c:type:: struct nvme_mi_vpd_hdr -``NVMF_RDMA_PRTYPE_NOT_SPECIFIED`` - No Provider Specified -``NVMF_RDMA_PRTYPE_IB`` - InfiniBand +**Definition** -``NVMF_RDMA_PRTYPE_ROCE`` - InfiniBand RoCE +:: -``NVMF_RDMA_PRTYPE_ROCEV2`` - InfiniBand RoCEV2 + struct nvme_mi_vpd_hdr { + __u8 ipmiver; + __u8 iuaoff; + __u8 ciaoff; + __u8 biaoff; + __u8 piaoff; + __u8 mrioff; + __u8 rsvd6; + __u8 chchk; + __u8 vpd[]; + }; -``NVMF_RDMA_PRTYPE_IWARP`` - iWARP +**Members** -.. c:type:: enum - RDMA Connection Management Service Type codes for Discovery Log Page entry TSAS RDMA_CMS field +.. c:type:: enum nvme_status_field + + Defines all parts of the nvme status field: status code, status code type, and additional flags. **Constants** -``NVMF_RDMA_CMS_RDMA_CM`` - Sockets based endpoint addressing +``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 -.. c:type:: enum +``NVME_SCT_VS`` + Vendor specific errors +``NVME_SCT_MASK`` + Mask to get the value of the Status Code Type -**Constants** +``NVME_SC_MASK`` + Mask to get the value of the status code. -``NVMF_TCP_SECTYPE_NONE`` - No Security +``NVME_SC_SUCCESS`` + Successful Completion: The command + completed without error. -``NVMF_TCP_SECTYPE_TLS`` - Transport Layer Security +``NVME_SC_INVALID_OPCODE`` + Invalid Command Opcode: A reserved coded + 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. +``NVME_SC_CMDID_CONFLICT`` + Command ID Conflict: The command + 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. -.. c:type:: struct nvmf_discovery_log +``NVME_SC_POWER_LOSS`` + Commands Aborted due to Power Loss + 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. -**Definition** +``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. -:: +``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. - struct nvmf_discovery_log { - __le64 genctr; - __le64 numrec; - __le16 recfmt; - __u8 rsvd14[1006]; - struct nvmf_disc_log_entry entries[0]; - }; +``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. -**Members** +``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. +``NVME_SC_INVALID_NS`` + Invalid Namespace or Format: The + 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. +``NVME_SC_SGL_INVALID_LAST`` + Invalid SGL Segment Descriptor: The + 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. -.. c:type:: struct nvmf_connect_data +``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. +``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. -**Definition** +``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. -:: +``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. - struct nvmf_connect_data { - __u8 hostid[16]; - __le16 cntlid; - char rsvd4[238]; - char subsysnqn[NVME_NQN_LENGTH]; - char hostnqn[NVME_NQN_LENGTH]; - char rsvd5[256]; - }; +``NVME_SC_PRP_INVALID_OFFSET`` + PRP Offset Invalid: The Offset field for + a PRP entry is invalid. -**Members** +``NVME_SC_AWU_EXCEEDED`` + Atomic Write Unit Exceeded: The length + specified exceeds the atomic write unit size. -``cntlid`` - **subsysnqn** - **hostnqn** +``NVME_SC_OP_DENIED`` + Operation Denied: The command was denied + 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. + +``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. +``NVME_SC_KAT_EXPIRED`` + Keep Alive Timer Expired: The Keep Alive + Timer expired. +``NVME_SC_KAT_INVALID`` + Keep Alive Timeout Invalid: The Keep + 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. +``NVME_SC_SANITIZE_FAILED`` + Sanitize Failed: The most recent sanitize + operation failed and no recovery action + has been successfully completed. -.. c:type:: struct nvme_mi_read_nvm_ss_info +``NVME_SC_SANITIZE_IN_PROGRESS`` + Sanitize In Progress: The requested + 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. -**Definition** +``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. -:: +``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. - struct nvme_mi_read_nvm_ss_info { - __u8 nump; - __u8 mjr; - __u8 mnr; - __u8 rsvd3[29]; - }; +``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. -**Members** +``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. +``NVME_SC_LBA_RANGE`` + LBA Out of Range: The command references + 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. +``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. +``NVME_SC_RESERVATION_CONFLICT`` + Reservation Conflict: The command was + aborted due to a conflict with a + reservation held on the accessed + namespace. -.. c:type:: struct nvme_mi_port_pcie +``NVME_SC_FORMAT_IN_PROGRESS`` + Format In Progress: A Format NVM command + is in progress on the namespace. +``NVME_SC_CQ_INVALID`` + Completion Queue Invalid: The Completion + Queue identifier specified in the command + does not exist. -**Definition** +``NVME_SC_QID_INVALID`` + Invalid Queue Identifier: The creation of + the I/O Completion Queue failed due to an + invalid queue identifier specified as + part of the command. An invalid queue + identifier is one that is currently in + 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. - struct nvme_mi_port_pcie { - __u8 mps; - __u8 sls; - __u8 cls; - __u8 mlw; - __u8 nlw; - __u8 pn; - __u8 rsvd14[18]; - }; +``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. -**Members** +``NVME_SC_ABORT_MISSING`` + Abort Command is missing: The abort + command is missing. +``NVME_SC_ASYNC_LIMIT`` + Asynchronous Event Request Limit + 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. +``NVME_SC_FIRMWARE_IMAGE`` + Invalid Firmware Image: The firmware + 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. -.. c:type:: struct nvme_mi_port_smb +``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. +``NVME_SC_INVALID_FORMAT`` + Invalid Format: The LBA Format specified + is not supported. -**Definition** +``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. -:: +``NVME_SC_INVALID_QUEUE`` + Invalid Queue Deletion: Invalid I/O + Completion Queue specified to delete. - struct nvme_mi_port_smb { - __u8 vpd_addr; - __u8 mvpd_freq; - __u8 mme_addr; - __u8 mme_freq; - __u8 nvmebm; - __u8 rsvd13[19]; - }; +``NVME_SC_FEATURE_NOT_SAVEABLE`` + Feature Identifier Not Saveable: The + Feature Identifier specified does not + support a saveable value. -**Members** +``NVME_SC_FEATURE_NOT_CHANGEABLE`` + Feature Not Changeable: The Feature + 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. +``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. +``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. +``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. -.. c:type:: struct nvme_mi_read_port_info +``NVME_SC_FW_ACTIVATE_PROHIBITED`` + Firmware Activation Prohibited: The image + 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. -**Definition** +``NVME_SC_NS_INSUFFICIENT_CAP`` + Namespace Insufficient Capacity: Creating + 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. - struct nvme_mi_read_port_info { - __u8 portt; - __u8 rsvd1; - __le16 mmctptus; - __le32 meb; - union { - struct nvme_mi_port_pcie pcie; - struct nvme_mi_port_smb smb; - }; - }; +``NVME_SC_NS_ALREADY_ATTACHED`` + Namespace Already Attached: The + controller is already attached to the + namespace specified. -**Members** +``NVME_SC_NS_IS_PRIVATE`` + Namespace Is Private: The namespace is + private and is already attached to one + controller. -``portt`` - **mmctptus**; +``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. -``{unnamed_union}`` - anonymous +``NVME_SC_THIN_PROV_NOT_SUPP`` + Thin Provisioning Not Supported: Thin + provisioning is not supported by the + controller. +``NVME_SC_CTRL_LIST_INVALID`` + Controller List Invalid: The controller + list provided contains invalid controller + ids. +``NVME_SC_SELF_TEST_IN_PROGRESS`` + Device Self-test In Progress: +``NVME_SC_BP_WRITE_PROHIBITED`` + Boot Partition Write Prohibited: The + command is trying to modify a locked Boot + Partition. +``NVME_SC_INVALID_CTRL_ID`` + Invalid Controller Identifier: -.. c:type:: struct nvme_mi_read_ctrl_info +``NVME_SC_INVALID_SEC_CTRL_STATE`` + Invalid Secondary Controller State - **portid**; **prii**; **pri**; **vid**; **did**; **ssvid**; **ssid**; +``NVME_SC_INVALID_CTRL_RESOURCES`` + Invalid Number of Controller Resources -**Definition** +``NVME_SC_INVALID_RESOURCE_ID`` + Invalid Resource Identifier -:: +``NVME_SC_PMR_SAN_PROHIBITED`` + Sanitize Prohibited While Persistent + Memory Region is Enabled - struct nvme_mi_read_ctrl_info { - __u8 portid; - __u8 rsvd1[4]; - __u8 prii; - __le16 pri; - __le16 vid; - __le16 did; - __le16 ssvid; - __le16 ssid; - __u8 rsvd16[16]; - }; +``NVME_SC_ANA_GROUP_ID_INVALID`` + ANA Group Identifier Invalid -**Members** +``NVME_SC_ANA_ATTACH_FAILED`` + ANA Attach Failed +``NVME_SC_BAD_ATTRIBUTES`` + Conflicting Dataset Management Attributes +``NVME_SC_INVALID_PI`` + Invalid Protection Information +``NVME_SC_READ_ONLY`` + Attempted Write to Read Only Range +``NVME_SC_CONNECT_FORMAT`` + Incompatible Format: The NVM subsystem + does not support the record format + specified by the host. -.. c:type:: struct nvme_mi_osc +``NVME_SC_CONNECT_CTRL_BUSY`` + Controller Busy: The controller is + already associated with a host. - **type**; **opc**; +``NVME_SC_CONNECT_INVALID_PARAM`` + Connect Invalid Parameters: One or more + of the command parameters. -**Definition** +``NVME_SC_CONNECT_RESTART_DISC`` + Connect Restart Discovery: The NVM + 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 - struct nvme_mi_osc { - __u8 type; - __u8 opc; - }; +``NVME_SC_DISCONNECT_INVALID_QTYPE`` + Invalid Queue Type: The command was sent + on the wrong queue type. -**Members** +``NVME_SC_DISCOVERY_RESTART`` + Discover Restart: The snapshot of the + 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. +``NVME_SC_WRITE_FAULT`` + Write Fault: The write data could not be + committed to the media. +``NVME_SC_READ_ERROR`` + Unrecovered Read Error: The read data + 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. -.. c:type:: struct nvme_mi_read_sc_list +``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. +``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. -**Definition** +``NVME_SC_COMPARE_FAILED`` + Compare Failure: The command failed due + 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. - struct nvme_mi_read_sc_list { - __le16 numcmd; - struct nvme_mi_osc cmds[]; - }; +``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. -**Members** +``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. +``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. +``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. +``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. +``NVME_SC_CTRL_PATH_ERROR`` + Controller Pathing Error: A pathing error + was detected by the controller. -.. c:type:: struct nvme_mi_nvm_ss_health_status +``NVME_SC_HOST_PATH_ERROR`` + Host Pathing Error: A pathing error was + detected by the host. +``NVME_SC_CMD_ABORTED_BY_HOST`` + Command Aborted By Host: The command was + aborted as a result of host action. -**Definition** +``NVME_SC_CRD`` + Mask to get value of Command Retry Delay + 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. - struct nvme_mi_nvm_ss_health_status { - __u8 nss; - __u8 sw; - __u8 ctemp; - __u8 pdlu; - __le16 ccs; - __u8 rsvd8[2]; - }; +``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. -**Members** +.. c:function:: __u16 nvme_status_code_type (__u16 status_field) + Returns the NVMe Status Code Type +**Parameters** +``__u16 status_field`` + The NVMe Completion Queue Entry's Status Field -.. c:type:: enum +**Description** +See :c:type:`enum nvme_status_field ` -**Constants** -``NVME_MI_CCS_RDY`` - *undescribed* +.. c:function:: __u16 nvme_status_code (__u16 status_field) -``NVME_MI_CSS_CFS`` - *undescribed* + Returns the NVMe Status Code -``NVME_MI_CSS_SHST`` - *undescribed* +**Parameters** -``NVME_MI_CSS_NSSRO`` - *undescribed* +``__u16 status_field`` + The NVMe Completion Queue Entry's Status Field -``NVME_MI_CSS_CECO`` - *undescribed* +**Description** -``NVME_MI_CSS_NAC`` - *undescribed* +See :c:type:`enum nvme_status_field ` -``NVME_MI_CSS_FA`` - *undescribed* -``NVME_MI_CSS_CSTS`` - *undescribed* +.. c:function:: __u8 nvme_status_to_errno (int status, bool fabrics) -``NVME_MI_CSS_CTEMP`` - *undescribed* + Converts nvme return status to errno -``NVME_MI_CSS_PDLU`` - *undescribed* +**Parameters** -``NVME_MI_CSS_SPARE`` - *undescribed* +``int status`` + Return status from an nvme passthrough commmand -``NVME_MI_CSS_CCWARN`` - *undescribed* +``bool fabrics`` + Set to true if :c:type:`status` is to a fabrics target. +**Return** +An errno representing the nvme status if it is an nvme status field, +or unchanged status is < 0 since errno is already set. -.. c:type:: struct nvme_mi_ctrl_heal_status +.. c:function:: int nvme_fw_download_seq (int fd, __u32 size, __u32 xfer, __u32 offset, void * buf) -**Definition** +**Parameters** -:: +``int fd`` + File descriptor of nvme device - struct nvme_mi_ctrl_heal_status { - __le16 ctlid; - __le16 csts; - __le16 ctemp; - __u8 pdlu; - __u8 spare; - __u8 cwarn; - __u8 rsvd9[7]; - }; +``__u32 size`` + Total size of the firmware image to transfer -**Members** +``__u32 xfer`` + Maximum size to send with each partial transfer +``__u32 offset`` + Starting offset to send with this firmware downlaod +``void * buf`` + Address of buffer containing all or part of the firmware image. +**Return** +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:type:: enum +.. c:function:: int nvme_get_ctrl_telemetry (int fd, bool rae, struct nvme_telemetry_log ** log) -**Constants** -``NVME_MI_CSTS_RDY`` - *undescribed* +**Parameters** -``NVME_MI_CSTS_CFS`` - *undescribed* +``int fd`` + File descriptor of nvme device -``NVME_MI_CSTS_SHST`` - *undescribed* +``bool rae`` + Retain asynchronous events -``NVME_MI_CSTS_NSSRO`` - *undescribed* +``struct nvme_telemetry_log ** log`` + On success, set to the value of the allocated and retreived log. -``NVME_MI_CSTS_CECO`` - *undescribed* +**Description** -``NVME_MI_CSTS_NAC`` - *undescribed* +The total size allocated can be calculated as: + (:c:type:`struct nvme_telemetry_log `.dalb3 + 1) * ``NVME_LOG_TELEM_BLOCK_SIZE``. -``NVME_MI_CSTS_FA`` - *undescribed* +**Return** -``NVME_MI_CWARN_ST`` - *undescribed* +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -``NVME_MI_CWARN_TAUT`` - *undescribed* -``NVME_MI_CWARN_RD`` - *undescribed* +.. c:function:: int nvme_get_host_telemetry (int fd, struct nvme_telemetry_log ** log) -``NVME_MI_CWARN_RO`` - *undescribed* -``NVME_MI_CWARN_VMBF`` - *undescribed* +**Parameters** +``int fd`` + File descriptor of nvme device +``struct nvme_telemetry_log ** log`` + On success, set to the value of the allocated and retreived log. +**Description** -.. c:type:: struct nvme_mi_vpd_mra +The total size allocated can be calculated as: + (:c:type:`struct nvme_telemetry_log `.dalb3 + 1) * ``NVME_LOG_TELEM_BLOCK_SIZE``. - **nmravn**; **ff**; **i18vpwr**; **m18vpwr**; **i33vpwr**; **m33vpwr**; **m33vapsr**; **i5vapsr**; **m5vapsr**; **i12vapsr**; **m12vapsr**; **mtl**; **tnvmcap**[16]; +**Return** -**Definition** +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -:: - struct nvme_mi_vpd_mra { - __u8 nmravn; - __u8 ff; - __u8 rsvd7[6]; - __u8 i18vpwr; - __u8 m18vpwr; - __u8 i33vpwr; - __u8 m33vpwr; - __u8 rsvd17; - __u8 m33vapsr; - __u8 i5vapsr; - __u8 m5vapsr; - __u8 i12vapsr; - __u8 m12vapsr; - __u8 mtl; - __u8 tnvmcap[16]; - __u8 rsvd37[27]; - }; +.. c:function:: int nvme_get_new_host_telemetry (int fd, struct nvme_telemetry_log ** log) -**Members** +**Parameters** +``int fd`` + File descriptor of nvme device +``struct nvme_telemetry_log ** log`` + On success, set to the value of the allocated and retreived log. +**Description** -.. c:type:: struct nvme_mi_vpd_ppmra +The total size allocated can be calculated as: + (:c:type:`struct nvme_telemetry_log `.dalb3 + 1) * ``NVME_LOG_TELEM_BLOCK_SIZE``. +**Return** -**Definition** +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -:: - struct nvme_mi_vpd_ppmra { - __u8 nppmravn; - __u8 pn; - __u8 ppi; - __u8 ls; - __u8 mlw; - __u8 mctp; - __u8 refccap; - __u8 pi; - __u8 rsvd13[3]; - }; +.. c:function:: void nvme_init_id_ns (struct nvme_id_ns * ns, __u64 nsze, __u64 ncap, __u8 flbas, __u8 dps, __u8 nmic, __u32 anagrpid, __u16 nvmsetid) -**Members** + Initialize an Identify Namepsace structure for creation. +**Parameters** +``struct nvme_id_ns * ns`` + Address of the Identify Namespace structure to initialize +``__u64 nsze`` + Namespace size +``__u64 ncap`` + namespace capacity -.. c:type:: struct nvme_mi_vpd_telem +``__u8 flbas`` + formatted logical block size settings +``__u8 dps`` + Data protection settings -**Definition** +``__u8 nmic`` + Namespace sharing capabilities -:: +``__u32 anagrpid`` + ANA group identifier - struct nvme_mi_vpd_telem { - __u8 type; - __u8 rev; - __u8 len; - __u8 data[0]; - }; +``__u16 nvmsetid`` + NVM Set identifer -**Members** +**Description** +This is intended to be used with a namespace management "create", see +:c:type:`nvme_ns_mgmt_create`(). +.. c:function:: void nvme_init_ctrl_list (struct nvme_ctrl_list * cntlist, __u16 num_ctrls, __u16 * ctrlist) + Initialize an nvme_ctrl_list structure from an array. -.. c:type:: enum +**Parameters** +``struct nvme_ctrl_list * cntlist`` + The controller list structure to initialize -**Constants** +``__u16 num_ctrls`` + The number of controllers in the array, :c:type:`ctrlist`. -``NVME_MI_ELEM_EED`` - *undescribed* +``__u16 * ctrlist`` + An array of controller identifiers in CPU native endian. -``NVME_MI_ELEM_USCE`` - *undescribed* +**Description** -``NVME_MI_ELEM_ECED`` - *undescribed* +This is intended to be used with any command that takes a controller list +argument. See :c:type:`nvme_ns_attach_ctrls`() and :c:type:`nvme_ns_detach`(). -``NVME_MI_ELEM_LED`` - *undescribed* -``NVME_MI_ELEM_SMBMED`` - *undescribed* +.. c:function:: void nvme_init_dsm_range (struct nvme_dsm_range * dsm, __u32 * ctx_attrs, __u32 * llbas, __u64 * slbas, __u16 nr_ranges) -``NVME_MI_ELEM_PCIESED`` - *undescribed* + Constructs a data set range structure -``NVME_MI_ELEM_NVMED`` - *undescribed* +**Parameters** +``struct nvme_dsm_range * dsm`` + DSM range array +``__u32 * ctx_attrs`` + Array of context attributes +``__u32 * llbas`` + Array of length in logical blocks -.. c:type:: struct nvme_mi_vpd_tra +``__u64 * slbas`` + Array of starting logical blocks +``__u16 nr_ranges`` + The size of the dsm arrays -**Definition** +**Description** -:: +Each array must be the same size of size 'nr_ranges'. This is intended to be +used with constructing a payload for :c:type:`nvme_dsm`(). - struct nvme_mi_vpd_tra { - __u8 vn; - __u8 rsvd6; - __u8 ec; - struct nvme_mi_vpd_telem elems[0]; - }; +**Return** -**Members** +The nvme command status if a response was received or -errno +otherwise. +.. c:function:: int __nvme_get_log_page (int fd, __u32 nsid, __u8 log_id, bool rae, __u32 xfer_len, __u32 data_len, void * data) +**Parameters** -.. c:type:: struct nvme_mi_vpd_mr_common +``int fd`` + File descriptor of nvme device +``__u32 nsid`` + Namespace Identifier, if applicable. -**Definition** +``__u8 log_id`` + Log Identifier, see :c:type:`enum nvme_cmd_get_log_lid `. -:: +``bool rae`` + Retain asynchronous events - struct nvme_mi_vpd_mr_common { - __u8 type; - __u8 rf; - __u8 rlen; - __u8 rchksum; - __u8 hchksum; - union { - struct nvme_mi_vpd_mra nmra; - struct nvme_mi_vpd_ppmra ppmra; - struct nvme_mi_vpd_tra tmra; - }; - }; +``__u32 xfer_len`` + Max log transfer size per request to split the total. -**Members** +``__u32 data_len`` + Total length of the log to transfer. -``{unnamed_union}`` - anonymous +``void * data`` + User address of at least :c:type:`data_len` to store the log. +**Return** +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. +.. c:function:: int nvme_get_log_page (int fd, __u32 nsid, __u8 log_id, bool rae, __u32 data_len, void * data) -.. c:type:: struct nvme_mi_vpd_hdr +**Parameters** -**Definition** +``int fd`` + File descriptor of nvme device -:: +``__u32 nsid`` + Namespace Identifier, if applicable. - struct nvme_mi_vpd_hdr { - __u8 ipmiver; - __u8 iuaoff; - __u8 ciaoff; - __u8 biaoff; - __u8 piaoff; - __u8 mrioff; - __u8 rsvd6; - __u8 chchk; - __u8 vpd[]; - }; +``__u8 log_id`` + Log Identifier, see :c:type:`enum nvme_cmd_get_log_lid `. -**Members** +``bool rae`` + Retain asynchronous events +``__u32 data_len`` + Total length of the log to transfer. +``void * data`` + User address of at least :c:type:`data_len` to store the log. +**Description** +Calls __nvme_get_log_page() with a default 4k transfer length, as that is +guarnateed by the protocol to be a safe transfer size. -.. c:type:: enum nvme_status_field +**Return** - Defines all parts of the nvme status field: status code, status code type, and additional flags. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -**Constants** -``NVME_SCT_MASK`` - Mask to get the value of the Status Code Type +.. c:function:: int nvme_get_ana_log_len (int fd, size_t * analen) -``NVME_SCT_GENERIC`` - Generic errors applicable to multiple opcodes + Retreive size of the current ANA log -``NVME_SCT_CMD_SPECIFIC`` - Errors associated to a specific opcode +**Parameters** -``NVME_SCT_MEDIA`` - Errors associated with media and data integrity +``int fd`` + File descriptor of nvme device -``NVME_SCT_PATH`` - Errors associated with the paths connection +``size_t * analen`` + Pointer to where the length will be set on success -``NVME_SCT_VS`` - Vendor specific errors +**Return** -``NVME_SC_MASK`` - Mask to get the value of the status code. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -``NVME_SC_SUCCESS`` - Successful Completion: The command - completed without error. -``NVME_SC_INVALID_OPCODE`` - Invalid Command Opcode: A reserved coded - value or an unsupported value in the command opcode field. +.. c:function:: int nvme_namespace_attach_ctrls (int fd, __u32 nsid, __u16 num_ctrls, __u16 * ctrlist) -``NVME_SC_INVALID_FIELD`` - Invalid Field in Command: A reserved - coded value or an unsupported value in a defined field. + Attach namespace to controller(s) -``NVME_SC_CMDID_CONFLICT`` - Command ID Conflict: The command - identifier is already in use. +**Parameters** -``NVME_SC_DATA_XFER_ERROR`` - Data Transfer Error: Transferring the - data or metadata associated with a command experienced an error. +``int fd`` + File descriptor of nvme device -``NVME_SC_POWER_LOSS`` - Commands Aborted due to Power Loss - Notification: Indicates that the command - was aborted due to a power loss - notification. +``__u32 nsid`` + Namespace ID to attach -``NVME_SC_INTERNAL`` - Internal Error: The command was not - completed successfully due to an internal error. +``__u16 num_ctrls`` + Number of controllers in ctrlist -``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. +``__u16 * ctrlist`` + List of controller IDs to perform the attach action -``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. +**Return** -``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 nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -``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. -``NVME_SC_INVALID_NS`` - Invalid Namespace or Format: The - namespace or the format of that namespace is invalid. +.. c:function:: int nvme_namespace_detach_ctrls (int fd, __u32 nsid, __u16 num_ctrls, __u16 * ctrlist) -``NVME_SC_CMD_SEQ_ERROR`` - Command Sequence Error: The command was - aborted due to a protocol violation in a multi-command sequence. + Detach namespace from controller(s) -``NVME_SC_SGL_INVALID_LAST`` - Invalid SGL Segment Descriptor: The - command includes an invalid SGL Last Segment or SGL Segment descriptor. +**Parameters** -``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. +``int fd`` + File descriptor of nvme device -``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. +``__u32 nsid`` + Namespace ID to detach -``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. +``__u16 num_ctrls`` + Number of controllers in ctrlist -``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. +``__u16 * ctrlist`` + List of controller IDs to perform the detach action -``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. +**Return** -``NVME_SC_PRP_INVALID_OFFSET`` - PRP Offset Invalid: The Offset field for - a PRP entry is invalid. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -``NVME_SC_AWU_EXCEEDED`` - Atomic Write Unit Exceeded: The length - 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. +.. c:function:: int nvme_get_feature_length (int fid, __u32 cdw11, __u32 * len) -``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. + Retreive the command payload length for a specific feature identifier -``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. +**Parameters** -``NVME_SC_KAT_EXPIRED`` - Keep Alive Timer Expired: The Keep Alive - Timer expired. +``int fid`` + Feature identifier, see :c:type:`enum nvme_features_id `. -``NVME_SC_KAT_INVALID`` - Keep Alive Timeout Invalid: The Keep - Alive Timeout value specified is invalid. +``__u32 cdw11`` + The cdw11 value may affect the transfer (only known fid is + ``NVME_FEAT_FID_HOST_ID``) -``NVME_SC_CMD_ABORTED_PREMEPT`` - Command Aborted due to Preempt and Abort: - The command was aborted due to a Reservation Acquire command. +``__u32 * len`` + On success, set to this features payload length in bytes. -``NVME_SC_SANITIZE_FAILED`` - Sanitize Failed: The most recent sanitize - operation failed and no recovery action has been successfully completed. +**Return** -``NVME_SC_SANITIZE_IN_PROGRESS`` - Sanitize In Progress: The requested - function (e.g., command) is prohibited - while a sanitize operation is in - progress. +0 on success, -1 with errno set to EINVAL if the function did not +recognize :c:type:`fid`. -``NVME_SC_SGL_INVALID_GRANULARITY`` - SGL Data Block Granularity Invalid: The - 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. +.. c:function:: int nvme_get_directive_receive_length (enum nvme_directive_dtype dtype, enum nvme_directive_receive_doper doper, __u32 * len) -``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. -``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. +**Parameters** -``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. +``enum nvme_directive_dtype dtype`` + Directive type, see :c:type:`enum nvme_directive_dtype ` -``NVME_SC_LBA_RANGE`` - LBA Out of Range: The command references - an LBA that exceeds the size of the namespace. +``enum nvme_directive_receive_doper doper`` + Directive receive operation, see :c:type:`enum nvme_directive_receive_doper ` -``NVME_SC_CAP_EXCEEDED`` - Capacity Exceeded: Execution of the - command has caused the capacity of the - namespace to be exceeded. +``__u32 * len`` + On success, set to this directives payload length in bytes. -``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. +**Return** -``NVME_SC_RESERVATION_CONFLICT`` - Reservation Conflict: The command was - aborted due to a conflict with a - reservation held on the accessed - namespace. +0 on success, -1 with errno set to EINVAL if the function did not +recognize :c:type:`dtype` or :c:type:`doper`. -``NVME_SC_FORMAT_IN_PROGRESS`` - Format In Progress: A Format NVM command - is in progress on the namespace. -``NVME_SC_CQ_INVALID`` - Completion Queue Invalid: The Completion - Queue identifier specified in the command - does not exist. +.. c:function:: int nvme_open (const char * name) -``NVME_SC_QID_INVALID`` - Invalid Queue Identifier: The creation of - the I/O Completion Queue failed due to an - invalid queue identifier specified as - part of the command. An invalid queue - identifier is one that is currently in - use or one that is outside the range - supported by the controller. + Open an nvme controller or namespace device -``NVME_SC_QUEUE_SIZE`` - Invalid Queue Size: The host attempted to - create an I/O Completion Queue with an - invalid number of entries. +**Parameters** -``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. +``const char * name`` + The basename of the device to open -``NVME_SC_ABORT_MISSING`` - Abort Command is missing: The abort - command is missing. +**Description** -``NVME_SC_ASYNC_LIMIT`` - Asynchronous Event Request Limit - Exceeded: The number of concurrently - outstanding Asynchronous Event Request - commands has been exceeded. +This will look for the handle in /dev/ and validate the name and filetype +match linux conventions. -``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. +**Return** -``NVME_SC_FIRMWARE_IMAGE`` - Invalid Firmware Image: The firmware - image specified for activation is invalid - and not loaded by the controller. +A file descriptor for the device on a successful open, or -1 with +errno set otherwise. -``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. -``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. -``NVME_SC_INVALID_FORMAT`` - Invalid Format: The LBA Format specified - 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. +.. c:type:: struct nvme_fabrics_config -``NVME_SC_INVALID_QUEUE`` - Invalid Queue Deletion: Invalid I/O - Completion Queue specified to delete. + Defines all linux nvme fabrics initiator options -``NVME_SC_FEATURE_NOT_SAVEABLE`` - Feature Identifier Not Saveable: The - Feature Identifier specified does not - support a saveable value. +**Definition** -``NVME_SC_FEATURE_NOT_CHANGEABLE`` - Feature Not Changeable: The Feature - 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. + struct nvme_fabrics_config { + const char *transport; + const char *traddr; + const char *trsvcid; + const char *nqn; + const char *hostnqn; + const char *host_traddr; + const char *hostid; + int queue_size; + int nr_io_queues; + int reconnect_delay; + int ctrl_loss_tmo; + int keep_alive_tmo; + int nr_write_queues; + int nr_poll_queues; + int tos; + bool duplicate_connect; + bool disable_sqflow; + bool hdr_digest; + bool data_digest; + }; -``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. +**Members** -``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. +``transport`` + The fabric transport to use, either loop, fc, tcp, or rdma -``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. +``traddr`` + Transport Address for the target, format specific to transport type -``NVME_SC_FW_ACTIVATE_PROHIBITED`` - Firmware Activation Prohibited: The image - specified is being prohibited from - activation by the controller for vendor - specific reasons. +``trsvcid`` + Transport Service Identifier, specific to the transport type -``NVME_SC_OVERLAPPING_RANGE`` - Overlapping Range: The downloaded - firmware image has overlapping ranges. +``nqn`` + Target NVMe Qualified Name -``NVME_SC_NS_INSUFFICIENT_CAP`` - Namespace Insufficient Capacity: Creating - the namespace requires more free space - than is currently available. +``hostnqn`` + Host NVMe Qualified Name -``NVME_SC_NS_ID_UNAVAILABLE`` - Namespace Identifier Unavailable: The - number of namespaces supported has been - exceeded. +``host_traddr`` + Host Transport Address -``NVME_SC_NS_ALREADY_ATTACHED`` - Namespace Already Attached: The - controller is already attached to the - namespace specified. +``hostid`` + Host Identifier -``NVME_SC_NS_IS_PRIVATE`` - Namespace Is Private: The namespace is - private and is already attached to one - controller. +``queue_size`` + Number of IO queue entries -``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. +``nr_io_queues`` + Number of controller IO queues to establish -``NVME_SC_THIN_PROV_NOT_SUPP`` - Thin Provisioning Not Supported: Thin - provisioning is not supported by the - controller. +``reconnect_delay`` + Time between two consecutive reconnect attempts. -``NVME_SC_CTRL_LIST_INVALID`` - Controller List Invalid: The controller - list provided contains invalid controller - ids. +``ctrl_loss_tmo`` + Override the default controller reconnect attempt timeout in seconds -``NVME_SC_SELF_TEST_IN_PROGRESS`` - Device Self-test In Progress: +``keep_alive_tmo`` + Override the default keep-alive-timeout to this value in seconds -``NVME_SC_BP_WRITE_PROHIBITED`` - Boot Partition Write Prohibited: The - command is trying to modify a locked Boot - Partition. +``nr_write_queues`` + Number of queues to use for exclusively for writing -``NVME_SC_INVALID_CTRL_ID`` - Invalid Controller Identifier: +``nr_poll_queues`` + Number of queues to reserve for polling completions -``NVME_SC_INVALID_SEC_CTRL_STATE`` - Invalid Secondary Controller State +``tos`` + Type of service -``NVME_SC_INVALID_CTRL_RESOURCES`` - Invalid Number of Controller Resources +``duplicate_connect`` + Allow multiple connections to the same target -``NVME_SC_INVALID_RESOURCE_ID`` - Invalid Resource Identifier +``disable_sqflow`` + Disable controller sq flow control -``NVME_SC_PMR_SAN_PROHIBITED`` - Sanitize Prohibited While Persistent - Memory Region is Enabled +``hdr_digest`` + Generate/verify header digest (TCP) -``NVME_SC_ANA_GROUP_ID_INVALID`` - ANA Group Identifier Invalid +``data_digest`` + Generate/verify data digest (TCP) -``NVME_SC_ANA_ATTACH_FAILED`` - ANA Attach Failed -``NVME_SC_BAD_ATTRIBUTES`` - Conflicting Dataset Management Attributes -``NVME_SC_INVALID_PI`` - Invalid Protection Information +.. c:function:: int nvmf_add_ctrl_opts (struct nvme_fabrics_config * cfg) -``NVME_SC_READ_ONLY`` - Attempted Write to Read Only Range -``NVME_SC_CONNECT_FORMAT`` - Incompatible Format: The NVM subsystem - does not support the record format - specified by the host. +**Parameters** -``NVME_SC_CONNECT_CTRL_BUSY`` - Controller Busy: The controller is - already associated with a host. +``struct nvme_fabrics_config * cfg`` -``NVME_SC_CONNECT_INVALID_PARAM`` - Connect Invalid Parameters: One or more - of the command parameters. -``NVME_SC_CONNECT_RESTART_DISC`` - Connect Restart Discovery: The NVM - subsystem requested is not available. +.. c:function:: nvme_ctrl_t nvmf_add_ctrl (struct nvme_fabrics_config * cfg) -``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 -``NVME_SC_DISCONNECT_INVALID_QTYPE`` - Invalid Queue Type: The command was sent - on the wrong queue type. +**Parameters** -``NVME_SC_DISCOVERY_RESTART`` - Discover Restart: The snapshot of the - records is now invalid or out of date. +``struct nvme_fabrics_config * cfg`` -``NVME_SC_AUTH_REQUIRED`` - Authentication Required: NVMe in-band - 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. +.. c:function:: int nvmf_get_discovery_log (nvme_ctrl_t c, struct nvmf_discovery_log ** logp, int max_retries) -``NVME_SC_READ_ERROR`` - Unrecovered Read Error: The read data - 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. +**Parameters** -``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. +``nvme_ctrl_t c`` + *undescribed* -``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. +``struct nvmf_discovery_log ** logp`` + *undescribed* -``NVME_SC_COMPARE_FAILED`` - Compare Failure: The command failed due - to a miscompare during a Compare command. +``int max_retries`` -``NVME_SC_ACCESS_DENIED`` - Access Denied: Access to the namespace - 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. +.. c:function:: char * nvmf_hostnqn_generate () -``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. + Generate a machine specific host nqn -``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. +**Parameters** -``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. +**Return** -``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. +An nvm namespace qualifieid name string based on the machine +identifier, or NULL if not successful. -``NVME_SC_CTRL_PATH_ERROR`` - Controller Pathing Error: A pathing error - was detected by the controller. -``NVME_SC_HOST_PATH_ERROR`` - Host Pathing Error: A pathing error was - detected by the host. +.. c:function:: char * nvmf_hostnqn_from_file () -``NVME_SC_CMD_ABORTED_BY_HOST`` - Command Aborted By Host: The command was - aborted as a result of host action. + Reads the host nvm qualified name from the config default location in /etc/nvme/ -``NVME_SC_CRD`` - Mask to get value of Command Retry Delay - index +**Parameters** -``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. +**Return** -``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. +The host nqn, or NULL if unsuccessful. If found, the caller +is responsible to free the string. -.. c:function:: __u16 nvme_status_code_type (__u16 status_field) +.. c:function:: char * nvmf_hostid_from_file () - Returns the NVMe Status Code Type + Reads the host identifier from the config default location in /etc/nvme/. **Parameters** -``__u16 status_field`` - The NVMe Completion Queue Entry's Status Field - -**Description** +**Return** -See :c:type:`enum nvme_status_field ` +The host identifier, or NULL if unsuccessful. If found, the caller + is responsible to free the string. -.. c:function:: __u16 nvme_status_code (__u16 status_field) +.. c:function:: nvme_ctrl_t nvmf_connect_disc_entry (struct nvmf_disc_log_entry * e, const struct nvme_fabrics_config * defcfg, bool * discover) - Returns the NVMe Status Code **Parameters** -``__u16 status_field`` - The NVMe Completion Queue Entry's Status Field +``struct nvmf_disc_log_entry * e`` + *undescribed* -**Description** +``const struct nvme_fabrics_config * defcfg`` + *undescribed* -See :c:type:`enum nvme_status_field ` +``bool * discover`` + +**Return** + +An diff --git a/src/nvme/fabrics.h b/src/nvme/fabrics.h index 1ca4eb53e8..d512cf3dab 100644 --- a/src/nvme/fabrics.h +++ b/src/nvme/fabrics.h @@ -14,27 +14,26 @@ #include "tree.h" /** - * struct nvme_fabrics_config - - * @transport: - * @traddr: - * @trsvcid: - * @nqn: - * @hostnqn: - * @host_traddr: - * @hostid: - * @queue_size: - * @nr_io_queues: - * @reconnect_delay: - * @ctrl_loss_tmo: - * @keep_alive_tmo: - * @nr_write_queues: - * @nr_poll_queues: - * @tos: - * @duplicate_connect: - * @disable_sqflow: - * @hdr_digest: - * @data_digest: - * @rsvd: + * struct nvme_fabrics_config - Defines all linux nvme fabrics initiator options + * @transport: The fabric transport to use, either loop, fc, tcp, or rdma + * @traddr: Transport Address for the target, format specific to transport type + * @trsvcid: Transport Service Identifier, specific to the transport type + * @nqn: Target NVMe Qualified Name + * @hostnqn: Host NVMe Qualified Name + * @host_traddr: Host Transport Address + * @hostid: Host Identifier + * @queue_size: Number of IO queue entries + * @nr_io_queues: Number of controller IO queues to establish + * @reconnect_delay: Time between two consecutive reconnect attempts. + * @ctrl_loss_tmo: Override the default controller reconnect attempt timeout in seconds + * @keep_alive_tmo: Override the default keep-alive-timeout to this value in seconds + * @nr_write_queues: Number of queues to use for exclusively for writing + * @nr_poll_queues: Number of queues to reserve for polling completions + * @tos: Type of service + * @duplicate_connect: Allow multiple connections to the same target + * @disable_sqflow: Disable controller sq flow control + * @hdr_digest: Generate/verify header digest (TCP) + * @data_digest: Generate/verify data digest (TCP) */ struct nvme_fabrics_config { const char *transport; @@ -58,8 +57,6 @@ struct nvme_fabrics_config { bool disable_sqflow; bool hdr_digest; bool data_digest; - - uint8_t rsvd[0x200]; }; /** @@ -92,7 +89,7 @@ int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, /** * nvmf_hostnqn_generate() - Generate a machine specific host nqn * Returns: An nvm namespace qualifieid name string based on the machine - * identifier, or NULL if not successful. + * identifier, or NULL if not successful. */ char *nvmf_hostnqn_generate(); @@ -100,7 +97,7 @@ char *nvmf_hostnqn_generate(); * nvmf_hostnqn_from_file() - Reads the host nvm qualified name from the config * default location in /etc/nvme/ * Return: The host nqn, or NULL if unsuccessful. If found, the caller - * is responsible to free the string. + * is responsible to free the string. */ char *nvmf_hostnqn_from_file(); @@ -118,7 +115,7 @@ char *nvmf_hostid_from_file(); * @defcfg: * @discover: * - * Return: + * Return: An */ nvme_ctrl_t nvmf_connect_disc_entry(struct nvmf_disc_log_entry *e, const struct nvme_fabrics_config *defcfg, bool *discover); diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 57ff36c4e4..ae16b8dadf 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -132,7 +132,7 @@ struct nvme_passthru_cmd64 { * Uses NVME_IOCTL_ADMIN64_CMD for the ioctl request. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_submit_admin_passthru64(int fd, struct nvme_passthru_cmd64 *cmd, __u64 *result); @@ -165,7 +165,7 @@ int nvme_submit_admin_passthru64(int fd, struct nvme_passthru_cmd64 *cmd, * Known values for @opcode are defined in &enum nvme_admin_opcode. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_admin_passthru64(int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, @@ -182,7 +182,7 @@ int nvme_admin_passthru64(int fd, __u8 opcode, __u8 flags, __u16 rsvd, * Uses NVME_IOCTL_ADMIN_CMD for the ioctl request. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_submit_admin_passthru(int fd, struct nvme_passthru_cmd *cmd, __u32 *result); @@ -215,7 +215,7 @@ int nvme_submit_admin_passthru(int fd, struct nvme_passthru_cmd *cmd, * Known values for @opcode are defined in &enum nvme_admin_opcode. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_admin_passthru(int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, @@ -232,7 +232,7 @@ int nvme_admin_passthru(int fd, __u8 opcode, __u8 flags, __u16 rsvd, * Uses NVME_IOCTL_IO64_CMD for the ioctl request. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_submit_io_passthru64(int fd, struct nvme_passthru_cmd64 *cmd, __u64 *result); @@ -265,7 +265,7 @@ int nvme_submit_io_passthru64(int fd, struct nvme_passthru_cmd64 *cmd, * Known values for @opcode are defined in &enum nvme_io_opcode. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_io_passthru64(int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, @@ -283,7 +283,7 @@ int nvme_io_passthru64(int fd, __u8 opcode, __u8 flags, __u16 rsvd, * Uses NVME_IOCTL_IO_CMD for the ioctl request. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_submit_io_passthru(int fd, struct nvme_passthru_cmd *cmd, __u32 *result); @@ -316,7 +316,7 @@ int nvme_submit_io_passthru(int fd, struct nvme_passthru_cmd *cmd, * Known values for @opcode are defined in &enum nvme_io_opcode. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_io_passthru(int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, @@ -331,7 +331,7 @@ int nvme_io_passthru(int fd, __u8 opcode, __u8 flags, __u16 rsvd, * This should only be sent to controller handles, not to namespaces. * * Return: Zero if a subsystem reset was initiated or -1 with errno set - * otherwise. + * otherwise. */ int nvme_subsystem_reset(int fd); @@ -341,7 +341,7 @@ int nvme_subsystem_reset(int fd); * * This should only be sent to controller handles, not to namespaces. * - * Return: Zero if a reset was initiated or -1 with errno set otherwise. + * Return: 0 if a reset was initiated or -1 with errno set otherwise. */ int nvme_ctrl_reset(int fd); @@ -351,7 +351,7 @@ int nvme_ctrl_reset(int fd); * * This should only be sent to controller handles, not to namespaces. * - * Return: Zero if a rescan was initiated or -1 with errno set otherwise. + * Return: 0 if a rescan was initiated or -1 with errno set otherwise. */ int nvme_ns_rescan(int fd); @@ -362,7 +362,7 @@ int nvme_ns_rescan(int fd); * This should only be sent to namespace handles, not to controllers. * * Return: The namespace identifier if a succecssful or -1 with errno set - * otherwise. + * otherwise. */ int nvme_get_nsid(int fd); @@ -772,7 +772,7 @@ enum nvme_virt_mgmt_rt { * the NVM subsystem, the controller or the namespace(s). * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify(int fd, enum nvme_identify_cns cns, __u32 nsid, __u16 cntid, __u16 nvmsetid, __u8 uuidx, void *data); @@ -787,7 +787,7 @@ int nvme_identify(int fd, enum nvme_identify_cns cns, __u32 nsid, * See &struct nvme_id_ctrl for details on the data returned. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_ctrl(int fd, struct nvme_id_ctrl *id); @@ -809,7 +809,7 @@ int nvme_identify_ctrl(int fd, struct nvme_id_ctrl *id); * See &struct nvme_id_ns for details on the structure returned. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_ns(int fd, __u32 nsid, struct nvme_id_ns *ns); @@ -821,7 +821,7 @@ int nvme_identify_ns(int fd, __u32 nsid, struct nvme_id_ns *ns); * @ns: User space destination address to transfer the data * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_allocated_ns(int fd, __u32 nsid, struct nvme_id_ns *ns); @@ -838,7 +838,7 @@ int nvme_identify_allocated_ns(int fd, __u32 nsid, struct nvme_id_ns *ns); * See &struct nvme_ns_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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_active_ns_list(int fd, __u32 nsid, struct nvme_ns_list *list); @@ -855,7 +855,7 @@ int nvme_identify_active_ns_list(int fd, __u32 nsid, struct nvme_ns_list *list); * See &struct nvme_ns_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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_allocated_ns_list(int fd, __u32 nsid, struct nvme_ns_list *list); @@ -873,7 +873,7 @@ int nvme_identify_allocated_ns_list(int fd, __u32 nsid, * See &struct nvme_ctrl_list for a definition of the structure returned. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_ctrl_list(int fd, __u16 cntid, struct nvme_ctrl_list *ctrlist); @@ -892,7 +892,7 @@ int nvme_identify_ctrl_list(int fd, __u16 cntid, * See &struct nvme_ctrl_list for a definition of the structure returned. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 + * &enum nvme_status_field) or -1 */ int nvme_identify_nsid_ctrl_list(int fd, __u32 nsid, __u16 cntid, struct nvme_ctrl_list *ctrlist); @@ -912,7 +912,7 @@ int nvme_identify_nsid_ctrl_list(int fd, __u32 nsid, __u16 cntid, * See &struct nvme_ns_id_desc for the definition of the returned structure. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_ns_descs(int fd, __u32 nsid, struct nvme_ns_id_desc *descs); @@ -930,7 +930,7 @@ int nvme_identify_ns_descs(int fd, __u32 nsid, struct nvme_ns_id_desc *descs); * See &struct nvme_id_nvmset_list 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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_nvmset_list(int fd, __u16 nvmsetid, struct nvme_id_nvmset_list *nvmset); @@ -945,7 +945,7 @@ int nvme_identify_nvmset_list(int fd, __u16 nvmsetid, * See &struct nvme_primary_ctrl_cap for the defintion 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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_primary_ctrl(int fd, __u16 cntid, struct nvme_primary_ctrl_cap *cap); @@ -965,7 +965,7 @@ int nvme_identify_primary_ctrl(int fd, __u16 cntid, * structure. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_secondary_ctrl_list(int fd, __u16 cntid, struct nvme_secondary_ctrl_list *list); @@ -984,7 +984,7 @@ int nvme_identify_secondary_ctrl_list(int fd, __u16 cntid, * structure. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_ns_granularity(int fd, struct nvme_id_ns_granularity_list *list); @@ -999,7 +999,7 @@ int nvme_identify_ns_granularity(int fd, struct nvme_id_ns_granularity_list *lis * See &struct nvme_id_uuid_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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify_uuid(int fd, struct nvme_id_uuid_list *list); @@ -1017,7 +1017,7 @@ int nvme_identify_uuid(int fd, struct nvme_id_uuid_list *list); * @log: User space destination address to transfer the data * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, __u8 lsp, __u16 lsi, bool rae, __u8 uuidx, __u32 len, void *log); @@ -1034,7 +1034,7 @@ int nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, * particular command. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_error(int fd, unsigned nr_entries, bool rae, struct nvme_error_log_page *log); @@ -1054,7 +1054,7 @@ int nvme_get_log_error(int fd, unsigned nr_entries, bool rae, * the LPA field in the Identify Controller data structure. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_smart(int fd, __u32 nsid, bool rae, struct nvme_smart_log *log); @@ -1069,7 +1069,7 @@ int nvme_get_log_smart(int fd, __u32 nsid, bool rae, struct nvme_smart_log *log) * string. The log page also indicates the active slot number. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_fw_slot(int fd, bool rae, struct nvme_firmware_slot *log); @@ -1084,7 +1084,7 @@ int nvme_get_log_fw_slot(int fd, bool rae, struct nvme_firmware_slot *log); * added, or deleted. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_changed_ns_list(int fd, bool rae, struct nvme_ns_list *log); @@ -1097,7 +1097,7 @@ int nvme_get_log_changed_ns_list(int fd, bool rae, struct nvme_ns_list *log); * and the effects of those commands on the state of the NVM subsystem. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_cmd_effects(int fd, struct nvme_cmd_effects_log *log); @@ -1112,7 +1112,7 @@ int nvme_get_log_cmd_effects(int fd, struct nvme_cmd_effects_log *log); * self-test operations. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_device_self_test(int fd, struct nvme_self_test_log *log); @@ -1132,7 +1132,7 @@ int nvme_get_log_create_telemetry_host(int fd, struct nvme_telemetry_log *log); * 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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_telemetry_host(int fd, __u64 offset, __u32 len, void *log); @@ -1161,7 +1161,7 @@ int nvme_get_log_telemetry_ctrl(int fd, bool rae, __u64 offset, __u32 len, * page. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_endurance_group(int fd, __u16 endgid, struct nvme_endurance_group_log *log); @@ -1172,7 +1172,7 @@ int nvme_get_log_endurance_group(int fd, __u16 endgid, * @nvmsetid: * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_predictable_lat_nvmset(int fd, __u16 nvmsetid, struct nvme_nvmset_predictable_lat_log *log); @@ -1210,7 +1210,7 @@ enum nvme_log_ana_lsp { * See &struct nvme_ana_rsp_hdr 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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_ana(int fd, enum nvme_log_ana_lsp lsp, bool rae, __u64 offset, __u32 len, void *log); @@ -1253,7 +1253,7 @@ int nvme_get_log_endurance_grp_evt(int fd, bool rae, __u32 offset, __u32 len, * records. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_discovery(int fd, bool rae, __u32 offset, __u32 len, void *log); @@ -1275,7 +1275,7 @@ int nvme_get_log_reservation(int fd, bool rae, * estimates and information about the most recent sanitize operation. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_sanitize(int fd, bool rae, struct nvme_sanitize_log_page *log); @@ -1295,7 +1295,7 @@ int nvme_get_log_sanitize(int fd, bool rae, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features(int fd, __u8 fid, __u32 nsid, __u32 cdw11, __u32 cdw12, bool save, __u8 uuidx, __u32 cdw15, __u32 data_len, @@ -1308,7 +1308,7 @@ int nvme_set_features(int fd, __u8 fid, __u32 nsid, __u32 cdw11, __u32 cdw12, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_arbitration(int fd, __u8 ab, __u8 lpw, __u8 mpw, __u8 hpw, bool save, __u32 *result); @@ -1320,7 +1320,7 @@ int nvme_set_features_arbitration(int fd, __u8 ab, __u8 lpw, __u8 mpw, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_power_mgmt(int fd, __u8 ps, __u8 wh, bool save, __u32 *result); @@ -1332,7 +1332,7 @@ int nvme_set_features_power_mgmt(int fd, __u8 ps, __u8 wh, bool save, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_lba_range(int fd, __u32 nsid, __u32 nr_ranges, bool save, struct nvme_lba_range_type *data, __u32 *result); @@ -1353,7 +1353,7 @@ enum nvme_feat_tmpthresh_thsel { * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_temp_thresh(int fd, __u16 tmpth, __u8 tmpsel, enum nvme_feat_tmpthresh_thsel thsel, @@ -1366,7 +1366,7 @@ int nvme_set_features_temp_thresh(int fd, __u16 tmpth, __u8 tmpsel, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_err_recovery(int fd, __u32 nsid, __u16 tler, bool dulbe, bool save, __u32 *result); @@ -1379,7 +1379,7 @@ int nvme_set_features_err_recovery(int fd, __u32 nsid, __u16 tler, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_volatile_wc(int fd, bool wce, bool save, __u32 *result); @@ -1391,7 +1391,7 @@ int nvme_set_features_volatile_wc(int fd, bool wce, bool save, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_irq_coalesce(int fd, __u8 thr, __u8 time, bool save, __u32 *result); @@ -1403,7 +1403,7 @@ int nvme_set_features_irq_coalesce(int fd, __u8 thr, __u8 time, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_irq_config(int fd, __u16 iv, bool cd, bool save, __u32 *result); @@ -1416,7 +1416,7 @@ int nvme_set_features_irq_config(int fd, __u16 iv, bool cd, bool save, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_write_atomic(int fd, bool dn, bool save, __u32 *result); @@ -1448,7 +1448,7 @@ enum nvme_features_async_event_config_flags { * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_async_event(int fd, __u32 events, bool save, __u32 *result); @@ -1461,7 +1461,7 @@ int nvme_set_features_async_event(int fd, __u32 events, bool save, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_auto_pst(int fd, bool apste, bool save, struct nvme_feat_auto_pst *apst, @@ -1474,7 +1474,7 @@ int nvme_set_features_auto_pst(int fd, bool apste, bool save, * @timestamp: The current timestamp value to assign to this this feature * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_timestamp(int fd, bool save, __u64 timestamp); @@ -1486,7 +1486,7 @@ int nvme_set_features_timestamp(int fd, bool save, __u64 timestamp); * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_hctm(int fd, __u16 tmt2, __u16 tmt1, bool save, __u32 *result); @@ -1503,7 +1503,7 @@ int nvme_set_features_nopsc(int fd, bool noppme, bool save, __u32 *result); * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_rrl(int fd, __u8 rrl, __u16 nvmsetid, bool save, __u32 *result); @@ -1515,7 +1515,7 @@ int nvme_set_features_rrl(int fd, __u8 rrl, __u16 nvmsetid, bool save, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_plm_config(int fd, bool enable, __u16 nvmsetid, bool save, struct nvme_plm_config *data, @@ -1536,7 +1536,7 @@ enum nvme_feat_plm_window_select { * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_plm_window(int fd, enum nvme_feat_plm_window_select sel, __u16 nvmsetid, bool save, __u32 *result); @@ -1549,7 +1549,7 @@ int nvme_set_features_plm_window(int fd, enum nvme_feat_plm_window_select sel, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_lba_sts_interval(int fd, __u16 lsiri, __u16 lsipi, bool save, __u32 *result); @@ -1561,7 +1561,7 @@ int nvme_set_features_lba_sts_interval(int fd, __u16 lsiri, __u16 lsipi, * @save: Save value across power states * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_host_behavior(int fd, bool save, struct nvme_feat_host_behavior *data); @@ -1573,7 +1573,7 @@ int nvme_set_features_host_behavior(int fd, bool save, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_sanitize(int fd, bool nodrm, bool save, __u32 *result); @@ -1586,7 +1586,7 @@ int nvme_set_features_sanitize(int fd, bool nodrm, bool save, __u32 *result); * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_endurance_evt_cfg(int fd, __u16 endgid, __u8 egwarn, bool save, __u32 *result); @@ -1598,7 +1598,7 @@ int nvme_set_features_endurance_evt_cfg(int fd, __u16 endgid, __u8 egwarn, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_sw_progress(int fd, __u8 pbslc, bool save, __u32 *result); @@ -1611,7 +1611,7 @@ int nvme_set_features_sw_progress(int fd, __u8 pbslc, bool save, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_host_id(int fd, bool exhid, bool save, __u8 *hostid); @@ -1631,7 +1631,7 @@ enum nvme_feat_resv_notify_flags { * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_resv_mask(int fd, __u32 mask, bool save, __u32 *result); @@ -1642,7 +1642,7 @@ int nvme_set_features_resv_mask(int fd, __u32 mask, bool save, __u32 *result); * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_resv_persist(int fd, bool ptpl, bool save, __u32 *result); @@ -1667,7 +1667,7 @@ enum nvme_feat_nswpcfg_state { * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_features_write_protect(int fd, enum nvme_feat_nswpcfg_state state, bool save, __u32 *result); @@ -1685,7 +1685,7 @@ int nvme_set_features_write_protect(int fd, enum nvme_feat_nswpcfg_state state, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features(int fd, enum nvme_features_id fid, __u32 nsid, enum nvme_get_features_sel sel, __u32 cdw11, __u8 uuidx, @@ -1698,7 +1698,7 @@ int nvme_get_features(int fd, enum nvme_features_id fid, __u32 nsid, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_arbitration(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1710,7 +1710,7 @@ int nvme_get_features_arbitration(int fd, enum nvme_get_features_sel sel, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_power_mgmt(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1722,7 +1722,7 @@ int nvme_get_features_power_mgmt(int fd, enum nvme_get_features_sel sel, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_lba_range(int fd, enum nvme_get_features_sel sel, struct nvme_lba_range_type *data, @@ -1735,7 +1735,7 @@ int nvme_get_features_lba_range(int fd, enum nvme_get_features_sel sel, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_temp_thresh(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1747,7 +1747,7 @@ int nvme_get_features_temp_thresh(int fd, enum nvme_get_features_sel sel, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_err_recovery(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1759,7 +1759,7 @@ int nvme_get_features_err_recovery(int fd, enum nvme_get_features_sel sel, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_volatile_wc(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1771,7 +1771,7 @@ int nvme_get_features_volatile_wc(int fd, enum nvme_get_features_sel sel, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_num_queues(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1783,7 +1783,7 @@ int nvme_get_features_num_queues(int fd, enum nvme_get_features_sel sel, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_irq_coalesce(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1795,7 +1795,7 @@ int nvme_get_features_irq_coalesce(int fd, enum nvme_get_features_sel sel, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_irq_config(int fd, enum nvme_get_features_sel sel, __u16 iv, __u32 *result); @@ -1807,7 +1807,7 @@ int nvme_get_features_irq_config(int fd, enum nvme_get_features_sel sel, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_write_atomic(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1819,7 +1819,7 @@ int nvme_get_features_write_atomic(int fd, enum nvme_get_features_sel sel, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_async_event(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1831,7 +1831,7 @@ int nvme_get_features_async_event(int fd, enum nvme_get_features_sel sel, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_auto_pst(int fd, enum nvme_get_features_sel sel, struct nvme_feat_auto_pst *apst, __u32 *result); @@ -1843,7 +1843,7 @@ int nvme_get_features_auto_pst(int fd, enum nvme_get_features_sel sel, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_host_mem_buf(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1855,7 +1855,7 @@ int nvme_get_features_host_mem_buf(int fd, enum nvme_get_features_sel sel, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_timestamp(int fd, enum nvme_get_features_sel sel, struct nvme_timestamp *ts); @@ -1867,7 +1867,7 @@ int nvme_get_features_timestamp(int fd, enum nvme_get_features_sel sel, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_kato(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1878,7 +1878,7 @@ int nvme_get_features_kato(int fd, enum nvme_get_features_sel sel, __u32 *result * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_hctm(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1889,7 +1889,7 @@ int nvme_get_features_hctm(int fd, enum nvme_get_features_sel sel, __u32 *result * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_nopsc(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1900,7 +1900,7 @@ int nvme_get_features_nopsc(int fd, enum nvme_get_features_sel sel, __u32 *resul * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_rrl(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1911,7 +1911,7 @@ int nvme_get_features_rrl(int fd, enum nvme_get_features_sel sel, __u32 *result) * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_plm_config(int fd, enum nvme_get_features_sel sel, __u16 nvmsetid, struct nvme_plm_config *data, @@ -1924,7 +1924,7 @@ int nvme_get_features_plm_config(int fd, enum nvme_get_features_sel sel, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_plm_window(int fd, enum nvme_get_features_sel sel, __u16 nvmsetid, __u32 *result); @@ -1936,7 +1936,7 @@ int nvme_get_features_plm_window(int fd, enum nvme_get_features_sel sel, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_lba_sts_interval(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1948,7 +1948,7 @@ int nvme_get_features_lba_sts_interval(int fd, enum nvme_get_features_sel sel, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_host_behavior(int fd, enum nvme_get_features_sel sel, struct nvme_feat_host_behavior *data, @@ -1961,7 +1961,7 @@ int nvme_get_features_host_behavior(int fd, enum nvme_get_features_sel sel, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_sanitize(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1973,7 +1973,7 @@ int nvme_get_features_sanitize(int fd, enum nvme_get_features_sel sel, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_endurance_event_cfg(int fd, enum nvme_get_features_sel sel, __u16 endgid, __u32 *result); @@ -1985,7 +1985,7 @@ int nvme_get_features_endurance_event_cfg(int fd, enum nvme_get_features_sel sel * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_sw_progress(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -1997,7 +1997,7 @@ int nvme_get_features_sw_progress(int fd, enum nvme_get_features_sel sel, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_host_id(int fd, enum nvme_get_features_sel sel, bool exhid, __u32 len, __u8 *hostid); @@ -2009,7 +2009,7 @@ int nvme_get_features_host_id(int fd, enum nvme_get_features_sel sel, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_resv_mask(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -2021,7 +2021,7 @@ int nvme_get_features_resv_mask(int fd, enum nvme_get_features_sel sel, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_resv_persist(int fd, enum nvme_get_features_sel sel, __u32 *result); @@ -2034,7 +2034,7 @@ int nvme_get_features_resv_persist(int fd, enum nvme_get_features_sel sel, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_features_write_protect(int fd, __u32 nsid, enum nvme_get_features_sel sel, @@ -2059,7 +2059,7 @@ int nvme_get_features_write_protect(int fd, __u32 nsid, * all namespaces or only the specific namespace associated with the command * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_format_nvm(int fd, __u32 nsid, __u8 lbaf, enum nvme_cmd_format_mset mset, @@ -2088,7 +2088,7 @@ int nvme_ns_mgmt(int fd, __u32 nsid, enum nvme_ns_mgmt_sel sel, * namespace to one or more controllers. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_ns_mgmt_create(int fd, struct nvme_id_ns *ns, __u32 *nsid, __u32 timeout); @@ -2103,7 +2103,7 @@ int nvme_ns_mgmt_create(int fd, struct nvme_id_ns *ns, __u32 *nsid, * attached. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_ns_mgmt_delete(int fd, __u32 nsid); @@ -2155,7 +2155,7 @@ int nvme_ns_detach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist); * image. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_fw_download(int fd, __u32 offset, __u32 data_len, void *data); @@ -2170,7 +2170,7 @@ int nvme_fw_download(int fd, __u32 offset, __u32 data_len, void *data); * Partitions. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. The command + * &enum nvme_status_field) or -1 with errno set otherwise. The command * status * response may specify additional * reset actions required to complete the commit process. @@ -2200,7 +2200,7 @@ int nvme_fw_commit(int fd, __u8 slot, enum nvme_fw_commit_ca action, bool bpid); * specification. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_security_send(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, __u8 secp, __u32 tl, __u32 data_len, void *data, @@ -2220,7 +2220,7 @@ int nvme_security_send(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, * @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. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_security_receive(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, __u8 secp, __u32 al, __u32 data_len, @@ -2241,7 +2241,7 @@ int nvme_security_receive(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, * Unrecoverable LBAs. Refer to the specification for action type descriptions. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_lba_status(int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl, enum nvme_lba_status_atype atype, @@ -2266,7 +2266,7 @@ int nvme_get_lba_status(int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl, * See the NVMe specification for more information. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_directive_send(int fd, __u32 nsid, __u16 dspec, enum nvme_directive_send_doper doper, @@ -2279,7 +2279,7 @@ int nvme_directive_send(int fd, __u32 nsid, __u16 dspec, * @nsid: Namespace ID * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_directive_send_id_endir(int fd, __u32 nsid, bool endir, enum nvme_directive_dtype dtype, @@ -2291,7 +2291,7 @@ int nvme_directive_send_id_endir(int fd, __u32 nsid, bool endir, * @nsid: Namespace ID * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_directive_send_stream_release_identifier(int fd, __u32 nsid, __u16 stream_id); @@ -2302,7 +2302,7 @@ int nvme_directive_send_stream_release_identifier(int fd, __u32 nsid, * @nsid: Namespace ID * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_directive_send_stream_release_resource(int fd, __u32 nsid); @@ -2319,7 +2319,7 @@ int nvme_directive_send_stream_release_resource(int fd, __u32 nsid); * @result: If successful, the CQE dword0 value * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_directive_recv(int fd, __u32 nsid, __u16 dspec, enum nvme_directive_receive_doper doper, @@ -2332,7 +2332,7 @@ int nvme_directive_recv(int fd, __u32 nsid, __u16 dspec, * @nsid: Namespace ID * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_directive_recv_identify_parameters(int fd, __u32 nsid, struct nvme_id_directives *id); @@ -2343,7 +2343,7 @@ int nvme_directive_recv_identify_parameters(int fd, __u32 nsid, * @nsid: Namespace ID * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_directive_recv_stream_parameters(int fd, __u32 nsid, struct nvme_streams_directive_params *parms); @@ -2354,7 +2354,7 @@ int nvme_directive_recv_stream_parameters(int fd, __u32 nsid, * @nsid: Namespace ID * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_directive_recv_stream_status(int fd, __u32 nsid, unsigned nr_entries, struct nvme_streams_directive_status *id); @@ -2365,7 +2365,7 @@ int nvme_directive_recv_stream_status(int fd, __u32 nsid, unsigned nr_entries, * @nsid: Namespace ID * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_directive_recv_stream_allocate(int fd, __u32 nsid, __u16 nsr, __u32 *result); @@ -2398,7 +2398,7 @@ enum nvme_fctype { * properties align to the PCI MMIO controller registers. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_set_property(int fd, int offset, __u64 value); @@ -2412,7 +2412,7 @@ int nvme_set_property(int fd, int offset, __u64 value); * properties align to the PCI MMIO controller registers. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_property(int fd, int offset, __u64 *value); @@ -2437,7 +2437,7 @@ int nvme_get_property(int fd, int offset, __u64 *value); * sanitize command does not indicate completion of the sanitize operation. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_sanitize_nvm(int fd, enum nvme_sanitize_sanact sanact, bool ause, __u8 owpass, bool oipbp, bool nodas, __u32 ovrpat); @@ -2460,7 +2460,7 @@ int nvme_sanitize_nvm(int fd, enum nvme_sanitize_sanact sanact, bool ause, * namespace, if present. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_dev_self_test(int fd, __u32 nsid, enum nvme_dst_stc stc); @@ -2482,7 +2482,7 @@ int nvme_dev_self_test(int fd, __u32 nsid, enum nvme_dst_stc stc); * - Setting the Online and Offline state for secondary controllers * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_virtual_mgmt(int fd, enum nvme_virt_mgmt_act act, enum nvme_virt_mgmt_rt rt, __u16 cntlid, __u16 nr, @@ -2527,7 +2527,7 @@ enum nvme_io_opcode { * cache be made non-volatile. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_flush(int fd, __u32 nsid); @@ -2612,7 +2612,7 @@ enum nvme_io_dsm_flags { * @metadata: Pointer to user address of the metadata buffer * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_read(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u8 dsm, __u32 reftag, __u16 apptag, __u16 appmask, @@ -2642,7 +2642,7 @@ int nvme_read(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, * @metadata: Pointer to user address of the metadata buffer * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_write(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u8 dsm, __u16 dspec, __u32 reftag, __u16 apptag, @@ -2671,7 +2671,7 @@ int nvme_write(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, * @metadata: Pointer to user address of the metadata buffer * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_compare(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 reftag, __u16 apptag, __u16 appmask, __u32 data_len, @@ -2700,7 +2700,7 @@ int nvme_compare(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, * to 0h until a write occurs to this LBA range. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_write_zeros(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 reftag, __u16 apptag, __u16 appmask); @@ -2719,7 +2719,7 @@ int nvme_write_zeros(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, * required. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_write_uncorrectable(int fd, __u32 nsid, __u64 slba, __u16 nlb); @@ -2745,7 +2745,7 @@ int nvme_write_uncorrectable(int fd, __u32 nsid, __u64 slba, __u16 nlb); * data or metadata to the host. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_verify(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 reftag, __u16 apptag, __u16 appmask); @@ -2777,7 +2777,7 @@ enum nvme_dsm_attributes { * deallocate/unmap/trim those logical blocks. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_dsm(int fd, __u32 nsid, __u32 attrs, __u16 nr_ranges, struct nvme_dsm_range *dsm); @@ -2828,7 +2828,7 @@ enum nvme_reservation_racqa { * reservation held on a namespace. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_resv_acquire(int fd, __u32 nsid, enum nvme_reservation_rtype rtype, enum nvme_reservation_racqa racqa, bool iekey, @@ -2873,7 +2873,7 @@ enum nvme_reservation_cptpl { * a reservation key. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_resv_register(int fd, __u32 nsid, enum nvme_reservation_rrega rrega, enum nvme_reservation_cptpl cptpl, bool iekey, @@ -2899,7 +2899,7 @@ enum nvme_reservation_rrela { * @crkey: The current reservation key to release * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_resv_release(int fd, __u32 nsid, enum nvme_reservation_rtype rtype, enum nvme_reservation_rrela rrela, bool iekey, @@ -2918,7 +2918,7 @@ int nvme_resv_release(int fd, __u32 nsid, enum nvme_reservation_rtype rtype, * the returned structure, &struct nvme_reservation_status, for more details. * * Return: The nvme command status if a response was received (see - * &enum + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_resv_report(int fd, __u32 nsid, bool eds, __u32 len, struct nvme_reservation_status *report); diff --git a/src/nvme/tree.h b/src/nvme/tree.h index 129ecbd27f..172196a0f4 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -21,12 +21,34 @@ extern const char *nvme_ctrl_sysfs_dir; extern const char *nvme_subsys_sysfs_dir; +/** + * + */ typedef struct nvme_ns *nvme_ns_t; + +/** + * + */ typedef struct nvme_path *nvme_path_t; + +/** + * + */ typedef struct nvme_ctrl *nvme_ctrl_t; + +/** + * + */ typedef struct nvme_subsystem *nvme_subsystem_t; + +/** + * + */ typedef struct nvme_root *nvme_root_t; +/** + * + */ typedef bool (*nvme_scan_filter_t)(nvme_subsystem_t); /** diff --git a/src/nvme/types.h b/src/nvme/types.h index 1039a87628..2f817ad123 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -286,7 +286,7 @@ enum nvme_psd_flags { }; /** - * enum nvme_psd_ps - Known values for &struct nvme_psd #ips and #aps. Use with + * 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_IPS_100_MICRO_WATT: 0.0001 watt scale @@ -495,12 +495,12 @@ struct nvme_id_psd { * 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. + * 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. + * 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 @@ -1998,8 +1998,8 @@ struct nvme_self_test_log { /** * struct nvme_telemetry_log - Retrieve internal data specific to the * manufacturer. - * @lpi: Log Identifier, either #NVME_LOG_LID_TELEMETRY_HOST or - * #NVME_LOG_LID_TELEMETRY_CTRL + * @lpi: Log Identifier, either %NVME_LOG_LID_TELEMETRY_HOST or + * %NVME_LOG_LID_TELEMETRY_CTRL * @ieee: IEEE OUI Identifier is the Organization Unique Identifier (OUI) * for the controller vendor that is able to interpret the data. * @dalb1: Telemetry Controller-Initiated Data Area 1 Last Block is @@ -3268,12 +3268,12 @@ 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. - * @NVME_SCT_MASK: Mask to get the value of the Status Code Type * @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_SC_MASK: Mask to get the value of the status code. * @NVME_SC_SUCCESS: Successful Completion: The command * completed without error. @@ -3630,13 +3630,12 @@ enum nvme_status_field { /* * Status Code Type indicators */ - NVME_SCT_MASK = 0x700, - NVME_SCT_SHIFT = 0x700, NVME_SCT_GENERIC = 0x000, NVME_SCT_CMD_SPECIFIC = 0x100, NVME_SCT_MEDIA = 0x200, NVME_SCT_PATH = 0x300, NVME_SCT_VS = 0x700, + NVME_SCT_MASK = 0x700, /* * Status Code inidicators diff --git a/src/nvme/util.h b/src/nvme/util.h index 62298c0af2..88f99d9935 100644 --- a/src/nvme/util.h +++ b/src/nvme/util.h @@ -17,7 +17,7 @@ * @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, - * or unchanged status is < 0 since errno is already set. + * or unchanged status is < 0 since errno is already set. */ __u8 nvme_status_to_errno(int status, bool fabrics); @@ -30,7 +30,7 @@ __u8 nvme_status_to_errno(int status, bool fabrics); * @buf: Address of buffer containing all or part of the firmware image. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_fw_download_seq(int fd, __u32 size, __u32 xfer, __u32 offset, void *buf); @@ -45,7 +45,7 @@ int nvme_fw_download_seq(int fd, __u32 size, __u32 xfer, __u32 offset, * (&struct nvme_telemetry_log.dalb3 + 1) * %NVME_LOG_TELEM_BLOCK_SIZE. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_ctrl_telemetry(int fd, bool rae, struct nvme_telemetry_log **log); @@ -58,7 +58,7 @@ int nvme_get_ctrl_telemetry(int fd, bool rae, struct nvme_telemetry_log **log); * (&struct nvme_telemetry_log.dalb3 + 1) * %NVME_LOG_TELEM_BLOCK_SIZE. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_host_telemetry(int fd, struct nvme_telemetry_log **log); @@ -71,7 +71,7 @@ int nvme_get_host_telemetry(int fd, struct nvme_telemetry_log **log); * (&struct nvme_telemetry_log.dalb3 + 1) * %NVME_LOG_TELEM_BLOCK_SIZE. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_new_host_telemetry(int fd, struct nvme_telemetry_log **log); @@ -116,7 +116,7 @@ void nvme_init_ctrl_list(struct nvme_ctrl_list *cntlist, __u16 num_ctrls, * used with constructing a payload for &nvme_dsm(). * * Return: The nvme command status if a response was received or -errno - * otherwise. + * otherwise. */ void nvme_init_dsm_range(struct nvme_dsm_range *dsm, __u32 *ctx_attrs, __u32 *llbas, __u64 *slbas, __u16 nr_ranges); @@ -132,7 +132,7 @@ void nvme_init_dsm_range(struct nvme_dsm_range *dsm, __u32 *ctx_attrs, * @data: User address of at least &data_len to store the log. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int __nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, __u32 xfer_len, __u32 data_len, void *data); @@ -150,7 +150,7 @@ int __nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, * guarnateed by the protocol to be a safe transfer size. * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, __u32 data_len, void *data); @@ -161,7 +161,7 @@ int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, * @analen: Pointer to where the length will be set on success * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_ana_log_len(int fd, size_t *analen); @@ -173,7 +173,7 @@ int nvme_get_ana_log_len(int fd, size_t *analen); * @ctrlist: List of controller IDs to perform the attach action * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_namespace_attach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist); @@ -185,7 +185,7 @@ int nvme_namespace_attach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrl * @ctrlist: List of controller IDs to perform the detach action * * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. + * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_namespace_detach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist); @@ -198,7 +198,7 @@ int nvme_namespace_detach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrl * @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 - * recognize &fid. + * recognize &fid. */ int nvme_get_feature_length(int fid, __u32 cdw11, __u32 *len); @@ -209,7 +209,7 @@ int nvme_get_feature_length(int fid, __u32 cdw11, __u32 *len); * @len: On success, set to this directives payload length in bytes. * * Return: 0 on success, -1 with errno set to EINVAL if the function did not - * recognize &dtype or &doper. + * recognize &dtype or &doper. */ int nvme_get_directive_receive_length(enum nvme_directive_dtype dtype, enum nvme_directive_receive_doper doper, __u32 *len); @@ -222,7 +222,7 @@ int nvme_get_directive_receive_length(enum nvme_directive_dtype dtype, * match linux conventions. * * Return: A file descriptor for the device on a successful open, or -1 with - * errno set otherwise. + * errno set otherwise. */ int nvme_open(const char *name); From 43ae8941ee312990805ab0df10534eb88c288dc6 Mon Sep 17 00:00:00 2001 From: Chaitanya Kulkarni Date: Thu, 12 Mar 2020 11:06:23 -0700 Subject: [PATCH 0044/1564] nvme/types.h: avoid using anon enums Signed-off-by: Chaitanya Kulkarni Signed-off-by: Keith Busch --- src/nvme/types.h | 61 +++++++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/src/nvme/types.h b/src/nvme/types.h index 2f817ad123..5e66d3ed9b 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -215,7 +215,7 @@ enum nvme_register_offsets { #define NVME_CMB_CQS(cmbsz) ((cmbsz) & 0x2) #define NVME_CMB_SQS(cmbsz) ((cmbsz) & 0x1) -enum { +enum nvme_cc { NVME_CC_ENABLE = 1 << 0, NVME_CC_CSS_NVM = 0 << 4, NVME_CC_EN_SHIFT = 0, @@ -232,6 +232,9 @@ enum { NVME_CC_SHN_NORMAL = 1 << NVME_CC_SHN_SHIFT, NVME_CC_SHN_ABRUPT = 2 << NVME_CC_SHN_SHIFT, NVME_CC_SHN_MASK = 3 << NVME_CC_SHN_SHIFT, +}; + +enum nvme_csts { NVME_CSTS_RDY = 1 << 0, NVME_CSTS_CFS = 1 << 1, NVME_CSTS_NSSRO = 1 << 4, @@ -1631,13 +1634,13 @@ struct nvme_id_uuid_list_entry { }; /** - * enum - + * enum - nvme_id_uuid * @NVME_ID_UUID_HDR_ASSOCIATION_MASK: * @NVME_ID_UUID_ASSOCIATION_NONE: * @NVME_ID_UUID_ASSOCIATION_VENDOR: * @NVME_ID_UUID_ASSOCIATION_SUBSYSTEM_VENDOR: */ -enum { +enum nvme_id_uuid { NVME_ID_UUID_HDR_ASSOCIATION_MASK = 0x3, NVME_ID_UUID_ASSOCIATION_NONE = 0, NVME_ID_UUID_ASSOCIATION_VENDOR = 1, @@ -1765,7 +1768,7 @@ struct nvme_error_log_page { * @NVME_ERR_PEL_BYTE_MASK: * @NVME_ERR_PEL_BIT_MASK: */ -enum { +enum nvme_err_pel { NVME_ERR_PEL_BYTE_MASK = 0xf, NVME_ERR_PEL_BIT_MASK = 0x70, }; @@ -1825,7 +1828,7 @@ struct nvme_smart_log { }; /** - * enum - + * enum - nvme_smart_crit * @NVME_SMART_CRIT_SPARE: * @NVME_SMART_CRIT_TEMPERATURE: * @NVME_SMART_CRIT_DEGRADED: @@ -1833,7 +1836,7 @@ struct nvme_smart_log { * @NVME_SMART_CRIT_VOLATILE_MEMORY: * @NVME_SMART_CRIT_PMR_RO: */ -enum { +enum nvme_smart_crit { NVME_SMART_CRIT_SPARE = 1 << 0, NVME_SMART_CRIT_TEMPERATURE = 1 << 1, NVME_SMART_CRIT_DEGRADED = 1 << 2, @@ -1843,12 +1846,12 @@ enum { }; /** - * enum - + * enum - nvme_smart_egcw * @NVME_SMART_EGCW_SPARE: * @NVME_SMART_EGCW_DEGRADED: * @NVME_SMART_EGCW_RO: */ -enum { +enum nvme_smart_egcw { NVME_SMART_EGCW_SPARE = 1 << 0, NVME_SMART_EGCW_DEGRADED = 1 << 2, NVME_SMART_EGCW_RO = 1 << 3, @@ -1878,7 +1881,7 @@ struct nvme_cmd_effects_log { }; /** - * enum - + * enum - nvme_cmd_effects * @NVME_CMD_EFFECTS_CSUPP: * @NVME_CMD_EFFECTS_LBCC: * @NVME_CMD_EFFECTS_NCC: @@ -1887,7 +1890,7 @@ struct nvme_cmd_effects_log { * @NVME_CMD_EFFECTS_CSE_MASK: * @NVME_CMD_EFFECTS_UUID_SEL: */ -enum { +enum nvme_cmd_effects { NVME_CMD_EFFECTS_CSUPP = 1 << 0, NVME_CMD_EFFECTS_LBCC = 1 << 1, NVME_CMD_EFFECTS_NCC = 1 << 2, @@ -1937,7 +1940,7 @@ struct nvme_st_result { * @NVME_ST_RESULT_NOT_USED: * @NVME_ST_RESULT_MASK: */ -enum { +enum nvme_status_result { NVME_ST_RESULT_NO_ERR = 0x0, NVME_ST_RESULT_ABORTED = 0x1, NVME_ST_RESULT_CLR = 0x2, @@ -1959,7 +1962,7 @@ enum { * @NVME_ST_CODE_EXTENDED: * @NVME_ST_CODE_VS: */ -enum { +enum nvme_st_code { NVME_ST_CODE_SHIFT = 4, NVME_ST_CODE_RESRVED = 0x0, NVME_ST_CODE_SHORT = 0x1, @@ -1974,7 +1977,7 @@ enum { * @NVME_ST_VALID_DIAG_INFO_SCT: * @NVME_ST_VALID_DIAG_INFO_SC: */ -enum { +enum nvme_st_valid_diag_info { NVME_ST_VALID_DIAG_INFO_NSID = 1 << 0, NVME_ST_VALID_DIAG_INFO_FLBA = 1 << 1, NVME_ST_VALID_DIAG_INFO_SCT = 1 << 2, @@ -2126,26 +2129,26 @@ struct nvme_nvmset_predictable_lat_log { }; /** - * enum - + * enum - nvme_nvmeset_pl_status * @NVME_NVMSET_PL_STATUS_DISABLED: * @NVME_NVMSET_PL_STATUS_DTWIN: * @NVME_NVMSET_PL_STATUS_NDWIN: */ -enum { +enum nvme_nvmeset_pl_status { NVME_NVMSET_PL_STATUS_DISABLED = 0, NVME_NVMSET_PL_STATUS_DTWIN = 1, NVME_NVMSET_PL_STATUS_NDWIN = 2, }; /** - * enum - + * 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 { +enum nvme_nvmset_pl_events { NVME_NVMSET_PL_EVENT_DTWIN_READ_WARN = 1 << 0, NVME_NVMSET_PL_EVENT_DTWIN_WRITE_WARN = 1 << 1, NVME_NVMSET_PL_EVENT_DTWIN_TIME_WARN = 1 << 2, @@ -2458,7 +2461,7 @@ struct nvme_lba_range_type_entry { }; /** - * enum - + * enum - nvme_lbart * @NVME_LBART_TYPE_GP: * @NVME_LBART_TYPE_FS: * @NVME_LBART_TYPE_RAID: @@ -2467,7 +2470,7 @@ struct nvme_lba_range_type_entry { * @NVME_LBART_ATTRIB_TEMP: * @NVME_LBART_ATTRIB_HIDE: */ -enum { +enum nvme_lbart { NVME_LBART_TYPE_GP = 0, NVME_LBART_TYPE_FS = 1, NVME_LBART_TYPE_RAID = 2, @@ -2788,7 +2791,7 @@ struct nvmf_disc_log_entry { * @NVMF_TRTYPE_TCP: TCP * @NVMF_TRTYPE_LOOP: Reserved for host usage */ -enum { +enum nvme_trtype { NVMF_TRTYPE_UNSPECIFIED = 0, NVMF_TRTYPE_RDMA = 1, NVMF_TRTYPE_FC = 2, @@ -2805,7 +2808,7 @@ enum { * @NVMF_ADDR_FAMILY_IB: InfiniBand * @NVMF_ADDR_FAMILY_FC: Fibre Channel */ -enum { +enum nvmf_addr_familiy { NVMF_ADDR_FAMILY_PCI = 0, NVMF_ADDR_FAMILY_IP4 = 1, NVMF_ADDR_FAMILY_IP6 = 2, @@ -2820,7 +2823,7 @@ enum { * @NVMF_TREQ_NOT_REQUIRED: Not Required * @NVMF_TREQ_DISABLE_SQFLOW: SQ flow control disable supported */ -enum { +enum nvmf_treq { NVMF_TREQ_NOT_SPECIFIED = 0, NVMF_TREQ_REQUIRED = 1, NVMF_TREQ_NOT_REQUIRED = 2, @@ -2847,7 +2850,7 @@ enum { * @NVMF_RDMA_PRTYPE_ROCEV2: InfiniBand RoCEV2 * @NVMF_RDMA_PRTYPE_IWARP: iWARP */ -enum { +enum nvme_rdma_prtype { NVMF_RDMA_PRTYPE_NOT_SPECIFIED = 1, NVMF_RDMA_PRTYPE_IB = 2, NVMF_RDMA_PRTYPE_ROCE = 3, @@ -3034,7 +3037,7 @@ struct nvme_mi_nvm_ss_health_status { }; /** - * enum - + * enum - nvme_mi_css * @NVME_MI_CCS_RDY: * @NVME_MI_CSS_CFS: * @NVME_MI_CSS_SHST: @@ -3048,7 +3051,7 @@ struct nvme_mi_nvm_ss_health_status { * @NVME_MI_CSS_SPARE: * @NVME_MI_CSS_CCWARN: */ -enum { +enum nvme_mi_css { NVME_MI_CCS_RDY = 1 << 0, NVME_MI_CSS_CFS = 1 << 1, NVME_MI_CSS_SHST = 1 << 2, @@ -3097,7 +3100,7 @@ struct nvme_mi_ctrl_heal_status { * @NVME_MI_CWARN_RO: * @NVME_MI_CWARN_VMBF: */ -enum { +enum nvme_mi_csts { NVME_MI_CSTS_RDY = 1 << 0, NVME_MI_CSTS_CFS = 1 << 1, NVME_MI_CSTS_SHST = 1 << 2, @@ -3105,6 +3108,10 @@ enum { NVME_MI_CSTS_CECO = 1 << 5, NVME_MI_CSTS_NAC = 1 << 6, NVME_MI_CSTS_FA = 1 << 7, +}; + +enum nvme_mi_cwarn { + NVME_MI_CWARN_ST = 1 << 0, NVME_MI_CWARN_TAUT = 1 << 1, NVME_MI_CWARN_RD = 1 << 2, @@ -3194,7 +3201,7 @@ struct nvme_mi_vpd_telem { * @NVME_MI_ELEM_PCIESED: * @NVME_MI_ELEM_NVMED: */ -enum { +enum nvme_mi_elem { NVME_MI_ELEM_EED = 1, NVME_MI_ELEM_USCE = 2, NVME_MI_ELEM_ECED = 3, From 39fe86ad3abe0e1242b72664663e724860efc0ed Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Fri, 27 Mar 2020 16:43:22 -0700 Subject: [PATCH 0045/1564] Export single namespace open Signed-off-by: Keith Busch --- Makefile | 2 +- examples/Makefile | 2 +- src/Makefile | 2 +- src/libnvme.map | 2 ++ src/nvme/tree.c | 51 ++++++++++++++++++++++++++++++++--------------- src/nvme/tree.h | 6 ++++++ 6 files changed, 46 insertions(+), 19 deletions(-) diff --git a/Makefile b/Makefile index 030f9abf05..ef470beffe 100644 --- a/Makefile +++ b/Makefile @@ -32,7 +32,7 @@ include config-host.mak endif SED_PROCESS = \ - $(SED) -e "s%@prefix@%$(prefix)%g" \ + sed -e "s%@prefix@%$(prefix)%g" \ -e "s%@libdir@%$(libdir)%g" \ -e "s%@includedir@%$(includedir)%g" \ -e "s%@NAME@%$(NAME)%g" \ diff --git a/examples/Makefile b/examples/Makefile index 3731d4ac27..be867a7648 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -1,5 +1,5 @@ CFLAGS ?= -g -O2 -override CFLAGS += -Wall -D_GNU_SOURCE -L../src/ -I../src/ +override CFLAGS += -Wall -D_GNU_SOURCE include ../Makefile.quiet diff --git a/src/Makefile b/src/Makefile index 8977e72a62..129e624d74 100644 --- a/src/Makefile +++ b/src/Makefile @@ -47,7 +47,7 @@ libccan_sobjs := $(patsubst %.c,%.os,$(libccan_srcs)) $(libccan_objs) $(libccan_sobjs): $(libccan_headers) $(CCANDIR)config.h libnvme_priv := nvme/private.h -libnvme_api := libnvme.h nvme/types.h nvme/ioctl.h nvme/filters.h nvme/tree.h nvme/util.h +libnvme_api := libnvme.h nvme/types.h nvme/ioctl.h nvme/filters.h nvme/tree.h nvme/util.h nvme/fabrics.h libnvme_srcs := nvme/ioctl.c nvme/filters.c nvme/fabrics.c nvme/util.c nvme/tree.c libnvme_objs := $(patsubst %.c,%.ol,$(libnvme_srcs)) libnvme_sobjs := $(patsubst %.c,%.os,$(libnvme_srcs)) diff --git a/src/libnvme.map b/src/libnvme.map index 6fb0c9e2c9..64c04b0a59 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -207,11 +207,13 @@ nvme_path_get_ana_state; nvme_ns_get_sysfs_dir; nvme_ns_get_name; + nvme_ns_open; nvme_status_type; nvme_status_to_string; nvme_status_to_errno; nvme_fw_download_seq; nvme_get_telemetry_log; + nvme_get_ctrl_telemetry; nvme_setup_id_ns; nvme_setup_ctrl_list; nvme_dsm_range; diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 05bfe74b3b..d850aa73cf 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -51,6 +52,7 @@ struct nvme_ns { char *sysfs_dir; int nsid; + int lba_shift; int lba_size; int meta_size; uint64_t lba_count; @@ -668,8 +670,8 @@ static int nvme_bytes_to_lba(nvme_ns_t n, off_t offset, size_t count, return -1; } - *lba = offset / bs; - *nlb = (count / bs) - 1; + *lba = offset >> n->lba_shift; + *nlb = (count >> n->lba_shift) - 1; return 0; } @@ -807,32 +809,27 @@ static void nvme_ns_init(struct nvme_ns *n) if (nvme_ns_identify(n, &ns) != 0) return; - n->lba_size = 1 << ns.lbaf[ns.flbas & NVME_NS_FLBAS_LBA_MASK].ds; + n->lba_shift = ns.lbaf[ns.flbas & NVME_NS_FLBAS_LBA_MASK].ds; + n->lba_size = 1 << n->lba_shift; n->lba_count = le64_to_cpu(ns.nsze); n->lba_util = le64_to_cpu(ns.nuse); } -static struct nvme_ns *__nvme_scan_namespace(const char *sysfs_dir, char *name) + +nvme_ns_t nvme_ns_open(char *name) { + char *b = basename(name); struct nvme_ns *n; - char *path; - int ret; - - ret = asprintf(&path, "%s/%s", sysfs_dir, name); - if (ret < 0) { - errno = ENOMEM; - return NULL; - } n = calloc(1, sizeof(*n)); if (!n) { errno = ENOMEM; - goto free_path; + return NULL; } - n->name = strdup(name); - n->sysfs_dir = path; - n->fd = nvme_open(name); + n->name = strdup(b); + n->fd = nvme_open(b); + if (n->fd < 0) goto free_ns; @@ -849,6 +846,28 @@ static struct nvme_ns *__nvme_scan_namespace(const char *sysfs_dir, char *name) close(n->fd); free_ns: free(n); + return NULL; +} + +static struct nvme_ns *__nvme_scan_namespace(const char *sysfs_dir, char *name) +{ + struct nvme_ns *n; + char *path; + int ret; + + ret = asprintf(&path, "%s/%s", sysfs_dir, name); + if (ret < 0) { + errno = ENOMEM; + return NULL; + } + + n = nvme_ns_open(name); + if (!n) + goto free_path; + + n->sysfs_dir = path; + return n; + free_path: free(path); return NULL; diff --git a/src/nvme/tree.h b/src/nvme/tree.h index 172196a0f4..6cce922447 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -51,6 +51,12 @@ typedef struct nvme_root *nvme_root_t; */ typedef bool (*nvme_scan_filter_t)(nvme_subsystem_t); + +/** + * + */ +nvme_ns_t nvme_ns_open(char *name); + /** * nvme_first_subsystem() - * @r: From 364396cafdecd361cb8c8f7f0480a988c5256d75 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Mon, 18 May 2020 12:39:53 -0700 Subject: [PATCH 0046/1564] Define all nvme registers Provide enum and accessor methods for all nvme regsiter values and sub-values. Signed-off-by: Keith Busch --- .gitignore | 3 + src/nvme/types.h | 497 +++++++++++++++++++++++++++++++++++++++-------- test/Makefile | 2 +- test/register.c | 210 ++++++++++++++++++++ 4 files changed, 626 insertions(+), 86 deletions(-) create mode 100644 test/register.c diff --git a/.gitignore b/.gitignore index c874c37600..ab78bf1ae2 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ a.out libnvme.pc +test/register test/test test/cpp @@ -20,6 +21,8 @@ examples/discover-loop ccan/config.h ccan/tools/configurator/configurator +doc/_build + config-host.h config-host.mak config.log diff --git a/src/nvme/types.h b/src/nvme/types.h index 5e66d3ed9b..d5b3e6b101 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -136,7 +136,7 @@ enum nvme_constants { }; /** - * enum nvme_register_offsets - The nvme controller registers for all transports. This + * enum nvme_register_offsets - controller registers for all transports. This * is the layout of BAR0/1 for PCIe, and * properties for fabrics. * @NVME_REG_CAP: Controller Capabilities @@ -162,87 +162,31 @@ enum nvme_constants { * @NVME_REG_PMREBS: Persistent Memory Region Elasticity Buffer Size * @NVME_REG_PMRSWTP: Memory Region Sustained Write Throughput * @NVME_REG_PMRMSC: Persistent Memory Region Controller Memory Space Control - * @NVME_REG_DBS: SQ 0 Tail Doorbell */ enum nvme_register_offsets { - NVME_REG_CAP = 0x0000, - NVME_REG_VS = 0x0008, - NVME_REG_INTMS = 0x000c, - NVME_REG_INTMC = 0x0010, - NVME_REG_CC = 0x0014, - NVME_REG_CSTS = 0x001c, - NVME_REG_NSSR = 0x0020, - NVME_REG_AQA = 0x0024, - NVME_REG_ASQ = 0x0028, - NVME_REG_ACQ = 0x0030, - 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_PMRSWTP= 0x0e10, - NVME_REG_PMRMSC = 0x0e14, - NVME_REG_DBS = 0x1000, -}; - -#define NVME_CAP_MQES(cap) ((cap) & 0xffff) -#define NVME_CAP_CQR(cap) (((cap) >> 16) & 0x1) -#define NVME_CAP_AMS(cap) (((cap) >> 17) & 0x3) -#define NVME_CAP_TIMEOUT(cap) (((cap) >> 24) & 0xff) -#define NVME_CAP_STRIDE(cap) (((cap) >> 32) & 0xf) -#define NVME_CAP_NSSRC(cap) (((cap) >> 36) & 0x1) -#define NVME_CAP_CSS(cap) (((cap) >> 37) & 0xff) -#define NVME_CAP_BPS(cap) (((cap) >> 45) & 0x1) -#define NVME_CAP_MPSMIN(cap) (((cap) >> 48) & 0xf) -#define NVME_CAP_MPSMAX(cap) (((cap) >> 52) & 0xf) -#define NVME_CAP_CMBS(cap) (((cap) >> 57) & 1) -#define NVME_CAP_PMRS(cap) (((cap) >> 56) & 1) - -#define NVME_CMB_BIR(cmbloc) ((cmbloc) & 0x7) -#define NVME_CMB_OFST(cmbloc) (((cmbloc) >> 12) & 0xfffff) -#define NVME_CMB_SZ(cmbsz) (((cmbsz) >> 12) & 0xfffff) -#define NVME_CMB_SZU(cmbsz) (((cmbsz) >> 8) & 0xf) - -#define NVME_CMB_WDS(cmbsz) ((cmbsz) & 0x10) -#define NVME_CMB_RDS(cmbsz) ((cmbsz) & 0x8) -#define NVME_CMB_LISTS(cmbsz) ((cmbsz) & 0x4) -#define NVME_CMB_CQS(cmbsz) ((cmbsz) & 0x2) -#define NVME_CMB_SQS(cmbsz) ((cmbsz) & 0x1) - -enum nvme_cc { - NVME_CC_ENABLE = 1 << 0, - NVME_CC_CSS_NVM = 0 << 4, - NVME_CC_EN_SHIFT = 0, - NVME_CC_CSS_SHIFT = 4, - NVME_CC_MPS_SHIFT = 7, - NVME_CC_AMS_SHIFT = 11, - NVME_CC_SHN_SHIFT = 14, - NVME_CC_IOSQES_SHIFT = 16, - NVME_CC_IOCQES_SHIFT = 20, - NVME_CC_AMS_RR = 0 << NVME_CC_AMS_SHIFT, - NVME_CC_AMS_WRRU = 1 << NVME_CC_AMS_SHIFT, - NVME_CC_AMS_VS = 7 << NVME_CC_AMS_SHIFT, - NVME_CC_SHN_NONE = 0 << NVME_CC_SHN_SHIFT, - NVME_CC_SHN_NORMAL = 1 << NVME_CC_SHN_SHIFT, - NVME_CC_SHN_ABRUPT = 2 << NVME_CC_SHN_SHIFT, - NVME_CC_SHN_MASK = 3 << NVME_CC_SHN_SHIFT, -}; - -enum nvme_csts { - NVME_CSTS_RDY = 1 << 0, - NVME_CSTS_CFS = 1 << 1, - NVME_CSTS_NSSRO = 1 << 4, - NVME_CSTS_PP = 1 << 5, - NVME_CSTS_SHST_NORMAL = 0 << 2, - NVME_CSTS_SHST_OCCUR = 1 << 2, - NVME_CSTS_SHST_CMPLT = 2 << 2, - NVME_CSTS_SHST_MASK = 3 << 2, + NVME_REG_CAP = 0x0000, + NVME_REG_VS = 0x0008, + NVME_REG_INTMS = 0x000c, + NVME_REG_INTMC = 0x0010, + NVME_REG_CC = 0x0014, + NVME_REG_CSTS = 0x001c, + NVME_REG_NSSR = 0x0020, + NVME_REG_AQA = 0x0024, + NVME_REG_ASQ = 0x0028, + NVME_REG_ACQ = 0x0030, + 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_PMRSWTP = 0x0e10, + NVME_REG_PMRMSC = 0x0e14, }; /** @@ -253,7 +197,7 @@ enum nvme_csts { * This function does not care about transport so that the offset is not going * to be checked inside of this function for the unsupported fields in a * specific transport. For example, BPMBL(Boot Partition Memory Buffer - * Location) register is not supported by fabrics, but it can be chcked here. + * 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. */ @@ -264,12 +208,399 @@ static inline bool nvme_is_64bit_reg(__u32 offset) case NVME_REG_ASQ: case NVME_REG_ACQ: case NVME_REG_BPMBL: + case NVME_REG_CMBMSC: + case NVME_REG_PMRMSC: return true; default: return false; } } +static inline __u32 nvme_mmio_read32(void *addr) +{ + __le32 *p = addr; + + return le32_to_cpu(*p); +} + +static inline __u64 nvme_mmio_read64(void *addr) +{ + __le32 *p = addr; + + /* + * Some devices fail 64-bit MMIO. Access 64-bit registers as 2 32-bit. + */ + return le32_to_cpu(*p) | ((uint64_t)le32_to_cpu(*(p + 1)) << 32); +} + +#define NVME_REG_VALUE(name, value) \ + (((value) >> NVME_##name##_SHIFT) & NVME_##name##_MASK) + +enum nvme_cap { + NVME_CAP_MQES_SHIFT = 0, + NVME_CAP_CQR_SHIFT = 16, + NVME_CAP_AMS_SHIFT = 17, + NVME_CAP_TO_SHIFT = 24, + NVME_CAP_DSTRD_SHIFT = 32, + NVME_CAP_NSSRC_SHIFT = 36, + NVME_CAP_CSS_SHIFT = 37, + NVME_CAP_BPS_SHIFT = 45, + NVME_CAP_MPSMIN_SHIFT = 48, + NVME_CAP_MPSMAX_SHIFT = 52, + NVME_CAP_PMRS_SHIFT = 56, + NVME_CAP_CMBS_SHIFT = 57, + NVME_CAP_MQES_MASK = 0xffff, + NVME_CAP_CQR_MASK = 0x1, + NVME_CAP_AMS_MASK = 0x3, + NVME_CAP_TO_MASK = 0xff, + NVME_CAP_DSTRD_MASK = 0xf, + NVME_CAP_NSSRC_MASK = 0x1, + NVME_CAP_CSS_MASK = 0xff, + NVME_CAP_BPS_MASK = 0x1, + NVME_CAP_MPSMIN_MASK = 0xf, + NVME_CAP_MPSMAX_MASK = 0xf, + NVME_CAP_PMRS_MASK = 0x1, + NVME_CAP_CMBS_MASK = 0x1, + NVME_CAP_AMS_WRR = 1 << 0, + NVME_CAP_AMS_VS = 1 << 1, + NVME_CAP_CSS_NVM = 1 << 0, + NVME_CAP_CSS_ADMIN = 1 << 7, +}; + +#define NVME_CAP_MQES(cap) NVME_REG_VALUE(CAP_MQES, cap) +#define NVME_CAP_CQR(cap) NVME_REG_VALUE(CAP_CQR, cap) +#define NVME_CAP_AMS(cap) NVME_REG_VALUE(CAP_AMS, cap) +#define NVME_CAP_TO(cap) NVME_REG_VALUE(CAP_TO, cap) +#define NVME_CAP_DSTRD(cap) NVME_REG_VALUE(CAP_DSTRD, cap) +#define NVME_CAP_NSSRC(cap) NVME_REG_VALUE(CAP_NSSRC, cap) +#define NVME_CAP_CSS(cap) NVME_REG_VALUE(CAP_CSS, cap) +#define NVME_CAP_BPS(cap) NVME_REG_VALUE(CAP_BPS, cap) +#define NVME_CAP_MPSMIN(cap) NVME_REG_VALUE(CAP_MPSMIN, cap) +#define NVME_CAP_MPSMAX(cap) NVME_REG_VALUE(CAP_MPSMAX, cap) +#define NVME_CAP_CMBS(cap) NVME_REG_VALUE(CAP_CMBS, cap) +#define NVME_CAP_PMRS(cap) NVME_REG_VALUE(CAP_PMRS, cap) + +enum nvme_vs { + NVME_VS_TER_SHIFT = 0, + NVME_VS_MNR_SHIFT = 8, + NVME_VS_MJR_SHIFT = 16, + NVME_VS_TER_MASK = 0xff, + NVME_VS_MNR_MASK = 0xff, + NVME_VS_MJR_MASK = 0xffff, +}; + +#define NVME_VS_TER(vs) NVME_REG_VALUE(VS_TER, vs) +#define NVME_VS_MNR(vs) NVME_REG_VALUE(VS_MNR, vs) +#define NVME_VS_MJR(vs) NVME_REG_VALUE(VS_MJR, vs) + +#define NVME_MAJOR(ver) NVME_VS_MJR(ver) +#define NVME_MINOR(ver) NVME_VS_MNR(ver) +#define NVME_TERTIARY(ver) NVME_VS_TER(ver) + +enum nvme_cc { + NVME_CC_EN_SHIFT = 0, + NVME_CC_CSS_SHIFT = 4, + NVME_CC_MPS_SHIFT = 7, + NVME_CC_AMS_SHIFT = 11, + NVME_CC_SHN_SHIFT = 14, + NVME_CC_IOSQES_SHIFT = 16, + NVME_CC_IOCQES_SHIFT = 20, + 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_IOSQES_MASK = 0xf, + NVME_CC_IOCQES_MASK = 0xf, + NVME_CC_CSS_NVM = 0, + NVME_CC_CSS_ADMIN = 7, + NVME_CC_AMS_RR = 0, + NVME_CC_AMS_WRRU = 1, + NVME_CC_AMS_VS = 7, + NVME_CC_SHN_NONE = 0, + NVME_CC_SHN_NORMAL = 1, + NVME_CC_SHN_ABRUPT = 2, +}; + +#define NVME_CC_EN(cc) NVME_REG_VALUE(CC_EN, cc) +#define NVME_CC_CSS(cc) NVME_REG_VALUE(CC_CSS, cc) +#define NVME_CC_MPS(cc) NVME_REG_VALUE(CC_MPS, cc) +#define NVME_CC_AMS(cc) NVME_REG_VALUE(CC_AMS, cc) +#define NVME_CC_SHN(cc) NVME_REG_VALUE(CC_SHN, cc) +#define NVME_CC_IOSQES(cc) NVME_REG_VALUE(CC_IOSQES, cc) +#define NVME_CC_IOCQES(cc) NVME_REG_VALUE(CC_IOCQES, cc) + +enum nvme_csts { + NVME_CSTS_RDY_SHIFT = 0, + NVME_CSTS_CFS_SHIFT = 1, + NVME_CSTS_SHST_SHIFT = 2, + NVME_CSTS_NSSRO_SHIFT = 4, + NVME_CSTS_PP_SHIFT = 5, + NVME_CSTS_RDY_MASK = 0x1, + NVME_CSTS_CFS_MASK = 0x1, + NVME_CSTS_SHN_MASK = 0x3, + NVME_CSTS_NSSRO_MASK = 0x1, + NVME_CSTS_PP_MASK = 0x1, + NVME_CSTS_SHST_NORMAL = 0, + NVME_CSTS_SHST_OCCUR = 1, + NVME_CSTS_SHST_CMPLT = 2, + NVME_CSTS_SHST_MASK = 3, +}; + +#define NVME_CSTS_RDY(csts) NVME_REG_VALUE(CSTS_RDY, csts) +#define NVME_CSTS_CFS(csts) NVME_REG_VALUE(CSTS_CFS, csts) +#define NVME_CSTS_SHST(csts) NVME_REG_VALUE(CSTS_SHST, csts) +#define NVME_CSTS_NSSRO(csts) NVME_REG_VALUE(CSTS_NSSRO, csts) +#define NVME_CSTS_PP(csts) NVME_REG_VALUE(CSTS_PP, csts) + +enum nvme_aqa { + NVME_AQA_ASQS_SHIFT = 0, + NVME_AQA_ACQS_SHIFT = 16, + NVME_AQA_ASQS_MASK = 0xfff, + NVME_AQA_ACQS_MASK = 0xfff, +}; + +#define NVME_AQA_ASQS(aqa) NVME_REG_VALUE(AQA_ASQS, aqa) +#define NVME_AQA_ACQS(aqa) NVME_REG_VALUE(AQA_ACQS, aqa) + +enum nvme_cmbloc { + NVME_CMBLOC_BIR_SHIFT = 0, + NVME_CMBLOC_CQMMS_SHIFT = 3, + NVME_CMBLOC_CQPDS_SHIFT = 4, + NVME_CMBLOC_CDPLMS_SHIFT = 5, + NVME_CMBLOC_CDPCILS_SHIFT = 6, + NVME_CMBLOC_CDMMMS_SHIFT = 7, + NVME_CMBLOC_CQDA_SHIFT = 8, + NVME_CMBLOC_OFST_SHIFT = 12, + NVME_CMBLOC_BIR_MASK = 0x7, + NVME_CMBLOC_CQMMS_MASK = 0x1, + NVME_CMBLOC_CQPDS_MASK = 0x1, + NVME_CMBLOC_CDPLMS_MASK = 0x1, + NVME_CMBLOC_CDPCILS_MASK = 0x1, + NVME_CMBLOC_CDMMMS_MASK = 0x1, + NVME_CMBLOC_CQDA_MASK = 0x1, + NVME_CMBLOC_OFST_MASK = 0xfffff, +}; + +#define NVME_CMBLOC_BIR(cmbloc) NVME_REG_VALUE(CMBLOC_BIR, cmbloc) +#define NVME_CMBLOC_CQMMS(cmbloc) NVME_REG_VALUE(CMBLOC_CQMMS, cmbloc) +#define NVME_CMBLOC_CQPDS(cmbloc) NVME_REG_VALUE(CMBLOC_CQPDS, cmbloc) +#define NVME_CMBLOC_CDPLMS(cmbloc) NVME_REG_VALUE(CMBLOC_CDPLMS, cmbloc) +#define NVME_CMBLOC_CDPCILS(cmbloc) NVME_REG_VALUE(CMBLOC_CDPCILS, cmbloc) +#define NVME_CMBLOC_CDMMMS(cmbloc) NVME_REG_VALUE(CMBLOC_CDMMMS, cmbloc) +#define NVME_CMBLOC_CQDA(cmbloc) NVME_REG_VALUE(CMBLOC_CQDA, cmbloc) +#define NVME_CMBLOC_OFST(cmbloc) NVME_REG_VALUE(CMBLOC_OFST, cmbloc) + +enum nvme_cmbsz { + NVME_CMBSZ_SQS_SHIFT = 0, + NVME_CMBSZ_CQS_SHIFT = 1, + NVME_CMBSZ_LISTS_SHIFT = 2, + NVME_CMBSZ_RDS_SHIFT = 3, + NVME_CMBSZ_WDS_SHIFT = 4, + NVME_CMBSZ_SZU_SHIFT = 8, + NVME_CMBSZ_SZ_SHIFT = 12, + NVME_CMBSZ_SQS_MASK = 0x1, + NVME_CMBSZ_CQS_MASK = 0x1, + NVME_CMBSZ_LISTS_MASK = 0x1, + NVME_CMBSZ_RDS_MASK = 0x1, + NVME_CMBSZ_WDS_MASK = 0x1, + NVME_CMBSZ_SZU_MASK = 0xf, + NVME_CMBSZ_SZ_MASK = 0xfffff, + NVME_CMBSZ_SZU_4K = 0, + NVME_CMBSZ_SZU_64K = 1, + NVME_CMBSZ_SZU_1M = 2, + NVME_CMBSZ_SZU_16M = 3, + NVME_CMBSZ_SZU_256M = 4, + NVME_CMBSZ_SZU_4G = 5, + NVME_CMBSZ_SZU_64G = 6, +}; + +#define NVME_CMBSZ_SQS(cmbsz) NVME_REG_VALUE(CMBSZ_SQS, cmbsz) +#define NVME_CMBSZ_CQS(cmbsz) NVME_REG_VALUE(CMBSZ_CQS, cmbsz) +#define NVME_CMBSZ_LISTS(cmbsz) NVME_REG_VALUE(CMBSZ_LISTS, cmbsz) +#define NVME_CMBSZ_RDS(cmbsz) NVME_REG_VALUE(CMBSZ_RDS, cmbsz) +#define NVME_CMBSZ_WDS(cmbsz) NVME_REG_VALUE(CMBSZ_WDS, cmbsz) +#define NVME_CMBSZ_SZU(cmbsz) NVME_REG_VALUE(CMBSZ_SZU, cmbsz) +#define NVME_CMBSZ_SZ(cmbsz) NVME_REG_VALUE(CMBSZ_SZ, 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 + */ +static inline __u64 nvme_cmb_size(__u32 cmbsz) +{ + return ((__u64)NVME_CMBSZ_SZ(cmbsz)) * + (1ULL << (12 + 4 * NVME_CMBSZ_SZU(cmbsz))); +} + +enum nvme_bpinfo { + NVME_BPINFO_BPSZ_SHIFT = 0, + NVME_BPINFO_BRS_SHIFT = 24, + NVME_BPINFO_ABPID_SHIFT = 31, + NVME_BPINFO_BPSZ_MASK = 0x7fff, + NVME_BPINFO_BRS_MASK = 0x3, + NVME_BPINFO_ABPID_MASK = 0x1, + NVME_BPINFO_BRS_NONE = 0, + NVME_BPINFO_BRS_READ_IN_PROGRESS = 1, + NVME_BPINFO_BRS_READ_SUCCESS = 2, + NVME_BPINFO_BRS_READ_ERROR = 3, +}; + +#define NVME_BPINFO_BPSZ(bpinfo) NVME_REG_VALUE(BPINFO_BPSZ, bpinfo) +#define NVME_BPINFO_BRS(bpinfo) NVME_REG_VALUE(BPINFO_BRS, bpinfo) +#define NVME_BPINFO_ABPID(bpinfo) NVME_REG_VALUE(BPINFO_ABPID, bpinfo) + +enum nvme_bprsel { + NVME_BPRSEL_BPRSZ_SHIFT = 0, + NVME_BPRSEL_BPROF_SHIFT = 10, + NVME_BPRSEL_BPID_SHIFT = 31, + NVME_BPRSEL_BPRSZ_MASK = 0x3ff, + NVME_BPRSEL_BPROF_MASK = 0xfff, + NVME_BPRSEL_BPID_MASK = 0x1, +}; + +#define NVME_BPRSEL_BPRSZ(bprsel) NVME_REG_VALUE(BPRSEL_BPRSZ, bprsel) +#define NVME_BPRSEL_BPROF(bprsel) NVME_REG_VALUE(BPRSEL_BPROF, bprsel) +#define NVME_BPRSEL_BPID(bprsel) NVME_REG_VALUE(BPRSEL_BPID, bprsel) + +enum nvme_cmbmsc { + NVME_CMBMSC_CRE_SHIFT = 0, + NVME_CMBMSC_CMSE_SHIFT = 1, + NVME_CMBMSC_CBA_SHIFT = 12, + NVME_CMBMSC_CRE_MASK = 0x1, + NVME_CMBMSC_CMSE_MASK = 0x1, +}; +static const __u64 NVME_CMBMSC_CBA_MASK = 0xfffffffffffffull; + +#define NVME_CMBMSC_CRE(cmbmsc) NVME_REG_VALUE(CMBMSC_CRE, cmbmsc) +#define NVME_CMBMSC_CMSE(cmbmsc) NVME_REG_VALUE(CMBMSC_CMSE, cmbmsc) +#define NVME_CMBMSC_CBA(cmbmsc) NVME_REG_VALUE(CMBMSC_CBA, cmbmsc) + +enum nvme_cmbsts { + NVME_CMBSTS_CBAI_SHIFT = 0, + NVME_CMBSTS_CBAI_MASK = 0x1, +}; + +#define NVME_CMBSTS_CBAI(cmbsts) NVME_REG_VALUE(CMBSTS_CBAI, cmbsts) + +enum nvme_pmrcap { + NVME_PMRCAP_RDS_SHIFT = 3, + NVME_PMRCAP_WDS_SHIFT = 4, + NVME_PMRCAP_BIR_SHIFT = 5, + NVME_PMRCAP_PMRTU_SHIFT = 8, + NVME_PMRCAP_PMRWMB_SHIFT = 10, + NVME_PMRCAP_PMRTO_SHIFT = 16, + NVME_PMRCAP_CMSS_SHIFT = 24, + NVME_PMRCAP_RDS_MASK = 0x1, + NVME_PMRCAP_WDS_MASK = 0x1, + NVME_PMRCAP_BIR_MASK = 0x7, + NVME_PMRCAP_PMRTU_MASK = 0x3, + NVME_PMRCAP_PMRWMB_MASK = 0xf, + NVME_PMRCAP_PMRTO_MASK = 0xff, + NVME_PMRCAP_CMSS_MASK = 0x1, + NVME_PMRCAP_PMRTU_500MS = 0, + NVME_PMRCAP_PMRTU_60S = 1, +}; + +#define NVME_PMRCAP_RDS(pmrcap) NVME_REG_VALUE(PMRCAP_RDS, pmrcap) +#define NVME_PMRCAP_WDS(pmrcap) NVME_REG_VALUE(PMRCAP_WDS, pmrcap) +#define NVME_PMRCAP_BIR(pmrcap) NVME_REG_VALUE(PMRCAP_BIR, pmrcap) +#define NVME_PMRCAP_PMRTU(pmrcap) NVME_REG_VALUE(PMRCAP_PMRTU, pmrcap) +#define NVME_PMRCAP_PMRWMB(pmrcap) NVME_REG_VALUE(PMRCAP_PMRWMB, pmrcap) +#define NVME_PMRCAP_PMRTO(pmrcap) NVME_REG_VALUE(PMRCAP_PMRTO, pmrcap) +#define NVME_PMRCAP_CMSS(pmrcap) NVME_REG_VALUE(PMRCAP_CMSS, pmrcap) + +enum nvme_pmrctl { + NVME_PMRCTL_EN_SHIFT = 0, + NVME_PMRCTL_EN_MASK = 0x1, +}; + +#define NVME_PMRCTL_EN(pmrctl) NVME_REG_VALUE(PMRCTL_EN, pmrctl) + +enum nvme_pmrsts { + NVME_PMRSTS_ERR_SHIFT = 0, + NVME_PMRSTS_NRDY_SHIFT = 8, + NVME_PMRSTS_HSTS_SHIFT = 9, + NVME_PMRSTS_CBAI_SHIFT = 12, + NVME_PMRSTS_ERR_MASK = 0xff, + NVME_PMRSTS_NRDY_MASK = 0x1, + NVME_PMRSTS_HSTS_MASK = 0x7, + NVME_PMRSTS_CBAI_MASK = 0x1, +}; + +#define NVME_PMRSTS_ERR(pmrsts) NVME_REG_VALUE(PMRSTS_ERR, pmrsts) +#define NVME_PMRSTS_NRDY(pmrsts) NVME_REG_VALUE(PMRSTS_NRDY, pmrsts) +#define NVME_PMRSTS_HSTS(pmrsts) NVME_REG_VALUE(PMRSTS_HSTS, pmrsts) +#define NVME_PMRSTS_CBAI(pmrsts) NVME_REG_VALUE(PMRSTS_CBAI, pmrsts) + +enum nvme_pmrebs { + NVME_PMREBS_PMRSZU_SHIFT = 0, + NVME_PMREBS_RBB_SHIFT = 4, + NVME_PMREBS_PMRWBZ_SHIFT = 8, + NVME_PMREBS_PMRSZU_MASK = 0xf, + NVME_PMREBS_RBB_MASK = 0x1, + NVME_PMREBS_PMRWBZ_MASK = 0xffffff, + NVME_PMREBS_PMRSZU_B = 0, + NVME_PMREBS_PMRSZU_1K = 1, + NVME_PMREBS_PMRSZU_1M = 2, + NVME_PMREBS_PMRSZU_1G = 3, +}; + +#define NVME_PMREBS_PMRSZU(pmrebs) NVME_REG_VALUE(PMREBS_PMRSZU, pmrebs) +#define NVME_PMREBS_RBB(pmrebs) NVME_REG_VALUE(PMREBS_RBB, pmrebs) +#define NVME_PMREBS_PMRWBZ(pmrebs) NVME_REG_VALUE(PMREBS_PMRWBZ, pmrebs) + +/** + * nvme_pmr_size() - Calculate size of persistent memory region elasticity + * buffer + * @pmrebs: Value from controller register %NVME_REG_PMREBS + * + * Returns size of controller persistent memory buffer in bytes + */ +static inline __u64 nvme_pmr_size(__u32 pmrebs) +{ + return ((__u64)NVME_PMREBS_PMRWBZ(pmrebs)) * + (1ULL << (10 * NVME_PMREBS_PMRSZU(pmrebs))); +} + +enum nvme_pmrswtp { + NVME_PMRSWTP_PMRSWTU_SHIFT = 0, + NVME_PMRSWTP_PMRSWTV_SHIFT = 8, + NVME_PMRSWTP_PMRSWTU_MASK = 0xf, + NVME_PMRSWTP_PMRSWTV_MASK = 0xffffff, + NVME_PMRSWTP_PMRSWTU_BPS = 0, + NVME_PMRSWTP_PMRSWTU_KBPS = 1, + NVME_PMRSWTP_PMRSWTU_MBPS = 2, + NVME_PMRSWTP_PMRSWTU_GBPS = 3, +}; + +#define NVME_PMRSWTP_PMRSWTU(pmrswtp) NVME_REG_VALUE(PMRSWTP_PMRSWTU, pmrswtp) +#define NVME_PMRSWTP_PMRSWTV(pmrswtp) NVME_REG_VALUE(PMRSWTP_PMRSWTU, pmrswtp) + +/** + * nvme_pmr_throughput() - Calculate throughput of persistent memory buffer + * @mprswtp: Value from controller register %NVME_REG_PMRSWTP + * + * Returns throughput of controller persistent memory buffer in bytes/second + */ +static inline __u64 nvme_pmr_throughput(__u32 pmrswtp) +{ + return ((__u64)NVME_PMRSWTP_PMRSWTV(pmrswtp)) * + (1ULL << (10 * NVME_PMRSWTP_PMRSWTU(pmrswtp))); +} + +enum nvme_pmrmsc { + NVME_PMRMSC_CMSE_SHIFT = 1, + NVME_PMRMSC_CBA_SHIFT = 12, + NVME_PMRMSC_CMSE_MASK = 0x1, +}; +static const __u64 NVME_PMRMSC_CBA_MASK = 0xfffffffffffffull; + +#define NVME_PMRMSC_CMSE(pmrmsc) NVME_REG_VALUE(PMRMSC_CMSE, pmrmsc) +#define NVME_PMRMSC_CBA(pmrmsc) NVME_REG_VALUE(PMRMSC_CBA, pmrmsc) + /** * enum nvme_psd_flags - Possible flag values in nvme power state descriptor * @NVME_PSD_FLAGS_MXPS: Indicates the scale for the Maximum Power @@ -3805,8 +4136,4 @@ static inline __u16 nvme_status_code(__u16 status_field) return status_field & NVME_SC_MASK; } -#define NVME_MAJOR(ver) ((ver) >> 16) -#define NVME_MINOR(ver) (((ver) >> 8) & 0xff) -#define NVME_TERTIARY(ver) ((ver) & 0xff) - #endif /* _LIBNVME_TYPES_H */ diff --git a/test/Makefile b/test/Makefile index ddb80b7a27..b5541aaf10 100644 --- a/test/Makefile +++ b/test/Makefile @@ -9,7 +9,7 @@ else CONFIG_CPLUSPLUS=y endif -c_targets += test +c_targets += test register ifdef CONFIG_CPLUSPLUS cpp_targets += cpp diff --git a/test/register.c b/test/register.c new file mode 100644 index 0000000000..b405eafa4e --- /dev/null +++ b/test/register.c @@ -0,0 +1,210 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/** + * This file is part of libnvme. + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + * + * Authors: Keith Busch + */ + +/** + * Prints the values of the nvme register map. Use the nvme controller resource + * for your pci device found in /sys/class/nvme/nvmeX/device/resource0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +void nvme_print_registers(void *regs) +{ + __u64 cap = nvme_mmio_read64(regs + NVME_REG_CAP); + __u32 vs = nvme_mmio_read32(regs + NVME_REG_VS); + __u32 intms = nvme_mmio_read32(regs + NVME_REG_INTMS); + __u32 intmc = nvme_mmio_read32(regs + NVME_REG_INTMC); + __u32 cc = nvme_mmio_read32(regs + NVME_REG_CC); + __u32 csts = nvme_mmio_read32(regs + NVME_REG_CSTS); + __u32 nssr = nvme_mmio_read32(regs + NVME_REG_NSSR); + __u32 aqa = nvme_mmio_read32(regs + NVME_REG_AQA); + __u64 asq = nvme_mmio_read64(regs + NVME_REG_ASQ); + __u64 acq = nvme_mmio_read64(regs + NVME_REG_ACQ); + __u32 cmbloc = nvme_mmio_read32(regs + NVME_REG_CMBLOC); + __u32 cmbsz = nvme_mmio_read32(regs + NVME_REG_CMBSZ); + __u32 bpinfo = nvme_mmio_read32(regs + NVME_REG_BPINFO); + __u32 bprsel = nvme_mmio_read32(regs + NVME_REG_BPRSEL); + __u64 bpmbl = nvme_mmio_read64(regs + NVME_REG_BPMBL); + __u64 cmbmsc = nvme_mmio_read64(regs + NVME_REG_CMBMSC); + __u32 cmbsts = nvme_mmio_read32(regs + NVME_REG_CMBSTS); + __u32 pmrcap = nvme_mmio_read32(regs + NVME_REG_PMRCAP); + __u32 pmrctl = nvme_mmio_read32(regs + NVME_REG_PMRCTL); + __u32 pmrsts = nvme_mmio_read32(regs + NVME_REG_PMRSTS); + __u32 pmrebs = nvme_mmio_read32(regs + NVME_REG_PMREBS); + __u32 pmrswtp = nvme_mmio_read32(regs + NVME_REG_PMRSWTP); + __u64 pmrmsc = nvme_mmio_read64(regs + NVME_REG_PMRMSC); + + printf("%-10s : %llx\n", "CAP", cap); + printf(" %-8s : %llx\n", "MQES", NVME_CAP_MQES(cap)); + printf(" %-8s : %llx\n", "CQRS", NVME_CAP_CQR(cap)); + printf(" %-8s : %llx\n", "AMS", NVME_CAP_AMS(cap)); + printf(" %-8s : %llx\n", "TO", NVME_CAP_TO(cap)); + printf(" %-8s : %llx\n", "DSTRD", NVME_CAP_DSTRD(cap)); + printf(" %-8s : %llx\n", "NSSRC", NVME_CAP_NSSRC(cap)); + printf(" %-8s : %llx\n", "CSS", NVME_CAP_CSS(cap)); + printf(" %-8s : %llx\n", "BPS", NVME_CAP_BPS(cap)); + printf(" %-8s : %llx\n", "MPSMIN", NVME_CAP_MPSMIN(cap)); + printf(" %-8s : %llx\n", "MPSMAX", NVME_CAP_MPSMAX(cap)); + printf(" %-8s : %llx\n", "CMBS", NVME_CAP_CMBS(cap)); + printf(" %-8s : %llx\n", "PMRS", NVME_CAP_PMRS(cap)); + + printf("%-10s : %x\n", "VS", vs); + printf(" %-8s : %x\n", "MJR", NVME_VS_TER(vs)); + printf(" %-8s : %x\n", "MNR", NVME_VS_MNR(vs)); + printf(" %-8s : %x\n", "TER", NVME_VS_MJR(vs)); + + printf("%-10s : %x\n", "INTMS", intms); + printf("%-10s : %x\n", "INTMC", intmc); + + printf("%-10s : %x\n", "CC", cc); + printf(" %-8s : %x\n", "EN", NVME_CC_EN(cc)); + printf(" %-8s : %x\n", "CSS", NVME_CC_CSS(cc)); + printf(" %-8s : %x\n", "MPS", NVME_CC_MPS(cc)); + printf(" %-8s : %x\n", "AMS", NVME_CC_AMS(cc)); + printf(" %-8s : %x\n", "SHN", NVME_CC_SHN(cc)); + printf(" %-8s : %x\n", "IOSQES", NVME_CC_IOSQES(cc)); + printf(" %-8s : %x\n", "IOCQES", NVME_CC_IOCQES(cc)); + + printf("%-10s : %x\n", "CSTS", csts); + printf(" %-8s : %x\n", "RDY", NVME_CSTS_RDY(csts)); + printf(" %-8s : %x\n", "CFS", NVME_CSTS_CFS(csts)); + printf(" %-8s : %x\n", "SHST", NVME_CSTS_SHST(csts)); + printf(" %-8s : %x\n", "NSSRO", NVME_CSTS_NSSRO(csts)); + printf(" %-8s : %x\n", "PP", NVME_CSTS_PP(csts)); + + printf("%-10s : %x\n", "NSSR", nssr); + + printf("%-10s : %x\n", "AQA", aqa); + printf(" %-8s : %x\n", "ASQS", NVME_AQA_ASQS(aqa)); + printf(" %-8s : %x\n", "ACQS", NVME_AQA_ACQS(aqa)); + + printf("%-10s : %llx\n", "ASQ", asq); + printf("%-10s : %llx\n", "ACQ", acq); + + printf("%-10s : %x\n", "CMBLOC", cmbloc); + printf(" %-8s : %x\n", "BIR", NVME_CMBLOC_BIR(cmbloc)); + printf(" %-8s : %x\n", "CQMMS", NVME_CMBLOC_CQMMS(cmbloc)); + printf(" %-8s : %x\n", "CQPDS", NVME_CMBLOC_CQPDS(cmbloc)); + printf(" %-8s : %x\n", "CDPLMS", NVME_CMBLOC_CDPLMS(cmbloc)); + printf(" %-8s : %x\n", "CDPCILS", NVME_CMBLOC_CDPCILS(cmbloc)); + printf(" %-8s : %x\n", "CDMMMS", NVME_CMBLOC_CDMMMS(cmbloc)); + printf(" %-8s : %x\n", "CQDA", NVME_CMBLOC_CQDA(cmbloc)); + printf(" %-8s : %x\n", "OFST", NVME_CMBLOC_OFST(cmbloc)); + + printf("%-10s : %x\n", "CMBSZ", cmbsz); + printf(" %-8s : %x\n", "SQS", NVME_CMBSZ_SQS(cmbsz)); + printf(" %-8s : %x\n", "CQS", NVME_CMBSZ_CQS(cmbsz)); + printf(" %-8s : %x\n", "LISTS", NVME_CMBSZ_LISTS(cmbsz)); + printf(" %-8s : %x\n", "RDS", NVME_CMBSZ_RDS(cmbsz)); + printf(" %-8s : %x\n", "WDS", NVME_CMBSZ_WDS(cmbsz)); + printf(" %-8s : %x\n", "SZU", NVME_CMBSZ_SZU(cmbsz)); + printf(" %-8s : %x\n", "SZ", NVME_CMBSZ_SZ(cmbsz)); + printf(" %-8s : %llx\n", "bytes", nvme_cmb_size(cmbsz)); + + printf("%-10s : %x\n", "BPINFO", bpinfo); + printf(" %-8s : %x\n", "BPSZ", NVME_BPINFO_BPSZ(bpinfo)); + printf(" %-8s : %x\n", "BRS", NVME_BPINFO_BRS(bpinfo)); + printf(" %-8s : %x\n", "ABPID", NVME_BPINFO_ABPID(bpinfo)); + + printf("%-10s : %x\n", "BPRSEL", bprsel); + printf(" %-8s : %x\n", "BPRSZ", NVME_BPRSEL_BPRSZ(bprsel)); + printf(" %-8s : %x\n", "BPROF", NVME_BPRSEL_BPROF(bprsel)); + printf(" %-8s : %x\n", "BPID", NVME_BPRSEL_BPID(bprsel)); + + printf("%-10s : %llx\n", "BPMBL", bpmbl); + + printf("%-10s : %llx\n", "CMBMSC", cmbmsc); + printf(" %-8s : %llx\n", "CRE", NVME_CMBMSC_CRE(cmbmsc)); + printf(" %-8s : %llx\n", "CMSE", NVME_CMBMSC_CMSE(cmbmsc)); + printf(" %-8s : %llx\n", "CBA", NVME_CMBMSC_CBA(cmbmsc)); + + printf("%-10s : %x\n", "CMBSTS", cmbsts); + printf(" %-8s : %x\n", "CBAI", NVME_CMBSTS_CBAI(cmbsts)); + + printf("%-10s : %x\n", "PMRCAP", pmrcap); + printf(" %-8s : %x\n", "RDS", NVME_PMRCAP_RDS(pmrcap)); + printf(" %-8s : %x\n", "WDS", NVME_PMRCAP_WDS(pmrcap)); + printf(" %-8s : %x\n", "BIR", NVME_PMRCAP_BIR(pmrcap)); + printf(" %-8s : %x\n", "PMRTU", NVME_PMRCAP_PMRTU(pmrcap)); + printf(" %-8s : %x\n", "PMRWMB", NVME_PMRCAP_PMRWMB(pmrcap)); + printf(" %-8s : %x\n", "PMRTO", NVME_PMRCAP_PMRTO(pmrcap)); + printf(" %-8s : %x\n", "CMSS", NVME_PMRCAP_CMSS(pmrcap)); + + printf("%-10s : %x\n", "PMRCTL", pmrctl); + printf(" %-8s : %x\n", "EN", NVME_PMRCTL_EN(pmrctl)); + + printf("%-10s : %x\n", "PMRSTS", pmrsts); + printf(" %-8s : %x\n", "ERR", NVME_PMRSTS_ERR(pmrsts)); + printf(" %-8s : %x\n", "NRDY", NVME_PMRSTS_NRDY(pmrsts)); + printf(" %-8s : %x\n", "HSTS", NVME_PMRSTS_HSTS(pmrsts)); + printf(" %-8s : %x\n", "CBAI", NVME_PMRSTS_CBAI(pmrsts)); + + printf("%-10s : %x\n", "PMREBS", pmrebs); + printf(" %-8s : %x\n", "PMRSZU", NVME_PMREBS_PMRSZU(pmrebs)); + printf(" %-8s : %x\n", "RBB", NVME_PMREBS_RBB(pmrebs)); + printf(" %-8s : %x\n", "PMRWBZ", NVME_PMREBS_PMRWBZ(pmrebs)); + printf(" %-8s : %llx\n", "bytes", nvme_pmr_size(pmrebs)); + + printf("%-10s : %x\n", "PMRSWTP", pmrswtp); + printf(" %-8s : %x\n", "PMRSWTU", NVME_PMRSWTP_PMRSWTU(pmrswtp)); + printf(" %-8s : %x\n", "PMRSWTV", NVME_PMRSWTP_PMRSWTV(pmrswtp)); + printf(" %-8s : %llx\n", "tput", nvme_pmr_throughput(pmrswtp)); + + printf("%-10s : %llx\n", "PMRMSC", pmrmsc); + printf(" %-8s : %llx\n", "CMSE", NVME_PMRMSC_CMSE(pmrmsc)); + printf(" %-8s : %llx\n", "CBA", NVME_PMRMSC_CBA(pmrmsc)); +} + +int main(int argc, char **argv) +{ + int ret, fd; + char *path; + void *regs; + + if (argc != 2) { + fprintf(stderr, "%s nvme\n", argv[0]); + return 1; + } + + ret = asprintf(&path, "/sys/class/nvme/%s/device/resource0", argv[1]); + if (ret < 0) + return 0; + + printf("open %s\n", path); + fd = open(path, O_RDONLY | O_SYNC); + if (fd < 0) { + fprintf(stderr, "failed to open %s\n", path); + free(path); + return 1; + } + + regs = mmap(NULL, getpagesize(), PROT_READ, MAP_SHARED, fd, 0); + if (regs == MAP_FAILED) { + fprintf(stderr, "failed to map device BAR\n"); + fprintf(stderr, "did your kernel enable CONFIG_IO_STRICT_DEVMEM?\n"); + free(path); + close(fd); + return 1; + } + + nvme_print_registers(regs); + munmap(regs, getpagesize()); + free(path); + close(fd); + + return 0; +} + From 380d801f46c58fd0a6883e441001edf2352ace07 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 28 May 2020 10:26:06 -0700 Subject: [PATCH 0047/1564] fix comment typo Signed-off-by: Keith Busch --- src/nvme/ioctl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index ae16b8dadf..f423bca175 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -1281,7 +1281,7 @@ int nvme_get_log_sanitize(int fd, bool rae, struct nvme_sanitize_log_page *log); /** - * nvme_set_feature() - Set a feature attribute + * nvme_set_features() - Set a feature attribute * @fd: File descriptor of nvme device * @fid: Feature identifier * @nsid: Namespace ID, if applicable From be604f2e8f0f3c55a57684db14b24f510489c0df Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 28 May 2020 13:41:32 -0700 Subject: [PATCH 0048/1564] Explicit casting from void * Signed-off-by: Keith Busch --- src/nvme/ioctl.h | 1 + src/nvme/types.h | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index f423bca175..445468b042 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -576,6 +576,7 @@ enum nvme_get_features_sel { NVME_GET_FEATURES_SEL_CURRENT = 0, NVME_GET_FEATURES_SEL_DEFAULT = 1, NVME_GET_FEATURES_SEL_SAVED = 2, + NVME_GET_FEATURES_SEL_SUPPORTED = 3, }; /** diff --git a/src/nvme/types.h b/src/nvme/types.h index d5b3e6b101..b10737c961 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -218,14 +218,14 @@ static inline bool nvme_is_64bit_reg(__u32 offset) static inline __u32 nvme_mmio_read32(void *addr) { - __le32 *p = addr; + __le32 *p = (__le32 *)addr; return le32_to_cpu(*p); } static inline __u64 nvme_mmio_read64(void *addr) { - __le32 *p = addr; + __le32 *p = (__le32 *)addr; /* * Some devices fail 64-bit MMIO. Access 64-bit registers as 2 32-bit. From a2e424322385bedfefbcf6620711083c7ff4f6c3 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Fri, 29 May 2020 09:33:42 -0700 Subject: [PATCH 0049/1564] minor updates A collection of updates including: Naming consistency improvements Namespace descriptor attributes added to namespace elements Doc updates to use more consise descriptions Signed-off-by: Keith Busch --- src/nvme/ioctl.c | 14 ++-- src/nvme/ioctl.h | 197 ++++++++++++++++++++++++----------------------- src/nvme/tree.c | 65 +++++++++++++++- src/nvme/tree.h | 36 +++++++++ src/nvme/types.h | 94 +++++++++++++--------- test/Makefile | 2 +- test/test.c | 23 +++++- 7 files changed, 283 insertions(+), 148 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 28aee2d3cf..2c3a12163d 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -1645,8 +1645,8 @@ int nvme_dsm(int fd, __u32 nsid, __u32 attrs, __u16 nr_ranges, return nvme_submit_io_passthru(fd, &cmd, NULL); } -int nvme_resv_acquire(int fd, __u32 nsid, enum nvme_reservation_rtype rtype, - enum nvme_reservation_racqa racqa, bool iekey, +int nvme_resv_acquire(int fd, __u32 nsid, enum nvme_resv_rtype rtype, + enum nvme_resv_racqa racqa, bool iekey, __u64 crkey, __u64 nrkey) { __le64 payload[2] = { cpu_to_le64(crkey), cpu_to_le64(nrkey) }; @@ -1663,8 +1663,8 @@ int nvme_resv_acquire(int fd, __u32 nsid, enum nvme_reservation_rtype rtype, return nvme_submit_io_passthru(fd, &cmd, NULL); } -int nvme_resv_register(int fd, __u32 nsid, enum nvme_reservation_rrega rrega, - enum nvme_reservation_cptpl cptpl, bool iekey, +int nvme_resv_register(int fd, __u32 nsid, enum nvme_resv_rrega rrega, + enum nvme_resv_cptpl cptpl, bool iekey, __u64 crkey, __u64 nrkey) { __le64 payload[2] = { cpu_to_le64(crkey), cpu_to_le64(nrkey) }; @@ -1681,8 +1681,8 @@ int nvme_resv_register(int fd, __u32 nsid, enum nvme_reservation_rrega rrega, return nvme_submit_io_passthru(fd, &cmd, NULL); } -int nvme_resv_release(int fd, __u32 nsid, enum nvme_reservation_rtype rtype, - enum nvme_reservation_rrela rrela, bool iekey, +int nvme_resv_release(int fd, __u32 nsid, enum nvme_resv_rtype rtype, + enum nvme_resv_rrela rrela, bool iekey, __u64 crkey) { __le64 payload[1] = { cpu_to_le64(crkey) }; @@ -1700,7 +1700,7 @@ int nvme_resv_release(int fd, __u32 nsid, enum nvme_reservation_rtype rtype, } int nvme_resv_report(int fd, __u32 nsid, bool eds, __u32 len, - struct nvme_reservation_status *report) + struct nvme_resv_status *report) { struct nvme_passthru_cmd cmd = { .opcode = nvme_cmd_resv_report, diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 445468b042..77ad9a3631 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -939,9 +939,9 @@ int nvme_identify_nvmset_list(int fd, __u16 nvmsetid, /** * nvme_identify_primary_ctrl() - Retrieve NVMe Primary Controller * identification - * &fd: - * @cntid: - * @cap: + * @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. * @@ -1006,10 +1006,11 @@ int nvme_identify_uuid(int fd, struct nvme_id_uuid_list *list); /** * nvme_get_log() - NVMe Admin Get Log command - * @fd: File descriptor of nvme device - * @lid: Log page identifier, see &enum nvme_cmd_get_log_lid for known values - * @nsid: Namespace identifier, if applicable - * @lpo: Log page offset for partial log transfers + * @fd: File descriptor of nvme device + * @lid: Log page identifier, see &enum nvme_cmd_get_log_lid for known + * values + * @nsid: Namespace identifier, if applicable + * @lpo: Log page offset for partial log transfers * @lsp: Log specific field * @lsi: Endurance group information * @rae: Retain asynchronous events @@ -1030,8 +1031,8 @@ int nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, * @rae: Retain asynchronous events * @err_log: Array of error logs of size 'entries' * - * This log page is used to describe extended error information for a command - * that completed with error, or may report an error that is not specific to a + * This log page describes extended error information for a command that + * completed with error, or may report an error that is not specific to a * particular command. * * Return: The nvme command status if a response was received (see @@ -1047,12 +1048,12 @@ int nvme_get_log_error(int fd, unsigned nr_entries, bool rae, * @rae: Retain asynchronous events * @smart_log: User address to store the smart log * - * This log page is used to provide SMART and general health information. The - * information provided is over the life of the controller and is retained - * across power cycles. To request the controller log page, the namespace - * identifier specified is FFFFFFFFh. The controller may also support - * requesting the log page on a per namespace basis, as indicated by bit 0 of - * the LPA field in the Identify Controller data structure. + * This log page provides SMART and general health information. The information + * provided is over the life of the controller and is retained across power + * cycles. To request the controller log page, the namespace identifier + * specified is FFFFFFFFh. The controller may also support requesting the log + * page on a per namespace basis, as indicated by bit 0 of the LPA field in the + * Identify Controller data structure. * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. @@ -1065,9 +1066,9 @@ int nvme_get_log_smart(int fd, __u32 nsid, bool rae, struct nvme_smart_log *log) * @rae: Retain asynchronous events * @fw_log: User address to store the log page * - * This log page is used to describe the firmware revision stored in each - * firmware slot supported. The firmware revision is indicated as an ASCII - * string. The log page also indicates the active slot number. + * This log page describes the firmware revision stored in each firmware slot + * supported. The firmware revision is indicated as an ASCII string. The log + * page also indicates the active slot number. * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. @@ -1080,9 +1081,9 @@ int nvme_get_log_fw_slot(int fd, bool rae, struct nvme_firmware_slot *log); * @rae: Retain asynchronous events * @ns_list: User address to store the log page * - * This log page is used to describe namespaces attached to this controller - * that have changed since the last time the namespace was identified, been - * added, or deleted. + * This log page describes namespaces attached to this controller that have + * changed since the last time the namespace was identified, been added, or + * deleted. * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. @@ -1094,8 +1095,8 @@ int nvme_get_log_changed_ns_list(int fd, bool rae, struct nvme_ns_list *log); * @fd: File descriptor of nvme device * @effects_log:User address to store the effects log * - * This log page is used to describe the commands that the controller supports - * and the effects of those commands on the state of the NVM subsystem. + * This log page describes the commands that the controller supports and the + * effects of those commands on the state of the NVM subsystem. * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. @@ -1108,8 +1109,8 @@ int nvme_get_log_cmd_effects(int fd, struct nvme_cmd_effects_log *log); * @nsid: Namespace ID being tested * @log: Userspace address of the log payload * - * The log page is used to indicate the status of an in progress self test and - * the percent complete of that operation, and the results of the previous 20 + * The log page indicates the status of an in progress self test and the + * percent complete of that operation, and the results of the previous 20 * self-test operations. * * Return: The nvme command status if a response was received (see @@ -1272,8 +1273,8 @@ int nvme_get_log_reservation(int fd, bool rae, * @rae: Retain asynchronous events * @log: User address to store the sanitize log * - * The Sanitize Status log page is used to report sanitize operation time - * estimates and information about the most recent sanitize operation. + * The Sanitize Status log page reports sanitize operation time estimates and + * information about the most recent sanitize operation. * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. @@ -1338,7 +1339,6 @@ int nvme_set_features_power_mgmt(int fd, __u8 ps, __u8 wh, bool save, int nvme_set_features_lba_range(int fd, __u32 nsid, __u32 nr_ranges, bool save, struct nvme_lba_range_type *data, __u32 *result); - /** * enum nvme_feat_tmpthresh_thsel - */ @@ -1372,7 +1372,6 @@ int nvme_set_features_temp_thresh(int fd, __u16 tmpth, __u8 tmpsel, int nvme_set_features_err_recovery(int fd, __u32 nsid, __u16 tler, bool dulbe, bool save, __u32 *result); - /** * nvme_set_features_volatile_wc() - * @fd: File descriptor of nvme device @@ -1409,7 +1408,6 @@ int nvme_set_features_irq_coalesce(int fd, __u8 thr, __u8 time, int nvme_set_features_irq_config(int fd, __u16 iv, bool cd, bool save, __u32 *result); - /** * nvme_set_features_write_atomic() - * @fd: File descriptor of nvme device @@ -1454,7 +1452,6 @@ enum nvme_features_async_event_config_flags { int nvme_set_features_async_event(int fd, __u32 events, bool save, __u32 *result); - /** * nvme_set_features_auto_pst() - * @fd: File descriptor of nvme device @@ -1479,7 +1476,6 @@ 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() - * @fd: File descriptor of nvme device @@ -1494,6 +1490,12 @@ int nvme_set_features_hctm(int fd, __u16 tmt2, __u16 tmt1, bool save, /** * nvme_set_features_nopsc() - + * @fd: File descriptor of nvme device + * @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. */ int nvme_set_features_nopsc(int fd, bool noppme, bool save, __u32 *result); @@ -1542,7 +1544,6 @@ enum nvme_feat_plm_window_select { 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() - * @fd: File descriptor of nvme device @@ -1555,11 +1556,11 @@ int nvme_set_features_plm_window(int fd, enum nvme_feat_plm_window_select sel, int nvme_set_features_lba_sts_interval(int fd, __u16 lsiri, __u16 lsipi, bool save, __u32 *result); - /** * nvme_set_features_host_behavior() - * @fd: File descriptor of nvme device * @save: Save value across power states + * @data: * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. @@ -1570,6 +1571,7 @@ int nvme_set_features_host_behavior(int fd, bool save, /** * nvme_set_features_sanitize() - * @fd: File descriptor of nvme device + * @nodrm: * @save: Save value across power states * @result: The command completion result from CQE dword0 * @@ -1595,6 +1597,7 @@ int nvme_set_features_endurance_evt_cfg(int fd, __u16 endgid, __u8 egwarn, /** * nvme_set_features_sw_progress() - * @fd: File descriptor of nvme device + * @pbslc: * @save: Save value across power states * @result: The command completion result from CQE dword0 * @@ -1608,6 +1611,7 @@ int nvme_set_features_sw_progress(int fd, __u8 pbslc, bool save, /** * nvme_set_features_host_id() - * @fd: File descriptor of nvme device + * @exhid: * @save: Save value across power states * @result: The command completion result from CQE dword0 * @@ -1628,6 +1632,7 @@ enum nvme_feat_resv_notify_flags { /** * nvme_set_features_resv_mask() - * @fd: File descriptor of nvme device + * @mask: * @save: Save value across power states * @result: The command completion result from CQE dword0 * @@ -1639,6 +1644,7 @@ int nvme_set_features_resv_mask(int fd, __u32 mask, bool save, __u32 *result); /** * nvme_set_features_resv_persist() - * @fd: File descriptor of nvme device + * @ptpl: * @save: Save value across power states * @result: The command completion result from CQE dword0 * @@ -1664,6 +1670,7 @@ enum nvme_feat_nswpcfg_state { /** * nvme_set_features_write_protect() - * @fd: File descriptor of nvme device + * @stat: * @save: Save value across power states * @result: The command completion result from CQE dword0 * @@ -2054,10 +2061,10 @@ int nvme_get_features_write_protect(int fd, __u32 nsid, * @timeout: Set to override default timeout to this value in milliseconds; * useful for long running formats. 0 will use system default. * - * The Format NVM command is used to low level format the NVM media. This - * command is used by the host to change the LBA data size and/or metadata - * size. A low level format may destroy all data and metadata associated with - * all namespaces or only the specific namespace associated with the command + * The Format NVM command low level formats the NVM media. This command is used + * by the host to change the LBA data size and/or metadata size. A low level + * format may destroy all data and metadata associated with all namespaces or + * only the specific namespace associated with the command * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. @@ -2142,9 +2149,9 @@ int nvme_ns_detach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist); * @data_len: Length of data in this command in bytes * @data: Userspace address of the firmware data * - * The Firmware Image Download command is used to download all or a portion of - * an image for a future update to the controller. The Firmware Image Download - * command downloads a new image (in whole or in part) to the controller. + * The Firmware Image Download command downloads all or a portion of an image + * for a future update to the controller. The Firmware Image Download command + * downloads a new image (in whole or in part) to the controller. * * The image may be constructed of multiple pieces that are individually * downloaded with separate Firmware Image Download commands. Each Firmware @@ -2167,8 +2174,7 @@ int nvme_fw_download(int fd, __u32 offset, __u32 data_len, void *data); * @action: Action to use for the firmware image, see &enum nvme_fw_commit_ca * @bpid: Set to true to select the boot partition id * - * The Firmware Commit command is used to modify the firmware image or Boot - * Partitions. + * The Firmware Commit command modifies the firmware image or Boot Partitions. * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. The command @@ -2191,7 +2197,7 @@ int nvme_fw_commit(int fd, __u8 slot, enum nvme_fw_commit_ca action, bool bpid); * @data: Security data payload to send * @result: The command completion result from CQE dword0 * - * The Security Send command is used to transfer security protocol data to the + * The Security Send command transfers security protocol data to the * controller. The data structure transferred to the controller as part of this * command contains security protocol specific commands to be performed by the * controller. The data structure transferred may also contain data or @@ -2261,8 +2267,8 @@ int nvme_get_lba_status(int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl, * @result: If successful, the CQE dword0 value * * Directives is a mechanism to enable host and NVM subsystem or controller - * information exchange. The Directive Send command is used to transfer data - * related to a specific Directive Type from the host to the controller. + * information exchange. The Directive Send command transfers data related to a + * specific Directive Type from the host to the controller. * * See the NVMe specification for more information. * @@ -2431,11 +2437,11 @@ int nvme_get_property(int fd, int offset, __u64 *value); * recovery of any previous user data from any cache, the non-volatile media, * or any Controller Memory Buffer is not possible. * - * The Sanitize command is used to start a sanitize operation or to recover - * from a previously failed sanitize operation. The sanitize operation types - * that may be supported are Block Erase, Crypto Erase, and Overwrite. All - * sanitize operations are processed in the background, i.e., completion of the - * sanitize command does not indicate completion of the sanitize operation. + * The Sanitize command starts a sanitize operation or to recover from a + * previously failed sanitize operation. The sanitize operation types that may + * be supported are Block Erase, Crypto Erase, and Overwrite. All sanitize + * operations are processed in the background, i.e., completion of the sanitize + * command does not indicate completion of the sanitize operation. * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. @@ -2449,12 +2455,12 @@ int nvme_sanitize_nvm(int fd, enum nvme_sanitize_sanact sanact, bool ause, * @nsid: Namespace ID to test * @stc: Self test code, see &enum nvme_dst_stc * - * The Device Self-test command is used to start a device self-test operation - * or abort a device self-test operation. A device self-test operation is a - * diagnostic testing sequence that tests the integrity and functionality of - * the controller and may include testing of the media associated with - * namespaces. The controller may return a response to this command immediately - * while running the self-test in the background. + * The Device Self-test command starts a device self-test operation or abort a + * device self-test operation. A device self-test operation is a diagnostic + * testing sequence that tests the integrity and functionality of the + * controller and may include testing of the media associated with namespaces. + * The controller may return a response to this command immediately while + * running the self-test in the background. * * Set the 'nsid' field to 0 to not include namepsaces in the test. Set to * 0xffffffff to test all namespaces. All other values tests a specific @@ -2524,8 +2530,8 @@ enum nvme_io_opcode { * @fd: File descriptor of nvme device * @nsid: Namespace identifier * - * The Flush command is used to request that the contents of volatile write - * cache be made non-volatile. + * The Flush command requests that the contents of volatile write cache be made + * non-volatile. * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. @@ -2695,10 +2701,10 @@ int nvme_compare(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, * only if the namespace is formatted to use end-to-end protection * information. * - * The Write Zeroes command is used to set a range of logical blocks to zero. - * After successful completion of this command, the value returned by - * subsequent reads of logical blocks in this range shall be all bytes cleared - * to 0h until a write occurs to this LBA range. + * The Write Zeroes command sets a range of logical blocks to zero. After + * successful completion of this command, the value returned by subsequent + * reads of logical blocks in this range shall be all bytes cleared to 0h until + * a write occurs to this LBA range. * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. @@ -2713,11 +2719,10 @@ int nvme_write_zeros(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, * @slba: Starting logical block * @nlb: Number of logical blocks to invalidate (0's based value) * - * The Write Uncorrectable command is used to mark a range of logical blocks as - * invalid. When the specified logical block(s) are read after this operation, - * a failure is returned with Unrecovered Read Error status. To clear the - * invalid logical block status, a write operation on those logical blocks is - * required. + * The Write Uncorrectable command marks a range of logical blocks as invalid. + * When the specified logical block(s) are read after this operation, a failure + * is returned with Unrecovered Read Error status. To clear the invalid logical + * block status, a write operation on those logical blocks is required. * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. @@ -2784,7 +2789,7 @@ int nvme_dsm(int fd, __u32 nsid, __u32 attrs, __u16 nr_ranges, struct nvme_dsm_range *dsm); /** - * enum nvme_reservation_rtype - + * enum nvme_resv_rtype - * @NVME_RESERVATION_RTYPE_WE: * @NVME_RESERVATION_RTYPE_EA: * @NVME_RESERVATION_RTYPE_WERO: @@ -2792,7 +2797,7 @@ int nvme_dsm(int fd, __u32 nsid, __u32 attrs, __u16 nr_ranges, * @NVME_RESERVATION_RTYPE_WEAR: * @NVME_RESERVATION_RTYPE_EAAR: */ -enum nvme_reservation_rtype { +enum nvme_resv_rtype { NVME_RESERVATION_RTYPE_WE = 1, NVME_RESERVATION_RTYPE_EA = 2, NVME_RESERVATION_RTYPE_WERO = 3, @@ -2802,12 +2807,12 @@ enum nvme_reservation_rtype { }; /** - * enum nvme_reservation_racqa - + * enum nvme_resv_racqa - * @NVME_RESERVATION_RACQA_ACQUIRE: * @NVME_RESERVATION_RACQA_PREEMPT: * @NVME_RESERVATION_RACQA_PREEMPT_AND_ABORT: */ -enum nvme_reservation_racqa { +enum nvme_resv_racqa { NVME_RESERVATION_RACQA_ACQUIRE = 0, NVME_RESERVATION_RACQA_PREEMPT = 1, NVME_RESERVATION_RACQA_PREEMPT_AND_ABORT = 2, @@ -2817,43 +2822,43 @@ enum nvme_reservation_racqa { * nvme_resv_acquire() - Send an nvme reservation acquire * @fd: File descriptor of nvme device * @nsid: Namespace identifier - * @rtype: The type of reservation to be create, see &enum nvme_reservation_rtype - * @racqa: The action that is performed by the command, see &enum nvme_reservation_racqa + * @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 * @iekey: Set to ignore the existing key * @crkey: The current reservation key associated with the host * @nrkey: The reservation key to be unregistered from the namespace if * the action is preempt * - * The Reservation Acquire command is used to acquire a reservation on a - * namespace, preempt a reservation held on a namespace, and abort a - * reservation held on a namespace. + * The Reservation Acquire command acquires a reservation on a namespace, + * preempt a reservation held on a namespace, and abort a reservation held on a + * namespace. * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_resv_acquire(int fd, __u32 nsid, enum nvme_reservation_rtype rtype, - enum nvme_reservation_racqa racqa, bool iekey, +int nvme_resv_acquire(int fd, __u32 nsid, enum nvme_resv_rtype rtype, + enum nvme_resv_racqa racqa, bool iekey, __u64 crkey, __u64 nrkey); /** - * enum nvme_reservation_rrega - + * enum nvme_resv_rrega - * @NVME_RESERVATION_RREGA_REGISTER_KEY: * @NVME_RESERVATION_RREGA_UNREGISTER_KEY: * @NVME_RESERVATION_RREGA_REPLACE_KEY: */ -enum nvme_reservation_rrega { +enum nvme_resv_rrega { NVME_RESERVATION_RREGA_REGISTER_KEY = 0, NVME_RESERVATION_RREGA_UNREGISTER_KEY = 1, NVME_RESERVATION_RREGA_REPLACE_KEY = 2, }; /** - * enum nvme_reservation_cptpl - + * enum nvme_resv_cptpl - * @NVME_RESERVATION_CPTPL_NO_CHANGE: * @NVME_RESERVATION_CPTPL_CLEAR: * @NVME_RESERVATION_CPTPL_PERSIST: */ -enum nvme_reservation_cptpl { +enum nvme_resv_cptpl { NVME_RESERVATION_CPTPL_NO_CHANGE = 0, NVME_RESERVATION_CPTPL_CLEAR = 2, NVME_RESERVATION_CPTPL_PERSIST = 3, @@ -2863,29 +2868,29 @@ enum nvme_reservation_cptpl { * nvme_resv_register() - Send an nvme reservation register * @fd: File descriptor of nvme device * @nsid: Namespace identifier - * @rrega: The registration action, see &enum nvme_reservation_rrega - * @cptpl: Change persist through power loss, see &enum nvme_reservation_cptpl + * @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 * @crkey: The current reservation key associated with the host * @nrkey: The new reservation key to be register if action is register or * replace * - * The Reservation Register command is used to register, unregister, or replace - * a reservation key. + * The Reservation Register command registers, unregisters, or replaces a + * reservation key. * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_resv_register(int fd, __u32 nsid, enum nvme_reservation_rrega rrega, - enum nvme_reservation_cptpl cptpl, bool iekey, +int nvme_resv_register(int fd, __u32 nsid, enum nvme_resv_rrega rrega, + enum nvme_resv_cptpl cptpl, bool iekey, __u64 crkey, __u64 nrkey); /** - * enum nvme_reservation_rrela - + * enum nvme_resv_rrela - * @NVME_RESERVATION_RRELA_RELEASE: * @NVME_RESERVATION_RRELA_CLEAR: */ -enum nvme_reservation_rrela { +enum nvme_resv_rrela { NVME_RESERVATION_RRELA_RELEASE = 0, NVME_RESERVATION_RRELA_CLEAR = 1 }; @@ -2894,16 +2899,16 @@ enum nvme_reservation_rrela { * nvme_resv_release() - Send an nvme reservation release * @fd: File descriptor of nvme device * @nsid: Namespace identifier - * @rtype: The type of reservation to be create, see &enum nvme_reservation_rtype - * @rrela: Reservation releast action, see &enum nvme_reservation_rrela + * @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 * @crkey: The current reservation key to release * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_resv_release(int fd, __u32 nsid, enum nvme_reservation_rtype rtype, - enum nvme_reservation_rrela rrela, bool iekey, +int nvme_resv_release(int fd, __u32 nsid, enum nvme_resv_rtype rtype, + enum nvme_resv_rrela rrela, bool iekey, __u64 crkey); /** @@ -2922,5 +2927,5 @@ int nvme_resv_release(int fd, __u32 nsid, enum nvme_reservation_rtype rtype, * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_resv_report(int fd, __u32 nsid, bool eds, __u32 len, - struct nvme_reservation_status *report); + struct nvme_resv_status *report); #endif /* _LIBNVME_IOCTL_H */ diff --git a/src/nvme/tree.c b/src/nvme/tree.c index d850aa73cf..620b74d8b5 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -18,6 +18,8 @@ #include +#include + #include "ioctl.h" #include "filters.h" #include "tree.h" @@ -48,15 +50,19 @@ struct nvme_ns { struct nvme_ctrl *c; int fd; + int nsid; char *name; char *sysfs_dir; - int nsid; int lba_shift; int lba_size; int meta_size; uint64_t lba_count; uint64_t lba_util; + + uint8_t eui64[8]; + uint8_t nguid[16]; + uuid_t uuid; }; struct nvme_ctrl { @@ -357,7 +363,7 @@ void nvme_free_path(struct nvme_path *p) static void nvme_subsystem_set_path_ns(nvme_subsystem_t s, nvme_path_t p) { - char n_name[32] = { 0 }; + char n_name[32] = { }; int i, c, nsid, ret; nvme_ns_t n; @@ -720,11 +726,31 @@ uint64_t nvme_ns_get_lba_util(nvme_ns_t n) return n->lba_util; } +const uint8_t *nvme_ns_get_eui64(nvme_ns_t n) +{ + return n->eui64; +} + +const uint8_t *nvme_ns_get_nguid(nvme_ns_t n) +{ + return n->nguid; +} + +void nvme_ns_get_uuid(nvme_ns_t n, uuid_t out) +{ + uuid_copy(out, n->uuid); +} + int nvme_ns_identify(nvme_ns_t n, struct nvme_id_ns *ns) { return nvme_identify_ns(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), ns); } +int nvme_ns_identify_descs(nvme_ns_t n, struct nvme_ns_id_desc *descs) +{ + return nvme_identify_ns_descs(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), descs); +} + int nvme_ns_verify(nvme_ns_t n, off_t offset, size_t count) { __u64 slba; @@ -802,9 +828,38 @@ int nvme_ns_flush(nvme_ns_t n) return nvme_flush(nvme_ns_get_fd(n), nvme_ns_get_nsid(n)); } +static void nvme_ns_parse_descriptors(struct nvme_ns *n, + struct nvme_ns_id_desc *descs) +{ + void *d = descs; + int i, len; + + for (i = 0; i < NVME_IDENTIFY_DATA_SIZE; i += len) { + struct nvme_ns_id_desc *desc = d + i; + + if (!desc->nidl) + break; + len = desc->nidl + sizeof(*desc); + + switch (desc->nidt) { + case NVME_NIDT_EUI64: + memcpy(n->eui64, desc->nid, sizeof(n->eui64)); + break; + case NVME_NIDT_NGUID: + memcpy(n->nguid, desc->nid, sizeof(n->nguid)); + break; + case NVME_NIDT_UUID: + memcpy(n->uuid, desc->nid, sizeof(n->uuid)); + break; + } + } +} + static void nvme_ns_init(struct nvme_ns *n) { - struct nvme_id_ns ns = { 0 }; + struct nvme_id_ns ns = { }; + uint8_t buffer[NVME_IDENTIFY_DATA_SIZE] = { }; + struct nvme_ns_id_desc *descs = (void *)buffer; if (nvme_ns_identify(n, &ns) != 0) return; @@ -813,8 +868,10 @@ static void nvme_ns_init(struct nvme_ns *n) n->lba_size = 1 << n->lba_shift; n->lba_count = le64_to_cpu(ns.nsze); n->lba_util = le64_to_cpu(ns.nuse); -} + if (!nvme_ns_identify_descs(n, descs)) + nvme_ns_parse_descriptors(n, descs); +} nvme_ns_t nvme_ns_open(char *name) { diff --git a/src/nvme/tree.h b/src/nvme/tree.h index 6cce922447..b8e66fc4d7 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -15,6 +15,8 @@ #include +#include + #include "ioctl.h" #include "util.h" @@ -262,6 +264,31 @@ uint64_t nvme_ns_get_lba_count(nvme_ns_t n); */ uint64_t nvme_ns_get_lba_util(nvme_ns_t n); +/** + * nvme_ns_get_eui64() - + * @n: + * + * Returns a pointer to the 64-bit eui + */ +const uint8_t *nvme_ns_get_eui64(nvme_ns_t n); + +/** + * nvme_ns_get_nguid() - + * @n: + * + * Returns a pointer to the 128-bit nguid + */ +const uint8_t *nvme_ns_get_nguid(nvme_ns_t n); + +/** + * nvme_ns_get_uuid() - + * @n: + * @out: + * + * Copies the namespace's uuid to the destination buffer + */ +void nvme_ns_get_uuid(nvme_ns_t n, uuid_t out); + /** * nvme_ns_get_sysfs_dir() - * @n: @@ -374,6 +401,15 @@ int nvme_ns_flush(nvme_ns_t n); */ int nvme_ns_identify(nvme_ns_t n, struct nvme_id_ns *ns); +/** + * nvme_ns_identify_descs() - + * @n: + * @descs: + * + * Return: + */ +int nvme_ns_identify_descs(nvme_ns_t n, struct nvme_ns_id_desc *descs); + /** * nvme_path_get_name() - * @p: diff --git a/src/nvme/types.h b/src/nvme/types.h index b10737c961..31fe5faccf 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -22,6 +22,20 @@ #define __force #endif +/** + * NVME_GET() - extract field from complex value + * @name: The name of the sub-field within an nvme value + * @value: The original value of a complex field + * + * By convention, this library defines _SHIFT and _MASK such that mask can be + * applied after the shift to isolate a specific set of bits that decode to a + * sub-field. + * + * Returns: The 'name' field from 'value' + */ +#define NVME_GET(name, value) \ + (((value) >> NVME_##name##_SHIFT) & NVME_##name##_MASK) + /** * cpu_to_le16() - * @x: 16-bit CPU value to turn to little endian. @@ -82,11 +96,11 @@ static inline uint64_t le64_to_cpu(__le64 x) * namespaces * @NVME_NSID_NONE: The invalid namespace id, for when the nsid * parameter is not used in a command - * @NVME_UUID_NONE: Use to omit the uuid command parameter - * @NVME_CNTLID_NONE: Use to omit the cntlid command parameter - * @NVME_NVMSETID_NONE: Use to omit the nvmsetid command parameter - * @NVME_LOG_LSP_NONE: Use to omit the log lsp command parameter - * @NVME_LOG_LSI_NONE: Use to omit the log lsi command parameter + * @NVME_UUID_NONE: Use to omit a uuid command parameter + * @NVME_CNTLID_NONE: Use to omit a cntlid command parameter + * @NVME_NVMSETID_NONE: Use to omit a nvmsetid 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_IDENTIFY_DATA_SIZE: The transfer size for nvme identify commands * @NVME_ID_NVMSET_LIST_MAX: The largest possible nvmset index in identify * nvmeset @@ -105,9 +119,9 @@ static inline uint64_t le64_to_cpu(__le64 x) * @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 - * @NVME_NQN_LENGTH: Max length for NVMe Qualified Name. - * @NVMF_TRADDR_SIZE: - * @NVMF_TSAS_SIZE: + * @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 */ enum nvme_constants { NVME_NSID_ALL = 0xffffffff, @@ -131,8 +145,6 @@ enum nvme_constants { NVME_NQN_LENGTH = 256, NVMF_TRADDR_SIZE = 256, NVMF_TSAS_SIZE = 256, - NVME_NIDT_EUI64_LEN = 8, - NVME_NIDT_NGUID_LEN = 16, }; /** @@ -233,8 +245,7 @@ static inline __u64 nvme_mmio_read64(void *addr) return le32_to_cpu(*p) | ((uint64_t)le32_to_cpu(*(p + 1)) << 32); } -#define NVME_REG_VALUE(name, value) \ - (((value) >> NVME_##name##_SHIFT) & NVME_##name##_MASK) +#define NVME_REG_VALUE(name, value) NVME_GET(name, value) enum nvme_cap { NVME_CAP_MQES_SHIFT = 0, @@ -1894,27 +1905,32 @@ enum nvme_ns_id_desc_nidt { NVME_NIDT_UUID = 3, }; +enum nvme_ns_id_desc_nidt_lens { + NVME_NIDT_EUI64_LEN = 8, + NVME_NIDT_NGUID_LEN = 16, + NVME_NIDT_UUID_LEN = 16, +}; + /** * struct nvme_nvmset_attr - NVM Set Attributes Entry - * @id: NVM Set Identifier - * @endurance_group_id: Endurance Group Identifier - * @random_4k_read_typical: Random 4 KiB Read Typical indicates the typical - * time to complete a 4 KiB random read in 100 - * nanosecond units when the NVM Set is in a - * Predictable Latency Mode Deterministic Window and - * there is 1 outstanding command per NVM Set. - * @opt_write_size: - * @total_nvmset_cap: - * @unalloc_nvmset_cap: + * @nvmsetid: NVM Set Identifier + * @endgid: Endurance Group Identifier + * @rr4kt: Random 4 KiB Read Typical indicates the typical + * time to complete a 4 KiB random read in 100 nanosecond units + * when the NVM Set is in a Predictable Latency Mode Deterministic + * Window and there is 1 outstanding command per NVM Set. + * @ows: Optimal Write Size + * @tnvmsetcap: Total NVM Set Capacity + * @unvmsetcap: Unallocated NVM Set Capacity */ struct nvme_nvmset_attr { - __le16 id; - __le16 endurance_group_id; + __le16 nvmsetid; + __le16 endgid; __u8 rsvd4[4]; - __le32 random_4k_read_typical; - __le32 opt_write_size; - __u8 total_nvmset_cap[16]; - __u8 unalloc_nvmset_cap[16]; + __le32 rr4kt; + __le32 ows; + __u8 tnvmsetcap[16]; + __u8 unvmsetcap[16]; __u8 rsvd48[80]; }; @@ -1931,12 +1947,12 @@ struct nvme_id_nvmset_list { /** * struct nvme_id_ns_granularity_desc - - * @namespace_size_granularity: - * @namespace_capacity_granularity: + * @nszegran: + * @ncapgran: */ struct nvme_id_ns_granularity_desc { - __le64 namespace_size_granularity; - __le64 namespace_capacity_granularity; + __le64 nszegran; + __le64 ncapgran; }; /** @@ -2706,15 +2722,17 @@ struct nvme_sanitize_log_page { * @NVME_SANITIZE_SSTAT_STATUS_ND_COMPLETE_SUCCESS: */ enum nvme_sanitize_sstat { + NVME_SANITIZE_SSTAT_STATUS_SHIFT = 0, NVME_SANITIZE_SSTAT_STATUS_MASK = 0x7, NVME_SANITIZE_SSTAT_STATUS_NEVER_SANITIZED = 0, NVME_SANITIZE_SSTAT_STATUS_COMPLETE_SUCCESS = 1, NVME_SANITIZE_SSTAT_STATUS_IN_PROGESS = 2, NVME_SANITIZE_SSTAT_STATUS_COMPLETED_FAILED = 3, NVME_SANITIZE_SSTAT_STATUS_ND_COMPLETE_SUCCESS = 4, - NVME_SANITIZE_SSTAT_COMPLETED_PASSES_MASK = 0xf8, NVME_SANITIZE_SSTAT_COMPLETED_PASSES_SHIFT = 3, - NVME_SANITIZE_SSTAT_GLOBAL_DATA_ERASED = 1 << 8, + NVME_SANITIZE_SSTAT_COMPLETED_PASSES_MASK = 0x1f, + NVME_SANITIZE_SSTAT_GLOBAL_DATA_ERASED_SHIFT = 8, + NVME_SANITIZE_SSTAT_GLOBAL_DATA_ERASED_MASK = 0x1, }; /** @@ -2756,10 +2774,10 @@ struct nvme_feat_auto_pst { * enum nvme_apst_entry - */ enum nvme_apst_entry { - NVME_APST_ENTRY_ITPS_MASK = 0xf8, NVME_APST_ENTRY_ITPS_SHIFT = 3, - NVME_APST_ENTRY_ITPT_MASK = 0xffffff00, NVME_APST_ENTRY_ITPT_SHIFT = 8, + NVME_APST_ENTRY_ITPS_MASK = 0x1f, + NVME_APST_ENTRY_ITPT_MASK = 0xffffff, }; /** @@ -2896,7 +2914,7 @@ struct nvme_registered_ctrl_ext { }; /** - * struct nvme_reservation_status -{ + * struct nvme_resv_status -{ * @gen: * @rtype: * @regctl: @@ -2904,7 +2922,7 @@ struct nvme_registered_ctrl_ext { * @regctl_eds: * @regctl_ds: */ -struct nvme_reservation_status { +struct nvme_resv_status { __le32 gen; __u8 rtype; __u8 regctl[2]; diff --git a/test/Makefile b/test/Makefile index b5541aaf10..7766921946 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,5 +1,5 @@ CFLAGS ?= -g -O2 -override CFLAGS += -Wall -D_GNU_SOURCE -L../src/ -I../src/ +override CFLAGS += -Wall -D_GNU_SOURCE -L../src/ -I../src/ -luuid include ../Makefile.quiet diff --git a/test/test.c b/test/test.c index 8992554531..79919e170b 100644 --- a/test/test.c +++ b/test/test.c @@ -277,7 +277,7 @@ static int test_namespace(nvme_ns_t n) printf(" ERROR: Identify allocated ns:%x\n", ret); ret = nvme_identify_ns_descs(fd, nsid, &descs); if (!ret) - printf(" Identify NS Descriptorss\n"); + printf(" Identify NS Descriptors\n"); else printf(" ERROR: Identify NS Descriptors:%x\n", ret); ret = nvme_get_features_write_protect(fd, nsid, @@ -289,6 +289,14 @@ static int test_namespace(nvme_ns_t n) return 0; } +static void print_hex(const uint8_t *x, int len) +{ + int i; + + for (i = 0; i < len; i++) + printf("%02x", x[i]); +} + int main() { nvme_root_t r; @@ -338,10 +346,21 @@ int main() nvme_ctrl_get_address(c), nvme_ctrl_get_state(c)); - nvme_ctrl_for_each_ns(c, n) + nvme_ctrl_for_each_ns(c, n) { + char uuid_str[40]; + uuid_t uuid; + printf(" `- %s lba size:%d lba max:%lu\n", nvme_ns_get_name(n), nvme_ns_get_lba_size(n), nvme_ns_get_lba_count(n)); + printf(" eui:"); + print_hex(nvme_ns_get_eui64(n), 8); + printf(" nguid:"); + print_hex(nvme_ns_get_nguid(n), 16); + nvme_ns_get_uuid(n, uuid); + uuid_unparse_lower(uuid, uuid_str); + printf(" uuid:%s\n", uuid_str); + } nvme_ctrl_for_each_path(c, p) printf(" `- %s %s\n", nvme_path_get_name(p), From 5fca2499aa7342ab7b57067982e54822409c8561 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Fri, 29 May 2020 13:43:52 -0700 Subject: [PATCH 0050/1564] have tree export directly opening namespaces Signed-off-by: Keith Busch --- src/nvme/filters.c | 1 + src/nvme/tree.c | 40 +++++++++++++++++++--------------------- src/nvme/tree.h | 15 +++++++++------ 3 files changed, 29 insertions(+), 27 deletions(-) diff --git a/src/nvme/filters.c b/src/nvme/filters.c index 790ca64fbd..06137f5f1a 100644 --- a/src/nvme/filters.c +++ b/src/nvme/filters.c @@ -23,6 +23,7 @@ #include "util.h" const char *nvme_ctrl_sysfs_dir = "/sys/class/nvme"; +const char *nvme_ns_sysfs_dir = "/sys/block"; const char *nvme_subsys_sysfs_dir = "/sys/class/nvme-subsystem"; int nvme_namespace_filter(const struct dirent *d) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 620b74d8b5..835bb4396a 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -29,6 +29,13 @@ /* XXX: Make a place for private declarations */ extern int nvme_set_attr(const char *dir, const char *attr, const char *value); +void nvme_free_subsystem(struct nvme_subsystem *s); +int nvme_subsystem_scan_namespace(struct nvme_subsystem *s, char *name); +int nvme_scan_subsystem(struct nvme_root *r, char *name, nvme_scan_filter_t f); +int nvme_subsystem_scan_ctrl(struct nvme_subsystem *s, char *name); +int nvme_ctrl_scan_namespace(struct nvme_ctrl *c, char *name); +int nvme_ctrl_scan_path(struct nvme_ctrl *c, char *name); + struct nvme_path { struct list_node entry; struct list_node nentry; @@ -102,20 +109,6 @@ struct nvme_root { struct list_head subsystems; }; -void nvme_free_ctrl(struct nvme_ctrl *c); -void nvme_ctrl_free_ns(struct nvme_ns *n); -void nvme_subsystem_free_ns(struct nvme_ns *n); -void nvme_free_path(struct nvme_path *p); -void nvme_free_subsystem(struct nvme_subsystem *s); - -int nvme_scan_subsystem(struct nvme_root *t, char *name, nvme_scan_filter_t f); -int nvme_subsystem_scan_namespace(struct nvme_subsystem *s, char *name); -int nvme_subsystem_scan_ctrls(struct nvme_subsystem *s); -int nvme_subsystem_scan_ctrl(struct nvme_subsystem *s, char *name); - -int nvme_ctrl_scan_namespace(struct nvme_ctrl *c, char *name); -int nvme_ctrl_scan_path(struct nvme_ctrl *c, char *name); - static inline void nvme_free_dirents(struct dirent **d, int i) { while (i-- > 0) @@ -229,7 +222,7 @@ nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n) return n ? list_next(&s->namespaces, n, entry) : NULL; } -static void nvme_free_ns(struct nvme_ns *n) +void nvme_free_ns(struct nvme_ns *n) { list_del_init(&n->entry); close(n->fd); @@ -873,9 +866,8 @@ static void nvme_ns_init(struct nvme_ns *n) nvme_ns_parse_descriptors(n, descs); } -nvme_ns_t nvme_ns_open(char *name) +static nvme_ns_t nvme_ns_open(const char *name) { - char *b = basename(name); struct nvme_ns *n; n = calloc(1, sizeof(*n)); @@ -884,9 +876,8 @@ nvme_ns_t nvme_ns_open(char *name) return NULL; } - n->name = strdup(b); - n->fd = nvme_open(b); - + n->name = strdup(name); + n->fd = nvme_open(n->name); if (n->fd < 0) goto free_ns; @@ -895,6 +886,7 @@ nvme_ns_t nvme_ns_open(char *name) goto close_fd; list_head_init(&n->paths); + list_node_init(&n->entry); nvme_ns_init(n); return n; @@ -902,11 +894,12 @@ nvme_ns_t nvme_ns_open(char *name) close_fd: close(n->fd); free_ns: + free(n->name); free(n); return NULL; } -static struct nvme_ns *__nvme_scan_namespace(const char *sysfs_dir, char *name) +static struct nvme_ns *__nvme_scan_namespace(const char *sysfs_dir, const char *name) { struct nvme_ns *n; char *path; @@ -930,6 +923,11 @@ static struct nvme_ns *__nvme_scan_namespace(const char *sysfs_dir, char *name) return NULL; } +nvme_ns_t nvme_scan_namespace(const char *name) +{ + return __nvme_scan_namespace(nvme_ns_sysfs_dir, name); +} + int nvme_ctrl_scan_namespace(struct nvme_ctrl *c, char *name) { struct nvme_ns *n; diff --git a/src/nvme/tree.h b/src/nvme/tree.h index b8e66fc4d7..86ecdc42e7 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -22,6 +22,7 @@ extern const char *nvme_ctrl_sysfs_dir; extern const char *nvme_subsys_sysfs_dir; +extern const char *nvme_ns_sysfs_dir; /** * @@ -53,12 +54,6 @@ typedef struct nvme_root *nvme_root_t; */ typedef bool (*nvme_scan_filter_t)(nvme_subsystem_t); - -/** - * - */ -nvme_ns_t nvme_ns_open(char *name); - /** * nvme_first_subsystem() - * @r: @@ -321,6 +316,12 @@ nvme_subsystem_t nvme_ns_get_subsystem(nvme_ns_t n); */ nvme_ctrl_t nvme_ns_get_ctrl(nvme_ns_t n); +/** + * nvme_free_ns() - + * @ns: + */ +void nvme_free_ns(struct nvme_ns *n); + /** * nvme_ns_read() - * @n: @@ -700,4 +701,6 @@ char *nvme_get_ns_attr(nvme_ns_t n, const char *attr); */ char *nvme_get_path_attr(nvme_path_t p, const char *attr); +nvme_ns_t nvme_scan_namespace(const char *name); + #endif /* _LIBNVME_TREE_H */ From af59d4979e10b8378fbeb76efe73917464ca374d Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Mon, 1 Jun 2020 07:08:49 -0700 Subject: [PATCH 0051/1564] generic whitespace strip routine Printing routines have a need to strip white spaces too, so make this a common nvme lib routine. Signed-off-by: Keith Busch --- src/nvme/fabrics.c | 12 +++--------- src/nvme/util.h | 11 +++++++++++ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index bf0ae67547..52e05670d9 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -186,12 +186,6 @@ nvme_ctrl_t nvmf_add_ctrl(struct nvme_fabrics_config *cfg) return nvme_scan_ctrl(d); } -static void chomp(char *s, int l) -{ - while (l && (s[l] == '\0' || s[l] == ' ')) - s[l--] = '\0'; -} - nvme_ctrl_t nvmf_connect_disc_entry(struct nvmf_disc_log_entry *e, const struct nvme_fabrics_config *defcfg, bool *discover) @@ -218,8 +212,8 @@ nvme_ctrl_t nvmf_connect_disc_entry(struct nvmf_disc_log_entry *e, switch (e->adrfam) { case NVMF_ADDR_FAMILY_IP4: case NVMF_ADDR_FAMILY_IP6: - chomp(e->traddr, NVMF_TRADDR_SIZE); - chomp(e->trsvcid, NVMF_TRSVCID_SIZE); + nvme_chomp(e->traddr, NVMF_TRADDR_SIZE); + nvme_chomp(e->trsvcid, NVMF_TRSVCID_SIZE); cfg.traddr = e->traddr; cfg.trsvcid = e->trsvcid; break; @@ -231,7 +225,7 @@ nvme_ctrl_t nvmf_connect_disc_entry(struct nvmf_disc_log_entry *e, case NVMF_TRTYPE_FC: switch (e->adrfam) { case NVMF_ADDR_FAMILY_FC: - chomp(e->traddr, NVMF_TRADDR_SIZE), + nvme_chomp(e->traddr, NVMF_TRADDR_SIZE), cfg.traddr = e->traddr; cfg.trsvcid = NULL; break; diff --git a/src/nvme/util.h b/src/nvme/util.h index 88f99d9935..05629ccb52 100644 --- a/src/nvme/util.h +++ b/src/nvme/util.h @@ -226,4 +226,15 @@ int nvme_get_directive_receive_length(enum nvme_directive_dtype dtype, */ int nvme_open(const char *name); +/** + * nvme_chomp() - Strip trailing white space + * &s: String to strip + * @l: Maximum length of string + */ +static inline void nvme_chomp(char *s, int l) +{ + while (l && (s[l] == '\0' || s[l] == ' ')) + s[l--] = '\0'; +} + #endif /* _LIBNVME_UTIL_H */ From e806afa1c2ce05708d496824a7d3b5716f0043f5 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Mon, 1 Jun 2020 09:59:14 -0700 Subject: [PATCH 0052/1564] export metadata size Signed-off-by: Keith Busch --- src/nvme/tree.c | 10 +++++++++- src/nvme/tree.h | 8 ++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 835bb4396a..4ef455ea00 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -709,6 +709,11 @@ int nvme_ns_get_lba_size(nvme_ns_t n) return n->lba_size; } +int nvme_ns_get_meta_size(nvme_ns_t n) +{ + return n->meta_size; +} + uint64_t nvme_ns_get_lba_count(nvme_ns_t n) { return n->lba_count; @@ -853,14 +858,17 @@ static void nvme_ns_init(struct nvme_ns *n) struct nvme_id_ns ns = { }; uint8_t buffer[NVME_IDENTIFY_DATA_SIZE] = { }; struct nvme_ns_id_desc *descs = (void *)buffer; + int flbas; if (nvme_ns_identify(n, &ns) != 0) return; - n->lba_shift = ns.lbaf[ns.flbas & NVME_NS_FLBAS_LBA_MASK].ds; + flbas = ns.flbas & NVME_NS_FLBAS_LBA_MASK; + n->lba_shift = ns.lbaf[flbas].ds; n->lba_size = 1 << n->lba_shift; n->lba_count = le64_to_cpu(ns.nsze); n->lba_util = le64_to_cpu(ns.nuse); + n->meta_size = le16_to_cpu(ns.lbaf[flbas].ms); if (!nvme_ns_identify_descs(n, descs)) nvme_ns_parse_descriptors(n, descs); diff --git a/src/nvme/tree.h b/src/nvme/tree.h index 86ecdc42e7..40a43f97bb 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -243,6 +243,14 @@ int nvme_ns_get_nsid(nvme_ns_t n); */ int nvme_ns_get_lba_size(nvme_ns_t n); +/** + * nvme_ns_get_meta_size() - + * @n: + * + * Return: + */ +int nvme_ns_get_meta_size(nvme_ns_t n); + /** * nvme_ns_get_lba_count() - * @n: From a4c001a47663d0392d2cedfe33a8dec5654fc527 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Mon, 1 Jun 2020 20:11:41 -0700 Subject: [PATCH 0053/1564] zns and ns-types Signed-off-by: Keith Busch --- .gitignore | 1 + src/nvme/ioctl.c | 215 +++++++++++++++++++++++++++++++++++++++++------ src/nvme/ioctl.h | 195 +++++++++++++++++++++++++++++++++++++++++- src/nvme/tree.c | 9 ++ src/nvme/tree.h | 8 ++ src/nvme/types.h | 141 +++++++++++++++++++++++++++++++ src/nvme/util.c | 2 +- test/Makefile | 6 +- test/test.c | 4 +- test/zns.c | 80 ++++++++++++++++++ 10 files changed, 625 insertions(+), 36 deletions(-) create mode 100644 test/zns.c diff --git a/.gitignore b/.gitignore index ab78bf1ae2..cbf80394b6 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ libnvme.pc test/register test/test test/cpp +test/zns examples/display-tree examples/display-columnar diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 2c3a12163d..d2bb0727e5 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -233,6 +233,7 @@ enum nvme_cmd_dword_fields { NVME_LOG_CDW11_NUMDU_SHIFT = 0, NVME_LOG_CDW11_LSI_SHIFT = 16, NVME_LOG_CDW14_UUID_SHIFT = 0, + NVME_LOG_CDW14_CSI_SHIFT = 24, NVME_LOG_CDW10_LID_MASK = 0xff, NVME_LOG_CDW10_LSP_MASK = 0xf, NVME_LOG_CDW10_RAE_MASK = 0x1, @@ -240,14 +241,17 @@ enum nvme_cmd_dword_fields { NVME_LOG_CDW11_NUMDU_MASK = 0xff, NVME_LOG_CDW11_LSI_MASK = 0xff, NVME_LOG_CDW14_UUID_MASK = 0x7f, + NVME_LOG_CDW14_CSI_MASK = 0xff, NVME_IDENTIFY_CDW10_CNS_SHIFT = 0, NVME_IDENTIFY_CDW10_CNTID_SHIFT = 16, NVME_IDENTIFY_CDW11_NVMSETID_SHIFT = 0, NVME_IDENTIFY_CDW14_UUID_SHIFT = 0, + NVME_IDENTIFY_CDW11_CSI_SHIFT = 24, NVME_IDENTIFY_CDW10_CNS_MASK = 0xff, NVME_IDENTIFY_CDW10_CNTID_MASK = 0xffff, NVME_IDENTIFY_CDW11_NVMSETID_MASK = 0xffff, NVME_IDENTIFY_CDW14_UUID_MASK = 0x7f, + NVME_IDENTIFY_CDW11_CSI_MASK = 0xff, NVME_NAMESPACE_ATTACH_CDW10_SEL_SHIFT = 0, NVME_NAMESPACE_ATTACH_CDW10_SEL_MASK = 0xf, NVME_NAMESPACE_MGMT_CDW10_SEL_SHIFT = 0, @@ -292,6 +296,16 @@ enum nvme_cmd_dword_fields { NVME_GET_LBA_STATUS_CDW13_ATYPE_SHIFT = 24, NVME_GET_LBA_STATUS_CDW13_RL_MASK = 0xffff, NVME_GET_LBA_STATUS_CDW13_ATYPE_MASK = 0xff, + NVME_ZNS_MGMT_SEND_SEL_SHIFT = 8, + NVME_ZNS_MGMT_SEND_SEL_MASK = 0x1, + NVME_ZNS_MGMT_SEND_ZSA_SHIFT = 0, + NVME_ZNS_MGMT_SEND_ZSA_MASK = 0xff, + NVME_ZNS_MGMT_RECV_ZRA_SHIFT = 0, + NVME_ZNS_MGMT_RECV_ZRA_MASK = 0xff, + NVME_ZNS_MGMT_RECV_ZRASF_SHIFT = 8, + NVME_ZNS_MGMT_RECV_ZRASF_MASK = 0xff, + NVME_ZNS_MGMT_RECV_ZRAS_FEAT_SHIFT = 16, + NVME_ZNS_MGMT_RECV_ZRAS_FEAT_MASK = 0x1, }; enum features { @@ -345,16 +359,19 @@ enum features { NVME_FEATURES_LBAS_LSIPI_SHIFT = 16, NVME_FEATURES_LBAS_LSIRI_MASK = 0xffff, NVME_FEATURES_LBAS_LSIPI_MASK = 0xffff, + NVME_FEATURES_IOCSP_IOCSCI_SHIFT = 0, + NVME_FEATURES_IOCSP_IOCSCI_MASK = 0xff, }; #define DW(value, prefix) ((value) & (prefix ## _MASK)) << prefix ## _SHIFT int nvme_identify(int fd, enum nvme_identify_cns cns, __u32 nsid, __u16 cntid, - __u16 nvmsetid, __u8 uuidx, void *data) + __u16 nvmsetid, __u8 uuidx, __u8 csi, void *data) { __u32 cdw10 = DW(cntid, NVME_IDENTIFY_CDW10_CNTID) | DW(cns, NVME_IDENTIFY_CDW10_CNS); - __u32 cdw11 = DW(nvmsetid, NVME_IDENTIFY_CDW11_NVMSETID); + __u32 cdw11 = DW(nvmsetid, NVME_IDENTIFY_CDW11_NVMSETID) | + DW(csi, NVME_IDENTIFY_CDW11_CSI); __u32 cdw14 = DW(uuidx, NVME_IDENTIFY_CDW14_UUID); struct nvme_passthru_cmd cmd = { @@ -373,7 +390,8 @@ int nvme_identify(int fd, enum nvme_identify_cns cns, __u32 nsid, __u16 cntid, static int __nvme_identify(int fd, __u8 cns, __u32 nsid, void *data) { return nvme_identify(fd, cns, nsid, NVME_CNTLID_NONE, - NVME_NVMSETID_NONE, NVME_UUID_NONE, data); + NVME_NVMSETID_NONE, NVME_UUID_NONE, NVME_CSI_NVM, + data); } int nvme_identify_ctrl(int fd, struct nvme_id_ctrl *id) @@ -413,7 +431,7 @@ int nvme_identify_ctrl_list(int fd, __u16 cntid, BUILD_ASSERT(sizeof(struct nvme_ctrl_list) == 4096); return nvme_identify(fd, NVME_IDENTIFY_CNS_CTRL_LIST, NVME_NSID_NONE, cntid, NVME_NVMSETID_NONE, - NVME_UUID_NONE, ctrlist); + NVME_UUID_NONE, NVME_CSI_NVM, ctrlist); } int nvme_identify_nsid_ctrl_list(int fd, __u32 nsid, __u16 cntid, @@ -421,7 +439,7 @@ int nvme_identify_nsid_ctrl_list(int fd, __u32 nsid, __u16 cntid, { return nvme_identify(fd, NVME_IDENTIFY_CNS_NS_CTRL_LIST, nsid, cntid, NVME_NVMSETID_NONE, NVME_UUID_NONE, - ctrlist); + NVME_CSI_NVM, ctrlist); } int nvme_identify_ns_descs(int fd, __u32 nsid, struct nvme_ns_id_desc *descs) @@ -435,7 +453,7 @@ int nvme_identify_nvmset_list(int fd, __u16 nvmsetid, BUILD_ASSERT(sizeof(struct nvme_id_nvmset_list) == 4096); return nvme_identify(fd, NVME_IDENTIFY_CNS_NVMSET_LIST, NVME_NSID_NONE, NVME_CNTLID_NONE, nvmsetid, - NVME_UUID_NONE, nvmset); + NVME_UUID_NONE, NVME_CSI_NVM, nvmset); } int nvme_identify_primary_ctrl(int fd, __u16 cntid, @@ -444,7 +462,7 @@ int nvme_identify_primary_ctrl(int fd, __u16 cntid, BUILD_ASSERT(sizeof(struct nvme_primary_ctrl_cap) == 4096); return nvme_identify(fd, NVME_IDENTIFY_CNS_PRIMARY_CTRL_CAP, NVME_NSID_NONE, cntid, NVME_NVMSETID_NONE, - NVME_UUID_NONE, cap); + NVME_UUID_NONE, NVME_CSI_NVM, cap); } int nvme_identify_secondary_ctrl_list(int fd, __u16 cntid, @@ -453,7 +471,7 @@ int nvme_identify_secondary_ctrl_list(int fd, __u16 cntid, BUILD_ASSERT(sizeof(struct nvme_secondary_ctrl_list) == 4096); return nvme_identify(fd, NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST, NVME_NSID_NONE, cntid, NVME_NVMSETID_NONE, - NVME_UUID_NONE, list); + NVME_UUID_NONE, NVME_CSI_NVM, list); } int nvme_identify_ns_granularity(int fd, @@ -471,8 +489,47 @@ int nvme_identify_uuid(int fd, struct nvme_id_uuid_list *list) list); } +int nvme_identify_ctrl_csi(int fd, __u8 csi, void *data) +{ + return nvme_identify(fd, NVME_IDENTIFY_CNS_CSI_CTRL, NVME_NSID_NONE, + NVME_CNTLID_NONE, NVME_NVMSETID_NONE, + NVME_UUID_NONE, csi, data); +} + +int nvme_identify_ns_csi(int fd, __u32 nsid, __u8 csi, void *data) +{ + return nvme_identify(fd, NVME_IDENTIFY_CNS_CSI_NS, nsid, + NVME_CNTLID_NONE, NVME_NVMSETID_NONE, + NVME_UUID_NONE, csi, data); +} + +int nvme_identify_iocs(int fd, struct nvme_id_iocs *iocs) +{ + BUILD_ASSERT(sizeof(struct nvme_id_iocs) == 4096); + return nvme_identify(fd, NVME_IDENTIFY_CNS_CSI_CTRL, NVME_NSID_NONE, + NVME_CNTLID_NONE, NVME_NVMSETID_NONE, + NVME_UUID_NONE, NVME_CSI_NVM, iocs); +} + +int nvme_zns_identify_ns(int fd, __u32 nsid, struct nvme_zns_id_ns *data) +{ + BUILD_ASSERT(sizeof(struct nvme_zns_id_ns) == 4096); + return nvme_identify(fd, NVME_IDENTIFY_CNS_CSI_NS, nsid, + NVME_CNTLID_NONE, NVME_NVMSETID_NONE, + NVME_UUID_NONE, NVME_CSI_ZNS, data); +} + +int nvme_zns_identify_ctrl(int fd, struct nvme_zns_id_ctrl *data) +{ + BUILD_ASSERT(sizeof(struct nvme_zns_id_ctrl) == 4096); + return nvme_identify(fd, NVME_IDENTIFY_CNS_CSI_CTRL, NVME_NSID_NONE, + NVME_CNTLID_NONE, NVME_NVMSETID_NONE, + NVME_UUID_NONE, NVME_CSI_ZNS, data); +} + int nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, - __u8 lsp, __u16 lsi, bool rae, __u8 uuidx, __u32 len, void *log) + __u8 lsp, __u16 lsi, bool rae, __u8 uuidx, enum nvme_csi csi, + __u32 len, void *log) { __u32 numd = (len >> 2) - 1; __u16 numdu = numd >> 16, numdl = numd & 0xffff; @@ -485,7 +542,8 @@ int nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, DW(lsi, NVME_LOG_CDW11_LSI); __u32 cdw12 = lpo & 0xffffffff; __u32 cdw13 = lpo >> 32; - __u32 cdw14 = DW(uuidx, NVME_LOG_CDW14_UUID); + __u32 cdw14 = DW(uuidx, NVME_LOG_CDW14_UUID) | + DW(csi, NVME_LOG_CDW14_CSI); struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_get_log_page, @@ -506,7 +564,8 @@ static int __nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, bool rae, __u32 len, void *log) { return nvme_get_log(fd, lid, NVME_NSID_ALL, 0, NVME_LOG_LSP_NONE, - NVME_LOG_LSI_NONE, NVME_UUID_NONE, rae, len, log); + NVME_LOG_LSI_NONE, NVME_UUID_NONE, NVME_CSI_NVM, + rae, len, log); } int nvme_get_log_error(int fd, unsigned nr_entries, bool rae, @@ -522,7 +581,7 @@ int nvme_get_log_smart(int fd, __u32 nsid, bool rae, struct nvme_smart_log *log) BUILD_ASSERT(sizeof(struct nvme_smart_log) == 512); return nvme_get_log(fd, NVME_LOG_LID_SMART, nsid, 0, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, - NVME_UUID_NONE, sizeof(*log), log); + NVME_UUID_NONE, NVME_CSI_NVM, sizeof(*log), log); } int nvme_get_log_fw_slot(int fd, bool rae, struct nvme_firmware_slot *log) @@ -538,11 +597,14 @@ int nvme_get_log_changed_ns_list(int fd, bool rae, struct nvme_ns_list *log) sizeof(*log), log); } -int nvme_get_log_cmd_effects(int fd, struct nvme_cmd_effects_log *log) +int nvme_get_log_cmd_effects(int fd, enum nvme_csi csi, + struct nvme_cmd_effects_log *log) { BUILD_ASSERT(sizeof(struct nvme_cmd_effects_log) == 4096); - return __nvme_get_log(fd, NVME_LOG_LID_CMD_EFFECTS, false, - sizeof(*log), log); + return nvme_get_log(fd, NVME_LOG_LID_CMD_EFFECTS, NVME_NSID_ALL, 0, + NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, + NVME_UUID_NONE, csi, false, sizeof(*log), + log); } int nvme_get_log_device_self_test(int fd, struct nvme_self_test_log *log) @@ -562,15 +624,16 @@ int nvme_get_log_create_telemetry_host(int fd, struct nvme_telemetry_log *log) BUILD_ASSERT(sizeof(struct nvme_telemetry_log) == 512); return nvme_get_log(fd, NVME_LOG_LID_TELEMETRY_HOST, NVME_NSID_NONE, 0, NVME_LOG_TELEM_HOST_LSP_CREATE, NVME_LOG_LSI_NONE, - false, NVME_UUID_NONE, sizeof(*log), log); + false, NVME_UUID_NONE, NVME_CSI_NVM, sizeof(*log), + log); } int nvme_get_log_telemetry_host(int fd, __u64 offset, __u32 len, void *log) { return nvme_get_log(fd, NVME_LOG_LID_TELEMETRY_HOST, NVME_NSID_NONE, offset, NVME_LOG_TELEM_HOST_LSP_RETAIN, - NVME_LOG_LSI_NONE, - false, NVME_UUID_NONE, len, log); + NVME_LOG_LSI_NONE, false, NVME_UUID_NONE, + NVME_CSI_NVM, len, log); } int nvme_get_log_telemetry_ctrl(int fd, bool rae, __u64 offset, __u32 len, @@ -578,7 +641,7 @@ int nvme_get_log_telemetry_ctrl(int fd, bool rae, __u64 offset, __u32 len, { return nvme_get_log(fd, NVME_LOG_LID_TELEMETRY_CTRL, NVME_NSID_NONE, offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, - NVME_UUID_NONE, len, log); + NVME_UUID_NONE, NVME_CSI_NVM, len, log); } int nvme_get_log_endurance_group(int fd, __u16 endgid, @@ -587,7 +650,7 @@ int nvme_get_log_endurance_group(int fd, __u16 endgid, BUILD_ASSERT(sizeof(struct nvme_endurance_group_log) == 512); return nvme_get_log(fd, NVME_LOG_LID_ENDURANCE_GROUP, NVME_NSID_NONE, 0, NVME_LOG_LSP_NONE, endgid, false, NVME_UUID_NONE, - sizeof(*log), log); + NVME_CSI_NVM, sizeof(*log), log); } int nvme_get_log_predictable_lat_nvmset(int fd, __u16 nvmsetid, @@ -596,7 +659,8 @@ int nvme_get_log_predictable_lat_nvmset(int fd, __u16 nvmsetid, BUILD_ASSERT(sizeof(struct nvme_nvmset_predictable_lat_log) == 512); return nvme_get_log(fd, NVME_LOG_LID_PREDICTABLE_LAT_NVMSET, NVME_NSID_NONE, 0, NVME_LOG_LSP_NONE, nvmsetid, - false, NVME_UUID_NONE, sizeof(*log), log); + false, NVME_UUID_NONE, NVME_CSI_NVM, sizeof(*log), + log); } int nvme_get_log_predictable_lat_event(int fd, bool rae, __u32 offset, @@ -604,7 +668,7 @@ int nvme_get_log_predictable_lat_event(int fd, bool rae, __u32 offset, { return nvme_get_log(fd, NVME_LOG_LID_PREDICTABLE_LAT_AGG, NVME_NSID_NONE, offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, - rae, NVME_UUID_NONE, len, log); + rae, NVME_UUID_NONE, NVME_CSI_NVM, len, log); } int nvme_get_log_ana(int fd, enum nvme_log_ana_lsp lsp, bool rae, __u64 offset, @@ -612,7 +676,7 @@ int nvme_get_log_ana(int fd, enum nvme_log_ana_lsp lsp, bool rae, __u64 offset, { return nvme_get_log(fd, NVME_LOG_LID_ANA, NVME_NSID_NONE, offset, lsp,NVME_LOG_LSI_NONE, false, NVME_UUID_NONE, - len, log); + NVME_CSI_NVM, len, log); } int nvme_get_log_ana_groups(int fd, bool rae, __u32 len, @@ -627,7 +691,7 @@ int nvme_get_log_lba_status(int fd, bool rae, __u64 offset, __u32 len, { return nvme_get_log(fd, NVME_LOG_LID_LBA_STATUS, NVME_NSID_NONE, offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, - NVME_UUID_NONE, len, log); + NVME_UUID_NONE, NVME_CSI_NVM, len, log); } int nvme_get_log_endurance_grp_evt(int fd, bool rae, __u32 offset, __u32 len, @@ -635,14 +699,15 @@ int nvme_get_log_endurance_grp_evt(int fd, bool rae, __u32 offset, __u32 len, { return nvme_get_log(fd, NVME_LOG_LID_ENDURANCE_GRP_EVT, NVME_NSID_NONE, offset, NVME_LOG_LSP_NONE, - NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, len, log); + NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, + NVME_CSI_NVM, len, log); } int nvme_get_log_discovery(int fd, bool rae, __u32 offset, __u32 len, void *log) { return nvme_get_log(fd, NVME_LOG_LID_DISCOVER, NVME_NSID_NONE, offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, - NVME_UUID_NONE, len, log); + NVME_UUID_NONE, NVME_CSI_NVM, len, log); } int nvme_get_log_reservation(int fd, bool rae, @@ -661,6 +726,15 @@ int nvme_get_log_sanitize(int fd, bool rae, log); } +int nvme_get_log_zns_changed_zones(int fd, __u32 nsid, bool rae, + struct nvme_zns_changed_zone_log *log) +{ + BUILD_ASSERT(sizeof(struct nvme_zns_changed_zone_log) == 4096); + return nvme_get_log(fd, NVME_LOG_LID_ZNS_CHANGED_ZONES, nsid, 0, + NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, + NVME_UUID_NONE, NVME_CSI_ZNS, sizeof(*log), log); +} + int nvme_set_features(int fd, __u8 fid, __u32 nsid, __u32 cdw11, __u32 cdw12, bool save, __u8 uuidx, __u32 cdw15, __u32 data_len, void *data, __u32 *result) @@ -915,6 +989,14 @@ int nvme_set_features_write_protect(int fd, enum nvme_feat_nswpcfg_state state, save, result); } +int nvme_set_features_iocs_profile(int fd, __u8 iocsi, bool save) +{ + __u32 value = DW(iocsi, NVME_FEATURES_IOCSP_IOCSCI); + + return __nvme_set_features(fd, NVME_FEAT_FID_IOCS_PROFILE, value, + save, NULL); +} + int nvme_get_features(int fd, enum nvme_features_id fid, __u32 nsid, enum nvme_get_features_sel sel, __u32 cdw11, __u8 uuidx, __u32 data_len, void *data, __u32 *result) @@ -1133,6 +1215,12 @@ int nvme_get_features_write_protect(int fd, __u32 nsid, NVME_UUID_NONE, 0, NULL, result); } +int nvme_get_features_iocs_profile(int fd, enum nvme_get_features_sel sel, + __u32 *result) +{ + return __nvme_get_features(fd, NVME_FEAT_FID_IOCS_PROFILE, sel, result); +} + int nvme_format_nvm(int fd, __u32 nsid, __u8 lbaf, enum nvme_cmd_format_mset mset, enum nvme_cmd_format_pi pi, enum nvme_cmd_format_pil pil, enum nvme_cmd_format_ses ses, @@ -1713,3 +1801,78 @@ int nvme_resv_report(int fd, __u32 nsid, bool eds, __u32 len, return nvme_submit_io_passthru(fd, &cmd, NULL); } + +int nvme_zns_mgmt_send(int fd, __u32 nsid, __u64 slba, bool select_all, + enum nvme_zns_send_action zsa, __u32 data_len, + void *data) +{ + __u32 cdw10 = slba & 0xffffffff; + __u32 cdw11 = slba >> 32; + __u32 cdw13 = DW(!!select_all, NVME_ZNS_MGMT_SEND_SEL) | + DW(zsa, NVME_ZNS_MGMT_SEND_ZSA); + + struct nvme_passthru_cmd cmd = { + .opcode = nvme_zns_cmd_mgmt_send, + .nsid = nsid, + .cdw10 = cdw10, + .cdw11 = cdw11, + .cdw13 = cdw13, + .addr = (__u64)(uintptr_t)data, + .data_len = data_len, + }; + + return nvme_submit_io_passthru(fd, &cmd, NULL); +} + +int nvme_zns_mgmt_recv(int fd, __u32 nsid, __u64 slba, + enum nvme_zns_recv_action zra, __u16 zrasf, + bool zras_feat, __u32 data_len, void *data) +{ + __u32 cdw10 = slba & 0xffffffff; + __u32 cdw11 = slba >> 32; + __u32 cdw12 = (data_len >> 2) - 1; + __u32 cdw13 = DW(zra , NVME_ZNS_MGMT_RECV_ZRA) | + DW(zrasf, NVME_ZNS_MGMT_RECV_ZRASF) | + DW(zras_feat, NVME_ZNS_MGMT_RECV_ZRAS_FEAT); + + struct nvme_passthru_cmd cmd = { + .opcode = nvme_zns_cmd_mgmt_send, + .nsid = nsid, + .cdw10 = cdw10, + .cdw11 = cdw11, + .cdw12 = cdw12, + .cdw13 = cdw13, + .addr = (__u64)(uintptr_t)data, + .data_len = data_len, + }; + + return nvme_submit_io_passthru(fd, &cmd, NULL); +} + +int nvme_zns_append(int fd, __u32 nsid, __u64 zslba, __u16 nlb, __u16 control, + __u32 ilbrt, __u16 lbat, __u16 lbatm, __u32 data_len, + void *data, __u32 metadata_len, void *metadata, + __u64 *result) +{ + __u32 cdw10 = zslba & 0xffffffff; + __u32 cdw11 = zslba >> 32; + __u32 cdw12 = nlb | (control << 16); + __u32 cdw14 = ilbrt; + __u32 cdw15 = lbat | (lbatm << 16); + + struct nvme_passthru_cmd64 cmd = { + .opcode = nvme_zns_cmd_append, + .nsid = nsid, + .cdw10 = cdw10, + .cdw11 = cdw11, + .cdw12 = cdw12, + .cdw14 = cdw14, + .cdw15 = cdw15, + .metadata = (__u64)(uintptr_t)metadata, + .addr = (__u64)(uintptr_t)data, + .metadata_len = metadata_len, + .data_len = data_len, + }; + + return nvme_submit_io_passthru64(fd, &cmd, result); +} diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 77ad9a3631..d1ebc68711 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -435,6 +435,8 @@ enum nvme_admin_opcode { * @NVME_IDENTIFY_CNS_NS_ACTIVE_LIST: * @NVME_IDENTIFY_CNS_NS_DESC_LIST: * @NVME_IDENTIFY_CNS_NVMSET_LIST: + * @NVME_IDENTIFY_CNS_CSI_NS: + * @NVME_IDENTIFY_CNS_CSI_CTRL: * @NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST: * @NVME_IDENTIFY_CNS_ALLOCATED_NS: * @NVME_IDENTIFY_CNS_NS_CTRL_LIST: @@ -443,6 +445,7 @@ enum nvme_admin_opcode { * @NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST: * @NVME_IDENTIFY_CNS_NS_GRANULARITY: * @NVME_IDENTIFY_CNS_UUID_LIST: + * @NVME_IDENTIFY_CNS_CSI_ALLOCATED_NS: */ enum nvme_identify_cns { NVME_IDENTIFY_CNS_NS = 0x00, @@ -450,6 +453,8 @@ enum nvme_identify_cns { NVME_IDENTIFY_CNS_NS_ACTIVE_LIST = 0x02, NVME_IDENTIFY_CNS_NS_DESC_LIST = 0x03, NVME_IDENTIFY_CNS_NVMSET_LIST = 0x04, + NVME_IDENTIFY_CNS_CSI_NS = 0x05, /* XXX: Placeholder until assigned */ + NVME_IDENTIFY_CNS_CSI_CTRL = 0x06, /* XXX: Placeholder until assigned */ NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST = 0x10, NVME_IDENTIFY_CNS_ALLOCATED_NS = 0x11, NVME_IDENTIFY_CNS_NS_CTRL_LIST = 0x12, @@ -458,6 +463,7 @@ enum nvme_identify_cns { NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST = 0x15, NVME_IDENTIFY_CNS_NS_GRANULARITY = 0x16, NVME_IDENTIFY_CNS_UUID_LIST = 0x17, + NVME_IDENTIFY_CNS_CSI_ALLOCATED_NS = 0x18, /* XXX: Placeholder until assigned */ }; /** @@ -480,6 +486,7 @@ enum nvme_identify_cns { * @NVME_LOG_LID_DISCOVER: * @NVME_LOG_LID_RESERVATION: * @NVME_LOG_LID_SANITIZE: + * @NVME_LOG_LID_ZNS_CHANGED_ZONES: */ enum nvme_cmd_get_log_lid { NVME_LOG_LID_ERROR = 0x01, @@ -500,6 +507,7 @@ enum nvme_cmd_get_log_lid { NVME_LOG_LID_DISCOVER = 0x70, NVME_LOG_LID_RESERVATION = 0x80, NVME_LOG_LID_SANITIZE = 0x81, + NVME_LOG_LID_ZNS_CHANGED_ZONES = 0xbf, }; /** @@ -528,6 +536,7 @@ enum nvme_cmd_get_log_lid { * @NVME_FEAT_FID_HOST_BEHAVIOR: * @NVME_FEAT_FID_SANITIZE: * @NVME_FEAT_FID_ENDURANCE_EVT_CFG: + * @NVME_FEAT_FID_IOCS_PROFILE: * @NVME_FEAT_FID_SW_PROGRESS: * @NVME_FEAT_FID_HOST_ID: * @NVME_FEAT_FID_RESV_MASK: @@ -559,6 +568,7 @@ enum nvme_features_id { NVME_FEAT_FID_HOST_BEHAVIOR = 0x16, NVME_FEAT_FID_SANITIZE = 0x17, NVME_FEAT_FID_ENDURANCE_EVT_CFG = 0x18, + NVME_FEAT_FID_IOCS_PROFILE = 0x19, /* XXX: Placeholder until assigned */ NVME_FEAT_FID_SW_PROGRESS = 0x80, NVME_FEAT_FID_HOST_ID = 0x81, NVME_FEAT_FID_RESV_MASK = 0x82, @@ -767,6 +777,7 @@ enum nvme_virt_mgmt_rt { * @cntid: The Controller Identifier, if applicable * @nvmsetid: The NVMe Set ID if CNS is 04h * @uuidx: UUID Index if controller supports this id selection method + * @csi: Command Set Identifier * @data: User space destination address to transfer the data * * The Identify command returns a data buffer that describes information about @@ -776,7 +787,8 @@ enum nvme_virt_mgmt_rt { * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify(int fd, enum nvme_identify_cns cns, __u32 nsid, - __u16 cntid, __u16 nvmsetid, __u8 uuidx, void *data); + __u16 cntid, __u16 nvmsetid, __u8 uuidx, __u8 csi, + void *data); /** * nvme_identify_ctrl() - Retrieves nvme identify controller @@ -1004,6 +1016,63 @@ int nvme_identify_ns_granularity(int fd, struct nvme_id_ns_granularity_list *lis */ int nvme_identify_uuid(int fd, struct nvme_id_uuid_list *list); +/** + * nvme_identify_ns_csi() - + * @fd: File descriptor of nvme device + * @nsid: Namespace to identify + * @csi: Command Set Identifier + * @data: User space destination address to transfer the data + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_identify_ns_csi(int fd, __u32 nsid, __u8 csi, void *data); + +/** + * nvme_identify_ctrl_csi() - + * @fd: File descriptor of nvme device + * @csi: Command Set Identifier + * @data: User space destination address to transfer the data + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_identify_ctrl_csi(int fd, __u8 csi, void *data); + +/** + * nvme_identify_iocs() - + * @fd: File descriptor of nvme device + * @iocs: User space destination address to transfer the data + * + * Retrieves list of the controller's supported io command set vectors. See + * @struct nvme_id_iocs. + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_identify_iocs(int fd, struct nvme_id_iocs *iocs); + +/** + * nvme_zns_identify_ns() - + * @fd: File descriptor of nvme device + * @nsid: Namespace to identify + * @data: User space destination address to transfer the data + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_zns_identify_ns(int fd, __u32 nsid, struct nvme_zns_id_ns *data); + +/** + * nvme_zns_identify_ctrl() - + * @fd: File descriptor of nvme device + * @data: User space destination address to transfer the data + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_zns_identify_ctrl(int fd, struct nvme_zns_id_ctrl *data); + /** * nvme_get_log() - NVMe Admin Get Log command * @fd: File descriptor of nvme device @@ -1022,7 +1091,8 @@ int nvme_identify_uuid(int fd, struct nvme_id_uuid_list *list); * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, - __u8 lsp, __u16 lsi, bool rae, __u8 uuidx, __u32 len, void *log); + __u8 lsp, __u16 lsi, bool rae, __u8 uuidx, enum nvme_csi csi, + __u32 len, void *log); /** * nvme_get_log_error() - Retrieve nvme error log @@ -1093,6 +1163,7 @@ int nvme_get_log_changed_ns_list(int fd, bool rae, struct nvme_ns_list *log); /** * nvme_get_log_cmd_effects() - Retrieve nvme command effects log * @fd: File descriptor of nvme device + * @csi: Command Set Identifier * @effects_log:User address to store the effects log * * This log page describes the commands that the controller supports and the @@ -1101,7 +1172,8 @@ int nvme_get_log_changed_ns_list(int fd, bool rae, struct nvme_ns_list *log); * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_get_log_cmd_effects(int fd, struct nvme_cmd_effects_log *log); +int nvme_get_log_cmd_effects(int fd, enum nvme_csi csi, + struct nvme_cmd_effects_log *log); /** * nvme_get_log_device_self_test() - Retrieve the device self test log @@ -1282,6 +1354,21 @@ int nvme_get_log_reservation(int fd, bool rae, int nvme_get_log_sanitize(int fd, bool rae, struct nvme_sanitize_log_page *log); +/** + * nvme_get_log_zns_changed_zones() - + * @fd: File descriptor of nvme device + * @nsid: Namespace ID + * @rae: Retain asynchronous events + * @log: User address to store the changed zone log + * + * The list of zones that have changed state due to an exceptional event. + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_get_log_zns_changed_zones(int fd, __u32 nsid, bool rae, + struct nvme_zns_changed_zone_log *log); + /** * nvme_set_features() - Set a feature attribute * @fd: File descriptor of nvme device @@ -1680,6 +1767,17 @@ enum nvme_feat_nswpcfg_state { int nvme_set_features_write_protect(int fd, enum nvme_feat_nswpcfg_state state, bool save, __u32 *result); +/** + * nvme_set_features_iocs_profile() - + * @fd: File descriptor of nvme device + * @iocsi: IO Command Set Combination Index + * @save: Save value across power states + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_set_features_iocs_profile(int fd, __u8 iocsi, bool save); + /** * nvme_get_features() - Retrieve a feature attribute * @fd: File descriptor of nvme device @@ -1735,7 +1833,6 @@ int nvme_get_features_power_mgmt(int fd, enum nvme_get_features_sel sel, int nvme_get_features_lba_range(int fd, enum nvme_get_features_sel sel, struct nvme_lba_range_type *data, __u32 *result); - /** * nvme_get_features_temp_thresh() - * @fd: File descriptor of nvme device @@ -2048,6 +2145,17 @@ int nvme_get_features_write_protect(int fd, __u32 nsid, enum nvme_get_features_sel sel, __u32 *result); +/** + * nvme_get_features_iocs_profile() - + * @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 + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_get_features_iocs_profile(int fd, enum nvme_get_features_sel sel, + __u32 *result); /** * nvme_format_nvm() - Format nvme namespace(s) @@ -2523,6 +2631,9 @@ enum nvme_io_opcode { nvme_cmd_resv_report = 0x0e, nvme_cmd_resv_acquire = 0x11, nvme_cmd_resv_release = 0x15, + nvme_zns_cmd_mgmt_send = 0x79, + nvme_zns_cmd_mgmt_recv = 0x7a, + nvme_zns_cmd_append = 0x7d, }; /** @@ -2542,6 +2653,7 @@ int nvme_flush(int fd, __u32 nsid); * enum nvme_io_control_flags - * @NVME_IO_DTYPE_STREAMS: * @NVME_IO_DEAC: + * @NVME_IO_ZNS_APPEND_PIREMAP: * @NVME_IO_PRINFO_PRCHK_REF: * @NVME_IO_PRINFO_PRCHK_APP: * @NVME_IO_PRINFO_PRCHK_GUARD: @@ -2552,6 +2664,7 @@ int nvme_flush(int fd, __u32 nsid); enum nvme_io_control_flags { NVME_IO_DTYPE_STREAMS = 1 << 4, NVME_IO_DEAC = 1 << 9, + NVME_IO_ZNS_APPEND_PIREMAP = 1 << 9, NVME_IO_PRINFO_PRCHK_REF = 1 << 10, NVME_IO_PRINFO_PRCHK_APP = 1 << 11, NVME_IO_PRINFO_PRCHK_GUARD = 1 << 12, @@ -2928,4 +3041,78 @@ int nvme_resv_release(int fd, __u32 nsid, enum nvme_resv_rtype rtype, */ int nvme_resv_report(int fd, __u32 nsid, bool eds, __u32 len, struct nvme_resv_status *report); + +enum nvme_zns_send_action { + NVME_ZNS_ZSA_CLOSE = 0x1, + NVME_ZNS_ZSA_FINISH = 0x2, + NVME_ZNS_ZSA_OPEN = 0x3, + NVME_ZNS_ZSA_RESET = 0x4, + NVME_ZNS_ZSA_OFFLINE = 0x5, + NVME_ZNS_ZSA_SET_DESC_EXT = 0x10, +}; + +/** + * nvme_zns_mgmt_send() - + * @fd: File descriptor of nvme device + * @nsid: Namespace ID + * @slba: + * @select_all: + * @zsa: + * @data_len: + * @data: + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_zns_mgmt_send(int fd, __u32 nsid, __u64 slba, bool select_all, + enum nvme_zns_send_action zsa, __u32 data_len, + void *data); + +/** + * enum nvme_zns_recv_action - + */ +enum nvme_zns_recv_action { + NVME_ZNS_ZRA_REPORT_ZONES = 0x0, + NVME_ZNS_ZRA_EXTENDED_REPORT_ZONES = 0x1, +}; + +/** + * enum nvme_zns_recv_action_spec - + */ +enum nvme_zns_recv_action_spec { + NVME_ZNS_ZRAS_REPORT_ALL = 0x0, + NVME_ZNS_ZRAS_REPORT_EMPTY = 0x1, + NVME_ZNS_ZRAS_REPORT_IMPL_OPENED = 0x2, + NVME_ZNS_ZRAS_REPORT_EXPL_OPENED = 0x3, + NVME_ZNS_ZRAS_REPORT_CLOSED = 0x4, + NVME_ZNS_ZRAS_REPORT_FULL = 0x5, + NVME_ZNS_ZRAS_REPORT_READ_ONLY = 0x6, + NVME_ZNS_ZRAS_REPORT_OFFLINE = 0x7, +}; + +/** + * nvme_zns_mgmt_recv() - + * @fd: File descriptor of nvme device + * @nsid: Namespace ID + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_zns_mgmt_recv(int fd, __u32 nsid, __u64 slba, + enum nvme_zns_recv_action zra, __u16 zrasf, + bool zras_feat, __u32 data_len, void *data); + +/** + * nvme_zns_append() - + * @fd: File descriptor of nvme device + * @nsid: Namespace ID + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_zns_append(int fd, __u32 nsid, __u64 zslba, __u16 nlb, __u16 control, + __u32 ilbrt, __u16 lbat, __u16 lbatm, __u32 data_len, + void *data, __u32 metadata_len, void *metadata, + __u64 *result); + #endif /* _LIBNVME_IOCTL_H */ diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 4ef455ea00..097d6165eb 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -70,6 +70,7 @@ struct nvme_ns { uint8_t eui64[8]; uint8_t nguid[16]; uuid_t uuid; + enum nvme_csi csi; }; struct nvme_ctrl { @@ -724,6 +725,11 @@ uint64_t nvme_ns_get_lba_util(nvme_ns_t n) return n->lba_util; } +enum nvme_csi nvme_ns_get_csi(nvme_ns_t n) +{ + return n->csi; +} + const uint8_t *nvme_ns_get_eui64(nvme_ns_t n) { return n->eui64; @@ -849,6 +855,9 @@ static void nvme_ns_parse_descriptors(struct nvme_ns *n, case NVME_NIDT_UUID: memcpy(n->uuid, desc->nid, sizeof(n->uuid)); break; + case NVME_NIDT_CSI: + memcpy(&n->csi, desc->nid, sizeof(n->csi)); + break; } } } diff --git a/src/nvme/tree.h b/src/nvme/tree.h index 40a43f97bb..dc52597485 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -267,6 +267,14 @@ uint64_t nvme_ns_get_lba_count(nvme_ns_t n); */ uint64_t nvme_ns_get_lba_util(nvme_ns_t n); +/** + * nvme_ns_get_csi() - + * @n: + * + * Return: The namespace's command set identifier in use + */ +enum nvme_csi nvme_ns_get_csi(nvme_ns_t n); + /** * nvme_ns_get_eui64() - * @n: diff --git a/src/nvme/types.h b/src/nvme/types.h index 31fe5faccf..31a46b7500 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -145,6 +145,16 @@ enum nvme_constants { NVME_NQN_LENGTH = 256, NVMF_TRADDR_SIZE = 256, NVMF_TSAS_SIZE = 256, + NVME_ZNS_CHANGED_ZONES_MAX = 511, +}; + +/** + * enum nvme_csi - Defined command set indicators + * @NVME_CSI_NVM: NVM Command Set Indicator + */ +enum nvme_csi { + NVME_CSI_NVM = 0, + NVME_CSI_ZNS = 2, }; /** @@ -324,6 +334,7 @@ enum nvme_cc { NVME_CC_IOSQES_MASK = 0xf, NVME_CC_IOCQES_MASK = 0xf, NVME_CC_CSS_NVM = 0, + NVME_CC_CSS_CSI = 6, NVME_CC_CSS_ADMIN = 7, NVME_CC_AMS_RR = 0, NVME_CC_AMS_WRRU = 1, @@ -1903,12 +1914,14 @@ enum nvme_ns_id_desc_nidt { NVME_NIDT_EUI64 = 1, NVME_NIDT_NGUID = 2, NVME_NIDT_UUID = 3, + NVME_NIDT_CSI = 4, }; enum nvme_ns_id_desc_nidt_lens { NVME_NIDT_EUI64_LEN = 8, NVME_NIDT_NGUID_LEN = 16, NVME_NIDT_UUID_LEN = 16, + NVME_NIDT_CSI_LEN = 1, }; /** @@ -2021,6 +2034,50 @@ struct nvme_ns_list { __le32 ns[NVME_ID_NS_LIST_MAX]; }; +/** + * struct nvme_zns_lbafe - + * zsze: + * zdes: + */ +struct nvme_zns_lbafe { + __le64 zsze; + __u8 zdes; + __u8 rsvd9[7]; +}; + +/** + * struct nvme_zns_id_ns - + * @zoc: + * @ozcs: + * @mar: + * @mor: + * @rrl: + * @frl: + * @lbafe: + * @vs: + */ +struct nvme_zns_id_ns { + __le16 zoc; + __le16 ozcs; + __le32 mar; + __le32 mor; + __le32 rrl; + __le32 frl; + __u8 rsvd20[2796]; + struct nvme_zns_lbafe lbafe[16]; + __u8 rsvd3072[768]; + __u8 vs[256]; +}; + +/** + * struct nvme_zns_id_ctrl - + * @zamds: + */ +struct nvme_zns_id_ctrl { + __u8 zamds; + __u8 rsvd1[4095]; +}; + /** * struct nvme_primary_ctrl_cap - * @cntlid: @@ -2091,6 +2148,14 @@ struct nvme_secondary_ctrl_list { struct nvme_secondary_ctrl sc_entry[NVME_ID_SECONDARY_CTRL_MAX]; }; +/** + * struct nvme_id_iocs - NVMe Identify IO Command Set data structure + * @iocsc: List of supported IO Command Set Combination vectors + */ +struct nvme_id_iocs { + __u64 iocsc[512]; +}; + /** * struct nvme_error_log_page - */ @@ -2735,6 +2800,70 @@ enum nvme_sanitize_sstat { NVME_SANITIZE_SSTAT_GLOBAL_DATA_ERASED_MASK = 0x1, }; +/** + * struct nvme_zns_changed_zone_log - ZNS Changed Zone List log + * @nrzid: + * @zid: + */ +struct nvme_zns_changed_zone_log { + __le16 nrzid; + __u8 rsvd2[6]; + __le64 zid[NVME_ZNS_CHANGED_ZONES_MAX]; +}; + +/** + * enum nvme_zns_zt - + */ +enum nvme_zns_zt { + NVME_ZONE_TYPE_SEQWRITE_REQ = 0x2, +}; + +/** + * enum nvme_zns_za - + */ +enum nvme_zns_za { + NVME_ZNS_ZA_ZFC = 1 << 0, + NVME_ZNS_ZA_FZR = 1 << 1, + NVME_ZNS_ZA_RZR = 1 << 2, + NVME_ZNS_ZA_ZDEV = 1 << 7, +}; + +/** + * enum nvme_zns_zs - + */ +enum nvme_zns_zs { + NVME_ZNS_ZS_EMPTY = 0x1, + NVME_ZNS_ZS_IMPL_OPEN = 0x2, + NVME_ZNS_ZS_EXPL_OPEN = 0x3, + NVME_ZNS_ZS_CLOSED = 0x4, + NVME_ZNS_ZS_READ_ONLY = 0xd, + NVME_ZNS_ZS_FULL = 0xe, + NVME_ZNS_ZS_OFFLINE = 0xf, +}; + +/** + * struct nvme_zns_desc - + */ +struct nvme_zns_desc { + __u8 zt; + __u8 zs; + __u8 za; + __u8 rsvd3[5]; + __le64 zcap; + __le64 zslba; + __le64 wp; + __u8 rsvd32[32]; +}; + +/** + * struct nvme_zone_report - + */ +struct nvme_zone_report { + __le64 nr_zones; + __u8 resv8[56]; + struct nvme_zns_desc entries[]; +}; + /** * struct nvme_lba_status_desc - * @dslba: @@ -4101,6 +4230,18 @@ enum nvme_status_field { NVME_SC_DISCOVERY_RESTART = 0x90, NVME_SC_AUTH_REQUIRED = 0x91, + /* + * I/O Command Set Specific - ZNS commands: + */ + 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: */ diff --git a/src/nvme/util.c b/src/nvme/util.c index 90e990256f..50a39dd78f 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -255,7 +255,7 @@ int __nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, ret = nvme_get_log(fd, log_id, nsid, offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, retain, NVME_UUID_NONE, - xfer, ptr); + NVME_CSI_NVM, xfer, ptr); if (ret) return ret; diff --git a/test/Makefile b/test/Makefile index 7766921946..16206220ed 100644 --- a/test/Makefile +++ b/test/Makefile @@ -9,7 +9,7 @@ else CONFIG_CPLUSPLUS=y endif -c_targets += test register +c_targets += test register zns ifdef CONFIG_CPLUSPLUS cpp_targets += cpp @@ -23,10 +23,10 @@ all: $(all_targets) CXXFLAGS ?= -lstdc++ %: %.cc - $(QUIET_CC)$(CC) $(CFLAGS) $(CXXFLAGS) -o $@ $< -lnvme + $(QUIET_CC)$(CC) $(CFLAGS) $(LDFLAGS) $(CXXFLAGS) -o $@ $< -lnvme %: %.c - $(QUIET_CC)$(CC) $(CFLAGS) -o $@ $< -lnvme + $(QUIET_CC)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lnvme clean: rm -f $(all_targets) diff --git a/test/test.c b/test/test.c index 79919e170b..a2229876d5 100644 --- a/test/test.c +++ b/test/test.c @@ -147,7 +147,7 @@ static int test_ctrl(nvme_ctrl_t c) printf(" Device Self Test\n"); else printf(" ERROR: Device Self Test:%x\n", ret); - ret = nvme_get_log_cmd_effects(fd, &cfx); + ret = nvme_get_log_cmd_effects(fd, NVME_CSI_NVM, &cfx); if (!ret) printf(" Command Effects\n"); else @@ -359,7 +359,7 @@ int main() print_hex(nvme_ns_get_nguid(n), 16); nvme_ns_get_uuid(n, uuid); uuid_unparse_lower(uuid, uuid_str); - printf(" uuid:%s\n", uuid_str); + printf(" uuid:%s csi:%d\n", uuid_str, nvme_ns_get_csi(n)); } nvme_ctrl_for_each_path(c, p) diff --git a/test/zns.c b/test/zns.c new file mode 100644 index 0000000000..fd186f19bf --- /dev/null +++ b/test/zns.c @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/** + * This file is part of libnvme. + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + * + * Authors: Keith Busch + */ + +/** + * Search out for ZNS type namespaces, and if found, report their properties. + */ +#include +#include +#include +#include +#include +#include + +static void show_zns_properties(nvme_ns_t n) +{ + struct nvme_zns_id_ns zns_ns; + struct nvme_zns_id_ctrl zns_ctrl; + struct nvme_zone_report *zr; + + zr = calloc(1, 0x1000); + if (!zr) + return; + + if (nvme_zns_identify_ns(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), + &zns_ns)) { + fprintf(stderr, "failed to identify zns ns\n");; + } + + printf("zoc:%x ozcs:%x mar:%x mor:%x\n", le16_to_cpu(zns_ns.zoc), + le16_to_cpu(zns_ns.ozcs), le32_to_cpu(zns_ns.mar), + le32_to_cpu(zns_ns.mor)); + + if (nvme_zns_identify_ctrl(nvme_ns_get_fd(n), &zns_ctrl)) { + fprintf(stderr, "failed to identify zns ctrl\n");; + return; + } + + printf("zamds:%u\n", zns_ctrl.zamds); + + if (nvme_zns_mgmt_recv(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), 0, + NVME_ZNS_ZRA_REPORT_ZONES, NVME_ZNS_ZRAS_REPORT_ALL, + 0, 0x1000, (void *)zr)) { + fprintf(stderr, "failed to report zones\n");; + return; + } + + printf("nr_zones:%"PRIu64"\n", le64_to_cpu(zr->nr_zones)); + free(zr); +} + +int main() +{ + nvme_subsystem_t s; + nvme_root_t r; + nvme_ctrl_t c; + nvme_ns_t n; + + r = nvme_scan(); + if (!r) + return -1; + + nvme_for_each_subsystem(r, s) { + nvme_subsystem_for_each_ctrl(s, c) { + nvme_ctrl_for_each_ns(c, n) { + if (nvme_ns_get_csi(n) == NVME_CSI_ZNS) + show_zns_properties(n); + } + } + nvme_subsystem_for_each_ns(s, n) { + if (nvme_ns_get_csi(n) == NVME_CSI_ZNS) + show_zns_properties(n); + } + } + nvme_free_tree(r); +} From 4b562745fb65d2eac5532ff59170eadb365fc7bc Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 4 Jun 2020 20:36:52 -0700 Subject: [PATCH 0054/1564] report zones helpers Signed-off-by: Keith Busch --- src/nvme/ioctl.c | 18 +++++++++++++++++- src/nvme/ioctl.h | 36 +++++++++++++++++++++++------------- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index d2bb0727e5..ced189b516 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -1836,7 +1836,7 @@ int nvme_zns_mgmt_recv(int fd, __u32 nsid, __u64 slba, DW(zras_feat, NVME_ZNS_MGMT_RECV_ZRAS_FEAT); struct nvme_passthru_cmd cmd = { - .opcode = nvme_zns_cmd_mgmt_send, + .opcode = nvme_zns_cmd_mgmt_recv, .nsid = nsid, .cdw10 = cdw10, .cdw11 = cdw11, @@ -1849,6 +1849,22 @@ int nvme_zns_mgmt_recv(int fd, __u32 nsid, __u64 slba, return nvme_submit_io_passthru(fd, &cmd, NULL); } +int nvme_zns_report_zones(int fd, __u32 nsid, __u64 slba, bool extended, + enum nvme_zns_report_options opts, bool partial, + __u32 data_len, void *data) +{ + BUILD_ASSERT(sizeof(struct nvme_zns_desc) == 64); + enum nvme_zns_recv_action zra; + + if (extended) + zra = NVME_ZNS_ZRA_EXTENDED_REPORT_ZONES; + else + zra = NVME_ZNS_ZRA_REPORT_ZONES; + + return nvme_zns_mgmt_recv(fd, nsid, slba, zra, opts, partial, + data_len, data); +} + int nvme_zns_append(int fd, __u32 nsid, __u64 zslba, __u16 nlb, __u16 control, __u32 ilbrt, __u16 lbat, __u16 lbatm, __u32 data_len, void *data, __u32 metadata_len, void *metadata, diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index d1ebc68711..22edcbe2be 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -3077,9 +3077,27 @@ enum nvme_zns_recv_action { }; /** - * enum nvme_zns_recv_action_spec - + * nvme_zns_mgmt_recv() - + * @fd: File descriptor of nvme device + * @nsid: Namespace ID + * @slba: + * @zra: + * @zrasf: + * @zras_feat: + * @data_len: + * @data: + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_zns_mgmt_recv(int fd, __u32 nsid, __u64 slba, + enum nvme_zns_recv_action zra, __u16 zrasf, + bool zras_feat, __u32 data_len, void *data); + +/** + * enum nvme_zns_report_options - */ -enum nvme_zns_recv_action_spec { +enum nvme_zns_report_options { NVME_ZNS_ZRAS_REPORT_ALL = 0x0, NVME_ZNS_ZRAS_REPORT_EMPTY = 0x1, NVME_ZNS_ZRAS_REPORT_IMPL_OPENED = 0x2, @@ -3090,17 +3108,9 @@ enum nvme_zns_recv_action_spec { NVME_ZNS_ZRAS_REPORT_OFFLINE = 0x7, }; -/** - * nvme_zns_mgmt_recv() - - * @fd: File descriptor of nvme device - * @nsid: Namespace ID - * - * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. - */ -int nvme_zns_mgmt_recv(int fd, __u32 nsid, __u64 slba, - enum nvme_zns_recv_action zra, __u16 zrasf, - bool zras_feat, __u32 data_len, void *data); +int nvme_zns_report_zones(int fd, __u32 nsid, __u64 slba, bool extended, + enum nvme_zns_report_options opts, bool partial, + __u32 data_len, void *data); /** * nvme_zns_append() - From 0895b50cead4ebd39b1409e6f3e87e6423c0974b Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Fri, 5 Jun 2020 08:01:27 -0700 Subject: [PATCH 0055/1564] fix up get_nsid api namespaces can be anything from 1 to 0xfffffffe, which means they must be unsigned. Change the api to take a parameter for the nsid value rather than try to return an 'int', which would have confusing signedness. Signed-off-by: Keith Busch --- src/nvme/ioctl.c | 16 ++++------------ src/nvme/ioctl.h | 6 +++--- src/nvme/tree.c | 5 ++--- 3 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index ced189b516..d02df36f0c 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -66,19 +66,11 @@ int nvme_ns_rescan(int fd) return ioctl(fd, NVME_IOCTL_RESCAN); } -int nvme_get_nsid(int fd) +int nvme_get_nsid(int fd, __u32 *nsid) { - static struct stat nvme_stat; - int err = fstat(fd, &nvme_stat); - - if (err < 0) - return -1; - - if (!S_ISBLK(nvme_stat.st_mode)) { - errno = ENOTBLK; - return -1; - } - return ioctl(fd, NVME_IOCTL_ID); + errno = 0; + *nsid = ioctl(fd, NVME_IOCTL_ID); + return -1 * (errno != 0); } static int nvme_submit_passthru64(int fd, unsigned long ioctl_cmd, diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 22edcbe2be..6c7b8c256e 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -358,13 +358,13 @@ int nvme_ns_rescan(int fd); /** * nvme_get_nsid() - Retrieve the NSID from a namespace file descriptor * @fd: File descriptor of nvme namespace + * @nsid: User pointer to namespace id * * This should only be sent to namespace handles, not to controllers. * - * Return: The namespace identifier if a succecssful or -1 with errno set - * otherwise. + * Return: 0 if @nsid was set succecssfully or -1 with errno set otherwise. */ -int nvme_get_nsid(int fd); +int nvme_get_nsid(int fd, __u32 *nsid); /** * enum nvme_admin_opcode - Known NVMe admin opcodes diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 097d6165eb..74aba7dfaf 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -57,7 +57,7 @@ struct nvme_ns { struct nvme_ctrl *c; int fd; - int nsid; + __u32 nsid; char *name; char *sysfs_dir; @@ -898,8 +898,7 @@ static nvme_ns_t nvme_ns_open(const char *name) if (n->fd < 0) goto free_ns; - n->nsid = nvme_get_nsid(n->fd); - if (n->nsid < 0) + if (nvme_get_nsid(n->fd, &n->nsid) < 0) goto close_fd; list_head_init(&n->paths); From e5b9974993e23dd065d4f6f9d3d60a71d3e15a45 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Tue, 9 Jun 2020 07:27:24 -0700 Subject: [PATCH 0056/1564] update and inline feature decoding Signed-off-by: Keith Busch --- src/nvme/types.h | 158 +++++++++++----------- src/nvme/util.c | 283 ---------------------------------------- src/nvme/util.h | 332 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 415 insertions(+), 358 deletions(-) diff --git a/src/nvme/types.h b/src/nvme/types.h index 31a46b7500..f5fb46ad42 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -36,6 +36,16 @@ #define NVME_GET(name, value) \ (((value) >> NVME_##name##_SHIFT) & NVME_##name##_MASK) +/** + * NVME_SET() - set field into complex value + * @name: The name of the sub-field within an nvme value + * @value: The value to be set + * + * Returns: The 'name' field from 'value' + */ +#define NVME_SET(name, value) \ + (((value) & NVME_##name##_MASK) << NVME_##name##_SHIFT) + /** * cpu_to_le16() - * @x: 16-bit CPU value to turn to little endian. @@ -255,8 +265,6 @@ static inline __u64 nvme_mmio_read64(void *addr) return le32_to_cpu(*p) | ((uint64_t)le32_to_cpu(*(p + 1)) << 32); } -#define NVME_REG_VALUE(name, value) NVME_GET(name, value) - enum nvme_cap { NVME_CAP_MQES_SHIFT = 0, NVME_CAP_CQR_SHIFT = 16, @@ -288,18 +296,18 @@ enum nvme_cap { NVME_CAP_CSS_ADMIN = 1 << 7, }; -#define NVME_CAP_MQES(cap) NVME_REG_VALUE(CAP_MQES, cap) -#define NVME_CAP_CQR(cap) NVME_REG_VALUE(CAP_CQR, cap) -#define NVME_CAP_AMS(cap) NVME_REG_VALUE(CAP_AMS, cap) -#define NVME_CAP_TO(cap) NVME_REG_VALUE(CAP_TO, cap) -#define NVME_CAP_DSTRD(cap) NVME_REG_VALUE(CAP_DSTRD, cap) -#define NVME_CAP_NSSRC(cap) NVME_REG_VALUE(CAP_NSSRC, cap) -#define NVME_CAP_CSS(cap) NVME_REG_VALUE(CAP_CSS, cap) -#define NVME_CAP_BPS(cap) NVME_REG_VALUE(CAP_BPS, cap) -#define NVME_CAP_MPSMIN(cap) NVME_REG_VALUE(CAP_MPSMIN, cap) -#define NVME_CAP_MPSMAX(cap) NVME_REG_VALUE(CAP_MPSMAX, cap) -#define NVME_CAP_CMBS(cap) NVME_REG_VALUE(CAP_CMBS, cap) -#define NVME_CAP_PMRS(cap) NVME_REG_VALUE(CAP_PMRS, cap) +#define NVME_CAP_MQES(cap) NVME_GET(CAP_MQES, cap) +#define NVME_CAP_CQR(cap) NVME_GET(CAP_CQR, cap) +#define NVME_CAP_AMS(cap) NVME_GET(CAP_AMS, cap) +#define NVME_CAP_TO(cap) NVME_GET(CAP_TO, cap) +#define NVME_CAP_DSTRD(cap) NVME_GET(CAP_DSTRD, cap) +#define NVME_CAP_NSSRC(cap) NVME_GET(CAP_NSSRC, cap) +#define NVME_CAP_CSS(cap) NVME_GET(CAP_CSS, cap) +#define NVME_CAP_BPS(cap) NVME_GET(CAP_BPS, cap) +#define NVME_CAP_MPSMIN(cap) NVME_GET(CAP_MPSMIN, cap) +#define NVME_CAP_MPSMAX(cap) NVME_GET(CAP_MPSMAX, cap) +#define NVME_CAP_CMBS(cap) NVME_GET(CAP_CMBS, cap) +#define NVME_CAP_PMRS(cap) NVME_GET(CAP_PMRS, cap) enum nvme_vs { NVME_VS_TER_SHIFT = 0, @@ -310,9 +318,9 @@ enum nvme_vs { NVME_VS_MJR_MASK = 0xffff, }; -#define NVME_VS_TER(vs) NVME_REG_VALUE(VS_TER, vs) -#define NVME_VS_MNR(vs) NVME_REG_VALUE(VS_MNR, vs) -#define NVME_VS_MJR(vs) NVME_REG_VALUE(VS_MJR, vs) +#define NVME_VS_TER(vs) NVME_GET(VS_TER, vs) +#define NVME_VS_MNR(vs) NVME_GET(VS_MNR, vs) +#define NVME_VS_MJR(vs) NVME_GET(VS_MJR, vs) #define NVME_MAJOR(ver) NVME_VS_MJR(ver) #define NVME_MINOR(ver) NVME_VS_MNR(ver) @@ -344,13 +352,13 @@ enum nvme_cc { NVME_CC_SHN_ABRUPT = 2, }; -#define NVME_CC_EN(cc) NVME_REG_VALUE(CC_EN, cc) -#define NVME_CC_CSS(cc) NVME_REG_VALUE(CC_CSS, cc) -#define NVME_CC_MPS(cc) NVME_REG_VALUE(CC_MPS, cc) -#define NVME_CC_AMS(cc) NVME_REG_VALUE(CC_AMS, cc) -#define NVME_CC_SHN(cc) NVME_REG_VALUE(CC_SHN, cc) -#define NVME_CC_IOSQES(cc) NVME_REG_VALUE(CC_IOSQES, cc) -#define NVME_CC_IOCQES(cc) NVME_REG_VALUE(CC_IOCQES, cc) +#define NVME_CC_EN(cc) NVME_GET(CC_EN, cc) +#define NVME_CC_CSS(cc) NVME_GET(CC_CSS, cc) +#define NVME_CC_MPS(cc) NVME_GET(CC_MPS, cc) +#define NVME_CC_AMS(cc) NVME_GET(CC_AMS, cc) +#define NVME_CC_SHN(cc) NVME_GET(CC_SHN, cc) +#define NVME_CC_IOSQES(cc) NVME_GET(CC_IOSQES, cc) +#define NVME_CC_IOCQES(cc) NVME_GET(CC_IOCQES, cc) enum nvme_csts { NVME_CSTS_RDY_SHIFT = 0, @@ -369,11 +377,11 @@ enum nvme_csts { NVME_CSTS_SHST_MASK = 3, }; -#define NVME_CSTS_RDY(csts) NVME_REG_VALUE(CSTS_RDY, csts) -#define NVME_CSTS_CFS(csts) NVME_REG_VALUE(CSTS_CFS, csts) -#define NVME_CSTS_SHST(csts) NVME_REG_VALUE(CSTS_SHST, csts) -#define NVME_CSTS_NSSRO(csts) NVME_REG_VALUE(CSTS_NSSRO, csts) -#define NVME_CSTS_PP(csts) NVME_REG_VALUE(CSTS_PP, csts) +#define NVME_CSTS_RDY(csts) NVME_GET(CSTS_RDY, csts) +#define NVME_CSTS_CFS(csts) NVME_GET(CSTS_CFS, csts) +#define NVME_CSTS_SHST(csts) NVME_GET(CSTS_SHST, csts) +#define NVME_CSTS_NSSRO(csts) NVME_GET(CSTS_NSSRO, csts) +#define NVME_CSTS_PP(csts) NVME_GET(CSTS_PP, csts) enum nvme_aqa { NVME_AQA_ASQS_SHIFT = 0, @@ -382,8 +390,8 @@ enum nvme_aqa { NVME_AQA_ACQS_MASK = 0xfff, }; -#define NVME_AQA_ASQS(aqa) NVME_REG_VALUE(AQA_ASQS, aqa) -#define NVME_AQA_ACQS(aqa) NVME_REG_VALUE(AQA_ACQS, aqa) +#define NVME_AQA_ASQS(aqa) NVME_GET(AQA_ASQS, aqa) +#define NVME_AQA_ACQS(aqa) NVME_GET(AQA_ACQS, aqa) enum nvme_cmbloc { NVME_CMBLOC_BIR_SHIFT = 0, @@ -404,14 +412,14 @@ enum nvme_cmbloc { NVME_CMBLOC_OFST_MASK = 0xfffff, }; -#define NVME_CMBLOC_BIR(cmbloc) NVME_REG_VALUE(CMBLOC_BIR, cmbloc) -#define NVME_CMBLOC_CQMMS(cmbloc) NVME_REG_VALUE(CMBLOC_CQMMS, cmbloc) -#define NVME_CMBLOC_CQPDS(cmbloc) NVME_REG_VALUE(CMBLOC_CQPDS, cmbloc) -#define NVME_CMBLOC_CDPLMS(cmbloc) NVME_REG_VALUE(CMBLOC_CDPLMS, cmbloc) -#define NVME_CMBLOC_CDPCILS(cmbloc) NVME_REG_VALUE(CMBLOC_CDPCILS, cmbloc) -#define NVME_CMBLOC_CDMMMS(cmbloc) NVME_REG_VALUE(CMBLOC_CDMMMS, cmbloc) -#define NVME_CMBLOC_CQDA(cmbloc) NVME_REG_VALUE(CMBLOC_CQDA, cmbloc) -#define NVME_CMBLOC_OFST(cmbloc) NVME_REG_VALUE(CMBLOC_OFST, cmbloc) +#define NVME_CMBLOC_BIR(cmbloc) NVME_GET(CMBLOC_BIR, cmbloc) +#define NVME_CMBLOC_CQMMS(cmbloc) NVME_GET(CMBLOC_CQMMS, cmbloc) +#define NVME_CMBLOC_CQPDS(cmbloc) NVME_GET(CMBLOC_CQPDS, cmbloc) +#define NVME_CMBLOC_CDPLMS(cmbloc) NVME_GET(CMBLOC_CDPLMS, cmbloc) +#define NVME_CMBLOC_CDPCILS(cmbloc) NVME_GET(CMBLOC_CDPCILS, cmbloc) +#define NVME_CMBLOC_CDMMMS(cmbloc) NVME_GET(CMBLOC_CDMMMS, cmbloc) +#define NVME_CMBLOC_CQDA(cmbloc) NVME_GET(CMBLOC_CQDA, cmbloc) +#define NVME_CMBLOC_OFST(cmbloc) NVME_GET(CMBLOC_OFST, cmbloc) enum nvme_cmbsz { NVME_CMBSZ_SQS_SHIFT = 0, @@ -437,13 +445,13 @@ enum nvme_cmbsz { NVME_CMBSZ_SZU_64G = 6, }; -#define NVME_CMBSZ_SQS(cmbsz) NVME_REG_VALUE(CMBSZ_SQS, cmbsz) -#define NVME_CMBSZ_CQS(cmbsz) NVME_REG_VALUE(CMBSZ_CQS, cmbsz) -#define NVME_CMBSZ_LISTS(cmbsz) NVME_REG_VALUE(CMBSZ_LISTS, cmbsz) -#define NVME_CMBSZ_RDS(cmbsz) NVME_REG_VALUE(CMBSZ_RDS, cmbsz) -#define NVME_CMBSZ_WDS(cmbsz) NVME_REG_VALUE(CMBSZ_WDS, cmbsz) -#define NVME_CMBSZ_SZU(cmbsz) NVME_REG_VALUE(CMBSZ_SZU, cmbsz) -#define NVME_CMBSZ_SZ(cmbsz) NVME_REG_VALUE(CMBSZ_SZ, cmbsz) +#define NVME_CMBSZ_SQS(cmbsz) NVME_GET(CMBSZ_SQS, cmbsz) +#define NVME_CMBSZ_CQS(cmbsz) NVME_GET(CMBSZ_CQS, cmbsz) +#define NVME_CMBSZ_LISTS(cmbsz) NVME_GET(CMBSZ_LISTS, cmbsz) +#define NVME_CMBSZ_RDS(cmbsz) NVME_GET(CMBSZ_RDS, cmbsz) +#define NVME_CMBSZ_WDS(cmbsz) NVME_GET(CMBSZ_WDS, cmbsz) +#define NVME_CMBSZ_SZU(cmbsz) NVME_GET(CMBSZ_SZU, cmbsz) +#define NVME_CMBSZ_SZ(cmbsz) NVME_GET(CMBSZ_SZ, cmbsz) /** * nvme_cmb_size() - Calculate size of the controller memory buffer @@ -470,9 +478,9 @@ enum nvme_bpinfo { NVME_BPINFO_BRS_READ_ERROR = 3, }; -#define NVME_BPINFO_BPSZ(bpinfo) NVME_REG_VALUE(BPINFO_BPSZ, bpinfo) -#define NVME_BPINFO_BRS(bpinfo) NVME_REG_VALUE(BPINFO_BRS, bpinfo) -#define NVME_BPINFO_ABPID(bpinfo) NVME_REG_VALUE(BPINFO_ABPID, bpinfo) +#define NVME_BPINFO_BPSZ(bpinfo) NVME_GET(BPINFO_BPSZ, bpinfo) +#define NVME_BPINFO_BRS(bpinfo) NVME_GET(BPINFO_BRS, bpinfo) +#define NVME_BPINFO_ABPID(bpinfo) NVME_GET(BPINFO_ABPID, bpinfo) enum nvme_bprsel { NVME_BPRSEL_BPRSZ_SHIFT = 0, @@ -483,9 +491,9 @@ enum nvme_bprsel { NVME_BPRSEL_BPID_MASK = 0x1, }; -#define NVME_BPRSEL_BPRSZ(bprsel) NVME_REG_VALUE(BPRSEL_BPRSZ, bprsel) -#define NVME_BPRSEL_BPROF(bprsel) NVME_REG_VALUE(BPRSEL_BPROF, bprsel) -#define NVME_BPRSEL_BPID(bprsel) NVME_REG_VALUE(BPRSEL_BPID, bprsel) +#define NVME_BPRSEL_BPRSZ(bprsel) NVME_GET(BPRSEL_BPRSZ, bprsel) +#define NVME_BPRSEL_BPROF(bprsel) NVME_GET(BPRSEL_BPROF, bprsel) +#define NVME_BPRSEL_BPID(bprsel) NVME_GET(BPRSEL_BPID, bprsel) enum nvme_cmbmsc { NVME_CMBMSC_CRE_SHIFT = 0, @@ -496,16 +504,16 @@ enum nvme_cmbmsc { }; static const __u64 NVME_CMBMSC_CBA_MASK = 0xfffffffffffffull; -#define NVME_CMBMSC_CRE(cmbmsc) NVME_REG_VALUE(CMBMSC_CRE, cmbmsc) -#define NVME_CMBMSC_CMSE(cmbmsc) NVME_REG_VALUE(CMBMSC_CMSE, cmbmsc) -#define NVME_CMBMSC_CBA(cmbmsc) NVME_REG_VALUE(CMBMSC_CBA, cmbmsc) +#define NVME_CMBMSC_CRE(cmbmsc) NVME_GET(CMBMSC_CRE, cmbmsc) +#define NVME_CMBMSC_CMSE(cmbmsc) NVME_GET(CMBMSC_CMSE, cmbmsc) +#define NVME_CMBMSC_CBA(cmbmsc) NVME_GET(CMBMSC_CBA, cmbmsc) enum nvme_cmbsts { NVME_CMBSTS_CBAI_SHIFT = 0, NVME_CMBSTS_CBAI_MASK = 0x1, }; -#define NVME_CMBSTS_CBAI(cmbsts) NVME_REG_VALUE(CMBSTS_CBAI, cmbsts) +#define NVME_CMBSTS_CBAI(cmbsts) NVME_GET(CMBSTS_CBAI, cmbsts) enum nvme_pmrcap { NVME_PMRCAP_RDS_SHIFT = 3, @@ -526,20 +534,20 @@ enum nvme_pmrcap { NVME_PMRCAP_PMRTU_60S = 1, }; -#define NVME_PMRCAP_RDS(pmrcap) NVME_REG_VALUE(PMRCAP_RDS, pmrcap) -#define NVME_PMRCAP_WDS(pmrcap) NVME_REG_VALUE(PMRCAP_WDS, pmrcap) -#define NVME_PMRCAP_BIR(pmrcap) NVME_REG_VALUE(PMRCAP_BIR, pmrcap) -#define NVME_PMRCAP_PMRTU(pmrcap) NVME_REG_VALUE(PMRCAP_PMRTU, pmrcap) -#define NVME_PMRCAP_PMRWMB(pmrcap) NVME_REG_VALUE(PMRCAP_PMRWMB, pmrcap) -#define NVME_PMRCAP_PMRTO(pmrcap) NVME_REG_VALUE(PMRCAP_PMRTO, pmrcap) -#define NVME_PMRCAP_CMSS(pmrcap) NVME_REG_VALUE(PMRCAP_CMSS, pmrcap) +#define NVME_PMRCAP_RDS(pmrcap) NVME_GET(PMRCAP_RDS, pmrcap) +#define NVME_PMRCAP_WDS(pmrcap) NVME_GET(PMRCAP_WDS, pmrcap) +#define NVME_PMRCAP_BIR(pmrcap) NVME_GET(PMRCAP_BIR, pmrcap) +#define NVME_PMRCAP_PMRTU(pmrcap) NVME_GET(PMRCAP_PMRTU, pmrcap) +#define NVME_PMRCAP_PMRWMB(pmrcap) NVME_GET(PMRCAP_PMRWMB, pmrcap) +#define NVME_PMRCAP_PMRTO(pmrcap) NVME_GET(PMRCAP_PMRTO, pmrcap) +#define NVME_PMRCAP_CMSS(pmrcap) NVME_GET(PMRCAP_CMSS, pmrcap) enum nvme_pmrctl { NVME_PMRCTL_EN_SHIFT = 0, NVME_PMRCTL_EN_MASK = 0x1, }; -#define NVME_PMRCTL_EN(pmrctl) NVME_REG_VALUE(PMRCTL_EN, pmrctl) +#define NVME_PMRCTL_EN(pmrctl) NVME_GET(PMRCTL_EN, pmrctl) enum nvme_pmrsts { NVME_PMRSTS_ERR_SHIFT = 0, @@ -552,10 +560,10 @@ enum nvme_pmrsts { NVME_PMRSTS_CBAI_MASK = 0x1, }; -#define NVME_PMRSTS_ERR(pmrsts) NVME_REG_VALUE(PMRSTS_ERR, pmrsts) -#define NVME_PMRSTS_NRDY(pmrsts) NVME_REG_VALUE(PMRSTS_NRDY, pmrsts) -#define NVME_PMRSTS_HSTS(pmrsts) NVME_REG_VALUE(PMRSTS_HSTS, pmrsts) -#define NVME_PMRSTS_CBAI(pmrsts) NVME_REG_VALUE(PMRSTS_CBAI, pmrsts) +#define NVME_PMRSTS_ERR(pmrsts) NVME_GET(PMRSTS_ERR, pmrsts) +#define NVME_PMRSTS_NRDY(pmrsts) NVME_GET(PMRSTS_NRDY, pmrsts) +#define NVME_PMRSTS_HSTS(pmrsts) NVME_GET(PMRSTS_HSTS, pmrsts) +#define NVME_PMRSTS_CBAI(pmrsts) NVME_GET(PMRSTS_CBAI, pmrsts) enum nvme_pmrebs { NVME_PMREBS_PMRSZU_SHIFT = 0, @@ -570,9 +578,9 @@ enum nvme_pmrebs { NVME_PMREBS_PMRSZU_1G = 3, }; -#define NVME_PMREBS_PMRSZU(pmrebs) NVME_REG_VALUE(PMREBS_PMRSZU, pmrebs) -#define NVME_PMREBS_RBB(pmrebs) NVME_REG_VALUE(PMREBS_RBB, pmrebs) -#define NVME_PMREBS_PMRWBZ(pmrebs) NVME_REG_VALUE(PMREBS_PMRWBZ, pmrebs) +#define NVME_PMREBS_PMRSZU(pmrebs) NVME_GET(PMREBS_PMRSZU, pmrebs) +#define NVME_PMREBS_RBB(pmrebs) NVME_GET(PMREBS_RBB, pmrebs) +#define NVME_PMREBS_PMRWBZ(pmrebs) NVME_GET(PMREBS_PMRWBZ, pmrebs) /** * nvme_pmr_size() - Calculate size of persistent memory region elasticity @@ -598,8 +606,8 @@ enum nvme_pmrswtp { NVME_PMRSWTP_PMRSWTU_GBPS = 3, }; -#define NVME_PMRSWTP_PMRSWTU(pmrswtp) NVME_REG_VALUE(PMRSWTP_PMRSWTU, pmrswtp) -#define NVME_PMRSWTP_PMRSWTV(pmrswtp) NVME_REG_VALUE(PMRSWTP_PMRSWTU, pmrswtp) +#define NVME_PMRSWTP_PMRSWTU(pmrswtp) NVME_GET(PMRSWTP_PMRSWTU, pmrswtp) +#define NVME_PMRSWTP_PMRSWTV(pmrswtp) NVME_GET(PMRSWTP_PMRSWTU, pmrswtp) /** * nvme_pmr_throughput() - Calculate throughput of persistent memory buffer @@ -620,8 +628,8 @@ enum nvme_pmrmsc { }; static const __u64 NVME_PMRMSC_CBA_MASK = 0xfffffffffffffull; -#define NVME_PMRMSC_CMSE(pmrmsc) NVME_REG_VALUE(PMRMSC_CMSE, pmrmsc) -#define NVME_PMRMSC_CBA(pmrmsc) NVME_REG_VALUE(PMRMSC_CBA, pmrmsc) +#define NVME_PMRMSC_CMSE(pmrmsc) NVME_GET(PMRMSC_CMSE, pmrmsc) +#define NVME_PMRMSC_CBA(pmrmsc) NVME_GET(PMRMSC_CBA, pmrmsc) /** * enum nvme_psd_flags - Possible flag values in nvme power state descriptor diff --git a/src/nvme/util.c b/src/nvme/util.c index 50a39dd78f..175714e423 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -588,286 +588,3 @@ char *nvme_get_path_attr(nvme_path_t p, const char *attr) { return nvme_get_attr(nvme_path_get_sysfs_dir(p), attr); } - -enum { - NVME_FEAT_ARB_BURST_MASK = 0x00000007, - NVME_FEAT_ARB_LPW_MASK = 0x0000ff00, - NVME_FEAT_ARB_MPW_MASK = 0x00ff0000, - NVME_FEAT_ARB_HPW_MASK = 0xff000000, - NVME_FEAT_PM_PS_MASK = 0x0000001f, - NVME_FEAT_PM_WH_MASK = 0x000000e0, - NVME_FEAT_LBAR_NR_MASK = 0x0000003f, - NVME_FEAT_TT_TMPTH_MASK = 0x0000ffff, - NVME_FEAT_TT_TMPSEL_MASK = 0x000f0000, - NVME_FEAT_TT_THSEL_MASK = 0x00300000, - NVME_FEAT_ER_TLER_MASK = 0x0000ffff, - NVME_FEAT_ER_DULBE_MASK = 0x00010000, - NVME_FEAT_VWC_WCE_MASK = 0x00000001, - NVME_FEAT_NRQS_NSQR_MASK = 0x0000ffff, - NVME_FEAT_NRQS_NCQR_MASK = 0xffff0000, - NVME_FEAT_ICOAL_THR_MASK = 0x000000ff, - NVME_FEAT_ICOAL_TIME_MASK = 0x0000ff00, - NVME_FEAT_ICFG_IV_MASK = 0x0000ffff, - NVME_FEAT_ICFG_CD_MASK = 0x00010000, - NVME_FEAT_WA_DN_MASK = 0x00000001, - NVME_FEAT_AE_SMART_MASK = 0x000000ff, - NVME_FEAT_AE_NAN_MASK = 0x00000100, - NVME_FEAT_AE_FW_MASK = 0x00000200, - NVME_FEAT_AE_TELEM_MASK = 0x00000400, - NVME_FEAT_AE_ANA_MASK = 0x00000800, - NVME_FEAT_AE_PLA_MASK = 0x00001000, - NVME_FEAT_AE_LBAS_MASK = 0x00002000, - NVME_FEAT_AE_EGA_MASK = 0x00004000, - NVME_FEAT_APST_APSTE_MASK = 0x00000001, - NVME_FEAT_HMEM_EHM_MASK = 0x00000001, - NVME_FEAT_HCTM_TMT2_MASK = 0x0000ffff, - NVME_FEAT_HCTM_TMT1_MASK = 0xffff0000, - NVME_FEAT_NOPS_NOPPME_MASK = 0x00000001, - NVME_FEAT_RRL_RRL_MASK = 0x000000ff, - NVME_FEAT_PLM_PLME_MASK = 0x00000001, - NVME_FEAT_PLMW_WS_MASK = 0x00000007, - NVME_FEAT_LBAS_LSIRI_MASK = 0x0000ffff, - NVME_FEAT_LBAS_LSIPI_MASK = 0xffff0000, - NVME_FEAT_SC_NODRM_MASK = 0x00000001, - NVME_FEAT_EG_ENDGID_MASK = 0x0000ffff, - NVME_FEAT_EG_EGCW_MASK = 0x00ff0000, - NVME_FEAT_SPM_PBSLC_MASK = 0x000000ff, - NVME_FEAT_HOSTID_EXHID_MASK = 0x00000001, - NVME_FEAT_RM_REGPRE_MASK = 0x00000002, - NVME_FEAT_RM_RESREL_MASK = 0x00000004, - NVME_FEAT_RM_RESPRE_MASK = 0x00000008, - NVME_FEAT_RP_PTPL_MASK = 0x00000001, - NVME_FEAT_WP_WPS_MASK = 0x00000007, -}; - -#define shift(v, s, m) ((v & m) >> s) - -#define NVME_FEAT_ARB_BURST(v) shift(v, 0, NVME_FEAT_ARB_BURST_MASK) -#define NVME_FEAT_ARB_LPW(v) shift(v, 8, NVME_FEAT_ARB_LPW_MASK) -#define NVME_FEAT_ARB_MPW(v) shift(v, 16, NVME_FEAT_ARB_MPW_MASK) -#define NVME_FEAT_ARB_HPW(v) shift(v, 24, NVME_FEAT_ARB_HPW_MASK) - -void nvme_feature_decode_arbitration(__u32 value, __u8 *ab, __u8 *lpw, - __u8 *mpw, __u8 *hpw) -{ - *ab = NVME_FEAT_ARB_BURST(value); - *lpw = NVME_FEAT_ARB_LPW(value); - *mpw = NVME_FEAT_ARB_MPW(value); - *hpw = NVME_FEAT_ARB_HPW(value); -}; - -#define NVME_FEAT_PM_PS(v) shift(v, 0, NVME_FEAT_PM_PS_MASK) -#define NVME_FEAT_PM_WH(v) shift(v, 5, NVME_FEAT_PM_WH_MASK) - -void nvme_feature_decode_power_mgmt(__u32 value, __u8 *ps, __u8 *wh) -{ - *ps = NVME_FEAT_PM_PS(value); - *wh = NVME_FEAT_PM_WH(value); -} - -#define NVME_FEAT_LBAR_NR(v) shift(v, 0, NVME_FEAT_LBAR_NR_MASK) - -void nvme_feature_decode_lba_range(__u32 value, __u8 *num) -{ - *num = NVME_FEAT_LBAR_NR(value); -} - -#define NVME_FEAT_TT_TMPTH(v) shift(v, 0, NVME_FEAT_TT_TMPTH_MASK) -#define NVME_FEAT_TT_TMPSEL(v) shift(v, 16, NVME_FEAT_TT_TMPSEL_MASK) -#define NVME_FEAT_TT_THSEL(v) shift(v, 20, NVME_FEAT_TT_THSEL_MASK) - -void nvme_feature_decode_temp_threshold(__u32 value, __u16 *tmpth, __u8 *tmpsel, __u8 *thsel) -{ - *tmpth = NVME_FEAT_TT_TMPTH(value); - *tmpsel = NVME_FEAT_TT_TMPSEL(value); - *thsel = NVME_FEAT_TT_THSEL(value); -} - -#define NVME_FEAT_ER_TLER(v) shift(v, 0, NVME_FEAT_ER_TLER_MASK) -#define NVME_FEAT_ER_DULBE(v) shift(v, 16, NVME_FEAT_ER_DULBE_MASK) - -void nvme_feature_decode_error_recovery(__u32 value, __u16 *tler, bool *dulbe) -{ - *tler = NVME_FEAT_ER_TLER(value); - *dulbe = NVME_FEAT_ER_DULBE(value); -} - -#define NVME_FEAT_VWC_WCE(v) shift(v, 0, NVME_FEAT_VWC_WCE_MASK) - -void nvme_feature_decode_volatile_write_cache(__u32 value, bool *wce) -{ - *wce = NVME_FEAT_VWC_WCE(value); -} - -#define NVME_FEAT_NRQS_NSQR(v) shift(v, 0, NVME_FEAT_NRQS_NSQR_MASK) -#define NVME_FEAT_NRQS_NCQR(v) shift(v, 16, NVME_FEAT_NRQS_NCQR_MASK) - -void nvme_feature_decode_number_of_queues(__u32 value, __u16 *nsqr, __u16 *ncqr) -{ - *nsqr = NVME_FEAT_NRQS_NSQR(value); - *ncqr = NVME_FEAT_NRQS_NCQR(value); -} - -#define NVME_FEAT_ICOAL_THR(v) shift(v, 0, NVME_FEAT_ICOAL_THR_MASK) -#define NVME_FEAT_ICOAL_TIME(v) shift(v, 8, NVME_FEAT_ICOAL_TIME_MASK) - -void nvme_feature_decode_interrupt_coalescing(__u32 value, __u8 *thr, __u8 *time) -{ - *thr = NVME_FEAT_ICOAL_THR(value); - *time = NVME_FEAT_ICOAL_TIME(value); -} - -#define NVME_FEAT_ICFG_IV(v) shift(v, 0, NVME_FEAT_ICFG_IV_MASK) -#define NVME_FEAT_ICFG_CD(v) shift(v, 16, NVME_FEAT_ICFG_CD_MASK) - -void nvme_feature_decode_interrupt_config(__u32 value, __u16 *iv, bool *cd) -{ - *iv = NVME_FEAT_ICFG_IV(value); - *cd = NVME_FEAT_ICFG_CD(value); -} - -#define NVME_FEAT_WA_DN(v) shift(v, 0, NVME_FEAT_WA_DN_MASK) - -void nvme_feature_decode_write_atomicity(__u32 value, bool *dn) -{ - *dn = NVME_FEAT_WA_DN(value); -} - -#define NVME_FEAT_AE_SMART(v) shift(v, 0, NVME_FEAT_AE_SMART_MASK) -#define NVME_FEAT_AE_NAN(v) shift(v, 8, NVME_FEAT_AE_NAN_MASK) -#define NVME_FEAT_AE_FW(v) shift(v, 9, NVME_FEAT_AE_FW_MASK) -#define NVME_FEAT_AE_TELEM(v) shift(v, 10, NVME_FEAT_AE_TELEM_MASK) -#define NVME_FEAT_AE_ANA(v) shift(v, 11, NVME_FEAT_AE_ANA_MASK) -#define NVME_FEAT_AE_PLA(v) shift(v, 12, NVME_FEAT_AE_PLA_MASK) -#define NVME_FEAT_AE_LBAS(v) shift(v, 13, NVME_FEAT_AE_LBAS_MASK) -#define NVME_FEAT_AE_EGA(v) shift(v, 14, NVME_FEAT_AE_EGA_MASK) - -void nvme_feature_decode_async_event_config(__u32 value, __u8 *smart, - bool *nan, bool *fw, bool *telem, bool *ana, bool *pla, bool *lbas, - bool *ega) -{ - *smart = NVME_FEAT_AE_SMART(value); - *nan = NVME_FEAT_AE_NAN(value); - *fw = NVME_FEAT_AE_FW(value); - *telem = NVME_FEAT_AE_TELEM(value); - *ana = NVME_FEAT_AE_ANA(value); - *pla = NVME_FEAT_AE_PLA(value); - *lbas = NVME_FEAT_AE_LBAS(value); - *ega = NVME_FEAT_AE_EGA(value); -} - -#define NVME_FEAT_APST_APSTE(v) shift(v, 0, NVME_FEAT_APST_APSTE_MASK) - -void nvme_feature_decode_auto_power_state(__u32 value, bool *apste) -{ - *apste = NVME_FEAT_APST_APSTE(value); -} - -#define NVME_FEAT_HMEM_EHM(v) shift(v, 0, NVME_FEAT_HMEM_EHM_MASK) - -void nvme_feature_decode_host_memory_buffer(__u32 value, bool *ehm) -{ - *ehm = NVME_FEAT_HMEM_EHM(value); -} - -#define NVME_FEAT_HCTM_TMT2(v) shift(v, 0, NVME_FEAT_HCTM_TMT2_MASK) -#define NVME_FEAT_HCTM_TMT1(v) shift(v, 16, NVME_FEAT_HCTM_TMT1_MASK) - -void nvme_feature_decode_host_thermal_mgmt(__u32 value, __u16 *tmt2, __u16 *tmt1) -{ - *tmt2 = NVME_FEAT_HCTM_TMT2(value); - *tmt1 = NVME_FEAT_HCTM_TMT1(value); -} - -#define NVME_FEAT_NOPS_NOPPME(v) shift(v, 0, NVME_FEAT_NOPS_NOPPME_MASK) - -void nvme_feature_decode_non_op_power_config(__u32 value, bool *noppme) -{ - *noppme = NVME_FEAT_NOPS_NOPPME(value); -} - -#define NVME_FEAT_RRL_RRL(v) shift(v, 0, NVME_FEAT_RRL_RRL_MASK) - -void nvme_feature_decode_read_recovery_level_config(__u32 value, __u8 *rrl) -{ - *rrl = NVME_FEAT_RRL_RRL(value); -} - -#define NVME_FEAT_PLM_PLME(v) shift(v, 0, NVME_FEAT_PLM_PLME_MASK) - -void nvme_feature_decode_predictable_latency_mode_config(__u32 value, bool *plme) -{ - *plme = NVME_FEAT_PLM_PLME(value); -} - -#define NVME_FEAT_PLMW_WS(v) shift(v, 0, NVME_FEAT_PLMW_WS_MASK) - -void nvme_feature_decode_predictable_latency_mode_window(__u32 value, __u8 *ws) -{ - *ws = NVME_FEAT_PLMW_WS(value); -} - -#define NVME_FEAT_LBAS_LSIRI(v) shift(v, 0, NVME_FEAT_LBAS_LSIRI_MASK) -#define NVME_FEAT_LBAS_LSIPI(v) shift(v, 16, NVME_FEAT_LBAS_LSIPI_MASK) - -void nvme_feature_decode_lba_status_attributes(__u32 value, __u16 *lsiri, __u16 *lsipi) -{ - *lsiri = NVME_FEAT_LBAS_LSIRI(value); - *lsipi = NVME_FEAT_LBAS_LSIPI(value); -} - -#define NVME_FEAT_SC_NODRM(v) shift(v, 0, NVME_FEAT_SC_NODRM_MASK) - -void nvme_feature_decode_sanitize_config(__u32 value, bool *nodrm) -{ - *nodrm = NVME_FEAT_SC_NODRM(value); -} - -#define NVME_FEAT_EG_ENDGID(v) shift(v, 0, NVME_FEAT_EG_ENDGID_MASK) -#define NVME_FEAT_EG_EGCW(v) shift(v, 16, NVME_FEAT_EG_EGCW_MASK) - -void nvme_feature_decode_endurance_group_event_config(__u32 value, - __u16 *endgid, __u8 *endgcw) -{ - *endgid = NVME_FEAT_EG_ENDGID(value); - *endgcw = NVME_FEAT_EG_EGCW(value); -} - -#define NVME_FEAT_SPM_PBSLC(v) shift(v, 0, NVME_FEAT_SPM_PBSLC_MASK) - -void nvme_feature_decode_software_progress_marker(__u32 value, __u8 *pbslc) -{ - *pbslc = NVME_FEAT_SPM_PBSLC(value); -} - -#define NVME_FEAT_HOSTID_EXHID(v) shift(v, 0, NVME_FEAT_HOSTID_EXHID_MASK) - -void nvme_feature_decode_host_identifier(__u32 value, bool *exhid) -{ - *exhid = NVME_FEAT_HOSTID_EXHID(value); -} - -#define NVME_FEAT_RM_REGPRE(v) shift(v, 1, NVME_FEAT_RM_REGPRE_MASK) -#define NVME_FEAT_RM_RESREL(v) shift(v, 2, NVME_FEAT_RM_RESREL_MASK) -#define NVME_FEAT_RM_RESPRE(v) shift(v, 3, NVME_FEAT_RM_RESPRE_MASK) - -void nvme_feature_decode_reservation_notification(__u32 value, bool *regpre, bool *resrel, bool *respre) -{ - *regpre = NVME_FEAT_RM_REGPRE(value); - *resrel = NVME_FEAT_RM_RESREL(value); - *respre = NVME_FEAT_RM_RESPRE(value); -} - -#define NVME_FEAT_RP_PTPL(v) shift(v, 0, NVME_FEAT_RP_PTPL_MASK) - -void nvme_feature_decode_reservation_persistance(__u32 value, bool *ptpl) -{ - *ptpl = NVME_FEAT_RP_PTPL(value); -} - -#define NVME_FEAT_WP_WPS(v) shift(v, 0, NVME_FEAT_WP_WPS_MASK) - -void nvme_feature_decode_namespace_write_protect(__u32 value, __u8 *wps) -{ - *wps = NVME_FEAT_WP_WPS(value); -} diff --git a/src/nvme/util.h b/src/nvme/util.h index 05629ccb52..6cf607a275 100644 --- a/src/nvme/util.h +++ b/src/nvme/util.h @@ -237,4 +237,336 @@ static inline void nvme_chomp(char *s, int l) s[l--] = '\0'; } +enum { + NVME_FEAT_ARB_BURST_SHIFT = 0, + NVME_FEAT_ARB_BURST_MASK = 0x7, + NVME_FEAT_ARB_LPW_SHIFT = 8, + NVME_FEAT_ARB_LPW_MASK = 0xff, + NVME_FEAT_ARB_MPW_SHIFT = 16, + NVME_FEAT_ARB_MPW_MASK = 0xff, + NVME_FEAT_ARB_HPW_SHIFT = 24, + NVME_FEAT_ARB_HPW_MASK = 0xff, + NVME_FEAT_PM_PS_SHIFT = 0, + NVME_FEAT_PM_PS_MASK = 0x1f, + NVME_FEAT_PM_WH_SHIFT = 5, + NVME_FEAT_PM_WH_MASK = 0x7, + NVME_FEAT_LBAR_NR_SHIFT = 0, + NVME_FEAT_LBAR_NR_MASK = 0x3f, + NVME_FEAT_TT_TMPTH_SHIFT = 0, + NVME_FEAT_TT_TMPTH_MASK = 0xffff, + NVME_FEAT_TT_TMPSEL_SHIFT = 16, + NVME_FEAT_TT_TMPSEL_MASK = 0xf, + NVME_FEAT_TT_THSEL_SHIFT = 20, + NVME_FEAT_TT_THSEL_MASK = 0x3, + NVME_FEAT_ER_TLER_SHIFT = 0, + NVME_FEAT_ER_TLER_MASK = 0xffff, + NVME_FEAT_ER_DULBE_SHIFT = 16, + NVME_FEAT_ER_DULBE_MASK = 0x1, + NVME_FEAT_VWC_WCE_SHIFT = 0, + NVME_FEAT_VWC_WCE_MASK = 0x1, + NVME_FEAT_NRQS_NSQR_SHIFT = 0, + NVME_FEAT_NRQS_NSQR_MASK = 0xffff, + NVME_FEAT_NRQS_NCQR_SHIFT = 16, + NVME_FEAT_NRQS_NCQR_MASK = 0xffff, + NVME_FEAT_ICOAL_THR_SHIFT = 0, + NVME_FEAT_ICOAL_THR_MASK = 0xff, + NVME_FEAT_ICOAL_TIME_SHIFT = 8, + NVME_FEAT_ICOAL_TIME_MASK = 0xff, + NVME_FEAT_ICFG_IV_SHIFT = 0, + NVME_FEAT_ICFG_IV_MASK = 0xffff, + NVME_FEAT_ICFG_CD_SHIFT = 16, + NVME_FEAT_ICFG_CD_MASK = 0x1, + NVME_FEAT_WA_DN_SHIFT = 0, + NVME_FEAT_WA_DN_MASK = 0x1, + NVME_FEAT_AE_SMART_SHIFT = 0, + NVME_FEAT_AE_SMART_MASK = 0xff, + NVME_FEAT_AE_NAN_SHIFT = 8, + NVME_FEAT_AE_NAN_MASK = 0x1, + NVME_FEAT_AE_FW_SHIFT = 9, + NVME_FEAT_AE_FW_MASK = 0x1, + NVME_FEAT_AE_TELEM_SHIFT = 10, + NVME_FEAT_AE_TELEM_MASK = 0x1, + NVME_FEAT_AE_ANA_SHIFT = 11, + NVME_FEAT_AE_ANA_MASK = 0x1, + NVME_FEAT_AE_PLA_SHIFT = 12, + NVME_FEAT_AE_PLA_MASK = 0x1, + NVME_FEAT_AE_LBAS_SHIFT = 13, + NVME_FEAT_AE_LBAS_MASK = 0x1, + NVME_FEAT_AE_EGA_SHIFT = 14, + NVME_FEAT_AE_EGA_MASK = 0x1, + NVME_FEAT_APST_APSTE_SHIFT = 0, + NVME_FEAT_APST_APSTE_MASK = 0x1, + NVME_FEAT_HMEM_EHM_SHIFT = 0, + NVME_FEAT_HMEM_EHM_MASK = 0x1, + NVME_FEAT_HCTM_TMT2_SHIFT = 0, + NVME_FEAT_HCTM_TMT2_MASK = 0xffff, + NVME_FEAT_HCTM_TMT1_SHIFT = 16, + NVME_FEAT_HCTM_TMT1_MASK = 0xffff, + NVME_FEAT_NOPS_NOPPME_SHIFT = 0, + NVME_FEAT_NOPS_NOPPME_MASK = 0x1, + NVME_FEAT_RRL_RRL_SHIFT = 0, + NVME_FEAT_RRL_RRL_MASK = 0xff, + NVME_FEAT_PLM_PLME_SHIFT = 0, + NVME_FEAT_PLM_PLME_MASK = 0x1, + NVME_FEAT_PLMW_WS_SHIFT = 0, + NVME_FEAT_PLMW_WS_MASK = 0x7, + NVME_FEAT_LBAS_LSIRI_SHIFT = 0, + NVME_FEAT_LBAS_LSIRI_MASK = 0xffff, + NVME_FEAT_LBAS_LSIPI_SHIFT = 16, + NVME_FEAT_LBAS_LSIPI_MASK = 0xffff, + NVME_FEAT_SC_NODRM_SHIFT = 0, + NVME_FEAT_SC_NODRM_MASK = 0x1, + NVME_FEAT_EG_ENDGID_SHIFT = 0, + NVME_FEAT_EG_ENDGID_MASK = 0xffff, + NVME_FEAT_EG_EGCW_SHIFT = 16, + NVME_FEAT_EG_EGCW_MASK = 0xff, + NVME_FEAT_SPM_PBSLC_SHIFT = 0, + NVME_FEAT_SPM_PBSLC_MASK = 0xff, + NVME_FEAT_HOSTID_EXHID_SHIFT = 0, + NVME_FEAT_HOSTID_EXHID_MASK = 0x1, + NVME_FEAT_RM_REGPRE_SHIFT = 1, + NVME_FEAT_RM_REGPRE_MASK = 0x1, + NVME_FEAT_RM_RESREL_SHIFT = 2, + NVME_FEAT_RM_RESREL_MASK = 0x1, + NVME_FEAT_RM_RESPRE_SHIFT = 0x3, + NVME_FEAT_RM_RESPRE_MASK = 0x1, + NVME_FEAT_RP_PTPL_SHIFT = 0, + NVME_FEAT_RP_PTPL_MASK = 0x1, + NVME_FEAT_WP_WPS_SHIFT = 0, + NVME_FEAT_WP_WPS_MASK = 0x7, + NVME_FEAT_IOCSP_IOCSCI_SHIFT = 0, + NVME_FEAT_IOCSP_IOCSCI_MASK = 0xff, +}; + +#define NVME_FEAT_ARB_BURST(v) NVME_GET(FEAT_ARB_BURST, v) +#define NVME_FEAT_ARB_LPW(v) NVME_GET(FEAT_ARB_LPW, v) +#define NVME_FEAT_ARB_MPW(v) NVME_GET(FEAT_ARB_MPW, v) +#define NVME_FEAT_ARB_HPW(v) NVME_GET(FEAT_ARB_HPW, v) + +inline void nvme_feature_decode_arbitration(__u32 value, __u8 *ab, __u8 *lpw, + __u8 *mpw, __u8 *hpw) +{ + *ab = NVME_FEAT_ARB_BURST(value); + *lpw = NVME_FEAT_ARB_LPW(value); + *mpw = NVME_FEAT_ARB_MPW(value); + *hpw = NVME_FEAT_ARB_HPW(value); +}; + +#define NVME_FEAT_PM_PS(v) NVME_GET(FEAT_PM_PS, v) +#define NVME_FEAT_PM_WH(v) NVME_GET(FEAT_PM_WH, v) + +inline void nvme_feature_decode_power_mgmt(__u32 value, __u8 *ps, __u8 *wh) +{ + *ps = NVME_FEAT_PM_PS(value); + *wh = NVME_FEAT_PM_WH(value); +} + +#define NVME_FEAT_LBAR_NR(v) NVME_GET(FEAT_LBAR_NR, v) + +inline void nvme_feature_decode_lba_range(__u32 value, __u8 *num) +{ + *num = NVME_FEAT_LBAR_NR(value); +} + +#define NVME_FEAT_TT_TMPTH(v) NVME_GET(FEAT_TT_TMPTH, v) +#define NVME_FEAT_TT_TMPSEL(v) NVME_GET(FEAT_TT_TMPSEL, v) +#define NVME_FEAT_TT_THSEL(v) NVME_GET(FEAT_TT_THSEL, v) + +inline void nvme_feature_decode_temp_threshold(__u32 value, __u16 *tmpth, + __u8 *tmpsel, __u8 *thsel) +{ + *tmpth = NVME_FEAT_TT_TMPTH(value); + *tmpsel = NVME_FEAT_TT_TMPSEL(value); + *thsel = NVME_FEAT_TT_THSEL(value); +} + +#define NVME_FEAT_ER_TLER(v) NVME_GET(FEAT_ER_TLER, v) +#define NVME_FEAT_ER_DULBE(v) NVME_GET(FEAT_ER_DULBE, v) + +inline void nvme_feature_decode_error_recovery(__u32 value, __u16 *tler, bool *dulbe) +{ + *tler = NVME_FEAT_ER_TLER(value); + *dulbe = NVME_FEAT_ER_DULBE(value); +} + +#define NVME_FEAT_VWC_WCE(v) NVME_GET(FEAT_VWC_WCE, v) + +inline void nvme_feature_decode_volatile_write_cache(__u32 value, bool *wce) +{ + *wce = NVME_FEAT_VWC_WCE(value); +} + +#define NVME_FEAT_NRQS_NSQR(v) NVME_GET(FEAT_NRQS_NSQR, v) +#define NVME_FEAT_NRQS_NCQR(v) NVME_GET(FEAT_NRQS_NCQR, v) + +inline void nvme_feature_decode_number_of_queues(__u32 value, __u16 *nsqr, __u16 *ncqr) +{ + *nsqr = NVME_FEAT_NRQS_NSQR(value); + *ncqr = NVME_FEAT_NRQS_NCQR(value); +} + +#define NVME_FEAT_ICOAL_THR(v) NVME_GET(FEAT_ICOAL_THR, v) +#define NVME_FEAT_ICOAL_TIME(v) NVME_GET(FEAT_ICOAL_TIME, v) + +inline void nvme_feature_decode_interrupt_coalescing(__u32 value, __u8 *thr, __u8 *time) +{ + *thr = NVME_FEAT_ICOAL_THR(value); + *time = NVME_FEAT_ICOAL_TIME(value); +} + +#define NVME_FEAT_ICFG_IV(v) NVME_GET(FEAT_ICFG_IV, v) +#define NVME_FEAT_ICFG_CD(v) NVME_GET(FEAT_ICFG_CD, v) + +inline void nvme_feature_decode_interrupt_config(__u32 value, __u16 *iv, bool *cd) +{ + *iv = NVME_FEAT_ICFG_IV(value); + *cd = NVME_FEAT_ICFG_CD(value); +} + +#define NVME_FEAT_WA_DN(v) NVME_GET(FEAT_WA_DN, v) + +inline void nvme_feature_decode_write_atomicity(__u32 value, bool *dn) +{ + *dn = NVME_FEAT_WA_DN(value); +} + +#define NVME_FEAT_AE_SMART(v) NVME_GET(FEAT_AE_SMART, v) +#define NVME_FEAT_AE_NAN(v) NVME_GET(FEAT_AE_NAN, v) +#define NVME_FEAT_AE_FW(v) NVME_GET(FEAT_AE_FW, v) +#define NVME_FEAT_AE_TELEM(v) NVME_GET(FEAT_AE_TELEM, v) +#define NVME_FEAT_AE_ANA(v) NVME_GET(FEAT_AE_ANA, v) +#define NVME_FEAT_AE_PLA(v) NVME_GET(FEAT_AE_PLA, v) +#define NVME_FEAT_AE_LBAS(v) NVME_GET(FEAT_AE_LBAS, v) +#define NVME_FEAT_AE_EGA(v) NVME_GET(FEAT_AE_EGA, v) + +inline void nvme_feature_decode_async_event_config(__u32 value, __u8 *smart, + bool *nan, bool *fw, bool *telem, bool *ana, bool *pla, bool *lbas, + bool *ega) +{ + *smart = NVME_FEAT_AE_SMART(value); + *nan = NVME_FEAT_AE_NAN(value); + *fw = NVME_FEAT_AE_FW(value); + *telem = NVME_FEAT_AE_TELEM(value); + *ana = NVME_FEAT_AE_ANA(value); + *pla = NVME_FEAT_AE_PLA(value); + *lbas = NVME_FEAT_AE_LBAS(value); + *ega = NVME_FEAT_AE_EGA(value); +} + +#define NVME_FEAT_APST_APSTE(v) NVME_GET(FEAT_APST_APSTE, v) + +inline void nvme_feature_decode_auto_power_state(__u32 value, bool *apste) +{ + *apste = NVME_FEAT_APST_APSTE(value); +} + +#define NVME_FEAT_HMEM_EHM(v) NVME_GET(FEAT_HMEM_EHM, v) + +inline void nvme_feature_decode_host_memory_buffer(__u32 value, bool *ehm) +{ + *ehm = NVME_FEAT_HMEM_EHM(value); +} + +#define NVME_FEAT_HCTM_TMT2(v) NVME_GET(FEAT_HCTM_TMT2, v) +#define NVME_FEAT_HCTM_TMT1(v) NVME_GET(FEAT_HCTM_TMT1, v) + +inline void nvme_feature_decode_host_thermal_mgmt(__u32 value, __u16 *tmt2, __u16 *tmt1) +{ + *tmt2 = NVME_FEAT_HCTM_TMT2(value); + *tmt1 = NVME_FEAT_HCTM_TMT1(value); +} + +#define NVME_FEAT_NOPS_NOPPME(v) NVME_GET(FEAT_NOPS_NOPPME, v) + +inline void nvme_feature_decode_non_op_power_config(__u32 value, bool *noppme) +{ + *noppme = NVME_FEAT_NOPS_NOPPME(value); +} + +#define NVME_FEAT_RRL_RRL(v) NVME_GET(FEAT_RRL_RRL, v) + +inline void nvme_feature_decode_read_recovery_level_config(__u32 value, __u8 *rrl) +{ + *rrl = NVME_FEAT_RRL_RRL(value); +} + +#define NVME_FEAT_PLM_PLME(v) NVME_GET(FEAT_PLM_PLME, v) + +inline void nvme_feature_decode_predictable_latency_mode_config(__u32 value, bool *plme) +{ + *plme = NVME_FEAT_PLM_PLME(value); +} + +#define NVME_FEAT_PLMW_WS(v) NVME_GET(FEAT_PLMW_WS, v) + +inline void nvme_feature_decode_predictable_latency_mode_window(__u32 value, __u8 *ws) +{ + *ws = NVME_FEAT_PLMW_WS(value); +} + +#define NVME_FEAT_LBAS_LSIRI(v) NVME_GET(FEAT_LBAS_LSIRI, v) +#define NVME_FEAT_LBAS_LSIPI(v) NVME_GET(FEAT_LBAS_LSIPI, v) + +inline void nvme_feature_decode_lba_status_attributes(__u32 value, __u16 *lsiri, __u16 *lsipi) +{ + *lsiri = NVME_FEAT_LBAS_LSIRI(value); + *lsipi = NVME_FEAT_LBAS_LSIPI(value); +} + +#define NVME_FEAT_SC_NODRM(v) NVME_GET(FEAT_SC_NODRM, v) + +inline void nvme_feature_decode_sanitize_config(__u32 value, bool *nodrm) +{ + *nodrm = NVME_FEAT_SC_NODRM(value); +} + +#define NVME_FEAT_EG_ENDGID(v) NVME_GET(FEAT_EG_ENDGID, v) +#define NVME_FEAT_EG_EGCW(v) NVME_GET(FEAT_EG_EGCW, v) + +inline void nvme_feature_decode_endurance_group_event_config(__u32 value, + __u16 *endgid, __u8 *endgcw) +{ + *endgid = NVME_FEAT_EG_ENDGID(value); + *endgcw = NVME_FEAT_EG_EGCW(value); +} + +#define NVME_FEAT_SPM_PBSLC(v) NVME_GET(FEAT_SPM_PBSLC, v) + +inline void nvme_feature_decode_software_progress_marker(__u32 value, __u8 *pbslc) +{ + *pbslc = NVME_FEAT_SPM_PBSLC(value); +} + +#define NVME_FEAT_HOSTID_EXHID(v) NVME_GET(FEAT_HOSTID_EXHID, v) + +inline void nvme_feature_decode_host_identifier(__u32 value, bool *exhid) +{ + *exhid = NVME_FEAT_HOSTID_EXHID(value); +} + +#define NVME_FEAT_RM_REGPRE(v) NVME_GET(FEAT_RM_REGPRE, v) +#define NVME_FEAT_RM_RESREL(v) NVME_GET(FEAT_RM_RESREL, v) +#define NVME_FEAT_RM_RESPRE(v) NVME_GET(FEAT_RM_RESPRE, v) + +inline void nvme_feature_decode_reservation_notification(__u32 value, bool *regpre, + bool *resrel, bool *respre) +{ + *regpre = NVME_FEAT_RM_REGPRE(value); + *resrel = NVME_FEAT_RM_RESREL(value); + *respre = NVME_FEAT_RM_RESPRE(value); +} + +#define NVME_FEAT_RP_PTPL(v) NVME_GET(FEAT_RP_PTPL, v) + +inline void nvme_feature_decode_reservation_persistance(__u32 value, bool *ptpl) +{ + *ptpl = NVME_FEAT_RP_PTPL(value); +} + +#define NVME_FEAT_WP_WPS(v) NVME_GET(FEAT_WP_WPS, v) + +inline void nvme_feature_decode_namespace_write_protect(__u32 value, __u8 *wps) +{ + *wps = NVME_FEAT_WP_WPS(value); +} #endif /* _LIBNVME_UTIL_H */ From 5f857ba56c78f5826f961d19c653e0d3ed77c46b Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Tue, 9 Jun 2020 09:49:58 -0700 Subject: [PATCH 0057/1564] common code all the complex value accessors Signed-off-by: Keith Busch --- src/nvme/ioctl.c | 177 +++++++++++++++++++++++------------------------ src/nvme/types.h | 159 +++++++++++++++++++++--------------------- src/nvme/util.h | 156 ++++++++++++++++++++--------------------- 3 files changed, 246 insertions(+), 246 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index d02df36f0c..0730f866c9 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -20,6 +20,7 @@ #include #include "ioctl.h" +#include "util.h" static int nvme_verify_chr(int fd) { @@ -355,16 +356,14 @@ enum features { NVME_FEATURES_IOCSP_IOCSCI_MASK = 0xff, }; -#define DW(value, prefix) ((value) & (prefix ## _MASK)) << prefix ## _SHIFT - int nvme_identify(int fd, enum nvme_identify_cns cns, __u32 nsid, __u16 cntid, __u16 nvmsetid, __u8 uuidx, __u8 csi, void *data) { - __u32 cdw10 = DW(cntid, NVME_IDENTIFY_CDW10_CNTID) | - DW(cns, NVME_IDENTIFY_CDW10_CNS); - __u32 cdw11 = DW(nvmsetid, NVME_IDENTIFY_CDW11_NVMSETID) | - DW(csi, NVME_IDENTIFY_CDW11_CSI); - __u32 cdw14 = DW(uuidx, NVME_IDENTIFY_CDW14_UUID); + __u32 cdw10 = NVME_SET(cntid, IDENTIFY_CDW10_CNTID) | + NVME_SET(cns, IDENTIFY_CDW10_CNS); + __u32 cdw11 = NVME_SET(nvmsetid, IDENTIFY_CDW11_NVMSETID) | + NVME_SET(csi, IDENTIFY_CDW11_CSI); + __u32 cdw14 = NVME_SET(uuidx, IDENTIFY_CDW14_UUID); struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_identify, @@ -526,16 +525,16 @@ int nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, __u32 numd = (len >> 2) - 1; __u16 numdu = numd >> 16, numdl = numd & 0xffff; - __u32 cdw10 = DW(lid, NVME_LOG_CDW10_LID) | - DW(lsp, NVME_LOG_CDW10_LSP) | - DW(!!rae, NVME_LOG_CDW10_RAE) | - DW(numdl, NVME_LOG_CDW10_NUMDL); - __u32 cdw11 = DW(numdu, NVME_LOG_CDW11_NUMDU) | - DW(lsi, NVME_LOG_CDW11_LSI); + __u32 cdw10 = NVME_SET(lid, LOG_CDW10_LID) | + NVME_SET(lsp, LOG_CDW10_LSP) | + NVME_SET(!!rae, LOG_CDW10_RAE) | + NVME_SET(numdl, LOG_CDW10_NUMDL); + __u32 cdw11 = NVME_SET(numdu, LOG_CDW11_NUMDU) | + NVME_SET(lsi, LOG_CDW11_LSI); __u32 cdw12 = lpo & 0xffffffff; __u32 cdw13 = lpo >> 32; - __u32 cdw14 = DW(uuidx, NVME_LOG_CDW14_UUID) | - DW(csi, NVME_LOG_CDW14_CSI); + __u32 cdw14 = NVME_SET(uuidx, LOG_CDW14_UUID) | + NVME_SET(csi, LOG_CDW14_CSI); struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_get_log_page, @@ -731,9 +730,9 @@ int nvme_set_features(int fd, __u8 fid, __u32 nsid, __u32 cdw11, __u32 cdw12, bool save, __u8 uuidx, __u32 cdw15, __u32 data_len, void *data, __u32 *result) { - __u32 cdw10 = DW(fid, NVME_FEATURES_CDW10_FID) | - DW(!!save, NVME_SET_FEATURES_CDW10_SAVE); - __u32 cdw14 = DW(uuidx, NVME_FEATURES_CDW14_UUID); + __u32 cdw10 = NVME_SET(fid, FEATURES_CDW10_FID) | + NVME_SET(!!save, SET_FEATURES_CDW10_SAVE); + __u32 cdw14 = NVME_SET(uuidx, FEATURES_CDW14_UUID); struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_set_features, @@ -760,10 +759,10 @@ static int __nvme_set_features(int fd, __u8 fid, __u32 cdw11, bool save, int nvme_set_features_arbitration(int fd, __u8 ab, __u8 lpw, __u8 mpw, __u8 hpw, bool save, __u32 *result) { - __u32 value = DW(ab, NVME_FEATURES_ARBITRATION_BURST) | - DW(lpw, NVME_FEATURES_ARBITRATION_LPW) | - DW(mpw, NVME_FEATURES_ARBITRATION_MPW) | - DW(hpw, NVME_FEATURES_ARBITRATION_HPW); + __u32 value = NVME_SET(ab, FEAT_ARBITRATION_BURST) | + NVME_SET(lpw, FEAT_ARBITRATION_LPW) | + NVME_SET(mpw, FEAT_ARBITRATION_MPW) | + NVME_SET(hpw, FEAT_ARBITRATION_HPW); return __nvme_set_features(fd, NVME_FEAT_FID_ARBITRATION, value, save, result); @@ -772,8 +771,8 @@ int nvme_set_features_arbitration(int fd, __u8 ab, __u8 lpw, __u8 mpw, int nvme_set_features_power_mgmt(int fd, __u8 ps, __u8 wh, bool save, __u32 *result) { - __u32 value = DW(ps, NVME_FEATURES_PWRMGMT_PS) | - DW(wh, NVME_FEATURES_PWRMGMT_PS); + __u32 value = NVME_SET(ps, FEAT_PWRMGMT_PS) | + NVME_SET(wh, FEAT_PWRMGMT_PS); return __nvme_set_features(fd, NVME_FEAT_FID_POWER_MGMT, value, save, result); @@ -788,9 +787,9 @@ int nvme_set_features_lba_range(int fd, __u32 nsid, __u32 nr_ranges, bool save, int nvme_set_features_temp_thresh(int fd, __u16 tmpth, __u8 tmpsel, enum nvme_feat_tmpthresh_thsel thsel, bool save, __u32 *result) { - __u32 value = DW(tmpth, NVME_FEATURES_TMPTH) | - DW(tmpsel, NVME_FEATURES_TMPSEL) | - DW(thsel, NVME_FEATURES_THSEL); + __u32 value = NVME_SET(tmpth, FEAT_TT_TMPTH) | + NVME_SET(tmpsel, FEAT_TT_TMPSEL) | + NVME_SET(thsel, FEAT_TT_THSEL); return __nvme_set_features(fd, NVME_FEAT_FID_TEMP_THRESH, value, save, result); @@ -799,8 +798,8 @@ int nvme_set_features_temp_thresh(int fd, __u16 tmpth, __u8 tmpsel, int nvme_set_features_err_recovery(int fd, __u32 nsid, __u16 tler, bool dulbe, bool save, __u32 *result) { - __u32 value = DW(tler, NVME_FEATURES_ERROR_RECOVERY_TLER) | - DW(!!dulbe, NVME_FEATURES_ERROR_RECOVERY_DULBE); + __u32 value = NVME_SET(tler, FEAT_ERROR_RECOVERY_TLER) | + NVME_SET(!!dulbe, FEAT_ERROR_RECOVERY_DULBE); return __nvme_set_features(fd, NVME_FEAT_FID_ERR_RECOVERY, value, save, result); @@ -808,7 +807,7 @@ int nvme_set_features_err_recovery(int fd, __u32 nsid, __u16 tler, bool dulbe, int nvme_set_features_volatile_wc(int fd, bool wce, bool save, __u32 *result) { - __u32 value = DW(!!wce, NVME_FEATURES_VWC_WCE); + __u32 value = NVME_SET(!!wce, FEAT_VWC_WCE); return __nvme_set_features(fd, NVME_FEAT_FID_VOLATILE_WC, value, save, result); @@ -817,8 +816,8 @@ int nvme_set_features_volatile_wc(int fd, bool wce, bool save, __u32 *result) int nvme_set_features_irq_coalesce(int fd, __u8 thr, __u8 time, bool save, __u32 *result) { - __u32 value = DW(thr, NVME_FEATURES_IRQC_TIME) | - DW(time, NVME_FEATURES_IRQC_THR); + __u32 value = NVME_SET(thr, FEAT_IRQC_TIME) | + NVME_SET(time, FEAT_IRQC_THR); return __nvme_set_features(fd, NVME_FEAT_FID_IRQ_COALESCE, value, save, result); @@ -827,8 +826,8 @@ int nvme_set_features_irq_coalesce(int fd, __u8 thr, __u8 time, bool save, int nvme_set_features_irq_config(int fd, __u16 iv, bool cd, bool save, __u32 *result) { - __u32 value = DW(iv, NVME_FEATURES_IVC_IV) | - DW(!!cd, NVME_FEATURES_IVC_CD); + __u32 value = NVME_SET(iv, FEAT_ICFG_IV) | + NVME_SET(!!cd, FEAT_ICFG_CD); return __nvme_set_features(fd, NVME_FEAT_FID_IRQ_CONFIG, value, save, result); @@ -836,7 +835,7 @@ int nvme_set_features_irq_config(int fd, __u16 iv, bool cd, bool save, int nvme_set_features_write_atomic(int fd, bool dn, bool save, __u32 *result) { - __u32 value = DW(!!dn, NVME_FEATURES_WAN_DN); + __u32 value = NVME_SET(!!dn, FEAT_WA_DN); return __nvme_set_features(fd, NVME_FEAT_FID_WRITE_ATOMIC, value, save, result); @@ -852,7 +851,7 @@ int nvme_set_features_async_event(int fd, __u32 events, int nvme_set_features_auto_pst(int fd, bool apste, bool save, struct nvme_feat_auto_pst *apst, __u32 *result) { - __u32 value = DW(!!apste, NVME_FEATURES_APST_APSTE); + __u32 value = NVME_SET(!!apste, FEAT_APST_APSTE); return __nvme_set_features(fd, NVME_FEAT_FID_AUTO_PST, value, save, result); @@ -872,8 +871,8 @@ int nvme_set_features_timestamp(int fd, bool save, __u64 timestamp) int nvme_set_features_hctm(int fd, __u16 tmt2, __u16 tmt1, bool save, __u32 *result) { - __u32 value = DW(tmt2, NVME_FEATURES_HCTM_TMT2) | - DW(tmt1, NVME_FEATURES_HCTM_TMT1); + __u32 value = NVME_SET(tmt2, FEAT_HCTM_TMT2) | + NVME_SET(tmt1, FEAT_HCTM_TMT1); return __nvme_set_features(fd, NVME_FEAT_FID_HCTM, value, save, result); @@ -881,7 +880,7 @@ int nvme_set_features_hctm(int fd, __u16 tmt2, __u16 tmt1, int nvme_set_features_nopsc(int fd, bool noppme, bool save, __u32 *result) { - __u32 value = DW(noppme, NVME_FEATURES_NOPS_NOPPME); + __u32 value = NVME_SET(noppme, FEAT_NOPS_NOPPME); return __nvme_set_features(fd, NVME_FEAT_FID_NOPSC, value, save, result); @@ -906,7 +905,7 @@ int nvme_set_features_plm_config(int fd, bool plm, __u16 nvmsetid, bool save, int nvme_set_features_plm_window(int fd, enum nvme_feat_plm_window_select sel, __u16 nvmsetid, bool save, __u32 *result) { - __u32 cdw12 = DW(sel, NVME_FEATURES_PLM_WINDOW_SELECT); + __u32 cdw12 = NVME_SET(sel, FEAT_PLMW_WS); return nvme_set_features(fd, NVME_FEAT_FID_PLM_WINDOW, NVME_NSID_NONE, nvmsetid, cdw12, save, NVME_UUID_NONE, 0, 0, @@ -916,8 +915,8 @@ int nvme_set_features_plm_window(int fd, enum nvme_feat_plm_window_select sel, int nvme_set_features_lba_sts_interval(int fd, __u16 lsiri, __u16 lsipi, bool save, __u32 *result) { - __u32 value = DW(lsiri, NVME_FEATURES_LBAS_LSIRI) | - DW(lsipi, NVME_FEATURES_LBAS_LSIPI); + __u32 value = NVME_SET(lsiri, FEAT_LBAS_LSIRI) | + NVME_SET(lsipi, FEAT_LBAS_LSIPI); return __nvme_set_features(fd, NVME_FEAT_FID_LBA_STS_INTERVAL, value, save, result); @@ -983,7 +982,7 @@ int nvme_set_features_write_protect(int fd, enum nvme_feat_nswpcfg_state state, int nvme_set_features_iocs_profile(int fd, __u8 iocsi, bool save) { - __u32 value = DW(iocsi, NVME_FEATURES_IOCSP_IOCSCI); + __u32 value = NVME_SET(iocsi, FEAT_IOCSP_IOCSCI); return __nvme_set_features(fd, NVME_FEAT_FID_IOCS_PROFILE, value, save, NULL); @@ -993,9 +992,9 @@ int nvme_get_features(int fd, enum nvme_features_id fid, __u32 nsid, enum nvme_get_features_sel sel, __u32 cdw11, __u8 uuidx, __u32 data_len, void *data, __u32 *result) { - __u32 cdw10 = DW(fid, NVME_FEATURES_CDW10_FID) | - DW(sel, NVME_GET_FEATURES_CDW10_SEL); - __u32 cdw14 = DW(uuidx, NVME_FEATURES_CDW14_UUID); + __u32 cdw10 = NVME_SET(fid, FEATURES_CDW10_FID) | + NVME_SET(sel, GET_FEATURES_CDW10_SEL); + __u32 cdw14 = NVME_SET(uuidx, FEATURES_CDW14_UUID); struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_get_features, @@ -1218,11 +1217,11 @@ int nvme_format_nvm(int fd, __u32 nsid, __u8 lbaf, enum nvme_cmd_format_pil pil, enum nvme_cmd_format_ses ses, __u32 timeout) { - __u32 cdw10 = DW(lbaf, NVME_FORMAT_CDW10_LBAF) | - DW(mset, NVME_FORMAT_CDW10_MSET) | - DW(pi, NVME_FORMAT_CDW10_PI) | - DW(pil, NVME_FORMAT_CDW10_PIL) | - DW(ses, NVME_FORMAT_CDW10_SES); + __u32 cdw10 = NVME_SET(lbaf, FORMAT_CDW10_LBAF) | + NVME_SET(mset, FORMAT_CDW10_MSET) | + NVME_SET(pi, FORMAT_CDW10_PI) | + NVME_SET(pil, FORMAT_CDW10_PIL) | + NVME_SET(ses, FORMAT_CDW10_SES); struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_format_nvm, @@ -1237,7 +1236,7 @@ int nvme_format_nvm(int fd, __u32 nsid, __u8 lbaf, int nvme_ns_mgmt(int fd, __u32 nsid, enum nvme_ns_mgmt_sel sel, struct nvme_id_ns *ns, __u32 *result, __u32 timeout) { - __u32 cdw10 = DW(sel, NVME_NAMESPACE_MGMT_CDW10_SEL); + __u32 cdw10 = NVME_SET(sel, NAMESPACE_MGMT_CDW10_SEL); __u32 data_len = ns ? sizeof(*ns) : 0; struct nvme_passthru_cmd cmd = { @@ -1267,7 +1266,7 @@ int nvme_ns_mgmt_delete(int fd, __u32 nsid) int nvme_ns_attach(int fd, __u32 nsid, enum nvme_ns_attach_sel sel, struct nvme_ctrl_list *ctrlist) { - __u32 cdw10 = DW(sel, NVME_NAMESPACE_ATTACH_CDW10_SEL); + __u32 cdw10 = NVME_SET(sel, NAMESPACE_ATTACH_CDW10_SEL); struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_ns_attach, @@ -1309,9 +1308,9 @@ int nvme_fw_download(int fd, __u32 offset, __u32 data_len, void *data) int nvme_fw_commit(int fd, __u8 slot, enum nvme_fw_commit_ca action, bool bpid) { - __u32 cdw10 = DW(slot, NVME_FW_COMMIT_CDW10_FS) | - DW(action, NVME_FW_COMMIT_CDW10_CA) | - DW(bpid, NVME_FW_COMMIT_CDW10_BPID); + __u32 cdw10 = NVME_SET(slot, FW_COMMIT_CDW10_FS) | + NVME_SET(action, FW_COMMIT_CDW10_CA) | + NVME_SET(bpid, FW_COMMIT_CDW10_BPID); struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_fw_commit, @@ -1325,10 +1324,10 @@ int nvme_security_send(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, __u8 secp, __u32 tl, __u32 data_len, void *data, __u32 *result) { - __u32 cdw10 = DW(secp, NVME_SECURITY_SECP) | - DW(spsp0, NVME_SECURITY_SPSP0) | - DW(spsp1, NVME_SECURITY_SPSP1) | - DW(nssf, NVME_SECURITY_NSSF); + __u32 cdw10 = NVME_SET(secp, SECURITY_SECP) | + NVME_SET(spsp0, SECURITY_SPSP0) | + NVME_SET(spsp1, SECURITY_SPSP1) | + NVME_SET(nssf, SECURITY_NSSF); __u32 cdw11 = tl; struct nvme_passthru_cmd cmd = { @@ -1347,10 +1346,10 @@ int nvme_security_receive(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, __u8 secp, __u32 al, __u32 data_len, void *data, __u32 *result) { - __u32 cdw10 = DW(secp, NVME_SECURITY_SECP) | - DW(spsp0, NVME_SECURITY_SPSP0) | - DW(spsp1, NVME_SECURITY_SPSP1) | - DW(nssf, NVME_SECURITY_NSSF); + __u32 cdw10 = NVME_SET(secp, SECURITY_SECP) | + NVME_SET(spsp0, SECURITY_SPSP0) | + NVME_SET(spsp1, SECURITY_SPSP1) | + NVME_SET(nssf, SECURITY_NSSF); __u32 cdw11 = al; struct nvme_passthru_cmd cmd = { @@ -1372,8 +1371,8 @@ int nvme_get_lba_status(int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl, __u32 cdw10 = slba & 0xffffffff; __u32 cdw11 = slba >> 32; __u32 cdw12 = mndw; - __u32 cdw13 = DW(rl, NVME_GET_LBA_STATUS_CDW13_RL) | - DW(atype, NVME_GET_LBA_STATUS_CDW13_ATYPE); + __u32 cdw13 = NVME_SET(rl, GET_LBA_STATUS_CDW13_RL) | + NVME_SET(atype, GET_LBA_STATUS_CDW13_ATYPE); struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_get_lba_status, @@ -1394,9 +1393,9 @@ int nvme_directive_send(int fd, __u32 nsid, __u16 dspec, __u32 data_len, void *data, __u32 *result) { __u32 cdw10 = data_len ? (data_len >> 2) - 1 : 0; - __u32 cdw11 = DW(doper, NVME_DIRECTIVE_CDW11_DOPER) | - DW(dtype, NVME_DIRECTIVE_CDW11_DTYPE) | - DW(dspec, NVME_DIRECTIVE_CDW11_DPSEC); + __u32 cdw11 = NVME_SET(doper, DIRECTIVE_CDW11_DOPER) | + NVME_SET(dtype, DIRECTIVE_CDW11_DTYPE) | + NVME_SET(dspec, DIRECTIVE_CDW11_DPSEC); struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_directive_send, @@ -1415,8 +1414,8 @@ int nvme_directive_send_id_endir(int fd, __u32 nsid, bool endir, enum nvme_directive_dtype dtype, struct nvme_id_directives *id) { - __u32 cdw12 = DW(dtype, NVME_DIRECTIVE_SEND_IDENTIFY_CDW12_DTYPE) | - DW(endir, NVME_DIRECTIVE_SEND_IDENTIFY_CDW12_ENDIR); + __u32 cdw12 = NVME_SET(dtype, DIRECTIVE_SEND_IDENTIFY_CDW12_DTYPE) | + NVME_SET(endir, DIRECTIVE_SEND_IDENTIFY_CDW12_ENDIR); return nvme_directive_send(fd, nsid, 0, NVME_DIRECTIVE_DTYPE_IDENTIFY, NVME_DIRECTIVE_SEND_IDENTIFY_DOPER_ENDIR, @@ -1449,9 +1448,9 @@ int nvme_directive_recv(int fd, __u32 nsid, __u16 dspec, __u32 data_len, void *data, __u32 *result) { __u32 cdw10 = data_len ? (data_len >> 2) - 1 : 0; - __u32 cdw11 = DW(doper, NVME_DIRECTIVE_CDW11_DOPER) | - DW(dtype, NVME_DIRECTIVE_CDW11_DTYPE) | - DW(dspec, NVME_DIRECTIVE_CDW11_DPSEC); + __u32 cdw11 = NVME_SET(doper, DIRECTIVE_CDW11_DOPER) | + NVME_SET(dtype, DIRECTIVE_CDW11_DTYPE) | + NVME_SET(dspec, DIRECTIVE_CDW11_DPSEC); struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_directive_recv, @@ -1539,11 +1538,11 @@ int nvme_get_property(int fd, int offset, __u64 *value) int nvme_sanitize_nvm(int fd, enum nvme_sanitize_sanact sanact, bool ause, __u8 owpass, bool oipbp, bool nodas, __u32 ovrpat) { - __u32 cdw10 = DW(sanact, NVME_SANITIZE_CDW10_SANACT) | - DW(!!ause, NVME_SANITIZE_CDW10_AUSE) | - DW(owpass, NVME_SANITIZE_CDW10_OWPASS) | - DW(!!oipbp, NVME_SANITIZE_CDW10_OIPBP) | - DW(!!nodas, NVME_SANITIZE_CDW10_NODAS); + __u32 cdw10 = NVME_SET(sanact, SANITIZE_CDW10_SANACT) | + NVME_SET(!!ause, SANITIZE_CDW10_AUSE) | + NVME_SET(owpass, SANITIZE_CDW10_OWPASS) | + NVME_SET(!!oipbp, SANITIZE_CDW10_OIPBP) | + NVME_SET(!!nodas, SANITIZE_CDW10_NODAS); __u32 cdw11 = ovrpat; struct nvme_passthru_cmd cmd = { @@ -1557,7 +1556,7 @@ int nvme_sanitize_nvm(int fd, enum nvme_sanitize_sanact sanact, bool ause, int nvme_dev_self_test(int fd, __u32 nsid, enum nvme_dst_stc stc) { - __u32 cdw10 = DW(stc, NVME_DEVICE_SELF_TEST_CDW10_STC); + __u32 cdw10 = NVME_SET(stc, DEVICE_SELF_TEST_CDW10_STC); struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_dev_self_test, @@ -1572,10 +1571,10 @@ int nvme_virtual_mgmt(int fd, enum nvme_virt_mgmt_act act, enum nvme_virt_mgmt_rt rt, __u16 cntlid, __u16 nr, __u32 *result) { - __u32 cdw10 = DW(act, NVME_VIRT_MGMT_CDW10_ACT) | - DW(rt, NVME_VIRT_MGMT_CDW10_RT) | - DW(cntlid, NVME_VIRT_MGMT_CDW10_CNTLID); - __u32 cdw11 = DW(nr, NVME_VIRT_MGMT_CDW11_NR); + __u32 cdw10 = NVME_SET(act, VIRT_MGMT_CDW10_ACT) | + NVME_SET(rt, VIRT_MGMT_CDW10_RT) | + NVME_SET(cntlid, VIRT_MGMT_CDW10_CNTLID); + __u32 cdw11 = NVME_SET(nr, VIRT_MGMT_CDW11_NR); struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_virtual_mgmt, @@ -1800,8 +1799,8 @@ int nvme_zns_mgmt_send(int fd, __u32 nsid, __u64 slba, bool select_all, { __u32 cdw10 = slba & 0xffffffff; __u32 cdw11 = slba >> 32; - __u32 cdw13 = DW(!!select_all, NVME_ZNS_MGMT_SEND_SEL) | - DW(zsa, NVME_ZNS_MGMT_SEND_ZSA); + __u32 cdw13 = NVME_SET(!!select_all, ZNS_MGMT_SEND_SEL) | + NVME_SET(zsa, ZNS_MGMT_SEND_ZSA); struct nvme_passthru_cmd cmd = { .opcode = nvme_zns_cmd_mgmt_send, @@ -1823,9 +1822,9 @@ int nvme_zns_mgmt_recv(int fd, __u32 nsid, __u64 slba, __u32 cdw10 = slba & 0xffffffff; __u32 cdw11 = slba >> 32; __u32 cdw12 = (data_len >> 2) - 1; - __u32 cdw13 = DW(zra , NVME_ZNS_MGMT_RECV_ZRA) | - DW(zrasf, NVME_ZNS_MGMT_RECV_ZRASF) | - DW(zras_feat, NVME_ZNS_MGMT_RECV_ZRAS_FEAT); + __u32 cdw13 = NVME_SET(zra, ZNS_MGMT_RECV_ZRA) | + NVME_SET(zrasf, ZNS_MGMT_RECV_ZRASF) | + NVME_SET(zras_feat, ZNS_MGMT_RECV_ZRAS_FEAT); struct nvme_passthru_cmd cmd = { .opcode = nvme_zns_cmd_mgmt_recv, diff --git a/src/nvme/types.h b/src/nvme/types.h index f5fb46ad42..e1333b3cec 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -24,8 +24,8 @@ /** * NVME_GET() - extract field from complex value - * @name: The name of the sub-field within an nvme value * @value: The original value of a complex field + * @name: The name of the sub-field within an nvme value * * By convention, this library defines _SHIFT and _MASK such that mask can be * applied after the shift to isolate a specific set of bits that decode to a @@ -33,17 +33,17 @@ * * Returns: The 'name' field from 'value' */ -#define NVME_GET(name, value) \ +#define NVME_GET(value, name) \ (((value) >> NVME_##name##_SHIFT) & NVME_##name##_MASK) /** * NVME_SET() - set field into complex value + * @value: The value to be set in its completed position * @name: The name of the sub-field within an nvme value - * @value: The value to be set * - * Returns: The 'name' field from 'value' + * Returns: The */ -#define NVME_SET(name, value) \ +#define NVME_SET(value, name) \ (((value) & NVME_##name##_MASK) << NVME_##name##_SHIFT) /** @@ -260,7 +260,8 @@ static inline __u64 nvme_mmio_read64(void *addr) __le32 *p = (__le32 *)addr; /* - * Some devices fail 64-bit MMIO. Access 64-bit registers as 2 32-bit. + * Some devices fail 64-bit MMIO, and at least one 64-bit register is + * not aligned to 64-bit. Access 64-bit registers as two 32-bit. */ return le32_to_cpu(*p) | ((uint64_t)le32_to_cpu(*(p + 1)) << 32); } @@ -296,18 +297,18 @@ enum nvme_cap { NVME_CAP_CSS_ADMIN = 1 << 7, }; -#define NVME_CAP_MQES(cap) NVME_GET(CAP_MQES, cap) -#define NVME_CAP_CQR(cap) NVME_GET(CAP_CQR, cap) -#define NVME_CAP_AMS(cap) NVME_GET(CAP_AMS, cap) -#define NVME_CAP_TO(cap) NVME_GET(CAP_TO, cap) -#define NVME_CAP_DSTRD(cap) NVME_GET(CAP_DSTRD, cap) -#define NVME_CAP_NSSRC(cap) NVME_GET(CAP_NSSRC, cap) -#define NVME_CAP_CSS(cap) NVME_GET(CAP_CSS, cap) -#define NVME_CAP_BPS(cap) NVME_GET(CAP_BPS, cap) -#define NVME_CAP_MPSMIN(cap) NVME_GET(CAP_MPSMIN, cap) -#define NVME_CAP_MPSMAX(cap) NVME_GET(CAP_MPSMAX, cap) -#define NVME_CAP_CMBS(cap) NVME_GET(CAP_CMBS, cap) -#define NVME_CAP_PMRS(cap) NVME_GET(CAP_PMRS, cap) +#define NVME_CAP_MQES(cap) NVME_GET(cap, CAP_MQES) +#define NVME_CAP_CQR(cap) NVME_GET(cap, CAP_CQR) +#define NVME_CAP_AMS(cap) NVME_GET(cap, CAP_AMS) +#define NVME_CAP_TO(cap) NVME_GET(cap, CAP_TO) +#define NVME_CAP_DSTRD(cap) NVME_GET(cap, CAP_DSTRD) +#define NVME_CAP_NSSRC(cap) NVME_GET(cap, CAP_NSSRC) +#define NVME_CAP_CSS(cap) NVME_GET(cap, CAP_CSS) +#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) enum nvme_vs { NVME_VS_TER_SHIFT = 0, @@ -318,9 +319,9 @@ enum nvme_vs { NVME_VS_MJR_MASK = 0xffff, }; -#define NVME_VS_TER(vs) NVME_GET(VS_TER, vs) -#define NVME_VS_MNR(vs) NVME_GET(VS_MNR, vs) -#define NVME_VS_MJR(vs) NVME_GET(VS_MJR, vs) +#define NVME_VS_TER(vs) NVME_GET(vs, VS_TER) +#define NVME_VS_MNR(vs) NVME_GET(vs, VS_MNR) +#define NVME_VS_MJR(vs) NVME_GET(vs, VS_MJR) #define NVME_MAJOR(ver) NVME_VS_MJR(ver) #define NVME_MINOR(ver) NVME_VS_MNR(ver) @@ -352,13 +353,13 @@ enum nvme_cc { NVME_CC_SHN_ABRUPT = 2, }; -#define NVME_CC_EN(cc) NVME_GET(CC_EN, cc) -#define NVME_CC_CSS(cc) NVME_GET(CC_CSS, cc) -#define NVME_CC_MPS(cc) NVME_GET(CC_MPS, cc) -#define NVME_CC_AMS(cc) NVME_GET(CC_AMS, cc) -#define NVME_CC_SHN(cc) NVME_GET(CC_SHN, cc) -#define NVME_CC_IOSQES(cc) NVME_GET(CC_IOSQES, cc) -#define NVME_CC_IOCQES(cc) NVME_GET(CC_IOCQES, cc) +#define NVME_CC_EN(cc) NVME_GET(cc, CC_EN) +#define NVME_CC_CSS(cc) NVME_GET(cc, CC_CSS) +#define NVME_CC_MPS(cc) NVME_GET(cc, CC_MPS) +#define NVME_CC_AMS(cc) NVME_GET(cc, CC_AMS) +#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) enum nvme_csts { NVME_CSTS_RDY_SHIFT = 0, @@ -377,11 +378,11 @@ enum nvme_csts { NVME_CSTS_SHST_MASK = 3, }; -#define NVME_CSTS_RDY(csts) NVME_GET(CSTS_RDY, csts) -#define NVME_CSTS_CFS(csts) NVME_GET(CSTS_CFS, csts) -#define NVME_CSTS_SHST(csts) NVME_GET(CSTS_SHST, csts) -#define NVME_CSTS_NSSRO(csts) NVME_GET(CSTS_NSSRO, csts) -#define NVME_CSTS_PP(csts) NVME_GET(CSTS_PP, csts) +#define NVME_CSTS_RDY(csts) NVME_GET(csts, CSTS_RDY) +#define NVME_CSTS_CFS(csts) NVME_GET(csts, CSTS_CFS) +#define NVME_CSTS_SHST(csts) NVME_GET(csts, CSTS_SHST) +#define NVME_CSTS_NSSRO(csts) NVME_GET(csts, CSTS_NSSRO) +#define NVME_CSTS_PP(csts) NVME_GET(csts, CSTS_PP) enum nvme_aqa { NVME_AQA_ASQS_SHIFT = 0, @@ -390,8 +391,8 @@ enum nvme_aqa { NVME_AQA_ACQS_MASK = 0xfff, }; -#define NVME_AQA_ASQS(aqa) NVME_GET(AQA_ASQS, aqa) -#define NVME_AQA_ACQS(aqa) NVME_GET(AQA_ACQS, aqa) +#define NVME_AQA_ASQS(aqa) NVME_GET(aqa, AQA_ASQS) +#define NVME_AQA_ACQS(aqa) NVME_GET(aqa, AQA_ACQS) enum nvme_cmbloc { NVME_CMBLOC_BIR_SHIFT = 0, @@ -412,14 +413,14 @@ enum nvme_cmbloc { NVME_CMBLOC_OFST_MASK = 0xfffff, }; -#define NVME_CMBLOC_BIR(cmbloc) NVME_GET(CMBLOC_BIR, cmbloc) -#define NVME_CMBLOC_CQMMS(cmbloc) NVME_GET(CMBLOC_CQMMS, cmbloc) -#define NVME_CMBLOC_CQPDS(cmbloc) NVME_GET(CMBLOC_CQPDS, cmbloc) -#define NVME_CMBLOC_CDPLMS(cmbloc) NVME_GET(CMBLOC_CDPLMS, cmbloc) -#define NVME_CMBLOC_CDPCILS(cmbloc) NVME_GET(CMBLOC_CDPCILS, cmbloc) -#define NVME_CMBLOC_CDMMMS(cmbloc) NVME_GET(CMBLOC_CDMMMS, cmbloc) -#define NVME_CMBLOC_CQDA(cmbloc) NVME_GET(CMBLOC_CQDA, cmbloc) -#define NVME_CMBLOC_OFST(cmbloc) NVME_GET(CMBLOC_OFST, cmbloc) +#define NVME_CMBLOC_BIR(cmbloc) NVME_GET(cmbloc, CMBLOC_BIR) +#define NVME_CMBLOC_CQMMS(cmbloc) NVME_GET(cmbloc, CMBLOC_CQMMS) +#define NVME_CMBLOC_CQPDS(cmbloc) NVME_GET(cmbloc, CMBLOC_CQPDS) +#define NVME_CMBLOC_CDPLMS(cmbloc) NVME_GET(cmbloc, CMBLOC_CDPLMS) +#define NVME_CMBLOC_CDPCILS(cmbloc) NVME_GET(cmbloc, CMBLOC_CDPCILS) +#define NVME_CMBLOC_CDMMMS(cmbloc) NVME_GET(cmbloc, CMBLOC_CDMMMS) +#define NVME_CMBLOC_CQDA(cmbloc) NVME_GET(cmbloc, CMBLOC_CQDA) +#define NVME_CMBLOC_OFST(cmbloc) NVME_GET(cmbloc, CMBLOC_OFST) enum nvme_cmbsz { NVME_CMBSZ_SQS_SHIFT = 0, @@ -445,13 +446,13 @@ enum nvme_cmbsz { NVME_CMBSZ_SZU_64G = 6, }; -#define NVME_CMBSZ_SQS(cmbsz) NVME_GET(CMBSZ_SQS, cmbsz) -#define NVME_CMBSZ_CQS(cmbsz) NVME_GET(CMBSZ_CQS, cmbsz) -#define NVME_CMBSZ_LISTS(cmbsz) NVME_GET(CMBSZ_LISTS, cmbsz) -#define NVME_CMBSZ_RDS(cmbsz) NVME_GET(CMBSZ_RDS, cmbsz) -#define NVME_CMBSZ_WDS(cmbsz) NVME_GET(CMBSZ_WDS, cmbsz) -#define NVME_CMBSZ_SZU(cmbsz) NVME_GET(CMBSZ_SZU, cmbsz) -#define NVME_CMBSZ_SZ(cmbsz) NVME_GET(CMBSZ_SZ, cmbsz) +#define NVME_CMBSZ_SQS(cmbsz) NVME_GET(cmbsz, CMBSZ_SQS) +#define NVME_CMBSZ_CQS(cmbsz) NVME_GET(cmbsz, CMBSZ_CQS) +#define NVME_CMBSZ_LISTS(cmbsz) NVME_GET(cmbsz, CMBSZ_LISTS) +#define NVME_CMBSZ_RDS(cmbsz) NVME_GET(cmbsz, CMBSZ_RDS) +#define NVME_CMBSZ_WDS(cmbsz) NVME_GET(cmbsz, CMBSZ_WDS) +#define NVME_CMBSZ_SZU(cmbsz) NVME_GET(cmbsz, CMBSZ_SZU) +#define NVME_CMBSZ_SZ(cmbsz) NVME_GET(cmbsz, CMBSZ_SZ) /** * nvme_cmb_size() - Calculate size of the controller memory buffer @@ -478,9 +479,9 @@ enum nvme_bpinfo { NVME_BPINFO_BRS_READ_ERROR = 3, }; -#define NVME_BPINFO_BPSZ(bpinfo) NVME_GET(BPINFO_BPSZ, bpinfo) -#define NVME_BPINFO_BRS(bpinfo) NVME_GET(BPINFO_BRS, bpinfo) -#define NVME_BPINFO_ABPID(bpinfo) NVME_GET(BPINFO_ABPID, bpinfo) +#define NVME_BPINFO_BPSZ(bpinfo) NVME_GET(bpinfo, BPINFO_BPSZ) +#define NVME_BPINFO_BRS(bpinfo) NVME_GET(bpinfo, BPINFO_BRS) +#define NVME_BPINFO_ABPID(bpinfo) NVME_GET(bpinfo, BPINFO_ABPID) enum nvme_bprsel { NVME_BPRSEL_BPRSZ_SHIFT = 0, @@ -491,9 +492,9 @@ enum nvme_bprsel { NVME_BPRSEL_BPID_MASK = 0x1, }; -#define NVME_BPRSEL_BPRSZ(bprsel) NVME_GET(BPRSEL_BPRSZ, bprsel) -#define NVME_BPRSEL_BPROF(bprsel) NVME_GET(BPRSEL_BPROF, bprsel) -#define NVME_BPRSEL_BPID(bprsel) NVME_GET(BPRSEL_BPID, bprsel) +#define NVME_BPRSEL_BPRSZ(bprsel) NVME_GET(bprsel, BPRSEL_BPRSZ) +#define NVME_BPRSEL_BPROF(bprsel) NVME_GET(bprsel, BPRSEL_BPROF) +#define NVME_BPRSEL_BPID(bprsel) NVME_GET(bprsel, BPRSEL_BPID) enum nvme_cmbmsc { NVME_CMBMSC_CRE_SHIFT = 0, @@ -504,16 +505,16 @@ enum nvme_cmbmsc { }; static const __u64 NVME_CMBMSC_CBA_MASK = 0xfffffffffffffull; -#define NVME_CMBMSC_CRE(cmbmsc) NVME_GET(CMBMSC_CRE, cmbmsc) -#define NVME_CMBMSC_CMSE(cmbmsc) NVME_GET(CMBMSC_CMSE, cmbmsc) -#define NVME_CMBMSC_CBA(cmbmsc) NVME_GET(CMBMSC_CBA, cmbmsc) +#define NVME_CMBMSC_CRE(cmbmsc) NVME_GET(cmbmsc, CMBMSC_CRE) +#define NVME_CMBMSC_CMSE(cmbmsc) NVME_GET(cmbmsc, CMBMSC_CMSE) +#define NVME_CMBMSC_CBA(cmbmsc) NVME_GET(cmbmsc, CMBMSC_CBA) enum nvme_cmbsts { NVME_CMBSTS_CBAI_SHIFT = 0, NVME_CMBSTS_CBAI_MASK = 0x1, }; -#define NVME_CMBSTS_CBAI(cmbsts) NVME_GET(CMBSTS_CBAI, cmbsts) +#define NVME_CMBSTS_CBAI(cmbsts) NVME_GET(cmbsts, CMBSTS_CBAI) enum nvme_pmrcap { NVME_PMRCAP_RDS_SHIFT = 3, @@ -534,20 +535,20 @@ enum nvme_pmrcap { NVME_PMRCAP_PMRTU_60S = 1, }; -#define NVME_PMRCAP_RDS(pmrcap) NVME_GET(PMRCAP_RDS, pmrcap) -#define NVME_PMRCAP_WDS(pmrcap) NVME_GET(PMRCAP_WDS, pmrcap) -#define NVME_PMRCAP_BIR(pmrcap) NVME_GET(PMRCAP_BIR, pmrcap) -#define NVME_PMRCAP_PMRTU(pmrcap) NVME_GET(PMRCAP_PMRTU, pmrcap) -#define NVME_PMRCAP_PMRWMB(pmrcap) NVME_GET(PMRCAP_PMRWMB, pmrcap) -#define NVME_PMRCAP_PMRTO(pmrcap) NVME_GET(PMRCAP_PMRTO, pmrcap) -#define NVME_PMRCAP_CMSS(pmrcap) NVME_GET(PMRCAP_CMSS, pmrcap) +#define NVME_PMRCAP_RDS(pmrcap) NVME_GET(pmrcap, PMRCAP_RDS) +#define NVME_PMRCAP_WDS(pmrcap) NVME_GET(pmrcap, PMRCAP_WDS) +#define NVME_PMRCAP_BIR(pmrcap) NVME_GET(pmrcap, PMRCAP_BIR) +#define NVME_PMRCAP_PMRTU(pmrcap) NVME_GET(pmrcap, PMRCAP_PMRTU) +#define NVME_PMRCAP_PMRWMB(pmrcap) NVME_GET(pmrcap, PMRCAP_PMRWMB) +#define NVME_PMRCAP_PMRTO(pmrcap) NVME_GET(pmrcap, PMRCAP_PMRTO) +#define NVME_PMRCAP_CMSS(pmrcap) NVME_GET(pmrcap, PMRCAP_CMSS) enum nvme_pmrctl { NVME_PMRCTL_EN_SHIFT = 0, NVME_PMRCTL_EN_MASK = 0x1, }; -#define NVME_PMRCTL_EN(pmrctl) NVME_GET(PMRCTL_EN, pmrctl) +#define NVME_PMRCTL_EN(pmrctl) NVME_GET(pmrctl, PMRCTL_EN) enum nvme_pmrsts { NVME_PMRSTS_ERR_SHIFT = 0, @@ -560,10 +561,10 @@ enum nvme_pmrsts { NVME_PMRSTS_CBAI_MASK = 0x1, }; -#define NVME_PMRSTS_ERR(pmrsts) NVME_GET(PMRSTS_ERR, pmrsts) -#define NVME_PMRSTS_NRDY(pmrsts) NVME_GET(PMRSTS_NRDY, pmrsts) -#define NVME_PMRSTS_HSTS(pmrsts) NVME_GET(PMRSTS_HSTS, pmrsts) -#define NVME_PMRSTS_CBAI(pmrsts) NVME_GET(PMRSTS_CBAI, pmrsts) +#define NVME_PMRSTS_ERR(pmrsts) NVME_GET(pmrsts, PMRSTS_ERR) +#define NVME_PMRSTS_NRDY(pmrsts) NVME_GET(pmrsts, PMRSTS_NRDY) +#define NVME_PMRSTS_HSTS(pmrsts) NVME_GET(pmrsts, PMRSTS_HSTS) +#define NVME_PMRSTS_CBAI(pmrsts) NVME_GET(pmrsts, PMRSTS_CBAI) enum nvme_pmrebs { NVME_PMREBS_PMRSZU_SHIFT = 0, @@ -578,9 +579,9 @@ enum nvme_pmrebs { NVME_PMREBS_PMRSZU_1G = 3, }; -#define NVME_PMREBS_PMRSZU(pmrebs) NVME_GET(PMREBS_PMRSZU, pmrebs) -#define NVME_PMREBS_RBB(pmrebs) NVME_GET(PMREBS_RBB, pmrebs) -#define NVME_PMREBS_PMRWBZ(pmrebs) NVME_GET(PMREBS_PMRWBZ, pmrebs) +#define NVME_PMREBS_PMRSZU(pmrebs) NVME_GET(pmrebs, PMREBS_PMRSZU) +#define NVME_PMREBS_RBB(pmrebs) NVME_GET(pmrebs, PMREBS_RBB) +#define NVME_PMREBS_PMRWBZ(pmrebs) NVME_GET(pmrebs, PMREBS_PMRWBZ) /** * nvme_pmr_size() - Calculate size of persistent memory region elasticity @@ -606,8 +607,8 @@ enum nvme_pmrswtp { NVME_PMRSWTP_PMRSWTU_GBPS = 3, }; -#define NVME_PMRSWTP_PMRSWTU(pmrswtp) NVME_GET(PMRSWTP_PMRSWTU, pmrswtp) -#define NVME_PMRSWTP_PMRSWTV(pmrswtp) NVME_GET(PMRSWTP_PMRSWTU, pmrswtp) +#define NVME_PMRSWTP_PMRSWTU(pmrswtp) NVME_GET(pmrswtp, PMRSWTP_PMRSWTU) +#define NVME_PMRSWTP_PMRSWTV(pmrswtp) NVME_GET(pmrswtp, PMRSWTP_PMRSWTU) /** * nvme_pmr_throughput() - Calculate throughput of persistent memory buffer @@ -628,8 +629,8 @@ enum nvme_pmrmsc { }; static const __u64 NVME_PMRMSC_CBA_MASK = 0xfffffffffffffull; -#define NVME_PMRMSC_CMSE(pmrmsc) NVME_GET(PMRMSC_CMSE, pmrmsc) -#define NVME_PMRMSC_CBA(pmrmsc) NVME_GET(PMRMSC_CBA, pmrmsc) +#define NVME_PMRMSC_CMSE(pmrmsc) NVME_GET(pmrmsc, PMRMSC_CMSE) +#define NVME_PMRMSC_CBA(pmrmsc) NVME_GET(pmrmsc, PMRMSC_CBA) /** * enum nvme_psd_flags - Possible flag values in nvme power state descriptor diff --git a/src/nvme/util.h b/src/nvme/util.h index 6cf607a275..6534f631ea 100644 --- a/src/nvme/util.h +++ b/src/nvme/util.h @@ -238,40 +238,40 @@ static inline void nvme_chomp(char *s, int l) } enum { - NVME_FEAT_ARB_BURST_SHIFT = 0, - NVME_FEAT_ARB_BURST_MASK = 0x7, - NVME_FEAT_ARB_LPW_SHIFT = 8, - NVME_FEAT_ARB_LPW_MASK = 0xff, - NVME_FEAT_ARB_MPW_SHIFT = 16, - NVME_FEAT_ARB_MPW_MASK = 0xff, - NVME_FEAT_ARB_HPW_SHIFT = 24, - NVME_FEAT_ARB_HPW_MASK = 0xff, - NVME_FEAT_PM_PS_SHIFT = 0, - NVME_FEAT_PM_PS_MASK = 0x1f, - NVME_FEAT_PM_WH_SHIFT = 5, - NVME_FEAT_PM_WH_MASK = 0x7, - NVME_FEAT_LBAR_NR_SHIFT = 0, - NVME_FEAT_LBAR_NR_MASK = 0x3f, - NVME_FEAT_TT_TMPTH_SHIFT = 0, - NVME_FEAT_TT_TMPTH_MASK = 0xffff, - NVME_FEAT_TT_TMPSEL_SHIFT = 16, - NVME_FEAT_TT_TMPSEL_MASK = 0xf, - NVME_FEAT_TT_THSEL_SHIFT = 20, - NVME_FEAT_TT_THSEL_MASK = 0x3, - NVME_FEAT_ER_TLER_SHIFT = 0, - NVME_FEAT_ER_TLER_MASK = 0xffff, - NVME_FEAT_ER_DULBE_SHIFT = 16, - NVME_FEAT_ER_DULBE_MASK = 0x1, + NVME_FEAT_ARBITRATION_BURST_SHIFT = 0, + NVME_FEAT_ARBITRATION_BURST_MASK = 0x7, + NVME_FEAT_ARBITRATION_LPW_SHIFT = 8, + NVME_FEAT_ARBITRATION_LPW_MASK = 0xff, + NVME_FEAT_ARBITRATION_MPW_SHIFT = 16, + NVME_FEAT_ARBITRATION_MPW_MASK = 0xff, + NVME_FEAT_ARBITRATION_HPW_SHIFT = 24, + NVME_FEAT_ARBITRATION_HPW_MASK = 0xff, + NVME_FEAT_PWRMGMT_PS_SHIFT = 0, + NVME_FEAT_PWRMGMT_PS_MASK = 0x1f, + NVME_FEAT_PWRMGMT_WH_SHIFT = 5, + NVME_FEAT_PWRMGMT_WH_MASK = 0x7, + NVME_FEAT_LBAR_NR_SHIFT = 0, + NVME_FEAT_LBAR_NR_MASK = 0x3f, + NVME_FEAT_TT_TMPTH_SHIFT = 0, + NVME_FEAT_TT_TMPTH_MASK = 0xffff, + NVME_FEAT_TT_TMPSEL_SHIFT = 16, + NVME_FEAT_TT_TMPSEL_MASK = 0xf, + NVME_FEAT_TT_THSEL_SHIFT = 20, + NVME_FEAT_TT_THSEL_MASK = 0x3, + NVME_FEAT_ERROR_RECOVERY_TLER_SHIFT = 0, + NVME_FEAT_ERROR_RECOVERY_TLER_MASK = 0xffff, + NVME_FEAT_ERROR_RECOVERY_DULBE_SHIFT = 16, + NVME_FEAT_ERROR_RECOVERY_DULBE_MASK = 0x1, NVME_FEAT_VWC_WCE_SHIFT = 0, NVME_FEAT_VWC_WCE_MASK = 0x1, NVME_FEAT_NRQS_NSQR_SHIFT = 0, NVME_FEAT_NRQS_NSQR_MASK = 0xffff, NVME_FEAT_NRQS_NCQR_SHIFT = 16, NVME_FEAT_NRQS_NCQR_MASK = 0xffff, - NVME_FEAT_ICOAL_THR_SHIFT = 0, - NVME_FEAT_ICOAL_THR_MASK = 0xff, - NVME_FEAT_ICOAL_TIME_SHIFT = 8, - NVME_FEAT_ICOAL_TIME_MASK = 0xff, + NVME_FEAT_IRQC_THR_SHIFT = 0, + NVME_FEAT_IRQC_THR_MASK = 0xff, + NVME_FEAT_IRQC_TIME_SHIFT = 8, + NVME_FEAT_IRQC_TIME_MASK = 0xff, NVME_FEAT_ICFG_IV_SHIFT = 0, NVME_FEAT_ICFG_IV_MASK = 0xffff, NVME_FEAT_ICFG_CD_SHIFT = 16, @@ -338,10 +338,10 @@ enum { NVME_FEAT_IOCSP_IOCSCI_MASK = 0xff, }; -#define NVME_FEAT_ARB_BURST(v) NVME_GET(FEAT_ARB_BURST, v) -#define NVME_FEAT_ARB_LPW(v) NVME_GET(FEAT_ARB_LPW, v) -#define NVME_FEAT_ARB_MPW(v) NVME_GET(FEAT_ARB_MPW, v) -#define NVME_FEAT_ARB_HPW(v) NVME_GET(FEAT_ARB_HPW, v) +#define NVME_FEAT_ARB_BURST(v) NVME_GET(v, FEAT_ARBITRATION_BURST) +#define NVME_FEAT_ARB_LPW(v) NVME_GET(v, FEAT_ARBITRATION_LPW) +#define NVME_FEAT_ARB_MPW(v) NVME_GET(v, FEAT_ARBITRATION_MPW) +#define NVME_FEAT_ARB_HPW(v) NVME_GET(v, FEAT_ARBITRATION_HPW) inline void nvme_feature_decode_arbitration(__u32 value, __u8 *ab, __u8 *lpw, __u8 *mpw, __u8 *hpw) @@ -352,8 +352,8 @@ inline void nvme_feature_decode_arbitration(__u32 value, __u8 *ab, __u8 *lpw, *hpw = NVME_FEAT_ARB_HPW(value); }; -#define NVME_FEAT_PM_PS(v) NVME_GET(FEAT_PM_PS, v) -#define NVME_FEAT_PM_WH(v) NVME_GET(FEAT_PM_WH, v) +#define NVME_FEAT_PM_PS(v) NVME_GET(v, FEAT_PWRMGMT_PS) +#define NVME_FEAT_PM_WH(v) NVME_GET(v, FEAT_PWRMGMT_WH) inline void nvme_feature_decode_power_mgmt(__u32 value, __u8 *ps, __u8 *wh) { @@ -361,16 +361,16 @@ inline void nvme_feature_decode_power_mgmt(__u32 value, __u8 *ps, __u8 *wh) *wh = NVME_FEAT_PM_WH(value); } -#define NVME_FEAT_LBAR_NR(v) NVME_GET(FEAT_LBAR_NR, v) +#define NVME_FEAT_LBAR_NR(v) NVME_GET(v, FEAT_LBAR_NR) inline void nvme_feature_decode_lba_range(__u32 value, __u8 *num) { *num = NVME_FEAT_LBAR_NR(value); } -#define NVME_FEAT_TT_TMPTH(v) NVME_GET(FEAT_TT_TMPTH, v) -#define NVME_FEAT_TT_TMPSEL(v) NVME_GET(FEAT_TT_TMPSEL, v) -#define NVME_FEAT_TT_THSEL(v) NVME_GET(FEAT_TT_THSEL, v) +#define NVME_FEAT_TT_TMPTH(v) NVME_GET(v, FEAT_TT_TMPTH) +#define NVME_FEAT_TT_TMPSEL(v) NVME_GET(v, FEAT_TT_TMPSEL) +#define NVME_FEAT_TT_THSEL(v) NVME_GET(v, FEAT_TT_THSEL) inline void nvme_feature_decode_temp_threshold(__u32 value, __u16 *tmpth, __u8 *tmpsel, __u8 *thsel) @@ -380,8 +380,8 @@ inline void nvme_feature_decode_temp_threshold(__u32 value, __u16 *tmpth, *thsel = NVME_FEAT_TT_THSEL(value); } -#define NVME_FEAT_ER_TLER(v) NVME_GET(FEAT_ER_TLER, v) -#define NVME_FEAT_ER_DULBE(v) NVME_GET(FEAT_ER_DULBE, v) +#define NVME_FEAT_ER_TLER(v) NVME_GET(v, FEAT_ERROR_RECOVERY_TLER) +#define NVME_FEAT_ER_DULBE(v) NVME_GET(v, FEAT_ERROR_RECOVERY_DULBE) inline void nvme_feature_decode_error_recovery(__u32 value, __u16 *tler, bool *dulbe) { @@ -389,15 +389,15 @@ inline void nvme_feature_decode_error_recovery(__u32 value, __u16 *tler, bool *d *dulbe = NVME_FEAT_ER_DULBE(value); } -#define NVME_FEAT_VWC_WCE(v) NVME_GET(FEAT_VWC_WCE, v) +#define NVME_FEAT_VWC_WCE(v) NVME_GET(v, FEAT_VWC_WCE) inline void nvme_feature_decode_volatile_write_cache(__u32 value, bool *wce) { *wce = NVME_FEAT_VWC_WCE(value); } -#define NVME_FEAT_NRQS_NSQR(v) NVME_GET(FEAT_NRQS_NSQR, v) -#define NVME_FEAT_NRQS_NCQR(v) NVME_GET(FEAT_NRQS_NCQR, v) +#define NVME_FEAT_NRQS_NSQR(v) NVME_GET(v, FEAT_NRQS_NSQR) +#define NVME_FEAT_NRQS_NCQR(v) NVME_GET(v, FEAT_NRQS_NCQR) inline void nvme_feature_decode_number_of_queues(__u32 value, __u16 *nsqr, __u16 *ncqr) { @@ -405,17 +405,17 @@ inline void nvme_feature_decode_number_of_queues(__u32 value, __u16 *nsqr, __u16 *ncqr = NVME_FEAT_NRQS_NCQR(value); } -#define NVME_FEAT_ICOAL_THR(v) NVME_GET(FEAT_ICOAL_THR, v) -#define NVME_FEAT_ICOAL_TIME(v) NVME_GET(FEAT_ICOAL_TIME, v) +#define NVME_FEAT_IRQC_THR(v) NVME_GET(v, FEAT_IRQC_THR) +#define NVME_FEAT_IRQC_TIME(v) NVME_GET(v, FEAT_IRQC_TIME) inline void nvme_feature_decode_interrupt_coalescing(__u32 value, __u8 *thr, __u8 *time) { - *thr = NVME_FEAT_ICOAL_THR(value); - *time = NVME_FEAT_ICOAL_TIME(value); + *thr = NVME_FEAT_IRQC_THR(value); + *time = NVME_FEAT_IRQC_TIME(value); } -#define NVME_FEAT_ICFG_IV(v) NVME_GET(FEAT_ICFG_IV, v) -#define NVME_FEAT_ICFG_CD(v) NVME_GET(FEAT_ICFG_CD, v) +#define NVME_FEAT_ICFG_IV(v) NVME_GET(v, FEAT_ICFG_IV) +#define NVME_FEAT_ICFG_CD(v) NVME_GET(v, FEAT_ICFG_CD) inline void nvme_feature_decode_interrupt_config(__u32 value, __u16 *iv, bool *cd) { @@ -423,21 +423,21 @@ inline void nvme_feature_decode_interrupt_config(__u32 value, __u16 *iv, bool *c *cd = NVME_FEAT_ICFG_CD(value); } -#define NVME_FEAT_WA_DN(v) NVME_GET(FEAT_WA_DN, v) +#define NVME_FEAT_WA_DN(v) NVME_GET(v, FEAT_WA_DN) inline void nvme_feature_decode_write_atomicity(__u32 value, bool *dn) { *dn = NVME_FEAT_WA_DN(value); } -#define NVME_FEAT_AE_SMART(v) NVME_GET(FEAT_AE_SMART, v) -#define NVME_FEAT_AE_NAN(v) NVME_GET(FEAT_AE_NAN, v) -#define NVME_FEAT_AE_FW(v) NVME_GET(FEAT_AE_FW, v) -#define NVME_FEAT_AE_TELEM(v) NVME_GET(FEAT_AE_TELEM, v) -#define NVME_FEAT_AE_ANA(v) NVME_GET(FEAT_AE_ANA, v) -#define NVME_FEAT_AE_PLA(v) NVME_GET(FEAT_AE_PLA, v) -#define NVME_FEAT_AE_LBAS(v) NVME_GET(FEAT_AE_LBAS, v) -#define NVME_FEAT_AE_EGA(v) NVME_GET(FEAT_AE_EGA, v) +#define NVME_FEAT_AE_SMART(v) NVME_GET(v, FEAT_AE_SMART) +#define NVME_FEAT_AE_NAN(v) NVME_GET(v, FEAT_AE_NAN) +#define NVME_FEAT_AE_FW(v) NVME_GET(v, FEAT_AE_FW) +#define NVME_FEAT_AE_TELEM(v) NVME_GET(v, FEAT_AE_TELEM) +#define NVME_FEAT_AE_ANA(v) NVME_GET(v, FEAT_AE_ANA) +#define NVME_FEAT_AE_PLA(v) NVME_GET(v, FEAT_AE_PLA) +#define NVME_FEAT_AE_LBAS(v) NVME_GET(v, FEAT_AE_LBAS) +#define NVME_FEAT_AE_EGA(v) NVME_GET(v, FEAT_AE_EGA) inline void nvme_feature_decode_async_event_config(__u32 value, __u8 *smart, bool *nan, bool *fw, bool *telem, bool *ana, bool *pla, bool *lbas, @@ -453,22 +453,22 @@ inline void nvme_feature_decode_async_event_config(__u32 value, __u8 *smart, *ega = NVME_FEAT_AE_EGA(value); } -#define NVME_FEAT_APST_APSTE(v) NVME_GET(FEAT_APST_APSTE, v) +#define NVME_FEAT_APST_APSTE(v) NVME_GET(v, FEAT_APST_APSTE) inline void nvme_feature_decode_auto_power_state(__u32 value, bool *apste) { *apste = NVME_FEAT_APST_APSTE(value); } -#define NVME_FEAT_HMEM_EHM(v) NVME_GET(FEAT_HMEM_EHM, v) +#define NVME_FEAT_HMEM_EHM(v) NVME_GET(v, FEAT_HMEM_EHM) inline void nvme_feature_decode_host_memory_buffer(__u32 value, bool *ehm) { *ehm = NVME_FEAT_HMEM_EHM(value); } -#define NVME_FEAT_HCTM_TMT2(v) NVME_GET(FEAT_HCTM_TMT2, v) -#define NVME_FEAT_HCTM_TMT1(v) NVME_GET(FEAT_HCTM_TMT1, v) +#define NVME_FEAT_HCTM_TMT2(v) NVME_GET(v, FEAT_HCTM_TMT2) +#define NVME_FEAT_HCTM_TMT1(v) NVME_GET(v, FEAT_HCTM_TMT1) inline void nvme_feature_decode_host_thermal_mgmt(__u32 value, __u16 *tmt2, __u16 *tmt1) { @@ -476,36 +476,36 @@ inline void nvme_feature_decode_host_thermal_mgmt(__u32 value, __u16 *tmt2, __u1 *tmt1 = NVME_FEAT_HCTM_TMT1(value); } -#define NVME_FEAT_NOPS_NOPPME(v) NVME_GET(FEAT_NOPS_NOPPME, v) +#define NVME_FEAT_NOPS_NOPPME(v) NVME_GET(v, FEAT_NOPS_NOPPME) inline void nvme_feature_decode_non_op_power_config(__u32 value, bool *noppme) { *noppme = NVME_FEAT_NOPS_NOPPME(value); } -#define NVME_FEAT_RRL_RRL(v) NVME_GET(FEAT_RRL_RRL, v) +#define NVME_FEAT_RRL_RRL(v) NVME_GET(v, FEAT_RRL_RRL) inline void nvme_feature_decode_read_recovery_level_config(__u32 value, __u8 *rrl) { *rrl = NVME_FEAT_RRL_RRL(value); } -#define NVME_FEAT_PLM_PLME(v) NVME_GET(FEAT_PLM_PLME, v) +#define NVME_FEAT_PLM_PLME(v) NVME_GET(v, FEAT_PLM_PLME) inline void nvme_feature_decode_predictable_latency_mode_config(__u32 value, bool *plme) { *plme = NVME_FEAT_PLM_PLME(value); } -#define NVME_FEAT_PLMW_WS(v) NVME_GET(FEAT_PLMW_WS, v) +#define NVME_FEAT_PLMW_WS(v) NVME_GET(v, FEAT_PLMW_WS) inline void nvme_feature_decode_predictable_latency_mode_window(__u32 value, __u8 *ws) { *ws = NVME_FEAT_PLMW_WS(value); } -#define NVME_FEAT_LBAS_LSIRI(v) NVME_GET(FEAT_LBAS_LSIRI, v) -#define NVME_FEAT_LBAS_LSIPI(v) NVME_GET(FEAT_LBAS_LSIPI, v) +#define NVME_FEAT_LBAS_LSIRI(v) NVME_GET(v, FEAT_LBAS_LSIRI) +#define NVME_FEAT_LBAS_LSIPI(v) NVME_GET(v, FEAT_LBAS_LSIPI) inline void nvme_feature_decode_lba_status_attributes(__u32 value, __u16 *lsiri, __u16 *lsipi) { @@ -513,15 +513,15 @@ inline void nvme_feature_decode_lba_status_attributes(__u32 value, __u16 *lsiri, *lsipi = NVME_FEAT_LBAS_LSIPI(value); } -#define NVME_FEAT_SC_NODRM(v) NVME_GET(FEAT_SC_NODRM, v) +#define NVME_FEAT_SC_NODRM(v) NVME_GET(v, FEAT_SC_NODRM) inline void nvme_feature_decode_sanitize_config(__u32 value, bool *nodrm) { *nodrm = NVME_FEAT_SC_NODRM(value); } -#define NVME_FEAT_EG_ENDGID(v) NVME_GET(FEAT_EG_ENDGID, v) -#define NVME_FEAT_EG_EGCW(v) NVME_GET(FEAT_EG_EGCW, v) +#define NVME_FEAT_EG_ENDGID(v) NVME_GET(v, FEAT_EG_ENDGID) +#define NVME_FEAT_EG_EGCW(v) NVME_GET(v, FEAT_EG_EGCW) inline void nvme_feature_decode_endurance_group_event_config(__u32 value, __u16 *endgid, __u8 *endgcw) @@ -530,23 +530,23 @@ inline void nvme_feature_decode_endurance_group_event_config(__u32 value, *endgcw = NVME_FEAT_EG_EGCW(value); } -#define NVME_FEAT_SPM_PBSLC(v) NVME_GET(FEAT_SPM_PBSLC, v) +#define NVME_FEAT_SPM_PBSLC(v) NVME_GET(v, FEAT_SPM_PBSLC) inline void nvme_feature_decode_software_progress_marker(__u32 value, __u8 *pbslc) { *pbslc = NVME_FEAT_SPM_PBSLC(value); } -#define NVME_FEAT_HOSTID_EXHID(v) NVME_GET(FEAT_HOSTID_EXHID, v) +#define NVME_FEAT_HOSTID_EXHID(v) NVME_GET(v, FEAT_HOSTID_EXHID) inline void nvme_feature_decode_host_identifier(__u32 value, bool *exhid) { *exhid = NVME_FEAT_HOSTID_EXHID(value); } -#define NVME_FEAT_RM_REGPRE(v) NVME_GET(FEAT_RM_REGPRE, v) -#define NVME_FEAT_RM_RESREL(v) NVME_GET(FEAT_RM_RESREL, v) -#define NVME_FEAT_RM_RESPRE(v) NVME_GET(FEAT_RM_RESPRE, v) +#define NVME_FEAT_RM_REGPRE(v) NVME_GET(v, FEAT_RM_REGPRE) +#define NVME_FEAT_RM_RESREL(v) NVME_GET(v, FEAT_RM_RESREL) +#define NVME_FEAT_RM_RESPRE(v) NVME_GET(v, FEAT_RM_RESPRE) inline void nvme_feature_decode_reservation_notification(__u32 value, bool *regpre, bool *resrel, bool *respre) @@ -556,14 +556,14 @@ inline void nvme_feature_decode_reservation_notification(__u32 value, bool *regp *respre = NVME_FEAT_RM_RESPRE(value); } -#define NVME_FEAT_RP_PTPL(v) NVME_GET(FEAT_RP_PTPL, v) +#define NVME_FEAT_RP_PTPL(v) NVME_GET(v, FEAT_RP_PTPL) inline void nvme_feature_decode_reservation_persistance(__u32 value, bool *ptpl) { *ptpl = NVME_FEAT_RP_PTPL(value); } -#define NVME_FEAT_WP_WPS(v) NVME_GET(FEAT_WP_WPS, v) +#define NVME_FEAT_WP_WPS(v) NVME_GET(v, FEAT_WP_WPS) inline void nvme_feature_decode_namespace_write_protect(__u32 value, __u8 *wps) { From 6d14f18d883ebc3cbca4fce1666fdfe3d5a9eb42 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Tue, 9 Jun 2020 13:45:44 -0700 Subject: [PATCH 0058/1564] fix mmio accesses 64-bit access needs to ensure no reorder or combining. Signed-off-by: Keith Busch --- src/nvme/types.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/nvme/types.h b/src/nvme/types.h index e1333b3cec..219ea6a147 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -248,22 +248,22 @@ static inline bool nvme_is_64bit_reg(__u32 offset) } } -static inline __u32 nvme_mmio_read32(void *addr) +static inline uint32_t nvme_mmio_read32(volatile void *addr) { - __le32 *p = (__le32 *)addr; + uint32_t *p = (__le32 *)addr; return le32_to_cpu(*p); } -static inline __u64 nvme_mmio_read64(void *addr) +static inline uint64_t nvme_mmio_read64(volatile void *addr) { - __le32 *p = (__le32 *)addr; + volatile __u32 *p = (__u32 *)addr; + uint32_t low, high; - /* - * Some devices fail 64-bit MMIO, and at least one 64-bit register is - * not aligned to 64-bit. Access 64-bit registers as two 32-bit. - */ - return le32_to_cpu(*p) | ((uint64_t)le32_to_cpu(*(p + 1)) << 32); + low = nvme_mmio_read32(p); + high = nvme_mmio_read32(p + 1); + + return low + ((uint64_t)high << 32); } enum nvme_cap { From a4582173fe8072f80f5eef7eca77d52f853d81dc Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Wed, 10 Jun 2020 11:06:35 -0700 Subject: [PATCH 0059/1564] document corner case for large nsids Signed-off-by: Keith Busch --- src/nvme/ioctl.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 6c7b8c256e..12edb604b4 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -360,7 +360,10 @@ int nvme_ns_rescan(int fd); * @fd: File descriptor of nvme namespace * @nsid: User pointer to namespace id * - * This should only be sent to namespace handles, not to controllers. + * This should only be sent to namespace handles, not to controllers. The + * kernel's interface returns the nsid as the return value. This is unfortunate + * for many architectures that are incapable of allowing distinguishing a + * namespace id > 0x80000000 from a negative error number. * * Return: 0 if @nsid was set succecssfully or -1 with errno set otherwise. */ From 15dd1ee75aa02b19d92fd260fae8e92ff74655e4 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 8 Oct 2020 08:13:08 -0700 Subject: [PATCH 0060/1564] update doc cross links Signed-off-by: Keith Busch --- src/nvme/ioctl.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 12edb604b4..4090aa8224 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -2203,7 +2203,7 @@ int nvme_ns_mgmt(int fd, __u32 nsid, enum nvme_ns_mgmt_sel sel, * set to 0 to use the system default. * * On successful creation, the namespace exists in the subsystem, but is not - * attached to any controller. Use the nvme_ns_attach_ctrls() to assign the + * attached to any controller. Use the &nvme_ns_attach_ctrls() to assign the * namespace to one or more controllers. * * Return: The nvme command status if a response was received (see @@ -2218,7 +2218,7 @@ int nvme_ns_mgmt_create(int fd, struct nvme_id_ns *ns, __u32 *nsid, * @nsid: Namespace identifier to delete * * It is recommended that a namespace being deleted is not attached to any - * controller. Use the nvme_ns_detach_ctrls() first if the namespace is still + * controller. Use the &nvme_ns_detach_ctrls() first if the namespace is still * attached. * * Return: The nvme command status if a response was received (see From e87f80ceb07c3b47a9d2d05a7392ba93a2dbd6c8 Mon Sep 17 00:00:00 2001 From: Han Han Date: Tue, 20 Oct 2020 21:49:20 +0800 Subject: [PATCH 0061/1564] spec: Use the correct url of libnvme Signed-off-by: Han Han --- libnvme.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libnvme.spec b/libnvme.spec index f3407d88c7..80d66e9e86 100644 --- a/libnvme.spec +++ b/libnvme.spec @@ -5,7 +5,7 @@ Summary: Linux-native nvme device management library License: LGPLv2+ Source: %{name}-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-root -URL: http://github.com/linux-nvme/nvme-cli +URL: http://github.com/linux-nvme/libnvme BuildRequires: gcc %description From 05ab55aef991b8a0084a95fffd04c887e0aff086 Mon Sep 17 00:00:00 2001 From: Han Han Date: Tue, 20 Oct 2020 21:49:21 +0800 Subject: [PATCH 0062/1564] spec: Fix the sub-include dir name to nvme It will fix the error of "libnvme/ dir is not found": $ rpmbuild -ba ~/rpmbuild/SPECS/libnvme.spec ... error: Directory not found: /home/hhan/rpmbuild/BUILDROOT/libnvme-0.1-0.x86_64/usr/include/libnvme Signed-off-by: Han Han --- libnvme.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libnvme.spec b/libnvme.spec index 80d66e9e86..9708084f88 100644 --- a/libnvme.spec +++ b/libnvme.spec @@ -39,7 +39,7 @@ for Linux-native nvme device maangement. %files devel %defattr(-,root,root) -%attr(-,root,root) %{_includedir}/libnvme/ +%attr(-,root,root) %{_includedir}/nvme/ %attr(0644,root,root) %{_includedir}/libnvme.h %attr(0755,root,root) %{_libdir}/libnvme.so %attr(0644,root,root) %{_libdir}/libnvme.a From be3308357d82c1be5f82769cf3e3a73e80fbd968 Mon Sep 17 00:00:00 2001 From: Han Han Date: Tue, 20 Oct 2020 20:45:31 +0800 Subject: [PATCH 0063/1564] examples: Add src/ into the include and library path That will fix the compiling errors like: CC telemetry-listen telemetry-listen.c:21:10: fatal error: libnvme.h: No such file or directory 21 | #include | ^~~~~~~~~~~ Signed-off-by: Han Han --- examples/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/Makefile b/examples/Makefile index be867a7648..24f8574660 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -1,5 +1,5 @@ CFLAGS ?= -g -O2 -override CFLAGS += -Wall -D_GNU_SOURCE +override CFLAGS += -Wall -D_GNU_SOURCE -I ../src -L ../src include ../Makefile.quiet From 76ba7703e7f84764f315af006430cd8f43e8eb14 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Wed, 24 Feb 2021 07:54:12 +0900 Subject: [PATCH 0064/1564] add lba status log helper This log requires a more complex multi-sequence to successfully get, so add a helper. Signed-off-by: Keith Busch --- src/nvme/util.c | 40 +++++++++++++++++++++++++++++++++++++++- src/nvme/util.h | 8 ++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/nvme/util.c b/src/nvme/util.c index 175714e423..7d044bf563 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -339,11 +339,49 @@ int nvme_get_host_telemetry(int fd, struct nvme_telemetry_log **log) return nvme_get_telemetry_log(fd, false, false, false, log); } -int nvme_get_new_host_telemetry(int fd, struct nvme_telemetry_log **log) +int nvme_get_new_host_telemetry(int fd, struct nvme_telemetry_log **log) { return nvme_get_telemetry_log(fd, true, false, false, log); } +int nvme_get_lba_status_log(int fd, bool rae, struct nvme_lba_status_log **log) +{ + __u32 size = sizeof(struct nvme_lba_status_log); + void *buf, *tmp; + int err; + + buf = malloc(size); + if (!buf) + return -1; + + *log = buf; + err = nvme_get_log_lba_status(fd, true, 0, size, buf); + if (err) + goto free; + + size = le32_to_cpu((*log)->lslplen); + if (!size) + return 0; + + tmp = realloc(buf, size); + if (!tmp) { + err = -1; + goto free; + } + buf = tmp; + *log = buf; + + err = nvme_get_log_page(fd, NVME_NSID_NONE, NVME_LOG_LID_LBA_STATUS, + rae, size, buf); + if (!err) + return 0; + +free: + *log = NULL; + free(buf); + return err; +} + void nvme_init_dsm_range(struct nvme_dsm_range *dsm, __u32 *ctx_attrs, __u32 *llbas, __u64 *slbas, __u16 nr_ranges) { diff --git a/src/nvme/util.h b/src/nvme/util.h index 6534f631ea..a3541ab66d 100644 --- a/src/nvme/util.h +++ b/src/nvme/util.h @@ -165,6 +165,14 @@ int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, */ int nvme_get_ana_log_len(int fd, size_t *analen); +/** + * nvme_get_lba_status_log() - Retreive 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. + */ +int nvme_get_lba_status_log(int fd, bool rae, struct nvme_lba_status_log **log); + /** * nvme_namespace_attach_ctrls() - Attach namespace to controller(s) * @fd: File descriptor of nvme device From 3ca422565fa5031c00261d25251a528566bb1066 Mon Sep 17 00:00:00 2001 From: Tomas Bzatek Date: Wed, 3 Mar 2021 18:21:47 +0100 Subject: [PATCH 0065/1564] ioctl: Fix NVME_LOG_CDW10_NUMDL_MASK Used in nvme_get_log(), caused nvme_get_log_error() failures. --- src/nvme/ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 0730f866c9..a19dacf832 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -230,7 +230,7 @@ enum nvme_cmd_dword_fields { NVME_LOG_CDW10_LID_MASK = 0xff, NVME_LOG_CDW10_LSP_MASK = 0xf, NVME_LOG_CDW10_RAE_MASK = 0x1, - NVME_LOG_CDW10_NUMDL_MASK = 0xff, + NVME_LOG_CDW10_NUMDL_MASK = 0xffff, NVME_LOG_CDW11_NUMDU_MASK = 0xff, NVME_LOG_CDW11_LSI_MASK = 0xff, NVME_LOG_CDW14_UUID_MASK = 0x7f, From d771662523a4d76b6132e7c849f4dbff4b6eca6f Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Wed, 3 Mar 2021 14:02:56 -0800 Subject: [PATCH 0066/1564] fix log numdu mask This is a 16-bit value, not 8. Signed-off-by: Keith Busch --- src/nvme/ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index a19dacf832..12d90d6eaf 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -231,7 +231,7 @@ enum nvme_cmd_dword_fields { NVME_LOG_CDW10_LSP_MASK = 0xf, NVME_LOG_CDW10_RAE_MASK = 0x1, NVME_LOG_CDW10_NUMDL_MASK = 0xffff, - NVME_LOG_CDW11_NUMDU_MASK = 0xff, + NVME_LOG_CDW11_NUMDU_MASK = 0xffff, NVME_LOG_CDW11_LSI_MASK = 0xff, NVME_LOG_CDW14_UUID_MASK = 0x7f, NVME_LOG_CDW14_CSI_MASK = 0xff, From 2beddedcf778bec15383b3c0b9ebab2cce9506be Mon Sep 17 00:00:00 2001 From: Tomas Bzatek Date: Thu, 4 Mar 2021 16:58:13 +0100 Subject: [PATCH 0067/1564] Docs strings updates --- src/nvme/ioctl.h | 2 +- src/nvme/types.h | 297 +++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 250 insertions(+), 49 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 4090aa8224..72a4b63f52 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -365,7 +365,7 @@ int nvme_ns_rescan(int fd); * for many architectures that are incapable of allowing distinguishing a * namespace id > 0x80000000 from a negative error number. * - * Return: 0 if @nsid was set succecssfully or -1 with errno set otherwise. + * Return: 0 if @nsid was set successfully or -1 with errno set otherwise. */ int nvme_get_nsid(int fd, __u32 *nsid); diff --git a/src/nvme/types.h b/src/nvme/types.h index 219ea6a147..b40e1f8b1a 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -778,8 +778,8 @@ struct nvme_id_psd { * from Runtime D3 * @rtd3e: RTD3 Exit Latency, the typical latency in microseconds to enter * Runtime D3. - * @oaes: Optional Async Events Supported, see @enum nvme_id_ctrl_oaes . - * @ctratt: Controller Attributes, see @enum nvme_id_ctrl_ctratt + * @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. @@ -898,7 +898,7 @@ struct nvme_id_psd { * @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 - * maximum number of namespaces supported by the NVM. subsystem. + * maximum number of namespaces supported by the NVM subsystem. * @oncs: Optional NVM Command Support, see &enum nvme_id_ctrl_oncs. * @fuses: Fused Operation Support, see &enum nvme_id_ctrl_fuses. * @fna: Format NVM Attributes, see &enum nvme_id_ctrl_fna. @@ -1037,7 +1037,8 @@ struct nvme_id_ctrl { }; /** - * enum nvme_id_ctrl_cmic - + * enum nvme_id_ctrl_cmic - Controller Multipath IO and Namespace Sharing + * Capabilities of the controller and NVM subsystem. * @NVME_CTRL_CMIC_MULTI_PORT: * @NVME_CTRL_CMIC_MULTI_CTRL: * @NVME_CTRL_CMIC_MULTI_SRIOV: @@ -1584,7 +1585,7 @@ enum nvme_lbaf_rp { * @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.labf. + * 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. * @dpc: End-to-end Data Protection Capabilities, see @@ -1708,12 +1709,12 @@ struct nvme_id_ns { * Controller data structure. * @NVME_NS_FEAT_DULBE: If set, indicates that the controller supports the * 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. + * 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. * @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 @@ -2166,7 +2167,64 @@ struct nvme_id_iocs { }; /** - * struct nvme_error_log_page - + * 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. + * @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. + * @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. + * @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. + * @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. + * Bits 7-0: Byte in command that contained the error. + * Valid values are 0 to 63. + * @lba: LBA: This field indicates the first LBA that experienced + * the error condition, if applicable. + * @nsid: Namespace: This field indicates the NSID of the namespace + * 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. + * @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. + * @cs: Command Specific Information: This field contains command + * specific information. If used, the command definition + * specifies the information returned. + * @trtype_spec_info: */ struct nvme_error_log_page { __le64 error_count; @@ -2185,7 +2243,7 @@ struct nvme_error_log_page { }; /** - * enum - + * enum - nvme_err_pel * @NVME_ERR_PEL_BYTE_MASK: * @NVME_ERR_PEL_BIT_MASK: */ @@ -2195,30 +2253,154 @@ enum nvme_err_pel { }; /** - * struct nvme_smart_log - - * @critical_warning: - * @temperature: - * @avail_spare: - * @spare_thresh: - * @percent_used: - * @endu_grp_crit_warn_sumry: - * @data_units_read: - * @data_units_written: - * @host_reads: - * @host_writes: - * @ctrl_busy_time: - * @power_cycles: - * @power_on_hours: - * @unsafe_shutdowns: - * @media_errors: - * @num_err_log_entries: - * @warning_temp_time: - * @critical_comp_time: - * @temp_sensor: - * @thm_temp1_trans_count: - * @thm_temp2_trans_count: - * @thm_temp1_total_time: - * @thm_temp2_total_time: + * 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). + * @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. + * @avail_spare: Available Spare: Contains a normalized percentage (0% + * 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. + * @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). + * @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). + * @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. + * @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. + * @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. + * @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. + * @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. + * @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. + * @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. + * @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. + * @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. + * @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. + * @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. + * @thm_temp2_total_time: Total Time For Thermal Management Temperature 2 */ struct nvme_smart_log { __u8 critical_warning; @@ -2249,13 +2431,25 @@ struct nvme_smart_log { }; /** - * enum - nvme_smart_crit - * @NVME_SMART_CRIT_SPARE: - * @NVME_SMART_CRIT_TEMPERATURE: - * @NVME_SMART_CRIT_DEGRADED: - * @NVME_SMART_CRIT_MEDIA: - * @NVME_SMART_CRIT_VOLATILE_MEMORY: - * @NVME_SMART_CRIT_PMR_RO: + * enum - nvme_smart_crit: Critical Warning + * @NVME_SMART_CRIT_SPARE: If set, then the available spare capacity has fallen + * 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. + * @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. + * @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. + * @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. + * @NVME_SMART_CRIT_PMR_RO: If set, then the Persistent Memory Region has become + * read-only or unreliable. */ enum nvme_smart_crit { NVME_SMART_CRIT_SPARE = 1 << 0, @@ -2267,10 +2461,17 @@ enum nvme_smart_crit { }; /** - * enum - nvme_smart_egcw - * @NVME_SMART_EGCW_SPARE: - * @NVME_SMART_EGCW_DEGRADED: - * @NVME_SMART_EGCW_RO: + * 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. + * @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. */ enum nvme_smart_egcw { NVME_SMART_EGCW_SPARE = 1 << 0, From fdf4864350fedf6a0c3e6fa2c8135cddcb5639b6 Mon Sep 17 00:00:00 2001 From: Tomas Bzatek Date: Thu, 4 Mar 2021 17:43:30 +0100 Subject: [PATCH 0068/1564] build: Include libnvme.pc in the default make target --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ef470beffe..a4dbd7dfaf 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ INSTALL=install default: all -all: +all: $(NAME).pc @$(MAKE) -C src @$(MAKE) -C test @$(MAKE) -C examples From 6b898a0c9b4e0141d60577a54499c7e6c8d69221 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 19 Mar 2021 09:51:25 +0100 Subject: [PATCH 0069/1564] Make systemd and uuid optional Add configuration flags '--disable-systemd' and '--disable-uuid' to forcibly exclude systemd and uuid during build. Signed-off-by: Hannes Reinecke --- configure | 22 ++++++++++++++++------ src/nvme/tree.c | 14 +++++++++++--- src/nvme/tree.h | 9 ++++++--- 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/configure b/configure index 9e63d9e2c9..3fc24852f0 100755 --- a/configure +++ b/configure @@ -27,6 +27,10 @@ for opt do ;; --datadir=*) datadir="$optarg" ;; + --disable-systemd) disable_systemd=1 + ;; + --disable-uuid) disable_uuid=1 + ;; *) echo "ERROR: unkown option $opt" echo "Try '$0 --help' for more information" @@ -62,6 +66,8 @@ Options: [defaults in brackets after descriptions] --libdir=PATH install libraries in PATH [$libdir] --mandir=PATH install man pages in PATH [$mandir] --datadir=PATH install shared data in PATH [$datadir] + --disable-systemd do not link against libsystemd + --disable-uuid do not link against libuuid EOF exit 0 fi @@ -177,18 +183,22 @@ print_and_output_mak "datadir" "$datadir" ########################################## # check for libuuid libuuid="no" -${ld} -o /dev/null -luuid >/dev/null 2>&1 -if [ $? -eq 0 ]; then - libuuid="yes" +if [ -z "$disable_uuid" ] ; then + ${ld} -o /dev/null -luuid >/dev/null 2>&1 + if [ $? -eq 0 ]; then + libuuid="yes" + fi fi print_config "libuuid" "${libuuid}" ########################################## # check for SystemD systemd="no" -pkg-config --exists libsystemd --atleast-version=232 -if [ $? -eq 0 ]; then - systemd="yes" +if [ -z "$disable_systemd" ] ; then + pkg-config --exists libsystemd --atleast-version=232 + if [ $? -eq 0 ]; then + systemd="yes" + fi fi print_config "systemd" "${systemd}" diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 74aba7dfaf..0a7202b3d0 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -17,9 +17,6 @@ #include #include - -#include - #include "ioctl.h" #include "filters.h" #include "tree.h" @@ -69,7 +66,11 @@ struct nvme_ns { uint8_t eui64[8]; uint8_t nguid[16]; +#ifdef CONFIG_UUID uuid_t uuid; +#else + uint8_t uuid[16]; +#endif enum nvme_csi csi; }; @@ -740,10 +741,17 @@ const uint8_t *nvme_ns_get_nguid(nvme_ns_t n) return n->nguid; } +#ifdef CONFIG_UUID void nvme_ns_get_uuid(nvme_ns_t n, uuid_t out) { uuid_copy(out, n->uuid); } +#else +void nvme_ns_get_uuid(nvme_ns_t n, uint8_t *out) +{ + memcpy(out, n, 16); +} +#endif int nvme_ns_identify(nvme_ns_t n, struct nvme_id_ns *ns) { diff --git a/src/nvme/tree.h b/src/nvme/tree.h index dc52597485..f08106a88d 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -14,9 +14,9 @@ #include #include - +#ifdef CONFIG_UUID #include - +#endif #include "ioctl.h" #include "util.h" @@ -298,8 +298,11 @@ const uint8_t *nvme_ns_get_nguid(nvme_ns_t n); * * Copies the namespace's uuid to the destination buffer */ +#ifdef CONFIG_UUID void nvme_ns_get_uuid(nvme_ns_t n, uuid_t out); - +#else +void nvme_ns_get_uuid(nvme_ns_t n, uint8_t *out); +#endif /** * nvme_ns_get_sysfs_dir() - * @n: From 1ceab68e3676af1d792c646825faf6c6ada91cec Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 19 Mar 2021 10:50:37 +0100 Subject: [PATCH 0070/1564] Parse 'address' string into components The 'address' string really are several parts (traddr, trsvcid, and host_addr) which are separated by commas. So avoid every user having to parse that string on its own this patch exposes the individual parts via nvme_ctrl_get_{traddr,trsvcid,host_traddr}. Each call might return NULL if the respective value isn't set. Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 44 +++++++++++++++++++++++++++++++++++++++++++- src/nvme/tree.h | 24 ++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 74aba7dfaf..5d5e5efcd3 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -93,6 +93,9 @@ struct nvme_ctrl { char *sqsize; char *transport; char *subsysnqn; + char *traddr; + char *trsvcid; + char *host_traddr; }; struct nvme_subsystem { @@ -482,6 +485,21 @@ const char *nvme_ctrl_get_transport(nvme_ctrl_t c) return c->transport; } +const char *nvme_ctrl_get_traddr(nvme_ctrl_t c) +{ + return c->traddr; +} + +const char *nvme_ctrl_get_trsvcid(nvme_ctrl_t c) +{ + return c->trsvcid; +} + +const char *nvme_ctrl_get_host_traddr(nvme_ctrl_t c) +{ + return c->host_traddr; +} + int nvme_ctrl_identify(nvme_ctrl_t c, struct nvme_id_ctrl *id) { return nvme_identify_ctrl(nvme_ctrl_get_fd(c), id); @@ -537,6 +555,11 @@ void nvme_free_ctrl(nvme_ctrl_t c) free(c->sysfs_dir); free(c->subsysnqn); free(c->address); + free(c->traddr); + if (c->trsvcid) + free(c->trsvcid); + if (c->host_traddr) + free(c->host_traddr); free(c->firmware); free(c->model); free(c->state); @@ -581,6 +604,8 @@ static nvme_ctrl_t __nvme_ctrl_alloc(const char *path, const char *name) { DIR *d; nvme_ctrl_t c; + char *addr, *a, *e; + char *traddr = NULL, *trsvcid = NULL, *host_traddr = NULL; d = opendir(path); if (!d) @@ -612,7 +637,24 @@ static nvme_ctrl_t __nvme_ctrl_alloc(const char *path, const char *name) c->serial = nvme_get_ctrl_attr(c, "serial"); c->sqsize = nvme_get_ctrl_attr(c, "sqsize"); c->transport = nvme_get_ctrl_attr(c, "transport"); - + /* Parse 'address' string into components */ + addr = strdup(c->address); + a = strtok_r(addr, ",", &e); + while (a && strlen(a)) { + if (!strncmp(a, "traddr=", 7)) + traddr = a + 7; + else if (!strncmp(a, "trsvcid=", 8)) + trsvcid = a + 8; + else if (!strncmp(a, "host_traddr=", 12)) + host_traddr = a + 12; + a = strtok_r(NULL, ",", &e); + } + c->traddr = strdup(traddr); + if (trsvcid) + c->trsvcid = strdup(trsvcid); + if (host_traddr) + c->host_traddr = strdup(host_traddr); + free(addr); return c; free_ctrl: diff --git a/src/nvme/tree.h b/src/nvme/tree.h index dc52597485..d936d2cb8c 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -587,6 +587,30 @@ const char *nvme_ctrl_get_subsysnqn(nvme_ctrl_t c); */ nvme_subsystem_t nvme_ctrl_get_subsystem(nvme_ctrl_t c); +/** + * nvme_ctrl_get_traddr() - + * @c: + * + * Return: + */ +const char *nvme_ctrl_get_traddr(nvme_ctrl_t c); + +/** + * nvme_ctrl_get_trsvcid() - + * @c: + * + * Return: + */ +const char *nvme_ctrl_get_trsvcid(nvme_ctrl_t c); + +/** + * nvme_ctrl_get_host_traddr() - + * @c: + * + * Return: + */ +const char *nvme_ctrl_get_host_traddr(nvme_ctrl_t c); + /** * nvme_ctrl_identify() - * @c: From c72de401fa571ca19ded03971053b7b9e905e8ad Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Wed, 7 Apr 2021 11:49:11 -0700 Subject: [PATCH 0071/1564] updates from integration Various fixes and support for newer nvme operations. Signed-off-by: Keith Busch --- src/nvme/ioctl.c | 54 +++++++++++-- src/nvme/ioctl.h | 94 ++++++++++++++++++++-- src/nvme/types.h | 200 ++++++++++++++++++++++++++++++++++++++++------- src/nvme/util.c | 19 ++++- src/nvme/util.h | 7 ++ 5 files changed, 330 insertions(+), 44 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 12d90d6eaf..f4960f6f95 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -494,12 +494,12 @@ int nvme_identify_ns_csi(int fd, __u32 nsid, __u8 csi, void *data) NVME_UUID_NONE, csi, data); } -int nvme_identify_iocs(int fd, struct nvme_id_iocs *iocs) +int nvme_identify_iocs(int fd, __u16 cntlid, struct nvme_id_iocs *iocs) { BUILD_ASSERT(sizeof(struct nvme_id_iocs) == 4096); return nvme_identify(fd, NVME_IDENTIFY_CNS_CSI_CTRL, NVME_NSID_NONE, - NVME_CNTLID_NONE, NVME_NVMSETID_NONE, - NVME_UUID_NONE, NVME_CSI_NVM, iocs); + cntlid, NVME_NVMSETID_NONE, NVME_UUID_NONE, + NVME_CSI_NVM, iocs); } int nvme_zns_identify_ns(int fd, __u32 nsid, struct nvme_zns_id_ns *data) @@ -510,12 +510,17 @@ int nvme_zns_identify_ns(int fd, __u32 nsid, struct nvme_zns_id_ns *data) NVME_UUID_NONE, NVME_CSI_ZNS, data); } -int nvme_zns_identify_ctrl(int fd, struct nvme_zns_id_ctrl *data) +int nvme_zns_identify_ctrl(int fd, struct nvme_zns_id_ctrl *id) { BUILD_ASSERT(sizeof(struct nvme_zns_id_ctrl) == 4096); - return nvme_identify(fd, NVME_IDENTIFY_CNS_CSI_CTRL, NVME_NSID_NONE, - NVME_CNTLID_NONE, NVME_NVMSETID_NONE, - NVME_UUID_NONE, NVME_CSI_ZNS, data); + return nvme_identify_ctrl_csi(fd, NVME_CSI_ZNS, id); +} + + +int nvme_nvm_identify_ctrl(int fd, struct nvme_id_ctrl_nvm *id) +{ + BUILD_ASSERT(sizeof(struct nvme_id_ctrl_nvm ) == 4096); + return nvme_identify_ctrl_csi(fd, NVME_CSI_NVM, id); } int nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, @@ -717,6 +722,13 @@ int nvme_get_log_sanitize(int fd, bool rae, log); } +int nvme_get_log_persistent_event(int fd, enum nvme_pevent_log_action action, + __u32 size, void *pevent_log) +{ + return __nvme_get_log(fd, NVME_LOG_LID_PERSISTENT_EVENT, false, size, + pevent_log); +} + int nvme_get_log_zns_changed_zones(int fd, __u32 nsid, bool rae, struct nvme_zns_changed_zone_log *log) { @@ -1284,7 +1296,7 @@ int nvme_ns_attach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist) return nvme_ns_attach(fd, nsid, NVME_NS_ATTACH_SEL_CTRL_ATTACH, ctrlist); } -int nvme_ns_dettach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist) +int nvme_ns_detach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist) { return nvme_ns_attach(fd, nsid, NVME_NS_ATTACH_SEL_CTRL_DEATTACH, ctrlist); @@ -1724,6 +1736,32 @@ int nvme_dsm(int fd, __u32 nsid, __u32 attrs, __u16 nr_ranges, return nvme_submit_io_passthru(fd, &cmd, NULL); } +int nvme_copy(int fd, __u32 nsid, struct nvme_copy_range *copy, __u64 sdlba, + __u16 nr, __u8 prinfor, __u8 prinfow, __u8 dtype, __u16 dspec, + __u8 format, int lr, int fua, __u32 ilbrt, __u16 lbatm, + __u16 lbat) +{ + __u32 cdw12 = ((nr - 1) & 0xff) | ((format & 0xf) << 8) | + ((prinfor & 0xf) << 12) | ((dtype & 0xf) << 20) | + ((prinfow & 0xf) << 26) | ((fua & 0x1) << 30) | + ((lr & 0x1) << 31); + + struct nvme_passthru_cmd cmd = { + .opcode = nvme_cmd_copy, + .nsid = nsid, + .addr = (__u64)(uintptr_t)copy, + .data_len = nr * sizeof(*copy), + .cdw10 = sdlba & 0xffffffff, + .cdw11 = sdlba >> 32, + .cdw12 = cdw12, + .cdw13 = (dspec & 0xffff) << 16, + .cdw14 = ilbrt, + .cdw15 = (lbatm << 16) | lbat, + }; + + return nvme_submit_io_passthru(fd, &cmd, NULL); +} + int nvme_resv_acquire(int fd, __u32 nsid, enum nvme_resv_rtype rtype, enum nvme_resv_racqa racqa, bool iekey, __u64 crkey, __u64 nrkey) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 72a4b63f52..6804b77564 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -413,6 +413,7 @@ enum nvme_admin_opcode { nvme_admin_async_event = 0x0c, nvme_admin_ns_mgmt = 0x0d, nvme_admin_fw_commit = 0x10, + nvme_admin_fw_activate = nvme_admin_fw_commit, nvme_admin_fw_download = 0x11, nvme_admin_dev_self_test = 0x14, nvme_admin_ns_attach = 0x15, @@ -938,7 +939,7 @@ int nvme_identify_ns_descs(int fd, __u32 nsid, struct nvme_ns_id_desc *descs); * @nvmeset_id: NVM Set Identifier * @nvmset: User space destination address to transfer the data * - * Retrieves an NVM Set List, struct nvme_id_nvmset. The data structure is an + * Retrieves an NVM Set List, @struct nvme_id_nvmset_list. The data structure is an * ordered list by NVM Set Identifier, starting with the first NVM Set * Identifier supported by the NVM subsystem that is equal to or greater than * the NVM Set Identifier. @@ -1042,9 +1043,20 @@ int nvme_identify_ns_csi(int fd, __u32 nsid, __u8 csi, void *data); */ int nvme_identify_ctrl_csi(int fd, __u8 csi, void *data); +/** + * nvme_identify_ctrl_nvm() - + * @fd: File descriptor of nvme device + * @id: User space destination address to transfer the data + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_nvm_identify_ctrl(int fd, struct nvme_id_ctrl_nvm *id); + /** * nvme_identify_iocs() - * @fd: File descriptor of nvme device + * @cntlid: Controller ID * @iocs: User space destination address to transfer the data * * Retrieves list of the controller's supported io command set vectors. See @@ -1053,7 +1065,7 @@ int nvme_identify_ctrl_csi(int fd, __u8 csi, void *data); * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_identify_iocs(int fd, struct nvme_id_iocs *iocs); +int nvme_identify_iocs(int fd, __u16 cntlid, struct nvme_id_iocs *iocs); /** * nvme_zns_identify_ns() - @@ -1068,13 +1080,13 @@ int nvme_zns_identify_ns(int fd, __u32 nsid, struct nvme_zns_id_ns *data); /** * nvme_zns_identify_ctrl() - - * @fd: File descriptor of nvme device - * @data: User space destination address to transfer the data + * @fd: File descriptor of nvme device + * @id: User space destination address to transfer the data * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_zns_identify_ctrl(int fd, struct nvme_zns_id_ctrl *data); +int nvme_zns_identify_ctrl(int fd, struct nvme_zns_id_ctrl *id); /** * nvme_get_log() - NVMe Admin Get Log command @@ -1097,6 +1109,19 @@ int nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, __u8 lsp, __u16 lsi, bool rae, __u8 uuidx, enum nvme_csi csi, __u32 len, void *log); +static inline int nvme_get_nsid_log(int fd, enum nvme_cmd_get_log_lid lid, + __u32 nsid, __u32 len, void *log) +{ + return nvme_get_log(fd, lid, nsid, 0, 0, 0, false, 0, 0, len, + log); +} + +static inline int nvme_get_log_simple(int fd, enum nvme_cmd_get_log_lid lid, + __u32 len, void *log) +{ + return nvme_get_nsid_log(fd, lid, NVME_NSID_ALL, len, log); +} + /** * nvme_get_log_error() - Retrieve nvme error log * @fd: File descriptor of nvme device @@ -1372,6 +1397,25 @@ int nvme_get_log_sanitize(int fd, bool rae, int nvme_get_log_zns_changed_zones(int fd, __u32 nsid, bool rae, struct nvme_zns_changed_zone_log *log); +/** + * enum nvme_pevent_log_action - + */ +enum nvme_pevent_log_action { + NVME_PEVENT_LOG_READ = 0x0, + NVME_PEVENT_LOG_EST_CTX_AND_READ = 0x1, + NVME_PEVENT_LOG_RELEASE_CTX = 0x2, +}; + +/** + * nvme_get_log_persistent_event() - + * &fd: + * &action: + * @size: + * @pevent_log: + */ +int nvme_get_log_persistent_event(int fd, enum nvme_pevent_log_action action, + __u32 size, void *pevent_log); + /** * nvme_set_features() - Set a feature attribute * @fd: File descriptor of nvme device @@ -1393,6 +1437,21 @@ int nvme_set_features(int fd, __u8 fid, __u32 nsid, __u32 cdw11, __u32 cdw12, bool save, __u8 uuidx, __u32 cdw15, __u32 data_len, void *data, __u32 *result); +static inline int nvme_set_features_data(int fd, __u8 fid, __u32 nsid, + __u32 cdw11, bool save, __u32 data_len, void *data, + __u32 *result) +{ + return nvme_set_features(fd, fid, nsid, cdw11, 0, save, 0, 0, data_len, + data, result); +} + +static inline int nvme_set_features_simple(int fd, __u8 fid, __u32 nsid, + __u32 cdw11, bool save, __u32 *result) +{ + return nvme_set_features_data(fd, fid, nsid, cdw11, save, 0, NULL, + result); +} + /** * nvme_set_features_arbitration() - * @fd: File descriptor of nvme device @@ -1800,6 +1859,17 @@ int nvme_get_features(int fd, enum nvme_features_id fid, __u32 nsid, enum nvme_get_features_sel sel, __u32 cdw11, __u8 uuidx, __u32 data_len, void *data, __u32 *result); +static inline int nvme_get_features_data(int fd, enum nvme_features_id fid, + __u32 nsid, __u32 data_len, void *data, __u32 *result) +{ + return nvme_get_features(fd, fid, nsid, 0, 0, 0, data_len, data, result); +} +static inline int nvme_get_features_simple(int fd, enum nvme_features_id fid, + __u32 nsid, __u32 *result) +{ + return nvme_get_features_data(fd, fid, nsid, 0, NULL, result); +} + /** * nvme_get_features_arbitration() - * @fd: File descriptor of nvme device @@ -2296,7 +2366,7 @@ int nvme_fw_download(int fd, __u32 offset, __u32 data_len, void *data); int nvme_fw_commit(int fd, __u8 slot, enum nvme_fw_commit_ca action, bool bpid); /** - * nvme_security_receive() - + * nvme_security_send() - * @fd: File descriptor of nvme device * @nsid: Namespace ID to issue security command on * @nssf: NVMe Security Specific field @@ -2634,6 +2704,7 @@ enum nvme_io_opcode { nvme_cmd_resv_report = 0x0e, nvme_cmd_resv_acquire = 0x11, nvme_cmd_resv_release = 0x15, + nvme_cmd_copy = 0x19, nvme_zns_cmd_mgmt_send = 0x79, nvme_zns_cmd_mgmt_recv = 0x7a, nvme_zns_cmd_append = 0x7d, @@ -2904,6 +2975,17 @@ enum nvme_dsm_attributes { int nvme_dsm(int fd, __u32 nsid, __u32 attrs, __u16 nr_ranges, struct nvme_dsm_range *dsm); +/** + * nvme_copy() - + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_copy(int fd, __u32 nsid, struct nvme_copy_range *copy, __u64 sdlba, + __u16 nr, __u8 prinfor, __u8 prinfow, __u8 dtype, __u16 dspec, + __u8 format, int lr, int fua, __u32 ilbrt, __u16 lbatm, + __u16 lbat); + /** * enum nvme_resv_rtype - * @NVME_RESERVATION_RTYPE_WE: diff --git a/src/nvme/types.h b/src/nvme/types.h index b40e1f8b1a..4a1dbce205 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -193,7 +193,8 @@ enum nvme_csi { * @NVME_REG_PMRSTS: Persistent Memory Region Status * @NVME_REG_PMREBS: Persistent Memory Region Elasticity Buffer Size * @NVME_REG_PMRSWTP: Memory Region Sustained Write Throughput - * @NVME_REG_PMRMSC: Persistent Memory Region Controller Memory Space Control + * @NVME_REG_PMRMSCL: Persistent Memory Region Controller Memory Space Control Lower + * @NVME_REG_PMRMSCU: Persistent Memory Region Controller Memory Space Control Upper */ enum nvme_register_offsets { NVME_REG_CAP = 0x0000, @@ -218,7 +219,8 @@ enum nvme_register_offsets { NVME_REG_PMRSTS = 0x0e08, NVME_REG_PMREBS = 0x0e0c, NVME_REG_PMRSWTP = 0x0e10, - NVME_REG_PMRMSC = 0x0e14, + NVME_REG_PMRMSCL = 0x0e14, + NVME_REG_PMRMSCU = 0x0e18, }; /** @@ -241,7 +243,6 @@ static inline bool nvme_is_64bit_reg(__u32 offset) case NVME_REG_ACQ: case NVME_REG_BPMBL: case NVME_REG_CMBMSC: - case NVME_REG_PMRMSC: return true; default: return false; @@ -913,7 +914,7 @@ struct nvme_id_psd { * 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. - * @nvscc: NVM Vendor Specific Command Configuration, see + * @icsvscc: NVM Vendor Specific Command Configuration, see * &enum nvme_id_ctrl_nvscc. * @nwpc: Namespace Write Protection Capabilities, see * &enum nvme_id_ctrl_nwpc. @@ -1013,7 +1014,7 @@ struct nvme_id_ctrl { __u8 vwc; __le16 awun; __le16 awupf; - __u8 nvscc; + __u8 icsvscc; __u8 nwpc; __le16 acwu; __u8 rsvd534[2]; @@ -1684,7 +1685,10 @@ struct nvme_id_ns { __le16 npdg; __le16 npda; __le16 nows; - __u8 rsvd74[18]; + __le16 mssrl; + __le32 mcl; + __u8 msrc; + __u8 rsvd81[11]; __le32 anagrpid; __u8 rsvd96[3]; __u8 nsattr; @@ -2028,7 +2032,7 @@ struct nvme_id_uuid_list { /** * struct nvme_ctrl_list - - * @num; + * @num: * @identifier: */ struct nvme_ctrl_list { @@ -2044,6 +2048,25 @@ struct nvme_ns_list { __le32 ns[NVME_ID_NS_LIST_MAX]; }; +/** + * struct nvme_id_ctrl_nvm - + * vsl: + * wzsl: + * wusl: + * dmrl: + * dmrsl: + * dmsl: + */ +struct nvme_id_ctrl_nvm { + __u8 vsl; + __u8 wzsl; + __u8 wusl; + __u8 dmrl; + __u32 dmrsl; + __u64 dmsl; + __u8 rsvd16[4080]; +}; + /** * struct nvme_zns_lbafe - * zsze: @@ -2081,10 +2104,10 @@ struct nvme_zns_id_ns { /** * struct nvme_zns_id_ctrl - - * @zamds: + * @zasl: */ struct nvme_zns_id_ctrl { - __u8 zamds; + __u8 zasl; __u8 rsvd1[4095]; }; @@ -2548,7 +2571,7 @@ struct nvme_st_result { } __attribute__((packed)); /** - * enum - + * enum nvme_status_result - * @NVME_ST_RESULT_NO_ERR: * @NVME_ST_RESULT_ABORTED: * @NVME_ST_RESULT_CLR: @@ -2578,7 +2601,7 @@ enum nvme_status_result { }; /** - * enum - + * enum nvme_st_code - * @NVME_ST_CODE_NONE: * @NVME_ST_CODE_SHORT: * @NVME_ST_CODE_EXTENDED: @@ -2593,7 +2616,7 @@ enum nvme_st_code { }; /** - * enum - + * enum nvme_st_valid_diag_info - * @NVME_ST_VALID_DIAG_INFO_NSID: * @NVME_ST_VALID_DIAG_INFO_FLBA: * @NVME_ST_VALID_DIAG_INFO_SCT: @@ -2606,7 +2629,6 @@ enum nvme_st_valid_diag_info { NVME_ST_VALID_DIAG_INFO_SC = 1 << 3, }; - /** * struct nvme_self_test_log - * @current_operation: @@ -2741,8 +2763,8 @@ struct nvme_nvmset_predictable_lat_log { __le64 dtwin_rt; __le64 dtwin_wt; __le64 dtwin_tmax; - __le64 dtwin_tmin_hi; - __le64 dtwin_tmin_lo; + __le64 ndwin_tmin_hi; + __le64 ndwin_tmin_lo; __u8 rsvd72[56]; __le64 dtwin_re; __le64 dtwin_we; @@ -2837,9 +2859,10 @@ struct nvme_ana_log { /** * struct nvme_persistent_event_log - * @lid: - * @ttl: + * @tnev: + * @tll: * @rv: - * @lht: + * @lhl: * @ts: * @poh: * @pcc: @@ -2853,10 +2876,11 @@ struct nvme_ana_log { struct nvme_persistent_event_log { __u8 lid; __u8 rsvd1[3]; - __le32 ttl; + __le32 tnev; + __le64 tll; __u8 rv; __u8 rsvd17; - __le16 lht; + __le16 lhl; __le64 ts; __u8 poh[16]; __le64 pcc; @@ -2865,8 +2889,114 @@ struct nvme_persistent_event_log { char sn[20]; char mn[40]; char subnqn[NVME_NQN_LENGTH]; - __u8 rsvd372; + __u8 rsvd372[108]; __u8 seb[32]; +} __attribute__((packed)); + +struct nvme_persistent_event_entry { + __u8 etype; + __u8 etype_rev; + __u8 ehl; + __u8 rsvd3; + __le16 cntlid; + __le64 ets; + __u8 rsvd14[6]; + __le16 vsil; + __le16 el; +}; + +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_THERMAL_EXCURSION_EVENT = 0x0d, +}; + +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; +} __attribute__((packed)); + +struct nvme_time_stamp_change_event { + __le64 previous_timestamp; + __le64 ml_secs_since_reset; +}; + +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; +} __attribute__((packed)); + +struct nvme_nss_hw_err_event { + __le16 nss_hw_err_event_code; + __u8 rsvd2[2]; + __u8 *add_hw_err_info; +}; + +struct nvme_change_ns_event { + __le32 nsmgt_cdw10; + __u8 rsvd4[4]; + __le64 nsze; + __u8 rsvd16[8]; + __le64 nscap; + __u8 flbas; + __u8 dps; + __u8 nmic; + __u8 rsvd35; + __le32 ana_grp_id; + __le16 nvmset_id; + __le16 rsvd42; + __le32 nsid; +}; + +struct nvme_format_nvm_start_event { + __le32 nsid; + __u8 fna; + __u8 rsvd5[3]; + __le32 format_nvm_cdw10; +}; + +struct nvme_format_nvm_compln_event { + __le32 nsid; + __u8 smallest_fpi; + __u8 format_nvm_status; + __le16 compln_info; + __le32 status_field; +}; + +struct nvme_sanitize_start_event { + __le32 sani_cap; + __le32 sani_cdw10; + __le32 sani_cdw11; +}; + +struct nvme_sanitize_compln_event { + __le16 sani_prog; + __le16 sani_status; + __le16 cmpln_info; + __u8 rsvd6[2]; +}; + +struct nvme_thermal_exc_event { + __u8 over_temp; + __u8 threshold; }; /** @@ -2883,13 +3013,13 @@ struct nvme_lba_rd { /** * struct nvme_lbas_ns_element - * @neid: - * @nrld: + * @nlrd: * @ratype: * @lba_rd: */ struct nvme_lbas_ns_element { __le32 neid; - __le32 nrld; + __le32 nlrd; __u8 ratype; __u8 rsvd8[7]; struct nvme_lba_rd lba_rd[]; @@ -3008,6 +3138,7 @@ enum nvme_sanitize_sstat { NVME_SANITIZE_SSTAT_COMPLETED_PASSES_MASK = 0x1f, NVME_SANITIZE_SSTAT_GLOBAL_DATA_ERASED_SHIFT = 8, NVME_SANITIZE_SSTAT_GLOBAL_DATA_ERASED_MASK = 0x1, + NVME_SANITIZE_SSTAT_GLOBAL_DATA_ERASED = 1 << NVME_SANITIZE_SSTAT_GLOBAL_DATA_ERASED_SHIFT, }; /** @@ -3221,6 +3352,16 @@ struct nvme_dsm_range { __le64 slba; }; +struct nvme_copy_range { + __u8 rsvd0[8]; + __le64 slba; + __le16 nlb; + __u8 rsvd18[6]; + __le32 eilbrt; + __le16 elbatm; + __le16 elbat; +}; + /** * struct nvme_registered_ctrl - * @cntlid: @@ -3253,7 +3394,7 @@ struct nvme_registered_ctrl_ext { }; /** - * struct nvme_resv_status -{ + * struct nvme_resv_status - * @gen: * @rtype: * @regctl: @@ -3319,12 +3460,15 @@ enum { }; /** - * struct nvme_host_mem_buf_desc - + * struct nvme_host_mem_buf_attrs - */ -struct nvme_host_mem_buf_desc { - __le64 addr; - __le32 size; - __u32 rsvd; +struct nvme_host_mem_buf_attrs { + __le32 hsize; + __le32 hmdlal; + __le32 hmdlau; + __le32 hmdlec; + __u8 rsvd16[4080]; + }; /** diff --git a/src/nvme/util.c b/src/nvme/util.c index 7d044bf563..46c423e8a8 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -334,12 +334,12 @@ int nvme_get_ctrl_telemetry(int fd, bool rae, struct nvme_telemetry_log **log) return nvme_get_telemetry_log(fd, false, true, rae, log); } -int nvme_get_host_telemetry(int fd, struct nvme_telemetry_log **log) +int nvme_get_host_telemetry(int fd, struct nvme_telemetry_log **log) { return nvme_get_telemetry_log(fd, false, false, false, log); } -int nvme_get_new_host_telemetry(int fd, struct nvme_telemetry_log **log) +int nvme_get_new_host_telemetry(int fd, struct nvme_telemetry_log **log) { return nvme_get_telemetry_log(fd, true, false, false, log); } @@ -382,6 +382,21 @@ int nvme_get_lba_status_log(int fd, bool rae, struct nvme_lba_status_log **log) return err; } +void nvme_init_copy_range(struct nvme_copy_range *copy, __u16 *nlbs, + __u64 *slbas, __u32 *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].eilbrt = cpu_to_le32(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) { diff --git a/src/nvme/util.h b/src/nvme/util.h index a3541ab66d..b5a1031cc8 100644 --- a/src/nvme/util.h +++ b/src/nvme/util.h @@ -121,6 +121,13 @@ void nvme_init_ctrl_list(struct nvme_ctrl_list *cntlist, __u16 num_ctrls, void nvme_init_dsm_range(struct nvme_dsm_range *dsm, __u32 *ctx_attrs, __u32 *llbas, __u64 *slbas, __u16 nr_ranges); +/** + * nvme_init_copy_range() - + */ +void nvme_init_copy_range(struct nvme_copy_range *copy, __u16 *nlbs, + __u64 *slbas, __u32 *eilbrts, __u32 *elbatms, + __u32 *elbats, __u16 nr); + /** * __nvme_get_log_page() - * @fd: File descriptor of nvme device From c68535a1cbf51b801f230f97cce8861b4fd455a0 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Wed, 7 Apr 2021 14:24:33 -0700 Subject: [PATCH 0072/1564] fix integration breakage Signed-off-by: Keith Busch --- src/nvme/ioctl.h | 6 ++++-- src/nvme/tree.c | 4 +++- test/register.c | 3 ++- test/test.c | 1 + test/zns.c | 2 +- 5 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 6804b77564..c9494ba80c 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -10,6 +10,7 @@ #ifndef _LIBNVME_IOCTL_H #define _LIBNVME_IOCTL_H +#include #include #include "types.h" @@ -1112,7 +1113,7 @@ int nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, static inline int nvme_get_nsid_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u32 len, void *log) { - return nvme_get_log(fd, lid, nsid, 0, 0, 0, false, 0, 0, len, + return nvme_get_log(fd, lid, nsid, 0, 0, 0, false, 0, NVME_CSI_NVM, len, log); } @@ -1862,7 +1863,8 @@ int nvme_get_features(int fd, enum nvme_features_id fid, __u32 nsid, static inline int nvme_get_features_data(int fd, enum nvme_features_id fid, __u32 nsid, __u32 data_len, void *data, __u32 *result) { - return nvme_get_features(fd, fid, nsid, 0, 0, 0, data_len, data, result); + return nvme_get_features(fd, fid, nsid, NVME_GET_FEATURES_SEL_CURRENT, + 0, 0, data_len, data, result); } static inline int nvme_get_features_simple(int fd, enum nvme_features_id fid, __u32 nsid, __u32 *result) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index d0309938af..f1bd2405a4 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -650,7 +650,9 @@ static nvme_ctrl_t __nvme_ctrl_alloc(const char *path, const char *name) host_traddr = a + 12; a = strtok_r(NULL, ",", &e); } - c->traddr = strdup(traddr); + + if (traddr) + c->traddr = strdup(traddr); if (trsvcid) c->trsvcid = strdup(trsvcid); if (host_traddr) diff --git a/test/register.c b/test/register.c index b405eafa4e..06244dfd5c 100644 --- a/test/register.c +++ b/test/register.c @@ -45,7 +45,8 @@ void nvme_print_registers(void *regs) __u32 pmrsts = nvme_mmio_read32(regs + NVME_REG_PMRSTS); __u32 pmrebs = nvme_mmio_read32(regs + NVME_REG_PMREBS); __u32 pmrswtp = nvme_mmio_read32(regs + NVME_REG_PMRSWTP); - __u64 pmrmsc = nvme_mmio_read64(regs + NVME_REG_PMRMSC); + __u64 pmrmsc = nvme_mmio_read32(regs + NVME_REG_PMRMSCL) | + (__u64)nvme_mmio_read64(regs + NVME_REG_PMRMSCU) << 32; printf("%-10s : %llx\n", "CAP", cap); printf(" %-8s : %llx\n", "MQES", NVME_CAP_MQES(cap)); diff --git a/test/test.c b/test/test.c index a2229876d5..851ccb3b50 100644 --- a/test/test.c +++ b/test/test.c @@ -18,6 +18,7 @@ #include #include #include +#include #include static char *nqn_match; diff --git a/test/zns.c b/test/zns.c index fd186f19bf..e54c7abaf8 100644 --- a/test/zns.c +++ b/test/zns.c @@ -40,7 +40,7 @@ static void show_zns_properties(nvme_ns_t n) return; } - printf("zamds:%u\n", zns_ctrl.zamds); + printf("zasl:%u\n", zns_ctrl.zasl); if (nvme_zns_mgmt_recv(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), 0, NVME_ZNS_ZRA_REPORT_ZONES, NVME_ZNS_ZRAS_REPORT_ALL, From 6c5dac4f4cd0f11ac9f08255fed8e4fa9f08bc5f Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 12 Apr 2021 08:11:44 +0200 Subject: [PATCH 0073/1564] Fixup libuuid compilation Use correct configure symbol 'CONFIG_LIBUUID' and allow the test program to compile without libuud. Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 4 ++-- src/nvme/tree.h | 4 ++-- test/Makefile | 2 +- test/test.c | 7 ++++++- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index f1bd2405a4..8dd709f1af 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -66,7 +66,7 @@ struct nvme_ns { uint8_t eui64[8]; uint8_t nguid[16]; -#ifdef CONFIG_UUID +#ifdef CONFIG_LIBUUID uuid_t uuid; #else uint8_t uuid[16]; @@ -785,7 +785,7 @@ const uint8_t *nvme_ns_get_nguid(nvme_ns_t n) return n->nguid; } -#ifdef CONFIG_UUID +#ifdef CONFIG_LIBUUID void nvme_ns_get_uuid(nvme_ns_t n, uuid_t out) { uuid_copy(out, n->uuid); diff --git a/src/nvme/tree.h b/src/nvme/tree.h index 49614aebf8..a2842bc22c 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -14,7 +14,7 @@ #include #include -#ifdef CONFIG_UUID +#ifdef CONFIG_LIBUUID #include #endif #include "ioctl.h" @@ -298,7 +298,7 @@ const uint8_t *nvme_ns_get_nguid(nvme_ns_t n); * * Copies the namespace's uuid to the destination buffer */ -#ifdef CONFIG_UUID +#ifdef CONFIG_LIBUUID void nvme_ns_get_uuid(nvme_ns_t n, uuid_t out); #else void nvme_ns_get_uuid(nvme_ns_t n, uint8_t *out); diff --git a/test/Makefile b/test/Makefile index 16206220ed..ed050d0bd6 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,5 +1,5 @@ CFLAGS ?= -g -O2 -override CFLAGS += -Wall -D_GNU_SOURCE -L../src/ -I../src/ -luuid +override CFLAGS += -Wall -D_GNU_SOURCE -L../src/ -I../src/ include ../Makefile.quiet diff --git a/test/test.c b/test/test.c index 851ccb3b50..0bc96b0a94 100644 --- a/test/test.c +++ b/test/test.c @@ -18,7 +18,9 @@ #include #include #include +#ifdef CONFIG_LIBUUID #include +#endif #include static char *nqn_match; @@ -348,9 +350,10 @@ int main() nvme_ctrl_get_state(c)); nvme_ctrl_for_each_ns(c, n) { +#ifdef CONFIG_LIBUUID char uuid_str[40]; uuid_t uuid; - +#endif printf(" `- %s lba size:%d lba max:%lu\n", nvme_ns_get_name(n), nvme_ns_get_lba_size(n), nvme_ns_get_lba_count(n)); @@ -358,9 +361,11 @@ int main() print_hex(nvme_ns_get_eui64(n), 8); printf(" nguid:"); print_hex(nvme_ns_get_nguid(n), 16); +#ifdef CONFIG_LIBUUID nvme_ns_get_uuid(n, uuid); uuid_unparse_lower(uuid, uuid_str); printf(" uuid:%s csi:%d\n", uuid_str, nvme_ns_get_csi(n)); +#endif } nvme_ctrl_for_each_path(c, p) From d10aab43889a3fbbd3eaa388d67b76fc37bdd1ea Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 13 Apr 2021 14:29:39 +0200 Subject: [PATCH 0074/1564] fabrics: fixup hostid size The NVMe host id is a UUID with the string length 36. As the read() call uses the passed-in length minus one we need to increase the host ID length by one to avoid nvmf_read_file(f, NVMF_HOSTID_LEN) skipping the last character. Signed-off-by: Hannes Reinecke --- src/nvme/fabrics.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 52e05670d9..c562f9a1b2 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -32,7 +32,7 @@ #include "ioctl.h" #include "util.h" -#define NVMF_HOSTID_SIZE 36 +#define NVMF_HOSTID_SIZE 37 const char *nvmf_dev = "/dev/nvme-fabrics"; const char *nvmf_hostnqn_file = "/etc/nvme/hostnqn"; @@ -374,7 +374,7 @@ static char *nvmf_read_file(const char *f, int len) return false; memset(buf, 0, len); - ret = read(fd, buf, sizeof(buf - 1)); + ret = read(fd, buf, len - 1); close (fd); if (ret < 0) From d5abea07960993cef9e6f965090a56e084a1e3ba Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 14 Apr 2021 12:57:55 +0200 Subject: [PATCH 0075/1564] fabrics: add mapping functions for discovery log entries The discovery log entries contain numerical values for attributes, so we should be providing mapping functions to translate them back to strings. Signed-off-by: Hannes Reinecke --- src/nvme/fabrics.c | 116 ++++++++++++++++++++++++++++++++++++++------- src/nvme/fabrics.h | 64 +++++++++++++++++++++++++ 2 files changed, 163 insertions(+), 17 deletions(-) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index c562f9a1b2..870bbb1d3d 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -38,6 +38,104 @@ const char *nvmf_dev = "/dev/nvme-fabrics"; const char *nvmf_hostnqn_file = "/etc/nvme/hostnqn"; const char *nvmf_hostid_file = "/etc/nvme/hostid"; +const char *arg_str(const char * const *strings, + size_t array_size, size_t idx) +{ + if (idx < array_size && strings[idx]) + return strings[idx]; + return "unrecognized"; +} + +const char * const trtypes[] = { + [NVMF_TRTYPE_RDMA] = "rdma", + [NVMF_TRTYPE_FC] = "fc", + [NVMF_TRTYPE_TCP] = "tcp", + [NVMF_TRTYPE_LOOP] = "loop", +}; + +const char *nvmf_trtype_str(__u8 trtype) +{ + return arg_str(trtypes, ARRAY_SIZE(trtypes), trtype); +} + +static const char * const adrfams[] = { + [NVMF_ADDR_FAMILY_PCI] = "pci", + [NVMF_ADDR_FAMILY_IP4] = "ipv4", + [NVMF_ADDR_FAMILY_IP6] = "ipv6", + [NVMF_ADDR_FAMILY_IB] = "infiniband", + [NVMF_ADDR_FAMILY_FC] = "fibre-channel", +}; + +const char *nvmf_adrfam_str(__u8 adrfam) +{ + return arg_str(adrfams, ARRAY_SIZE(adrfams), adrfam); +} + +static const char * const subtypes[] = { + [NVME_NQN_DISC] = "discovery subsystem", + [NVME_NQN_NVME] = "nvme subsystem", +}; + +const char *nvmf_subtype_str(__u8 subtype) +{ + return arg_str(subtypes, ARRAY_SIZE(subtypes), subtype); +} + +static const char * const treqs[] = { + [NVMF_TREQ_NOT_SPECIFIED] = "not specified", + [NVMF_TREQ_REQUIRED] = "required", + [NVMF_TREQ_NOT_REQUIRED] = "not required", + [NVMF_TREQ_DISABLE_SQFLOW] = "not specified, " + "sq flow control disable supported", +}; + +const char *nvmf_treq_str(__u8 treq) +{ + return arg_str(treqs, ARRAY_SIZE(treqs), treq); +} + +static const char * const sectypes[] = { + [NVMF_TCP_SECTYPE_NONE] = "none", + [NVMF_TCP_SECTYPE_TLS] = "tls", +}; + +const char *nvmf_sectype_str(__u8 sectype) +{ + return arg_str(sectypes, ARRAY_SIZE(sectypes), sectype); +} + +static const char * const prtypes[] = { + [NVMF_RDMA_PRTYPE_NOT_SPECIFIED] = "not specified", + [NVMF_RDMA_PRTYPE_IB] = "infiniband", + [NVMF_RDMA_PRTYPE_ROCE] = "roce", + [NVMF_RDMA_PRTYPE_ROCEV2] = "roce-v2", + [NVMF_RDMA_PRTYPE_IWARP] = "iwarp", +}; + +const char *nvmf_prtype_str(__u8 prtype) +{ + return arg_str(prtypes, ARRAY_SIZE(prtypes), prtype); +} + +static const char * const qptypes[] = { + [NVMF_RDMA_QPTYPE_CONNECTED] = "connected", + [NVMF_RDMA_QPTYPE_DATAGRAM] = "datagram", +}; + +const char *nvmf_qptype_str(__u8 qptype) +{ + return arg_str(qptypes, ARRAY_SIZE(qptypes), qptype); +} + +static const char * const cms[] = { + [NVMF_RDMA_CMS_RDMA_CM] = "rdma-cm", +}; + +const char *nvmf_cms_str(__u8 cm) +{ + return arg_str(cms, ARRAY_SIZE(cms), cm); +} + static int add_bool_argument(char **argstr, char *tok, bool arg) { char *nstr; @@ -235,23 +333,7 @@ nvme_ctrl_t nvmf_connect_disc_entry(struct nvmf_disc_log_entry *e, return NULL; } - switch (e->trtype) { - case NVMF_TRTYPE_RDMA: - cfg.transport = "rdma"; - break; - case NVMF_TRTYPE_FC: - cfg.transport = "fc"; - break; - case NVMF_TRTYPE_TCP: - cfg.transport = "tcp"; - break; - case NVMF_TRTYPE_LOOP: - cfg.transport = "loop"; - break; - default: - break; - } - + cfg.transport = nvmf_trtype_str(e->trtype); cfg.nqn = e->subnqn; if (e->treq & NVMF_TREQ_DISABLE_SQFLOW) cfg.disable_sqflow = true; diff --git a/src/nvme/fabrics.h b/src/nvme/fabrics.h index d512cf3dab..cbf4e4872a 100644 --- a/src/nvme/fabrics.h +++ b/src/nvme/fabrics.h @@ -59,6 +59,70 @@ struct nvme_fabrics_config { bool data_digest; }; +/** + * nvmf_trtype_str() - + * @trtype: + * + * Return: + */ +const char *nvmf_trtype_str(__u8 trtype); + +/** + * nvmf_adrfam_str() - + * @adrfam: + * + * Return: + */ +const char *nvmf_adrfam_str(__u8 adrfam); + +/** + * nvmf_subtype_str() - + * @subtype: + * + * Return: + */ +const char *nvmf_subtype_str(__u8 subtype); + +/** + * nvmf_treq_str() - + * @treq: + * + * Return: + */ +const char *nvmf_treq_str(__u8 treq); + +/** + * nvmf_sectype_str() - + * @sectype: + * + * Return: + */ +const char *nvmf_sectype_str(__u8 sectype); + +/** + * nvmf_prtype_str() - + * @prtype: + * + * Return: + */ +const char *nvmf_prtype_str(__u8 prtype); + +/** + * nvmf_qptype_str() - + * @qptype: + * + * Return: + */ +const char *nvmf_qptype_str(__u8 qptype); + +/** + * nvmf_cms_str() - + * @cms: + * + * Return: + */ +const char *nvmf_cms_str(__u8 cms); + /** * nvmf_add_ctrl_opts() - * @cfg: From ad58c7f2beeab274204b10b9a892882e97563984 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 30 Apr 2021 10:03:20 +0200 Subject: [PATCH 0076/1564] tree: Make functions static Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 8dd709f1af..669f83be9f 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -26,12 +26,13 @@ /* XXX: Make a place for private declarations */ extern int nvme_set_attr(const char *dir, const char *attr, const char *value); -void nvme_free_subsystem(struct nvme_subsystem *s); -int nvme_subsystem_scan_namespace(struct nvme_subsystem *s, char *name); -int nvme_scan_subsystem(struct nvme_root *r, char *name, nvme_scan_filter_t f); -int nvme_subsystem_scan_ctrl(struct nvme_subsystem *s, char *name); -int nvme_ctrl_scan_namespace(struct nvme_ctrl *c, char *name); -int nvme_ctrl_scan_path(struct nvme_ctrl *c, char *name); +static void nvme_free_subsystem(struct nvme_subsystem *s); +static int nvme_subsystem_scan_namespace(struct nvme_subsystem *s, char *name); +static int nvme_scan_subsystem(struct nvme_root *r, char *name, + nvme_scan_filter_t f); +static int nvme_subsystem_scan_ctrl(struct nvme_subsystem *s, char *name); +static int nvme_ctrl_scan_namespace(struct nvme_ctrl *c, char *name); +static int nvme_ctrl_scan_path(struct nvme_ctrl *c, char *name); struct nvme_path { struct list_node entry; @@ -236,7 +237,7 @@ void nvme_free_ns(struct nvme_ns *n) free(n); } -void nvme_free_subsystem(struct nvme_subsystem *s) +static void nvme_free_subsystem(struct nvme_subsystem *s) { struct nvme_ctrl *c, *_c; struct nvme_ns *n, *_n; @@ -270,7 +271,7 @@ static int nvme_subsystem_scan_namespaces(struct nvme_subsystem *s) return 0; } -int nvme_subsystem_scan_ctrls(struct nvme_subsystem *s) +static int nvme_subsystem_scan_ctrls(struct nvme_subsystem *s) { struct dirent **ctrls; int i, ret; @@ -286,7 +287,8 @@ int nvme_subsystem_scan_ctrls(struct nvme_subsystem *s) return 0; } -int nvme_scan_subsystem(struct nvme_root *r, char *name, nvme_scan_filter_t f) +static int nvme_scan_subsystem(struct nvme_root *r, char *name, + nvme_scan_filter_t f) { struct nvme_subsystem *s; char *path; @@ -324,6 +326,7 @@ int nvme_scan_subsystem(struct nvme_root *r, char *name, nvme_scan_filter_t f) free(path); return -1; } + nvme_ctrl_t nvme_path_get_subsystem(nvme_path_t p) { return p->c; @@ -378,7 +381,7 @@ static void nvme_subsystem_set_path_ns(nvme_subsystem_t s, nvme_path_t p) } } -int nvme_ctrl_scan_path(struct nvme_ctrl *c, char *name) +static int nvme_ctrl_scan_path(struct nvme_ctrl *c, char *name) { struct nvme_path *p; char *path, *grpid; @@ -688,7 +691,7 @@ nvme_ctrl_t nvme_scan_ctrl(const char *name) return nvme_ctrl_alloc(nvme_ctrl_sysfs_dir, name); } -int nvme_subsystem_scan_ctrl(struct nvme_subsystem *s, char *name) +static int nvme_subsystem_scan_ctrl(struct nvme_subsystem *s, char *name) { nvme_ctrl_t c; @@ -996,7 +999,7 @@ nvme_ns_t nvme_scan_namespace(const char *name) return __nvme_scan_namespace(nvme_ns_sysfs_dir, name); } -int nvme_ctrl_scan_namespace(struct nvme_ctrl *c, char *name) +static int nvme_ctrl_scan_namespace(struct nvme_ctrl *c, char *name) { struct nvme_ns *n; @@ -1010,7 +1013,7 @@ int nvme_ctrl_scan_namespace(struct nvme_ctrl *c, char *name) return 0; } -int nvme_subsystem_scan_namespace(struct nvme_subsystem *s, char *name) +static int nvme_subsystem_scan_namespace(struct nvme_subsystem *s, char *name) { struct nvme_ns *n; From 00b666fcee5f94695e3330729e64de91b5ff23ef Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 30 Apr 2021 13:40:09 +0200 Subject: [PATCH 0077/1564] Match systemd version with nvme-cli nvme-cli refers to systemd version 242, so we should be checking for the same version here to avoid linking failures. Signed-off-by: Hannes Reinecke --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 3fc24852f0..2481163184 100755 --- a/configure +++ b/configure @@ -195,7 +195,7 @@ print_config "libuuid" "${libuuid}" # check for SystemD systemd="no" if [ -z "$disable_systemd" ] ; then - pkg-config --exists libsystemd --atleast-version=232 + pkg-config --exists libsystemd --atleast-version=242 if [ $? -eq 0 ]; then systemd="yes" fi From 2912365abcb201d5c088aaae91016fe07e5842ea Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 8 Apr 2021 14:13:48 +0200 Subject: [PATCH 0078/1564] tree: add 'nvme_host' structure Add a 'nvme_host' structure to hold the host NQN and host ID and place it between 'nvme_root' and 'nvme_subsystem'. Signed-off-by: Hannes Reinecke --- examples/display-columnar.c | 114 ++++++++++++++++++--------------- examples/display-tree.c | 64 ++++++++++--------- examples/telemetry-listen.c | 30 +++++---- src/nvme/tree.c | 123 +++++++++++++++++++++++++++++------- src/nvme/tree.h | 100 +++++++++++++++++++++++++---- test/cpp.cc | 55 ++++++++++------ test/test.c | 108 +++++++++++++++++-------------- test/zns.c | 17 +++-- 8 files changed, 410 insertions(+), 201 deletions(-) diff --git a/examples/display-columnar.c b/examples/display-columnar.c index 283f073e44..cd3f007f16 100644 --- a/examples/display-columnar.c +++ b/examples/display-columnar.c @@ -17,6 +17,7 @@ static const char dash[101] = {[0 ... 99] = '-'}; int main() { nvme_root_t r; + nvme_host_t h; nvme_subsystem_t s; nvme_ctrl_t c; nvme_path_t p; @@ -30,15 +31,19 @@ int main() printf("%-16s %-96s %-.16s\n", "Subsystem", "Subsystem-NQN", "Controllers"); printf("%-.16s %-.96s %-.16s\n", dash, dash, dash); - nvme_for_each_subsystem(r, s) { - bool first = true; - printf("%-16s %-96s ", nvme_subsystem_get_name(s), nvme_subsystem_get_nqn(s)); + nvme_for_each_host(r, h) { + nvme_for_each_subsystem(h, s) { + bool first = true; + printf("%-16s %-96s ", nvme_subsystem_get_name(s), + nvme_subsystem_get_nqn(s)); - nvme_subsystem_for_each_ctrl(s, c) { - printf("%s%s", first ? "": ", ", nvme_ctrl_get_name(c)); - first = false; + nvme_subsystem_for_each_ctrl(s, c) { + printf("%s%s", first ? "": ", ", + nvme_ctrl_get_name(c)); + first = false; + } + printf("\n"); } - printf("\n"); } printf("\n"); @@ -47,28 +52,33 @@ int main() printf("%-.8s %-.20s %-.40s %-.8s %-.6s %-.14s %-.12s %-.16s\n", dash, dash, dash, dash, dash, dash, dash, dash); - nvme_for_each_subsystem(r, s) { - nvme_subsystem_for_each_ctrl(s, c) { - bool first = true; - - printf("%-8s %-20s %-40s %-8s %-6s %-14s %-12s ", - nvme_ctrl_get_name(c), nvme_ctrl_get_serial(c), - nvme_ctrl_get_model(c), nvme_ctrl_get_firmware(c), - nvme_ctrl_get_transport(c), nvme_ctrl_get_address(c), - nvme_subsystem_get_name(s)); - - nvme_ctrl_for_each_ns(c, n) { - printf("%s%s", first ? "": ", ", - nvme_ns_get_name(n)); - first = false; - } - - nvme_ctrl_for_each_path(c, p) { - printf("%s%s", first ? "": ", ", - nvme_ns_get_name(nvme_path_get_ns(p))); - first = false; + nvme_for_each_host(r, h) { + nvme_for_each_subsystem(h, s) { + nvme_subsystem_for_each_ctrl(s, c) { + bool first = true; + + printf("%-8s %-20s %-40s %-8s %-6s %-14s %-12s ", + nvme_ctrl_get_name(c), + nvme_ctrl_get_serial(c), + nvme_ctrl_get_model(c), + nvme_ctrl_get_firmware(c), + nvme_ctrl_get_transport(c), + nvme_ctrl_get_address(c), + nvme_subsystem_get_name(s)); + + nvme_ctrl_for_each_ns(c, n) { + printf("%s%s", first ? "": ", ", + nvme_ns_get_name(n)); + first = false; + } + + nvme_ctrl_for_each_path(c, p) { + printf("%s%s", first ? "": ", ", + nvme_ns_get_name(nvme_path_get_ns(p))); + first = false; + } + printf("\n"); } - printf("\n"); } } printf("\n"); @@ -76,31 +86,33 @@ int main() printf("%-12s %-8s %-16s %-8s %-16s\n", "Device", "NSID", "Sectors", "Format", "Controllers"); printf("%-.12s %-.8s %-.16s %-.8s %-.16s\n", dash, dash, dash, dash, dash); - nvme_for_each_subsystem(r, s) { - nvme_subsystem_for_each_ctrl(s, c) - nvme_ctrl_for_each_ns(c, n) - printf("%-12s %-8d %-16lu %-8d %s\n", - nvme_ns_get_name(n), - nvme_ns_get_nsid(n), - nvme_ns_get_lba_count(n), - nvme_ns_get_lba_size(n), - nvme_ctrl_get_name(c)); - - nvme_subsystem_for_each_ns(s, n) { - bool first = true; - - printf("%-12s %-8d %-16lu %-8d ", - nvme_ns_get_name(n), - nvme_ns_get_nsid(n), - nvme_ns_get_lba_count(n), - nvme_ns_get_lba_size(n)); - + nvme_for_each_host(r, h) { + nvme_for_each_subsystem(h, s) { nvme_subsystem_for_each_ctrl(s, c) { - printf("%s%s", first ? "" : ", ", - nvme_ctrl_get_name(c)); - first = false; + nvme_ctrl_for_each_ns(c, n) + printf("%-12s %-8d %-16lu %-8d %s\n", + nvme_ns_get_name(n), + nvme_ns_get_nsid(n), + nvme_ns_get_lba_count(n), + nvme_ns_get_lba_size(n), + nvme_ctrl_get_name(c)); + } + + nvme_subsystem_for_each_ns(s, n) { + bool first = true; + + printf("%-12s %-8d %-16lu %-8d ", + nvme_ns_get_name(n), + nvme_ns_get_nsid(n), + nvme_ns_get_lba_count(n), + nvme_ns_get_lba_size(n)); + nvme_subsystem_for_each_ctrl(s, c) { + printf("%s%s", first ? "" : ", ", + nvme_ctrl_get_name(c)); + first = false; + } + printf("\n"); } - printf("\n"); } } return 0; diff --git a/examples/display-tree.c b/examples/display-tree.c index 58520dfd96..66b16c276d 100644 --- a/examples/display-tree.c +++ b/examples/display-tree.c @@ -16,6 +16,7 @@ int main() { nvme_root_t r; + nvme_host_t h; nvme_subsystem_t s, _s; nvme_ctrl_t c, _c; nvme_path_t p, _p; @@ -26,40 +27,43 @@ int main() return -1; printf(".\n"); - nvme_for_each_subsystem_safe(r, s, _s) { - printf("%c-- %s - NQN=%s\n", _s ? '|' : '`', - nvme_subsystem_get_name(s), - nvme_subsystem_get_nqn(s)); + nvme_for_each_host(r, h) { + nvme_for_each_subsystem_safe(h, s, _s) { + printf("%c-- %s - NQN=%s\n", _s ? '|' : '`', + nvme_subsystem_get_name(s), + nvme_subsystem_get_nqn(s)); - nvme_subsystem_for_each_ns_safe(s, n, _n) { - printf("%c |-- %s lba size:%d lba max:%lu\n", - _s ? '|' : ' ', - nvme_ns_get_name(n), nvme_ns_get_lba_size(n), - nvme_ns_get_lba_count(n)); - } + nvme_subsystem_for_each_ns_safe(s, n, _n) { + printf("%c |-- %s lba size:%d lba max:%lu\n", + _s ? '|' : ' ', + nvme_ns_get_name(n), + nvme_ns_get_lba_size(n), + nvme_ns_get_lba_count(n)); + } - nvme_subsystem_for_each_ctrl_safe(s, c, _c) { - printf("%c %c-- %s %s %s %s\n", - _s ? '|' : ' ', _c ? '|' : '`', - nvme_ctrl_get_name(c), - nvme_ctrl_get_transport(c), - nvme_ctrl_get_address(c), - nvme_ctrl_get_state(c)); + nvme_subsystem_for_each_ctrl_safe(s, c, _c) { + printf("%c %c-- %s %s %s %s\n", + _s ? '|' : ' ', _c ? '|' : '`', + nvme_ctrl_get_name(c), + nvme_ctrl_get_transport(c), + nvme_ctrl_get_address(c), + nvme_ctrl_get_state(c)); - nvme_ctrl_for_each_ns_safe(c, n, _n) - printf("%c %c %c-- %s lba size:%d lba max:%lu\n", - _s ? '|' : ' ', _c ? '|' : ' ', - _n ? '|' : '`', - nvme_ns_get_name(n), - nvme_ns_get_lba_size(n), - nvme_ns_get_lba_count(n)); + nvme_ctrl_for_each_ns_safe(c, n, _n) + printf("%c %c %c-- %s lba size:%d lba max:%lu\n", + _s ? '|' : ' ', _c ? '|' : ' ', + _n ? '|' : '`', + nvme_ns_get_name(n), + nvme_ns_get_lba_size(n), + nvme_ns_get_lba_count(n)); - nvme_ctrl_for_each_path_safe(c, p, _p) - printf("%c %c %c-- %s %s\n", - _s ? '|' : ' ', _c ? '|' : ' ', - _p ? '|' : '`', - nvme_path_get_name(p), - nvme_path_get_ana_state(p)); + nvme_ctrl_for_each_path_safe(c, p, _p) + printf("%c %c %c-- %s %s\n", + _s ? '|' : ' ', _c ? '|' : ' ', + _p ? '|' : '`', + nvme_path_get_name(p), + nvme_path_get_ana_state(p)); + } } } nvme_free_tree(r); diff --git a/examples/telemetry-listen.c b/examples/telemetry-listen.c index 7d1f260bda..c4cde957db 100644 --- a/examples/telemetry-listen.c +++ b/examples/telemetry-listen.c @@ -126,30 +126,34 @@ int main() nvme_subsystem_t s; nvme_ctrl_t c; + nvme_host_t h; nvme_root_t r; r = nvme_scan(); if (!r) return EXIT_FAILURE; - nvme_for_each_subsystem(r, s) - nvme_subsystem_for_each_ctrl(s, c) - i++; + nvme_for_each_host(r, h) + nvme_for_each_subsystem(h, s) + nvme_subsystem_for_each_ctrl(s, c) + i++; e = calloc(i, sizeof(e)); FD_ZERO(&fds); i = 0; - nvme_for_each_subsystem(r, s) { - nvme_subsystem_for_each_ctrl(s, c) { - int fd = open_uevent(c); - - if (fd < 0) - continue; - FD_SET(fd, &fds); - e[i].uevent_fd = fd; - e[i].c = c; - i++; + nvme_for_each_host(r, h) { + nvme_for_each_subsystem(h, s) { + nvme_subsystem_for_each_ctrl(s, c) { + int fd = open_uevent(c); + + if (fd < 0) + continue; + FD_SET(fd, &fds); + e[i].uevent_fd = fd; + e[i].c = c; + i++; + } } } diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 669f83be9f..eb554a3523 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -22,13 +22,15 @@ #include "tree.h" #include "filters.h" #include "util.h" +#include "fabrics.h" /* XXX: Make a place for private declarations */ extern int nvme_set_attr(const char *dir, const char *attr, const char *value); +static void nvme_free_host(struct nvme_host *h); static void nvme_free_subsystem(struct nvme_subsystem *s); static int nvme_subsystem_scan_namespace(struct nvme_subsystem *s, char *name); -static int nvme_scan_subsystem(struct nvme_root *r, char *name, +static int nvme_scan_subsystem(struct nvme_host *h, char *name, nvme_scan_filter_t f); static int nvme_subsystem_scan_ctrl(struct nvme_subsystem *s, char *name); static int nvme_ctrl_scan_namespace(struct nvme_ctrl *c, char *name); @@ -104,15 +106,24 @@ struct nvme_subsystem { struct list_node entry; struct list_head ctrls; struct list_head namespaces; - struct nvme_root *r; + struct nvme_host *h; char *name; char *sysfs_dir; char *subsysnqn; }; -struct nvme_root { +struct nvme_host { + struct list_node entry; struct list_head subsystems; + struct nvme_root *r; + + char *hostnqn; + char *hostid; +}; + +struct nvme_root { + struct list_head hosts; }; static inline void nvme_free_dirents(struct dirent **d, int i) @@ -121,17 +132,42 @@ static inline void nvme_free_dirents(struct dirent **d, int i) free(d[i]); free(d); } + +nvme_host_t nvme_default_host(nvme_root_t r) +{ + struct nvme_host *h = calloc(1, sizeof(*h)); + + if (!h) { + errno = ENOMEM; + return NULL; + } + + h->hostnqn = nvmf_hostnqn_from_file(); + h->hostid = nvmf_hostid_from_file(); + list_head_init(&h->subsystems); + list_add(&r->hosts, &h->entry); + h->r = r; + return h; +} + static int nvme_scan_topology(struct nvme_root *r, nvme_scan_filter_t f) { + struct nvme_host *h; struct dirent **subsys; int i, ret; + h = nvme_default_host(r); + if (!h) { + free(r); + errno = ENOMEM; + return -1; + } ret = nvme_scan_subsystems(&subsys); if (ret < 0) return ret; for (i = 0; i < ret; i++) - nvme_scan_subsystem(r, subsys[i]->d_name, f); + nvme_scan_subsystem(h, subsys[i]->d_name, f); nvme_free_dirents(subsys, i); return 0; @@ -146,7 +182,7 @@ nvme_root_t nvme_scan_filter(nvme_scan_filter_t f) return NULL; } - list_head_init(&r->subsystems); + list_head_init(&r->hosts); nvme_scan_topology(r, f); return r; } @@ -156,40 +192,65 @@ nvme_root_t nvme_scan() return nvme_scan_filter(NULL); } -nvme_subsystem_t nvme_first_subsystem(nvme_root_t r) +nvme_host_t nvme_first_host(nvme_root_t r) +{ + return list_top(&r->hosts, struct nvme_host, entry); +} + +nvme_host_t nvme_next_host(nvme_root_t r, nvme_host_t h) +{ + return h ? list_next(&r->hosts, h, entry) : NULL; +} + +nvme_root_t nvme_host_get_root(nvme_host_t h) +{ + return h->r; +} + +const char *nvme_host_get_hostnqn(nvme_host_t h) +{ + return h->hostnqn; +} + +const char *nvme_host_get_hostid(nvme_host_t h) { - return list_top(&r->subsystems, struct nvme_subsystem, entry); + return h->hostid; } -nvme_subsystem_t nvme_next_subsystem(nvme_root_t r, nvme_subsystem_t s) +nvme_subsystem_t nvme_first_subsystem(nvme_host_t h) { - return s ? list_next(&r->subsystems, s, entry) : NULL; + return list_top(&h->subsystems, struct nvme_subsystem, entry); +} + +nvme_subsystem_t nvme_next_subsystem(nvme_host_t h, nvme_subsystem_t s) +{ + return s ? list_next(&h->subsystems, s, entry) : NULL; } void nvme_refresh_topology(nvme_root_t r) { - struct nvme_subsystem *s, *_s; + struct nvme_host *h, *_h; - nvme_for_each_subsystem_safe(r, s, _s) - nvme_free_subsystem(s); + nvme_for_each_host_safe(r, h, _h) + nvme_free_host(h); nvme_scan_topology(r, NULL); } void nvme_reset_topology(nvme_root_t r) { - struct nvme_subsystem *s, *_s; + struct nvme_host *h, *_h; - nvme_for_each_subsystem_safe(r, s, _s) - nvme_free_subsystem(s); + nvme_for_each_host_safe(r, h, _h) + nvme_free_host(h); nvme_scan_topology(r, NULL); } void nvme_free_tree(nvme_root_t r) { - struct nvme_subsystem *s, *_s; + struct nvme_host *h, *_h; - nvme_for_each_subsystem_safe(r, s, _s) - nvme_free_subsystem(s); + nvme_for_each_host_safe(r, h, _h) + nvme_free_host(h); free(r); } @@ -218,6 +279,11 @@ nvme_ctrl_t nvme_subsystem_next_ctrl(nvme_subsystem_t s, nvme_ctrl_t c) return c ? list_next(&s->ctrls, c, entry) : NULL; } +nvme_host_t nvme_subsystem_get_host(nvme_subsystem_t s) +{ + return s->h; +} + nvme_ns_t nvme_subsystem_first_ns(nvme_subsystem_t s) { return list_top(&s->namespaces, struct nvme_ns, entry); @@ -255,6 +321,19 @@ static void nvme_free_subsystem(struct nvme_subsystem *s) free(s); } +void nvme_free_host(struct nvme_host *h) +{ + struct nvme_subsystem *s, *_s; + + list_del_init(&h->entry); + nvme_for_each_subsystem_safe(h, s, _s) + nvme_free_subsystem(s); + free(h->hostnqn); + if (h->hostid) + free(h->hostid); + free(h); +} + static int nvme_subsystem_scan_namespaces(struct nvme_subsystem *s) { struct dirent **namespaces; @@ -287,7 +366,7 @@ static int nvme_subsystem_scan_ctrls(struct nvme_subsystem *s) return 0; } -static int nvme_scan_subsystem(struct nvme_root *r, char *name, +static int nvme_scan_subsystem(struct nvme_host *h, char *name, nvme_scan_filter_t f) { struct nvme_subsystem *s; @@ -304,16 +383,16 @@ static int nvme_scan_subsystem(struct nvme_root *r, char *name, goto free_path; } - s->r = r; - s->name = strdup(name);; + s->h = h; + s->name = strdup(name); s->sysfs_dir = path; s->subsysnqn = nvme_get_subsys_attr(s, "subsysnqn"); list_head_init(&s->ctrls); list_head_init(&s->namespaces); + list_add(&h->subsystems, &s->entry); nvme_subsystem_scan_namespaces(s); nvme_subsystem_scan_ctrls(s); - list_add(&r->subsystems, &s->entry); if (f && !f(s)) { nvme_free_subsystem(s); diff --git a/src/nvme/tree.h b/src/nvme/tree.h index a2842bc22c..b3c96ed8cc 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -44,6 +44,11 @@ typedef struct nvme_ctrl *nvme_ctrl_t; */ typedef struct nvme_subsystem *nvme_subsystem_t; +/** + * + */ +typedef struct nvme_host *nvme_host_t; + /** * */ @@ -55,21 +60,78 @@ typedef struct nvme_root *nvme_root_t; typedef bool (*nvme_scan_filter_t)(nvme_subsystem_t); /** - * nvme_first_subsystem() - + * nvme_first_host() - * @r: * * Return: */ -nvme_subsystem_t nvme_first_subsystem(nvme_root_t r); +nvme_host_t nvme_first_host(nvme_root_t r); /** - * nvme_next_subsystem() - + * nvme_next_host() - * @r: + * @h: + * + * Return: + */ +nvme_host_t nvme_next_host(nvme_root_t r, nvme_host_t h); + +/** + * nvme_host_get_root() - + * @h: + * + * Return: + */ +nvme_root_t nvme_host_get_root(nvme_host_t h); + +/** + * nvme_host_get_hostnqn() - + * @h: + * + * Return: + */ +const char *nvme_host_get_hostnqn(nvme_host_t h); + +/** + * nvme_host_get_hostid() - + * @h: + * + * Return: + */ +const char *nvme_host_get_hostid(nvme_host_t h); + +/** + * nvme_default_host() - + * @r: + * + * Return: + */ +nvme_host_t nvme_default_host(nvme_root_t r); + +/** + * nvme_first_subsystem() - + * @h: + * + * Return: + */ +nvme_subsystem_t nvme_first_subsystem(nvme_host_t h); + +/** + * nvme_next_subsystem() - + * @h: * @s: * * Return: */ -nvme_subsystem_t nvme_next_subsystem(nvme_root_t r, nvme_subsystem_t s); +nvme_subsystem_t nvme_next_subsystem(nvme_host_t h, nvme_subsystem_t s); + +/** + * nvme_subsystem_get_host() - + * @s: + * + * Return: + */ +nvme_host_t nvme_subsystem_get_host(nvme_subsystem_t s); /** * nvme_ctrl_first_ns() - @@ -139,21 +201,37 @@ nvme_ns_t nvme_subsystem_first_ns(nvme_subsystem_t s); */ nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n); +/** + * nvme_for_each_host_safe() + */ +#define nvme_for_each_host_safe(r, h, _h) \ + for (h = nvme_first_host(r), \ + _h = nvme_next_host(r, h); \ + h != NULL; \ + h = _h, _h = nvme_next_host(r, h)) + +/** + * nvme_for_each_host() + */ +#define nvme_for_each_host(r, h) \ + for (h = nvme_first_host(r); h != NULL; \ + h = nvme_next_host(r, h)) + /** * nvme_for_each_subsystem_safe() */ -#define nvme_for_each_subsystem_safe(r, s, _s) \ - for (s = nvme_first_subsystem(r), \ - _s = nvme_next_subsystem(r, s); \ +#define nvme_for_each_subsystem_safe(h, s, _s) \ + for (s = nvme_first_subsystem(h), \ + _s = nvme_next_subsystem(h, s); \ s != NULL; \ - s = _s, _s = nvme_next_subsystem(r, s)) + s = _s, _s = nvme_next_subsystem(h, s)) /** * nvme_for_each_subsystem() */ -#define nvme_for_each_subsystem(r, s) \ - for (s = nvme_first_subsystem(r); s != NULL; \ - s = nvme_next_subsystem(r, s)) +#define nvme_for_each_subsystem(h, s) \ + for (s = nvme_first_subsystem(h); s != NULL; \ + s = nvme_next_subsystem(h, s)) /** * nvme_subsystem_for_each_ctrl_safe() diff --git a/test/cpp.cc b/test/cpp.cc index eb48b78e3a..f1463b46f5 100644 --- a/test/cpp.cc +++ b/test/cpp.cc @@ -12,6 +12,7 @@ int main() { nvme_root_t r; + nvme_host_t h; nvme_subsystem_t s; nvme_ctrl_t c; nvme_path_t p; @@ -21,25 +22,41 @@ int main() if (!r) return -1; - nvme_for_each_subsystem(r, s) { - std::cout << nvme_subsystem_get_name(s) << " - NQN=" << nvme_subsystem_get_nqn(s) << "\n"; - nvme_subsystem_for_each_ctrl(s, c) { - std::cout << " `- " << nvme_ctrl_get_name(c) << " " << - nvme_ctrl_get_transport(c) << " " << - nvme_ctrl_get_address(c) << " " << - nvme_ctrl_get_state(c) << "\n"; - nvme_ctrl_for_each_ns(c, n) - std::cout << " `- " << nvme_ns_get_name(n) << - "lba size:" << nvme_ns_get_lba_size(n) << " lba max:" << - nvme_ns_get_lba_count(n) << "\n"; - nvme_ctrl_for_each_path(c, p) - std::cout << " `- " << nvme_path_get_name(p) << " " << - nvme_path_get_ana_state(p) << "\n"; - } - nvme_subsystem_for_each_ns(s, n) { - std::cout << " `- " << nvme_ns_get_name(n) << - "lba size:" << nvme_ns_get_lba_size(n) << " lba max:" << - nvme_ns_get_lba_count(n) << "\n"; + nvme_for_each_host(r, h) { + nvme_for_each_subsystem(h, s) { + std::cout << nvme_subsystem_get_name(s) + << " - NQN=" << nvme_subsystem_get_nqn(s) + << "\n"; + nvme_subsystem_for_each_ctrl(s, c) { + std::cout << " `- " << nvme_ctrl_get_name(c) + << " " << nvme_ctrl_get_transport(c) + << " " << nvme_ctrl_get_address(c) + << " " << nvme_ctrl_get_state(c) + << "\n"; + nvme_ctrl_for_each_ns(c, n) { + std::cout << " `- " + << nvme_ns_get_name(n) + << "lba size:" + << nvme_ns_get_lba_size(n) + << " lba max:" + << nvme_ns_get_lba_count(n) + << "\n"; + } + nvme_ctrl_for_each_path(c, p) { + std::cout << " `- " + << nvme_path_get_name(p) + << " " + << nvme_path_get_ana_state(p) + << "\n"; + } + } + nvme_subsystem_for_each_ns(s, n) { + std::cout << " `- " << nvme_ns_get_name(n) + << "lba size:" + << nvme_ns_get_lba_size(n) + << " lba max:" + << nvme_ns_get_lba_count(n) << "\n"; + } } } std::cout << "\n"; diff --git a/test/test.c b/test/test.c index 0bc96b0a94..e8ee0403a6 100644 --- a/test/test.c +++ b/test/test.c @@ -303,6 +303,7 @@ static void print_hex(const uint8_t *x, int len) int main() { nvme_root_t r; + nvme_host_t h; nvme_subsystem_t s; nvme_ctrl_t c; nvme_path_t p; @@ -311,14 +312,16 @@ int main() printf("Test filter for common loop back target\n"); nqn_match = "testnqn"; r = nvme_scan_filter(nvme_match_subsysnqn_filter); - nvme_for_each_subsystem(r, s) { - printf("%s - NQN=%s\n", nvme_subsystem_get_name(s), - nvme_subsystem_get_nqn(s)); - nvme_subsystem_for_each_ctrl(s, c) { - printf(" %s %s %s %s\n", nvme_ctrl_get_name(c), - nvme_ctrl_get_transport(c), - nvme_ctrl_get_address(c), - nvme_ctrl_get_state(c)); + nvme_for_each_host(r, h) { + nvme_for_each_subsystem(h, s) { + printf("%s - NQN=%s\n", nvme_subsystem_get_name(s), + nvme_subsystem_get_nqn(s)); + nvme_subsystem_for_each_ctrl(s, c) { + printf(" %s %s %s %s\n", nvme_ctrl_get_name(c), + nvme_ctrl_get_transport(c), + nvme_ctrl_get_address(c), + nvme_ctrl_get_state(c)); + } } } printf("\n"); @@ -340,61 +343,70 @@ int main() return -1; printf("Test walking the topology\n"); - nvme_for_each_subsystem(r, s) { - printf("%s - NQN=%s\n", nvme_subsystem_get_name(s), - nvme_subsystem_get_nqn(s)); - nvme_subsystem_for_each_ctrl(s, c) { - printf(" `- %s %s %s %s\n", nvme_ctrl_get_name(c), - nvme_ctrl_get_transport(c), - nvme_ctrl_get_address(c), - nvme_ctrl_get_state(c)); + nvme_for_each_host(r, h) { + nvme_for_each_subsystem(h, s) { + printf("%s - NQN=%s\n", nvme_subsystem_get_name(s), + nvme_subsystem_get_nqn(s)); + nvme_subsystem_for_each_ctrl(s, c) { + printf(" `- %s %s %s %s\n", + nvme_ctrl_get_name(c), + nvme_ctrl_get_transport(c), + nvme_ctrl_get_address(c), + nvme_ctrl_get_state(c)); - nvme_ctrl_for_each_ns(c, n) { + nvme_ctrl_for_each_ns(c, n) { #ifdef CONFIG_LIBUUID - char uuid_str[40]; - uuid_t uuid; + char uuid_str[40]; + uuid_t uuid; #endif - printf(" `- %s lba size:%d lba max:%lu\n", - nvme_ns_get_name(n), nvme_ns_get_lba_size(n), - nvme_ns_get_lba_count(n)); - printf(" eui:"); - print_hex(nvme_ns_get_eui64(n), 8); - printf(" nguid:"); - print_hex(nvme_ns_get_nguid(n), 16); + printf(" `- %s lba size:%d lba max:%lu\n", + nvme_ns_get_name(n), + nvme_ns_get_lba_size(n), + nvme_ns_get_lba_count(n)); + printf(" eui:"); + print_hex(nvme_ns_get_eui64(n), 8); + printf(" nguid:"); + print_hex(nvme_ns_get_nguid(n), 16); #ifdef CONFIG_LIBUUID - nvme_ns_get_uuid(n, uuid); - uuid_unparse_lower(uuid, uuid_str); - printf(" uuid:%s csi:%d\n", uuid_str, nvme_ns_get_csi(n)); + nvme_ns_get_uuid(n, uuid); + uuid_unparse_lower(uuid, uuid_str); + printf(" uuid:%s csi:%d\n", uuid_str, + nvme_ns_get_csi(n)); #endif - } + } - nvme_ctrl_for_each_path(c, p) - printf(" `- %s %s\n", nvme_path_get_name(p), - nvme_path_get_ana_state(p)); - } + nvme_ctrl_for_each_path(c, p) + printf(" `- %s %s\n", + nvme_path_get_name(p), + nvme_path_get_ana_state(p)); + } - nvme_subsystem_for_each_ns(s, n) { - printf(" `- %s lba size:%d lba max:%lu\n", - nvme_ns_get_name(n), nvme_ns_get_lba_size(n), - nvme_ns_get_lba_count(n)); + nvme_subsystem_for_each_ns(s, n) { + printf(" `- %s lba size:%d lba max:%lu\n", + nvme_ns_get_name(n), + nvme_ns_get_lba_size(n), + nvme_ns_get_lba_count(n)); + } } + printf("\n"); } - printf("\n"); printf("Test identification, logs, and features\n"); - nvme_for_each_subsystem(r, s) { - nvme_subsystem_for_each_ctrl(s, c) { - test_ctrl(c); - printf("\n"); - nvme_ctrl_for_each_ns(c, n) { + nvme_for_each_host(r, h) { + nvme_for_each_subsystem(h, s) { + nvme_subsystem_for_each_ctrl(s, c) { + test_ctrl(c); + printf("\n"); + nvme_ctrl_for_each_ns(c, n) { + test_namespace(n); + printf("\n"); + } + } + nvme_subsystem_for_each_ns(s, n) { test_namespace(n); printf("\n"); } } - nvme_subsystem_for_each_ns(s, n) { - test_namespace(n); - printf("\n"); - } } nvme_free_tree(r); diff --git a/test/zns.c b/test/zns.c index e54c7abaf8..7d854cd745 100644 --- a/test/zns.c +++ b/test/zns.c @@ -57,6 +57,7 @@ int main() { nvme_subsystem_t s; nvme_root_t r; + nvme_host_t h; nvme_ctrl_t c; nvme_ns_t n; @@ -64,17 +65,19 @@ int main() if (!r) return -1; - nvme_for_each_subsystem(r, s) { - nvme_subsystem_for_each_ctrl(s, c) { - nvme_ctrl_for_each_ns(c, n) { + nvme_for_each_host(r, h) { + nvme_for_each_subsystem(h, s) { + nvme_subsystem_for_each_ctrl(s, c) { + nvme_ctrl_for_each_ns(c, n) { + if (nvme_ns_get_csi(n) == NVME_CSI_ZNS) + show_zns_properties(n); + } + } + nvme_subsystem_for_each_ns(s, n) { if (nvme_ns_get_csi(n) == NVME_CSI_ZNS) show_zns_properties(n); } } - nvme_subsystem_for_each_ns(s, n) { - if (nvme_ns_get_csi(n) == NVME_CSI_ZNS) - show_zns_properties(n); - } } nvme_free_tree(r); } From 1c057aba7539c706bc55f049ef3435cd6c4517b4 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 9 Apr 2021 09:26:54 +0200 Subject: [PATCH 0079/1564] util: export nvme_get_attr() Add raw nvme_get_attr() function for use within the library. Signed-off-by: Hannes Reinecke --- src/nvme/tree.h | 9 +++++++++ src/nvme/util.c | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/nvme/tree.h b/src/nvme/tree.h index b3c96ed8cc..adb5bd063c 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -786,6 +786,15 @@ void nvme_reset_topology(nvme_root_t r); */ void nvme_free_tree(nvme_root_t r); +/** + * nvme_get_attr() - + * @dir: + * @attr: + * + * Return: + */ +char *nvme_get_attr(const char *dir, const char *attr); + /** * nvme_get_subsys_attr() - * @s: diff --git a/src/nvme/util.c b/src/nvme/util.c index 46c423e8a8..8dbef2033b 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -608,7 +608,7 @@ static char *__nvme_get_attr(const char *path) return strdup(value); } -static char *nvme_get_attr(const char *dir, const char *attr) +char *nvme_get_attr(const char *dir, const char *attr) { char *path, *value; int ret; From f62aa1f16526cdc0e9d824c6a5732bef46e4dead Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 12 Apr 2021 07:46:37 +0200 Subject: [PATCH 0080/1564] test: allow passing in controller name Allow to specify the controller name as first command argument. Signed-off-by: Hannes Reinecke --- test/test.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/test.c b/test/test.c index e8ee0403a6..db5c019d0b 100644 --- a/test/test.c +++ b/test/test.c @@ -300,7 +300,7 @@ static void print_hex(const uint8_t *x, int len) printf("%02x", x[i]); } -int main() +int main(int argc, char **argv) { nvme_root_t r; nvme_host_t h; @@ -308,6 +308,7 @@ int main() nvme_ctrl_t c; nvme_path_t p; nvme_ns_t n; + const char *ctrl = "nvme4"; printf("Test filter for common loop back target\n"); nqn_match = "testnqn"; @@ -327,8 +328,11 @@ int main() printf("\n"); nvme_free_tree(r); + if (argc > 1) + ctrl = argv[1]; + printf("Test scan specific controller\n"); - c = nvme_scan_ctrl("nvme4"); + c = nvme_scan_ctrl(ctrl); if (c) { printf("%s %s %s %s\n", nvme_ctrl_get_name(c), nvme_ctrl_get_transport(c), From 1637f8ccc525ddf94add8886fb47dd6119aa0beb Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 30 Apr 2021 10:23:54 +0200 Subject: [PATCH 0081/1564] tree,fabrics: use topology information for discovery Implement a topology tree containing all hosts, subsystems, and controllers in the system, and use that information during discovery. Signed-off-by: Hannes Reinecke --- examples/discover-loop.c | 25 ++- src/nvme/fabrics.c | 121 ++++++---- src/nvme/fabrics.h | 30 +-- src/nvme/tree.c | 472 +++++++++++++++++++++++++++++++++------ src/nvme/tree.h | 123 +++++++++- test/test.c | 4 +- 6 files changed, 634 insertions(+), 141 deletions(-) diff --git a/examples/discover-loop.c b/examples/discover-loop.c index 2aaa9b6137..0281609122 100644 --- a/examples/discover-loop.c +++ b/examples/discover-loop.c @@ -47,21 +47,31 @@ static void print_discover_log(struct nvmf_discovery_log *log) int main() { struct nvmf_discovery_log *log = NULL; + nvme_root_t r; + nvme_host_t h; nvme_ctrl_t c; - char *hnqn; + char *hnqn, *hid; int ret; struct nvme_fabrics_config cfg = { - .nqn = NVME_DISC_SUBSYS_NAME, - .transport = "loop", .tos = -1, }; - hnqn = nvmf_hostnqn_from_file(), - cfg.hostnqn = hnqn; - - c = nvmf_add_ctrl(&cfg); + r = nvme_scan(); + hnqn = nvmf_hostnqn_from_file(); + hid = nvmf_hostid_from_file(); + h = nvme_lookup_host(r, hnqn, hid); + if (!h) { + fprintf(stderr, "Failed to allocated memory\n"); + return ENOMEM; + } + c = nvme_create_ctrl(NVME_DISC_SUBSYS_NAME, "loop", NULL, NULL, NULL); if (!c) { + fprintf(stderr, "Failed to allocate memory\n"); + return ENOMEM; + } + ret = nvmf_add_ctrl(h, c, &cfg); + if (ret < 0) { fprintf(stderr, "no controller found\n"); return errno; } @@ -75,6 +85,7 @@ int main() else print_discover_log(log); + nvme_free_tree(r); free(hnqn); return 0; } diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 870bbb1d3d..ac5daa1ba3 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -184,34 +184,55 @@ static int add_argument(char **argstr, const char *tok, const char *arg) return 0; } -static int build_options(char **argstr, struct nvme_fabrics_config *cfg) +static int build_options(nvme_ctrl_t c, char **argstr, + const struct nvme_fabrics_config *cfg) { + const char *transport = nvme_ctrl_get_transport(c); + /* always specify nqn as first arg - this will init the string */ - if (asprintf(argstr, "nqn=%s", cfg->nqn) < 0) { + if (asprintf(argstr, "nqn=%s", + nvme_ctrl_get_subsysnqn(c)) < 0) { errno = ENOMEM; return -1; } - if (add_argument(argstr, "transport", cfg->transport) || - add_argument(argstr, "traddr", cfg->traddr) || - add_argument(argstr, "host_traddr", cfg->host_traddr) || - add_argument(argstr, "trsvcid", cfg->trsvcid) || - add_argument(argstr, "hostnqn", cfg->hostnqn) || - add_argument(argstr, "hostid", cfg->hostid) || - add_int_argument(argstr, "nr_write_queues", cfg->nr_write_queues, false) || - add_int_argument(argstr, "nr_poll_queues", cfg->nr_poll_queues, false) || - add_int_argument(argstr, "reconnect_delay", cfg->reconnect_delay, false) || - add_int_argument(argstr, "ctrl_loss_tmo", cfg->ctrl_loss_tmo, false) || + if (add_argument(argstr, "transport", transport) || + add_argument(argstr, "traddr", + nvme_ctrl_get_traddr(c)) || + add_argument(argstr, "host_traddr", + nvme_ctrl_get_host_traddr(c)) || + add_argument(argstr, "trsvcid", + nvme_ctrl_get_trsvcid(c)) || + add_argument(argstr, "hostnqn", + nvme_ctrl_get_hostnqn(c)) || + add_argument(argstr, "hostid", + nvme_ctrl_get_hostid(c)) || + add_int_argument(argstr, "nr_write_queues", + cfg->nr_write_queues, false) || + add_int_argument(argstr, "nr_poll_queues", + cfg->nr_poll_queues, false) || + add_int_argument(argstr, "reconnect_delay", + cfg->reconnect_delay, false) || + (strcmp(transport, "loop") && + add_int_argument(argstr, "ctrl_loss_tmo", + cfg->ctrl_loss_tmo, false)) || add_int_argument(argstr, "tos", cfg->tos, true) || - add_bool_argument(argstr, "duplicate_connect", cfg->duplicate_connect) || - add_bool_argument(argstr, "disable_sqflow", cfg->disable_sqflow) || - add_bool_argument(argstr, "hdr_digest", cfg->hdr_digest) || - add_bool_argument(argstr, "data_digest", cfg->data_digest) || + add_bool_argument(argstr, "duplicate_connect", + cfg->duplicate_connect) || + add_bool_argument(argstr, "disable_sqflow", + cfg->disable_sqflow) || + (!strcmp(transport, "tcp") && + add_bool_argument(argstr, "hdr_digest", cfg->hdr_digest)) || + (!strcmp(transport, "tcp") && + add_bool_argument(argstr, "data_digest", cfg->data_digest)) || add_int_argument(argstr, "queue_size", cfg->queue_size, false) || - add_int_argument(argstr, "keep_alive_tmo", cfg->keep_alive_tmo, false) || - add_int_argument(argstr, "nr_io_queues", cfg->nr_io_queues, false)) { + add_int_argument(argstr, "keep_alive_tmo", + cfg->keep_alive_tmo, false) || + add_int_argument(argstr, "nr_io_queues", + cfg->nr_io_queues, false)) { free(*argstr); + errno = ENOMEM; return -1; } @@ -255,12 +276,12 @@ static int __nvmf_add_ctrl(const char *argstr) return ret; } -int nvmf_add_ctrl_opts(struct nvme_fabrics_config *cfg) +int nvmf_add_ctrl_opts(nvme_ctrl_t c, const struct nvme_fabrics_config *cfg) { char *argstr; int ret; - ret = build_options(&argstr, cfg); + ret = build_options(c, &argstr, cfg); if (ret) return ret; @@ -269,27 +290,34 @@ int nvmf_add_ctrl_opts(struct nvme_fabrics_config *cfg) return ret; } -nvme_ctrl_t nvmf_add_ctrl(struct nvme_fabrics_config *cfg) +int nvmf_add_ctrl(nvme_host_t h, nvme_ctrl_t c, + const struct nvme_fabrics_config *cfg) { - char d[32] = { 0 }; + char *argstr; int ret; - ret = nvmf_add_ctrl_opts(cfg); - if (ret < 0) - return NULL; + ret = build_options(c, &argstr, cfg); + if (ret) + return ret; - if (snprintf(d, sizeof(d), "nvme%d", ret) < 0) - return NULL; + ret = __nvmf_add_ctrl(argstr); + free(argstr); + if (ret < 0) + return ret; - return nvme_scan_ctrl(d); + return nvme_init_ctrl(h, c, ret); } -nvme_ctrl_t nvmf_connect_disc_entry(struct nvmf_disc_log_entry *e, +nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, + struct nvmf_disc_log_entry *e, const struct nvme_fabrics_config *defcfg, bool *discover) { struct nvme_fabrics_config cfg = { 0 }; + const char *transport; + char *traddr = NULL, *trsvcid = NULL; nvme_ctrl_t c; + int ret; memcpy(&cfg, defcfg, sizeof(cfg)); switch (e->subtype) { @@ -312,8 +340,8 @@ nvme_ctrl_t nvmf_connect_disc_entry(struct nvmf_disc_log_entry *e, case NVMF_ADDR_FAMILY_IP6: nvme_chomp(e->traddr, NVMF_TRADDR_SIZE); nvme_chomp(e->trsvcid, NVMF_TRSVCID_SIZE); - cfg.traddr = e->traddr; - cfg.trsvcid = e->trsvcid; + traddr = e->traddr; + trsvcid = e->trsvcid; break; default: errno = EINVAL; @@ -324,29 +352,42 @@ nvme_ctrl_t nvmf_connect_disc_entry(struct nvmf_disc_log_entry *e, switch (e->adrfam) { case NVMF_ADDR_FAMILY_FC: nvme_chomp(e->traddr, NVMF_TRADDR_SIZE), - cfg.traddr = e->traddr; - cfg.trsvcid = NULL; + traddr = e->traddr; + trsvcid = NULL; break; } + case NVMF_TRTYPE_LOOP: + break; default: errno = EINVAL; return NULL; } - cfg.transport = nvmf_trtype_str(e->trtype); - cfg.nqn = e->subnqn; + transport = nvmf_trtype_str(e->trtype); + c = nvme_create_ctrl(e->subnqn, transport, traddr, + NULL, trsvcid); + if (!c) { + errno = ENOMEM; + return NULL; + } + if (e->treq & NVMF_TREQ_DISABLE_SQFLOW) cfg.disable_sqflow = true; - c = nvmf_add_ctrl(&cfg); - if (!c && errno == EINVAL && cfg.disable_sqflow) { + ret = nvmf_add_ctrl(h, c, &cfg); + if (!ret) + return c; + + if (errno == EINVAL && cfg.disable_sqflow) { errno = 0; /* disable_sqflow is unrecognized option on older kernels */ cfg.disable_sqflow = false; - c = nvmf_add_ctrl(&cfg); + ret = nvmf_add_ctrl(h, c, &cfg); + if (!ret) + return c; } - - return c; + nvme_free_ctrl(c); + return NULL; } static int nvme_discovery_log(int fd, __u32 len, struct nvmf_discovery_log *log) diff --git a/src/nvme/fabrics.h b/src/nvme/fabrics.h index cbf4e4872a..cfab4b515f 100644 --- a/src/nvme/fabrics.h +++ b/src/nvme/fabrics.h @@ -13,15 +13,11 @@ #include #include "tree.h" +/* default to 600 seconds of reconnect attempts before giving up */ +#define NVMF_DEF_CTRL_LOSS_TMO 600 + /** * struct nvme_fabrics_config - Defines all linux nvme fabrics initiator options - * @transport: The fabric transport to use, either loop, fc, tcp, or rdma - * @traddr: Transport Address for the target, format specific to transport type - * @trsvcid: Transport Service Identifier, specific to the transport type - * @nqn: Target NVMe Qualified Name - * @hostnqn: Host NVMe Qualified Name - * @host_traddr: Host Transport Address - * @hostid: Host Identifier * @queue_size: Number of IO queue entries * @nr_io_queues: Number of controller IO queues to establish * @reconnect_delay: Time between two consecutive reconnect attempts. @@ -36,14 +32,6 @@ * @data_digest: Generate/verify data digest (TCP) */ struct nvme_fabrics_config { - const char *transport; - const char *traddr; - const char *trsvcid; - const char *nqn; - const char *hostnqn; - const char *host_traddr; - const char *hostid; - int queue_size; int nr_io_queues; int reconnect_delay; @@ -125,19 +113,23 @@ const char *nvmf_cms_str(__u8 cms); /** * nvmf_add_ctrl_opts() - + * @c: * @cfg: * * Return: */ -int nvmf_add_ctrl_opts(struct nvme_fabrics_config *cfg); +int nvmf_add_ctrl_opts(nvme_ctrl_t c, const struct nvme_fabrics_config *cfg); /** * nvmf_add_ctrl() - + * @h: + * @c: * @cfg: * * Return: */ -nvme_ctrl_t nvmf_add_ctrl(struct nvme_fabrics_config *cfg); +int nvmf_add_ctrl(nvme_host_t h, nvme_ctrl_t c, + const struct nvme_fabrics_config *cfg); /** * nvmf_get_discovery_log() - @@ -175,13 +167,15 @@ char *nvmf_hostid_from_file(); /** * nvmf_connect_disc_entry() - + * @h: * @e: * @defcfg: * @discover: * * Return: An */ -nvme_ctrl_t nvmf_connect_disc_entry(struct nvmf_disc_log_entry *e, +nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, + struct nvmf_disc_log_entry *e, const struct nvme_fabrics_config *defcfg, bool *discover); #endif /* _LIBNVME_FABRICS_H */ diff --git a/src/nvme/tree.c b/src/nvme/tree.c index eb554a3523..5643075fa0 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -27,6 +27,9 @@ /* XXX: Make a place for private declarations */ extern int nvme_set_attr(const char *dir, const char *attr, const char *value); +static struct nvme_host *default_host; + +nvme_host_t nvme_default_host(nvme_root_t r); static void nvme_free_host(struct nvme_host *h); static void nvme_free_subsystem(struct nvme_subsystem *s); static int nvme_subsystem_scan_namespace(struct nvme_subsystem *s, char *name); @@ -95,6 +98,8 @@ struct nvme_ctrl { char *queue_count; char *serial; char *sqsize; + char *hostnqn; + char *hostid; char *transport; char *subsysnqn; char *traddr; @@ -111,6 +116,9 @@ struct nvme_subsystem { char *name; char *sysfs_dir; char *subsysnqn; + char *model; + char *serial; + char *firmware; }; struct nvme_host { @@ -135,18 +143,16 @@ static inline void nvme_free_dirents(struct dirent **d, int i) nvme_host_t nvme_default_host(nvme_root_t r) { - struct nvme_host *h = calloc(1, sizeof(*h)); + struct nvme_host *h; + char *hostnqn, *hostid; - if (!h) { - errno = ENOMEM; - return NULL; - } + hostnqn = nvmf_hostnqn_from_file(); + hostid = nvmf_hostid_from_file(); - h->hostnqn = nvmf_hostnqn_from_file(); - h->hostid = nvmf_hostid_from_file(); - list_head_init(&h->subsystems); - list_add(&r->hosts, &h->entry); - h->r = r; + h = nvme_lookup_host(r, hostnqn, hostid); + default_host = h; + free(hostnqn); + free(hostid); return h; } @@ -318,10 +324,42 @@ static void nvme_free_subsystem(struct nvme_subsystem *s) free(s->name); free(s->sysfs_dir); free(s->subsysnqn); + if (s->model) + free(s->model); + if (s->serial) + free(s->serial); + if (s->firmware) + free(s->firmware); free(s); } -void nvme_free_host(struct nvme_host *h) +struct nvme_subsystem *nvme_lookup_subsystem(struct nvme_host *h, + const char *name, + const char *subsysnqn) +{ + struct nvme_subsystem *s; + + nvme_for_each_subsystem(h, s) { + if (strcmp(s->subsysnqn, subsysnqn)) + continue; + if (name && s->name && + strcmp(s->name, name)) + continue; + return s; + } + s = calloc(1, sizeof(*s)); + if (!s) + return NULL; + + s->h = h; + s->subsysnqn = strdup(subsysnqn); + list_head_init(&s->ctrls); + list_head_init(&s->namespaces); + list_add(&h->subsystems, &s->entry); + return s; +} + +static void nvme_free_host(struct nvme_host *h) { struct nvme_subsystem *s, *_s; @@ -334,6 +372,33 @@ void nvme_free_host(struct nvme_host *h) free(h); } +struct nvme_host *nvme_lookup_host(nvme_root_t r, const char *hostnqn, + const char *hostid) +{ + struct nvme_host *h; + + nvme_for_each_host(r, h) { + if (strcmp(h->hostnqn, hostnqn)) + continue; + if (hostid && + strcmp(h->hostid, hostid)) + continue; + return h; + } + h = calloc(1,sizeof(*h)); + if (!h) + return NULL; + h->hostnqn = strdup(hostnqn); + if (hostid) + h->hostid = strdup(hostid); + list_head_init(&h->subsystems); + list_node_init(&h->entry); + h->r = r; + list_add(&r->hosts, &h->entry); + + return h; +} + static int nvme_subsystem_scan_namespaces(struct nvme_subsystem *s) { struct dirent **namespaces; @@ -366,30 +431,49 @@ static int nvme_subsystem_scan_ctrls(struct nvme_subsystem *s) return 0; } +int nvme_init_subsystem(nvme_subsystem_t s, const char *name, const char *path) +{ + s->model = nvme_get_attr(path, "model"); + if (!s->model) { + errno = ENODEV; + return -1; + } + s->serial = nvme_get_attr(path, "serial"); + s->firmware = nvme_get_attr(path, "firmware_rev"); + s->name = strdup(name); + s->sysfs_dir = (char *)path; + + return 0; +} + static int nvme_scan_subsystem(struct nvme_host *h, char *name, nvme_scan_filter_t f) { struct nvme_subsystem *s; - char *path; + char *path, *subsysnqn; int ret; ret = asprintf(&path, "%s/%s", nvme_subsys_sysfs_dir, name); if (ret < 0) return ret; - s = calloc(1, sizeof(*s)); + subsysnqn = nvme_get_attr(path, "subsysnqn"); + if (!subsysnqn) { + errno = ENODEV; + goto free_path; + } + s = nvme_lookup_subsystem(h, name, subsysnqn); if (!s) { + free(subsysnqn); errno = ENOMEM; goto free_path; } - - s->h = h; - s->name = strdup(name); - s->sysfs_dir = path; - s->subsysnqn = nvme_get_subsys_attr(s, "subsysnqn"); - list_head_init(&s->ctrls); - list_head_init(&s->namespaces); - list_add(&h->subsystems, &s->entry); + free(subsysnqn); + if (!s->name) { + ret = nvme_init_subsystem(s, name, path); + if (ret < 0) + return ret; + } nvme_subsystem_scan_namespaces(s); nvme_subsystem_scan_ctrls(s); @@ -520,7 +604,7 @@ const char *nvme_ctrl_get_sysfs_dir(nvme_ctrl_t c) const char *nvme_ctrl_get_subsysnqn(nvme_ctrl_t c) { - return c->subsysnqn; + return c->s ? c->s->subsysnqn : c->subsysnqn; } const char *nvme_ctrl_get_address(nvme_ctrl_t c) @@ -583,6 +667,20 @@ const char *nvme_ctrl_get_host_traddr(nvme_ctrl_t c) return c->host_traddr; } +const char *nvme_ctrl_get_hostnqn(nvme_ctrl_t c) +{ + if (!c->s) + return default_host->hostnqn; + return c->s->h->hostnqn; +} + +const char *nvme_ctrl_get_hostid(nvme_ctrl_t c) +{ + if (!c->s) + return default_host->hostid; + return c->s->h->hostid; +} + int nvme_ctrl_identify(nvme_ctrl_t c, struct nvme_id_ctrl *id) { return nvme_identify_ctrl(nvme_ctrl_get_fd(c), id); @@ -608,10 +706,33 @@ nvme_path_t nvme_ctrl_next_path(nvme_ctrl_t c, nvme_path_t p) return p ? list_next(&c->paths, p, entry) : NULL; } +#define FREE_CTRL_ATTR(a) \ + do { if (a) { free(a); (a) = NULL; } } while (0) int nvme_ctrl_disconnect(nvme_ctrl_t c) { - return nvme_set_attr(nvme_ctrl_get_sysfs_dir(c), - "delete_controller", "1"); + int ret; + + ret = nvme_set_attr(nvme_ctrl_get_sysfs_dir(c), + "delete_controller", "1"); + if (ret < 0) + return ret; + + if (c->fd >= 0) { + close(c->fd); + c->fd = -1; + } + FREE_CTRL_ATTR(c->name); + FREE_CTRL_ATTR(c->sysfs_dir); + FREE_CTRL_ATTR(c->firmware); + FREE_CTRL_ATTR(c->model); + FREE_CTRL_ATTR(c->state); + FREE_CTRL_ATTR(c->numa_node); + FREE_CTRL_ATTR(c->queue_count); + FREE_CTRL_ATTR(c->serial); + FREE_CTRL_ATTR(c->sqsize); + FREE_CTRL_ATTR(c->address); + + return 0; } void nvme_unlink_ctrl(nvme_ctrl_t c) @@ -633,12 +754,16 @@ void nvme_free_ctrl(nvme_ctrl_t c) nvme_ctrl_for_each_ns_safe(c, n, _n) nvme_free_ns(n); - close(c->fd); - free(c->name); - free(c->sysfs_dir); - free(c->subsysnqn); - free(c->address); - free(c->traddr); + if (c->fd >= 0) + close(c->fd); + if (c->name) + free(c->name); + if (c->sysfs_dir) + free(c->sysfs_dir); + if (c->address) + free(c->address); + if (c->traddr) + free(c->traddr); if (c->trsvcid) free(c->trsvcid); if (c->host_traddr) @@ -654,6 +779,69 @@ void nvme_free_ctrl(nvme_ctrl_t c) free(c); } +struct nvme_ctrl *nvme_create_ctrl(const char *subsysnqn, + const char *transport, const char *traddr, + const char *host_traddr, const char *trsvcid) +{ + struct nvme_ctrl *c; + + if (!transport) + return NULL; + c = calloc(1, sizeof(*c)); + c->fd = -1; + list_head_init(&c->namespaces); + list_head_init(&c->paths); + list_node_init(&c->entry); + c->transport = strdup(transport); + if (subsysnqn) + c->subsysnqn = strdup(subsysnqn); + if (traddr) + c->traddr = strdup(traddr); + else + c->traddr = strdup("none"); + if (host_traddr) + c->host_traddr = strdup(host_traddr); + else + c->host_traddr = strdup("none"); + if (trsvcid) + c->trsvcid = strdup(trsvcid); + else + c->trsvcid = strdup("none"); + + return c; +} + +struct nvme_ctrl *nvme_lookup_ctrl(struct nvme_subsystem *s, + const char *transport, const char *traddr, + const char *host_traddr, const char *trsvcid) +{ + struct nvme_ctrl *c; + + if (!transport) + return NULL; + nvme_subsystem_for_each_ctrl(s, c) { + if (strcmp(c->transport, transport)) + continue; + if (traddr && + strcmp(c->traddr, traddr)) + continue; + if (host_traddr && + strcmp(c->host_traddr, host_traddr)) + continue; + if (trsvcid && + strcmp(c->trsvcid, trsvcid)) + continue; + return c; + } + c = nvme_create_ctrl(s->subsysnqn, transport, + traddr, host_traddr, trsvcid); + if (c) { + c->s = s; + list_add(&s->ctrls, &c->entry); + } + return c; +} + static int nvme_ctrl_scan_paths(struct nvme_ctrl *c) { struct dirent **paths; @@ -683,35 +871,48 @@ static int nvme_ctrl_scan_namespaces(struct nvme_ctrl *c) return 0; } -static nvme_ctrl_t __nvme_ctrl_alloc(const char *path, const char *name) +static char *nvme_ctrl_lookup_subsystem_name(nvme_ctrl_t c) { + struct dirent **subsys; + char *subsys_name = NULL; DIR *d; - nvme_ctrl_t c; - char *addr, *a, *e; - char *traddr = NULL, *trsvcid = NULL, *host_traddr = NULL; + int ret, i; + char path[PATH_MAX]; - d = opendir(path); - if (!d) + ret = nvme_scan_subsystems(&subsys); + if (ret < 0) return NULL; - closedir(d); + for (i = 0; i < ret; i++) { + sprintf(path, "%s/%s/%s", nvme_subsys_sysfs_dir, + subsys[i]->d_name, c->name); + d = opendir(path); + if (!d) + continue; + subsys_name = strdup(subsys[i]->d_name); + closedir(d); + break; + } + nvme_free_dirents(subsys, i); + return subsys_name; +} - c = calloc(1, sizeof(*c)); - if (!c) { - errno = ENOMEM; - return NULL; +static int __nvme_ctrl_init(nvme_ctrl_t c, const char *path, const char *name) +{ + DIR *d; + + d = opendir(path); + if (!d) { + errno = ENODEV; + return -1; } + closedir(d); c->fd = nvme_open(name); if (c->fd < 0) - goto free_ctrl; + return c->fd; - list_head_init(&c->namespaces); - list_head_init(&c->paths); - list_node_init(&c->entry); c->name = strdup(name); c->sysfs_dir = (char *)path; - c->subsysnqn = nvme_get_ctrl_attr(c, "subsysnqn"); - c->address = nvme_get_ctrl_attr(c, "address"); c->firmware = nvme_get_ctrl_attr(c, "firmware_rev"); c->model = nvme_get_ctrl_attr(c, "model"); c->state = nvme_get_ctrl_attr(c, "state"); @@ -719,9 +920,67 @@ static nvme_ctrl_t __nvme_ctrl_alloc(const char *path, const char *name) c->queue_count = nvme_get_ctrl_attr(c, "queue_count"); c->serial = nvme_get_ctrl_attr(c, "serial"); c->sqsize = nvme_get_ctrl_attr(c, "sqsize"); - c->transport = nvme_get_ctrl_attr(c, "transport"); + return 0; +} + +int nvme_init_ctrl(nvme_host_t h, nvme_ctrl_t c, int instance) +{ + nvme_subsystem_t s; + const char *subsys_name; + char *path, *name; + int ret; + + ret = asprintf(&name, "nvme%d", instance); + if (ret < 0) { + errno = ENOMEM; + return -1; + } + ret = asprintf(&path, "%s/nvme%d", nvme_ctrl_sysfs_dir, instance); + if (ret < 0) { + free(name); + errno = ENOMEM; + return -1; + } + + ret = __nvme_ctrl_init(c, path, name); + if (ret < 0) + free(path); + + c->address = nvme_get_attr(path, "address"); + if (!c->address) { + free(path); + free(name); + errno = -ENXIO; + return -1; + } + subsys_name = nvme_ctrl_lookup_subsystem_name(c); + s = nvme_lookup_subsystem(h, subsys_name, c->subsysnqn); + if (!s) { + errno = ENXIO; + ret = -1; + } + c->s = s; + list_add(&s->ctrls, &c->entry); + free(name); + return ret; +} + +static nvme_ctrl_t nvme_ctrl_alloc(nvme_subsystem_t s, const char *path, + const char *name) +{ + nvme_ctrl_t c; + char *addr, *address, *a, *e; + char *transport, *traddr = NULL, *trsvcid = NULL, *host_traddr = NULL; + int ret; + + transport = nvme_get_attr(path, "transport"); + if (!transport) { + errno = ENXIO; + return NULL; + } /* Parse 'address' string into components */ - addr = strdup(c->address); + addr = nvme_get_attr(path, "address"); + address = strdup(addr); a = strtok_r(addr, ",", &e); while (a && strlen(a)) { if (!strncmp(a, "traddr=", 7)) @@ -733,55 +992,88 @@ static nvme_ctrl_t __nvme_ctrl_alloc(const char *path, const char *name) a = strtok_r(NULL, ",", &e); } - if (traddr) - c->traddr = strdup(traddr); - if (trsvcid) - c->trsvcid = strdup(trsvcid); - if (host_traddr) - c->host_traddr = strdup(host_traddr); + c = nvme_lookup_ctrl(s, transport, traddr, host_traddr, trsvcid); free(addr); - return c; - -free_ctrl: - free(c); - return NULL; + if (!c) { + errno = ENOMEM; + return NULL; + } + c->address = address; + ret = __nvme_ctrl_init(c, path, name); + return (ret < 0) ? NULL : c; } -static nvme_ctrl_t nvme_ctrl_alloc(const char *sysfs, const char *name) +nvme_ctrl_t nvme_scan_ctrl(nvme_root_t r, const char *name) { + nvme_host_t h; + nvme_subsystem_t s; nvme_ctrl_t c; char *path; + char *hostnqn, *hostid, *subsysnqn; int ret; - ret = asprintf(&path, "%s/%s", sysfs, name); + ret = asprintf(&path, "%s/%s", nvme_ctrl_sysfs_dir, name); if (ret < 0) { errno = ENOMEM; return NULL; } - c = __nvme_ctrl_alloc(path, name); + hostnqn = nvme_get_attr(path, "hostnqn"); + if (!hostnqn) { + free(path); + errno = ENODEV; + return NULL; + } + hostid = nvme_get_attr(path, "hostid"); + h = nvme_lookup_host(r, hostnqn, hostid); + free(hostnqn); + if (hostid) + free(hostid); + if (!h) { + h = nvme_default_host(r); + if (!h) { + free(path); + errno = ENOMEM; + return NULL; + } + } + + subsysnqn = nvme_get_attr(path, "subsysnqn"); + if (!subsysnqn) { + free(path); + errno = ENXIO; + return NULL; + } + s = nvme_lookup_subsystem(h, NULL, subsysnqn); + if (!s) { + free(path); + errno = ENOMEM; + return NULL; + } + c = nvme_ctrl_alloc(s, path, name); if (!c) free(path); - return c; -} -nvme_ctrl_t nvme_scan_ctrl(const char *name) -{ - return nvme_ctrl_alloc(nvme_ctrl_sysfs_dir, name); + return c; } static int nvme_subsystem_scan_ctrl(struct nvme_subsystem *s, char *name) { nvme_ctrl_t c; + char *path; - c = nvme_ctrl_alloc(s->sysfs_dir, name); - if (!c) + if (asprintf(&path, "%s/%s", s->sysfs_dir, name) < 0) { + errno = ENOMEM; return -1; + } - c->s = s; + c = nvme_ctrl_alloc(s, path, name); + if (!c) { + free(path); + return -1; + } nvme_ctrl_scan_namespaces(c); nvme_ctrl_scan_paths(c); - list_add(&s->ctrls, &c->entry); return 0; } @@ -832,6 +1124,21 @@ const char *nvme_ns_get_name(nvme_ns_t n) return n->name; } +const char *nvme_ns_get_model(nvme_ns_t n) +{ + return n->c ? n->c->model : n->s->model; +} + +const char *nvme_ns_get_serial(nvme_ns_t n) +{ + return n->c ? n->c->serial : n->s->serial; +} + +const char *nvme_ns_get_firmware(nvme_ns_t n) +{ + return n->c ? n->c->firmware : n->s->firmware; +} + int nvme_ns_get_lba_size(nvme_ns_t n) { return n->lba_size; @@ -1104,3 +1411,24 @@ static int nvme_subsystem_scan_namespace(struct nvme_subsystem *s, char *name) list_add(&s->namespaces, &n->entry); return 0; } + +struct nvme_ns *nvme_subsystem_lookup_namespace(struct nvme_subsystem *s, + __u32 nsid) +{ + 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); + if (!n) { + free(name); + return NULL; + } + + n->s = s; + list_add(&s->namespaces, &n->entry); + return n; +} diff --git a/src/nvme/tree.h b/src/nvme/tree.h index adb5bd063c..f27daa43a7 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -84,6 +84,15 @@ nvme_host_t nvme_next_host(nvme_root_t r, nvme_host_t h); */ nvme_root_t nvme_host_get_root(nvme_host_t h); +/** + * nvme_lookup_host() - + * @r: + * + * Return: + */ +nvme_host_t nvme_lookup_host(nvme_root_t r, const char *hostnqn, + const char *hostid); + /** * nvme_host_get_hostnqn() - * @h: @@ -125,6 +134,18 @@ nvme_subsystem_t nvme_first_subsystem(nvme_host_t h); */ nvme_subsystem_t nvme_next_subsystem(nvme_host_t h, nvme_subsystem_t s); +/** + * nvme_lookup_subsystem() - + * @h: + * @name: + * @subsysnqn: + * + * Return: + */ +nvme_subsystem_t nvme_lookup_subsystem(struct nvme_host *h, + const char *name, + const char *subsysnqn); + /** * nvme_subsystem_get_host() - * @s: @@ -184,6 +205,36 @@ nvme_ctrl_t nvme_subsystem_first_ctrl(nvme_subsystem_t s); */ nvme_ctrl_t nvme_subsystem_next_ctrl(nvme_subsystem_t s, nvme_ctrl_t c); +/** + * nvme_lookup_ctrl() - + * @s: + * @transport: + * @traddr: + * @host_traddr: + * @trsvcid: + * + * Return: + */ +nvme_ctrl_t nvme_lookup_ctrl(nvme_subsystem_t s, const char *transport, + const char *traddr, const char *host_traddr, + const char *trsvcid); + + +/** + * nvme_create_ctrl() - + * @subsysnqn: + * @transport: + * @traddr: + * @host_traddr: + * @trsvcid: + * + * Return: + */ +nvme_ctrl_t nvme_create_ctrl(const char *subsysnqn, const char *transport, + const char *traddr, const char *host_traddr, + const char *trsvcid); + + /** * nvme_subsystem_first_ns() - * @s: @@ -397,6 +448,30 @@ const char *nvme_ns_get_sysfs_dir(nvme_ns_t n); */ const char *nvme_ns_get_name(nvme_ns_t n); +/** + * nvme_ns_get_firmware() - + * @n: + * + * Return: + */ +const char *nvme_ns_get_firmware(nvme_ns_t n); + +/** + * nvme_ns_get_serial() - + * @n: + * + * Return: + */ +const char *nvme_ns_get_serial(nvme_ns_t n); + +/** + * nvme_ns_get_model() - + * @n: + * + * Return: + */ +const char *nvme_ns_get_model(nvme_ns_t n); + /** * nvme_ns_get_subsystem() - * @n: @@ -660,6 +735,22 @@ const char *nvme_ctrl_get_nqn(nvme_ctrl_t c); */ const char *nvme_ctrl_get_subsysnqn(nvme_ctrl_t c); +/** + * nvme_ctrl_get_hostnqn() - + * @c: + * + * Return: + */ +const char *nvme_ctrl_get_hostnqn(nvme_ctrl_t c); + +/** + * nvme_ctrl_get_hostid() - + * @c: + * + * Return: + */ +const char *nvme_ctrl_get_hostid(nvme_ctrl_t c); + /** * nvme_ctrl_get_subsystem() - * @c: @@ -715,7 +806,17 @@ int nvme_ctrl_disconnect(nvme_ctrl_t c); * * Return: */ -nvme_ctrl_t nvme_scan_ctrl(const char *name); +nvme_ctrl_t nvme_scan_ctrl(nvme_root_t r, const char *name); + +/** + * nvme_init_ctrl() - + * @h: + * @c: + * @instance: + * + * Return: + */ +int nvme_init_ctrl(nvme_host_t h, nvme_ctrl_t c, int instance); /** * nvme_free_ctrl() - @@ -761,12 +862,28 @@ const char *nvme_subsystem_get_name(nvme_subsystem_t s); */ nvme_root_t nvme_scan_filter(nvme_scan_filter_t f); +/** + * nvme_host_get_hostnqn() - + * @h: + * + * Return: + */ +const char *nvme_host_get_hostnqn(nvme_host_t h); + +/** + * nvme_host_get_hostid() - + * @h: + * + * Return: + */ +const char *nvme_host_get_hostid(nvme_host_t h); + /** * nvme_scan() - * * Return: */ -nvme_root_t nvme_scan(); +nvme_root_t nvme_scan(void); /** * nvme_refresh_topology() - @@ -822,6 +939,8 @@ char *nvme_get_ctrl_attr(nvme_ctrl_t c, const char *attr); */ char *nvme_get_ns_attr(nvme_ns_t n, const char *attr); +nvme_ns_t nvme_subsystem_lookup_namespace(struct nvme_subsystem *s, + __u32 nsid); /** * nvme_get_path_attr() - * @p: diff --git a/test/test.c b/test/test.c index db5c019d0b..aa4e82e720 100644 --- a/test/test.c +++ b/test/test.c @@ -326,13 +326,12 @@ int main(int argc, char **argv) } } printf("\n"); - nvme_free_tree(r); if (argc > 1) ctrl = argv[1]; printf("Test scan specific controller\n"); - c = nvme_scan_ctrl(ctrl); + c = nvme_scan_ctrl(r, ctrl); if (c) { printf("%s %s %s %s\n", nvme_ctrl_get_name(c), nvme_ctrl_get_transport(c), @@ -341,6 +340,7 @@ int main(int argc, char **argv) nvme_free_ctrl(c); } printf("\n"); + nvme_free_tree(r); r = nvme_scan(); if (!r) From df97aa957b67425d46b3184bbb414c8480c9c65c Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 13 Apr 2021 09:28:30 +0200 Subject: [PATCH 0082/1564] tree,fabrics: per-controller configuration Make the fabrics configuration settings per-controller and implement nvme_ctrl_disable_sqflow(). Signed-off-by: Hannes Reinecke --- examples/discover-loop.c | 2 +- src/nvme/fabrics.c | 60 +++++++++++++++++++++++++++++----------- src/nvme/fabrics.h | 6 ++-- src/nvme/tree.c | 12 ++++++++ src/nvme/tree.h | 17 ++++++++++++ 5 files changed, 78 insertions(+), 19 deletions(-) diff --git a/examples/discover-loop.c b/examples/discover-loop.c index 0281609122..4a8d140c00 100644 --- a/examples/discover-loop.c +++ b/examples/discover-loop.c @@ -70,7 +70,7 @@ int main() fprintf(stderr, "Failed to allocate memory\n"); return ENOMEM; } - ret = nvmf_add_ctrl(h, c, &cfg); + ret = nvmf_add_ctrl(h, c, &cfg, false); if (ret < 0) { fprintf(stderr, "no controller found\n"); return errno; diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index ac5daa1ba3..c9016ed407 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -136,6 +136,30 @@ const char *nvmf_cms_str(__u8 cm) return arg_str(cms, ARRAY_SIZE(cms), cm); } +#define UPDATE_CFG_OPTION(c, n, o, d) \ + if ((c)->o == d) (c)->o = (n)->o +static struct nvme_fabrics_config *merge_config(nvme_ctrl_t c, + const struct nvme_fabrics_config *cfg) +{ + struct nvme_fabrics_config *ctrl_cfg = nvme_ctrl_get_config(c); + + UPDATE_CFG_OPTION(ctrl_cfg, cfg, nr_io_queues, 0); + UPDATE_CFG_OPTION(ctrl_cfg, cfg, nr_write_queues, 0); + UPDATE_CFG_OPTION(ctrl_cfg, cfg, nr_poll_queues, 0); + UPDATE_CFG_OPTION(ctrl_cfg, cfg, queue_size, 0); + UPDATE_CFG_OPTION(ctrl_cfg, cfg, keep_alive_tmo, 0); + UPDATE_CFG_OPTION(ctrl_cfg, cfg, reconnect_delay, 0); + UPDATE_CFG_OPTION(ctrl_cfg, cfg, ctrl_loss_tmo, + NVMF_DEF_CTRL_LOSS_TMO); + UPDATE_CFG_OPTION(ctrl_cfg, cfg, tos, -1); + UPDATE_CFG_OPTION(ctrl_cfg, cfg, duplicate_connect, false); + UPDATE_CFG_OPTION(ctrl_cfg, cfg, disable_sqflow, false); + UPDATE_CFG_OPTION(ctrl_cfg, cfg, hdr_digest, false); + UPDATE_CFG_OPTION(ctrl_cfg, cfg, data_digest, false); + + return ctrl_cfg; +} + static int add_bool_argument(char **argstr, char *tok, bool arg) { char *nstr; @@ -184,9 +208,9 @@ static int add_argument(char **argstr, const char *tok, const char *arg) return 0; } -static int build_options(nvme_ctrl_t c, char **argstr, - const struct nvme_fabrics_config *cfg) +static int build_options(nvme_ctrl_t c, char **argstr) { + struct nvme_fabrics_config *cfg = nvme_ctrl_get_config(c); const char *transport = nvme_ctrl_get_transport(c); /* always specify nqn as first arg - this will init the string */ @@ -276,12 +300,14 @@ static int __nvmf_add_ctrl(const char *argstr) return ret; } -int nvmf_add_ctrl_opts(nvme_ctrl_t c, const struct nvme_fabrics_config *cfg) +int nvmf_add_ctrl_opts(nvme_ctrl_t c, struct nvme_fabrics_config *cfg) { char *argstr; int ret; - ret = build_options(c, &argstr, cfg); + cfg = merge_config(c, cfg); + + ret = build_options(c, &argstr); if (ret) return ret; @@ -291,12 +317,16 @@ int nvmf_add_ctrl_opts(nvme_ctrl_t c, const struct nvme_fabrics_config *cfg) } int nvmf_add_ctrl(nvme_host_t h, nvme_ctrl_t c, - const struct nvme_fabrics_config *cfg) + const struct nvme_fabrics_config *cfg, + bool disable_sqflow) { char *argstr; int ret; - ret = build_options(c, &argstr, cfg); + cfg = merge_config(c, cfg); + nvme_ctrl_disable_sqflow(c, disable_sqflow); + + ret = build_options(c, &argstr); if (ret) return ret; @@ -310,16 +340,15 @@ int nvmf_add_ctrl(nvme_host_t h, nvme_ctrl_t c, nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, struct nvmf_disc_log_entry *e, - const struct nvme_fabrics_config *defcfg, + const struct nvme_fabrics_config *cfg, bool *discover) { - struct nvme_fabrics_config cfg = { 0 }; const char *transport; char *traddr = NULL, *trsvcid = NULL; nvme_ctrl_t c; + bool disable_sqflow = false; int ret; - memcpy(&cfg, defcfg, sizeof(cfg)); switch (e->subtype) { case NVME_NQN_DISC: if (discover) @@ -364,25 +393,24 @@ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, } transport = nvmf_trtype_str(e->trtype); - c = nvme_create_ctrl(e->subnqn, transport, traddr, - NULL, trsvcid); + c = nvme_create_ctrl(e->subnqn, transport, traddr, NULL, trsvcid); if (!c) { errno = ENOMEM; return NULL; } if (e->treq & NVMF_TREQ_DISABLE_SQFLOW) - cfg.disable_sqflow = true; + disable_sqflow = true; - ret = nvmf_add_ctrl(h, c, &cfg); + ret = nvmf_add_ctrl(h, c, cfg, disable_sqflow); if (!ret) return c; - if (errno == EINVAL && cfg.disable_sqflow) { + if (errno == EINVAL && disable_sqflow) { errno = 0; /* disable_sqflow is unrecognized option on older kernels */ - cfg.disable_sqflow = false; - ret = nvmf_add_ctrl(h, c, &cfg); + disable_sqflow = false; + ret = nvmf_add_ctrl(h, c, cfg, disable_sqflow); if (!ret) return c; } diff --git a/src/nvme/fabrics.h b/src/nvme/fabrics.h index cfab4b515f..c130339b15 100644 --- a/src/nvme/fabrics.h +++ b/src/nvme/fabrics.h @@ -118,18 +118,20 @@ const char *nvmf_cms_str(__u8 cms); * * Return: */ -int nvmf_add_ctrl_opts(nvme_ctrl_t c, const struct nvme_fabrics_config *cfg); +int nvmf_add_ctrl_opts(nvme_ctrl_t c, struct nvme_fabrics_config *cfg); /** * nvmf_add_ctrl() - * @h: * @c: * @cfg: + * @disable_sqflow: * * Return: */ int nvmf_add_ctrl(nvme_host_t h, nvme_ctrl_t c, - const struct nvme_fabrics_config *cfg); + const struct nvme_fabrics_config *cfg, + bool disable_sqflow); /** * nvmf_get_discovery_log() - diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 5643075fa0..5805b44723 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -105,6 +105,7 @@ struct nvme_ctrl { char *traddr; char *trsvcid; char *host_traddr; + struct nvme_fabrics_config cfg; }; struct nvme_subsystem { @@ -681,6 +682,16 @@ const char *nvme_ctrl_get_hostid(nvme_ctrl_t c) return c->s->h->hostid; } +struct nvme_fabrics_config *nvme_ctrl_get_config(nvme_ctrl_t c) +{ + return &c->cfg; +} + +void nvme_ctrl_disable_sqflow(nvme_ctrl_t c, bool disable_sqflow) +{ + c->cfg.disable_sqflow = disable_sqflow; +} + int nvme_ctrl_identify(nvme_ctrl_t c, struct nvme_id_ctrl *id) { return nvme_identify_ctrl(nvme_ctrl_get_fd(c), id); @@ -789,6 +800,7 @@ struct nvme_ctrl *nvme_create_ctrl(const char *subsysnqn, return NULL; c = calloc(1, sizeof(*c)); c->fd = -1; + c->cfg.tos = -1; list_head_init(&c->namespaces); list_head_init(&c->paths); list_node_init(&c->entry); diff --git a/src/nvme/tree.h b/src/nvme/tree.h index f27daa43a7..419bfeba76 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -783,6 +783,23 @@ const char *nvme_ctrl_get_trsvcid(nvme_ctrl_t c); */ const char *nvme_ctrl_get_host_traddr(nvme_ctrl_t c); +/** + * nvme_ctrl_get_config() - + * @c: + * + * Return: + */ +struct nvme_fabrics_config *nvme_ctrl_get_config(nvme_ctrl_t c); + +/** + * nvme_ctrl_disable_sqflow() - + * @c: + * @disable_sqflow: + * + * Return: + */ +void nvme_ctrl_disable_sqflow(nvme_ctrl_t c, bool disable_sqflow); + /** * nvme_ctrl_identify() - * @c: From 06a8f001d3142cf8b2e71466e588101af92ab144 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 14 Apr 2021 12:06:36 +0200 Subject: [PATCH 0083/1564] tree,fabrics: detect discovery loops Add an attribute 'discovered' to the controller configuration to identify discovery referral loops; if the controller is already discovered we'll skip it for subsequent discovery commands. Signed-off-by: Hannes Reinecke --- src/nvme/fabrics.c | 5 +++++ src/nvme/tree.c | 11 +++++++++++ src/nvme/tree.h | 17 +++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index c9016ed407..7adbc5f52e 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -325,6 +325,7 @@ int nvmf_add_ctrl(nvme_host_t h, nvme_ctrl_t c, cfg = merge_config(c, cfg); nvme_ctrl_disable_sqflow(c, disable_sqflow); + nvme_ctrl_set_discovered(c, true); ret = build_options(c, &argstr); if (ret) @@ -398,6 +399,10 @@ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, errno = ENOMEM; return NULL; } + if (nvme_ctrl_is_discovered(c)) { + errno = EAGAIN; + return NULL; + } if (e->treq & NVMF_TREQ_DISABLE_SQFLOW) disable_sqflow = true; diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 5805b44723..663d7af90f 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -105,6 +105,7 @@ struct nvme_ctrl { char *traddr; char *trsvcid; char *host_traddr; + bool discovered; struct nvme_fabrics_config cfg; }; @@ -692,6 +693,16 @@ void nvme_ctrl_disable_sqflow(nvme_ctrl_t c, bool disable_sqflow) c->cfg.disable_sqflow = disable_sqflow; } +void nvme_ctrl_set_discovered(nvme_ctrl_t c, bool discovered) +{ + c->discovered = discovered; +} + +bool nvme_ctrl_is_discovered(nvme_ctrl_t c) +{ + return c->discovered; +} + int nvme_ctrl_identify(nvme_ctrl_t c, struct nvme_id_ctrl *id) { return nvme_identify_ctrl(nvme_ctrl_get_fd(c), id); diff --git a/src/nvme/tree.h b/src/nvme/tree.h index 419bfeba76..3555c768c4 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -791,6 +791,23 @@ const char *nvme_ctrl_get_host_traddr(nvme_ctrl_t c); */ struct nvme_fabrics_config *nvme_ctrl_get_config(nvme_ctrl_t c); +/** + * nvme_ctrl_set_discovered() - + * @c: + * @discovered: + * + * Return: + */ +void nvme_ctrl_set_discovered(nvme_ctrl_t c, bool discovered); + +/** + * nvme_ctrl_is_discovered() - + * @c: + * + * Return: + */ +bool nvme_ctrl_is_discovered(nvme_ctrl_t c); + /** * nvme_ctrl_disable_sqflow() - * @c: From e03ca78c0688a1bafc04d266670a52db3a0c9f44 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 14 Apr 2021 08:10:26 +0200 Subject: [PATCH 0084/1564] fabrics: add 'verbose' option Add a 'verbose' option to print out logging messages during discovery. Signed-off-by: Hannes Reinecke --- src/nvme/fabrics.c | 80 +++++++++++++++++++++++++++++++++++++++++++--- src/nvme/fabrics.h | 2 ++ src/nvme/tree.c | 19 +++++++++-- src/nvme/tree.h | 17 ++++++++++ 4 files changed, 111 insertions(+), 7 deletions(-) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 7adbc5f52e..ead59d110d 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -156,6 +156,7 @@ static struct nvme_fabrics_config *merge_config(nvme_ctrl_t c, UPDATE_CFG_OPTION(ctrl_cfg, cfg, disable_sqflow, false); UPDATE_CFG_OPTION(ctrl_cfg, cfg, hdr_digest, false); UPDATE_CFG_OPTION(ctrl_cfg, cfg, data_digest, false); + UPDATE_CFG_OPTION(ctrl_cfg, cfg, verbose, false); return ctrl_cfg; } @@ -311,8 +312,16 @@ int nvmf_add_ctrl_opts(nvme_ctrl_t c, struct nvme_fabrics_config *cfg) if (ret) return ret; + if (cfg->verbose) + fprintf(stderr, "nvmf connect %s\n", argstr); ret = __nvmf_add_ctrl(argstr); free(argstr); + if (cfg->verbose) { + if (ret < 0) + fprintf(stderr, "failed to add ctrl, error %d\n", errno); + else + fprintf(stderr, "nvme%d: added ctrl\n", ret); + } return ret; } @@ -331,11 +340,17 @@ int nvmf_add_ctrl(nvme_host_t h, nvme_ctrl_t c, if (ret) return ret; + if (cfg->verbose) + fprintf(stderr, "nvmf connect %s\n", argstr); ret = __nvmf_add_ctrl(argstr); free(argstr); - if (ret < 0) + if (ret < 0) { + if (cfg->verbose) + fprintf(stderr, "failed to add ctrl, error %d\n", ret); return ret; - + } + if (cfg->verbose) + fprintf(stderr, "nvme%d: ctrl connected\n", ret); return nvme_init_ctrl(h, c, ret); } @@ -358,6 +373,10 @@ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, case NVME_NQN_NVME: break; default: + if (cfg->verbose) + fprintf(stderr, "skipping discovery entry, " + "invalid subsystem type %d\n", + e->subtype); errno = EINVAL; return NULL; } @@ -374,6 +393,10 @@ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, trsvcid = e->trsvcid; break; default: + if (cfg->verbose) + fprintf(stderr, "skipping discovery entry, " + "invalid address family %d\n", + e->trtype); errno = EINVAL; return NULL; } @@ -389,13 +412,25 @@ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, case NVMF_TRTYPE_LOOP: break; default: + if (cfg->verbose) + fprintf(stderr, "skipping discovery entry, " + "invalid transport type %d\n", + e->trtype); errno = EINVAL; return NULL; } transport = nvmf_trtype_str(e->trtype); + if (cfg->verbose) + fprintf(stderr, "lookup ctrl %s %s %s\n", + transport, traddr, trsvcid); + c = nvme_create_ctrl(e->subnqn, transport, traddr, NULL, trsvcid); if (!c) { + if (cfg->verbose) + fprintf(stderr, "skipping discovery entry, " + "failed to allocate controller on %s port %s\n", + transport, traddr); errno = ENOMEM; return NULL; } @@ -414,11 +449,17 @@ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, if (errno == EINVAL && disable_sqflow) { errno = 0; /* disable_sqflow is unrecognized option on older kernels */ + if (cfg->verbose) + fprintf(stderr, "failed to connect controller, " + "retry with disabling SQ flow control\n"); disable_sqflow = false; ret = nvmf_add_ctrl(h, c, cfg, disable_sqflow); if (!ret) return c; } + if (cfg->verbose) + fprintf(stderr, "failed to connect controller, " + "error %d\n", errno); nvme_free_ctrl(c); return NULL; } @@ -434,6 +475,7 @@ int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, { struct nvmf_discovery_log *log; int hdr, ret, retries = 0; + const char *name = nvme_ctrl_get_name(c); uint64_t genctr, numrec; unsigned int size; @@ -445,9 +487,15 @@ int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, } memset(log, 0, hdr); + if (nvme_ctrl_is_verbose(c)) + fprintf(stderr, "%s: discover length %d\n", name, 0x100); ret = nvme_discovery_log(nvme_ctrl_get_fd(c), 0x100, log); - if (ret) + if (ret) { + if (nvme_ctrl_is_verbose(c)) + fprintf(stderr, "%s: discover failed, error %d\n", + name, errno); goto out_free_log; + } do { numrec = le64_to_cpu(log->numrec); @@ -469,21 +517,43 @@ int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, } memset(log, 0, size); + if (nvme_ctrl_is_verbose(c)) + fprintf(stderr, "%s: discover length %d\n", name, size); + ret = nvme_discovery_log(nvme_ctrl_get_fd(c), size, log); - if (ret) + if (ret) { + if (nvme_ctrl_is_verbose(c)) + fprintf(stderr, "%s: discover " + "try %d/%d failed, error %d\n", + name, retries, max_retries, errno); goto out_free_log; + } genctr = le64_to_cpu(log->genctr); + if (nvme_ctrl_is_verbose(c)) + fprintf(stderr, "%s: discover genctr %lu, retry\n", + name, genctr); ret = nvme_discovery_log(nvme_ctrl_get_fd(c), hdr, log); - if (ret) + if (ret) { + if (nvme_ctrl_is_verbose(c)) + fprintf(stderr, "%s: discover " + "try %d/%d failed, error %d\n", + name, retries, max_retries, errno); goto out_free_log; + } } while (genctr != le64_to_cpu(log->genctr) && ++retries < max_retries); if (genctr != le64_to_cpu(log->genctr)) { + if (nvme_ctrl_is_verbose(c)) + fprintf(stderr, "%s: discover genctr mismatch\n", name); errno = EAGAIN; ret = -1; } else if (numrec != le64_to_cpu(log->numrec)) { + if (nvme_ctrl_is_verbose(c)) + fprintf(stderr, + "%s: could only fetch %lu of %lu records\n", + name, numrec, le64_to_cpu(log->numrec)); errno = EBADSLT; ret = -1; } else { diff --git a/src/nvme/fabrics.h b/src/nvme/fabrics.h index c130339b15..077e47311d 100644 --- a/src/nvme/fabrics.h +++ b/src/nvme/fabrics.h @@ -30,6 +30,7 @@ * @disable_sqflow: Disable controller sq flow control * @hdr_digest: Generate/verify header digest (TCP) * @data_digest: Generate/verify data digest (TCP) + * @verbose: Verbose output */ struct nvme_fabrics_config { int queue_size; @@ -45,6 +46,7 @@ struct nvme_fabrics_config { bool disable_sqflow; bool hdr_digest; bool data_digest; + bool verbose; }; /** diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 663d7af90f..ebb073a75f 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -703,6 +703,16 @@ bool nvme_ctrl_is_discovered(nvme_ctrl_t c) return c->discovered; } +void nvme_ctrl_set_verbosity(nvme_ctrl_t c, bool verbose) +{ + c->cfg.verbose = verbose; +} + +bool nvme_ctrl_is_verbose(nvme_ctrl_t c) +{ + return c->cfg.verbose; +} + int nvme_ctrl_identify(nvme_ctrl_t c, struct nvme_id_ctrl *id) { return nvme_identify_ctrl(nvme_ctrl_get_fd(c), id); @@ -734,11 +744,16 @@ int nvme_ctrl_disconnect(nvme_ctrl_t c) { int ret; + if (c->cfg.verbose) + fprintf(stderr, "%s: disconnect\n", c->name); ret = nvme_set_attr(nvme_ctrl_get_sysfs_dir(c), "delete_controller", "1"); - if (ret < 0) + if (ret < 0) { + if (c->cfg.verbose) + fprintf(stderr, "%s: failed to disconnect, error %d\n", + c->name, errno); return ret; - + } if (c->fd >= 0) { close(c->fd); c->fd = -1; diff --git a/src/nvme/tree.h b/src/nvme/tree.h index 3555c768c4..018838d9bb 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -817,6 +817,23 @@ bool nvme_ctrl_is_discovered(nvme_ctrl_t c); */ void nvme_ctrl_disable_sqflow(nvme_ctrl_t c, bool disable_sqflow); +/** + * nvme_ctrl_set_verbosity() - + * @c: + * @verbose: + * + * Return: + */ +void nvme_ctrl_set_verbosity(nvme_ctrl_t c, bool verbose); + +/** + * nvme_ctrl_is_verbose() - + * @c: + * + * Return: + */ +bool nvme_ctrl_is_verbose(nvme_ctrl_t c); + /** * nvme_ctrl_identify() - * @c: From a84e6e135dbbd2ea0d2962d6a8fd5111c8555fb3 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 13 Apr 2021 09:55:19 +0200 Subject: [PATCH 0085/1564] tree: implement nvme_ctrl_is_persistent() Move the 'persistent' argument into the controller configuration. Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 11 +++++++++++ src/nvme/tree.h | 17 +++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index ebb073a75f..5201b87a25 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -106,6 +106,7 @@ struct nvme_ctrl { char *trsvcid; char *host_traddr; bool discovered; + bool persistent; struct nvme_fabrics_config cfg; }; @@ -703,6 +704,16 @@ bool nvme_ctrl_is_discovered(nvme_ctrl_t c) return c->discovered; } +void nvme_ctrl_set_persistent(nvme_ctrl_t c, bool persistent) +{ + c->persistent = persistent; +} + +bool nvme_ctrl_is_persistent(nvme_ctrl_t c) +{ + return c->persistent; +} + void nvme_ctrl_set_verbosity(nvme_ctrl_t c, bool verbose) { c->cfg.verbose = verbose; diff --git a/src/nvme/tree.h b/src/nvme/tree.h index 018838d9bb..903680f000 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -808,6 +808,23 @@ void nvme_ctrl_set_discovered(nvme_ctrl_t c, bool discovered); */ bool nvme_ctrl_is_discovered(nvme_ctrl_t c); +/** + * nvme_ctrl_set_persistent() - + * @c: + * @persistent: + * + * Return: + */ +void nvme_ctrl_set_persistent(nvme_ctrl_t c, bool persistent); + +/** + * nvme_ctrl_is_persistent() - + * @c: + * + * Return: + */ +bool nvme_ctrl_is_persistent(nvme_ctrl_t c); + /** * nvme_ctrl_disable_sqflow() - * @c: From 13c32e09d93ae34951572255628099739e60e4c4 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 11 May 2021 13:26:36 +0200 Subject: [PATCH 0086/1564] fabrics: 'tos' is invalid for loop Signed-off-by: Hannes Reinecke --- src/nvme/fabrics.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index ead59d110d..e3497b3c1a 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -242,7 +242,8 @@ static int build_options(nvme_ctrl_t c, char **argstr) (strcmp(transport, "loop") && add_int_argument(argstr, "ctrl_loss_tmo", cfg->ctrl_loss_tmo, false)) || - add_int_argument(argstr, "tos", cfg->tos, true) || + (strcmp(transport, "loop") && + add_int_argument(argstr, "tos", cfg->tos, true)) || add_bool_argument(argstr, "duplicate_connect", cfg->duplicate_connect) || add_bool_argument(argstr, "disable_sqflow", From 31b4ee1f287e6bb112dadd28c65910a9e628c2e7 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 5 May 2021 13:55:39 +0200 Subject: [PATCH 0087/1564] JSON configuration file handling Add functions 'json_read_config()' and 'json_update_config()' to read and write configuration informations from or to a JSON file. Signed-off-by: Hannes Reinecke --- configure | 19 +++ examples/discover-loop.c | 8 +- examples/display-columnar.c | 2 +- examples/display-tree.c | 2 +- examples/telemetry-listen.c | 2 +- src/Makefile | 3 + src/nvme/fabrics.c | 1 + src/nvme/json.c | 265 ++++++++++++++++++++++++++++++++++++ src/nvme/private.h | 18 +++ src/nvme/tree.c | 13 +- src/nvme/tree.h | 11 +- test/cpp.cc | 2 +- test/test.c | 2 +- test/zns.c | 2 +- 14 files changed, 331 insertions(+), 19 deletions(-) create mode 100644 src/nvme/json.c create mode 100644 src/nvme/private.h diff --git a/configure b/configure index 2481163184..c81f48ea4d 100755 --- a/configure +++ b/configure @@ -31,6 +31,8 @@ for opt do ;; --disable-uuid) disable_uuid=1 ;; + --disable-json) disable_json=1 + ;; *) echo "ERROR: unkown option $opt" echo "Try '$0 --help' for more information" @@ -68,6 +70,7 @@ Options: [defaults in brackets after descriptions] --datadir=PATH install shared data in PATH [$datadir] --disable-systemd do not link against libsystemd --disable-uuid do not link against libuuid + --disable-json do not link against libjson-c EOF exit 0 fi @@ -202,6 +205,17 @@ if [ -z "$disable_systemd" ] ; then fi print_config "systemd" "${systemd}" +########################################## +# check for libjson-c +libjsonc="no" +if [ -z "$disable_json" ] ; then + ${ld} -o /dev/null -ljson-c >/dev/null 2>&1 + if [ $? -eq 0 ]; then + libjsonc="yes" + fi +fi +print_config "libjson-c" "${libjsonc}" + ########################################## # check for c++ cpp="no" @@ -221,6 +235,11 @@ if test "$systemd" = "yes"; then output_sym "CONFIG_SYSTEMD" echo "override LDFLAGS += -lsystemd" >> $config_host_mak fi +if test "$libjsonc" = "yes"; then + output_sym "CONFIG_JSONC" + echo "override LDFLAGS += -ljson-c" >> $config_host_mak + echo "override LIB_DEPENDS += json-c" >> $config_host_mak +fi if test "$cpp" = "yes"; then output_mak "CONFIG_CPLUSPLUS" "y" fi diff --git a/examples/discover-loop.c b/examples/discover-loop.c index 4a8d140c00..37637e24ce 100644 --- a/examples/discover-loop.c +++ b/examples/discover-loop.c @@ -50,17 +50,14 @@ int main() nvme_root_t r; nvme_host_t h; nvme_ctrl_t c; - char *hnqn, *hid; int ret; struct nvme_fabrics_config cfg = { .tos = -1, }; - r = nvme_scan(); - hnqn = nvmf_hostnqn_from_file(); - hid = nvmf_hostid_from_file(); - h = nvme_lookup_host(r, hnqn, hid); + r = nvme_scan(NULL); + h = nvme_default_host(r); if (!h) { fprintf(stderr, "Failed to allocated memory\n"); return ENOMEM; @@ -86,6 +83,5 @@ int main() print_discover_log(log); nvme_free_tree(r); - free(hnqn); return 0; } diff --git a/examples/display-columnar.c b/examples/display-columnar.c index cd3f007f16..a2a2938e11 100644 --- a/examples/display-columnar.c +++ b/examples/display-columnar.c @@ -23,7 +23,7 @@ int main() nvme_path_t p; nvme_ns_t n; - r = nvme_scan(); + r = nvme_scan(NULL); if (!r) return -1; diff --git a/examples/display-tree.c b/examples/display-tree.c index 66b16c276d..f5bddb2c1d 100644 --- a/examples/display-tree.c +++ b/examples/display-tree.c @@ -22,7 +22,7 @@ int main() nvme_path_t p, _p; nvme_ns_t n, _n; - r = nvme_scan(); + r = nvme_scan(NULL); if (!r) return -1; diff --git a/examples/telemetry-listen.c b/examples/telemetry-listen.c index c4cde957db..374ffa4dbb 100644 --- a/examples/telemetry-listen.c +++ b/examples/telemetry-listen.c @@ -129,7 +129,7 @@ int main() nvme_host_t h; nvme_root_t r; - r = nvme_scan(); + r = nvme_scan(NULL); if (!r) return EXIT_FAILURE; diff --git a/src/Makefile b/src/Makefile index 129e624d74..4beb13d8db 100644 --- a/src/Makefile +++ b/src/Makefile @@ -49,6 +49,9 @@ $(libccan_objs) $(libccan_sobjs): $(libccan_headers) $(CCANDIR)config.h libnvme_priv := nvme/private.h libnvme_api := libnvme.h nvme/types.h nvme/ioctl.h nvme/filters.h nvme/tree.h nvme/util.h nvme/fabrics.h libnvme_srcs := nvme/ioctl.c nvme/filters.c nvme/fabrics.c nvme/util.c nvme/tree.c +ifneq ($(CONFIG_JSONC),0) +override libnvme_srcs += nvme/json.c +endif libnvme_objs := $(patsubst %.c,%.ol,$(libnvme_srcs)) libnvme_sobjs := $(patsubst %.c,%.os,$(libnvme_srcs)) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index e3497b3c1a..4c59704497 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -31,6 +31,7 @@ #include "fabrics.h" #include "ioctl.h" #include "util.h" +#include "private.h" #define NVMF_HOSTID_SIZE 37 diff --git a/src/nvme/json.c b/src/nvme/json.c new file mode 100644 index 0000000000..98280822f2 --- /dev/null +++ b/src/nvme/json.c @@ -0,0 +1,265 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/* + * This file is part of libnvme. + * Copyright (c) 2021 SUSE Software Solutions + * + * Authors: Hannes Reinecke + */ + +#include +#include +#include + +#include + +#include "fabrics.h" +#include "private.h" + +#define json_object_add_value_string(o, k, v) \ + json_object_object_add(o, k, json_object_new_string(v)) +#define json_object_add_value_int(o, k, v) \ + json_object_object_add(o, k, json_object_new_int(v)) +#define json_object_add_value_bool(o, k, v) \ + json_object_object_add(o, k, json_object_new_boolean(v)) +#define json_object_add_value_string(o, k, v) \ + json_object_object_add(o, k, json_object_new_string(v)) + +#define JSON_UPDATE_INT_OPTION(c, k, a, o) \ + if (!strcmp(# a, k ) && !c->a) c->a = json_object_get_int(o); +#define JSON_UPDATE_BOOL_OPTION(c, k, a, o) \ + if (!strcmp(# a, k ) && !c->a) c->a = json_object_get_boolean(o); + +static void json_update_attributes(nvme_ctrl_t c, + struct json_object *ctrl_obj) +{ + struct nvme_fabrics_config *cfg = nvme_ctrl_get_config(c); + + json_object_object_foreach(ctrl_obj, key_str, val_obj) { + JSON_UPDATE_INT_OPTION(cfg, key_str, + nr_io_queues, val_obj); + JSON_UPDATE_INT_OPTION(cfg, key_str, + nr_write_queues, val_obj); + JSON_UPDATE_INT_OPTION(cfg, key_str, + nr_poll_queues, val_obj); + JSON_UPDATE_INT_OPTION(cfg, key_str, + queue_size, val_obj); + JSON_UPDATE_INT_OPTION(cfg, key_str, + keep_alive_tmo, val_obj); + JSON_UPDATE_INT_OPTION(cfg, key_str, + reconnect_delay, val_obj); + if (!strcmp("ctrl_loss_tmo", key_str) && + cfg->ctrl_loss_tmo != NVMF_DEF_CTRL_LOSS_TMO) + cfg->ctrl_loss_tmo = json_object_get_int(val_obj); + if (!strcmp("tos", key_str) && cfg->tos != -1) + cfg->tos = json_object_get_int(val_obj); + JSON_UPDATE_BOOL_OPTION(cfg, key_str, + duplicate_connect, val_obj); + JSON_UPDATE_BOOL_OPTION(cfg, key_str, + disable_sqflow, val_obj); + JSON_UPDATE_BOOL_OPTION(cfg, key_str, + hdr_digest, val_obj); + JSON_UPDATE_BOOL_OPTION(cfg, key_str, + data_digest, val_obj); + if (!strcmp("persistent", key_str) && + !nvme_ctrl_is_persistent(c)) + nvme_ctrl_set_persistent(c, true); + } +} + +static void json_parse_port(nvme_subsystem_t s, struct json_object *port_obj) +{ + nvme_ctrl_t c; + struct json_object *attr_obj; + const char *transport, *traddr = NULL; + const char *host_traddr = NULL, *trsvcid = NULL; + + attr_obj = json_object_object_get(port_obj, "transport"); + if (!attr_obj) + return; + transport = json_object_get_string(attr_obj); + attr_obj = json_object_object_get(port_obj, "traddr"); + if (attr_obj) + traddr = json_object_get_string(attr_obj); + attr_obj = json_object_object_get(port_obj, "host_traddr"); + if (attr_obj) + host_traddr = json_object_get_string(attr_obj); + attr_obj = json_object_object_get(port_obj, "trsvcid"); + if (attr_obj) + trsvcid = json_object_get_string(attr_obj); + c = nvme_lookup_ctrl(s, transport, traddr, + host_traddr, trsvcid); + if (c) { + json_update_attributes(c, port_obj); + } +} + +static void json_parse_subsys(nvme_host_t h, struct json_object *subsys_obj) +{ + struct json_object *nqn_obj, *port_array; + nvme_subsystem_t s; + const char *nqn; + int p; + + nqn_obj = json_object_object_get(subsys_obj, "nqn"); + if (!nqn_obj) + return; + nqn = json_object_get_string(nqn_obj); + s = nvme_lookup_subsystem(h, NULL, nqn); + port_array = json_object_object_get(subsys_obj, "ports"); + if (!port_array) + return; + for (p = 0; p < json_object_array_length(port_array); p++) { + struct json_object *port_obj; + + port_obj = json_object_array_get_idx(port_array, p); + json_parse_port(s, port_obj); + } +} + +static void json_parse_host(nvme_root_t r, struct json_object *host_obj) +{ + struct json_object *attr_obj, *subsys_array, *subsys_obj; + nvme_host_t h; + const char *hostnqn, *hostid = NULL; + int s; + + attr_obj = json_object_object_get(host_obj, "hostnqn"); + if (!attr_obj) + return; + hostnqn = json_object_get_string(attr_obj); + attr_obj = json_object_object_get(host_obj, "hostid"); + if (attr_obj) + hostid = json_object_get_string(attr_obj); + h = nvme_lookup_host(r, hostnqn, hostid); + subsys_array = json_object_object_get(host_obj, "subsystems"); + if (!subsys_array) + return; + for (s = 0; s < json_object_array_length(subsys_array); s++) { + subsys_obj = json_object_array_get_idx(subsys_array, s); + json_parse_subsys(h, subsys_obj); + } +} + +void json_read_config(nvme_root_t r, const char *config_file) +{ + struct json_object *json_root, *host_obj; + int h; + + json_root = json_object_from_file(config_file); + if (!json_root) { + fprintf(stderr, "Failed to read %s, %s\n", + config_file, json_util_get_last_err()); + return; + } + for (h = 0; h < json_object_array_length(json_root); h++) { + host_obj = json_object_array_get_idx(json_root, h); + json_parse_host(r, host_obj); + } + json_object_put(json_root); +} + +#define JSON_STRING_OPTION(c, p, o) \ + if ((c)->o && strcmp((c)->o, "none")) \ + json_object_add_value_string((p), # o , (c)->o) +#define JSON_INT_OPTION(c, p, o, d) \ + if ((c)->o != d) json_object_add_value_int((p), # o , (c)->o) +#define JSON_BOOL_OPTION(c, p, o) \ + if ((c)->o) json_object_add_value_bool((p), # o , (c)->o) + +static void json_update_port(struct json_object *ctrl_array, nvme_ctrl_t c) +{ + struct nvme_fabrics_config *cfg = nvme_ctrl_get_config(c); + struct json_object *port_obj = json_object_new_object(); + const char *transport, *value; + + transport = nvme_ctrl_get_transport(c); + json_object_add_value_string(port_obj, "transport", transport); + value = nvme_ctrl_get_traddr(c); + if (value) + json_object_add_value_string(port_obj, "traddr", value); + value = nvme_ctrl_get_host_traddr(c); + if (value) + json_object_add_value_string(port_obj, "host_traddr", value); + value = nvme_ctrl_get_trsvcid(c); + if (value) + json_object_add_value_string(port_obj, "trsvcid", value); + JSON_INT_OPTION(cfg, port_obj, nr_io_queues, 0); + JSON_INT_OPTION(cfg, port_obj, nr_write_queues, 0); + JSON_INT_OPTION(cfg, port_obj, nr_poll_queues, 0); + JSON_INT_OPTION(cfg, port_obj, queue_size, 0); + JSON_INT_OPTION(cfg, port_obj, keep_alive_tmo, 0); + JSON_INT_OPTION(cfg, port_obj, reconnect_delay, 0); + if (strcmp(transport, "loop")) + JSON_INT_OPTION(cfg, port_obj, ctrl_loss_tmo, + NVMF_DEF_CTRL_LOSS_TMO); + JSON_INT_OPTION(cfg, port_obj, tos, -1); + JSON_BOOL_OPTION(cfg, port_obj, duplicate_connect); + JSON_BOOL_OPTION(cfg, port_obj, disable_sqflow); + JSON_BOOL_OPTION(cfg, port_obj, hdr_digest); + JSON_BOOL_OPTION(cfg, port_obj, data_digest); + if (nvme_ctrl_is_persistent(c)) + json_object_add_value_bool(port_obj, "persistent", true); + json_object_array_add(ctrl_array, port_obj); +} + +static void json_update_subsys(struct json_object *subsys_array, + nvme_subsystem_t s) +{ + nvme_ctrl_t c; + const char *subsysnqn = nvme_subsystem_get_nqn(s); + struct json_object *subsys_obj = json_object_new_object(); + struct json_object *port_array; + + /* Skip discovery subsystems as the nqn is not unique */ + if (!strcmp(subsysnqn, NVME_DISC_SUBSYS_NAME)) + return; + + json_object_add_value_string(subsys_obj, "nqn", + nvme_subsystem_get_nqn(s)); + port_array = json_object_new_array(); + nvme_subsystem_for_each_ctrl(s, c) { + json_update_port(port_array, c); + } + if (json_object_array_length(port_array)) + json_object_object_add(subsys_obj, "ports", port_array); + else + json_object_put(port_array); + json_object_array_add(subsys_array, subsys_obj); +} + +void json_update_config(nvme_root_t r, const char *config_file) +{ + nvme_host_t h; + struct json_object *json_root, *host_obj; + struct json_object *subsys_array; + + json_root = json_object_new_array(); + nvme_for_each_host(r, h) { + nvme_subsystem_t s; + const char *hostid; + + host_obj = json_object_new_object(); + json_object_add_value_string(host_obj, "hostnqn", + nvme_host_get_hostnqn(h)); + hostid = nvme_host_get_hostid(h); + if (hostid) + json_object_add_value_string(host_obj, "hostid", + hostid); + subsys_array = json_object_new_array(); + nvme_for_each_subsystem(h, s) { + json_update_subsys(subsys_array, s); + } + if (json_object_array_length(subsys_array)) + json_object_object_add(host_obj, "subsystems", + subsys_array); + else + json_object_put(subsys_array); + json_object_array_add(json_root, host_obj); + } + if (json_object_to_file_ext(config_file, json_root, + JSON_C_TO_STRING_PRETTY) < 0) { + fprintf(stderr, "Failed to write %s, %s\n", + config_file, json_util_get_last_err()); + } + json_object_put(json_root); +} diff --git a/src/nvme/private.h b/src/nvme/private.h new file mode 100644 index 0000000000..bc823abb27 --- /dev/null +++ b/src/nvme/private.h @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/* + * This file is part of libnvme. + * Copyright (c) 2021 SUSE Software Solutions + * + * Authors: Hannes Reinecke + */ + +#ifndef _LIBNVME_PRIVATE_H +#define _LIBNVME_PRIVATE_H + +int nvme_set_attr(const char *dir, const char *attr, const char *value); + +void json_read_config(nvme_root_t r, const char *config_file); + +void json_update_config(nvme_root_t r, const char *config_file); + +#endif /* _LIBNVME_PRIVATE_H */ diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 5201b87a25..518e89edf2 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -23,13 +23,10 @@ #include "filters.h" #include "util.h" #include "fabrics.h" - -/* XXX: Make a place for private declarations */ -extern int nvme_set_attr(const char *dir, const char *attr, const char *value); +#include "private.h" static struct nvme_host *default_host; -nvme_host_t nvme_default_host(nvme_root_t r); static void nvme_free_host(struct nvme_host *h); static void nvme_free_subsystem(struct nvme_subsystem *s); static int nvme_subsystem_scan_namespace(struct nvme_subsystem *s, char *name); @@ -196,9 +193,13 @@ nvme_root_t nvme_scan_filter(nvme_scan_filter_t f) return r; } -nvme_root_t nvme_scan() +nvme_root_t nvme_scan(const char *config_file) { - return nvme_scan_filter(NULL); + nvme_root_t r = nvme_scan_filter(NULL); + + if (r && config_file) + json_read_config(r, config_file); + return r; } nvme_host_t nvme_first_host(nvme_root_t r) diff --git a/src/nvme/tree.h b/src/nvme/tree.h index 903680f000..68428e9fe3 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -946,12 +946,21 @@ const char *nvme_host_get_hostnqn(nvme_host_t h); */ const char *nvme_host_get_hostid(nvme_host_t h); +/** + * nvme_default_host() - + * @root: + * + * Return: + */ +nvme_host_t nvme_default_host(nvme_root_t r); + /** * nvme_scan() - + * @config_file: * * Return: */ -nvme_root_t nvme_scan(void); +nvme_root_t nvme_scan(const char *config_file); /** * nvme_refresh_topology() - diff --git a/test/cpp.cc b/test/cpp.cc index f1463b46f5..3d0a7d250d 100644 --- a/test/cpp.cc +++ b/test/cpp.cc @@ -18,7 +18,7 @@ int main() nvme_path_t p; nvme_ns_t n; - r = nvme_scan(); + r = nvme_scan(NULL); if (!r) return -1; diff --git a/test/test.c b/test/test.c index aa4e82e720..fc9c21ef08 100644 --- a/test/test.c +++ b/test/test.c @@ -342,7 +342,7 @@ int main(int argc, char **argv) printf("\n"); nvme_free_tree(r); - r = nvme_scan(); + r = nvme_scan(NULL); if (!r) return -1; diff --git a/test/zns.c b/test/zns.c index 7d854cd745..3ca55dfc75 100644 --- a/test/zns.c +++ b/test/zns.c @@ -61,7 +61,7 @@ int main() nvme_ctrl_t c; nvme_ns_t n; - r = nvme_scan(); + r = nvme_scan(NULL); if (!r) return -1; From ab242a6a4d9f6155eaf1685720f2fdc34b08be5e Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 5 May 2021 14:15:55 +0200 Subject: [PATCH 0088/1564] tree: add 'nvme_update_config()' as API function Add a function nvme_update_config() to write out the configuration as an JSON file. Signed-off-by: Hannes Reinecke --- src/nvme/json.c | 7 ++++++- src/nvme/private.h | 2 +- src/nvme/tree.c | 16 +++++++++++++++- src/nvme/tree.h | 9 +++++++++ 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/nvme/json.c b/src/nvme/json.c index 98280822f2..c902a3e92e 100644 --- a/src/nvme/json.c +++ b/src/nvme/json.c @@ -227,11 +227,12 @@ static void json_update_subsys(struct json_object *subsys_array, json_object_array_add(subsys_array, subsys_obj); } -void json_update_config(nvme_root_t r, const char *config_file) +int json_update_config(nvme_root_t r, const char *config_file) { nvme_host_t h; struct json_object *json_root, *host_obj; struct json_object *subsys_array; + int ret = 0; json_root = json_object_new_array(); nvme_for_each_host(r, h) { @@ -260,6 +261,10 @@ void json_update_config(nvme_root_t r, const char *config_file) JSON_C_TO_STRING_PRETTY) < 0) { fprintf(stderr, "Failed to write %s, %s\n", config_file, json_util_get_last_err()); + ret = -1; + errno = EIO; } json_object_put(json_root); + + return ret; } diff --git a/src/nvme/private.h b/src/nvme/private.h index bc823abb27..3d1a164f51 100644 --- a/src/nvme/private.h +++ b/src/nvme/private.h @@ -13,6 +13,6 @@ int nvme_set_attr(const char *dir, const char *attr, const char *value); void json_read_config(nvme_root_t r, const char *config_file); -void json_update_config(nvme_root_t r, const char *config_file); +int json_update_config(nvme_root_t r, const char *config_file); #endif /* _LIBNVME_PRIVATE_H */ diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 518e89edf2..38333e9712 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -132,6 +132,7 @@ struct nvme_host { struct nvme_root { struct list_head hosts; + bool modified; }; static inline void nvme_free_dirents(struct dirent **d, int i) @@ -202,6 +203,13 @@ nvme_root_t nvme_scan(const char *config_file) return r; } +int nvme_update_config(nvme_root_t r, const char *config_file) +{ + if (!r->modified) + return 0; + return json_update_config(r, config_file); +} + nvme_host_t nvme_first_host(nvme_root_t r) { return list_top(&r->hosts, struct nvme_host, entry); @@ -360,6 +368,7 @@ struct nvme_subsystem *nvme_lookup_subsystem(struct nvme_host *h, list_head_init(&s->ctrls); list_head_init(&s->namespaces); list_add(&h->subsystems, &s->entry); + h->r->modified = true; return s; } @@ -373,6 +382,7 @@ static void nvme_free_host(struct nvme_host *h) free(h->hostnqn); if (h->hostid) free(h->hostid); + h->r->modified = true; free(h); } @@ -399,6 +409,7 @@ struct nvme_host *nvme_lookup_host(nvme_root_t r, const char *hostnqn, list_node_init(&h->entry); h->r = r; list_add(&r->hosts, &h->entry); + r->modified = true; return h; } @@ -435,7 +446,8 @@ static int nvme_subsystem_scan_ctrls(struct nvme_subsystem *s) return 0; } -int nvme_init_subsystem(nvme_subsystem_t s, const char *name, const char *path) +static int nvme_init_subsystem(nvme_subsystem_t s, const char *name, + const char *path) { s->model = nvme_get_attr(path, "model"); if (!s->model) { @@ -693,6 +705,7 @@ struct nvme_fabrics_config *nvme_ctrl_get_config(nvme_ctrl_t c) void nvme_ctrl_disable_sqflow(nvme_ctrl_t c, bool disable_sqflow) { c->cfg.disable_sqflow = disable_sqflow; + c->s->h->r->modified = true; } void nvme_ctrl_set_discovered(nvme_ctrl_t c, bool discovered) @@ -888,6 +901,7 @@ struct nvme_ctrl *nvme_lookup_ctrl(struct nvme_subsystem *s, if (c) { c->s = s; list_add(&s->ctrls, &c->entry); + s->h->r->modified = true; } return c; } diff --git a/src/nvme/tree.h b/src/nvme/tree.h index 68428e9fe3..8823254a09 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -974,6 +974,15 @@ void nvme_refresh_topology(nvme_root_t r); */ void nvme_reset_topology(nvme_root_t r); +/** + * nvme_update_config() - + * @r: + * @config_file: + * + * Return: + */ +int nvme_update_config(nvme_root_t r, const char *config_file); + /** * nvme_free_tree() - * @r: From 809245170c65e3d39c03182b02806d5d0e30a100 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 7 May 2021 10:12:41 +0200 Subject: [PATCH 0089/1564] tree: move config_file argument into nvme_root Store the config file in the nvme_root structure; that allows us to call nvme_update_config() without having to specify the configuration file. Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 13 +++++++++---- src/nvme/tree.h | 3 +-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 38333e9712..04c7074271 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -131,6 +131,7 @@ struct nvme_host { }; struct nvme_root { + char *config_file; struct list_head hosts; bool modified; }; @@ -198,16 +199,18 @@ nvme_root_t nvme_scan(const char *config_file) { nvme_root_t r = nvme_scan_filter(NULL); - if (r && config_file) + if (r && config_file) { json_read_config(r, config_file); + r->config_file = strdup(config_file); + } return r; } -int nvme_update_config(nvme_root_t r, const char *config_file) +int nvme_update_config(nvme_root_t r) { - if (!r->modified) + if (!r->modified || !r->config_file) return 0; - return json_update_config(r, config_file); + return json_update_config(r, r->config_file); } nvme_host_t nvme_first_host(nvme_root_t r) @@ -269,6 +272,8 @@ void nvme_free_tree(nvme_root_t r) nvme_for_each_host_safe(r, h, _h) nvme_free_host(h); + if (r->config_file) + free(r->config_file); free(r); } diff --git a/src/nvme/tree.h b/src/nvme/tree.h index 8823254a09..53f53e3f2c 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -977,11 +977,10 @@ void nvme_reset_topology(nvme_root_t r); /** * nvme_update_config() - * @r: - * @config_file: * * Return: */ -int nvme_update_config(nvme_root_t r, const char *config_file); +int nvme_update_config(nvme_root_t r); /** * nvme_free_tree() - From df68eb67ceebbaf307bfba84ab21bcd0ba3ccda8 Mon Sep 17 00:00:00 2001 From: Klaus Jensen Date: Tue, 15 Jun 2021 21:22:20 +0200 Subject: [PATCH 0090/1564] Typo fix Fix a small typo. Signed-off-by: Klaus Jensen --- src/nvme/ioctl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index c9494ba80c..aee6aefb13 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -1494,7 +1494,7 @@ int nvme_set_features_lba_range(int fd, __u32 nsid, __u32 nr_ranges, bool save, */ enum nvme_feat_tmpthresh_thsel { NVME_FEATURE_TEMPTHRESH_THSEL_OVER = 0, - NVME_FEATURETEMPTHRESH__THSEL_UNDER = 1, + NVME_FEATURE_TEMPTHRESH_THSEL_UNDER = 1, }; /** From 6755e2e19d12cdd1f407083739a98a8f8406df7e Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Sun, 13 Jun 2021 12:40:54 +0200 Subject: [PATCH 0091/1564] types: add NVME_LOG_LPO_NONE Add additional log page definition. Signed-off-by: Hannes Reinecke --- src/nvme/types.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/nvme/types.h b/src/nvme/types.h index 4a1dbce205..9b3427b7db 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -111,6 +111,7 @@ static inline uint64_t le64_to_cpu(__le64 x) * @NVME_NVMSETID_NONE: Use to omit a nvmsetid 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_ID_NVMSET_LIST_MAX: The largest possible nvmset index in identify * nvmeset @@ -141,6 +142,7 @@ enum nvme_constants { NVME_NVMSETID_NONE = 0, NVME_LOG_LSP_NONE = 0, NVME_LOG_LSI_NONE = 0, + NVME_LOG_LPO_NONE = 0, NVME_IDENTIFY_DATA_SIZE = 4096, NVME_ID_NVMSET_LIST_MAX = 31, NVME_ID_UUID_LIST_MAX = 127, From 8999e3d9b21844e75b072851658fd3b3fd4de12e Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 14 Jun 2021 09:20:06 +0200 Subject: [PATCH 0092/1564] fabrics: Read system UUID from DMI and merge hostnqn generation functions Ported from nvme-cli. Signed-off-by: Hannes Reinecke --- src/nvme/fabrics.c | 109 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 95 insertions(+), 14 deletions(-) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 4c59704497..ad2fe7b994 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -568,30 +569,110 @@ int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, return ret; } -#ifdef CONFIG_SYSTEMD -char *nvmf_hostnqn_generate() +#define PATH_DMI_ENTRIES "/sys/firmware/dmi/entries" + +int uuid_from_dmi(char *system_uuid) { - char *ret = NULL; - sd_id128_t id; + int f; + DIR *d; + struct dirent *de; + char buf[512]; + + system_uuid[0] = '\0'; + d = opendir(PATH_DMI_ENTRIES); + if (!d) + return -ENXIO; + while ((de = readdir(d))) { + char filename[PATH_MAX]; + int len, type; + + if (de->d_name[0] == '.') + continue; + sprintf(filename, "%s/%s/type", PATH_DMI_ENTRIES, de->d_name); + f = open(filename, O_RDONLY); + if (f < 0) + continue; + len = read(f, buf, 512); + len = read(f, buf, 512); + close(f); + if (len < 0) + continue; + if (sscanf(buf, "%d", &type) != 1) + continue; + if (type != 1) + continue; + sprintf(filename, "%s/%s/raw", PATH_DMI_ENTRIES, de->d_name); + f = open(filename, O_RDONLY); + if (f < 0) + continue; + len = read(f, buf, 512); + close(f); + if (len < 0) + continue; + /* Sigh. https://en.wikipedia.org/wiki/Overengineering */ + /* DMTF SMBIOS 3.0 Section 7.2.1 System UUID */ + sprintf(system_uuid, + "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" + "%02x%02x%02x%02x%02x%02x", + (uint8_t)buf[8 + 3], (uint8_t)buf[8 + 2], + (uint8_t)buf[8 + 1], (uint8_t)buf[8 + 0], + (uint8_t)buf[8 + 5], (uint8_t)buf[8 + 4], + (uint8_t)buf[8 + 7], (uint8_t)buf[8 + 6], + (uint8_t)buf[8 + 8], (uint8_t)buf[8 + 9], + (uint8_t)buf[8 + 10], (uint8_t)buf[8 + 11], + (uint8_t)buf[8 + 12], (uint8_t)buf[8 + 13], + (uint8_t)buf[8 + 14], (uint8_t)buf[8 + 15]); + break; + } + closedir(d); + return strlen(system_uuid) ? 0 : -ENXIO; +} - if (sd_id128_get_machine_app_specific(NVME_HOSTNQN_ID, &id) < 0) - return NULL; +#ifdef CONFIG_SYSTEMD +#include +#define NVME_HOSTNQN_ID SD_ID128_MAKE(c7,f4,61,81,12,be,49,32,8c,83,10,6f,9d,dd,d8,6b) +#endif - if (asprintf(&ret, - "nqn.2014-08.org.nvmexpress:uuid:" SD_ID128_FORMAT_STR "\n", - SD_ID128_FORMAT_VAL(id)) < 0) - ret = NULL; +static int uuid_from_systemd(char *system_uuid) +{ + int ret = -ENOTSUP; +#ifdef CONFIG_SYSTEMD + sd_id128_t id; + ret = sd_id128_get_machine_app_specific(NVME_HOSTNQN_ID, &id); + if (!ret) + asprintf(systemd_uuid, SD_ID128_FORMAT_STR, + SD_ID128_FORMAT_VAL(id)); +#endif return ret; } -#else + char *nvmf_hostnqn_generate() { - errno = ENOTSUP; - return NULL; -} + char *hostnqn; + int ret; + char uuid_str[37]; /* e.g. 1b4e28ba-2fa1-11d2-883f-0016d3cca427 + \0 */ +#ifdef CONFIG_LIBUUID + uuid_t uuid; #endif + ret = uuid_from_dmi(uuid_str); + if (ret < 0) + ret = uuid_from_systemd(uuid_str); +#ifdef CONFIG_LIBUUID + if (ret < 0) { + uuid_generate_random(uuid); + uuid_unparse_lower(uuid, uuid_str); + ret = 0; + } +#endif + if (ret < 0) + return NULL; + + asprintf(&hostnqn, "nqn.2014-08.org.nvmexpress:uuid:%s\n", uuid_str); + return hostnqn; +} + static char *nvmf_read_file(const char *f, int len) { char buf[len]; From 650291e77248852d9965f37a4297e75636db95cb Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 14 Jun 2021 12:24:42 +0200 Subject: [PATCH 0093/1564] ioctl: add definitions for Namespace Write Protect Feature Signed-off-by: Hannes Reinecke --- src/nvme/ioctl.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index aee6aefb13..2878cd01c9 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -774,6 +774,20 @@ enum nvme_virt_mgmt_rt { NVME_VIRT_MGMT_RT_VI_RESOURCE = 1, }; +/** + * enum nvme_ns_write_protect - + * @NVME_NS_WP_CFG_NONE + * @NVME_NS_WP_CFG_PROTECT + * @NVME_NS_WP_CFG_PROTECT_POWER_CYCLE + * @NVME_NS_WP_CFG_PROTECT_PERMANENT + */ +enum nvme_ns_write_protect_cfg { + NVME_NS_WP_CFG_NONE = 0, + NVME_NS_WP_CFG_PROTECT = 1, + NVME_NS_WP_CFG_PROTECT_POWER_CYCLE = 2, + NVME_NS_WP_CFG_PROTECT_PERMANENT = 3, +}; + /** * nvme_identify() - Send the NVMe Identify command * @fd: File descriptor of nvme device From 37989a237a58f33f822f1551c46770c0c83ae819 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 14 Jun 2021 13:39:13 +0200 Subject: [PATCH 0094/1564] ioctl: add 'nsid' parameter to nvme_identify_secondary_ctrl_list() nvme_identify_secondary_ctrl_list() can relate to specific nsids, so allow the nsid parameter to be settable. Signed-off-by: Hannes Reinecke --- src/nvme/ioctl.c | 4 ++-- src/nvme/ioctl.h | 3 ++- test/test.c | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index f4960f6f95..edc4433b95 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -456,12 +456,12 @@ int nvme_identify_primary_ctrl(int fd, __u16 cntid, NVME_UUID_NONE, NVME_CSI_NVM, cap); } -int nvme_identify_secondary_ctrl_list(int fd, __u16 cntid, +int nvme_identify_secondary_ctrl_list(int fd, __u32 nsid, __u16 cntid, struct nvme_secondary_ctrl_list *list) { BUILD_ASSERT(sizeof(struct nvme_secondary_ctrl_list) == 4096); return nvme_identify(fd, NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST, - NVME_NSID_NONE, cntid, NVME_NVMSETID_NONE, + nsid, cntid, NVME_NVMSETID_NONE, NVME_UUID_NONE, NVME_CSI_NVM, list); } diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 2878cd01c9..ef6faf1d1e 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -985,6 +985,7 @@ int nvme_identify_primary_ctrl(int fd, __u16 cntid, /** * nvme_identify_secondary_ctrl_list() - Retrieves secondary controller list * @fd: File descriptor of nvme device + * @nsid: Namespace identifier * @cntid: Return controllers starting at this identifier * @sc_list: User space destination address to transfer the data * @@ -999,7 +1000,7 @@ int nvme_identify_primary_ctrl(int fd, __u16 cntid, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_identify_secondary_ctrl_list(int fd, __u16 cntid, +int nvme_identify_secondary_ctrl_list(int fd, __u32 nsid, __u16 cntid, struct nvme_secondary_ctrl_list *list); /** diff --git a/test/test.c b/test/test.c index fc9c21ef08..7c6a5cb835 100644 --- a/test/test.c +++ b/test/test.c @@ -101,7 +101,7 @@ static int test_ctrl(nvme_ctrl_t c) printf(" Identify Primary:\n"); else printf(" ERROR: Identify Primary:%x\n", ret); - ret = nvme_identify_secondary_ctrl_list(fd, 0, &sec); + ret = nvme_identify_secondary_ctrl_list(fd, 1, 0, &sec); if (!ret) printf(" Identify Secondary:\n"); else From 9df8676d2db6941a7f7d8f0b562dcfc4bdeb63e4 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 14 Jun 2021 15:44:28 +0200 Subject: [PATCH 0095/1564] Add logging functionality to libnvme Port the logging functionality from nvme-cli to libnvme and replace the 'verbose' option. Signed-off-by: Hannes Reinecke --- src/Makefile | 2 +- src/libnvme.h | 1 + src/nvme/cleanup.c | 4 ++ src/nvme/cleanup.h | 18 ++++++ src/nvme/fabrics.c | 140 +++++++++++++++++++++++---------------------- src/nvme/fabrics.h | 2 - src/nvme/log.c | 90 +++++++++++++++++++++++++++++ src/nvme/log.h | 37 ++++++++++++ src/nvme/tree.c | 19 ++---- src/nvme/tree.h | 17 ------ src/nvme/util.c | 12 +++- 11 files changed, 235 insertions(+), 107 deletions(-) create mode 100644 src/nvme/cleanup.c create mode 100644 src/nvme/cleanup.h create mode 100644 src/nvme/log.c create mode 100644 src/nvme/log.h diff --git a/src/Makefile b/src/Makefile index 4beb13d8db..19361f89ff 100644 --- a/src/Makefile +++ b/src/Makefile @@ -48,7 +48,7 @@ $(libccan_objs) $(libccan_sobjs): $(libccan_headers) $(CCANDIR)config.h libnvme_priv := nvme/private.h libnvme_api := libnvme.h nvme/types.h nvme/ioctl.h nvme/filters.h nvme/tree.h nvme/util.h nvme/fabrics.h -libnvme_srcs := nvme/ioctl.c nvme/filters.c nvme/fabrics.c nvme/util.c nvme/tree.c +libnvme_srcs := nvme/ioctl.c nvme/filters.c nvme/fabrics.c nvme/util.c nvme/tree.c nvme/log.c nvme/cleanup.c ifneq ($(CONFIG_JSONC),0) override libnvme_srcs += nvme/json.c endif diff --git a/src/libnvme.h b/src/libnvme.h index bd60d0d8a5..00b1211e70 100644 --- a/src/libnvme.h +++ b/src/libnvme.h @@ -20,6 +20,7 @@ extern "C" { #include "nvme/filters.h" #include "nvme/tree.h" #include "nvme/util.h" +#include "nvme/log.h" #ifdef __cplusplus } diff --git a/src/nvme/cleanup.c b/src/nvme/cleanup.c new file mode 100644 index 0000000000..0d5d910a8f --- /dev/null +++ b/src/nvme/cleanup.c @@ -0,0 +1,4 @@ +#include +#include "cleanup.h" + +DEFINE_CLEANUP_FUNC(cleanup_charp, char *, free); diff --git a/src/nvme/cleanup.h b/src/nvme/cleanup.h new file mode 100644 index 0000000000..89a4984dfe --- /dev/null +++ b/src/nvme/cleanup.h @@ -0,0 +1,18 @@ +#ifndef __CLEANUP_H +#define __CLEANUP_H + +#define __cleanup__(fn) __attribute__((cleanup(fn))) + +#define DECLARE_CLEANUP_FUNC(name, type) \ + void name(type *__p) + +#define DEFINE_CLEANUP_FUNC(name, type, free_fn)\ +DECLARE_CLEANUP_FUNC(name, type) \ +{ \ + if (*__p) \ + free_fn(*__p); \ +} + +DECLARE_CLEANUP_FUNC(cleanup_charp, char *); + +#endif diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index ad2fe7b994..19cc188146 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -32,6 +32,7 @@ #include "fabrics.h" #include "ioctl.h" #include "util.h" +#include "log.h" #include "private.h" #define NVMF_HOSTID_SIZE 37 @@ -158,7 +159,6 @@ static struct nvme_fabrics_config *merge_config(nvme_ctrl_t c, UPDATE_CFG_OPTION(ctrl_cfg, cfg, disable_sqflow, false); UPDATE_CFG_OPTION(ctrl_cfg, cfg, hdr_digest, false); UPDATE_CFG_OPTION(ctrl_cfg, cfg, data_digest, false); - UPDATE_CFG_OPTION(ctrl_cfg, cfg, verbose, false); return ctrl_cfg; } @@ -215,6 +215,21 @@ static int build_options(nvme_ctrl_t c, char **argstr) { struct nvme_fabrics_config *cfg = nvme_ctrl_get_config(c); const char *transport = nvme_ctrl_get_transport(c); + const char *hostnqn, *hostid; + + if (!transport) { + nvme_msg(LOG_ERR, "need a transport (-t) argument\n"); + errno = EINVAL; + return -1; + } + + if (strncmp(transport, "loop", 4)) { + if (!nvme_ctrl_get_traddr(c)) { + nvme_msg(LOG_ERR, "need a address (-a) argument\n"); + errno = EINVAL; + return -1; + } + } /* always specify nqn as first arg - this will init the string */ if (asprintf(argstr, "nqn=%s", @@ -273,21 +288,29 @@ static int __nvmf_add_ctrl(const char *argstr) char buf[0x1000], *options, *p; fd = open(nvmf_dev, O_RDWR); - if (fd < 0) + if (fd < 0) { + nvme_msg(LOG_ERR, "Failed to open %s: %s\n", + nvmf_dev, strerror(errno)); return -1; + } + nvme_msg(LOG_DEBUG, "connect ctrl, '%s'\n", argstr); ret = write(fd, argstr, len); if (ret != len) { + nvme_msg(LOG_NOTICE, "Failed to write to %s: %s\n", + nvmf_dev, strerror(errno)); ret = -1; goto out_close; } len = read(fd, buf, sizeof(buf)); if (len < 0) { + nvme_msg(LOG_ERR, "Failed to read from %s: %s\n", + nvmf_dev, strerror(errno)); ret = -1; goto out_close; } - + nvme_msg(LOG_DEBUG, "connect ctrl, response '%s'\n", buf); buf[len] = '\0'; options = buf; while ((p = strsep(&options, ",\n")) != NULL) { @@ -297,6 +320,7 @@ static int __nvmf_add_ctrl(const char *argstr) goto out_close; } + nvme_msg(LOG_ERR, "Failed to parse ctrl info for \"%s\"\n", argstr); errno = EINVAL; ret = -1; out_close: @@ -315,16 +339,10 @@ int nvmf_add_ctrl_opts(nvme_ctrl_t c, struct nvme_fabrics_config *cfg) if (ret) return ret; - if (cfg->verbose) - fprintf(stderr, "nvmf connect %s\n", argstr); ret = __nvmf_add_ctrl(argstr); free(argstr); - if (cfg->verbose) { - if (ret < 0) - fprintf(stderr, "failed to add ctrl, error %d\n", errno); - else - fprintf(stderr, "nvme%d: added ctrl\n", ret); - } + if (ret >= 0) + nvme_msg(LOG_INFO, "nvme%d: ctrl connected\n", ret); return ret; } @@ -343,17 +361,12 @@ int nvmf_add_ctrl(nvme_host_t h, nvme_ctrl_t c, if (ret) return ret; - if (cfg->verbose) - fprintf(stderr, "nvmf connect %s\n", argstr); ret = __nvmf_add_ctrl(argstr); free(argstr); - if (ret < 0) { - if (cfg->verbose) - fprintf(stderr, "failed to add ctrl, error %d\n", ret); + if (ret < 0) return ret; - } - if (cfg->verbose) - fprintf(stderr, "nvme%d: ctrl connected\n", ret); + + nvme_msg(LOG_INFO, "nvme%d: ctrl connected\n", ret); return nvme_init_ctrl(h, c, ret); } @@ -376,10 +389,8 @@ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, case NVME_NQN_NVME: break; default: - if (cfg->verbose) - fprintf(stderr, "skipping discovery entry, " - "invalid subsystem type %d\n", - e->subtype); + nvme_msg(LOG_ERR, "skipping unsupported subtype %d\n", + e->subtype); errno = EINVAL; return NULL; } @@ -396,10 +407,8 @@ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, trsvcid = e->trsvcid; break; default: - if (cfg->verbose) - fprintf(stderr, "skipping discovery entry, " - "invalid address family %d\n", - e->trtype); + nvme_msg(LOG_ERR, "skipping unsupported adrfam %d\n", + e->adrfam); errno = EINVAL; return NULL; } @@ -411,29 +420,31 @@ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, traddr = e->traddr; trsvcid = NULL; break; + default: + nvme_msg(LOG_ERR, "skipping unsupported adrfam %d\n", + e->adrfam); + errno = EINVAL; + return NULL; } case NVMF_TRTYPE_LOOP: break; default: - if (cfg->verbose) - fprintf(stderr, "skipping discovery entry, " - "invalid transport type %d\n", - e->trtype); + nvme_msg(LOG_ERR, "skipping unsupported transport %d\n", + e->trtype); errno = EINVAL; return NULL; } transport = nvmf_trtype_str(e->trtype); - if (cfg->verbose) - fprintf(stderr, "lookup ctrl %s %s %s\n", - transport, traddr, trsvcid); + nvme_msg(LOG_DEBUG, "lookup ctrl " + "(transport: %s, traddr: %s, trsvcid %s)\n", + transport, traddr, trsvcid); c = nvme_create_ctrl(e->subnqn, transport, traddr, NULL, trsvcid); if (!c) { - if (cfg->verbose) - fprintf(stderr, "skipping discovery entry, " - "failed to allocate controller on %s port %s\n", - transport, traddr); + nvme_msg(LOG_DEBUG, "skipping discovery entry, " + "failed to allocate %s controller with traddr %s\n", + transport, traddr); errno = ENOMEM; return NULL; } @@ -452,17 +463,14 @@ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, if (errno == EINVAL && disable_sqflow) { errno = 0; /* disable_sqflow is unrecognized option on older kernels */ - if (cfg->verbose) - fprintf(stderr, "failed to connect controller, " - "retry with disabling SQ flow control\n"); + nvme_msg(LOG_INFO, "failed to connect controller, " + "retry with disabling SQ flow control\n"); disable_sqflow = false; ret = nvmf_add_ctrl(h, c, cfg, disable_sqflow); if (!ret) return c; } - if (cfg->verbose) - fprintf(stderr, "failed to connect controller, " - "error %d\n", errno); + nvme_msg(LOG_ERR, "failed to connect controller, error %d\n", errno); nvme_free_ctrl(c); return NULL; } @@ -485,18 +493,18 @@ int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, hdr = sizeof(struct nvmf_discovery_log); log = malloc(hdr); if (!log) { + nvme_msg(LOG_ERR, + "could not allocate memory for discovery log header\n"); errno = ENOMEM; return -1; } memset(log, 0, hdr); - if (nvme_ctrl_is_verbose(c)) - fprintf(stderr, "%s: discover length %d\n", name, 0x100); + nvme_msg(LOG_DEBUG, "%s: discover length %d\n", name, 0x100); ret = nvme_discovery_log(nvme_ctrl_get_fd(c), 0x100, log); if (ret) { - if (nvme_ctrl_is_verbose(c)) - fprintf(stderr, "%s: discover failed, error %d\n", - name, errno); + nvme_msg(LOG_INFO, "%s: discover failed, error %d\n", + name, errno); goto out_free_log; } @@ -515,48 +523,42 @@ int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, free(log); log = malloc(size); if (!log) { + nvme_msg(LOG_ERR, + "could not alloc memory for discovery log page\n"); errno = ENOMEM; return -1; } memset(log, 0, size); - if (nvme_ctrl_is_verbose(c)) - fprintf(stderr, "%s: discover length %d\n", name, size); - + nvme_msg(LOG_DEBUG, "%s: discover length %d\n", name, size); ret = nvme_discovery_log(nvme_ctrl_get_fd(c), size, log); if (ret) { - if (nvme_ctrl_is_verbose(c)) - fprintf(stderr, "%s: discover " - "try %d/%d failed, error %d\n", - name, retries, max_retries, errno); + nvme_msg(LOG_INFO, + "%s: discover try %d/%d failed, error %d\n", + name, retries, max_retries, errno); goto out_free_log; } genctr = le64_to_cpu(log->genctr); - if (nvme_ctrl_is_verbose(c)) - fprintf(stderr, "%s: discover genctr %lu, retry\n", - name, genctr); + nvme_msg(LOG_DEBUG, "%s: discover genctr %lu, retry\n", + name, genctr); ret = nvme_discovery_log(nvme_ctrl_get_fd(c), hdr, log); if (ret) { - if (nvme_ctrl_is_verbose(c)) - fprintf(stderr, "%s: discover " - "try %d/%d failed, error %d\n", - name, retries, max_retries, errno); + nvme_msg(LOG_INFO, + "%s: discover try %d/%d failed, error %d\n", + name, retries, max_retries, errno); goto out_free_log; } } while (genctr != le64_to_cpu(log->genctr) && ++retries < max_retries); if (genctr != le64_to_cpu(log->genctr)) { - if (nvme_ctrl_is_verbose(c)) - fprintf(stderr, "%s: discover genctr mismatch\n", name); + nvme_msg(LOG_INFO, "%s: discover genctr mismatch\n", name); errno = EAGAIN; ret = -1; } else if (numrec != le64_to_cpu(log->numrec)) { - if (nvme_ctrl_is_verbose(c)) - fprintf(stderr, - "%s: could only fetch %lu of %lu records\n", - name, numrec, le64_to_cpu(log->numrec)); + nvme_msg(LOG_INFO, "%s: could only fetch %lu of %lu records\n", + name, numrec, le64_to_cpu(log->numrec)); errno = EBADSLT; ret = -1; } else { diff --git a/src/nvme/fabrics.h b/src/nvme/fabrics.h index 077e47311d..c130339b15 100644 --- a/src/nvme/fabrics.h +++ b/src/nvme/fabrics.h @@ -30,7 +30,6 @@ * @disable_sqflow: Disable controller sq flow control * @hdr_digest: Generate/verify header digest (TCP) * @data_digest: Generate/verify data digest (TCP) - * @verbose: Verbose output */ struct nvme_fabrics_config { int queue_size; @@ -46,7 +45,6 @@ struct nvme_fabrics_config { bool disable_sqflow; bool hdr_digest; bool data_digest; - bool verbose; }; /** diff --git a/src/nvme/log.c b/src/nvme/log.c new file mode 100644 index 0000000000..66cf692b80 --- /dev/null +++ b/src/nvme/log.c @@ -0,0 +1,90 @@ +/* + * 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. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This file implements basic logging functionality. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#define LOG_FUNCNAME 1 +#include "log.h" +#include "cleanup.h" + +#ifndef LOG_CLOCK +#define LOG_CLOCK CLOCK_MONOTONIC +#endif + +int nvme_log_level = DEFAULT_LOGLEVEL; +bool nvme_log_timestamp; +bool nvme_log_pid; + +void __attribute__((format(printf, 3, 4))) +__nvme_msg(int lvl, const char *func, const char *format, ...) +{ + va_list ap; + char pidbuf[16]; + char timebuf[32]; + static const char *const formats[] = { + "%s%s%s", + "%s%s%s: ", + "%s<%s>%s ", + "%s<%s> %s: ", + "[%s] %s%s ", + "[%s]%s %s: ", + "[%s] <%s>%s ", + "[%s] <%s> %s: ", + }; + char *header __cleanup__(cleanup_charp) = NULL; + char *message __cleanup__(cleanup_charp) = NULL; + int idx; + + if (lvl > nvme_log_level) + return; + + if (nvme_log_timestamp) { + struct timespec now; + + clock_gettime(LOG_CLOCK, &now); + snprintf(timebuf, sizeof(timebuf), "%6ld.%06ld", + (long)now.tv_sec, now.tv_nsec / 1000); + } else + *timebuf = '\0'; + + if (nvme_log_pid) + snprintf(pidbuf, sizeof(pidbuf), "%ld", (long)getpid()); + else + *pidbuf = '\0'; + + idx = ((nvme_log_timestamp ? 1 : 0) << 2) | + ((nvme_log_pid ? 1 : 0) << 1) | (func ? 1 : 0); + + if (asprintf(&header, formats[idx], timebuf, pidbuf, func ? func : "") + == -1) + header = NULL; + + va_start(ap, format); + if (vasprintf(&message, format, ap) == -1) + message = NULL; + va_end(ap); + + fprintf(stderr, "%s%s", header ? header : "", + message ? message : ""); + +} diff --git a/src/nvme/log.h b/src/nvme/log.h new file mode 100644 index 0000000000..36f56e8796 --- /dev/null +++ b/src/nvme/log.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 Martin Wilck, SUSE LLC + * SPDX-License-Identifier: LGPL-2.1-or-newer + */ +#ifndef _LOG_H +#define _LOG_H + +#include + +#ifndef MAX_LOGLEVEL +# define MAX_LOGLEVEL LOG_DEBUG +#endif +#ifndef DEFAULT_LOGLEVEL +# define DEFAULT_LOGLEVEL LOG_NOTICE +#endif + +#if (LOG_FUNCNAME == 1) +#define __nvme_log_func __func__ +#else +#define __nvme_log_func NULL +#endif + +extern int nvme_log_level; +extern bool nvme_log_timestamp; +extern bool nvme_log_pid; + +void __attribute__((format(printf, 3, 4))) +__nvme_msg(int lvl, const char *func, const char *format, ...); + +#define nvme_msg(lvl, format, ...) \ + do { \ + if ((lvl) <= MAX_LOGLEVEL) \ + __nvme_msg(lvl, __nvme_log_func, \ + format, ##__VA_ARGS__); \ + } while (0) + +#endif /* _LOG_H */ diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 04c7074271..896257dc27 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -23,6 +23,7 @@ #include "filters.h" #include "util.h" #include "fabrics.h" +#include "log.h" #include "private.h" static struct nvme_host *default_host; @@ -733,16 +734,6 @@ bool nvme_ctrl_is_persistent(nvme_ctrl_t c) return c->persistent; } -void nvme_ctrl_set_verbosity(nvme_ctrl_t c, bool verbose) -{ - c->cfg.verbose = verbose; -} - -bool nvme_ctrl_is_verbose(nvme_ctrl_t c) -{ - return c->cfg.verbose; -} - int nvme_ctrl_identify(nvme_ctrl_t c, struct nvme_id_ctrl *id) { return nvme_identify_ctrl(nvme_ctrl_get_fd(c), id); @@ -774,16 +765,14 @@ int nvme_ctrl_disconnect(nvme_ctrl_t c) { int ret; - if (c->cfg.verbose) - fprintf(stderr, "%s: disconnect\n", c->name); ret = nvme_set_attr(nvme_ctrl_get_sysfs_dir(c), "delete_controller", "1"); if (ret < 0) { - if (c->cfg.verbose) - fprintf(stderr, "%s: failed to disconnect, error %d\n", - c->name, errno); + nvme_msg(LOG_ERR, "%s: failed to disconnect, error %d\n", + c->name, errno); return ret; } + nvme_msg(LOG_INFO, "%s: disconnected\n", c->name); if (c->fd >= 0) { close(c->fd); c->fd = -1; diff --git a/src/nvme/tree.h b/src/nvme/tree.h index 53f53e3f2c..4983bbaec1 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -834,23 +834,6 @@ bool nvme_ctrl_is_persistent(nvme_ctrl_t c); */ void nvme_ctrl_disable_sqflow(nvme_ctrl_t c, bool disable_sqflow); -/** - * nvme_ctrl_set_verbosity() - - * @c: - * @verbose: - * - * Return: - */ -void nvme_ctrl_set_verbosity(nvme_ctrl_t c, bool verbose); - -/** - * nvme_ctrl_is_verbose() - - * @c: - * - * Return: - */ -bool nvme_ctrl_is_verbose(nvme_ctrl_t c); - /** * nvme_ctrl_identify() - * @c: diff --git a/src/nvme/util.c b/src/nvme/util.c index 8dbef2033b..761ae81cf8 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -24,6 +24,7 @@ #include "filters.h" #include "util.h" #include "tree.h" +#include "log.h" static inline __u8 nvme_generic_status_to_errno(__u16 status) { @@ -562,9 +563,11 @@ static int __nvme_set_attr(const char *path, const char *value) int ret, fd; fd = open(path, O_WRONLY); - if (fd < 0) + if (fd < 0) { + nvme_msg(LOG_ERR, "Failed to open %s: %s\n", path, + strerror(errno)); return -1; - + } ret = write(fd, value, strlen(value)); close(fd); return ret; @@ -590,8 +593,11 @@ static char *__nvme_get_attr(const char *path) int ret, fd; fd = open(path, O_RDONLY); - if (fd < 0) + if (fd < 0) { + nvme_msg(LOG_ERR, "Failed to open %s: %s\n", path, + strerror(errno)); return NULL; + } ret = read(fd, value, sizeof(value) - 1); if (ret < 0) { From f5fa40c89d3d4d8840322c4e5373c00ea2e5eaca Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 16 Jun 2021 09:25:50 +0200 Subject: [PATCH 0096/1564] tree: argument checking for nvme_create_ctrl() Add argument checking for nvme_create_ctrl() to ensure the controller values are correct and avoid failures later on in nvme_add_ctrl(). Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 122 +++++++++++++++++++++++++++++++++++++++++------ src/nvme/types.h | 1 + 2 files changed, 109 insertions(+), 14 deletions(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 896257dc27..e3ce92b6f6 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -16,6 +16,10 @@ #include #include +#include +#include +#include + #include #include "ioctl.h" #include "filters.h" @@ -835,14 +839,98 @@ void nvme_free_ctrl(nvme_ctrl_t c) free(c); } +#define ____stringify(x...) #x +#define __stringify(x...) ____stringify(x) + +static void discovery_trsvcid(nvme_ctrl_t c) +{ + if (!strcmp(c->transport, "tcp")) { + /* Default port for NVMe/TCP discovery controllers */ + c->trsvcid = strdup(__stringify(NVME_DISC_IP_PORT)); + } else if (!strcmp(c->transport, "rdma")) { + /* Default port for NVMe/RDMA controllers */ + c->trsvcid = strdup(__stringify(NVME_RDMA_IP_PORT)); + } +} + +static bool traddr_is_hostname(const char *transport, const char *traddr) +{ + char addrstr[NVMF_TRADDR_SIZE]; + + if (!traddr || !transport) + return false; + if (strcmp(transport, "tcp") && + strcmp(transport, "rdma")) + return false; + if (inet_pton(AF_INET, traddr, addrstr) > 0 || + inet_pton(AF_INET6, traddr, addrstr) > 0) + return false; + return true; +} + +void hostname2traddr(nvme_ctrl_t c, const char *host_traddr) +{ + struct addrinfo *host_info, hints = {.ai_family = AF_UNSPEC}; + char addrstr[NVMF_TRADDR_SIZE]; + const char *p; + int ret; + + ret = getaddrinfo(host_traddr, NULL, &hints, &host_info); + if (ret) { + nvme_msg(LOG_DEBUG, "failed to resolve host %s info\n", + host_traddr); + c->host_traddr = strdup(host_traddr); + return; + } + + switch (host_info->ai_family) { + case AF_INET: + p = inet_ntop(host_info->ai_family, + &(((struct sockaddr_in *)host_info->ai_addr)->sin_addr), + addrstr, NVMF_TRADDR_SIZE); + break; + case AF_INET6: + p = inet_ntop(host_info->ai_family, + &(((struct sockaddr_in6 *)host_info->ai_addr)->sin6_addr), + addrstr, NVMF_TRADDR_SIZE); + break; + default: + nvme_msg(LOG_DEBUG, "unrecognized address family (%d) %s\n", + host_info->ai_family, c->traddr); + c->host_traddr = strdup(host_traddr); + goto free_addrinfo; + } + if (!p) { + nvme_msg(LOG_DEBUG, "failed to get traddr for %s\n", + c->traddr); + c->host_traddr = strdup(host_traddr); + } else + c->host_traddr = strdup(addrstr); + +free_addrinfo: + freeaddrinfo(host_info); +} + struct nvme_ctrl *nvme_create_ctrl(const char *subsysnqn, const char *transport, const char *traddr, const char *host_traddr, const char *trsvcid) { struct nvme_ctrl *c; + bool discovery = false; - if (!transport) + if (!transport) { + nvme_msg(LOG_ERR, "No transport specified\n"); + return NULL; + } + if (strncmp(transport, "loop", 4) && !traddr) { + nvme_msg(LOG_ERR, "No transport address for '%s'\n", transport); + return NULL; + } + if (!subsysnqn) { + nvme_msg(LOG_ERR, "No subsystem NQN specified\n"); return NULL; + } else if (!strcmp(subsysnqn, NVME_DISC_SUBSYS_NAME)) + discovery = true; c = calloc(1, sizeof(*c)); c->fd = -1; c->cfg.tos = -1; @@ -850,20 +938,26 @@ struct nvme_ctrl *nvme_create_ctrl(const char *subsysnqn, list_head_init(&c->paths); list_node_init(&c->entry); c->transport = strdup(transport); - if (subsysnqn) - c->subsysnqn = strdup(subsysnqn); + c->subsysnqn = strdup(subsysnqn); if (traddr) c->traddr = strdup(traddr); - else - c->traddr = strdup("none"); - if (host_traddr) - c->host_traddr = strdup(host_traddr); - else - c->host_traddr = strdup("none"); + if (host_traddr) { + if (traddr_is_hostname(transport, host_traddr)) + hostname2traddr(c, host_traddr); + else + c->host_traddr = strdup(host_traddr); + } if (trsvcid) c->trsvcid = strdup(trsvcid); - else - c->trsvcid = strdup("none"); + else if (discovery) + discovery_trsvcid(c); + else if (!strncmp(transport, "rdma", 4) || + !strncmp(transport, "tcp", 3)) { + nvme_msg(LOG_ERR, "No trsvcid specified for '%s'\n", + transport); + nvme_free_ctrl(c); + c = NULL; + } return c; } @@ -879,13 +973,13 @@ struct nvme_ctrl *nvme_lookup_ctrl(struct nvme_subsystem *s, nvme_subsystem_for_each_ctrl(s, c) { if (strcmp(c->transport, transport)) continue; - if (traddr && + if (traddr && c->traddr && strcmp(c->traddr, traddr)) continue; - if (host_traddr && + if (host_traddr && c->host_traddr && strcmp(c->host_traddr, host_traddr)) continue; - if (trsvcid && + if (trsvcid && c->trsvcid && strcmp(c->trsvcid, trsvcid)) continue; return c; diff --git a/src/nvme/types.h b/src/nvme/types.h index 9b3427b7db..773c721c7c 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -3564,6 +3564,7 @@ enum nvme_subsys_type { #define NVME_DISC_SUBSYS_NAME "nqn.2014-08.org.nvmexpress.discovery" #define NVME_RDMA_IP_PORT 4420 +#define NVME_DISC_IP_PORT 8009 /* However the max length of a qualified name is another size */ #define NVMF_NQN_SIZE 223 From 671cfdfdf12bd1ba4938df7a14157a13e29fbfd5 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 16 Jun 2021 09:44:59 +0200 Subject: [PATCH 0097/1564] fabrics: blank out invalid arguments in build_options() Not all options are valid under all circumstances; eg for discovery some options like 'nr_io_queues' are invalid. So mask out invalid options to avoid a failure when creating a controller. Signed-off-by: Hannes Reinecke --- src/nvme/fabrics.c | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 19cc188146..83fbc64bd6 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -216,6 +216,7 @@ static int build_options(nvme_ctrl_t c, char **argstr) struct nvme_fabrics_config *cfg = nvme_ctrl_get_config(c); const char *transport = nvme_ctrl_get_transport(c); const char *hostnqn, *hostid; + bool discover = false; if (!transport) { nvme_msg(LOG_ERR, "need a transport (-t) argument\n"); @@ -229,6 +230,9 @@ static int build_options(nvme_ctrl_t c, char **argstr) errno = EINVAL; return -1; } + /* Use the default ctrl loss timeout if unset */ + if (cfg->ctrl_loss_tmo == -1) + cfg->ctrl_loss_tmo = NVMF_DEF_CTRL_LOSS_TMO; } /* always specify nqn as first arg - this will init the string */ @@ -237,8 +241,10 @@ static int build_options(nvme_ctrl_t c, char **argstr) errno = ENOMEM; return -1; } - - + if (!strcmp(nvme_ctrl_get_subsysnqn(c), NVME_DISC_SUBSYS_NAME)) + discover = true; + hostnqn = nvme_ctrl_get_hostnqn(c); + hostid = nvme_ctrl_get_hostid(c); if (add_argument(argstr, "transport", transport) || add_argument(argstr, "traddr", nvme_ctrl_get_traddr(c)) || @@ -246,14 +252,22 @@ static int build_options(nvme_ctrl_t c, char **argstr) nvme_ctrl_get_host_traddr(c)) || add_argument(argstr, "trsvcid", nvme_ctrl_get_trsvcid(c)) || - add_argument(argstr, "hostnqn", - nvme_ctrl_get_hostnqn(c)) || - add_argument(argstr, "hostid", - nvme_ctrl_get_hostid(c)) || - add_int_argument(argstr, "nr_write_queues", - cfg->nr_write_queues, false) || - add_int_argument(argstr, "nr_poll_queues", - cfg->nr_poll_queues, false) || + (hostnqn && add_argument(argstr, "hostnqn", hostnqn)) || + (hostid && add_argument(argstr, "hostid", hostid)) || + (!discover && + add_int_argument(argstr, "nr_io_queues", + cfg->nr_io_queues, false)) || + (!discover && + add_int_argument(argstr, "nr_write_queues", + cfg->nr_write_queues, false)) || + (!discover && + add_int_argument(argstr, "nr_poll_queues", + cfg->nr_poll_queues, false)) || + (!discover && + add_int_argument(argstr, "queue_size", + cfg->queue_size, false)) || + add_int_argument(argstr, "keep_alive_tmo", + cfg->keep_alive_tmo, false) || add_int_argument(argstr, "reconnect_delay", cfg->reconnect_delay, false) || (strcmp(transport, "loop") && @@ -268,14 +282,8 @@ static int build_options(nvme_ctrl_t c, char **argstr) (!strcmp(transport, "tcp") && add_bool_argument(argstr, "hdr_digest", cfg->hdr_digest)) || (!strcmp(transport, "tcp") && - add_bool_argument(argstr, "data_digest", cfg->data_digest)) || - add_int_argument(argstr, "queue_size", cfg->queue_size, false) || - add_int_argument(argstr, "keep_alive_tmo", - cfg->keep_alive_tmo, false) || - add_int_argument(argstr, "nr_io_queues", - cfg->nr_io_queues, false)) { + add_bool_argument(argstr, "data_digest", cfg->data_digest))) { free(*argstr); - errno = ENOMEM; return -1; } From 0130570f900bb30d46194bc3acb6244966025ee9 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 16 Jun 2021 09:56:07 +0200 Subject: [PATCH 0098/1564] fabrics: add fast_io_fail_tmo option Option to fail fast I/O when connecting to a controller. It is useful to set a fast-fail timeout for nvme in case upper layer SW wants to detect unresponsive controllers early (e.g. mdraid). Ported from nvme-cli. Signed-off-by: Hannes Reinecke --- src/nvme/fabrics.c | 4 ++++ src/nvme/fabrics.h | 2 ++ src/nvme/json.c | 6 +++++- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 83fbc64bd6..6484564443 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -154,6 +154,7 @@ static struct nvme_fabrics_config *merge_config(nvme_ctrl_t c, UPDATE_CFG_OPTION(ctrl_cfg, cfg, reconnect_delay, 0); UPDATE_CFG_OPTION(ctrl_cfg, cfg, ctrl_loss_tmo, NVMF_DEF_CTRL_LOSS_TMO); + UPDATE_CFG_OPTION(ctrl_cfg, cfg, fast_io_fail_tmo, 0); UPDATE_CFG_OPTION(ctrl_cfg, cfg, tos, -1); UPDATE_CFG_OPTION(ctrl_cfg, cfg, duplicate_connect, false); UPDATE_CFG_OPTION(ctrl_cfg, cfg, disable_sqflow, false); @@ -273,6 +274,9 @@ static int build_options(nvme_ctrl_t c, char **argstr) (strcmp(transport, "loop") && add_int_argument(argstr, "ctrl_loss_tmo", cfg->ctrl_loss_tmo, false)) || + (strcmp(transport, "loop") && + add_int_argument(argstr, "fast_io_fail_tmo", + cfg->fast_io_fail_tmo, false)) || (strcmp(transport, "loop") && add_int_argument(argstr, "tos", cfg->tos, true)) || add_bool_argument(argstr, "duplicate_connect", diff --git a/src/nvme/fabrics.h b/src/nvme/fabrics.h index c130339b15..10ac2e29a5 100644 --- a/src/nvme/fabrics.h +++ b/src/nvme/fabrics.h @@ -22,6 +22,7 @@ * @nr_io_queues: Number of controller IO queues to establish * @reconnect_delay: Time between two consecutive reconnect attempts. * @ctrl_loss_tmo: Override the default controller reconnect attempt timeout in seconds + * @fast_io_fail_tmo: Set the fast I/O fail timeout in seconds. * @keep_alive_tmo: Override the default keep-alive-timeout to this value in seconds * @nr_write_queues: Number of queues to use for exclusively for writing * @nr_poll_queues: Number of queues to reserve for polling completions @@ -36,6 +37,7 @@ struct nvme_fabrics_config { int nr_io_queues; int reconnect_delay; int ctrl_loss_tmo; + int fast_io_fail_tmo; int keep_alive_tmo; int nr_write_queues; int nr_poll_queues; diff --git a/src/nvme/json.c b/src/nvme/json.c index c902a3e92e..307dc7fdb1 100644 --- a/src/nvme/json.c +++ b/src/nvme/json.c @@ -50,6 +50,8 @@ static void json_update_attributes(nvme_ctrl_t c, if (!strcmp("ctrl_loss_tmo", key_str) && cfg->ctrl_loss_tmo != NVMF_DEF_CTRL_LOSS_TMO) cfg->ctrl_loss_tmo = json_object_get_int(val_obj); + JSON_UPDATE_INT_OPTION(cfg, key_str, + fast_io_fail_tmo, val_obj); if (!strcmp("tos", key_str) && cfg->tos != -1) cfg->tos = json_object_get_int(val_obj); JSON_UPDATE_BOOL_OPTION(cfg, key_str, @@ -189,9 +191,11 @@ static void json_update_port(struct json_object *ctrl_array, nvme_ctrl_t c) JSON_INT_OPTION(cfg, port_obj, queue_size, 0); JSON_INT_OPTION(cfg, port_obj, keep_alive_tmo, 0); JSON_INT_OPTION(cfg, port_obj, reconnect_delay, 0); - if (strcmp(transport, "loop")) + if (strcmp(transport, "loop")) { JSON_INT_OPTION(cfg, port_obj, ctrl_loss_tmo, NVMF_DEF_CTRL_LOSS_TMO); + JSON_INT_OPTION(cfg, port_obj, fast_io_fail_tmo, 0); + } JSON_INT_OPTION(cfg, port_obj, tos, -1); JSON_BOOL_OPTION(cfg, port_obj, duplicate_connect); JSON_BOOL_OPTION(cfg, port_obj, disable_sqflow); From f4ad497dae82c8be8f130b31c892635f5428d97c Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 16 Jun 2021 10:06:42 +0200 Subject: [PATCH 0099/1564] tree,fabrics: add 'host_iface' controller option Add a 'host_iface' controller option. Ported from nvme-cli. Signed-off-by: Hannes Reinecke --- examples/discover-loop.c | 3 ++- src/nvme/fabrics.c | 4 +++- src/nvme/json.c | 12 +++++++++--- src/nvme/tree.c | 37 +++++++++++++++++++++++++++---------- src/nvme/tree.h | 14 ++++++++++++-- 5 files changed, 53 insertions(+), 17 deletions(-) diff --git a/examples/discover-loop.c b/examples/discover-loop.c index 37637e24ce..e31e54054a 100644 --- a/examples/discover-loop.c +++ b/examples/discover-loop.c @@ -62,7 +62,8 @@ int main() fprintf(stderr, "Failed to allocated memory\n"); return ENOMEM; } - c = nvme_create_ctrl(NVME_DISC_SUBSYS_NAME, "loop", NULL, NULL, NULL); + c = nvme_create_ctrl(NVME_DISC_SUBSYS_NAME, "loop", + NULL, NULL, NULL, NULL); if (!c) { fprintf(stderr, "Failed to allocate memory\n"); return ENOMEM; diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 6484564443..9a95f32811 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -251,6 +251,8 @@ static int build_options(nvme_ctrl_t c, char **argstr) nvme_ctrl_get_traddr(c)) || add_argument(argstr, "host_traddr", nvme_ctrl_get_host_traddr(c)) || + add_argument(argstr, "host_iface", + nvme_ctrl_get_host_iface(c)) || add_argument(argstr, "trsvcid", nvme_ctrl_get_trsvcid(c)) || (hostnqn && add_argument(argstr, "hostnqn", hostnqn)) || @@ -452,7 +454,7 @@ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, nvme_msg(LOG_DEBUG, "lookup ctrl " "(transport: %s, traddr: %s, trsvcid %s)\n", transport, traddr, trsvcid); - c = nvme_create_ctrl(e->subnqn, transport, traddr, NULL, trsvcid); + c = nvme_create_ctrl(e->subnqn, transport, traddr, NULL, NULL, trsvcid); if (!c) { nvme_msg(LOG_DEBUG, "skipping discovery entry, " "failed to allocate %s controller with traddr %s\n", diff --git a/src/nvme/json.c b/src/nvme/json.c index 307dc7fdb1..d4f2644c63 100644 --- a/src/nvme/json.c +++ b/src/nvme/json.c @@ -73,7 +73,7 @@ static void json_parse_port(nvme_subsystem_t s, struct json_object *port_obj) nvme_ctrl_t c; struct json_object *attr_obj; const char *transport, *traddr = NULL; - const char *host_traddr = NULL, *trsvcid = NULL; + const char *host_traddr = NULL, *host_iface = NULL, *trsvcid = NULL; attr_obj = json_object_object_get(port_obj, "transport"); if (!attr_obj) @@ -85,11 +85,14 @@ static void json_parse_port(nvme_subsystem_t s, struct json_object *port_obj) attr_obj = json_object_object_get(port_obj, "host_traddr"); if (attr_obj) host_traddr = json_object_get_string(attr_obj); + attr_obj = json_object_object_get(port_obj, "host_iface"); + if (attr_obj) + host_iface = json_object_get_string(attr_obj); attr_obj = json_object_object_get(port_obj, "trsvcid"); if (attr_obj) trsvcid = json_object_get_string(attr_obj); - c = nvme_lookup_ctrl(s, transport, traddr, - host_traddr, trsvcid); + c = nvme_lookup_ctrl(s, transport, traddr, host_traddr, + host_iface, trsvcid); if (c) { json_update_attributes(c, port_obj); } @@ -182,6 +185,9 @@ static void json_update_port(struct json_object *ctrl_array, nvme_ctrl_t c) value = nvme_ctrl_get_host_traddr(c); if (value) json_object_add_value_string(port_obj, "host_traddr", value); + value = nvme_ctrl_get_host_iface(c); + if (value) + json_object_add_value_string(port_obj, "host_iface", value); value = nvme_ctrl_get_trsvcid(c); if (value) json_object_add_value_string(port_obj, "trsvcid", value); diff --git a/src/nvme/tree.c b/src/nvme/tree.c index e3ce92b6f6..887c6444b6 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -107,6 +107,7 @@ struct nvme_ctrl { char *traddr; char *trsvcid; char *host_traddr; + char *host_iface; bool discovered; bool persistent; struct nvme_fabrics_config cfg; @@ -693,6 +694,11 @@ const char *nvme_ctrl_get_host_traddr(nvme_ctrl_t c) return c->host_traddr; } +const char *nvme_ctrl_get_host_iface(nvme_ctrl_t c) +{ + return c->host_iface; +} + const char *nvme_ctrl_get_hostnqn(nvme_ctrl_t c) { if (!c->s) @@ -828,6 +834,8 @@ void nvme_free_ctrl(nvme_ctrl_t c) free(c->trsvcid); if (c->host_traddr) free(c->host_traddr); + if (c->host_iface) + free(c->host_iface); free(c->firmware); free(c->model); free(c->state); @@ -911,9 +919,9 @@ void hostname2traddr(nvme_ctrl_t c, const char *host_traddr) freeaddrinfo(host_info); } -struct nvme_ctrl *nvme_create_ctrl(const char *subsysnqn, - const char *transport, const char *traddr, - const char *host_traddr, const char *trsvcid) +struct nvme_ctrl *nvme_create_ctrl(const char *subsysnqn, const char *transport, + const char *traddr, const char *host_traddr, + const char *host_iface, const char *trsvcid) { struct nvme_ctrl *c; bool discovery = false; @@ -947,6 +955,8 @@ struct nvme_ctrl *nvme_create_ctrl(const char *subsysnqn, else c->host_traddr = strdup(host_traddr); } + if (host_iface) + c->host_iface = strdup(host_iface); if (trsvcid) c->trsvcid = strdup(trsvcid); else if (discovery) @@ -962,9 +972,9 @@ struct nvme_ctrl *nvme_create_ctrl(const char *subsysnqn, return c; } -struct nvme_ctrl *nvme_lookup_ctrl(struct nvme_subsystem *s, - const char *transport, const char *traddr, - const char *host_traddr, const char *trsvcid) +struct nvme_ctrl *nvme_lookup_ctrl(struct nvme_subsystem *s, const char *transport, + const char *traddr, const char *host_traddr, + const char *host_iface, const char *trsvcid) { struct nvme_ctrl *c; @@ -979,13 +989,16 @@ struct nvme_ctrl *nvme_lookup_ctrl(struct nvme_subsystem *s, if (host_traddr && c->host_traddr && strcmp(c->host_traddr, host_traddr)) continue; + if (host_iface && c->host_iface && + strcmp(c->host_iface, host_iface)) + continue; if (trsvcid && c->trsvcid && strcmp(c->trsvcid, trsvcid)) continue; return c; } - c = nvme_create_ctrl(s->subsysnqn, transport, - traddr, host_traddr, trsvcid); + c = nvme_create_ctrl(s->subsysnqn, transport, traddr, + host_traddr, host_iface, trsvcid); if (c) { c->s = s; list_add(&s->ctrls, &c->entry); @@ -1122,7 +1135,8 @@ static nvme_ctrl_t nvme_ctrl_alloc(nvme_subsystem_t s, const char *path, { nvme_ctrl_t c; char *addr, *address, *a, *e; - char *transport, *traddr = NULL, *trsvcid = NULL, *host_traddr = NULL; + char *transport, *traddr = NULL, *trsvcid = NULL; + char *host_traddr = NULL, *host_iface = NULL; int ret; transport = nvme_get_attr(path, "transport"); @@ -1141,10 +1155,13 @@ static nvme_ctrl_t nvme_ctrl_alloc(nvme_subsystem_t s, const char *path, trsvcid = a + 8; else if (!strncmp(a, "host_traddr=", 12)) host_traddr = a + 12; + else if (!strncmp(a, "host_iface=", 11)) + host_iface = a + 12; a = strtok_r(NULL, ",", &e); } - c = nvme_lookup_ctrl(s, transport, traddr, host_traddr, trsvcid); + c = nvme_lookup_ctrl(s, transport, traddr, + host_traddr, host_iface, trsvcid); free(addr); if (!c) { errno = ENOMEM; diff --git a/src/nvme/tree.h b/src/nvme/tree.h index 4983bbaec1..e65b1f5095 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -211,13 +211,14 @@ nvme_ctrl_t nvme_subsystem_next_ctrl(nvme_subsystem_t s, nvme_ctrl_t c); * @transport: * @traddr: * @host_traddr: + * @host_iface: * @trsvcid: * * Return: */ nvme_ctrl_t nvme_lookup_ctrl(nvme_subsystem_t s, const char *transport, const char *traddr, const char *host_traddr, - const char *trsvcid); + const char *host_iface, const char *trsvcid); /** @@ -226,13 +227,14 @@ nvme_ctrl_t nvme_lookup_ctrl(nvme_subsystem_t s, const char *transport, * @transport: * @traddr: * @host_traddr: + * @host_iface: * @trsvcid: * * Return: */ nvme_ctrl_t nvme_create_ctrl(const char *subsysnqn, const char *transport, const char *traddr, const char *host_traddr, - const char *trsvcid); + const char *host_iface, const char *trsvcid); /** @@ -783,6 +785,14 @@ const char *nvme_ctrl_get_trsvcid(nvme_ctrl_t c); */ const char *nvme_ctrl_get_host_traddr(nvme_ctrl_t c); +/** + * nvme_ctrl_get_host_iface() - + * @c: + * + * Return: + */ +const char *nvme_ctrl_get_host_iface(nvme_ctrl_t c); + /** * nvme_ctrl_get_config() - * @c: From 1e761cda67c35b09e43aa2895a8ac7edfabf994e Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 16 Jun 2021 17:49:54 +0200 Subject: [PATCH 0100/1564] fabrics,tree: Fixes for PCIe devices PCIe devices do not necessarily have a hostnqn set, so use the default hostnqn when looking up hosts. And for PCIe devices the transport address is the entire 'address' string, no parsing required. Signed-off-by: Hannes Reinecke --- src/nvme/fabrics.c | 4 ++-- src/nvme/tree.c | 43 ++++++++++++++++++++++++------------------- src/nvme/util.c | 11 +++++------ 3 files changed, 31 insertions(+), 27 deletions(-) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 9a95f32811..b59b2efade 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -696,13 +696,13 @@ static char *nvmf_read_file(const char *f, int len) fd = open(f, O_RDONLY); if (fd < 0) - return false; + return NULL; memset(buf, 0, len); ret = read(fd, buf, len - 1); close (fd); - if (ret < 0) + if (ret < 0 || !strlen(buf)) return NULL; return strndup(buf, strcspn(buf, "\n")); } diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 887c6444b6..ceda8198f7 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -155,12 +155,15 @@ nvme_host_t nvme_default_host(nvme_root_t r) char *hostnqn, *hostid; hostnqn = nvmf_hostnqn_from_file(); + if (!hostnqn) + hostnqn = nvmf_hostnqn_generate(); hostid = nvmf_hostid_from_file(); h = nvme_lookup_host(r, hostnqn, hostid); default_host = h; free(hostnqn); - free(hostid); + if (hostid) + free(hostid); return h; } @@ -402,6 +405,8 @@ struct nvme_host *nvme_lookup_host(nvme_root_t r, const char *hostnqn, { struct nvme_host *h; + if (!hostnqn) + return NULL; nvme_for_each_host(r, h) { if (strcmp(h->hostnqn, hostnqn)) continue; @@ -1147,19 +1152,23 @@ static nvme_ctrl_t nvme_ctrl_alloc(nvme_subsystem_t s, const char *path, /* Parse 'address' string into components */ addr = nvme_get_attr(path, "address"); address = strdup(addr); - a = strtok_r(addr, ",", &e); - while (a && strlen(a)) { - if (!strncmp(a, "traddr=", 7)) - traddr = a + 7; - else if (!strncmp(a, "trsvcid=", 8)) - trsvcid = a + 8; - else if (!strncmp(a, "host_traddr=", 12)) - host_traddr = a + 12; - else if (!strncmp(a, "host_iface=", 11)) - host_iface = a + 12; - a = strtok_r(NULL, ",", &e); + if (!strcmp(transport, "pcie")) { + /* The 'address' string is the transport address */ + traddr = address; + } else { + a = strtok_r(addr, ",", &e); + while (a && strlen(a)) { + if (!strncmp(a, "traddr=", 7)) + traddr = a + 7; + else if (!strncmp(a, "trsvcid=", 8)) + trsvcid = a + 8; + else if (!strncmp(a, "host_traddr=", 12)) + host_traddr = a + 12; + else if (!strncmp(a, "host_iface=", 11)) + host_iface = a + 12; + a = strtok_r(NULL, ",", &e); + } } - c = nvme_lookup_ctrl(s, transport, traddr, host_traddr, host_iface, trsvcid); free(addr); @@ -1188,14 +1197,10 @@ nvme_ctrl_t nvme_scan_ctrl(nvme_root_t r, const char *name) } hostnqn = nvme_get_attr(path, "hostnqn"); - if (!hostnqn) { - free(path); - errno = ENODEV; - return NULL; - } hostid = nvme_get_attr(path, "hostid"); h = nvme_lookup_host(r, hostnqn, hostid); - free(hostnqn); + if (hostnqn) + free(hostnqn); if (hostid) free(hostid); if (!h) { diff --git a/src/nvme/util.c b/src/nvme/util.c index 761ae81cf8..fb0d284e90 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -564,7 +564,7 @@ static int __nvme_set_attr(const char *path, const char *value) fd = open(path, O_WRONLY); if (fd < 0) { - nvme_msg(LOG_ERR, "Failed to open %s: %s\n", path, + nvme_msg(LOG_DEBUG, "Failed to open %s: %s\n", path, strerror(errno)); return -1; } @@ -594,14 +594,14 @@ static char *__nvme_get_attr(const char *path) fd = open(path, O_RDONLY); if (fd < 0) { - nvme_msg(LOG_ERR, "Failed to open %s: %s\n", path, + nvme_msg(LOG_DEBUG, "Failed to open %s: %s\n", path, strerror(errno)); return NULL; } ret = read(fd, value, sizeof(value) - 1); - if (ret < 0) { - close(fd); + close(fd); + if (ret < 0 || !strlen(value)) { return NULL; } @@ -610,8 +610,7 @@ static char *__nvme_get_attr(const char *path) while (strlen(value) > 0 && value[strlen(value) - 1] == ' ') value[strlen(value) - 1] = '\0'; - close(fd); - return strdup(value); + return strlen(value) ? strdup(value) : NULL; } char *nvme_get_attr(const char *dir, const char *attr) From c34e21a98f592984899ac94465cf4e37b4de698a Mon Sep 17 00:00:00 2001 From: Klaus Jensen Date: Thu, 17 Jun 2021 10:07:40 +0200 Subject: [PATCH 0101/1564] nvme/fabrics: fix compile error Fix string formatting of the uuid from systemd. Fixes: 8999e3d9b218 ("fabrics: Read system UUID from DMI and merge hostnqn generation functions") Signed-off-by: Klaus Jensen --- src/nvme/fabrics.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index b59b2efade..fb614aacfe 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -657,8 +657,7 @@ static int uuid_from_systemd(char *system_uuid) ret = sd_id128_get_machine_app_specific(NVME_HOSTNQN_ID, &id); if (!ret) - asprintf(systemd_uuid, SD_ID128_FORMAT_STR, - SD_ID128_FORMAT_VAL(id)); + sd_id128_to_string(id, system_uuid); #endif return ret; } From 0618fede3210957eb7e184dcab2f6072645ff0a4 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 17 Jun 2021 09:17:59 +0200 Subject: [PATCH 0102/1564] tree: error checking in nvme_ns_init() The call to 'nvme_ns_identify()' in nvme_ns_init() might fail, leading to a largely unusable namespace. So not continue here, but rather fail the call to nvme_ns_open(). Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index ceda8198f7..653521dab3 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -1477,15 +1477,17 @@ static void nvme_ns_parse_descriptors(struct nvme_ns *n, } } -static void nvme_ns_init(struct nvme_ns *n) +static int nvme_ns_init(struct nvme_ns *n) { struct nvme_id_ns ns = { }; uint8_t buffer[NVME_IDENTIFY_DATA_SIZE] = { }; struct nvme_ns_id_desc *descs = (void *)buffer; int flbas; + int ret; - if (nvme_ns_identify(n, &ns) != 0) - return; + ret = nvme_ns_identify(n, &ns); + if (ret) + return ret; flbas = ns.flbas & NVME_NS_FLBAS_LBA_MASK; n->lba_shift = ns.lbaf[flbas].ds; @@ -1496,6 +1498,8 @@ static void nvme_ns_init(struct nvme_ns *n) if (!nvme_ns_identify_descs(n, descs)) nvme_ns_parse_descriptors(n, descs); + + return 0; } static nvme_ns_t nvme_ns_open(const char *name) @@ -1516,9 +1520,11 @@ static nvme_ns_t nvme_ns_open(const char *name) if (nvme_get_nsid(n->fd, &n->nsid) < 0) goto close_fd; + if (nvme_ns_init(n) != 0) + goto close_fd; + list_head_init(&n->paths); list_node_init(&n->entry); - nvme_ns_init(n); return n; From 6493b6a5be377bf45dce0969636f5dde21dca6b4 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 11 May 2021 15:38:20 +0200 Subject: [PATCH 0103/1564] tree: initialize subsystem in nvme_init_ctrl() nvme_init_ctrl() might be called from a nvme_ctrl with no subsystem set (eg after a connect call). So ensure to re-scan the subsystem to have it fully initialized. Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 653521dab3..99941bac68 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -1096,7 +1096,7 @@ static int __nvme_ctrl_init(nvme_ctrl_t c, const char *path, const char *name) int nvme_init_ctrl(nvme_host_t h, nvme_ctrl_t c, int instance) { nvme_subsystem_t s; - const char *subsys_name; + char *subsys_name = NULL; char *path, *name; int ret; @@ -1128,9 +1128,18 @@ int nvme_init_ctrl(nvme_host_t h, nvme_ctrl_t c, int instance) if (!s) { errno = ENXIO; ret = -1; + } else if (!s->name) { + ret = asprintf(&path, "%s/%s", nvme_subsys_sysfs_dir, + subsys_name); + if (ret > 0) { + ret = nvme_init_subsystem(s, subsys_name, path); + if (ret < 0) + free(path); + } } c->s = s; list_add(&s->ctrls, &c->entry); + free(subsys_name); free(name); return ret; } From e43835c1021ba98152b8dda70c9cc24b7b120276 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Sat, 19 Jun 2021 13:22:28 +0200 Subject: [PATCH 0104/1564] tree: error checking in nvme_init_ctrl() nvme_init_ctrl() is called to initialize a controller after a 'connect' call. As this might fail for a variety of reasons we need to ensure to change the controller state if we need to return an error; this ensures that we can repeat a call to nvme_init_ctrl() after the error causing the failure has been resolved. Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 99941bac68..907d3382ca 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -1107,39 +1107,45 @@ int nvme_init_ctrl(nvme_host_t h, nvme_ctrl_t c, int instance) } ret = asprintf(&path, "%s/nvme%d", nvme_ctrl_sysfs_dir, instance); if (ret < 0) { - free(name); errno = ENOMEM; - return -1; + goto out_free_name; } ret = __nvme_ctrl_init(c, path, name); - if (ret < 0) + if (ret < 0) { free(path); + goto out_free_name; + } c->address = nvme_get_attr(path, "address"); if (!c->address) { free(path); - free(name); - errno = -ENXIO; - return -1; + errno = ENXIO; + ret = -1; + goto out_free_name; } subsys_name = nvme_ctrl_lookup_subsystem_name(c); s = nvme_lookup_subsystem(h, subsys_name, c->subsysnqn); if (!s) { errno = ENXIO; ret = -1; - } else if (!s->name) { + goto out_free_subsys; + } + if (!s->name) { ret = asprintf(&path, "%s/%s", nvme_subsys_sysfs_dir, subsys_name); - if (ret > 0) { + if (ret > 0) ret = nvme_init_subsystem(s, subsys_name, path); - if (ret < 0) - free(path); + if (ret < 0) { + free(path); + goto out_free_subsys; } } c->s = s; list_add(&s->ctrls, &c->entry); +out_free_subsys: free(subsys_name); + out_free_name: free(name); return ret; } From caab3ad0899b914cb2ccad57eaa6b3037f112c9c Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 17 Jun 2021 11:00:58 +0200 Subject: [PATCH 0105/1564] tree: controller subsystem pointer might be NULL The subsystem pointer 's' in the controller structure might be NULL, as the controller is only associated with a subsystem once nvmf_add_ctrl() has been called. Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 907d3382ca..9bd3a14d42 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -582,6 +582,10 @@ static int nvme_ctrl_scan_path(struct nvme_ctrl *c, char *name) char *path, *grpid; int ret; + if (!c->s) { + errno = ENXIO; + return -1; + } ret = asprintf(&path, "%s/%s", c->sysfs_dir, name); if (ret < 0) { errno = ENOMEM; @@ -726,7 +730,8 @@ struct nvme_fabrics_config *nvme_ctrl_get_config(nvme_ctrl_t c) void nvme_ctrl_disable_sqflow(nvme_ctrl_t c, bool disable_sqflow) { c->cfg.disable_sqflow = disable_sqflow; - c->s->h->r->modified = true; + if (c->s && c->s->h && c->s->h->r) + c->s->h->r->modified = true; } void nvme_ctrl_set_discovered(nvme_ctrl_t c, bool discovered) @@ -983,7 +988,7 @@ struct nvme_ctrl *nvme_lookup_ctrl(struct nvme_subsystem *s, const char *transpo { struct nvme_ctrl *c; - if (!transport) + if (!s || !transport) return NULL; nvme_subsystem_for_each_ctrl(s, c) { if (strcmp(c->transport, transport)) @@ -1584,6 +1589,10 @@ static int nvme_ctrl_scan_namespace(struct nvme_ctrl *c, char *name) { struct nvme_ns *n; + if (!c->s) { + errno = EINVAL; + return -1; + } n = __nvme_scan_namespace(c->sysfs_dir, name); if (!n) return -1; From 6682b34384c410eff63e697c643edb2c8308f818 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 5 May 2021 14:35:36 +0200 Subject: [PATCH 0106/1564] tree: move static declarations into private header file Static directory declarations are not part of the libnvme API, so move them into the private header file. Signed-off-by: Hannes Reinecke --- src/nvme/private.h | 4 ++++ src/nvme/tree.h | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/nvme/private.h b/src/nvme/private.h index 3d1a164f51..70b38d451b 100644 --- a/src/nvme/private.h +++ b/src/nvme/private.h @@ -9,6 +9,10 @@ #ifndef _LIBNVME_PRIVATE_H #define _LIBNVME_PRIVATE_H +extern const char *nvme_ctrl_sysfs_dir; +extern const char *nvme_subsys_sysfs_dir; +extern const char *nvme_ns_sysfs_dir; + int nvme_set_attr(const char *dir, const char *attr, const char *value); void json_read_config(nvme_root_t r, const char *config_file); diff --git a/src/nvme/tree.h b/src/nvme/tree.h index e65b1f5095..7228a10ea1 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -20,10 +20,6 @@ #include "ioctl.h" #include "util.h" -extern const char *nvme_ctrl_sysfs_dir; -extern const char *nvme_subsys_sysfs_dir; -extern const char *nvme_ns_sysfs_dir; - /** * */ From f2828b3e34d23356f19d227631c1c579138386c8 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 7 May 2021 15:49:59 +0200 Subject: [PATCH 0107/1564] tree: Move structures to private.h Move generic structures to private.h to avoid having to duplicate definitions in the SWIG interface file. Signed-off-by: Hannes Reinecke --- src/nvme/fabrics.c | 1 + src/nvme/json.c | 1 - src/nvme/private.h | 101 +++++++++++++++++++++++++++++++++++++++++++++ src/nvme/tree.c | 101 --------------------------------------------- 4 files changed, 102 insertions(+), 102 deletions(-) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index fb614aacfe..8b415cf40b 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -27,6 +27,7 @@ #define NVME_HOSTNQN_ID SD_ID128_MAKE(c7,f4,61,81,12,be,49,32,8c,83,10,6f,9d,dd,d8,6b) #endif +#include #include #include "fabrics.h" diff --git a/src/nvme/json.c b/src/nvme/json.c index d4f2644c63..da4f18d3bf 100644 --- a/src/nvme/json.c +++ b/src/nvme/json.c @@ -13,7 +13,6 @@ #include #include "fabrics.h" -#include "private.h" #define json_object_add_value_string(o, k, v) \ json_object_object_add(o, k, json_object_new_string(v)) diff --git a/src/nvme/private.h b/src/nvme/private.h index 70b38d451b..fbda6e226c 100644 --- a/src/nvme/private.h +++ b/src/nvme/private.h @@ -13,6 +13,107 @@ extern const char *nvme_ctrl_sysfs_dir; extern const char *nvme_subsys_sysfs_dir; extern const char *nvme_ns_sysfs_dir; +struct nvme_path { + struct list_node entry; + struct list_node nentry; + + struct nvme_ctrl *c; + struct nvme_ns *n; + + char *name; + char *sysfs_dir; + char *ana_state; + int grpid; +}; + +struct nvme_ns { + struct list_node entry; + struct list_head paths; + + struct nvme_subsystem *s; + struct nvme_ctrl *c; + + int fd; + __u32 nsid; + char *name; + char *sysfs_dir; + + int lba_shift; + int lba_size; + int meta_size; + uint64_t lba_count; + uint64_t lba_util; + + uint8_t eui64[8]; + uint8_t nguid[16]; +#ifdef CONFIG_LIBUUID + uuid_t uuid; +#else + uint8_t uuid[16]; +#endif + enum nvme_csi csi; +}; + +struct nvme_ctrl { + struct list_node entry; + struct list_head paths; + struct list_head namespaces; + + struct nvme_subsystem *s; + + int fd; + char *name; + char *sysfs_dir; + char *address; + char *firmware; + char *model; + char *state; + char *numa_node; + char *queue_count; + char *serial; + char *sqsize; + char *hostnqn; + char *hostid; + char *transport; + char *subsysnqn; + char *traddr; + char *trsvcid; + char *host_traddr; + char *host_iface; + bool discovered; + bool persistent; + struct nvme_fabrics_config cfg; +}; + +struct nvme_subsystem { + struct list_node entry; + struct list_head ctrls; + struct list_head namespaces; + struct nvme_host *h; + + char *name; + char *sysfs_dir; + char *subsysnqn; + char *model; + char *serial; + char *firmware; +}; + +struct nvme_host { + struct list_node entry; + struct list_head subsystems; + struct nvme_root *r; + + char *hostnqn; + char *hostid; +}; + +struct nvme_root { + char *config_file; + struct list_head hosts; + bool modified; +}; + int nvme_set_attr(const char *dir, const char *attr, const char *value); void json_read_config(nvme_root_t r, const char *config_file); diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 9bd3a14d42..777ee9d177 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -41,107 +41,6 @@ static int nvme_subsystem_scan_ctrl(struct nvme_subsystem *s, char *name); static int nvme_ctrl_scan_namespace(struct nvme_ctrl *c, char *name); static int nvme_ctrl_scan_path(struct nvme_ctrl *c, char *name); -struct nvme_path { - struct list_node entry; - struct list_node nentry; - - struct nvme_ctrl *c; - struct nvme_ns *n; - - char *name; - char *sysfs_dir; - char *ana_state; - int grpid; -}; - -struct nvme_ns { - struct list_node entry; - struct list_head paths; - - struct nvme_subsystem *s; - struct nvme_ctrl *c; - - int fd; - __u32 nsid; - char *name; - char *sysfs_dir; - - int lba_shift; - int lba_size; - int meta_size; - uint64_t lba_count; - uint64_t lba_util; - - uint8_t eui64[8]; - uint8_t nguid[16]; -#ifdef CONFIG_LIBUUID - uuid_t uuid; -#else - uint8_t uuid[16]; -#endif - enum nvme_csi csi; -}; - -struct nvme_ctrl { - struct list_node entry; - struct list_head paths; - struct list_head namespaces; - - struct nvme_subsystem *s; - - int fd; - char *name; - char *sysfs_dir; - char *address; - char *firmware; - char *model; - char *state; - char *numa_node; - char *queue_count; - char *serial; - char *sqsize; - char *hostnqn; - char *hostid; - char *transport; - char *subsysnqn; - char *traddr; - char *trsvcid; - char *host_traddr; - char *host_iface; - bool discovered; - bool persistent; - struct nvme_fabrics_config cfg; -}; - -struct nvme_subsystem { - struct list_node entry; - struct list_head ctrls; - struct list_head namespaces; - struct nvme_host *h; - - char *name; - char *sysfs_dir; - char *subsysnqn; - char *model; - char *serial; - char *firmware; -}; - -struct nvme_host { - struct list_node entry; - struct list_head subsystems; - struct nvme_root *r; - - char *hostnqn; - char *hostid; -}; - -struct nvme_root { - char *config_file; - struct list_head hosts; - bool modified; -}; - static inline void nvme_free_dirents(struct dirent **d, int i) { while (i-- > 0) From 25825a26f7485d7b3c25461e568c8571f6651c56 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 11 May 2021 12:30:47 +0200 Subject: [PATCH 0108/1564] tree: add refcounting for objects Each object can be referenced multiple times, so add reference counting for hosts, subsystems, and controllers. Signed-off-by: Hannes Reinecke --- src/nvme/private.h | 5 ++++- src/nvme/tree.c | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/nvme/private.h b/src/nvme/private.h index fbda6e226c..b6bdfa2522 100644 --- a/src/nvme/private.h +++ b/src/nvme/private.h @@ -58,8 +58,8 @@ struct nvme_ctrl { struct list_node entry; struct list_head paths; struct list_head namespaces; - struct nvme_subsystem *s; + int refcount; int fd; char *name; @@ -90,6 +90,7 @@ struct nvme_subsystem { struct list_head ctrls; struct list_head namespaces; struct nvme_host *h; + int refcount; char *name; char *sysfs_dir; @@ -103,6 +104,7 @@ struct nvme_host { struct list_node entry; struct list_head subsystems; struct nvme_root *r; + int refcount; char *hostnqn; char *hostid; @@ -111,6 +113,7 @@ struct nvme_host { struct nvme_root { char *config_file; struct list_head hosts; + int refcount; bool modified; }; diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 777ee9d177..a75e914ca7 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -239,6 +239,9 @@ static void nvme_free_subsystem(struct nvme_subsystem *s) struct nvme_ctrl *c, *_c; struct nvme_ns *n, *_n; + if (--s->refcount > 0) + return; + list_del_init(&s->entry); nvme_subsystem_for_each_ctrl_safe(s, c, _c) nvme_free_ctrl(c); @@ -270,6 +273,7 @@ struct nvme_subsystem *nvme_lookup_subsystem(struct nvme_host *h, if (name && s->name && strcmp(s->name, name)) continue; + s->refcount++; return s; } s = calloc(1, sizeof(*s)); @@ -278,6 +282,7 @@ struct nvme_subsystem *nvme_lookup_subsystem(struct nvme_host *h, s->h = h; s->subsysnqn = strdup(subsysnqn); + s->refcount = 1; list_head_init(&s->ctrls); list_head_init(&s->namespaces); list_add(&h->subsystems, &s->entry); @@ -289,6 +294,8 @@ static void nvme_free_host(struct nvme_host *h) { struct nvme_subsystem *s, *_s; + if (--h->refcount > 0) + return; list_del_init(&h->entry); nvme_for_each_subsystem_safe(h, s, _s) nvme_free_subsystem(s); @@ -312,6 +319,7 @@ struct nvme_host *nvme_lookup_host(nvme_root_t r, const char *hostnqn, if (hostid && strcmp(h->hostid, hostid)) continue; + h->refcount++; return h; } h = calloc(1,sizeof(*h)); @@ -323,6 +331,7 @@ struct nvme_host *nvme_lookup_host(nvme_root_t r, const char *hostnqn, list_head_init(&h->subsystems); list_node_init(&h->entry); h->r = r; + h->refcount = 1; list_add(&r->hosts, &h->entry); r->modified = true; @@ -721,6 +730,9 @@ void nvme_free_ctrl(nvme_ctrl_t c) struct nvme_path *p, *_p; struct nvme_ns *n, *_n; + if (--c->refcount > 0) + return; + nvme_unlink_ctrl(c); nvme_ctrl_for_each_path_safe(c, p, _p) @@ -904,12 +916,14 @@ struct nvme_ctrl *nvme_lookup_ctrl(struct nvme_subsystem *s, const char *transpo if (trsvcid && c->trsvcid && strcmp(c->trsvcid, trsvcid)) continue; + c->refcount++; return c; } c = nvme_create_ctrl(s->subsysnqn, transport, traddr, host_traddr, host_iface, trsvcid); if (c) { c->s = s; + c->refcount = 1; list_add(&s->ctrls, &c->entry); s->h->r->modified = true; } From f18c7288bc12fa98bab1a581994ef7e29ddd6511 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 7 May 2021 16:54:19 +0200 Subject: [PATCH 0109/1564] tree: add nvme_rescan_ctrl() Add a function to rescan a controller eg after receiving an AEN. Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 9 +++++++++ src/nvme/tree.h | 6 ++++++ 2 files changed, 15 insertions(+) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index a75e914ca7..49b2b18ab2 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -1185,6 +1185,15 @@ static int nvme_subsystem_scan_ctrl(struct nvme_subsystem *s, char *name) return 0; } +void nvme_rescan_ctrl(struct nvme_ctrl *c) +{ + if (!c->s) + return; + nvme_subsystem_scan_namespaces(c->s); + nvme_ctrl_scan_namespaces(c); + nvme_ctrl_scan_paths(c); +} + static int nvme_bytes_to_lba(nvme_ns_t n, off_t offset, size_t count, __u64 *lba, __u16 *nlb) { diff --git a/src/nvme/tree.h b/src/nvme/tree.h index 7228a10ea1..719dbbfbc0 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -865,6 +865,12 @@ int nvme_ctrl_disconnect(nvme_ctrl_t c); */ nvme_ctrl_t nvme_scan_ctrl(nvme_root_t r, const char *name); +/** + * @c: + * + */ +void nvme_rescan_ctrl(nvme_ctrl_t c); + /** * nvme_init_ctrl() - * @h: From 7b42640fd58a2e8d63732f46634bc08f1297a6a1 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 17 Jun 2021 09:50:32 +0200 Subject: [PATCH 0110/1564] tree: export nvme_free_host() Required for SWIG interface. Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 3 +-- src/nvme/tree.h | 6 ++++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 49b2b18ab2..09c8084477 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -32,7 +32,6 @@ static struct nvme_host *default_host; -static void nvme_free_host(struct nvme_host *h); static void nvme_free_subsystem(struct nvme_subsystem *s); static int nvme_subsystem_scan_namespace(struct nvme_subsystem *s, char *name); static int nvme_scan_subsystem(struct nvme_host *h, char *name, @@ -290,7 +289,7 @@ struct nvme_subsystem *nvme_lookup_subsystem(struct nvme_host *h, return s; } -static void nvme_free_host(struct nvme_host *h) +void nvme_free_host(struct nvme_host *h) { struct nvme_subsystem *s, *_s; diff --git a/src/nvme/tree.h b/src/nvme/tree.h index 719dbbfbc0..299bbc87e8 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -949,6 +949,12 @@ const char *nvme_host_get_hostid(nvme_host_t h); */ nvme_host_t nvme_default_host(nvme_root_t r); +/** + * nvme_free_host() - + * @r: + */ +void nvme_free_host(nvme_host_t h); + /** * nvme_scan() - * @config_file: From 00ffc522c90a6a2924fcf04ec63f0cc4d4edef61 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 17 Jun 2021 09:50:32 +0200 Subject: [PATCH 0111/1564] tree: export nvme_free_subsystem() Required for SWIG interface. Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 3 +-- src/nvme/tree.h | 6 ++++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 09c8084477..bb24465d86 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -32,7 +32,6 @@ static struct nvme_host *default_host; -static void nvme_free_subsystem(struct nvme_subsystem *s); static int nvme_subsystem_scan_namespace(struct nvme_subsystem *s, char *name); static int nvme_scan_subsystem(struct nvme_host *h, char *name, nvme_scan_filter_t f); @@ -233,7 +232,7 @@ void nvme_free_ns(struct nvme_ns *n) free(n); } -static void nvme_free_subsystem(struct nvme_subsystem *s) +void nvme_free_subsystem(struct nvme_subsystem *s) { struct nvme_ctrl *c, *_c; struct nvme_ns *n, *_n; diff --git a/src/nvme/tree.h b/src/nvme/tree.h index 299bbc87e8..ac45e3936f 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -142,6 +142,12 @@ nvme_subsystem_t nvme_lookup_subsystem(struct nvme_host *h, const char *name, const char *subsysnqn); +/** + * nvme_free_subsystem() - + * @s: + */ +void nvme_free_subsystem(struct nvme_subsystem *s); + /** * nvme_subsystem_get_host() - * @s: From 52bd7bd29b48388b54b831b4a70607320c058c36 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 7 May 2021 17:13:22 +0200 Subject: [PATCH 0112/1564] tree: rename nvme_disconnect_ctrl() Rename nvme_ctrl_disconnect() to nvme_disconnect_ctrl() to avoid name clash with SWIG generated interface files. Signed-off-by: Hannes Reinecke --- examples/discover-loop.c | 2 +- src/nvme/tree.c | 2 +- src/nvme/tree.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/discover-loop.c b/examples/discover-loop.c index e31e54054a..599edd2057 100644 --- a/examples/discover-loop.c +++ b/examples/discover-loop.c @@ -75,7 +75,7 @@ int main() } ret = nvmf_get_discovery_log(c, &log, 4); - nvme_ctrl_disconnect(c); + nvme_disconnect_ctrl(c); nvme_free_ctrl(c); if (ret) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index bb24465d86..e118be5291 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -687,7 +687,7 @@ nvme_path_t nvme_ctrl_next_path(nvme_ctrl_t c, nvme_path_t p) #define FREE_CTRL_ATTR(a) \ do { if (a) { free(a); (a) = NULL; } } while (0) -int nvme_ctrl_disconnect(nvme_ctrl_t c) +int nvme_disconnect_ctrl(nvme_ctrl_t c) { int ret; diff --git a/src/nvme/tree.h b/src/nvme/tree.h index ac45e3936f..c19b11389e 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -856,12 +856,12 @@ void nvme_ctrl_disable_sqflow(nvme_ctrl_t c, bool disable_sqflow); int nvme_ctrl_identify(nvme_ctrl_t c, struct nvme_id_ctrl *id); /** - * nvme_ctrl_disconnect() - + * nvme_disconnect_ctrl() - * @c: * * Return: */ -int nvme_ctrl_disconnect(nvme_ctrl_t c); +int nvme_disconnect_ctrl(nvme_ctrl_t c); /** * nvme_scan_ctrl() - From a43489eb597684160f6e76ed841af734ec95da7d Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 11 May 2021 17:59:20 +0200 Subject: [PATCH 0113/1564] tree: re-read 'state' attribute The 'state' attribute might change at any time, so we need to update it upon access. Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index e118be5291..56cb733350 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -566,6 +566,11 @@ const char *nvme_ctrl_get_model(nvme_ctrl_t c) const char *nvme_ctrl_get_state(nvme_ctrl_t c) { + char *state = c->state; + + c->state = nvme_get_ctrl_attr(c, "state"); + if (state) + free(state); return c->state; } From c6cbf0e6b1ffe2a9ac13a148e3543eec41c04424 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 6 May 2021 08:19:32 +0200 Subject: [PATCH 0114/1564] Add SWIG interface generator files Add files to generate a python binding via SWIG. Signed-off-by: Hannes Reinecke --- Makefile | 3 + src/Makefile | 11 + src/nvme/libnvme.i | 515 +++++++++++++++++++++++++++++++++++++++++++++ src/setup.py | 14 ++ 4 files changed, 543 insertions(+) create mode 100644 src/nvme/libnvme.i create mode 100644 src/setup.py diff --git a/Makefile b/Makefile index a4dbd7dfaf..2dd7137a9f 100644 --- a/Makefile +++ b/Makefile @@ -8,6 +8,9 @@ INSTALL=install default: all +python: all + @$(MAKE) -C src python + all: $(NAME).pc @$(MAKE) -C src @$(MAKE) -C test diff --git a/src/Makefile b/src/Makefile index 19361f89ff..c07d1fe29a 100644 --- a/src/Makefile +++ b/src/Makefile @@ -49,6 +49,7 @@ $(libccan_objs) $(libccan_sobjs): $(libccan_headers) $(CCANDIR)config.h libnvme_priv := nvme/private.h libnvme_api := libnvme.h nvme/types.h nvme/ioctl.h nvme/filters.h nvme/tree.h nvme/util.h nvme/fabrics.h libnvme_srcs := nvme/ioctl.c nvme/filters.c nvme/fabrics.c nvme/util.c nvme/tree.c nvme/log.c nvme/cleanup.c +libnvme_swig := nvme/libnvme.i ifneq ($(CONFIG_JSONC),0) override libnvme_srcs += nvme/json.c endif @@ -65,6 +66,9 @@ $(libnvme_objs) $(libnvme_sobjs): $(libnvme_api) $(libnvme_private) $(libccan_ob AR ?= ar RANLIB ?= ranlib +SWIG ?= swig +PYTHON ?= python3 + libnvme.a: $(libnvme_objs) $(libccan_objs) @rm -f libnvme.a $(QUIET_AR)$(AR) r libnvme.a $^ @@ -73,6 +77,12 @@ libnvme.a: $(libnvme_objs) $(libccan_objs) $(libname): $(libnvme_sobjs) $(libccan_sobjs) libnvme.map $(QUIET_CC)$(CC) $(SO_CFLAGS) -Wl,--version-script=libnvme.map -Wl,-soname=$(soname) -o $@ $(libnvme_sobjs) $(libccan_sobjs) $(LINK_FLAGS) +libnvme_wrap.c: $(libnvme_swig) + $(SWIG) -python -py3 -outdir . $< + +python: libnvme_wrap.c setup.py + $(PYTHON) setup.py build + install: $(all_targets) $(INSTALL) -D -m 644 libnvme.a $(libdir)/libnvme.a for i in $(libnvme_api); do $(INSTALL) -D -m 644 $$i $(includedir)/$$i; done @@ -89,4 +99,5 @@ clean: rm -f $(all_targets) $(libnvme_objs) $(libnvme_sobjs) $(libccan_objs) $(libccan_sobjs) $(soname).new rm -f $(CCANDIR)config.h rm -f $(CCANDIR)tools/configurator/configurator + rm -f libnvme_wrap.c rm -f *.so* *.a *.o diff --git a/src/nvme/libnvme.i b/src/nvme/libnvme.i new file mode 100644 index 0000000000..25eddb4461 --- /dev/null +++ b/src/nvme/libnvme.i @@ -0,0 +1,515 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/* + * This file is part of libnvme. + * Copyright (c) 2021 SUSE Software Solutions + * + * Authors: Hannes Reinecke + */ + +%module libnvme + +%include "exception.i" + +%allowexception; + +%{ +#include +#include +#include "tree.h" +#include "fabrics.h" +#include "private.h" + +static int host_iter_err = 0; +static int subsys_iter_err = 0; +static int ctrl_iter_err = 0; +static int ns_iter_err = 0; +static int connect_err = 0; +static int discover_err = 0; +%} + +%inline %{ + struct nvme_host_iter { + struct nvme_root *root; + struct nvme_host *pos; + }; + + struct nvme_subsystem_iter { + struct nvme_host *host; + struct nvme_subsystem *pos; + }; + + struct nvme_ctrl_iter { + struct nvme_subsystem *subsystem; + struct nvme_ctrl *pos; + }; + + struct nvme_ns_iter { + struct nvme_subsystem *subsystem; + struct nvme_ctrl *ctrl; + struct nvme_ns *pos; + }; +%} + +%exception nvme_host_iter::__next__ { + assert(!host_iter_err); + $action + if (host_iter_err) { + host_iter_err = 0; + PyErr_SetString(PyExc_StopIteration, "End of list"); + return NULL; + } +} + +%exception nvme_subsystem_iter::__next__ { + assert(!subsys_iter_err); + $action + if (subsys_iter_err) { + subsys_iter_err = 0; + PyErr_SetString(PyExc_StopIteration, "End of list"); + return NULL; + } +} + +%exception nvme_ctrl_iter::__next__ { + assert(!ctrl_iter_err); + $action + if (ctrl_iter_err) { + ctrl_iter_err = 0; + PyErr_SetString(PyExc_StopIteration, "End of list"); + return NULL; + } +} + +%exception nvme_ns_iter::__next__ { + assert(!ns_iter_err); + $action + if (ns_iter_err) { + ns_iter_err = 0; + PyErr_SetString(PyExc_StopIteration, "End of list"); + return NULL; + } +} + +%exception nvme_ctrl::connect { + $action + if (connect_err == 1) { + connect_err = 0; + SWIG_exception(SWIG_AttributeError, "Existing controller connection"); + } else if (connect_err) { + connect_err = 0; + SWIG_exception(SWIG_RuntimeError, "Connect failed"); + } +} + +%exception nvme_ctrl::discover { + $action + if (discover_err) { + discover_err = 0; + SWIG_exception(SWIG_RuntimeError,"Discover failed"); + } +} + +#include "tree.h" +#include "fabrics.h" + +%typemap(in) struct nvme_fabrics_config * ($*1_type temp) { + Py_ssize_t pos = 0; + PyObject *key, *value; + char *keystr; + memset(&temp, 0, sizeof(struct nvme_fabrics_config)); + temp.tos = -1; + temp.ctrl_loss_tmo = NVMF_DEF_CTRL_LOSS_TMO; + while (PyDict_Next($input, &pos, &key, &value)) { + keystr = PyString_AsString(key); + if (!keystr) + continue; + if (!strcmp(keystr, "nr_io_queues")) + temp.nr_io_queues = PyLong_AsLong(value); + if (!strcmp(keystr, "reconnect_delay")) + temp.reconnect_delay = PyLong_AsLong(value); + if (!strcmp(keystr, "ctrl_loss_tmo")) + temp.ctrl_loss_tmo = PyLong_AsLong(value); + if (!strcmp(keystr, "keep_alive_tmo")) + temp.keep_alive_tmo = PyLong_AsLong(value); + if (!strcmp(keystr, "nr_write_queues")) + temp.nr_write_queues = PyLong_AsLong(value); + if (!strcmp(keystr, "nr_poll_queues")) + temp.nr_poll_queues = PyLong_AsLong(value); + if (!strcmp(keystr, "tos")) + temp.tos = PyLong_AsLong(value); + if (!strcmp(keystr, "duplicate_connect")) + temp.duplicate_connect = PyLong_AsLong(value); + if (!strcmp(keystr, "disable_sqflow")) + temp.disable_sqflow = PyLong_AsLong(value); + if (!strcmp(keystr, "hdr_digest")) + temp.hdr_digest = PyLong_AsLong(value); + if (!strcmp(keystr, "data_digest")) + temp.data_digest = PyLong_AsLong(value); + } + $1 = &temp; + }; + +%typemap(out) uint8_t [8] { + $result = PyBytes_FromStringAndSize((char *)$1, 8); +}; + +%typemap(out) uint8_t [16] { + $result = PyBytes_FromStringAndSize((char *)$1, 16); +}; + +%typemap(out) struct nvmf_discovery_log * { + struct nvmf_discovery_log *log = $1; + int numrec = log? log->numrec : 0, i; + PyObject *obj = PyList_New(numrec); + if (!obj) + return NULL; + for (i = 0; i < numrec; i++) { + struct nvmf_disc_log_entry *e = &log->entries[i]; + PyObject *entry = PyDict_New(), *val; + + val = PyLong_FromLong(e->trtype); + PyDict_SetItemString(entry, "trtype", val); + val = PyLong_FromLong(e->adrfam); + PyDict_SetItemString(entry, "adrfam", val); + val = PyUnicode_FromString(e->traddr); + PyDict_SetItemString(entry, "traddr", val); + val = PyUnicode_FromString(e->trsvcid); + PyDict_SetItemString(entry, "trsvcid", val); + val = PyUnicode_FromString(e->subnqn); + PyDict_SetItemString(entry, "subnqn", val); + val = PyLong_FromLong(e->subtype); + PyDict_SetItemString(entry, "subtype", val); + val = PyLong_FromLong(e->treq); + PyDict_SetItemString(entry, "treq", val); + val = PyLong_FromLong(e->portid); + PyDict_SetItemString(entry, "portid", val); + val = PyLong_FromLong(e->cntlid); + PyDict_SetItemString(entry, "cntlid", val); + val = PyLong_FromLong(e->asqsz); + PyDict_SetItemString(entry, "asqsz", val); + PyList_SetItem(obj, i, entry); + } + $result = obj; + }; +struct nvme_root { + %immutable config_file; + char *config_file; +}; + +struct nvme_host { + %immutable hostnqn; + %immutable hostid; + char *hostnqn; + char *hostid; +}; + +struct nvme_subsystem { + %immutable subsysnqn; + %immutable model; + %immutable serial; + %immutable firmware; + char *subsysnqn; + char *model; + char *serial; + char *firmware; +}; + +struct nvme_ctrl { + %immutable transport; + %immutable subsysnqn; + %immutable traddr; + %immutable host_traddr; + %immutable trsvcid; + %immutable address; + %immutable firmware; + %immutable model; + %immutable numa_node; + %immutable queue_count; + %immutable serial; + %immutable sqsize; + char *transport; + char *subsysnqn; + char *traddr; + char *host_traddr; + char *trsvcid; + char *address; + char *firmware; + char *model; + char *numa_node; + char *queue_count; + char *serial; + char *sqsize; +}; + +struct nvme_ns { + %immutable nsid; + %immutable eui64; + %immutable nguid; + %immutable uuid; + unsigned int nsid; + uint8_t eui64[8]; + uint8_t nguid[16]; + uint8_t uuid[16]; +}; + +%extend nvme_root { + nvme_root(const char *config_file = NULL) { + return nvme_scan(config_file); + } + ~nvme_root() { + nvme_free_tree($self); + } + struct nvme_host *hosts() { + return nvme_first_host($self); + } + void refresh_topology() { + nvme_refresh_topology($self); + } + void update_config() { + nvme_update_config($self); + } +} + +%extend nvme_host_iter { + struct nvme_host_iter *__iter__() { + return $self; + } + struct nvme_host *__next__() { + struct nvme_host *this = $self->pos; + + if (!this) { + host_iter_err = 1; + return NULL; + } + $self->pos = nvme_next_host($self->root, this); + return this; + } +} + +%extend nvme_host { + nvme_host(struct nvme_root *r, const char *hostnqn = NULL, + const char *hostid = NULL) { + if (!hostnqn) + return nvme_default_host(r); + return nvme_lookup_host(r, hostnqn, hostid); + } + ~nvme_host() { + nvme_free_host($self); + } + char *__str__() { + static char tmp[2048]; + + sprintf(tmp, "nvme_host(%s,%s)", $self->hostnqn, $self->hostid); + return tmp; + } + struct nvme_host_iter __iter__() { + struct nvme_host_iter ret = { .root = nvme_host_get_root($self), + .pos = $self }; + return ret; + } + struct nvme_subsystem *subsystems() { + return nvme_first_subsystem($self); + } +} + +%extend nvme_subsystem_iter { + struct nvme_subsystem_iter *__iter__() { + return $self; + } + struct nvme_subsystem *__next__() { + struct nvme_subsystem *this = $self->pos; + + if (!this) { + subsys_iter_err = 1; + return NULL; + } + $self->pos = nvme_next_subsystem($self->host, this); + return this; + } +} + +%extend nvme_ns_iter { + struct nvme_ns_iter *__iter__() { + return $self; + } + struct nvme_ns *__next__() { + struct nvme_ns *this = $self->pos; + + if (!this) { + ns_iter_err = 1; + return NULL; + } + if ($self->ctrl) + $self->pos = nvme_ctrl_next_ns($self->ctrl, this); + else + $self->pos = nvme_subsystem_next_ns($self->subsystem, this); + return this; + } +} + +%extend nvme_subsystem { + nvme_subsystem(struct nvme_host *host, const char *subsysnqn, + const char *name = NULL) { + return nvme_lookup_subsystem(host, name, subsysnqn); + } + ~nvme_subsystem() { + nvme_free_subsystem($self); + } + char *__str__() { + static char tmp[1024]; + + sprintf(tmp, "nvme_subsystem(%s,%s)", $self->name,$self->subsysnqn); + return tmp; + } + struct nvme_subsystem_iter __iter__() { + struct nvme_subsystem_iter ret = { .host = nvme_subsystem_get_host($self), + .pos = $self }; + return ret; + } + struct nvme_ctrl *controllers() { + return nvme_subsystem_first_ctrl($self); + } + struct nvme_ns *namespaces() { + return nvme_subsystem_first_ns($self); + } + %immutable name; + const char *name; + %immutable host; + struct nvme_host *host; +} + +%{ + const char *nvme_subsystem_name_get(struct nvme_subsystem *s) { + return nvme_subsystem_get_name(s); + } + struct nvme_host *nvme_subsystem_host_get(struct nvme_subsystem *s) { + return nvme_subsystem_get_host(s); + } +%}; + +%extend nvme_ctrl_iter { + struct nvme_ctrl_iter *__iter__() { + return $self; + } + struct nvme_ctrl *__next__() { + struct nvme_ctrl *this = $self->pos; + + if (!this) { + ctrl_iter_err = 1; + return NULL; + } + $self->pos = nvme_subsystem_next_ctrl($self->subsystem, this); + return this; + } +} + +%extend nvme_ctrl { + nvme_ctrl(const char *subsysnqn, const char *transport, + const char *traddr = NULL, const char *host_traddr = NULL, + const char *host_iface = NULL, const char *trsvcid = NULL) { + return nvme_create_ctrl(subsysnqn, transport, traddr, + host_traddr, host_iface, trsvcid); + } + ~nvme_ctrl() { + nvme_free_ctrl($self); + } + void connect(struct nvme_host *h, struct nvme_fabrics_config *cfg = NULL) { + int ret; + const char *dev; + + dev = nvme_ctrl_get_name($self); + if (dev && !cfg->duplicate_connect) { + connect_err = 1; + return; + } + ret = nvmf_add_ctrl(h, $self, cfg, cfg->disable_sqflow); + if (ret < 0) { + connect_err = 2; + return; + } + } + bool connected() { + return nvme_ctrl_get_name($self) != NULL; + } + void rescan() { + nvme_rescan_ctrl($self); + } + void disconnect() { + nvme_disconnect_ctrl($self); + } + struct nvmf_discovery_log *discover(int max_retries = 6) { + struct nvmf_discovery_log *logp = NULL; + int ret = 0; + ret = nvmf_get_discovery_log($self, &logp, max_retries); + if (ret < 0) { + discover_err = 1; + return NULL; + } + return logp; + } + char *__str__() { + static char tmp[1024]; + + if ($self->address) + sprintf(tmp, "nvme_ctrl(transport=%s,%s)", $self->transport, + $self->address); + else + sprintf(tmp, "nvme_ctrl(transport=%s)", $self->transport); + return tmp; + } + struct nvme_ctrl_iter __iter__() { + struct nvme_ctrl_iter ret = { .subsystem = nvme_ctrl_get_subsystem($self), + .pos = $self }; + return ret; + } + struct nvme_ns *namespaces() { + return nvme_ctrl_first_ns($self); + } + %immutable name; + const char *name; + %immutable subsystem; + struct nvme_subsystem *subsystem; + %immutable state; + const char *state; +} + +%{ + const char *nvme_ctrl_name_get(struct nvme_ctrl *c) { + return nvme_ctrl_get_name(c); + } + struct nvme_subsystem *nvme_ctrl_subsystem_get(struct nvme_ctrl *c) { + return nvme_ctrl_get_subsystem(c); + } + const char *nvme_ctrl_state_get(struct nvme_ctrl *c) { + return nvme_ctrl_get_state(c); + } +%}; + +%extend nvme_ns { + nvme_ns(struct nvme_subsystem *s, unsigned int nsid) { + return nvme_subsystem_lookup_namespace(s, nsid); + } + ~nvme_ns() { + nvme_free_ns($self); + } + char *__str__() { + static char tmp[1024]; + + sprintf(tmp, "nvme_ns(%u)", $self->nsid); + return tmp; + } + struct nvme_ns_iter __iter__() { + struct nvme_ns_iter ret = { .ctrl = nvme_ns_get_ctrl($self), + .subsystem = nvme_ns_get_subsystem($self), + .pos = $self }; + return ret; + } + %immutable name; + const char *name; +} + +%{ + const char *nvme_ns_name_get(struct nvme_ns *n) { + return nvme_ns_get_name(n); + } +%}; diff --git a/src/setup.py b/src/setup.py new file mode 100644 index 0000000000..028eec8932 --- /dev/null +++ b/src/setup.py @@ -0,0 +1,14 @@ +from distutils.core import setup, Extension + +libnvme_module = Extension('_libnvme', + sources=['nvme/libnvme_wrap.c'], + libraries=['nvme', 'json-c', 'uuid', 'systemd'], library_dirs=['./'], + include_dirs = ['../ccan','nvme']) + +setup(name='libnvme', + author="Hannes Reinecke", + author_email='hare@suse.de', + description='python bindings for libnvme', + ext_modules=[libnvme_module], + py_modules=["libnvme"], +) From fe948f082f61db7e697901dc0af8ec4304bedb5d Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 11 May 2021 17:27:58 +0200 Subject: [PATCH 0115/1564] examples/discover-loop.py: python example for nvme discovery Add an example script on how nvme discovery can be done with the libnvme python binding. Signed-off-by: Hannes Reinecke --- examples/discover-loop.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 examples/discover-loop.py diff --git a/examples/discover-loop.py b/examples/discover-loop.py new file mode 100644 index 0000000000..4582e6a9fb --- /dev/null +++ b/examples/discover-loop.py @@ -0,0 +1,35 @@ +#!/usr/bin/python3 +''' +Example script for nvme discovery + +Copyright (c) 2021 Hannes Reinecke, SUSE Software Solutions +Licensed under the Apache License, Version 2.0 (the "License"); you may +not use this file except in compliance with the License. You may obtain +a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +License for the specific language governing permissions and limitations +under the License. +''' + +import libnvme +r = libnvme.nvme_root() +h = libnvme.nvme_host(r) +c = libnvme.nvme_ctrl('nqn.2014-08.org.nvmexpress.discovery','loop') +try: + c.connect(h) +except: + sys.exit("Failed to connect!") + +print("connected to %s subsys %s" % (c.name, c.subsystem.name)) +try: + d = c.discover() + print (d) +except: + print("Failed to discover!") + pass +c.disconnect() From c3759fcf96281a7f1f79a5cb7f045d4e8ff377c4 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 17 Jun 2021 13:08:20 +0200 Subject: [PATCH 0116/1564] test/tree.py: add test script for the python binding Add a simple test script for the python binding which just prints out details about the NVMe subsystem. Signed-off-by: Hannes Reinecke --- test/tree.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 test/tree.py diff --git a/test/tree.py b/test/tree.py new file mode 100644 index 0000000000..626a0aaf87 --- /dev/null +++ b/test/tree.py @@ -0,0 +1,23 @@ +#!/usr/bin/python3 +''' +SPDX-License-Identifier: LGPL-3.1-or-later + +This file is part of libnvme. +Copyright (c) 2021 SUSE Software Solutions AG + +Authors: Hannes Reinecke + +Scans the NVMe subsystem and prints out all found hosts, +subsystems, and controllers +''' + +import libnvme + +r = libnvme.nvme_root() +for h in r.hosts(): + print (h) + for s in h.subsystems(): + print (s) + for c in s.controllers(): + print (c) + From 7254cdd67def84200567e93b6343ddc9dd5f10bd Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 21 Jun 2021 17:09:27 +0200 Subject: [PATCH 0117/1564] tree: check hostnqn and hostid when scanning topology Newer kernel versions will display the hostnqn and hostid in sysfs attributes, so we should be using them to find the host structure instead of the default host. Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 56cb733350..f964772d24 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -33,7 +33,7 @@ static struct nvme_host *default_host; static int nvme_subsystem_scan_namespace(struct nvme_subsystem *s, char *name); -static int nvme_scan_subsystem(struct nvme_host *h, char *name, +static int nvme_scan_subsystem(struct nvme_root *r, char *name, nvme_scan_filter_t f); static int nvme_subsystem_scan_ctrl(struct nvme_subsystem *s, char *name); static int nvme_ctrl_scan_namespace(struct nvme_ctrl *c, char *name); @@ -66,22 +66,15 @@ nvme_host_t nvme_default_host(nvme_root_t r) static int nvme_scan_topology(struct nvme_root *r, nvme_scan_filter_t f) { - struct nvme_host *h; struct dirent **subsys; int i, ret; - h = nvme_default_host(r); - if (!h) { - free(r); - errno = ENOMEM; - return -1; - } ret = nvme_scan_subsystems(&subsys); if (ret < 0) return ret; for (i = 0; i < ret; i++) - nvme_scan_subsystem(h, subsys[i]->d_name, f); + nvme_scan_subsystem(r, subsys[i]->d_name, f); nvme_free_dirents(subsys, i); return 0; @@ -384,17 +377,33 @@ static int nvme_init_subsystem(nvme_subsystem_t s, const char *name, return 0; } -static int nvme_scan_subsystem(struct nvme_host *h, char *name, +static int nvme_scan_subsystem(struct nvme_root *r, char *name, nvme_scan_filter_t f) { struct nvme_subsystem *s; char *path, *subsysnqn; + char *hostnqn, *hostid = NULL; + nvme_host_t h = NULL; int ret; ret = asprintf(&path, "%s/%s", nvme_subsys_sysfs_dir, name); if (ret < 0) return ret; + hostnqn = nvme_get_attr(path, "hostnqn"); + if (hostnqn) { + hostid = nvme_get_attr(path, "hostid"); + h = nvme_lookup_host(r, hostnqn, hostid); + free(hostnqn); + if (hostid) + free(hostid); + } + if (!h) + h = nvme_default_host(r); + if (!h) { + errno = ENOMEM; + return -1; + } subsysnqn = nvme_get_attr(path, "subsysnqn"); if (!subsysnqn) { errno = ENODEV; From e8c763aa2281c3ea09fef5bfad261be8cb37dc4c Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 23 Jun 2021 08:59:56 +0200 Subject: [PATCH 0118/1564] libnvme.i: decode discover log page entry fields Decode the individual fields from the discover log page entry to make the output usable for creating controllers. Signed-off-by: Hannes Reinecke --- src/nvme/libnvme.i | 68 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 4 deletions(-) diff --git a/src/nvme/libnvme.i b/src/nvme/libnvme.i index 25eddb4461..a754aebaf7 100644 --- a/src/nvme/libnvme.i +++ b/src/nvme/libnvme.i @@ -167,9 +167,45 @@ static int discover_err = 0; struct nvmf_disc_log_entry *e = &log->entries[i]; PyObject *entry = PyDict_New(), *val; - val = PyLong_FromLong(e->trtype); + switch (e->trtype) { + case NVMF_TRTYPE_UNSPECIFIED: + val = PyUnicode_FromString("unspecified"); + break; + case NVMF_TRTYPE_RDMA: + val = PyUnicode_FromString("rdma"); + break; + case NVMF_TRTYPE_FC: + val = PyUnicode_FromString("fc"); + break; + case NVMF_TRTYPE_TCP: + val = PyUnicode_FromString("tcp"); + break; + case NVMF_TRTYPE_LOOP: + val = PyUnicode_FromString("loop"); + break; + default: + val = PyLong_FromLong(e->trtype); + } PyDict_SetItemString(entry, "trtype", val); - val = PyLong_FromLong(e->adrfam); + switch (e->adrfam) { + case NVMF_ADDR_FAMILY_PCI: + val = PyUnicode_FromString("pci"); + break; + case NVMF_ADDR_FAMILY_IP4: + val = PyUnicode_FromString("ipv4"); + break; + case NVMF_ADDR_FAMILY_IP6: + val = PyUnicode_FromString("ipv6"); + break; + case NVMF_ADDR_FAMILY_IB: + val = PyUnicode_FromString("infiniband"); + break; + case NVMF_ADDR_FAMILY_FC: + val = PyUnicode_FromString("fc"); + break; + default: + val = PyLong_FromLong(e->adrfam); + } PyDict_SetItemString(entry, "adrfam", val); val = PyUnicode_FromString(e->traddr); PyDict_SetItemString(entry, "traddr", val); @@ -177,9 +213,33 @@ static int discover_err = 0; PyDict_SetItemString(entry, "trsvcid", val); val = PyUnicode_FromString(e->subnqn); PyDict_SetItemString(entry, "subnqn", val); - val = PyLong_FromLong(e->subtype); + switch (e->subtype) { + case NVME_NQN_DISC: + val = PyUnicode_FromString("discovery"); + break; + case NVME_NQN_NVME: + val = PyUnicode_FromString("nvme"); + break; + default: + val = PyLong_FromLong(e->subtype); + } PyDict_SetItemString(entry, "subtype", val); - val = PyLong_FromLong(e->treq); + switch (e->treq) { + case NVMF_TREQ_NOT_SPECIFIED: + val = PyUnicode_FromString("not specified"); + break; + case NVMF_TREQ_REQUIRED: + val = PyUnicode_FromString("required"); + break; + case NVMF_TREQ_NOT_REQUIRED: + val = PyUnicode_FromString("not required"); + break; + case NVMF_TREQ_DISABLE_SQFLOW: + val = PyUnicode_FromString("disable sqflow"); + break; + default: + val = PyLong_FromLong(e->treq); + } PyDict_SetItemString(entry, "treq", val); val = PyLong_FromLong(e->portid); PyDict_SetItemString(entry, "portid", val); From 91f8f037879cf32206da7adf321b0295e6620134 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 23 Jun 2021 09:43:07 +0200 Subject: [PATCH 0119/1564] tree: initialize all lists As otherwise python will crash horribly. Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index f964772d24..be710b6e3b 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -90,6 +90,7 @@ nvme_root_t nvme_scan_filter(nvme_scan_filter_t f) } list_head_init(&r->hosts); + r->refcount = 1; nvme_scan_topology(r, f); return r; } @@ -276,6 +277,7 @@ struct nvme_subsystem *nvme_lookup_subsystem(struct nvme_host *h, s->refcount = 1; list_head_init(&s->ctrls); list_head_init(&s->namespaces); + list_node_init(&s->entry); list_add(&h->subsystems, &s->entry); h->r->modified = true; return s; @@ -525,6 +527,8 @@ static int nvme_ctrl_scan_path(struct nvme_ctrl *c, char *name) free(grpid); } + list_node_init(&p->nentry); + list_node_init(&p->entry); list_add(&c->paths, &p->entry); return 0; From 5c1eb92dcb4db259bec42d2d2369e87dfc68535f Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 23 Jun 2021 11:51:10 +0200 Subject: [PATCH 0120/1564] tree: rework topology deallocation The original idea of implementing a simple refcount doesn't really work out, as refcounting is everything but. And especially when used with the SWIG bindings it's not easy to figure if and when a refcount needs to be released. So kill the entire refcounting and free the internal structure only when calling nvme_free_tree(); the object-dependent functions like nvme_free_subsystem() etc now merely become stubs for symmetry and to keep SWIG happy. That removes the need for refcounting at all as the tree and its contents will always be available, and a call to nvme_free_tree() will clear the entire structure. Signed-off-by: Hannes Reinecke --- src/nvme/private.h | 4 --- src/nvme/tree.c | 65 ++++++++++++++++++++++++++-------------------- 2 files changed, 37 insertions(+), 32 deletions(-) diff --git a/src/nvme/private.h b/src/nvme/private.h index b6bdfa2522..a500f2d995 100644 --- a/src/nvme/private.h +++ b/src/nvme/private.h @@ -59,7 +59,6 @@ struct nvme_ctrl { struct list_head paths; struct list_head namespaces; struct nvme_subsystem *s; - int refcount; int fd; char *name; @@ -90,7 +89,6 @@ struct nvme_subsystem { struct list_head ctrls; struct list_head namespaces; struct nvme_host *h; - int refcount; char *name; char *sysfs_dir; @@ -104,7 +102,6 @@ struct nvme_host { struct list_node entry; struct list_head subsystems; struct nvme_root *r; - int refcount; char *hostnqn; char *hostid; @@ -113,7 +110,6 @@ struct nvme_host { struct nvme_root { char *config_file; struct list_head hosts; - int refcount; bool modified; }; diff --git a/src/nvme/tree.c b/src/nvme/tree.c index be710b6e3b..7fa4f262ec 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -32,6 +32,8 @@ static struct nvme_host *default_host; +static void __nvme_free_host(nvme_host_t h); +static void __nvme_free_ctrl(nvme_ctrl_t c); static int nvme_subsystem_scan_namespace(struct nvme_subsystem *s, char *name); static int nvme_scan_subsystem(struct nvme_root *r, char *name, nvme_scan_filter_t f); @@ -90,7 +92,6 @@ nvme_root_t nvme_scan_filter(nvme_scan_filter_t f) } list_head_init(&r->hosts); - r->refcount = 1; nvme_scan_topology(r, f); return r; } @@ -153,7 +154,7 @@ void nvme_refresh_topology(nvme_root_t r) struct nvme_host *h, *_h; nvme_for_each_host_safe(r, h, _h) - nvme_free_host(h); + __nvme_free_host(h); nvme_scan_topology(r, NULL); } @@ -162,7 +163,7 @@ void nvme_reset_topology(nvme_root_t r) struct nvme_host *h, *_h; nvme_for_each_host_safe(r, h, _h) - nvme_free_host(h); + __nvme_free_host(h); nvme_scan_topology(r, NULL); } @@ -171,7 +172,7 @@ void nvme_free_tree(nvme_root_t r) struct nvme_host *h, *_h; nvme_for_each_host_safe(r, h, _h) - nvme_free_host(h); + __nvme_free_host(h); if (r->config_file) free(r->config_file); free(r); @@ -217,7 +218,7 @@ nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n) return n ? list_next(&s->namespaces, n, entry) : NULL; } -void nvme_free_ns(struct nvme_ns *n) +static void __nvme_free_ns(struct nvme_ns *n) { list_del_init(&n->entry); close(n->fd); @@ -226,20 +227,22 @@ void nvme_free_ns(struct nvme_ns *n) free(n); } -void nvme_free_subsystem(struct nvme_subsystem *s) +/* Stub for SWIG */ +void nvme_free_ns(struct nvme_ns *n) +{ +} + +static void __nvme_free_subsystem(struct nvme_subsystem *s) { struct nvme_ctrl *c, *_c; struct nvme_ns *n, *_n; - if (--s->refcount > 0) - return; - list_del_init(&s->entry); nvme_subsystem_for_each_ctrl_safe(s, c, _c) - nvme_free_ctrl(c); + __nvme_free_ctrl(c); nvme_subsystem_for_each_ns_safe(s, n, _n) - nvme_free_ns(n); + __nvme_free_ns(n); free(s->name); free(s->sysfs_dir); @@ -253,6 +256,13 @@ void nvme_free_subsystem(struct nvme_subsystem *s) free(s); } +/* + * Stub for SWIG + */ +void nvme_free_subsystem(nvme_subsystem_t s) +{ +} + struct nvme_subsystem *nvme_lookup_subsystem(struct nvme_host *h, const char *name, const char *subsysnqn) @@ -265,7 +275,6 @@ struct nvme_subsystem *nvme_lookup_subsystem(struct nvme_host *h, if (name && s->name && strcmp(s->name, name)) continue; - s->refcount++; return s; } s = calloc(1, sizeof(*s)); @@ -274,7 +283,6 @@ struct nvme_subsystem *nvme_lookup_subsystem(struct nvme_host *h, s->h = h; s->subsysnqn = strdup(subsysnqn); - s->refcount = 1; list_head_init(&s->ctrls); list_head_init(&s->namespaces); list_node_init(&s->entry); @@ -283,15 +291,13 @@ struct nvme_subsystem *nvme_lookup_subsystem(struct nvme_host *h, return s; } -void nvme_free_host(struct nvme_host *h) +static void __nvme_free_host(struct nvme_host *h) { struct nvme_subsystem *s, *_s; - if (--h->refcount > 0) - return; list_del_init(&h->entry); nvme_for_each_subsystem_safe(h, s, _s) - nvme_free_subsystem(s); + __nvme_free_subsystem(s); free(h->hostnqn); if (h->hostid) free(h->hostid); @@ -299,6 +305,11 @@ void nvme_free_host(struct nvme_host *h) free(h); } +/* Stub for SWIG */ +void nvme_free_host(struct nvme_host *h) +{ +} + struct nvme_host *nvme_lookup_host(nvme_root_t r, const char *hostnqn, const char *hostid) { @@ -312,7 +323,6 @@ struct nvme_host *nvme_lookup_host(nvme_root_t r, const char *hostnqn, if (hostid && strcmp(h->hostid, hostid)) continue; - h->refcount++; return h; } h = calloc(1,sizeof(*h)); @@ -324,7 +334,6 @@ struct nvme_host *nvme_lookup_host(nvme_root_t r, const char *hostnqn, list_head_init(&h->subsystems); list_node_init(&h->entry); h->r = r; - h->refcount = 1; list_add(&r->hosts, &h->entry); r->modified = true; @@ -428,7 +437,7 @@ static int nvme_scan_subsystem(struct nvme_root *r, char *name, nvme_subsystem_scan_ctrls(s); if (f && !f(s)) { - nvme_free_subsystem(s); + __nvme_free_subsystem(s); return -1; } @@ -741,21 +750,18 @@ void nvme_unlink_ctrl(nvme_ctrl_t c) c->s = NULL; } -void nvme_free_ctrl(nvme_ctrl_t c) +static void __nvme_free_ctrl(nvme_ctrl_t c) { struct nvme_path *p, *_p; struct nvme_ns *n, *_n; - if (--c->refcount > 0) - return; - nvme_unlink_ctrl(c); nvme_ctrl_for_each_path_safe(c, p, _p) nvme_free_path(p); nvme_ctrl_for_each_ns_safe(c, n, _n) - nvme_free_ns(n); + __nvme_free_ns(n); if (c->fd >= 0) close(c->fd); @@ -784,6 +790,11 @@ void nvme_free_ctrl(nvme_ctrl_t c) free(c); } +/* Stub for SWIG */ +void nvme_free_ctrl(nvme_ctrl_t c) +{ +} + #define ____stringify(x...) #x #define __stringify(x...) ____stringify(x) @@ -902,7 +913,7 @@ struct nvme_ctrl *nvme_create_ctrl(const char *subsysnqn, const char *transport, !strncmp(transport, "tcp", 3)) { nvme_msg(LOG_ERR, "No trsvcid specified for '%s'\n", transport); - nvme_free_ctrl(c); + __nvme_free_ctrl(c); c = NULL; } @@ -932,14 +943,12 @@ struct nvme_ctrl *nvme_lookup_ctrl(struct nvme_subsystem *s, const char *transpo if (trsvcid && c->trsvcid && strcmp(c->trsvcid, trsvcid)) continue; - c->refcount++; return c; } c = nvme_create_ctrl(s->subsysnqn, transport, traddr, host_traddr, host_iface, trsvcid); if (c) { c->s = s; - c->refcount = 1; list_add(&s->ctrls, &c->entry); s->h->r->modified = true; } From b8b45653211ec078a55cb2b5b32b9fd809a99a63 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 24 Jun 2021 08:26:46 +0200 Subject: [PATCH 0121/1564] log: export last error message Add a static string 'nvme_log_message' containing the last error message written out by 'nvme_msg'. Signed-off-by: Hannes Reinecke --- src/nvme/log.c | 14 +++++++++----- src/nvme/log.h | 1 + 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/nvme/log.c b/src/nvme/log.c index 66cf692b80..9a7bcafeeb 100644 --- a/src/nvme/log.c +++ b/src/nvme/log.c @@ -23,6 +23,7 @@ #include #include #include +#include #define LOG_FUNCNAME 1 #include "log.h" #include "cleanup.h" @@ -34,6 +35,7 @@ int nvme_log_level = DEFAULT_LOGLEVEL; bool nvme_log_timestamp; bool nvme_log_pid; +char *nvme_log_message = NULL; void __attribute__((format(printf, 3, 4))) __nvme_msg(int lvl, const char *func, const char *format, ...) @@ -55,9 +57,6 @@ __nvme_msg(int lvl, const char *func, const char *format, ...) char *message __cleanup__(cleanup_charp) = NULL; int idx; - if (lvl > nvme_log_level) - return; - if (nvme_log_timestamp) { struct timespec now; @@ -84,7 +83,12 @@ __nvme_msg(int lvl, const char *func, const char *format, ...) message = NULL; va_end(ap); - fprintf(stderr, "%s%s", header ? header : "", - message ? message : ""); + if (nvme_log_message) + free(nvme_log_message); + nvme_log_message = strdup(message); + + if (lvl <= nvme_log_level) + fprintf(stderr, "%s%s", header ? header : "", + message ? message : ""); } diff --git a/src/nvme/log.h b/src/nvme/log.h index 36f56e8796..4ed695c430 100644 --- a/src/nvme/log.h +++ b/src/nvme/log.h @@ -23,6 +23,7 @@ extern int nvme_log_level; extern bool nvme_log_timestamp; extern bool nvme_log_pid; +extern char *nvme_log_message; void __attribute__((format(printf, 3, 4))) __nvme_msg(int lvl, const char *func, const char *format, ...); From 6d29e04fe89bf4f0cf8240c7f54330179cb46a7e Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 24 Jun 2021 08:28:09 +0200 Subject: [PATCH 0122/1564] libnvme.i: display last error message on connect() Instead of displaying just a generic 'connect failed' message we should be using nvme_log_message to display the most recent failure message to the user. Signed-off-by: Hannes Reinecke --- src/nvme/libnvme.i | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/nvme/libnvme.i b/src/nvme/libnvme.i index a754aebaf7..7f16eb37a4 100644 --- a/src/nvme/libnvme.i +++ b/src/nvme/libnvme.i @@ -18,6 +18,7 @@ #include "tree.h" #include "fabrics.h" #include "private.h" +#include "log.h" static int host_iter_err = 0; static int subsys_iter_err = 0; @@ -97,7 +98,10 @@ static int discover_err = 0; SWIG_exception(SWIG_AttributeError, "Existing controller connection"); } else if (connect_err) { connect_err = 0; - SWIG_exception(SWIG_RuntimeError, "Connect failed"); + if (nvme_log_message) + SWIG_exception(SWIG_RuntimeError, nvme_log_message); + else + SWIG_exception(SWIG_RuntimeError, "Connect failed"); } } @@ -314,6 +318,7 @@ struct nvme_ns { %extend nvme_root { nvme_root(const char *config_file = NULL) { + nvme_log_level = LOG_ERR; return nvme_scan(config_file); } ~nvme_root() { From b992f78f715579ce6f12c20d90ac8d74349a0449 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 24 Jun 2021 09:20:25 +0200 Subject: [PATCH 0123/1564] libnvme.i: add a 'log_level' function to nvme_root object Add a 'log_level' function to the nvme_root object to allow to increase the logging level of the libnvme library. Signed-off-by: Hannes Reinecke --- src/nvme/libnvme.i | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/nvme/libnvme.i b/src/nvme/libnvme.i index 7f16eb37a4..00388dfcf1 100644 --- a/src/nvme/libnvme.i +++ b/src/nvme/libnvme.i @@ -324,6 +324,24 @@ struct nvme_ns { ~nvme_root() { nvme_free_tree($self); } + void log_level(const char *level) { + if (!strcmp(level,"debug")) + nvme_log_level = LOG_DEBUG; + else if (!strcmp(level, "info")) + nvme_log_level = LOG_INFO; + else if (!strcmp(level, "notice")) + nvme_log_level = LOG_NOTICE; + else if (!strcmp(level, "warning")) + nvme_log_level = LOG_WARNING; + else if (!strcmp(level, "err")) + nvme_log_level = LOG_ERR; + else if (!strcmp(level, "crit")) + nvme_log_level = LOG_CRIT; + else if (!strcmp(level, "alert")) + nvme_log_level = LOG_ALERT; + else if (!strcmp(level, "emerg")) + nvme_log_level = LOG_EMERG; + } struct nvme_host *hosts() { return nvme_first_host($self); } From 61f436dc535106d45d4d13454dfc9938628bb344 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 24 Jun 2021 16:28:52 +0200 Subject: [PATCH 0124/1564] tree: add error logging when failing to lookup subsystem name Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 7fa4f262ec..a0631ccb90 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -1067,7 +1067,15 @@ int nvme_init_ctrl(nvme_host_t h, nvme_ctrl_t c, int instance) ret = -1; goto out_free_name; } + free(path); subsys_name = nvme_ctrl_lookup_subsystem_name(c); + if (!subsys_name) { + nvme_msg(LOG_ERR, "Failed to lookup subsystem name for %s\n", + c->name); + errno = ENXIO; + ret = -1; + goto out_free_name; + } s = nvme_lookup_subsystem(h, subsys_name, c->subsysnqn); if (!s) { errno = ENXIO; From c81b17964cdd0284d17050cc9df6142b186bfcb0 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Sat, 26 Jun 2021 13:05:10 +0200 Subject: [PATCH 0125/1564] tree: use 'stat' to lookup nvme controller When looking up nvme subsystems for individual controllers we should be using 'stat()' instead of 'opendir()'; this is less heavy-handed and provides better error checking. Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index a0631ccb90..25b9b586aa 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -17,6 +17,7 @@ #include #include +#include #include #include @@ -988,7 +989,6 @@ static char *nvme_ctrl_lookup_subsystem_name(nvme_ctrl_t c) { struct dirent **subsys; char *subsys_name = NULL; - DIR *d; int ret, i; char path[PATH_MAX]; @@ -996,13 +996,14 @@ static char *nvme_ctrl_lookup_subsystem_name(nvme_ctrl_t c) if (ret < 0) return NULL; for (i = 0; i < ret; i++) { + struct stat st; + sprintf(path, "%s/%s/%s", nvme_subsys_sysfs_dir, subsys[i]->d_name, c->name); - d = opendir(path); - if (!d) + nvme_msg(LOG_DEBUG, "lookup subsystem %s\n", path); + if (stat(path, &st) < 0) continue; subsys_name = strdup(subsys[i]->d_name); - closedir(d); break; } nvme_free_dirents(subsys, i); From c82baf96a71a6263d348f541a64869105cf7ee9d Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Sat, 26 Jun 2021 13:08:29 +0200 Subject: [PATCH 0126/1564] tree: rename __nvme_init_ctrl() to nvme_configure_ctrl() To clarify the intent on the function, and reduce confusion between nvme_ctrl_init() and __nvme_init_ctrl(). Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 25b9b586aa..d193fc9470 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -1010,7 +1010,8 @@ static char *nvme_ctrl_lookup_subsystem_name(nvme_ctrl_t c) return subsys_name; } -static int __nvme_ctrl_init(nvme_ctrl_t c, const char *path, const char *name) +static int nvme_configure_ctrl(nvme_ctrl_t c, const char *path, + const char *name) { DIR *d; @@ -1055,7 +1056,7 @@ int nvme_init_ctrl(nvme_host_t h, nvme_ctrl_t c, int instance) goto out_free_name; } - ret = __nvme_ctrl_init(c, path, name); + ret = nvme_configure_ctrl(c, path, name); if (ret < 0) { free(path); goto out_free_name; @@ -1144,7 +1145,7 @@ static nvme_ctrl_t nvme_ctrl_alloc(nvme_subsystem_t s, const char *path, return NULL; } c->address = address; - ret = __nvme_ctrl_init(c, path, name); + ret = nvme_configure_ctrl(c, path, name); return (ret < 0) ? NULL : c; } From 858ca9b53a4431d8486296071e0f9520e7fc599f Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Sat, 26 Jun 2021 13:09:14 +0200 Subject: [PATCH 0127/1564] tree: implement nvme_deconfigure_ctrl() Separate out nvme_deconfigure_ctrl() from nvme_disconnect_ctrl() to make it symmetric with nvme_configure_ctrl(). Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 57 +++++++++++++++++++------------------------------ 1 file changed, 22 insertions(+), 35 deletions(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index d193fc9470..bb87587cb3 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -715,18 +715,8 @@ nvme_path_t nvme_ctrl_next_path(nvme_ctrl_t c, nvme_path_t p) #define FREE_CTRL_ATTR(a) \ do { if (a) { free(a); (a) = NULL; } } while (0) -int nvme_disconnect_ctrl(nvme_ctrl_t c) +void nvme_deconfigure_ctrl(nvme_ctrl_t c) { - int ret; - - ret = nvme_set_attr(nvme_ctrl_get_sysfs_dir(c), - "delete_controller", "1"); - if (ret < 0) { - nvme_msg(LOG_ERR, "%s: failed to disconnect, error %d\n", - c->name, errno); - return ret; - } - nvme_msg(LOG_INFO, "%s: disconnected\n", c->name); if (c->fd >= 0) { close(c->fd); c->fd = -1; @@ -741,7 +731,21 @@ int nvme_disconnect_ctrl(nvme_ctrl_t c) FREE_CTRL_ATTR(c->serial); FREE_CTRL_ATTR(c->sqsize); FREE_CTRL_ATTR(c->address); +} + +int nvme_disconnect_ctrl(nvme_ctrl_t c) +{ + int ret; + ret = nvme_set_attr(nvme_ctrl_get_sysfs_dir(c), + "delete_controller", "1"); + if (ret < 0) { + nvme_msg(LOG_ERR, "%s: failed to disconnect, error %d\n", + c->name, errno); + return ret; + } + nvme_msg(LOG_INFO, "%s: disconnected\n", c->name); + nvme_deconfigure_ctrl(c); return 0; } @@ -764,30 +768,13 @@ static void __nvme_free_ctrl(nvme_ctrl_t c) nvme_ctrl_for_each_ns_safe(c, n, _n) __nvme_free_ns(n); - if (c->fd >= 0) - close(c->fd); - if (c->name) - free(c->name); - if (c->sysfs_dir) - free(c->sysfs_dir); - if (c->address) - free(c->address); - if (c->traddr) - free(c->traddr); - if (c->trsvcid) - free(c->trsvcid); - if (c->host_traddr) - free(c->host_traddr); - if (c->host_iface) - free(c->host_iface); - free(c->firmware); - free(c->model); - free(c->state); - free(c->numa_node); - free(c->queue_count); - free(c->serial); - free(c->sqsize); - free(c->transport); + nvme_deconfigure_ctrl(c); + + FREE_CTRL_ATTR(c->transport); + FREE_CTRL_ATTR(c->traddr); + FREE_CTRL_ATTR(c->host_traddr); + FREE_CTRL_ATTR(c->host_iface); + FREE_CTRL_ATTR(c->trsvcid); free(c); } From 96c5e19fe968c8a86430aa9457a73c854fedda15 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Sat, 26 Jun 2021 13:46:22 +0200 Subject: [PATCH 0128/1564] tree: do not free 'path' in nvme_init_ctrl() After nvme_configure_ctrl() completes successfully we must not free the 'path' argument as control has been transferred to the controller structure. Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index bb87587cb3..de3bb585ae 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -245,7 +245,8 @@ static void __nvme_free_subsystem(struct nvme_subsystem *s) nvme_subsystem_for_each_ns_safe(s, n, _n) __nvme_free_ns(n); - free(s->name); + if (s->name) + free(s->name); free(s->sysfs_dir); free(s->subsysnqn); if (s->model) @@ -1056,7 +1057,6 @@ int nvme_init_ctrl(nvme_host_t h, nvme_ctrl_t c, int instance) ret = -1; goto out_free_name; } - free(path); subsys_name = nvme_ctrl_lookup_subsystem_name(c); if (!subsys_name) { nvme_msg(LOG_ERR, "Failed to lookup subsystem name for %s\n", From fde71c1117630bd716c1ede2609796c80272555b Mon Sep 17 00:00:00 2001 From: Martin Belanger Date: Sat, 26 Jun 2021 13:58:41 +0200 Subject: [PATCH 0129/1564] Makefile: fix libnvme_wrap targets Signed-off-by: Martin Belanger --- src/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Makefile b/src/Makefile index c07d1fe29a..cf767e26ce 100644 --- a/src/Makefile +++ b/src/Makefile @@ -77,10 +77,10 @@ libnvme.a: $(libnvme_objs) $(libccan_objs) $(libname): $(libnvme_sobjs) $(libccan_sobjs) libnvme.map $(QUIET_CC)$(CC) $(SO_CFLAGS) -Wl,--version-script=libnvme.map -Wl,-soname=$(soname) -o $@ $(libnvme_sobjs) $(libccan_sobjs) $(LINK_FLAGS) -libnvme_wrap.c: $(libnvme_swig) +nvme/libnvme_wrap.c: $(libnvme_swig) $(SWIG) -python -py3 -outdir . $< -python: libnvme_wrap.c setup.py +python: nvme/libnvme_wrap.c setup.py $(PYTHON) setup.py build install: $(all_targets) @@ -99,5 +99,5 @@ clean: rm -f $(all_targets) $(libnvme_objs) $(libnvme_sobjs) $(libccan_objs) $(libccan_sobjs) $(soname).new rm -f $(CCANDIR)config.h rm -f $(CCANDIR)tools/configurator/configurator - rm -f libnvme_wrap.c + rm -f nvme/libnvme_wrap.c rm -f *.so* *.a *.o From 1e46cc261357cffb97c66172d064f1476101cb08 Mon Sep 17 00:00:00 2001 From: Martin Belanger Date: Sat, 26 Jun 2021 14:02:25 +0200 Subject: [PATCH 0130/1564] fabrics: Remove trailing newline from debugging messages The debugging messages in __nvmf_add_ctrl() contained newlines, making for an improper formatted message. Signed-off-by: Martin Belanger --- src/nvme/fabrics.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 8b415cf40b..466295641d 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -309,7 +309,8 @@ static int __nvmf_add_ctrl(const char *argstr) return -1; } - nvme_msg(LOG_DEBUG, "connect ctrl, '%s'\n", argstr); + nvme_msg(LOG_DEBUG, "connect ctrl, '%.*s'\n", + (int)strcspn(argstr,"\n"), argstr); ret = write(fd, argstr, len); if (ret != len) { nvme_msg(LOG_NOTICE, "Failed to write to %s: %s\n", @@ -325,7 +326,8 @@ static int __nvmf_add_ctrl(const char *argstr) ret = -1; goto out_close; } - nvme_msg(LOG_DEBUG, "connect ctrl, response '%s'\n", buf); + nvme_msg(LOG_DEBUG, "connect ctrl, response '%.*s'\n", + (int)strcspn(buf, "\n"), buf); buf[len] = '\0'; options = buf; while ((p = strsep(&options, ",\n")) != NULL) { From ecec9ea23c821dadabc9329ad212479574f414b8 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Fri, 9 Jul 2021 08:19:17 -0700 Subject: [PATCH 0131/1564] re-arm discovery AEN Ensure that the discovery AEN is unmasked by clearing RAE on the last read of the full discovery log page. Link: https://github.com/linux-nvme/libnvme/issues/17 Signed-off-by: Keith Busch --- src/nvme/fabrics.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 8b415cf40b..c0d0708a09 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -490,9 +490,9 @@ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, return NULL; } -static int nvme_discovery_log(int fd, __u32 len, struct nvmf_discovery_log *log) +static int nvme_discovery_log(int fd, __u32 len, struct nvmf_discovery_log *log, bool rae) { - return __nvme_get_log_page(fd, 0, NVME_LOG_LID_DISCOVER, true, 512, + return __nvme_get_log_page(fd, 0, NVME_LOG_LID_DISCOVER, rae, 512, len, log); } @@ -516,7 +516,7 @@ int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, memset(log, 0, hdr); nvme_msg(LOG_DEBUG, "%s: discover length %d\n", name, 0x100); - ret = nvme_discovery_log(nvme_ctrl_get_fd(c), 0x100, log); + ret = nvme_discovery_log(nvme_ctrl_get_fd(c), 0x100, log, true); if (ret) { nvme_msg(LOG_INFO, "%s: discover failed, error %d\n", name, errno); @@ -546,7 +546,7 @@ int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, memset(log, 0, size); nvme_msg(LOG_DEBUG, "%s: discover length %d\n", name, size); - ret = nvme_discovery_log(nvme_ctrl_get_fd(c), size, log); + ret = nvme_discovery_log(nvme_ctrl_get_fd(c), size, log, false); if (ret) { nvme_msg(LOG_INFO, "%s: discover try %d/%d failed, error %d\n", @@ -557,7 +557,7 @@ int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, genctr = le64_to_cpu(log->genctr); nvme_msg(LOG_DEBUG, "%s: discover genctr %lu, retry\n", name, genctr); - ret = nvme_discovery_log(nvme_ctrl_get_fd(c), hdr, log); + ret = nvme_discovery_log(nvme_ctrl_get_fd(c), hdr, log, true); if (ret) { nvme_msg(LOG_INFO, "%s: discover try %d/%d failed, error %d\n", From 9bdc0b91dbc76126d001ed753c64a5b3e54b5fff Mon Sep 17 00:00:00 2001 From: Martin Belanger Date: Wed, 14 Jul 2021 10:51:52 -0400 Subject: [PATCH 0132/1564] fix memory leak --- src/nvme/libnvme.i | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/nvme/libnvme.i b/src/nvme/libnvme.i index 00388dfcf1..cc4db6439b 100644 --- a/src/nvme/libnvme.i +++ b/src/nvme/libnvme.i @@ -161,6 +161,10 @@ static int discover_err = 0; $result = PyBytes_FromStringAndSize((char *)$1, 16); }; +%typemap(newfree) struct nvmf_discovery_log * { + if ($1) free($1); +} + %typemap(out) struct nvmf_discovery_log * { struct nvmf_discovery_log *log = $1; int numrec = log? log->numrec : 0, i; @@ -520,6 +524,7 @@ struct nvme_ns { void disconnect() { nvme_disconnect_ctrl($self); } + %newobject discover; struct nvmf_discovery_log *discover(int max_retries = 6) { struct nvmf_discovery_log *logp = NULL; int ret = 0; From 4339038bc9bbdda7815ba00c3249aa5a9db1857f Mon Sep 17 00:00:00 2001 From: Martin Belanger Date: Wed, 14 Jul 2021 11:10:47 -0400 Subject: [PATCH 0133/1564] rename Python class names using SWIG's %rename --- src/nvme/libnvme.i | 56 +++++++++++++++++++++++++--------------------- src/setup.py | 4 ++-- 2 files changed, 33 insertions(+), 27 deletions(-) diff --git a/src/nvme/libnvme.i b/src/nvme/libnvme.i index cc4db6439b..8037df48bf 100644 --- a/src/nvme/libnvme.i +++ b/src/nvme/libnvme.i @@ -6,12 +6,18 @@ * Authors: Hannes Reinecke */ -%module libnvme +%module nvme %include "exception.i" %allowexception; +%rename(root) nvme_root; +%rename(host) nvme_host; +%rename(ctrl) nvme_ctrl; +%rename(subsystem) nvme_subsystem; +%rename(ns) nvme_ns; + %{ #include #include @@ -29,29 +35,29 @@ static int discover_err = 0; %} %inline %{ - struct nvme_host_iter { + struct host_iter { struct nvme_root *root; struct nvme_host *pos; }; - struct nvme_subsystem_iter { + struct subsystem_iter { struct nvme_host *host; struct nvme_subsystem *pos; }; - struct nvme_ctrl_iter { + struct ctrl_iter { struct nvme_subsystem *subsystem; struct nvme_ctrl *pos; }; - struct nvme_ns_iter { + struct ns_iter { struct nvme_subsystem *subsystem; struct nvme_ctrl *ctrl; struct nvme_ns *pos; }; %} -%exception nvme_host_iter::__next__ { +%exception host_iter::__next__ { assert(!host_iter_err); $action if (host_iter_err) { @@ -61,7 +67,7 @@ static int discover_err = 0; } } -%exception nvme_subsystem_iter::__next__ { +%exception subsystem_iter::__next__ { assert(!subsys_iter_err); $action if (subsys_iter_err) { @@ -71,7 +77,7 @@ static int discover_err = 0; } } -%exception nvme_ctrl_iter::__next__ { +%exception ctrl_iter::__next__ { assert(!ctrl_iter_err); $action if (ctrl_iter_err) { @@ -81,7 +87,7 @@ static int discover_err = 0; } } -%exception nvme_ns_iter::__next__ { +%exception ns_iter::__next__ { assert(!ns_iter_err); $action if (ns_iter_err) { @@ -357,8 +363,8 @@ struct nvme_ns { } } -%extend nvme_host_iter { - struct nvme_host_iter *__iter__() { +%extend host_iter { + struct host_iter *__iter__() { return $self; } struct nvme_host *__next__() { @@ -389,8 +395,8 @@ struct nvme_ns { sprintf(tmp, "nvme_host(%s,%s)", $self->hostnqn, $self->hostid); return tmp; } - struct nvme_host_iter __iter__() { - struct nvme_host_iter ret = { .root = nvme_host_get_root($self), + struct host_iter __iter__() { + struct host_iter ret = { .root = nvme_host_get_root($self), .pos = $self }; return ret; } @@ -399,8 +405,8 @@ struct nvme_ns { } } -%extend nvme_subsystem_iter { - struct nvme_subsystem_iter *__iter__() { +%extend subsystem_iter { + struct subsystem_iter *__iter__() { return $self; } struct nvme_subsystem *__next__() { @@ -415,8 +421,8 @@ struct nvme_ns { } } -%extend nvme_ns_iter { - struct nvme_ns_iter *__iter__() { +%extend ns_iter { + struct ns_iter *__iter__() { return $self; } struct nvme_ns *__next__() { @@ -448,8 +454,8 @@ struct nvme_ns { sprintf(tmp, "nvme_subsystem(%s,%s)", $self->name,$self->subsysnqn); return tmp; } - struct nvme_subsystem_iter __iter__() { - struct nvme_subsystem_iter ret = { .host = nvme_subsystem_get_host($self), + struct subsystem_iter __iter__() { + struct subsystem_iter ret = { .host = nvme_subsystem_get_host($self), .pos = $self }; return ret; } @@ -474,8 +480,8 @@ struct nvme_ns { } %}; -%extend nvme_ctrl_iter { - struct nvme_ctrl_iter *__iter__() { +%extend ctrl_iter { + struct ctrl_iter *__iter__() { return $self; } struct nvme_ctrl *__next__() { @@ -545,8 +551,8 @@ struct nvme_ns { sprintf(tmp, "nvme_ctrl(transport=%s)", $self->transport); return tmp; } - struct nvme_ctrl_iter __iter__() { - struct nvme_ctrl_iter ret = { .subsystem = nvme_ctrl_get_subsystem($self), + struct ctrl_iter __iter__() { + struct ctrl_iter ret = { .subsystem = nvme_ctrl_get_subsystem($self), .pos = $self }; return ret; } @@ -586,8 +592,8 @@ struct nvme_ns { sprintf(tmp, "nvme_ns(%u)", $self->nsid); return tmp; } - struct nvme_ns_iter __iter__() { - struct nvme_ns_iter ret = { .ctrl = nvme_ns_get_ctrl($self), + struct ns_iter __iter__() { + struct ns_iter ret = { .ctrl = nvme_ns_get_ctrl($self), .subsystem = nvme_ns_get_subsystem($self), .pos = $self }; return ret; diff --git a/src/setup.py b/src/setup.py index 028eec8932..01100edc61 100644 --- a/src/setup.py +++ b/src/setup.py @@ -1,6 +1,6 @@ from distutils.core import setup, Extension -libnvme_module = Extension('_libnvme', +libnvme_module = Extension('_nvme', sources=['nvme/libnvme_wrap.c'], libraries=['nvme', 'json-c', 'uuid', 'systemd'], library_dirs=['./'], include_dirs = ['../ccan','nvme']) @@ -10,5 +10,5 @@ author_email='hare@suse.de', description='python bindings for libnvme', ext_modules=[libnvme_module], - py_modules=["libnvme"], + py_modules=["nvme"], ) From ed821fd141e90e02104f2fb28d9a0bc84becc352 Mon Sep 17 00:00:00 2001 From: Martin Belanger Date: Wed, 14 Jul 2021 13:49:59 -0400 Subject: [PATCH 0134/1564] Move 'Python bindings' SWIG and Makefile to 'pynvme' directory --- Makefile | 2 +- pynvme/.gitignore | 3 +++ pynvme/Makefile | 18 ++++++++++++++++++ src/nvme/libnvme.i => pynvme/nvme.i | 10 ++++++---- pynvme/setup.py | 18 ++++++++++++++++++ src/Makefile | 10 ---------- src/setup.py | 14 -------------- 7 files changed, 46 insertions(+), 29 deletions(-) create mode 100644 pynvme/.gitignore create mode 100644 pynvme/Makefile rename src/nvme/libnvme.i => pynvme/nvme.i (99%) create mode 100644 pynvme/setup.py delete mode 100644 src/setup.py diff --git a/Makefile b/Makefile index 2dd7137a9f..3574a9ac58 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ INSTALL=install default: all python: all - @$(MAKE) -C src python + @$(MAKE) -C pynvme python all: $(NAME).pc @$(MAKE) -C src diff --git a/pynvme/.gitignore b/pynvme/.gitignore new file mode 100644 index 0000000000..44ac4fefc0 --- /dev/null +++ b/pynvme/.gitignore @@ -0,0 +1,3 @@ +build/ +nvme.py +nvme_wrap.c diff --git a/pynvme/Makefile b/pynvme/Makefile new file mode 100644 index 0000000000..f82a83bb0d --- /dev/null +++ b/pynvme/Makefile @@ -0,0 +1,18 @@ +.DEFAULT_GOAL := python + +SWIG ?= swig +PYTHON ?= python3 + +nvme_swig := nvme.i + +nvme_wrap.c: $(nvme_swig) + $(SWIG) -python -py3 -outdir . $< + +python: nvme_wrap.c setup.py + $(PYTHON) setup.py build + +#install: +# + +clean: + rm -rf nvme_wrap.c nvme.py build diff --git a/src/nvme/libnvme.i b/pynvme/nvme.i similarity index 99% rename from src/nvme/libnvme.i rename to pynvme/nvme.i index 8037df48bf..18a3261783 100644 --- a/src/nvme/libnvme.i +++ b/pynvme/nvme.i @@ -21,10 +21,10 @@ %{ #include #include -#include "tree.h" -#include "fabrics.h" -#include "private.h" -#include "log.h" +#include "nvme/tree.h" +#include "nvme/fabrics.h" +#include "nvme/private.h" +#include "nvme/log.h" static int host_iter_err = 0; static int subsys_iter_err = 0; @@ -530,6 +530,7 @@ struct nvme_ns { void disconnect() { nvme_disconnect_ctrl($self); } + %newobject discover; struct nvmf_discovery_log *discover(int max_retries = 6) { struct nvmf_discovery_log *logp = NULL; @@ -607,3 +608,4 @@ struct nvme_ns { return nvme_ns_get_name(n); } %}; + diff --git a/pynvme/setup.py b/pynvme/setup.py new file mode 100644 index 0000000000..8db418aef4 --- /dev/null +++ b/pynvme/setup.py @@ -0,0 +1,18 @@ +from distutils.core import setup, Extension + +libnvme_module = Extension( + '_nvme', + sources = ['nvme_wrap.c'], + libraries = ['nvme', 'json-c', 'uuid', 'systemd'], + library_dirs = ['../src'], + include_dirs = ['../ccan', '../src', '../src/nvme'], +) + +setup( + name='libnvme', + author="Hannes Reinecke", + author_email='hare@suse.de', + description='python bindings for libnvme', + ext_modules=[libnvme_module], + py_modules=["nvme"], +) diff --git a/src/Makefile b/src/Makefile index cf767e26ce..06a4ad34cf 100644 --- a/src/Makefile +++ b/src/Makefile @@ -49,7 +49,6 @@ $(libccan_objs) $(libccan_sobjs): $(libccan_headers) $(CCANDIR)config.h libnvme_priv := nvme/private.h libnvme_api := libnvme.h nvme/types.h nvme/ioctl.h nvme/filters.h nvme/tree.h nvme/util.h nvme/fabrics.h libnvme_srcs := nvme/ioctl.c nvme/filters.c nvme/fabrics.c nvme/util.c nvme/tree.c nvme/log.c nvme/cleanup.c -libnvme_swig := nvme/libnvme.i ifneq ($(CONFIG_JSONC),0) override libnvme_srcs += nvme/json.c endif @@ -66,8 +65,6 @@ $(libnvme_objs) $(libnvme_sobjs): $(libnvme_api) $(libnvme_private) $(libccan_ob AR ?= ar RANLIB ?= ranlib -SWIG ?= swig -PYTHON ?= python3 libnvme.a: $(libnvme_objs) $(libccan_objs) @rm -f libnvme.a @@ -77,12 +74,6 @@ libnvme.a: $(libnvme_objs) $(libccan_objs) $(libname): $(libnvme_sobjs) $(libccan_sobjs) libnvme.map $(QUIET_CC)$(CC) $(SO_CFLAGS) -Wl,--version-script=libnvme.map -Wl,-soname=$(soname) -o $@ $(libnvme_sobjs) $(libccan_sobjs) $(LINK_FLAGS) -nvme/libnvme_wrap.c: $(libnvme_swig) - $(SWIG) -python -py3 -outdir . $< - -python: nvme/libnvme_wrap.c setup.py - $(PYTHON) setup.py build - install: $(all_targets) $(INSTALL) -D -m 644 libnvme.a $(libdir)/libnvme.a for i in $(libnvme_api); do $(INSTALL) -D -m 644 $$i $(includedir)/$$i; done @@ -99,5 +90,4 @@ clean: rm -f $(all_targets) $(libnvme_objs) $(libnvme_sobjs) $(libccan_objs) $(libccan_sobjs) $(soname).new rm -f $(CCANDIR)config.h rm -f $(CCANDIR)tools/configurator/configurator - rm -f nvme/libnvme_wrap.c rm -f *.so* *.a *.o diff --git a/src/setup.py b/src/setup.py deleted file mode 100644 index 01100edc61..0000000000 --- a/src/setup.py +++ /dev/null @@ -1,14 +0,0 @@ -from distutils.core import setup, Extension - -libnvme_module = Extension('_nvme', - sources=['nvme/libnvme_wrap.c'], - libraries=['nvme', 'json-c', 'uuid', 'systemd'], library_dirs=['./'], - include_dirs = ['../ccan','nvme']) - -setup(name='libnvme', - author="Hannes Reinecke", - author_email='hare@suse.de', - description='python bindings for libnvme', - ext_modules=[libnvme_module], - py_modules=["nvme"], -) From 667cfbd42e987adaba6bce9bc9a6c7f111b0aa9e Mon Sep 17 00:00:00 2001 From: Martin Belanger Date: Fri, 16 Jul 2021 09:08:31 -0400 Subject: [PATCH 0135/1564] add README file for python bindings --- pynvme/README.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 pynvme/README.md diff --git a/pynvme/README.md b/pynvme/README.md new file mode 100644 index 0000000000..ac51b387e2 --- /dev/null +++ b/pynvme/README.md @@ -0,0 +1,32 @@ +# Python bindings for libnvme + +We use [SWIG](http://www.swig.org/) to generate Python bindings for libnvme. + +## How to use + +```python +import sys +from libnvme import nvme + +root = nvme.root() # This is a singleton +host = nvme.host(root) # This "may be" a singleton. +ctrl = nvme.ctrl(subsysnqn=, transport=, traddr=, trsvcid=, host_traddr=, host_iface=) + +try: + ctrl.connect(host) + print(f"connected to {ctrl.name} subsys {ctrl.subsystem.name}") +except Exception as e: + sys.exit(f'Failed to connect: {e}') + +try: + log_pages = ctrl.discover() + print(pprint.pformat(log_pages)) +except Exception as e: + sys.exit(f'Failed to retrieve log pages: {e}') + +try: + ctrl.disconnect() +except Exception as e: + sys.exit(f'Failed to disconnect: {e}') +``` + From fe62ba70807882aab6a4696515f3d966a3f63a77 Mon Sep 17 00:00:00 2001 From: Tomas Bzatek Date: Thu, 22 Jul 2021 16:42:51 +0200 Subject: [PATCH 0136/1564] util: Add nvme_status_to_string() Taken from nvme-cli/libnvme-int-3.4.2021 branch, commit 70b9835a9dace56557acc5ed10fd4c77ac063238. --- src/nvme/util.c | 169 ++++++++++++++++++++++++++++++++++++++++++++++++ src/nvme/util.h | 10 +++ 2 files changed, 179 insertions(+) diff --git a/src/nvme/util.c b/src/nvme/util.c index fb0d284e90..5ea67e2002 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -156,6 +156,175 @@ __u8 nvme_status_to_errno(int status, bool fabrics) } } +static const char * const generic_status[] = { + [NVME_SC_SUCCESS] = "Successful Completion: The command completed without error", + [NVME_SC_INVALID_OPCODE] = "Invalid Command Opcode: A reserved coded 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", + [NVME_SC_CMDID_CONFLICT] = "Command ID Conflict: The command 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", + [NVME_SC_POWER_LOSS] = "Commands Aborted due to Power Loss 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", + [NVME_SC_ABORT_REQ] = "Command Abort Requested: The command was aborted due to an Abort command", + [NVME_SC_ABORT_QUEUE] = "Command Aborted due to SQ Deletion: The command was aborted due to a Delete I/O Submission Queue", + [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", + [NVME_SC_FUSED_MISSING] = "Command Aborted due to Missing Fused Command: The fused command was aborted due to the adjacent submission queue entry not containing a fused command", + [NVME_SC_INVALID_NS] = "Invalid Namespace or Format: The 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", + [NVME_SC_SGL_INVALID_LAST] = "Invalid SGL Segment Descriptor: The 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", + [NVME_SC_SGL_INVALID_DATA] = "Data SGL Length Invalid: The length of a Data SGL is too short or too long and the controller does not support SGL transfers longer than the amount of data to be transferred", + [NVME_SC_SGL_INVALID_METADATA] = "Metadata SGL Length Invalid: The length of a Metadata SGL is too short or too long and the controller does not support SGL transfers longer than the amount of data to be transferred", + [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", + [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", + [NVME_SC_AWU_EXCEEDED] = "Atomic Write Unit Exceeded: The length specified exceeds the atomic write unit size", + [NVME_SC_OP_DENIED] = "Operation Denied: The command was denied due to lack of access rights", + [NVME_SC_SGL_INVALID_OFFSET] = "SGL Offset Invalid: The offset specified in a descriptor is invalid", + [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", + [NVME_SC_KAT_EXPIRED] = "Keep Alive Timer Expired: The Keep Alive Timer expired", + [NVME_SC_KAT_INVALID] = "Keep Alive Timeout Invalid: The Keep 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", + [NVME_SC_SANITIZE_FAILED] = "Sanitize Failed: The most recent sanitize operation failed and no recovery action has been successfully completed", + [NVME_SC_SANITIZE_IN_PROGRESS] = "Sanitize In Progress: The requested function 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", + [NVME_SC_CMD_IN_CMBQ_NOT_SUPP] = "Command Not Supported for Queue in CMB: The controller does not support Submission Queue in the Controller Memory Buffer or 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", + [NVME_SC_CMD_INTERRUPTED] = "Command Interrupted: Command processing was interrupted and the controller is unable to successfully complete the command", + [NVME_SC_TRAN_TPORT_ERROR] = "Transient Transport Error: A transient transport error was detected", + [NVME_SC_LBA_RANGE] = "LBA Out of Range: The command references 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", + [NVME_SC_NS_NOT_READY] = "Namespace Not Ready: The namespace is not ready to be accessed", + [NVME_SC_RESERVATION_CONFLICT] = "Reservation Conflict: The command was 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", +}; + +static const char * const cmd_spec_status[] = { + [NVME_SC_CQ_INVALID] = "Completion Queue Invalid: The Completion 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 part of the command", + [NVME_SC_QUEUE_SIZE] = "Invalid Queue Size: The host attempted to 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", + [NVME_SC_ASYNC_LIMIT] = "Asynchronous Event Request Limit 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", + [NVME_SC_FIRMWARE_IMAGE] = "Invalid Firmware Image: The firmware 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", + [NVME_SC_INVALID_LOG_PAGE] = "Invalid Log Page: The log page indicated is invalid", + [NVME_SC_INVALID_FORMAT] = "Invalid Format: The LBA Format specified 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", + [NVME_SC_INVALID_QUEUE] = "Invalid Queue Deletion: Invalid I/O Completion Queue specified to delete", + [NVME_SC_FEATURE_NOT_SAVEABLE] = "Feature Identifier Not Saveable: The 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", + [NVME_SC_FEATURE_NOT_PER_NS] = "Feature Not Namespace Specific: The Feature Identifier specified is not namespace specific", + [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", + [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", + [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", + [NVME_SC_FW_ACTIVATE_PROHIBITED] = "Firmware Activation Prohibited: The image 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", + [NVME_SC_NS_INSUFFICIENT_CAP] = "Namespace Insufficient Capacity: Creating 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", + [NVME_SC_NS_ALREADY_ATTACHED] = "Namespace Already Attached: The 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", + [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", + [NVME_SC_THIN_PROV_NOT_SUPP] = "Thin Provisioning Not Supported: Thin provisioning is not supported by the controller", + [NVME_SC_CTRL_LIST_INVALID] = "Controller List Invalid: The controller list provided contains invalid controller ids", + [NVME_SC_SELF_TEST_IN_PROGRESS] = "Device Self-test In Progress", + [NVME_SC_BP_WRITE_PROHIBITED] = "Boot Partition Write Prohibited: The command tried to modify a locked Boot Partition", + [NVME_SC_INVALID_CTRL_ID] = "Invalid Controller Identifier: An invalid controller id was specified", + [NVME_SC_INVALID_SEC_CTRL_STATE] = "Invalid Secondary Controller State: The requested secondary controller action is invalid based on the secondary and primary controllers current states", + [NVME_SC_INVALID_CTRL_RESOURCES] = "Invalid Number of Controller Resources: The specified number of Flexible Resources is invalid", + [NVME_SC_INVALID_RESOURCE_ID] = "Invalid Resource Identifier: At least one of the specified resource identifiers was invalid", + [NVME_SC_PMR_SAN_PROHIBITED] = "Sanitize Prohibited While Persistent Memory Region is Enabled", + [NVME_SC_ANA_GROUP_ID_INVALID] = "ANA Group Identifier Invalid", + [NVME_SC_ANA_ATTACH_FAILED] = "ANA Attach Failed: The command's specified ANA Group Identifier is not supported", +}; + +static const char * const nvm_status[] = { + [NVME_SC_BAD_ATTRIBUTES] = "Conflicting Attributes: The attributes specified in the command are conflicting", + [NVME_SC_INVALID_PI] = "Invalid Protection Information: The command's Protection Information Field settings are invalid for the namespace's Protection Information format", + [NVME_SC_READ_ONLY] = "Attempted Write to Read Only Range: The LBA range specified contains read-only blocks", +}; + +static const char * const nvmf_status[] = { + [NVME_SC_CONNECT_FORMAT] = "Incompatible Format: The NVM subsystem 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", + [NVME_SC_CONNECT_INVALID_PARAM] = "Connect Invalid Parameters: One or more of the command parameters", + [NVME_SC_CONNECT_RESTART_DISC] = "Connect Restart Discovery: The NVM subsystem requested is not available", + [NVME_SC_CONNECT_INVALID_HOST] = "Connect Invalid Host: The host is not allowed to establish an association to either any controller in the NVM subsystem or the specified controller", + [NVME_SC_DISCONNECT_INVALID_QTYPE] = "Invalid Queue Type: The command was sent on the wrong queue type", + [NVME_SC_DISCOVERY_RESTART] = "Discover Restart: The snapshot of the 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", +}; + +static const char * const media_status[] = { + [NVME_SC_WRITE_FAULT] = "Write Fault: The write data could not be committed to the media", + [NVME_SC_READ_ERROR] = "Unrecovered Read Error: The read data 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", + [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", + [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", + [NVME_SC_COMPARE_FAILED] = "Compare Failure: The command failed due 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", + [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", +}; + +static const char * const path_status[] = { + [NVME_SC_ANA_INTERNAL_PATH_ERROR] = "Internal Path Error: An internal error specific to the controller processing the commmand prevented completion", + [NVME_SC_ANA_PERSISTENT_LOSS] = "Asymmetric Access Persistent Loss: The controller is in a persistent loss state with the requested namespace", + [NVME_SC_ANA_INACCESSIBLE] = "Asymmetric Access Inaccessible: The controller is in an inaccessible state with the requested namespace", + [NVME_SC_ANA_TRANSITION] = "Asymmetric Access Transition: The controller is currently transitioning states with the requested namespace", + [NVME_SC_CTRL_PATH_ERROR] = "Controller Pathing Error: A pathing error was detected by the controller", + [NVME_SC_HOST_PATH_ERROR] = "Host Pathing Error: A pathing error was detected by the host", + [NVME_SC_CMD_ABORTED_BY_HOST] = "Command Aborted By Host: The command was aborted as a result of host action", +}; + +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) +#define ARGSTR(s, i) arg_str(s, ARRAY_SIZE(s), i) + +static const char *arg_str(const char * const *strings, + size_t array_size, size_t idx) +{ + if (idx < array_size && strings[idx]) + return strings[idx]; + return "unrecognized"; +} + +const char *nvme_status_to_string(int status, bool fabrics) +{ + const char *s = "Unknown status"; + __u16 sc, sct; + + if (status < 0) + return strerror(errno); + + sc = nvme_status_code(status); + sct = nvme_status_code_type(status); + + switch (sct) { + case NVME_SCT_GENERIC: + s = ARGSTR(generic_status, sc); + break; + case NVME_SCT_CMD_SPECIFIC: + if (sc < ARRAY_SIZE(cmd_spec_status)) + s = ARGSTR(cmd_spec_status, sc); + else if (fabrics) + s = ARGSTR(nvmf_status, sc); + else + s = ARGSTR(nvm_status, sc); + break; + case NVME_SCT_MEDIA: + s = ARGSTR(media_status, sc); + break; + case NVME_SCT_PATH: + s = ARGSTR(path_status, sc); + break; + case NVME_SCT_VS: + s = "Vendor Specific Status"; + break; + default: + break; + } + + return s; +} + static int __nvme_open(const char *name) { char *path; diff --git a/src/nvme/util.h b/src/nvme/util.h index b5a1031cc8..f4b3b4095e 100644 --- a/src/nvme/util.h +++ b/src/nvme/util.h @@ -21,6 +21,16 @@ */ __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 + * @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, + * or a standard errno string if status is < 0. + */ +const char *nvme_status_to_string(int status, bool fabrics); + /** * nvme_fw_download_seq() - * @fd: File descriptor of nvme device From 688982d14a44939f961bdfe593de4a03ed9ec4d8 Mon Sep 17 00:00:00 2001 From: Tomas Bzatek Date: Fri, 23 Jul 2021 16:01:15 +0200 Subject: [PATCH 0137/1564] types: Add new status codes Sync with nvme-cli master, doc strings updates. --- src/nvme/types.h | 227 ++++++++++++++++++++++++++++++----------------- 1 file changed, 145 insertions(+), 82 deletions(-) diff --git a/src/nvme/types.h b/src/nvme/types.h index 773c721c7c..10e7b153ec 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -4255,6 +4255,13 @@ struct nvme_mi_vpd_hdr { * 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. + * @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. * @NVME_SC_LBA_RANGE: LBA Out of Range: The command references * an LBA that exceeds the size of the namespace. * @NVME_SC_CAP_EXCEEDED: Capacity Exceeded: Execution of the @@ -4285,9 +4292,9 @@ struct nvme_mi_vpd_hdr { * 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. * @NVME_SC_ASYNC_LIMIT: Asynchronous Event Request Limit @@ -4370,7 +4377,9 @@ struct nvme_mi_vpd_hdr { * @NVME_SC_CTRL_LIST_INVALID: Controller List Invalid: The controller * list provided contains invalid controller * ids. - * @NVME_SC_SELF_TEST_IN_PROGRESS: Device Self-test In Progress: + * @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. * @NVME_SC_BP_WRITE_PROHIBITED: Boot Partition Write Prohibited: The * command is trying to modify a locked Boot * Partition. @@ -4380,11 +4389,30 @@ struct nvme_mi_vpd_hdr { * @NVME_SC_INVALID_RESOURCE_ID: Invalid Resource Identifier * @NVME_SC_PMR_SAN_PROHIBITED: Sanitize Prohibited While Persistent * Memory Region is Enabled - * @NVME_SC_ANA_GROUP_ID_INVALID: ANA Group Identifier Invalid - * @NVME_SC_ANA_ATTACH_FAILED: ANA Attach Failed + * @NVME_SC_ANA_GROUP_ID_INVALID: ANA Group Identifier Invalid: The specified + * 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. + * @NVME_SC_INSUFFICIENT_CAP: Insufficient Capacity: Requested operation + * 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. + * @NVME_SC_PROHIBIT_CMD_EXEC_NOT_SUPPORTED: Prohibition of Command Execution + * 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 + * @NVME_SC_INVALID_IOCS: Invalid I/O Command Set + * @NVME_SC_ID_UNAVAILABLE: Identifier Unavailable * @NVME_SC_BAD_ATTRIBUTES: Conflicting Dataset Management Attributes * @NVME_SC_INVALID_PI: Invalid Protection Information * @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. @@ -4429,6 +4457,9 @@ struct nvme_mi_vpd_hdr { * 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. * @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 @@ -4467,6 +4498,22 @@ struct nvme_mi_vpd_hdr { * command is re-submitted to any controller * in the NVM subsystem, then that * re-submitted command is expected to fail. + * @NVME_SC_ZNS_BOUNDARY_ERROR: Zone Boundary Error: The command specifies + * logical blocks in more than one zone. + * @NVME_SC_ZNS_FULL: Zone Is Full: The accessed zone is in the + * ZSF:Full state. + * @NVME_SC_ZNS_READ_ONLY: Zone Is Read Only: The accessed zone is + * in the ZSRO:Read Only state. + * @NVME_SC_ZNS_OFFLINE: Zone Is Offline: The accessed zone is + * in the ZSO:Offline state. + * @NVME_SC_ZNS_INVALID_WRITE: Zone Invalid Write: The write to a zone + * 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. + * @NVME_SC_ZNS_INVAL_TRANSITION: Invalid Zone State Transition: The request + * is not a valid zone state transition. */ enum nvme_status_field { /* @@ -4487,86 +4534,100 @@ enum nvme_status_field { /* * Generic Command Status Codes: */ - NVME_SC_SUCCESS = 0x0, - NVME_SC_INVALID_OPCODE = 0x1, - NVME_SC_INVALID_FIELD = 0x2, - NVME_SC_CMDID_CONFLICT = 0x3, - NVME_SC_DATA_XFER_ERROR = 0x4, - NVME_SC_POWER_LOSS = 0x5, - NVME_SC_INTERNAL = 0x6, - NVME_SC_ABORT_REQ = 0x7, - NVME_SC_ABORT_QUEUE = 0x8, - NVME_SC_FUSED_FAIL = 0x9, - NVME_SC_FUSED_MISSING = 0xa, - NVME_SC_INVALID_NS = 0xb, - NVME_SC_CMD_SEQ_ERROR = 0xc, - NVME_SC_SGL_INVALID_LAST = 0xd, - NVME_SC_SGL_INVALID_COUNT = 0xe, - NVME_SC_SGL_INVALID_DATA = 0xf, - NVME_SC_SGL_INVALID_METADATA = 0x10, - NVME_SC_SGL_INVALID_TYPE = 0x11, - NVME_SC_CMB_INVALID_USE = 0x12, - NVME_SC_PRP_INVALID_OFFSET = 0x13, - NVME_SC_AWU_EXCEEDED = 0x14, - NVME_SC_OP_DENIED = 0x15, - NVME_SC_SGL_INVALID_OFFSET = 0x16, - NVME_SC_HOSTID_FORMAT = 0x18, - NVME_SC_KAT_EXPIRED = 0x19, - NVME_SC_KAT_INVALID = 0x1a, - NVME_SC_CMD_ABORTED_PREMEPT = 0x1b, - NVME_SC_SANITIZE_FAILED = 0x1c, - NVME_SC_SANITIZE_IN_PROGRESS = 0x1d, - NVME_SC_SGL_INVALID_GRANULARITY = 0x1e, - NVME_SC_CMD_IN_CMBQ_NOT_SUPP = 0x1f, - NVME_SC_NS_WRITE_PROTECTED = 0x20, - NVME_SC_CMD_INTERRUPTED = 0x21, - NVME_SC_TRAN_TPORT_ERROR = 0x22, - NVME_SC_LBA_RANGE = 0x80, - NVME_SC_CAP_EXCEEDED = 0x81, - NVME_SC_NS_NOT_READY = 0x82, - NVME_SC_RESERVATION_CONFLICT = 0x83, - NVME_SC_FORMAT_IN_PROGRESS = 0x84, + NVME_SC_SUCCESS = 0x0, + NVME_SC_INVALID_OPCODE = 0x1, + NVME_SC_INVALID_FIELD = 0x2, + NVME_SC_CMDID_CONFLICT = 0x3, + NVME_SC_DATA_XFER_ERROR = 0x4, + NVME_SC_POWER_LOSS = 0x5, + NVME_SC_INTERNAL = 0x6, + NVME_SC_ABORT_REQ = 0x7, + NVME_SC_ABORT_QUEUE = 0x8, + NVME_SC_FUSED_FAIL = 0x9, + NVME_SC_FUSED_MISSING = 0xa, + NVME_SC_INVALID_NS = 0xb, + NVME_SC_CMD_SEQ_ERROR = 0xc, + NVME_SC_SGL_INVALID_LAST = 0xd, + NVME_SC_SGL_INVALID_COUNT = 0xe, + NVME_SC_SGL_INVALID_DATA = 0xf, + NVME_SC_SGL_INVALID_METADATA = 0x10, + NVME_SC_SGL_INVALID_TYPE = 0x11, + NVME_SC_CMB_INVALID_USE = 0x12, + NVME_SC_PRP_INVALID_OFFSET = 0x13, + NVME_SC_AWU_EXCEEDED = 0x14, + NVME_SC_OP_DENIED = 0x15, + NVME_SC_SGL_INVALID_OFFSET = 0x16, + NVME_SC_HOSTID_FORMAT = 0x18, + NVME_SC_KAT_EXPIRED = 0x19, + NVME_SC_KAT_INVALID = 0x1a, + NVME_SC_CMD_ABORTED_PREMEPT = 0x1b, + NVME_SC_SANITIZE_FAILED = 0x1c, + NVME_SC_SANITIZE_IN_PROGRESS = 0x1d, + NVME_SC_SGL_INVALID_GRANULARITY = 0x1e, + NVME_SC_CMD_IN_CMBQ_NOT_SUPP = 0x1f, + NVME_SC_NS_WRITE_PROTECTED = 0x20, + NVME_SC_CMD_INTERRUPTED = 0x21, + NVME_SC_TRAN_TPORT_ERROR = 0x22, + NVME_SC_PROHIBITED_BY_CMD_AND_FEAT = 0x23, + NVME_SC_ADMIN_CMD_MEDIA_NOT_READY = 0x24, + NVME_SC_LBA_RANGE = 0x80, + NVME_SC_CAP_EXCEEDED = 0x81, + NVME_SC_NS_NOT_READY = 0x82, + NVME_SC_RESERVATION_CONFLICT = 0x83, + NVME_SC_FORMAT_IN_PROGRESS = 0x84, /* * Command Specific Status Codes: */ - NVME_SC_CQ_INVALID = 0x00, - NVME_SC_QID_INVALID = 0x01, - NVME_SC_QUEUE_SIZE = 0x02, - NVME_SC_ABORT_LIMIT = 0x03, - NVME_SC_ABORT_MISSING = 0x04, - NVME_SC_ASYNC_LIMIT = 0x05, - NVME_SC_FIRMWARE_SLOT = 0x06, - NVME_SC_FIRMWARE_IMAGE = 0x07, - NVME_SC_INVALID_VECTOR = 0x08, - NVME_SC_INVALID_LOG_PAGE = 0x09, - NVME_SC_INVALID_FORMAT = 0x0a, - NVME_SC_FW_NEEDS_CONV_RESET = 0x0b, - NVME_SC_INVALID_QUEUE = 0x0c, - NVME_SC_FEATURE_NOT_SAVEABLE = 0x0d, - NVME_SC_FEATURE_NOT_CHANGEABLE = 0x0e, - NVME_SC_FEATURE_NOT_PER_NS = 0x0f, - NVME_SC_FW_NEEDS_SUBSYS_RESET = 0x10, - NVME_SC_FW_NEEDS_RESET = 0x11, - NVME_SC_FW_NEEDS_MAX_TIME = 0x12, - NVME_SC_FW_ACTIVATE_PROHIBITED = 0x13, - NVME_SC_OVERLAPPING_RANGE = 0x14, - NVME_SC_NS_INSUFFICIENT_CAP = 0x15, - NVME_SC_NS_ID_UNAVAILABLE = 0x16, - NVME_SC_NS_ALREADY_ATTACHED = 0x18, - NVME_SC_NS_IS_PRIVATE = 0x19, - NVME_SC_NS_NOT_ATTACHED = 0x1a, - NVME_SC_THIN_PROV_NOT_SUPP = 0x1b, - NVME_SC_CTRL_LIST_INVALID = 0x1c, - NVME_SC_SELF_TEST_IN_PROGRESS = 0x1d, - NVME_SC_BP_WRITE_PROHIBITED = 0x1e, - NVME_SC_INVALID_CTRL_ID = 0x1f, - NVME_SC_INVALID_SEC_CTRL_STATE = 0x20, - NVME_SC_INVALID_CTRL_RESOURCES = 0x21, - NVME_SC_INVALID_RESOURCE_ID = 0x22, - NVME_SC_PMR_SAN_PROHIBITED = 0x23, - NVME_SC_ANA_GROUP_ID_INVALID = 0x24, - NVME_SC_ANA_ATTACH_FAILED = 0x25, + NVME_SC_CQ_INVALID = 0x00, + NVME_SC_QID_INVALID = 0x01, + NVME_SC_QUEUE_SIZE = 0x02, + NVME_SC_ABORT_LIMIT = 0x03, + NVME_SC_ABORT_MISSING = 0x04, + NVME_SC_ASYNC_LIMIT = 0x05, + NVME_SC_FIRMWARE_SLOT = 0x06, + NVME_SC_FIRMWARE_IMAGE = 0x07, + NVME_SC_INVALID_VECTOR = 0x08, + NVME_SC_INVALID_LOG_PAGE = 0x09, + NVME_SC_INVALID_FORMAT = 0x0a, + NVME_SC_FW_NEEDS_CONV_RESET = 0x0b, + NVME_SC_INVALID_QUEUE = 0x0c, + NVME_SC_FEATURE_NOT_SAVEABLE = 0x0d, + NVME_SC_FEATURE_NOT_CHANGEABLE = 0x0e, + NVME_SC_FEATURE_NOT_PER_NS = 0x0f, + NVME_SC_FW_NEEDS_SUBSYS_RESET = 0x10, + NVME_SC_FW_NEEDS_RESET = 0x11, + NVME_SC_FW_NEEDS_MAX_TIME = 0x12, + NVME_SC_FW_ACTIVATE_PROHIBITED = 0x13, + NVME_SC_OVERLAPPING_RANGE = 0x14, + NVME_SC_NS_INSUFFICIENT_CAP = 0x15, + NVME_SC_NS_ID_UNAVAILABLE = 0x16, + NVME_SC_NS_ALREADY_ATTACHED = 0x18, + NVME_SC_NS_IS_PRIVATE = 0x19, + NVME_SC_NS_NOT_ATTACHED = 0x1a, + NVME_SC_THIN_PROV_NOT_SUPP = 0x1b, + NVME_SC_CTRL_LIST_INVALID = 0x1c, + NVME_SC_SELF_TEST_IN_PROGRESS = 0x1d, + NVME_SC_BP_WRITE_PROHIBITED = 0x1e, + NVME_SC_INVALID_CTRL_ID = 0x1f, + NVME_SC_INVALID_SEC_CTRL_STATE = 0x20, + NVME_SC_INVALID_CTRL_RESOURCES = 0x21, + NVME_SC_INVALID_RESOURCE_ID = 0x22, + NVME_SC_PMR_SAN_PROHIBITED = 0x23, + NVME_SC_ANA_GROUP_ID_INVALID = 0x24, + NVME_SC_ANA_ATTACH_FAILED = 0x25, + NVME_SC_INSUFFICIENT_CAP = 0x26, + NVME_SC_NS_ATTACHMENT_LIMIT_EXCEEDED = 0x27, + NVME_SC_PROHIBIT_CMD_EXEC_NOT_SUPPORTED = 0x28, + + /* + * Command Set Specific - Namespace Types commands: + */ + NVME_SC_IOCS_NOT_SUPPORTED = 0x29, + NVME_SC_IOCS_NOT_ENABLED = 0x2a, + NVME_SC_IOCS_COMBINATION_REJECTED = 0x2b, + NVME_SC_INVALID_IOCS = 0x2c, + NVME_SC_ID_UNAVAILABLE = 0x2d, /* * I/O Command Set Specific - NVM commands: @@ -4574,6 +4635,7 @@ enum nvme_status_field { NVME_SC_BAD_ATTRIBUTES = 0x80, NVME_SC_INVALID_PI = 0x81, NVME_SC_READ_ONLY = 0x82, + NVME_SC_CMD_SIZE_LIMIT_EXCEEDED = 0x83, /* * I/O Command Set Specific - Fabrics commands: @@ -4610,6 +4672,7 @@ enum nvme_status_field { NVME_SC_COMPARE_FAILED = 0x85, NVME_SC_ACCESS_DENIED = 0x86, NVME_SC_UNWRITTEN_BLOCK = 0x87, + NVME_SC_STORAGE_TAG_CHECK = 0x88, /* * Path-related Errors: From 45387011e22c3bdfe83df8123d037b7ee2be626f Mon Sep 17 00:00:00 2001 From: Tomas Bzatek Date: Fri, 23 Jul 2021 16:03:02 +0200 Subject: [PATCH 0138/1564] util: Add strings for new status codes --- src/nvme/util.c | 193 +++++++++++++++++++++++++++--------------------- 1 file changed, 107 insertions(+), 86 deletions(-) diff --git a/src/nvme/util.c b/src/nvme/util.c index 5ea67e2002..0167f45ef6 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -157,90 +157,110 @@ __u8 nvme_status_to_errno(int status, bool fabrics) } static const char * const generic_status[] = { - [NVME_SC_SUCCESS] = "Successful Completion: The command completed without error", - [NVME_SC_INVALID_OPCODE] = "Invalid Command Opcode: A reserved coded 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", - [NVME_SC_CMDID_CONFLICT] = "Command ID Conflict: The command 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", - [NVME_SC_POWER_LOSS] = "Commands Aborted due to Power Loss 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", - [NVME_SC_ABORT_REQ] = "Command Abort Requested: The command was aborted due to an Abort command", - [NVME_SC_ABORT_QUEUE] = "Command Aborted due to SQ Deletion: The command was aborted due to a Delete I/O Submission Queue", - [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", - [NVME_SC_FUSED_MISSING] = "Command Aborted due to Missing Fused Command: The fused command was aborted due to the adjacent submission queue entry not containing a fused command", - [NVME_SC_INVALID_NS] = "Invalid Namespace or Format: The 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", - [NVME_SC_SGL_INVALID_LAST] = "Invalid SGL Segment Descriptor: The 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", - [NVME_SC_SGL_INVALID_DATA] = "Data SGL Length Invalid: The length of a Data SGL is too short or too long and the controller does not support SGL transfers longer than the amount of data to be transferred", - [NVME_SC_SGL_INVALID_METADATA] = "Metadata SGL Length Invalid: The length of a Metadata SGL is too short or too long and the controller does not support SGL transfers longer than the amount of data to be transferred", - [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", - [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", - [NVME_SC_AWU_EXCEEDED] = "Atomic Write Unit Exceeded: The length specified exceeds the atomic write unit size", - [NVME_SC_OP_DENIED] = "Operation Denied: The command was denied due to lack of access rights", - [NVME_SC_SGL_INVALID_OFFSET] = "SGL Offset Invalid: The offset specified in a descriptor is invalid", - [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", - [NVME_SC_KAT_EXPIRED] = "Keep Alive Timer Expired: The Keep Alive Timer expired", - [NVME_SC_KAT_INVALID] = "Keep Alive Timeout Invalid: The Keep 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", - [NVME_SC_SANITIZE_FAILED] = "Sanitize Failed: The most recent sanitize operation failed and no recovery action has been successfully completed", - [NVME_SC_SANITIZE_IN_PROGRESS] = "Sanitize In Progress: The requested function 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", - [NVME_SC_CMD_IN_CMBQ_NOT_SUPP] = "Command Not Supported for Queue in CMB: The controller does not support Submission Queue in the Controller Memory Buffer or 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", - [NVME_SC_CMD_INTERRUPTED] = "Command Interrupted: Command processing was interrupted and the controller is unable to successfully complete the command", - [NVME_SC_TRAN_TPORT_ERROR] = "Transient Transport Error: A transient transport error was detected", - [NVME_SC_LBA_RANGE] = "LBA Out of Range: The command references 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", - [NVME_SC_NS_NOT_READY] = "Namespace Not Ready: The namespace is not ready to be accessed", - [NVME_SC_RESERVATION_CONFLICT] = "Reservation Conflict: The command was 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", + [NVME_SC_SUCCESS] = "Successful Completion: The command completed without error", + [NVME_SC_INVALID_OPCODE] = "Invalid Command Opcode: A reserved coded 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", + [NVME_SC_CMDID_CONFLICT] = "Command ID Conflict: The command 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", + [NVME_SC_POWER_LOSS] = "Commands Aborted due to Power Loss 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", + [NVME_SC_ABORT_REQ] = "Command Abort Requested: The command was aborted due to an Abort command", + [NVME_SC_ABORT_QUEUE] = "Command Aborted due to SQ Deletion: The command was aborted due to a Delete I/O Submission Queue", + [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", + [NVME_SC_FUSED_MISSING] = "Command Aborted due to Missing Fused Command: The fused command was aborted due to the adjacent submission queue entry not containing a fused command", + [NVME_SC_INVALID_NS] = "Invalid Namespace or Format: The 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", + [NVME_SC_SGL_INVALID_LAST] = "Invalid SGL Segment Descriptor: The 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", + [NVME_SC_SGL_INVALID_DATA] = "Data SGL Length Invalid: The length of a Data SGL is too short or too long and the controller does not support SGL transfers longer than the amount of data to be transferred", + [NVME_SC_SGL_INVALID_METADATA] = "Metadata SGL Length Invalid: The length of a Metadata SGL is too short or too long and the controller does not support SGL transfers longer than the amount of data to be transferred", + [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", + [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", + [NVME_SC_AWU_EXCEEDED] = "Atomic Write Unit Exceeded: The length specified exceeds the atomic write unit size", + [NVME_SC_OP_DENIED] = "Operation Denied: The command was denied due to lack of access rights", + [NVME_SC_SGL_INVALID_OFFSET] = "SGL Offset Invalid: The offset specified in a descriptor is invalid", + [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", + [NVME_SC_KAT_EXPIRED] = "Keep Alive Timer Expired: The Keep Alive Timer expired", + [NVME_SC_KAT_INVALID] = "Keep Alive Timeout Invalid: The Keep 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", + [NVME_SC_SANITIZE_FAILED] = "Sanitize Failed: The most recent sanitize operation failed and no recovery action has been successfully completed", + [NVME_SC_SANITIZE_IN_PROGRESS] = "Sanitize In Progress: The requested function 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", + [NVME_SC_CMD_IN_CMBQ_NOT_SUPP] = "Command Not Supported for Queue in CMB: The controller does not support Submission Queue in the Controller Memory Buffer or 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", + [NVME_SC_CMD_INTERRUPTED] = "Command Interrupted: Command processing was interrupted and the controller is unable to successfully complete the command", + [NVME_SC_TRAN_TPORT_ERROR] = "Transient Transport Error: A transient transport error was detected", + [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", + [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", + [NVME_SC_LBA_RANGE] = "LBA Out of Range: The command references 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", + [NVME_SC_NS_NOT_READY] = "Namespace Not Ready: The namespace is not ready to be accessed", + [NVME_SC_RESERVATION_CONFLICT] = "Reservation Conflict: The command was 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", }; static const char * const cmd_spec_status[] = { - [NVME_SC_CQ_INVALID] = "Completion Queue Invalid: The Completion 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 part of the command", - [NVME_SC_QUEUE_SIZE] = "Invalid Queue Size: The host attempted to 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", - [NVME_SC_ASYNC_LIMIT] = "Asynchronous Event Request Limit 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", - [NVME_SC_FIRMWARE_IMAGE] = "Invalid Firmware Image: The firmware 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", - [NVME_SC_INVALID_LOG_PAGE] = "Invalid Log Page: The log page indicated is invalid", - [NVME_SC_INVALID_FORMAT] = "Invalid Format: The LBA Format specified 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", - [NVME_SC_INVALID_QUEUE] = "Invalid Queue Deletion: Invalid I/O Completion Queue specified to delete", - [NVME_SC_FEATURE_NOT_SAVEABLE] = "Feature Identifier Not Saveable: The 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", - [NVME_SC_FEATURE_NOT_PER_NS] = "Feature Not Namespace Specific: The Feature Identifier specified is not namespace specific", - [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", - [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", - [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", - [NVME_SC_FW_ACTIVATE_PROHIBITED] = "Firmware Activation Prohibited: The image 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", - [NVME_SC_NS_INSUFFICIENT_CAP] = "Namespace Insufficient Capacity: Creating 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", - [NVME_SC_NS_ALREADY_ATTACHED] = "Namespace Already Attached: The 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", - [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", - [NVME_SC_THIN_PROV_NOT_SUPP] = "Thin Provisioning Not Supported: Thin provisioning is not supported by the controller", - [NVME_SC_CTRL_LIST_INVALID] = "Controller List Invalid: The controller list provided contains invalid controller ids", - [NVME_SC_SELF_TEST_IN_PROGRESS] = "Device Self-test In Progress", - [NVME_SC_BP_WRITE_PROHIBITED] = "Boot Partition Write Prohibited: The command tried to modify a locked Boot Partition", - [NVME_SC_INVALID_CTRL_ID] = "Invalid Controller Identifier: An invalid controller id was specified", - [NVME_SC_INVALID_SEC_CTRL_STATE] = "Invalid Secondary Controller State: The requested secondary controller action is invalid based on the secondary and primary controllers current states", - [NVME_SC_INVALID_CTRL_RESOURCES] = "Invalid Number of Controller Resources: The specified number of Flexible Resources is invalid", - [NVME_SC_INVALID_RESOURCE_ID] = "Invalid Resource Identifier: At least one of the specified resource identifiers was invalid", - [NVME_SC_PMR_SAN_PROHIBITED] = "Sanitize Prohibited While Persistent Memory Region is Enabled", - [NVME_SC_ANA_GROUP_ID_INVALID] = "ANA Group Identifier Invalid", - [NVME_SC_ANA_ATTACH_FAILED] = "ANA Attach Failed: The command's specified ANA Group Identifier is not supported", + [NVME_SC_CQ_INVALID] = "Completion Queue Invalid: The Completion 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 part of the command", + [NVME_SC_QUEUE_SIZE] = "Invalid Queue Size: The host attempted to 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", + [NVME_SC_ABORT_MISSING] = "Abort Command Is Missing: The abort command is missing", + [NVME_SC_ASYNC_LIMIT] = "Asynchronous Event Request Limit 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", + [NVME_SC_FIRMWARE_IMAGE] = "Invalid Firmware Image: The firmware 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", + [NVME_SC_INVALID_LOG_PAGE] = "Invalid Log Page: The log page indicated is invalid", + [NVME_SC_INVALID_FORMAT] = "Invalid Format: The LBA Format specified 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", + [NVME_SC_INVALID_QUEUE] = "Invalid Queue Deletion: Invalid I/O Completion Queue specified to delete", + [NVME_SC_FEATURE_NOT_SAVEABLE] = "Feature Identifier Not Saveable: The 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", + [NVME_SC_FEATURE_NOT_PER_NS] = "Feature Not Namespace Specific: The Feature Identifier specified is not namespace specific", + [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", + [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", + [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", + [NVME_SC_FW_ACTIVATE_PROHIBITED] = "Firmware Activation Prohibited: The image 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", + [NVME_SC_NS_INSUFFICIENT_CAP] = "Namespace Insufficient Capacity: Creating 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", + [NVME_SC_NS_ALREADY_ATTACHED] = "Namespace Already Attached: The 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", + [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", + [NVME_SC_THIN_PROV_NOT_SUPP] = "Thin Provisioning Not Supported: Thin provisioning is not supported by the controller", + [NVME_SC_CTRL_LIST_INVALID] = "Controller List Invalid: The controller 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", + [NVME_SC_BP_WRITE_PROHIBITED] = "Boot Partition Write Prohibited: The command tried to modify a locked Boot Partition", + [NVME_SC_INVALID_CTRL_ID] = "Invalid Controller Identifier: An invalid controller id was specified", + [NVME_SC_INVALID_SEC_CTRL_STATE] = "Invalid Secondary Controller State: The requested secondary controller action is invalid based on the secondary and primary controllers current states", + [NVME_SC_INVALID_CTRL_RESOURCES] = "Invalid Number of Controller Resources: The specified number of Flexible Resources is invalid", + [NVME_SC_INVALID_RESOURCE_ID] = "Invalid Resource Identifier: At least one of the specified resource identifiers was invalid", + [NVME_SC_PMR_SAN_PROHIBITED] = "Sanitize Prohibited While Persistent 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", + [NVME_SC_ANA_ATTACH_FAILED] = "ANA Attach Failed: The controller is not 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", + [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", + [NVME_SC_PROHIBIT_CMD_EXEC_NOT_SUPPORTED] = "Prohibition of Command Execution Not Supported", + [NVME_SC_IOCS_NOT_SUPPORTED] = "The I/O command set is not supported", + [NVME_SC_IOCS_NOT_ENABLED] = "The I/O command set is not enabled", + [NVME_SC_IOCS_COMBINATION_REJECTED] = "The I/O command set combination is rejected", + [NVME_SC_INVALID_IOCS] = "The I/O command set is invalid", + [NVME_SC_ID_UNAVAILABLE] = "Identifier Unavailable: The number of Endurance Groups or NVM Sets supported has been exceeded", }; static const char * const nvm_status[] = { - [NVME_SC_BAD_ATTRIBUTES] = "Conflicting Attributes: The attributes specified in the command are conflicting", - [NVME_SC_INVALID_PI] = "Invalid Protection Information: The command's Protection Information Field settings are invalid for the namespace's Protection Information format", - [NVME_SC_READ_ONLY] = "Attempted Write to Read Only Range: The LBA range specified contains read-only blocks", + [NVME_SC_BAD_ATTRIBUTES] = "Conflicting Attributes: The attributes specified in the command are conflicting", + [NVME_SC_INVALID_PI] = "Invalid Protection Information: The command's Protection Information Field settings are invalid for the namespace's Protection Information format", + [NVME_SC_READ_ONLY] = "Attempted Write to Read Only Range: The LBA range specified contains read-only blocks", + [NVME_SC_CMD_SIZE_LIMIT_EXCEEDED] = "Command Size Limit Exceeded", + [NVME_SC_ZNS_BOUNDARY_ERROR] = "Zoned Boundary Error: Invalid Zone Boundary crossing", + [NVME_SC_ZNS_FULL] = "Zone Is Full: The accessed zone is in ZSF:Full state", + [NVME_SC_ZNS_READ_ONLY] = "Zone Is Read Only: The accessed zone is in ZSRO:Read Only state", + [NVME_SC_ZNS_OFFLINE] = "Zone Is Offline: The access zone is in ZSO:Offline state", + [NVME_SC_ZNS_INVALID_WRITE] = "Zone Invalid Write: The write to zone was not at the write pointer offset", + [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", + [NVME_SC_ZNS_INVAL_TRANSITION] = "Invalid Zone State Transition: The request is not a valid zone state transition", }; static const char * const nvmf_status[] = { @@ -255,14 +275,15 @@ static const char * const nvmf_status[] = { }; static const char * const media_status[] = { - [NVME_SC_WRITE_FAULT] = "Write Fault: The write data could not be committed to the media", - [NVME_SC_READ_ERROR] = "Unrecovered Read Error: The read data 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", - [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", - [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", - [NVME_SC_COMPARE_FAILED] = "Compare Failure: The command failed due 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", - [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", + [NVME_SC_WRITE_FAULT] = "Write Fault: The write data could not be committed to the media", + [NVME_SC_READ_ERROR] = "Unrecovered Read Error: The read data 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", + [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", + [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", + [NVME_SC_COMPARE_FAILED] = "Compare Failure: The command failed due 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", + [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", + [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", }; static const char * const path_status[] = { From d9ce0800b11f14d591c270998aed98a3b6d6d27f Mon Sep 17 00:00:00 2001 From: Tomas Bzatek Date: Fri, 23 Jul 2021 16:16:47 +0200 Subject: [PATCH 0139/1564] build: Fix build without json-c --- src/Makefile | 2 +- src/nvme/tree.c | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index cf767e26ce..2c9b996b75 100644 --- a/src/Makefile +++ b/src/Makefile @@ -50,7 +50,7 @@ libnvme_priv := nvme/private.h libnvme_api := libnvme.h nvme/types.h nvme/ioctl.h nvme/filters.h nvme/tree.h nvme/util.h nvme/fabrics.h libnvme_srcs := nvme/ioctl.c nvme/filters.c nvme/fabrics.c nvme/util.c nvme/tree.c nvme/log.c nvme/cleanup.c libnvme_swig := nvme/libnvme.i -ifneq ($(CONFIG_JSONC),0) +ifeq ($(CONFIG_JSONC),y) override libnvme_srcs += nvme/json.c endif libnvme_objs := $(patsubst %.c,%.ol,$(libnvme_srcs)) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index de3bb585ae..2c8192fd07 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -101,10 +101,12 @@ nvme_root_t nvme_scan(const char *config_file) { nvme_root_t r = nvme_scan_filter(NULL); +#ifdef CONFIG_JSONC if (r && config_file) { json_read_config(r, config_file); r->config_file = strdup(config_file); } +#endif return r; } @@ -112,7 +114,12 @@ int nvme_update_config(nvme_root_t r) { if (!r->modified || !r->config_file) return 0; +#ifdef CONFIG_JSONC return json_update_config(r, r->config_file); +#else + errno = ENOTSUP; + return -1; +#endif } nvme_host_t nvme_first_host(nvme_root_t r) From 05bca7e1c0ff283f0a82be8e925c382586140a00 Mon Sep 17 00:00:00 2001 From: Martin Belanger Date: Fri, 23 Jul 2021 15:35:17 -0400 Subject: [PATCH 0140/1564] Bug fix in Python SWIG module --- pynvme/nvme.i | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/pynvme/nvme.i b/pynvme/nvme.i index 18a3261783..919361727f 100644 --- a/pynvme/nvme.i +++ b/pynvme/nvme.i @@ -125,36 +125,32 @@ static int discover_err = 0; %typemap(in) struct nvme_fabrics_config * ($*1_type temp) { Py_ssize_t pos = 0; PyObject *key, *value; - char *keystr; - memset(&temp, 0, sizeof(struct nvme_fabrics_config)); + memset(&temp, 0, sizeof(temp)); temp.tos = -1; temp.ctrl_loss_tmo = NVMF_DEF_CTRL_LOSS_TMO; while (PyDict_Next($input, &pos, &key, &value)) { - keystr = PyString_AsString(key); - if (!keystr) - continue; - if (!strcmp(keystr, "nr_io_queues")) + if (!PyUnicode_CompareWithASCIIString(key, "nr_io_queues")) temp.nr_io_queues = PyLong_AsLong(value); - if (!strcmp(keystr, "reconnect_delay")) + if (!PyUnicode_CompareWithASCIIString(key, "reconnect_delay")) temp.reconnect_delay = PyLong_AsLong(value); - if (!strcmp(keystr, "ctrl_loss_tmo")) + if (!PyUnicode_CompareWithASCIIString(key, "ctrl_loss_tmo")) temp.ctrl_loss_tmo = PyLong_AsLong(value); - if (!strcmp(keystr, "keep_alive_tmo")) + if (!PyUnicode_CompareWithASCIIString(key, "keep_alive_tmo")) temp.keep_alive_tmo = PyLong_AsLong(value); - if (!strcmp(keystr, "nr_write_queues")) + if (!PyUnicode_CompareWithASCIIString(key, "nr_write_queues")) temp.nr_write_queues = PyLong_AsLong(value); - if (!strcmp(keystr, "nr_poll_queues")) + if (!PyUnicode_CompareWithASCIIString(key, "nr_poll_queues")) temp.nr_poll_queues = PyLong_AsLong(value); - if (!strcmp(keystr, "tos")) + if (!PyUnicode_CompareWithASCIIString(key, "tos")) temp.tos = PyLong_AsLong(value); - if (!strcmp(keystr, "duplicate_connect")) - temp.duplicate_connect = PyLong_AsLong(value); - if (!strcmp(keystr, "disable_sqflow")) - temp.disable_sqflow = PyLong_AsLong(value); - if (!strcmp(keystr, "hdr_digest")) - temp.hdr_digest = PyLong_AsLong(value); - if (!strcmp(keystr, "data_digest")) - temp.data_digest = PyLong_AsLong(value); + if (!PyUnicode_CompareWithASCIIString(key, "duplicate_connect")) + temp.duplicate_connect = PyObject_IsTrue(value) ? true : false; + if (!PyUnicode_CompareWithASCIIString(key, "disable_sqflow")) + temp.disable_sqflow = PyObject_IsTrue(value) ? true : false; + if (!PyUnicode_CompareWithASCIIString(key, "hdr_digest")) + temp.hdr_digest = PyObject_IsTrue(value) ? true : false; + if (!PyUnicode_CompareWithASCIIString(key, "data_digest")) + temp.data_digest = PyObject_IsTrue(value) ? true : false; } $1 = &temp; }; From b6b63d6b2d0ede7afcbae5d0509a4fbe5bcd4772 Mon Sep 17 00:00:00 2001 From: Tomas Bzatek Date: Tue, 3 Aug 2021 18:29:53 +0200 Subject: [PATCH 0141/1564] types: Device self-test doc strings update Doc strings update related to the device self-test log page retrieval and the self-test command issue. API changes: * renamed NVME_ST_CODE_RESRVED -> NVME_ST_CODE_RESERVED * added enum nvme_st_curr_op definiton --- src/nvme/ioctl.h | 12 ++-- src/nvme/types.h | 184 +++++++++++++++++++++++++++++++++++------------ 2 files changed, 144 insertions(+), 52 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index ef6faf1d1e..20cb75d184 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -715,7 +715,7 @@ enum nvme_directive_send_doper { }; /** - * enum - + * enum nvme_directive_send_identify_endir - */ enum nvme_directive_send_identify_endir { NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_DISABLE = 0, @@ -737,11 +737,11 @@ enum nvme_sanitize_sanact { }; /** - * enum nvme_dst_stc - - * @NVME_DST_STC_SHORT: - * @NVME_DST_STC_LONG: - * @NVME_DST_STC_VS: - * @NVME_DST_STC_ABORT: + * enum nvme_dst_stc - Action taken by the Device Self-test command + * @NVME_DST_STC_SHORT: Start a short device self-test operation + * @NVME_DST_STC_LONG: Start an extended device self-test operation + * @NVME_DST_STC_VS: Start a vendor specific device self-test operation + * @NVME_DST_STC_ABORT: Abort device self-test operation */ enum nvme_dst_stc { NVME_DST_STC_SHORT = 0x1, diff --git a/src/nvme/types.h b/src/nvme/types.h index 10e7b153ec..a07a925642 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -1041,11 +1041,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: - * @NVME_CTRL_CMIC_MULTI_CTRL: - * @NVME_CTRL_CMIC_MULTI_SRIOV: - * @NVME_CTRL_CMIC_MULTI_ANA_REPORTING: + * 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. */ enum nvme_id_ctrl_cmic { NVME_CTRL_CMIC_MULTI_PORT = 1 << 0, @@ -2548,16 +2561,42 @@ enum nvme_cmd_effects { }; /** - * struct nvme_st_result - - * @dsts: - * @seg: - * @vdi: - * @poh: - * @nsid: - * @flba: - * @sct: - * @sc: - * @vs: + * 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). + * @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. + * @vdi: Valid Diagnostic Information: Indicates the diagnostic failure + * information that is reported. See &enum nvme_st_valid_diag_info. + * @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. + * @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. + * @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. + * @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. + * @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. + * @vs: Vendor Specific. */ struct nvme_st_result { __u8 dsts; @@ -2573,23 +2612,32 @@ struct nvme_st_result { } __attribute__((packed)); /** - * enum nvme_status_result - - * @NVME_ST_RESULT_NO_ERR: - * @NVME_ST_RESULT_ABORTED: - * @NVME_ST_RESULT_CLR: - * @NVME_ST_RESULT_NS_REMOVED: - * @NVME_ST_RESULT_ABORTED_FORMAT: - * @NVME_ST_RESULT_FATAL_ERR: - * @NVME_ST_RESULT_UNKNOWN_SEG_FAIL: - * @NVME_ST_RESULT_KNOWN_SEG_FAIL: - * @NVME_ST_RESULT_ABORTED_UNKNOWN: - * @NVME_ST_RESULT_ABORTED_SANITIZE: - * @NVME_ST_RESULT_NOT_USED: - * @NVME_ST_RESULT_MASK: + * enum nvme_status_result - Result of the device self-test operation + * @NVME_ST_RESULT_NO_ERR: Operation completed without error. + * @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. + * @NVME_ST_RESULT_ABORTED_FORMAT: Operation was aborted due to the processing + * 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. + * @NVME_ST_RESULT_UNKNOWN_SEG_FAIL: Operation completed with a segment that failed + * 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. + * @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. */ enum nvme_status_result { - NVME_ST_RESULT_NO_ERR = 0x0, - NVME_ST_RESULT_ABORTED = 0x1, + NVME_ST_RESULT_NO_ERR = 0x0, + NVME_ST_RESULT_ABORTED = 0x1, NVME_ST_RESULT_CLR = 0x2, NVME_ST_RESULT_NS_REMOVED = 0x3, NVME_ST_RESULT_ABORTED_FORMAT = 0x4, @@ -2603,26 +2651,54 @@ enum nvme_status_result { }; /** - * enum nvme_st_code - - * @NVME_ST_CODE_NONE: - * @NVME_ST_CODE_SHORT: - * @NVME_ST_CODE_EXTENDED: - * @NVME_ST_CODE_VS: + * enum nvme_st_code - Self-test Code value + * @NVME_ST_CODE_RESERVED: Reserved. + * @NVME_ST_CODE_SHORT: Short device self-test operation. + * @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. */ enum nvme_st_code { - NVME_ST_CODE_SHIFT = 4, - NVME_ST_CODE_RESRVED = 0x0, + NVME_ST_CODE_RESERVED = 0x0, NVME_ST_CODE_SHORT = 0x1, NVME_ST_CODE_EXTENDED = 0x2, NVME_ST_CODE_VS = 0xe, + NVME_ST_CODE_SHIFT = 4, +}; + +/** + * enum nvme_st_curr_op - Current Device Self-Test Operation + * @NVME_ST_CURR_OP_NOT_RUNNING: No device self-test operation in progress. + * @NVME_ST_CURR_OP_SHORT: Short device self-test operation in progress. + * @NVME_ST_CURR_OP_EXTENDED: Extended device self-test operation in progress. + * @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. + * @NVME_ST_CURR_OP_CMPL_MASK: Mask to get the current operation completion value + * from the &struct nvme_self_test_log.completion field. + */ +enum nvme_st_curr_op { + NVME_ST_CURR_OP_NOT_RUNNING = 0x0, + NVME_ST_CURR_OP_SHORT = 0x1, + NVME_ST_CURR_OP_EXTENDED = 0x2, + NVME_ST_CURR_OP_VS = 0xe, + NVME_ST_CURR_OP_RESERVED = 0xf, + NVME_ST_CURR_OP_MASK = 0xf, + NVME_ST_CURR_OP_CMPL_MASK = 0x7f, }; /** - * enum nvme_st_valid_diag_info - - * @NVME_ST_VALID_DIAG_INFO_NSID: - * @NVME_ST_VALID_DIAG_INFO_FLBA: - * @NVME_ST_VALID_DIAG_INFO_SCT: - * @NVME_ST_VALID_DIAG_INFO_SC: + * 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. + * @NVME_ST_VALID_DIAG_INFO_FLBA: FLBA Valid: if set, then the contents of + * 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. */ enum nvme_st_valid_diag_info { NVME_ST_VALID_DIAG_INFO_NSID = 1 << 0, @@ -2632,10 +2708,26 @@ enum nvme_st_valid_diag_info { }; /** - * struct nvme_self_test_log - - * @current_operation: - * @completion: - * @result: + * 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. + * @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. + * @result: Self-test Result Data Structures, see &struct nvme_st_result. */ struct nvme_self_test_log { __u8 current_operation; From 0f8265b11cae3a4e7e71146ae7c6836ec2d9a632 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Thu, 1 Jul 2021 14:26:57 +0800 Subject: [PATCH 0142/1564] Separate libs from link flags to fix link-order compile failure Currently, builds fail for me with a link error: /usr/bin/ld: ../src//libnvme.a(tree.ol): in function `nvme_ns_get_uuid': src/nvme/tree.c:1321: undefined reference to `uuid_copy' /usr/bin/ld: ../src//libnvme.a(json.ol): in function `json_read_config': src/nvme/json.c:152: undefined reference to `json_object_from_file' Turns out my linker ("GNU ld (GNU Binutils for Debian) 2.35.2") is sensitive to object argument order - the dependent libs need to be listed last. This change splits the required libraries into a LIBS variable, used last on the Makefile rules to perform the link. Signed-off-by: Jeremy Kerr --- configure | 6 +++--- examples/Makefile | 2 +- src/Makefile | 2 +- test/Makefile | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/configure b/configure index c81f48ea4d..91a56d0546 100755 --- a/configure +++ b/configure @@ -228,16 +228,16 @@ print_config "cpp" "${cpp}" if test "$libuuid" = "yes"; then output_sym "CONFIG_LIBUUID" - echo "override LDFLAGS += -luuid" >> $config_host_mak + echo "override LIBS += -luuid" >> $config_host_mak echo "override LIB_DEPENDS += uuid" >> $config_host_mak fi if test "$systemd" = "yes"; then output_sym "CONFIG_SYSTEMD" - echo "override LDFLAGS += -lsystemd" >> $config_host_mak + echo "override LIBS += -lsystemd" >> $config_host_mak fi if test "$libjsonc" = "yes"; then output_sym "CONFIG_JSONC" - echo "override LDFLAGS += -ljson-c" >> $config_host_mak + echo "override LIBS += -ljson-c" >> $config_host_mak echo "override LIB_DEPENDS += json-c" >> $config_host_mak fi if test "$cpp" = "yes"; then diff --git a/examples/Makefile b/examples/Makefile index 24f8574660..c909c87e40 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -12,7 +12,7 @@ all_targets += telemetry-listen display-tree display-columnar discover-loop all: $(all_targets) %: %.c - $(QUIET_CC)$(CC) $(CFLAGS) -o $@ $< -lnvme ${LDFLAGS} + $(QUIET_CC)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lnvme $(LIBS) clean: rm -f $(all_targets) diff --git a/src/Makefile b/src/Makefile index a4c33dabab..b706a6da45 100644 --- a/src/Makefile +++ b/src/Makefile @@ -72,7 +72,7 @@ libnvme.a: $(libnvme_objs) $(libccan_objs) $(QUIET_RANLIB)$(RANLIB) libnvme.a $(libname): $(libnvme_sobjs) $(libccan_sobjs) libnvme.map - $(QUIET_CC)$(CC) $(SO_CFLAGS) -Wl,--version-script=libnvme.map -Wl,-soname=$(soname) -o $@ $(libnvme_sobjs) $(libccan_sobjs) $(LINK_FLAGS) + $(QUIET_CC)$(CC) $(SO_CFLAGS) -Wl,--version-script=libnvme.map -Wl,-soname=$(soname) -o $@ $(libnvme_sobjs) $(libccan_sobjs) $(LINK_FLAGS) $(LIBS) install: $(all_targets) $(INSTALL) -D -m 644 libnvme.a $(libdir)/libnvme.a diff --git a/test/Makefile b/test/Makefile index ed050d0bd6..2df695e0ce 100644 --- a/test/Makefile +++ b/test/Makefile @@ -23,10 +23,10 @@ all: $(all_targets) CXXFLAGS ?= -lstdc++ %: %.cc - $(QUIET_CC)$(CC) $(CFLAGS) $(LDFLAGS) $(CXXFLAGS) -o $@ $< -lnvme + $(QUIET_CC)$(CC) $(CFLAGS) $(LDFLAGS) $(CXXFLAGS) -o $@ $< -lnvme $(LIBS) %: %.c - $(QUIET_CC)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lnvme + $(QUIET_CC)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lnvme $(LIBS) clean: rm -f $(all_targets) From 2e02dd440718a73c752b2dbb7cfe022b91794b11 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Thu, 8 Jul 2021 12:46:43 +0800 Subject: [PATCH 0143/1564] Build c++ objects with c++ compiler We should use $(CXX) when building objects from .cc sources Signed-off-by: Jeremy Kerr --- test/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Makefile b/test/Makefile index 2df695e0ce..9327a4d46d 100644 --- a/test/Makefile +++ b/test/Makefile @@ -23,7 +23,7 @@ all: $(all_targets) CXXFLAGS ?= -lstdc++ %: %.cc - $(QUIET_CC)$(CC) $(CFLAGS) $(LDFLAGS) $(CXXFLAGS) -o $@ $< -lnvme $(LIBS) + $(QUIET_CC)$(CXX) $(CFLAGS) $(LDFLAGS) $(CXXFLAGS) -o $@ $< -lnvme $(LIBS) %: %.c $(QUIET_CC)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lnvme $(LIBS) From f72d5acef5968cc44e0400534155cbd125ca705f Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Mon, 2 Aug 2021 13:50:16 +0800 Subject: [PATCH 0144/1564] ioctl: Fix incorrect cdw initialisation in nvme_set_features We're not currently setting cdw15 in nvme_set_features due to a typo in the struct initialisation. This change fixes the init. Signed-off-by: Jeremy Kerr --- src/nvme/ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index edc4433b95..cac8e23693 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -755,7 +755,7 @@ int nvme_set_features(int fd, __u8 fid, __u32 nsid, __u32 cdw11, __u32 cdw12, .cdw11 = cdw11, .cdw12 = cdw12, .cdw14 = cdw14, - .cdw14 = cdw15, + .cdw15 = cdw15, }; return nvme_submit_admin_passthru(fd, &cmd, result); From 56255757be29a30ef0bf537783828c858796ad53 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 12 Aug 2021 11:28:31 +0200 Subject: [PATCH 0145/1564] tree: avoid crash on unset subsystem in nvme_ctrl_get_host{nqn,id} Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 2c8192fd07..6bcaf035ec 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -652,14 +652,14 @@ const char *nvme_ctrl_get_host_iface(nvme_ctrl_t c) const char *nvme_ctrl_get_hostnqn(nvme_ctrl_t c) { - if (!c->s) + if (!c->s || !c->s->h) return default_host->hostnqn; return c->s->h->hostnqn; } const char *nvme_ctrl_get_hostid(nvme_ctrl_t c) { - if (!c->s) + if (!c->s || !c->s->h) return default_host->hostid; return c->s->h->hostid; } From d23c2e027643c292a8794a470643ab1660e4b07d Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 12 Aug 2021 11:29:25 +0200 Subject: [PATCH 0146/1564] fabrics: add nvme_host_t as argument to build_options() build_options() can be called when the controller hasn't been instantiated; in that case the 'subsystem' link in the controller is empty, and there is no host associated with it. Rather than selecting the default nvme host (and thereby losing any different hostnqn settings which might have passed in from the commandline) we should be passing in the nvme host directly as argument to build_options(). Signed-off-by: Hannes Reinecke --- src/nvme/fabrics.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 16a99c2ca4..8295c45f63 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -213,7 +213,7 @@ static int add_argument(char **argstr, const char *tok, const char *arg) return 0; } -static int build_options(nvme_ctrl_t c, char **argstr) +static int build_options(nvme_host_t h, nvme_ctrl_t c, char **argstr) { struct nvme_fabrics_config *cfg = nvme_ctrl_get_config(c); const char *transport = nvme_ctrl_get_transport(c); @@ -245,8 +245,8 @@ static int build_options(nvme_ctrl_t c, char **argstr) } if (!strcmp(nvme_ctrl_get_subsysnqn(c), NVME_DISC_SUBSYS_NAME)) discover = true; - hostnqn = nvme_ctrl_get_hostnqn(c); - hostid = nvme_ctrl_get_hostid(c); + hostnqn = nvme_host_get_hostnqn(h); + hostid = nvme_host_get_hostid(h); if (add_argument(argstr, "transport", transport) || add_argument(argstr, "traddr", nvme_ctrl_get_traddr(c)) || @@ -347,12 +347,14 @@ static int __nvmf_add_ctrl(const char *argstr) int nvmf_add_ctrl_opts(nvme_ctrl_t c, struct nvme_fabrics_config *cfg) { + nvme_subsystem_t s = nvme_ctrl_get_subsystem(c); + nvme_host_t h = nvme_subsystem_get_host(s); char *argstr; int ret; cfg = merge_config(c, cfg); - ret = build_options(c, &argstr); + ret = build_options(h, c, &argstr); if (ret) return ret; @@ -374,7 +376,7 @@ int nvmf_add_ctrl(nvme_host_t h, nvme_ctrl_t c, nvme_ctrl_disable_sqflow(c, disable_sqflow); nvme_ctrl_set_discovered(c, true); - ret = build_options(c, &argstr); + ret = build_options(h, c, &argstr); if (ret) return ret; From e6184c0f276650f32ee650cf1517ef0e0ba8d2e1 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 12 Aug 2021 08:25:45 +0200 Subject: [PATCH 0147/1564] tree: set errno in nvme_create_ctrl() There is no reason why we shouldn't be setting errno in nvme_create_ctrl(); in fact, doing so will help with debugging. Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 6bcaf035ec..774427ff64 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -872,18 +872,25 @@ struct nvme_ctrl *nvme_create_ctrl(const char *subsysnqn, const char *transport, if (!transport) { nvme_msg(LOG_ERR, "No transport specified\n"); + errno = EINVAL; return NULL; } if (strncmp(transport, "loop", 4) && !traddr) { nvme_msg(LOG_ERR, "No transport address for '%s'\n", transport); + errno = EINVAL; return NULL; } if (!subsysnqn) { nvme_msg(LOG_ERR, "No subsystem NQN specified\n"); + errno = EINVAL; return NULL; } else if (!strcmp(subsysnqn, NVME_DISC_SUBSYS_NAME)) discovery = true; c = calloc(1, sizeof(*c)); + if (!c) { + errno = ENOMEM; + return NULL; + } c->fd = -1; c->cfg.tos = -1; list_head_init(&c->namespaces); @@ -909,6 +916,7 @@ struct nvme_ctrl *nvme_create_ctrl(const char *subsysnqn, const char *transport, !strncmp(transport, "tcp", 3)) { nvme_msg(LOG_ERR, "No trsvcid specified for '%s'\n", transport); + errno = EINVAL; __nvme_free_ctrl(c); c = NULL; } From 112ff5e48e2889b805255a246137ef59fb37b1cf Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 11 Aug 2021 10:59:42 +0200 Subject: [PATCH 0148/1564] json: use nvme_msg() instead of fprintf() Use nvme logging to make error output configurable. Signed-off-by: Hannes Reinecke --- src/nvme/json.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/nvme/json.c b/src/nvme/json.c index da4f18d3bf..faadf2d383 100644 --- a/src/nvme/json.c +++ b/src/nvme/json.c @@ -13,6 +13,7 @@ #include #include "fabrics.h" +#include "log.h" #define json_object_add_value_string(o, k, v) \ json_object_object_add(o, k, json_object_new_string(v)) @@ -151,7 +152,7 @@ void json_read_config(nvme_root_t r, const char *config_file) json_root = json_object_from_file(config_file); if (!json_root) { - fprintf(stderr, "Failed to read %s, %s\n", + nvme_msg(LOG_DEBUG, "Failed to read %s, %s\n", config_file, json_util_get_last_err()); return; } @@ -268,7 +269,7 @@ int json_update_config(nvme_root_t r, const char *config_file) } if (json_object_to_file_ext(config_file, json_root, JSON_C_TO_STRING_PRETTY) < 0) { - fprintf(stderr, "Failed to write %s, %s\n", + nvme_msg(LOG_ERR, "Failed to write %s, %s\n", config_file, json_util_get_last_err()); ret = -1; errno = EIO; From d98525151582801ee2e9e8ba8cd2641e1ce4cc92 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 12 Aug 2021 08:26:41 +0200 Subject: [PATCH 0149/1564] tree.h: remove stale declaration of nvme_ctrl_get_nqn() Signed-off-by: Hannes Reinecke --- src/nvme/tree.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/nvme/tree.h b/src/nvme/tree.h index c19b11389e..68f5cbfca9 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -723,14 +723,6 @@ const char *nvme_ctrl_get_sqsize(nvme_ctrl_t c); */ const char *nvme_ctrl_get_transport(nvme_ctrl_t c); -/** - * nvme_ctrl_get_nqn() - - * @c: - * - * Return: - */ -const char *nvme_ctrl_get_nqn(nvme_ctrl_t c); - /** * nvme_ctrl_get_subsysnqn() - * @c: From 28f5cf35ed34c3e421861597acc25296fe166e9e Mon Sep 17 00:00:00 2001 From: Martin Belanger Date: Thu, 12 Aug 2021 15:52:30 -0400 Subject: [PATCH 0150/1564] Default empty model attribute to 'undefined' --- src/nvme/tree.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 774427ff64..264cdf3589 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -385,10 +385,8 @@ static int nvme_init_subsystem(nvme_subsystem_t s, const char *name, const char *path) { s->model = nvme_get_attr(path, "model"); - if (!s->model) { - errno = ENODEV; - return -1; - } + if (!s->model) + s->model = strdup("undefined"); s->serial = nvme_get_attr(path, "serial"); s->firmware = nvme_get_attr(path, "firmware_rev"); s->name = strdup(name); @@ -1092,6 +1090,7 @@ int nvme_init_ctrl(nvme_host_t h, nvme_ctrl_t c, int instance) if (ret > 0) ret = nvme_init_subsystem(s, subsys_name, path); if (ret < 0) { + nvme_msg(LOG_ERR, "Failed to init subsystem %s\n", path); free(path); goto out_free_subsys; } From aad3881a446560e6add56202e8029183d5dd825d Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 13 Aug 2021 11:58:08 +0200 Subject: [PATCH 0151/1564] tree: rework topology for multiple hosts Our tree structure host->subsys->ctrl doesn't match the underlying topology; the subsystem actually just a container for controllers, and the hosts are specified on the controller level, not the subsystem level. So to flatten that into our tree structure we need to duplicate the subsystem objects for each host, and filter out the controllers such that only the controllers with the correct hostnqn will show up in our internal tree. Signed-off-by: Hannes Reinecke --- src/nvme/filters.c | 6 +++ src/nvme/filters.h | 8 ++++ src/nvme/tree.c | 116 +++++++++++++++++++++++++++++++++++---------- 3 files changed, 106 insertions(+), 24 deletions(-) diff --git a/src/nvme/filters.c b/src/nvme/filters.c index 06137f5f1a..0f6202f9e5 100644 --- a/src/nvme/filters.c +++ b/src/nvme/filters.c @@ -87,6 +87,12 @@ int nvme_subsys_filter(const struct dirent *d) return 0; } +int nvme_scan_ctrls(struct dirent ***ctrls) +{ + return scandir(nvme_ctrl_sysfs_dir, ctrls, nvme_ctrls_filter, + alphasort); +} + int nvme_scan_subsystems(struct dirent ***subsys) { return scandir(nvme_subsys_sysfs_dir, subsys, nvme_subsys_filter, diff --git a/src/nvme/filters.h b/src/nvme/filters.h index 52318311b0..6ff8473565 100644 --- a/src/nvme/filters.h +++ b/src/nvme/filters.h @@ -36,6 +36,14 @@ int nvme_paths_filter(const struct dirent *d); */ int nvme_ctrls_filter(const struct dirent *d); +/** + * nvme_scan_ctrls() - + * @ctrls: + * + * Return: + */ +int nvme_scan_ctrls(struct dirent ***ctrls); + /** * nvme_subsys_filter() - * @d: diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 264cdf3589..149c8ec045 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -34,9 +34,10 @@ static struct nvme_host *default_host; static void __nvme_free_host(nvme_host_t h); +static void __nvme_free_subsystem(nvme_subsystem_t c); static void __nvme_free_ctrl(nvme_ctrl_t c); static int nvme_subsystem_scan_namespace(struct nvme_subsystem *s, char *name); -static int nvme_scan_subsystem(struct nvme_root *r, char *name, +static int nvme_scan_subsystem(struct nvme_host *h, char *name, nvme_scan_filter_t f); static int nvme_subsystem_scan_ctrl(struct nvme_subsystem *s, char *name); static int nvme_ctrl_scan_namespace(struct nvme_ctrl *c, char *name); @@ -67,19 +68,65 @@ nvme_host_t nvme_default_host(nvme_root_t r) return h; } +static int nvme_scan_hosts(struct nvme_root *r) +{ + struct dirent **ctrls; + int ret, i; + + ret = nvme_scan_ctrls(&ctrls); + if (ret < 0) + return ret; + + for (i = 0; i < ret; i++) { + char *path, *hostnqn, *hostid; + + if (asprintf(&path, "%s/%s", nvme_ctrl_sysfs_dir, + ctrls[i]->d_name) < 0) { + errno = ENOMEM; + return -1; + } + hostnqn = nvme_get_attr(path, "hostnqn"); + hostid = nvme_get_attr(path, "hostid"); + nvme_lookup_host(r, hostnqn, hostid); + free(hostnqn); + if (hostid) + free(hostid); + free(path); + } + return 0; +} + static int nvme_scan_topology(struct nvme_root *r, nvme_scan_filter_t f) { struct dirent **subsys; int i, ret; + struct nvme_host *h, *_h; + ret = nvme_scan_hosts(r); + if (ret < 0) + return ret; ret = nvme_scan_subsystems(&subsys); if (ret < 0) return ret; - for (i = 0; i < ret; i++) - nvme_scan_subsystem(r, subsys[i]->d_name, f); + nvme_for_each_host(r, h) { + for (i = 0; i < ret; i++) + nvme_scan_subsystem(h, subsys[i]->d_name, f); + } - nvme_free_dirents(subsys, i); + nvme_free_dirents(subsys, ret); + + /* Prune hosts with empty subsystems */ + nvme_for_each_host_safe(r, h, _h) { + nvme_subsystem_t s, _s; + nvme_for_each_subsystem_safe(h, s, _s) { + if (list_empty(&s->ctrls) && + list_empty(&s->namespaces)) + __nvme_free_subsystem(s); + } + if (list_empty(&h->subsystems)) + __nvme_free_host(h); + } return 0; } @@ -395,33 +442,33 @@ static int nvme_init_subsystem(nvme_subsystem_t s, const char *name, return 0; } -static int nvme_scan_subsystem(struct nvme_root *r, char *name, +/* + * nvme_scan_subsystem + * + * This is slightly non-obvious, as the underlying topology is + * _not_ a tree. + * Rather we're having 'hosts' which have several 'controllers', + * each controller is exposed by a 'subsystem'. + * Note that each 'subsystem' may expose several 'controllers', + * but these do not necessarily belong to the same 'host'. + * In our abstraction we have a tree host->subsystem->controller, + * so to flatten the underlying topology into our tree we have + * to duplicate the 'subsystem' objects, one for each host. + * But that doesn't matter as the 'subsystem' list is per-host + * anyway, so the duplicate objects will never be seen by + * other hosts. + */ +static int nvme_scan_subsystem(struct nvme_host *h, char *name, nvme_scan_filter_t f) { struct nvme_subsystem *s; char *path, *subsysnqn; - char *hostnqn, *hostid = NULL; - nvme_host_t h = NULL; int ret; ret = asprintf(&path, "%s/%s", nvme_subsys_sysfs_dir, name); if (ret < 0) return ret; - hostnqn = nvme_get_attr(path, "hostnqn"); - if (hostnqn) { - hostid = nvme_get_attr(path, "hostid"); - h = nvme_lookup_host(r, hostnqn, hostid); - free(hostnqn); - if (hostid) - free(hostid); - } - if (!h) - h = nvme_default_host(r); - if (!h) { - errno = ENOMEM; - return -1; - } subsysnqn = nvme_get_attr(path, "subsysnqn"); if (!subsysnqn) { errno = ENODEV; @@ -1203,13 +1250,34 @@ nvme_ctrl_t nvme_scan_ctrl(nvme_root_t r, const char *name) static int nvme_subsystem_scan_ctrl(struct nvme_subsystem *s, char *name) { nvme_ctrl_t c; - char *path; + char *path, *hostnqn, *hostid; if (asprintf(&path, "%s/%s", s->sysfs_dir, name) < 0) { errno = ENOMEM; return -1; } - + hostnqn = nvme_get_attr(path, "hostnqn"); + if (hostnqn) { + if (strcmp(s->h->hostnqn, hostnqn)) { + nvme_msg(LOG_DEBUG, + "%s: skip ctrl %s for non-matching host %s\n", + __func__, name, s->h->hostnqn); + free(path); + return 0; + } + free(hostnqn); + } + hostid = nvme_get_attr(path, "hostid"); + if (hostid) { + if (s->h->hostid && strcmp(s->h->hostid, hostid)) { + nvme_msg(LOG_DEBUG, + "%s: skip ctrl %s for non-matching host %s\n", + __func__, name, s->h->hostid); + free(path); + return 0; + } + free(hostid); + } c = nvme_ctrl_alloc(s, path, name); if (!c) { free(path); @@ -1217,7 +1285,7 @@ static int nvme_subsystem_scan_ctrl(struct nvme_subsystem *s, char *name) } nvme_ctrl_scan_namespaces(c); nvme_ctrl_scan_paths(c); - + free(path); return 0; } From 5edf04e7f136b5c24c92992f8fe37ebb0d6e6ab2 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 13 Aug 2021 12:28:27 +0200 Subject: [PATCH 0152/1564] src/Makefile: fixup depencendy for private.h The Makefile references 'private.h' as 'libnvme_priv', not 'libnvme_private'. Signed-off-by: Hannes Reinecke --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index b706a6da45..721590f33c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -55,7 +55,7 @@ endif libnvme_objs := $(patsubst %.c,%.ol,$(libnvme_srcs)) libnvme_sobjs := $(patsubst %.c,%.os,$(libnvme_srcs)) -$(libnvme_objs) $(libnvme_sobjs): $(libnvme_api) $(libnvme_private) $(libccan_objs) +$(libnvme_objs) $(libnvme_sobjs): $(libnvme_api) $(libnvme_priv) $(libccan_objs) %.os: %.c $(QUIET_CC)$(CC) $(SO_CFLAGS) -c -o $@ $< From 7e4cf339d631ba9d598599bb33099922b8cde1f1 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 13 Aug 2021 12:33:17 +0200 Subject: [PATCH 0153/1564] private.h: drop 'hostid' and 'hostnqn' from nvme_ctrl_t Never referenced anywhere. Signed-off-by: Hannes Reinecke --- src/nvme/private.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/nvme/private.h b/src/nvme/private.h index a500f2d995..2a151bf861 100644 --- a/src/nvme/private.h +++ b/src/nvme/private.h @@ -71,8 +71,6 @@ struct nvme_ctrl { char *queue_count; char *serial; char *sqsize; - char *hostnqn; - char *hostid; char *transport; char *subsysnqn; char *traddr; From afa06a0dd5d55e2a2685c48ba49fa3235418972d Mon Sep 17 00:00:00 2001 From: Martin Belanger Date: Fri, 13 Aug 2021 09:08:26 -0400 Subject: [PATCH 0154/1564] Fix compiler warning --- src/nvme/fabrics.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 8295c45f63..bdbcb8317b 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -689,7 +689,9 @@ char *nvmf_hostnqn_generate() if (ret < 0) return NULL; - asprintf(&hostnqn, "nqn.2014-08.org.nvmexpress:uuid:%s\n", uuid_str); + if (asprintf(&hostnqn, "nqn.2014-08.org.nvmexpress:uuid:%s\n", uuid_str) < 0) + return NULL; + return hostnqn; } From 645a7b3208399d0f8e7d8e5ab3024af27d44d61e Mon Sep 17 00:00:00 2001 From: Martin Belanger Date: Thu, 19 Aug 2021 15:51:34 -0400 Subject: [PATCH 0155/1564] Fix memory leaks and double free --- src/nvme/tree.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 149c8ec045..a02e35bb26 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -475,16 +475,15 @@ static int nvme_scan_subsystem(struct nvme_host *h, char *name, goto free_path; } s = nvme_lookup_subsystem(h, name, subsysnqn); + free(subsysnqn); if (!s) { - free(subsysnqn); errno = ENOMEM; goto free_path; } - free(subsysnqn); if (!s->name) { ret = nvme_init_subsystem(s, name, path); if (ret < 0) - return ret; + goto free_path; } nvme_subsystem_scan_namespaces(s); @@ -1112,7 +1111,6 @@ int nvme_init_ctrl(nvme_host_t h, nvme_ctrl_t c, int instance) c->address = nvme_get_attr(path, "address"); if (!c->address) { - free(path); errno = ENXIO; ret = -1; goto out_free_name; @@ -1136,9 +1134,12 @@ int nvme_init_ctrl(nvme_host_t h, nvme_ctrl_t c, int instance) subsys_name); if (ret > 0) ret = nvme_init_subsystem(s, subsys_name, path); + else + path = NULL; if (ret < 0) { nvme_msg(LOG_ERR, "Failed to init subsystem %s\n", path); - free(path); + if (path) + free(path); goto out_free_subsys; } } @@ -1235,6 +1236,7 @@ nvme_ctrl_t nvme_scan_ctrl(nvme_root_t r, const char *name) return NULL; } s = nvme_lookup_subsystem(h, NULL, subsysnqn); + free(subsysnqn); if (!s) { free(path); errno = ENOMEM; @@ -1285,7 +1287,6 @@ static int nvme_subsystem_scan_ctrl(struct nvme_subsystem *s, char *name) } nvme_ctrl_scan_namespaces(c); nvme_ctrl_scan_paths(c); - free(path); return 0; } From 955a985d4fb081ef1a9bc3be0e04242063542ba3 Mon Sep 17 00:00:00 2001 From: Martin Belanger Date: Mon, 23 Aug 2021 13:52:38 -0400 Subject: [PATCH 0156/1564] Un-stub nvme_free_ctrl(). In other words, nvme_free_ctrl() will now properly delete ctrl objects --- src/nvme/tree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index a02e35bb26..0ac1d99f0d 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -830,9 +830,9 @@ static void __nvme_free_ctrl(nvme_ctrl_t c) free(c); } -/* Stub for SWIG */ void nvme_free_ctrl(nvme_ctrl_t c) { + __nvme_free_ctrl(c); } #define ____stringify(x...) #x From d94f6eb8865ed4a65aad62383f316a74c6c24792 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 2 Sep 2021 09:53:29 -0700 Subject: [PATCH 0157/1564] Revert "tree: rework topology for multiple hosts" The hosts check breaks pci This reverts commit aad3881a446560e6add56202e8029183d5dd825d. Link: https://github.com/linux-nvme/libnvme/issues/32 Signed-off-by: Keith Busch --- src/nvme/filters.c | 6 --- src/nvme/filters.h | 8 ---- src/nvme/tree.c | 114 +++++++++------------------------------------ 3 files changed, 23 insertions(+), 105 deletions(-) diff --git a/src/nvme/filters.c b/src/nvme/filters.c index 0f6202f9e5..06137f5f1a 100644 --- a/src/nvme/filters.c +++ b/src/nvme/filters.c @@ -87,12 +87,6 @@ int nvme_subsys_filter(const struct dirent *d) return 0; } -int nvme_scan_ctrls(struct dirent ***ctrls) -{ - return scandir(nvme_ctrl_sysfs_dir, ctrls, nvme_ctrls_filter, - alphasort); -} - int nvme_scan_subsystems(struct dirent ***subsys) { return scandir(nvme_subsys_sysfs_dir, subsys, nvme_subsys_filter, diff --git a/src/nvme/filters.h b/src/nvme/filters.h index 6ff8473565..52318311b0 100644 --- a/src/nvme/filters.h +++ b/src/nvme/filters.h @@ -36,14 +36,6 @@ int nvme_paths_filter(const struct dirent *d); */ int nvme_ctrls_filter(const struct dirent *d); -/** - * nvme_scan_ctrls() - - * @ctrls: - * - * Return: - */ -int nvme_scan_ctrls(struct dirent ***ctrls); - /** * nvme_subsys_filter() - * @d: diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 0ac1d99f0d..49815dba2e 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -34,10 +34,9 @@ static struct nvme_host *default_host; static void __nvme_free_host(nvme_host_t h); -static void __nvme_free_subsystem(nvme_subsystem_t c); static void __nvme_free_ctrl(nvme_ctrl_t c); static int nvme_subsystem_scan_namespace(struct nvme_subsystem *s, char *name); -static int nvme_scan_subsystem(struct nvme_host *h, char *name, +static int nvme_scan_subsystem(struct nvme_root *r, char *name, nvme_scan_filter_t f); static int nvme_subsystem_scan_ctrl(struct nvme_subsystem *s, char *name); static int nvme_ctrl_scan_namespace(struct nvme_ctrl *c, char *name); @@ -68,65 +67,19 @@ nvme_host_t nvme_default_host(nvme_root_t r) return h; } -static int nvme_scan_hosts(struct nvme_root *r) -{ - struct dirent **ctrls; - int ret, i; - - ret = nvme_scan_ctrls(&ctrls); - if (ret < 0) - return ret; - - for (i = 0; i < ret; i++) { - char *path, *hostnqn, *hostid; - - if (asprintf(&path, "%s/%s", nvme_ctrl_sysfs_dir, - ctrls[i]->d_name) < 0) { - errno = ENOMEM; - return -1; - } - hostnqn = nvme_get_attr(path, "hostnqn"); - hostid = nvme_get_attr(path, "hostid"); - nvme_lookup_host(r, hostnqn, hostid); - free(hostnqn); - if (hostid) - free(hostid); - free(path); - } - return 0; -} - static int nvme_scan_topology(struct nvme_root *r, nvme_scan_filter_t f) { struct dirent **subsys; int i, ret; - struct nvme_host *h, *_h; - ret = nvme_scan_hosts(r); - if (ret < 0) - return ret; ret = nvme_scan_subsystems(&subsys); if (ret < 0) return ret; - nvme_for_each_host(r, h) { - for (i = 0; i < ret; i++) - nvme_scan_subsystem(h, subsys[i]->d_name, f); - } - - nvme_free_dirents(subsys, ret); + for (i = 0; i < ret; i++) + nvme_scan_subsystem(r, subsys[i]->d_name, f); - /* Prune hosts with empty subsystems */ - nvme_for_each_host_safe(r, h, _h) { - nvme_subsystem_t s, _s; - nvme_for_each_subsystem_safe(h, s, _s) { - if (list_empty(&s->ctrls) && - list_empty(&s->namespaces)) - __nvme_free_subsystem(s); - } - if (list_empty(&h->subsystems)) - __nvme_free_host(h); - } + nvme_free_dirents(subsys, i); return 0; } @@ -442,33 +395,33 @@ static int nvme_init_subsystem(nvme_subsystem_t s, const char *name, return 0; } -/* - * nvme_scan_subsystem - * - * This is slightly non-obvious, as the underlying topology is - * _not_ a tree. - * Rather we're having 'hosts' which have several 'controllers', - * each controller is exposed by a 'subsystem'. - * Note that each 'subsystem' may expose several 'controllers', - * but these do not necessarily belong to the same 'host'. - * In our abstraction we have a tree host->subsystem->controller, - * so to flatten the underlying topology into our tree we have - * to duplicate the 'subsystem' objects, one for each host. - * But that doesn't matter as the 'subsystem' list is per-host - * anyway, so the duplicate objects will never be seen by - * other hosts. - */ -static int nvme_scan_subsystem(struct nvme_host *h, char *name, +static int nvme_scan_subsystem(struct nvme_root *r, char *name, nvme_scan_filter_t f) { struct nvme_subsystem *s; char *path, *subsysnqn; + char *hostnqn, *hostid = NULL; + nvme_host_t h = NULL; int ret; ret = asprintf(&path, "%s/%s", nvme_subsys_sysfs_dir, name); if (ret < 0) return ret; + hostnqn = nvme_get_attr(path, "hostnqn"); + if (hostnqn) { + hostid = nvme_get_attr(path, "hostid"); + h = nvme_lookup_host(r, hostnqn, hostid); + free(hostnqn); + if (hostid) + free(hostid); + } + if (!h) + h = nvme_default_host(r); + if (!h) { + errno = ENOMEM; + return -1; + } subsysnqn = nvme_get_attr(path, "subsysnqn"); if (!subsysnqn) { errno = ENODEV; @@ -1252,34 +1205,13 @@ nvme_ctrl_t nvme_scan_ctrl(nvme_root_t r, const char *name) static int nvme_subsystem_scan_ctrl(struct nvme_subsystem *s, char *name) { nvme_ctrl_t c; - char *path, *hostnqn, *hostid; + char *path; if (asprintf(&path, "%s/%s", s->sysfs_dir, name) < 0) { errno = ENOMEM; return -1; } - hostnqn = nvme_get_attr(path, "hostnqn"); - if (hostnqn) { - if (strcmp(s->h->hostnqn, hostnqn)) { - nvme_msg(LOG_DEBUG, - "%s: skip ctrl %s for non-matching host %s\n", - __func__, name, s->h->hostnqn); - free(path); - return 0; - } - free(hostnqn); - } - hostid = nvme_get_attr(path, "hostid"); - if (hostid) { - if (s->h->hostid && strcmp(s->h->hostid, hostid)) { - nvme_msg(LOG_DEBUG, - "%s: skip ctrl %s for non-matching host %s\n", - __func__, name, s->h->hostid); - free(path); - return 0; - } - free(hostid); - } + c = nvme_ctrl_alloc(s, path, name); if (!c) { free(path); From 76c8f69d001572fe9319e506d53c0d69691b43ac Mon Sep 17 00:00:00 2001 From: chengjike Date: Thu, 9 Sep 2021 22:57:09 +0800 Subject: [PATCH 0158/1564] fix path->nentry bugs The "path->nentry" is initialized after it is added to the list in "nvme_subsystem_set_path_ns" function. Signed-off-by: chengjike --- src/nvme/tree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 49815dba2e..293b0c0a2b 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -534,7 +534,6 @@ static int nvme_ctrl_scan_path(struct nvme_ctrl *c, char *name) p->name = strdup(name); p->sysfs_dir = path; p->ana_state = nvme_get_path_attr(p, "ana_state"); - nvme_subsystem_set_path_ns(c->s, p); grpid = nvme_get_path_attr(p, "ana_grpid"); if (grpid) { @@ -543,6 +542,7 @@ static int nvme_ctrl_scan_path(struct nvme_ctrl *c, char *name) } list_node_init(&p->nentry); + nvme_subsystem_set_path_ns(c->s, p); list_node_init(&p->entry); list_add(&c->paths, &p->entry); return 0; From 4fdb5027805387b3b5077381a7d81d67f277059b Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 10 Sep 2021 14:50:12 +0200 Subject: [PATCH 0159/1564] examples,test: depend on libnvme.a When libnvme is changed we should be rebuilding the example and test programs, too, to build them against the updated libnvme. Signed-off-by: Hannes Reinecke --- examples/Makefile | 2 +- test/Makefile | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/Makefile b/examples/Makefile index c909c87e40..7e3109851d 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -11,7 +11,7 @@ all_targets += telemetry-listen display-tree display-columnar discover-loop all: $(all_targets) -%: %.c +%: %.c ../src/libnvme.a $(QUIET_CC)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lnvme $(LIBS) clean: diff --git a/test/Makefile b/test/Makefile index 9327a4d46d..0c4eb361b1 100644 --- a/test/Makefile +++ b/test/Makefile @@ -22,10 +22,10 @@ all: $(all_targets) CXXFLAGS ?= -lstdc++ -%: %.cc +%: %.cc ../src/libnvme.a $(QUIET_CC)$(CXX) $(CFLAGS) $(LDFLAGS) $(CXXFLAGS) -o $@ $< -lnvme $(LIBS) -%: %.c +%: %.c ../src/libnvme.a $(QUIET_CC)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lnvme $(LIBS) clean: From c8a7cdb07ee094883d7af7093b1132d5517fe8dd Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 10 Sep 2021 18:06:03 +0200 Subject: [PATCH 0160/1564] tree: fixup crash on pcie controller for older kernels Older kernels do not provide an 'address' sysfs entry for 'pcie' controllers, causing a crash during scanning. Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 293b0c0a2b..6c46ef1b31 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -872,7 +872,8 @@ struct nvme_ctrl *nvme_create_ctrl(const char *subsysnqn, const char *transport, errno = EINVAL; return NULL; } - if (strncmp(transport, "loop", 4) && !traddr) { + if (strncmp(transport, "loop", 4) && + strncmp(transport, "pcie", 4) && !traddr) { nvme_msg(LOG_ERR, "No transport address for '%s'\n", transport); errno = EINVAL; return NULL; @@ -1109,7 +1110,7 @@ static nvme_ctrl_t nvme_ctrl_alloc(nvme_subsystem_t s, const char *path, const char *name) { nvme_ctrl_t c; - char *addr, *address, *a, *e; + char *addr, *address = NULL, *a, *e; char *transport, *traddr = NULL, *trsvcid = NULL; char *host_traddr = NULL, *host_iface = NULL; int ret; @@ -1121,7 +1122,14 @@ static nvme_ctrl_t nvme_ctrl_alloc(nvme_subsystem_t s, const char *path, } /* Parse 'address' string into components */ addr = nvme_get_attr(path, "address"); - address = strdup(addr); + if (!addr) { + /* Older kernel don't support pcie transport addresses */ + if (strcmp(transport, "pcie")) { + errno = ENXIO; + return NULL; + } + } else + address = strdup(addr); if (!strcmp(transport, "pcie")) { /* The 'address' string is the transport address */ traddr = address; From b78640e41f43170100e31873696547e2c401236a Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 13 Sep 2021 10:18:07 +0200 Subject: [PATCH 0161/1564] tree: better logging output Add logging messages when scan fails, and remove the logging from failure to read the individual attributes. Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 80 +++++++++++++++++++++++++++++++++++-------------- src/nvme/util.c | 4 +++ 2 files changed, 62 insertions(+), 22 deletions(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 6c46ef1b31..d2f2314d50 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -70,14 +70,22 @@ nvme_host_t nvme_default_host(nvme_root_t r) static int nvme_scan_topology(struct nvme_root *r, nvme_scan_filter_t f) { struct dirent **subsys; - int i, ret; + int i, num_subsys, ret; - ret = nvme_scan_subsystems(&subsys); - if (ret < 0) - return ret; + num_subsys = nvme_scan_subsystems(&subsys); + if (num_subsys < 0) { + nvme_msg(LOG_DEBUG, "failed to scan subsystems: %s\n", + strerror(errno)); + return num_subsys; + } - for (i = 0; i < ret; i++) - nvme_scan_subsystem(r, subsys[i]->d_name, f); + for (i = 0; i < num_subsys; i++) { + ret = nvme_scan_subsystem(r, subsys[i]->d_name, f); + if (ret < 0) { + nvme_msg(LOG_DEBUG, "failed to scan subsystem %s: %s\n", + subsys[i]->d_name, strerror(errno)); + } + } nvme_free_dirents(subsys, i); return 0; @@ -352,14 +360,23 @@ struct nvme_host *nvme_lookup_host(nvme_root_t r, const char *hostnqn, static int nvme_subsystem_scan_namespaces(struct nvme_subsystem *s) { struct dirent **namespaces; - int i, ret; - - ret = nvme_scan_subsystem_namespaces(s, &namespaces); - if (ret < 0) - return ret; + int i, num_ns, ret; + + num_ns = nvme_scan_subsystem_namespaces(s, &namespaces); + if (num_ns < 0) { + nvme_msg(LOG_DEBUG, + "failed to scan namespaces for subsys %s: %s\n", + s->subsysnqn, strerror(errno)); + return num_ns; + } - for (i = 0; i < ret; i++) - nvme_subsystem_scan_namespace(s, namespaces[i]->d_name); + for (i = 0; i < num_ns; i++) { + ret = nvme_subsystem_scan_namespace(s, namespaces[i]->d_name); + if (ret < 0) + nvme_msg(LOG_DEBUG, + "failed to scan namespace %s: %s\n", + namespaces[i]->d_name, strerror(errno)); + } nvme_free_dirents(namespaces, i); return 0; @@ -368,14 +385,23 @@ static int nvme_subsystem_scan_namespaces(struct nvme_subsystem *s) static int nvme_subsystem_scan_ctrls(struct nvme_subsystem *s) { struct dirent **ctrls; - int i, ret; - - ret = nvme_scan_subsystem_ctrls(s, &ctrls); - if (ret < 0) - return ret; + int i, num_ctrls, ret; + + num_ctrls = nvme_scan_subsystem_ctrls(s, &ctrls); + if (num_ctrls < 0) { + nvme_msg(LOG_DEBUG, + "failed to scan ctrls for subsys %s: %s\n", + s->subsysnqn, strerror(errno)); + return num_ctrls; + } - for (i = 0; i < ret; i++) - nvme_subsystem_scan_ctrl(s, ctrls[i]->d_name); + for (i = 0; i < num_ctrls; i++) { + ret = nvme_subsystem_scan_ctrl(s, ctrls[i]->d_name); + if (ret < 0) + nvme_msg(LOG_DEBUG, + "failed to scan ctrl %s: %s\n", + ctrls[i]->d_name, strerror(errno)); + } nvme_free_dirents(ctrls, i); return 0; @@ -1557,12 +1583,17 @@ static int nvme_ctrl_scan_namespace(struct nvme_ctrl *c, char *name) struct nvme_ns *n; if (!c->s) { + nvme_msg(LOG_DEBUG, "%s: no subsystem for %s\n", + __func__, name); errno = EINVAL; return -1; } n = __nvme_scan_namespace(c->sysfs_dir, name); - if (!n) + if (!n) { + nvme_msg(LOG_DEBUG, "%s: failed to scan namespace %s\n", + __func__, name); return -1; + } n->s = c->s; n->c = c; @@ -1575,8 +1606,11 @@ static int nvme_subsystem_scan_namespace(struct nvme_subsystem *s, char *name) struct nvme_ns *n; n = __nvme_scan_namespace(s->sysfs_dir, name); - if (!n) + if (!n) { + nvme_msg(LOG_DEBUG, "%s: failed to scan namespace %s\n", + __func__, name); return -1; + } n->s = s; list_add(&s->namespaces, &n->entry); @@ -1595,6 +1629,8 @@ struct nvme_ns *nvme_subsystem_lookup_namespace(struct nvme_subsystem *s, return NULL; n = __nvme_scan_namespace(s->sysfs_dir, name); if (!n) { + nvme_msg(LOG_DEBUG, "%s: failed to scan namespace %d\n", + __func__, nsid); free(name); return NULL; } diff --git a/src/nvme/util.c b/src/nvme/util.c index 0167f45ef6..bd82add218 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -754,8 +754,10 @@ static int __nvme_set_attr(const char *path, const char *value) fd = open(path, O_WRONLY); if (fd < 0) { +#if 0 nvme_msg(LOG_DEBUG, "Failed to open %s: %s\n", path, strerror(errno)); +#endif return -1; } ret = write(fd, value, strlen(value)); @@ -784,8 +786,10 @@ static char *__nvme_get_attr(const char *path) fd = open(path, O_RDONLY); if (fd < 0) { +#if 0 nvme_msg(LOG_DEBUG, "Failed to open %s: %s\n", path, strerror(errno)); +#endif return NULL; } From ceed025b0d015804d53b4040b50da756d70af608 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 13 Sep 2021 10:24:50 +0200 Subject: [PATCH 0162/1564] tree: free 'subsysnqn' Valgrind complained. Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index d2f2314d50..85cff3cfb1 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -802,6 +802,7 @@ static void __nvme_free_ctrl(nvme_ctrl_t c) nvme_deconfigure_ctrl(c); FREE_CTRL_ATTR(c->transport); + FREE_CTRL_ATTR(c->subsysnqn); FREE_CTRL_ATTR(c->traddr); FREE_CTRL_ATTR(c->host_traddr); FREE_CTRL_ATTR(c->host_iface); From d00390fd7dcc15b4c8213843cbe32ee63dd65d4b Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 13 Sep 2021 10:23:53 +0200 Subject: [PATCH 0163/1564] tree: set default ANA state to 'optimized' Older kernels do not provide an ANA state attribute, so always display 'optimized' here. Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 85cff3cfb1..bc0517bd41 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -560,6 +560,8 @@ static int nvme_ctrl_scan_path(struct nvme_ctrl *c, char *name) p->name = strdup(name); p->sysfs_dir = path; p->ana_state = nvme_get_path_attr(p, "ana_state"); + if (!p->ana_state) + p->ana_state = strdup("optimized"); grpid = nvme_get_path_attr(p, "ana_grpid"); if (grpid) { From 2003f2e2b494a14a879ddf6c02840c0cf085eccb Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 13 Sep 2021 10:22:15 +0200 Subject: [PATCH 0164/1564] tree: rework ctrl address generation Older kernel do not display an 'address' sysfs attribute for pcie controllers, so we need to infer it from the sysfs path itself. Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index bc0517bd41..2c5837a1a7 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -1152,18 +1152,39 @@ static nvme_ctrl_t nvme_ctrl_alloc(nvme_subsystem_t s, const char *path, /* Parse 'address' string into components */ addr = nvme_get_attr(path, "address"); if (!addr) { + char *rpath = NULL, *p = NULL, *_a = NULL; + /* Older kernel don't support pcie transport addresses */ if (strcmp(transport, "pcie")) { + free(transport); errno = ENXIO; return NULL; } - } else - address = strdup(addr); - if (!strcmp(transport, "pcie")) { + /* Figure out the PCI address from the attribute path */ + rpath = realpath(path, NULL); + if (!rpath) { + free(transport); + errno = ENOMEM; + return NULL; + } + a = strtok_r(rpath, "/", &e); + while(a && strlen(a)) { + if (_a) + p = _a; + _a = a; + if (!strncmp(a, "nvme", 4)) + break; + a = strtok_r(NULL, "/", &e); + } + if (p) + addr = strdup(p); + free(rpath); + } else if (!strcmp(transport, "pcie")) { /* The 'address' string is the transport address */ - traddr = address; + traddr = addr; } else { - a = strtok_r(addr, ",", &e); + address = strdup(addr); + a = strtok_r(address, ",", &e); while (a && strlen(a)) { if (!strncmp(a, "traddr=", 7)) traddr = a + 7; @@ -1178,12 +1199,14 @@ static nvme_ctrl_t nvme_ctrl_alloc(nvme_subsystem_t s, const char *path, } c = nvme_lookup_ctrl(s, transport, traddr, host_traddr, host_iface, trsvcid); - free(addr); + free(transport); + if (address) + free(address); if (!c) { errno = ENOMEM; return NULL; } - c->address = address; + c->address = addr; ret = nvme_configure_ctrl(c, path, name); return (ret < 0) ? NULL : c; } From 62bac64627b7ee99c49f30a399240acf04c95d92 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 15 Sep 2021 11:24:42 -0400 Subject: [PATCH 0165/1564] nvme-cli: nvme gen-hostnqn use partition UUID on IBM IBM POWER systems expose a platform created UUID in the device tree. Use that as the UUID in the host NQN Signed-Off-by: Wen Xiong Reviewed-by: Brian King --- src/nvme/fabrics.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index bdbcb8317b..cf0b168ba5 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -590,6 +590,27 @@ int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, return ret; } +#define PATH_UUID_IBM "/proc/device-tree/ibm,partition-uuid" + +int uuid_from_device_tree(char *system_uuid) +{ + char filename[PATH_MAX]; + int f, len, ret; + + sprintf(filename, "%s", PATH_UUID_IBM); + f = open(filename, O_RDONLY); + if (f < 0) + goto out_close; + len = read(f, system_uuid, 512); + if (len < 0) + goto out_close; + +out_close: + close(f); + ret = -ENXIO; + return strlen(system_uuid) ? 0 : ret; +} + #define PATH_DMI_ENTRIES "/sys/firmware/dmi/entries" int uuid_from_dmi(char *system_uuid) @@ -677,8 +698,11 @@ char *nvmf_hostnqn_generate() #endif ret = uuid_from_dmi(uuid_str); - if (ret < 0) - ret = uuid_from_systemd(uuid_str); + if (ret < 0) { + ret = uuid_from_device_tree(uuid_str); + if (ret < 0) + ret = uuid_from_systemd(uuid_str); + } #ifdef CONFIG_LIBUUID if (ret < 0) { uuid_generate_random(uuid); From e658f1d2bf7dfe99dcf6f2fa3c7274b4f8ed960e Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Tue, 21 Sep 2021 09:03:06 +0200 Subject: [PATCH 0166/1564] fabrics: Refactor uuid_from_device_tree The recently added uuid_from_device_tree function can be refactored by minimizing use of local variables and early returns in error handling. No functional change. Signed-off-by: Daniel Wagner --- src/nvme/fabrics.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index cf0b168ba5..4b0ba16e66 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -594,21 +594,18 @@ int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, int uuid_from_device_tree(char *system_uuid) { - char filename[PATH_MAX]; - int f, len, ret; + ssize_t len; + int f; - sprintf(filename, "%s", PATH_UUID_IBM); - f = open(filename, O_RDONLY); + f = open(PATH_UUID_IBM, O_RDONLY); if (f < 0) - goto out_close; + return -ENXIO; len = read(f, system_uuid, 512); + close(f); if (len < 0) - goto out_close; + return -ENXIO; -out_close: - close(f); - ret = -ENXIO; - return strlen(system_uuid) ? 0 : ret; + return strlen(system_uuid) ? 0 : -ENXIO; } #define PATH_DMI_ENTRIES "/sys/firmware/dmi/entries" From a2749fcdceac68bc42f5874628990be67fd79bb1 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Tue, 21 Sep 2021 13:55:16 +0200 Subject: [PATCH 0167/1564] pynvme: Add install target to Makefile Use setup.py to install the binding to the sitearch. Signed-off-by: Daniel Wagner --- Makefile | 3 +++ pynvme/Makefile | 6 ++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 3574a9ac58..6cc8338645 100644 --- a/Makefile +++ b/Makefile @@ -54,6 +54,9 @@ install: $(NAME).pc install-tests: @$(MAKE) -C test install prefix=$(DESTDIR)$(prefix) datadir=$(DESTDIR)$(datadir) +install-python: + @$(MAKE) -C pynvme install prefix=$(DESTDIR)$(prefix) + clean: @rm -f config-host.mak config-host.h cscope.out $(NAME).pc @$(MAKE) -C src clean diff --git a/pynvme/Makefile b/pynvme/Makefile index f82a83bb0d..5f2640738a 100644 --- a/pynvme/Makefile +++ b/pynvme/Makefile @@ -3,6 +3,8 @@ SWIG ?= swig PYTHON ?= python3 +prefix ?= /usr + nvme_swig := nvme.i nvme_wrap.c: $(nvme_swig) @@ -11,8 +13,8 @@ nvme_wrap.c: $(nvme_swig) python: nvme_wrap.c setup.py $(PYTHON) setup.py build -#install: -# +install: + $(PYTHON) setup.py install --prefix=$(prefix) clean: rm -rf nvme_wrap.c nvme.py build From d103568762cf54cc9af4b2bcd32a888a4b1481f3 Mon Sep 17 00:00:00 2001 From: Andreas Hindborg Date: Wed, 22 Sep 2021 13:08:22 +0200 Subject: [PATCH 0168/1564] Fix bug in `nvme_identify_iocs` This patch fixes a bug in `nvme_identify_iocs` where the wrong CNS value used in the Identify Command data structure. Signed-off-by: Andreas Hindborg --- src/nvme/ioctl.c | 2 +- src/nvme/ioctl.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index cac8e23693..0863467fa1 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -497,7 +497,7 @@ int nvme_identify_ns_csi(int fd, __u32 nsid, __u8 csi, void *data) int nvme_identify_iocs(int fd, __u16 cntlid, struct nvme_id_iocs *iocs) { BUILD_ASSERT(sizeof(struct nvme_id_iocs) == 4096); - return nvme_identify(fd, NVME_IDENTIFY_CNS_CSI_CTRL, NVME_NSID_NONE, + return nvme_identify(fd, NVME_IDENTIFY_CNS_COMMAND_SET_STRUCTURE, NVME_NSID_NONE, cntlid, NVME_NVMSETID_NONE, NVME_UUID_NONE, NVME_CSI_NVM, iocs); } diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 20cb75d184..2b5a2108a8 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -451,6 +451,7 @@ enum nvme_admin_opcode { * @NVME_IDENTIFY_CNS_NS_GRANULARITY: * @NVME_IDENTIFY_CNS_UUID_LIST: * @NVME_IDENTIFY_CNS_CSI_ALLOCATED_NS: + * @NVME_IDENTIFY_CNS_COMMAND_SET_STRUCTURE: Base Specification 2.0a section 5.17.2.21 */ enum nvme_identify_cns { NVME_IDENTIFY_CNS_NS = 0x00, @@ -469,6 +470,7 @@ enum nvme_identify_cns { NVME_IDENTIFY_CNS_NS_GRANULARITY = 0x16, NVME_IDENTIFY_CNS_UUID_LIST = 0x17, NVME_IDENTIFY_CNS_CSI_ALLOCATED_NS = 0x18, /* XXX: Placeholder until assigned */ + NVME_IDENTIFY_CNS_COMMAND_SET_STRUCTURE = 0x1C, }; /** From c6e852e62c045faab4db826def1a0fc8d6073df6 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Mon, 27 Sep 2021 15:27:38 +0200 Subject: [PATCH 0169/1564] libnvme.map: Sort global export section Sort the global section so that we when new entries are inserted they are in the correct position. Signed-off-by: Daniel Wagner --- src/libnvme.map | 422 ++++++++++++++++++++++++------------------------ 1 file changed, 211 insertions(+), 211 deletions(-) diff --git a/src/libnvme.map b/src/libnvme.map index 64c04b0a59..5075f9d014 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -1,252 +1,252 @@ { global: - nvme_submit_admin_passthru64; - nvme_submit_admin_passthru; - nvme_submit_io_passthru64; - nvme_submit_io_passthru; + __nvme_get_log_page; nvme_admin_passthru64; nvme_admin_passthru; - nvme_io_passthru64; - nvme_io_passthru; - nvme_subsystem_reset; + nvme_compare; + nvme_ctrl_disconnect; + nvme_ctrl_first_ns; + nvme_ctrl_first_path; + nvme_ctrl_get_address; + nvme_ctrl_get_fd; + nvme_ctrl_get_firmware; + nvme_ctrl_get_model; + nvme_ctrl_get_name; + nvme_ctrl_get_nqn; + nvme_ctrl_get_numa_node; + nvme_ctrl_get_queue_count; + nvme_ctrl_get_serial; + nvme_ctrl_get_sqsize; + nvme_ctrl_get_state; + nvme_ctrl_get_subsysnqn; + nvme_ctrl_get_subsystem; + nvme_ctrl_get_sysfs_dir; + nvme_ctrl_get_transport; + nvme_ctrl_identify; + nvme_ctrl_next_ns; + nvme_ctrl_next_path; nvme_ctrl_reset; - nvme_ns_rescan; - nvme_get_nsid; - nvme_identify; - nvme_identify_ctrl; - nvme_identify_ns; - nvme_identify_allocated_ns; - nvme_identify_active_ns_list; - nvme_identify_allocated_ns_list; - nvme_identify_nsid_ctrl_list; - nvme_identify_ns_descs; - nvme_identify_nvmset_list; - nvme_identify_primary_ctrl; - nvme_identify_secondary_ctrl_list; - nvme_identify_ns_granularity; - nvme_identify_uuid; - nvme_get_log; - nvme_get_log_error; - nvme_get_log_smart; - nvme_get_log_fw_slot; - nvme_get_log_changed_ns_list; - nvme_get_log_cmd_effects; - nvme_get_log_device_self_test; - nvme_get_log_create_telemetry_host; - nvme_get_log_telemetry_host; - nvme_get_log_telemetry_ctrl; - nvme_get_log_endurance_group; - nvme_get_log_predictable_lat_nvmset; - nvme_get_log_predictable_lat_event; - nvme_get_log_ana; - nvme_get_log_ana_groups; - nvme_get_log_lba_status; - nvme_get_log_endurance_grp_evt; - nvme_get_log_discovery; - nvme_get_log_reservation; - nvme_get_log_sanitize; - nvme_set_feature; - nvme_set_features_arbitration; - nvme_set_features_power_mgmt; - nvme_set_features_lba_range; - nvme_set_features_temp_thresh; - nvme_set_features_err_recovery; - nvme_set_features_volatile_wc; - nvme_set_features_irq_coalesce; - nvme_set_features_irq_config; - nvme_set_features_write_atomic; - nvme_set_features_async_event; - nvme_set_features_auto_pst; - nvme_set_features_timestamp; - nvme_set_features_hctm; - nvme_set_features_nopsc; - nvme_set_features_rrl; - nvme_set_features_plm_config; - nvme_set_features_plm_window; - nvme_set_features_lba_sts_interval; - nvme_set_features_host_behavior; - nvme_set_features_sanitize; - nvme_set_features_endurance_evt_cfg; - nvme_set_features_sw_progress; - nvme_set_features_host_id; - nvme_set_features_resv_mask; - nvme_set_features_resv_persist; - nvme_set_features_write_protect; + nvme_ctrls_filter; + nvme_dev_self_test; + nvme_directive_recv; + nvme_directive_recv_identify_parameters; + nvme_directive_recv_stream_allocate; + nvme_directive_recv_stream_parameters; + nvme_directive_recv_stream_status; + nvme_directive_send; + nvme_directive_send_id_endir; + nvme_directive_send_stream_release_identifier; + nvme_directive_send_stream_release_resource; + nvme_dsm; + nvme_dsm_range; + nvme_first_subsystem; + nvme_flush; + nvme_format_nvm; + nvme_free_ctrl; + nvme_free_tree; + nvme_fw_commit; + nvme_fw_download; + nvme_fw_download_seq; + nvme_get_ana_log_len; + nvme_get_ctrl_attr; + nvme_get_ctrl_telemetry; + nvme_get_directive_receive_length; + nvme_get_feature_length; nvme_get_features; nvme_get_features_arbitration; - nvme_get_features_power_mgmt; - nvme_get_features_lba_range; - nvme_get_features_temp_thresh; - nvme_get_features_err_recovery; - nvme_get_features_volatile_wc; - nvme_get_features_num_queues; - nvme_get_features_irq_coalesce; - nvme_get_features_irq_config; - nvme_get_features_write_atomic; nvme_get_features_async_event; nvme_get_features_auto_pst; + nvme_get_features_endurance_event_cfg; + nvme_get_features_err_recovery; + nvme_get_features_hctm; + nvme_get_features_host_behavior; + nvme_get_features_host_id; nvme_get_features_host_mem_buf; - nvme_get_features_timestamp; + nvme_get_features_irq_coalesce; + nvme_get_features_irq_config; nvme_get_features_kato; - nvme_get_features_hctm; + nvme_get_features_lba_range; + nvme_get_features_lba_sts_interval; nvme_get_features_nopsc; - nvme_get_features_rrl; + nvme_get_features_num_queues; nvme_get_features_plm_config; nvme_get_features_plm_window; - nvme_get_features_lba_sts_interval; - nvme_get_features_host_behavior; - nvme_get_features_sanitize; - nvme_get_features_endurance_event_cfg; - nvme_get_features_sw_progress; - nvme_get_features_host_id; + nvme_get_features_power_mgmt; nvme_get_features_resv_mask; nvme_get_features_resv_persist; + nvme_get_features_rrl; + nvme_get_features_sanitize; + nvme_get_features_sw_progress; + nvme_get_features_temp_thresh; + nvme_get_features_timestamp; + nvme_get_features_volatile_wc; + nvme_get_features_write_atomic; nvme_get_features_write_protect; - nvme_format_nvm; - nvme_ns_mgmt; - nvme_ns_mgmt_create; - nvme_ns_mgmt_delete; - nvme_ns_attach; - nvme_ns_attach_ctrls; - nvme_ns_dettach_ctrls; - nvme_fw_download; - nvme_fw_commit; - nvme_security_receive; - nvme_security_receive; nvme_get_lba_status; - nvme_directive_send; - nvme_directive_send_id_endir; - nvme_directive_send_stream_release_identifier; - nvme_directive_send_stream_release_resource; - nvme_directive_recv; - nvme_directive_recv_identify_parameters; - nvme_directive_recv_stream_parameters; - nvme_directive_recv_stream_status; - nvme_directive_recv_stream_allocate; - nvme_set_property; + nvme_get_log; + nvme_get_log_ana; + nvme_get_log_ana_groups; + nvme_get_log_changed_ns_list; + nvme_get_log_cmd_effects; + nvme_get_log_create_telemetry_host; + nvme_get_log_device_self_test; + nvme_get_log_discovery; + nvme_get_log_endurance_group; + nvme_get_log_endurance_grp_evt; + nvme_get_log_error; + nvme_get_log_fw_slot; + nvme_get_log_lba_status; + nvme_get_log_page; + nvme_get_log_predictable_lat_event; + nvme_get_log_predictable_lat_nvmset; + nvme_get_log_reservation; + nvme_get_log_sanitize; + nvme_get_log_smart; + nvme_get_log_telemetry_ctrl; + nvme_get_log_telemetry_host; + nvme_get_ns_attr; + nvme_get_nsid; + nvme_get_path_attr; nvme_get_property; - nvme_sanitize; - nvme_dev_self_test; - nvme_virtual_mgmt; - nvme_flush; - nvme_read; - nvme_write; - nvme_compare; - nvme_write_zeros; - nvme_write_uncorrectable; - nvme_verify; - nvme_dsm; - nvme_resv_acquire; - nvme_resv_register; - nvme_resv_release; - nvme_resv_report; - nvmf_add_ctrl_opts; - nvmf_add_ctrl; - nvme_first_subsystem; + nvme_get_subsys_attr; + nvme_get_telemetry_log; + nvme_identify; + nvme_identify_active_ns_list; + nvme_identify_allocated_ns; + nvme_identify_allocated_ns_list; + nvme_identify_ctrl; + nvme_identify_ns; + nvme_identify_ns_descs; + nvme_identify_ns_granularity; + nvme_identify_nsid_ctrl_list; + nvme_identify_nvmset_list; + nvme_identify_primary_ctrl; + nvme_identify_secondary_ctrl_list; + nvme_identify_uuid; + nvme_io_passthru64; + nvme_io_passthru; + nvme_namespace_attach_ctrls; + nvme_namespace_detach_ctrls; + nvme_namespace_filter; nvme_next_subsystem; - nvme_ctrl_first_ns; - nvme_ctrl_next_ns; - nvme_ctrl_first_path; - nvme_ctrl_next_path; - nvme_subsystem_first_ctrl; - nvme_subsystem_next_ctrl; - nvme_subsystem_first_ns; - nvme_subsystem_next_ns; + nvme_ns_attach; + nvme_ns_attach_ctrls; + nvme_ns_compare; + nvme_ns_dettach_ctrls; + nvme_ns_flush; + nvme_ns_get_ctrl; nvme_ns_get_fd; - nvme_ns_get_nsid; - nvme_ns_get_lba_size; nvme_ns_get_lba_count; + nvme_ns_get_lba_size; nvme_ns_get_lba_util; + nvme_ns_get_name; + nvme_ns_get_nsid; nvme_ns_get_subsystem; - nvme_ns_get_ctrl; + nvme_ns_get_sysfs_dir; + nvme_ns_identify; + nvme_ns_mgmt; + nvme_ns_mgmt_create; + nvme_ns_mgmt_delete; + nvme_ns_open; nvme_ns_read; - nvme_ns_write; + nvme_ns_rescan; nvme_ns_verify; - nvme_ns_compare; - nvme_ns_write_zeros; + nvme_ns_write; nvme_ns_write_uncorrectable; - nvme_ns_flush; - nvme_ns_identify; - nvme_path_get_subsystem; + nvme_ns_write_zeros; + nvme_open; + nvme_path_get_ana_state; + nvme_path_get_name; nvme_path_get_ns; - nvme_ctrl_get_subsystem; - nvme_ctrl_identify; - nvme_ctrl_disconnect; - nvme_scan_ctrl; - nvme_free_ctrl; - nvme_unlink_ctrl; - nvme_scan_filter; - nvme_scan; + nvme_path_get_subsystem; + nvme_path_get_sysfs_dir; + nvme_paths_filter; + nvme_read; nvme_refresh_topology; nvme_reset_topology; - nvme_free_tree; - nvme_get_subsys_attr; - nvme_get_ctrl_attr; - nvme_get_ns_attr; - nvme_get_path_attr; - nvme_subsystem_get_nqn; - nvme_subsystem_get_sysfs_dir; - nvme_subsystem_get_name; - nvme_subsystem_get_nqn; - nvme_ctrl_get_fd; - nvme_ctrl_get_name; - nvme_ctrl_get_sysfs_dir; - nvme_ctrl_get_address; - nvme_ctrl_get_firmware; - nvme_ctrl_get_model; - nvme_ctrl_get_state; - nvme_ctrl_get_numa_node; - nvme_ctrl_get_queue_count; - nvme_ctrl_get_serial; - nvme_ctrl_get_sqsize; - nvme_ctrl_get_transport; - nvme_ctrl_get_nqn; - nvme_ctrl_get_subsysnqn; - nvme_path_get_name; - nvme_path_get_sysfs_dir; - nvme_path_get_ana_state; - nvme_ns_get_sysfs_dir; - nvme_ns_get_name; - nvme_ns_open; - nvme_status_type; - nvme_status_to_string; - nvme_status_to_errno; - nvme_fw_download_seq; - nvme_get_telemetry_log; - nvme_get_ctrl_telemetry; - nvme_setup_id_ns; - nvme_setup_ctrl_list; - nvme_dsm_range; - nvme_get_log_page; - __nvme_get_log_page; - nvme_get_ana_log_len; - nvme_namespace_attach_ctrls; - nvme_namespace_detach_ctrls; - nvme_get_feature_length; - nvme_get_directive_receive_length; - nvme_open; - nvme_scan_ctrl_namespaces; + nvme_resv_acquire; + nvme_resv_register; + nvme_resv_release; + nvme_resv_report; + nvme_sanitize; + nvme_scan; + nvme_scan_ctrl; nvme_scan_ctrl_namespace_paths; - nvme_scan_subsystem_namespaces; + nvme_scan_ctrl_namespaces; + nvme_scan_filter; nvme_scan_subsystem_ctrls; + nvme_scan_subsystem_namespaces; nvme_scan_subsystems; + nvme_security_receive; + nvme_security_receive; + nvme_set_feature; + nvme_set_features_arbitration; + nvme_set_features_async_event; + nvme_set_features_auto_pst; + nvme_set_features_endurance_evt_cfg; + nvme_set_features_err_recovery; + nvme_set_features_hctm; + nvme_set_features_host_behavior; + nvme_set_features_host_id; + nvme_set_features_irq_coalesce; + nvme_set_features_irq_config; + nvme_set_features_lba_range; + nvme_set_features_lba_sts_interval; + nvme_set_features_nopsc; + nvme_set_features_plm_config; + nvme_set_features_plm_window; + nvme_set_features_power_mgmt; + nvme_set_features_resv_mask; + nvme_set_features_resv_persist; + nvme_set_features_rrl; + nvme_set_features_sanitize; + nvme_set_features_sw_progress; + nvme_set_features_temp_thresh; + nvme_set_features_timestamp; + nvme_set_features_volatile_wc; + nvme_set_features_write_atomic; + nvme_set_features_write_protect; + nvme_set_property; + nvme_setup_ctrl_list; + nvme_setup_id_ns; + nvme_status_to_errno; + nvme_status_to_string; + nvme_status_type; + nvme_submit_admin_passthru64; + nvme_submit_admin_passthru; + nvme_submit_io_passthru64; + nvme_submit_io_passthru; nvme_subsys_filter; - nvme_ctrls_filter; - nvme_paths_filter; - nvme_namespace_filter; + nvme_subsystem_first_ctrl; + nvme_subsystem_first_ns; + nvme_subsystem_get_name; + nvme_subsystem_get_nqn; + nvme_subsystem_get_nqn; + nvme_subsystem_get_sysfs_dir; + nvme_subsystem_next_ctrl; + nvme_subsystem_next_ns; + nvme_subsystem_reset; + nvme_unlink_ctrl; + nvme_verify; + nvme_virtual_mgmt; + nvme_write; + nvme_write_uncorrectable; + nvme_write_zeros; + nvmf_add_ctrl; + nvmf_add_ctrl_opts; + nvmf_adrfam_str; + nvmf_cms_str; + nvmf_connect_disc_entry; nvmf_get_discovery_log; - nvmf_hostnqn_generate; - nvmf_hostnqn_from_file; nvmf_hostid_from_file; - nvmf_trtype_str; - nvmf_adrfam_str; - nvmf_subtype_str; - nvmf_treq_str; - nvmf_sectype_str; + nvmf_hostnqn_from_file; + nvmf_hostnqn_generate; nvmf_prtype_str; nvmf_qptype_str; - nvmf_cms_str; - nvmf_connect_disc_entry; + nvmf_sectype_str; + nvmf_subtype_str; + nvmf_treq_str; + nvmf_trtype_str; local: *; }; From cea74ccb43fb8539e3997cec0ab46b1437bfa465 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Mon, 27 Sep 2021 15:29:56 +0200 Subject: [PATCH 0170/1564] libnvme.map: Add missing exports for nvme-cli When building nvme-cli with a shared library a few symbols where missing in the export list. Let's export the missing symbols. Signed-off-by: Daniel Wagner --- src/libnvme.map | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/libnvme.map b/src/libnvme.map index 5075f9d014..c0f7c7ebd9 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -1,15 +1,21 @@ { global: __nvme_get_log_page; + __nvme_msg; nvme_admin_passthru64; nvme_admin_passthru; + nvme_attach_ns; nvme_compare; + nvme_copy; + nvme_create_ctrl; nvme_ctrl_disconnect; nvme_ctrl_first_ns; nvme_ctrl_first_path; nvme_ctrl_get_address; nvme_ctrl_get_fd; nvme_ctrl_get_firmware; + nvme_ctrl_get_host_iface; + nvme_ctrl_get_host_traddr; nvme_ctrl_get_model; nvme_ctrl_get_name; nvme_ctrl_get_nqn; @@ -21,7 +27,9 @@ nvme_ctrl_get_subsysnqn; nvme_ctrl_get_subsystem; nvme_ctrl_get_sysfs_dir; + nvme_ctrl_get_traddr; nvme_ctrl_get_transport; + nvme_ctrl_get_trsvcid; nvme_ctrl_identify; nvme_ctrl_next_ns; nvme_ctrl_next_path; @@ -37,12 +45,15 @@ nvme_directive_send_id_endir; nvme_directive_send_stream_release_identifier; nvme_directive_send_stream_release_resource; + nvme_disconnect_ctrl; nvme_dsm; nvme_dsm_range; + nvme_first_host; nvme_first_subsystem; nvme_flush; nvme_format_nvm; nvme_free_ctrl; + nvme_free_ns; nvme_free_tree; nvme_fw_commit; nvme_fw_download; @@ -82,6 +93,7 @@ nvme_get_features_volatile_wc; nvme_get_features_write_atomic; nvme_get_features_write_protect; + nvme_get_host_telemetry; nvme_get_lba_status; nvme_get_log; nvme_get_log_ana; @@ -97,6 +109,7 @@ nvme_get_log_fw_slot; nvme_get_log_lba_status; nvme_get_log_page; + nvme_get_log_persistent_event; nvme_get_log_predictable_lat_event; nvme_get_log_predictable_lat_nvmset; nvme_get_log_reservation; @@ -104,17 +117,21 @@ nvme_get_log_smart; nvme_get_log_telemetry_ctrl; nvme_get_log_telemetry_host; + nvme_get_new_host_telemetry; nvme_get_ns_attr; nvme_get_nsid; nvme_get_path_attr; nvme_get_property; nvme_get_subsys_attr; nvme_get_telemetry_log; + nvme_host_get_hostid; + nvme_host_get_hostnqn; nvme_identify; nvme_identify_active_ns_list; nvme_identify_allocated_ns; nvme_identify_allocated_ns_list; nvme_identify_ctrl; + nvme_identify_iocs; nvme_identify_ns; nvme_identify_ns_descs; nvme_identify_ns_granularity; @@ -123,24 +140,37 @@ nvme_identify_primary_ctrl; nvme_identify_secondary_ctrl_list; nvme_identify_uuid; + nvme_init_copy_range; + nvme_init_ctrl_list; + nvme_init_dsm_range; + nvme_init_id_ns; nvme_io_passthru64; nvme_io_passthru; + nvme_log_level; + nvme_lookup_host; nvme_namespace_attach_ctrls; nvme_namespace_detach_ctrls; nvme_namespace_filter; + nvme_next_host; nvme_next_subsystem; nvme_ns_attach; nvme_ns_attach_ctrls; nvme_ns_compare; + nvme_ns_detach_ctrls; nvme_ns_dettach_ctrls; nvme_ns_flush; nvme_ns_get_ctrl; nvme_ns_get_fd; + nvme_ns_get_firmware; nvme_ns_get_lba_count; nvme_ns_get_lba_size; nvme_ns_get_lba_util; + nvme_ns_get_meta_size; + nvme_ns_get_model; + nvme_ns_get_model; nvme_ns_get_name; nvme_ns_get_nsid; + nvme_ns_get_serial; nvme_ns_get_subsystem; nvme_ns_get_sysfs_dir; nvme_ns_identify; @@ -154,6 +184,7 @@ nvme_ns_write; nvme_ns_write_uncorrectable; nvme_ns_write_zeros; + nvme_nvm_identify_ctrl; nvme_open; nvme_path_get_ana_state; nvme_path_get_name; @@ -169,17 +200,21 @@ nvme_resv_release; nvme_resv_report; nvme_sanitize; + nvme_sanitize_nvm; nvme_scan; nvme_scan_ctrl; nvme_scan_ctrl_namespace_paths; nvme_scan_ctrl_namespaces; nvme_scan_filter; + nvme_scan_namespace; nvme_scan_subsystem_ctrls; nvme_scan_subsystem_namespaces; nvme_scan_subsystems; nvme_security_receive; nvme_security_receive; + nvme_security_send; nvme_set_feature; + nvme_set_features; nvme_set_features_arbitration; nvme_set_features_async_event; nvme_set_features_auto_pst; @@ -219,6 +254,7 @@ nvme_subsys_filter; nvme_subsystem_first_ctrl; nvme_subsystem_first_ns; + nvme_subsystem_get_host; nvme_subsystem_get_name; nvme_subsystem_get_nqn; nvme_subsystem_get_nqn; @@ -232,6 +268,13 @@ nvme_write; nvme_write_uncorrectable; nvme_write_zeros; + nvme_zns_append; + nvme_zns_identify_ctrl; + nvme_zns_identify_ns; + nvme_zns_identify_ns; + nvme_zns_mgmt_recv; + nvme_zns_mgmt_send; + nvme_zns_report_zones; nvmf_add_ctrl; nvmf_add_ctrl_opts; nvmf_adrfam_str; From 0fcee9faad6ad80c785576b02ad9a04deac56b12 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Mon, 27 Sep 2021 15:36:58 +0200 Subject: [PATCH 0171/1564] Makefile: Install log.h header file Add the missing nvme/log.h header file. Signed-off-by: Daniel Wagner --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index 721590f33c..40744d4265 100644 --- a/src/Makefile +++ b/src/Makefile @@ -47,7 +47,7 @@ libccan_sobjs := $(patsubst %.c,%.os,$(libccan_srcs)) $(libccan_objs) $(libccan_sobjs): $(libccan_headers) $(CCANDIR)config.h libnvme_priv := nvme/private.h -libnvme_api := libnvme.h nvme/types.h nvme/ioctl.h nvme/filters.h nvme/tree.h nvme/util.h nvme/fabrics.h +libnvme_api := libnvme.h nvme/types.h nvme/ioctl.h nvme/filters.h nvme/tree.h nvme/util.h nvme/fabrics.h nvme/log.h libnvme_srcs := nvme/ioctl.c nvme/filters.c nvme/fabrics.c nvme/util.c nvme/tree.c nvme/log.c nvme/cleanup.c ifeq ($(CONFIG_JSONC),y) override libnvme_srcs += nvme/json.c From d569afca332ae1cefa45df2dfb0d74ffdfb055b6 Mon Sep 17 00:00:00 2001 From: Sagi Grimberg Date: Sun, 26 Sep 2021 21:29:32 +0300 Subject: [PATCH 0172/1564] fabrics: restore hostname traddr support We used to support hostname passed in traddr, with the move of nvme-cli to use libnvme we lost this capability, now lets restore it. Signed-off-by: Sagi Grimberg --- src/nvme/fabrics.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 4b0ba16e66..ebfc635684 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -21,6 +21,8 @@ #include #include +#include +#include #ifdef CONFIG_SYSTEMD #include @@ -213,6 +215,63 @@ static int add_argument(char **argstr, const char *tok, const char *arg) return 0; } +static bool traddr_is_hostname(nvme_ctrl_t c) +{ + char addrstr[NVMF_TRADDR_SIZE]; + + if (!c->traddr) + return false; + if (strcmp(c->transport, "tcp") && strcmp(c->transport, "rdma")) + return false; + if (inet_pton(AF_INET, c->traddr, addrstr) > 0 || + inet_pton(AF_INET6, c->traddr, addrstr) > 0) + return false; + return true; +} + +static int hostname2traddr(nvme_ctrl_t c) +{ + struct addrinfo *host_info, hints = {.ai_family = AF_UNSPEC}; + char addrstr[NVMF_TRADDR_SIZE]; + const char *p; + int ret; + + ret = getaddrinfo(c->traddr, NULL, &hints, &host_info); + if (ret) { + fprintf(stderr, "failed to resolve host %s info\n", c->traddr); + return ret; + } + + switch (host_info->ai_family) { + case AF_INET: + p = inet_ntop(host_info->ai_family, + &(((struct sockaddr_in *)host_info->ai_addr)->sin_addr), + addrstr, NVMF_TRADDR_SIZE); + break; + case AF_INET6: + p = inet_ntop(host_info->ai_family, + &(((struct sockaddr_in6 *)host_info->ai_addr)->sin6_addr), + addrstr, NVMF_TRADDR_SIZE); + break; + default: + fprintf(stderr, "unrecognized address family (%d) %s\n", + host_info->ai_family, c->traddr); + ret = -EINVAL; + goto free_addrinfo; + } + + if (!p) { + fprintf(stderr, "failed to get traddr for %s\n", c->traddr); + ret = -errno; + goto free_addrinfo; + } + c->traddr = strdup(addrstr); + +free_addrinfo: + freeaddrinfo(host_info); + return ret; +} + static int build_options(nvme_host_t h, nvme_ctrl_t c, char **argstr) { struct nvme_fabrics_config *cfg = nvme_ctrl_get_config(c); @@ -353,6 +412,11 @@ int nvmf_add_ctrl_opts(nvme_ctrl_t c, struct nvme_fabrics_config *cfg) int ret; cfg = merge_config(c, cfg); + if (traddr_is_hostname(c)) { + ret = hostname2traddr(c); + if (ret) + return ret; + } ret = build_options(h, c, &argstr); if (ret) @@ -375,6 +439,11 @@ int nvmf_add_ctrl(nvme_host_t h, nvme_ctrl_t c, cfg = merge_config(c, cfg); nvme_ctrl_disable_sqflow(c, disable_sqflow); nvme_ctrl_set_discovered(c, true); + if (traddr_is_hostname(c)) { + ret = hostname2traddr(c); + if (ret) + return ret; + } ret = build_options(h, c, &argstr); if (ret) From 198c38362663d55952d8c88d40965cee25e38cd6 Mon Sep 17 00:00:00 2001 From: Andreas Hindborg Date: Fri, 17 Sep 2021 16:21:28 +0200 Subject: [PATCH 0173/1564] Fix a bug where CSI was not passed to to nvme_ns_mgmt Signed-off-by: Andreas Hindborg --- src/nvme/ioctl.c | 29 +++++++++++++++++------------ src/nvme/ioctl.h | 14 ++++++++------ 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 0863467fa1..9a8526d652 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -249,6 +249,8 @@ enum nvme_cmd_dword_fields { NVME_NAMESPACE_ATTACH_CDW10_SEL_MASK = 0xf, NVME_NAMESPACE_MGMT_CDW10_SEL_SHIFT = 0, NVME_NAMESPACE_MGMT_CDW10_SEL_MASK = 0xf, + NVME_NAMESPACE_MGMT_CDW11_CSI_SHIFT = 24, + NVME_NAMESPACE_MGMT_CDW11_CSI_MASK = 0xff, NVME_VIRT_MGMT_CDW10_ACT_SHIFT = 0, NVME_VIRT_MGMT_CDW10_RT_SHIFT = 8, NVME_VIRT_MGMT_CDW10_CNTLID_SHIFT = 16, @@ -1246,33 +1248,36 @@ int nvme_format_nvm(int fd, __u32 nsid, __u8 lbaf, } int nvme_ns_mgmt(int fd, __u32 nsid, enum nvme_ns_mgmt_sel sel, - struct nvme_id_ns *ns, __u32 *result, __u32 timeout) + struct nvme_id_ns *ns, __u32 *result, __u32 timeout, __u8 csi) { - __u32 cdw10 = NVME_SET(sel, NAMESPACE_MGMT_CDW10_SEL); + __u32 cdw10 = NVME_SET(sel, NAMESPACE_MGMT_CDW10_SEL); + __u32 cdw11 = NVME_SET(csi, NAMESPACE_MGMT_CDW11_CSI); __u32 data_len = ns ? sizeof(*ns) : 0; struct nvme_passthru_cmd cmd = { - .nsid = nsid, - .opcode = nvme_admin_ns_mgmt, - .cdw10 = cdw10, - .timeout_ms = timeout, - .data_len = data_len, - .addr = (__u64)(uintptr_t)ns, + .nsid = nsid, + .opcode = nvme_admin_ns_mgmt, + .cdw10 = cdw10, + .cdw11 = cdw11, + .timeout_ms = timeout, + .data_len = data_len, + .addr = (__u64)(uintptr_t)ns, }; return nvme_submit_admin_passthru(fd, &cmd, result); } int nvme_ns_mgmt_create(int fd, struct nvme_id_ns *ns, __u32 *nsid, - __u32 timeout) + __u32 timeout, __u8 csi) { - return nvme_ns_mgmt(fd, NVME_NSID_NONE, NVME_NS_MGMT_SEL_CREATE, ns, nsid, - timeout); + return nvme_ns_mgmt(fd, NVME_NSID_NONE, NVME_NS_MGMT_SEL_CREATE, ns, + nsid, timeout, csi); } int nvme_ns_mgmt_delete(int fd, __u32 nsid) { - return nvme_ns_mgmt(fd, nsid, NVME_NS_MGMT_SEL_DELETE, NULL, NULL, 0); + return nvme_ns_mgmt(fd, nsid, NVME_NS_MGMT_SEL_DELETE, NULL, NULL, 0, + 0); } int nvme_ns_attach(int fd, __u32 nsid, enum nvme_ns_attach_sel sel, diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 2b5a2108a8..a040da5d0b 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -2279,17 +2279,19 @@ int nvme_format_nvm(int fd, __u32 nsid, __u8 lbaf, /** * nvme_ns_mgmt() - * @fd: File descriptor of nvme device + * @csi: Command Set Identifier */ int nvme_ns_mgmt(int fd, __u32 nsid, enum nvme_ns_mgmt_sel sel, - struct nvme_id_ns *ns, __u32 *result, __u32 timeout); + struct nvme_id_ns *ns, __u32 *result, __u32 timeout, __u8 csi); /** * nvme_ns_mgmt_create() - * @fd: File descriptor of nvme device - * @ns: Namespace identifiaction that defines 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. + * @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. + * @csi: Command Set Identifier * * On successful creation, the namespace exists in the subsystem, but is not * attached to any controller. Use the &nvme_ns_attach_ctrls() to assign the @@ -2299,7 +2301,7 @@ int nvme_ns_mgmt(int fd, __u32 nsid, enum nvme_ns_mgmt_sel sel, * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_ns_mgmt_create(int fd, struct nvme_id_ns *ns, __u32 *nsid, - __u32 timeout); + __u32 timeout, __u8 csi); /** * nvme_ns_mgmt_delete() - From 7476fedbc9156d8de84a21af2d6a97f48407eb4a Mon Sep 17 00:00:00 2001 From: Klaus Jensen Date: Wed, 29 Sep 2021 14:23:02 +0200 Subject: [PATCH 0174/1564] types: add NVME_CAP_CSS_CSI Signed-off-by: Klaus Jensen --- src/nvme/types.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/nvme/types.h b/src/nvme/types.h index a07a925642..292284e05a 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -297,6 +297,7 @@ enum nvme_cap { 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, }; From abdd8bec59c5049bf0f412e9e391918f84c54f74 Mon Sep 17 00:00:00 2001 From: Martin Belanger Date: Wed, 6 Oct 2021 14:39:56 -0400 Subject: [PATCH 0175/1564] Add support for scoped IPv6 --- src/nvme/fabrics.c | 108 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 105 insertions(+), 3 deletions(-) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index ebfc635684..319d66f79d 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -23,6 +23,7 @@ #include #include #include +#include #ifdef CONFIG_SYSTEMD #include @@ -215,16 +216,117 @@ static int add_argument(char **argstr, const char *tok, const char *arg) return 0; } +static int inet4_pton(const char *src, uint16_t port, + struct sockaddr_storage *addr) +{ + struct sockaddr_in *addr4 = (struct sockaddr_in *)addr; + + if (strlen(src) > INET_ADDRSTRLEN) + return -EINVAL; + + if (inet_pton(AF_INET, src, &addr4->sin_addr.s_addr) <= 0) + return -EINVAL; + + addr4->sin_family = AF_INET; + addr4->sin_port = htons(port); + + return 0; +} + +static int inet6_pton(const char *src, uint16_t port, + struct sockaddr_storage *addr) +{ + int ret = -EINVAL; + struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr; + + if (strlen(src) > INET6_ADDRSTRLEN) + return -EINVAL; + + char *tmp = strdup(src); + if (!tmp) + nvme_msg(LOG_ERR, "cannot copy: %s\n", src); + + const char *scope = NULL; + char *p = strchr(tmp, SCOPE_DELIMITER); + if (p) { + *p = '\0'; + scope = src + (p - tmp) + 1; + } + + if (inet_pton(AF_INET6, tmp, &addr6->sin6_addr) != 1) + goto free_tmp; + + if (IN6_IS_ADDR_LINKLOCAL(&addr6->sin6_addr) && scope) { + addr6->sin6_scope_id = if_nametoindex(scope); + if (addr6->sin6_scope_id == 0) { + nvme_msg(LOG_ERR, + "can't find iface index for: %s (%m)\n", scope); + goto free_tmp; + } + } + + addr6->sin6_family = AF_INET6; + addr6->sin6_port = htons(port); + ret = 0; + +free_tmp: + free(tmp); + return ret; +} + +/** + * inet_pton_with_scope - convert an IPv4/IPv6 to socket address + * @af: address family, AF_INET, AF_INET6 or AF_UNSPEC for either + * @src: the start of the address string + * @addr: output socket address + * + * Return 0 on success, errno otherwise. + */ +static int inet_pton_with_scope(int af, const char *src, const char * trsvcid, + struct sockaddr_storage *addr) +{ + int ret = -EINVAL; + uint16_t port = 0; + + if (trsvcid) { + unsigned long long tmp = strtoull(trsvcid, NULL, 0); + port = (uint16_t)tmp; + if (tmp != port) { + nvme_msg(LOG_ERR, "trsvcid out of range: %s\n", trsvcid); + return -ERANGE; + } + } else { + port = 0; + } + + switch (af) { + case AF_INET: + ret = inet4_pton(src, port, addr); + break; + case AF_INET6: + ret = inet6_pton(src, port, addr); + break; + case AF_UNSPEC: + ret = inet4_pton(src, port, addr); + if (ret) + ret = inet6_pton(src, port, addr); + break; + default: + nvme_msg(LOG_ERR, "unexpected address family %d\n", af); + } + + return ret; +} + static bool traddr_is_hostname(nvme_ctrl_t c) { - char addrstr[NVMF_TRADDR_SIZE]; + struct sockaddr_storage addr; if (!c->traddr) return false; if (strcmp(c->transport, "tcp") && strcmp(c->transport, "rdma")) return false; - if (inet_pton(AF_INET, c->traddr, addrstr) > 0 || - inet_pton(AF_INET6, c->traddr, addrstr) > 0) + if (inet_pton_with_scope(AF_UNSPEC, c->traddr, c->trsvcid, &addr) == 0) return false; return true; } From f73bfe826ff4b2c352d700392607bab31c479046 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 7 Oct 2021 17:42:50 +0200 Subject: [PATCH 0176/1564] libnvme.map: Add nvme_get_attr nvme_get_attr is missing in the export. Signed-off-by: Daniel Wagner --- src/libnvme.map | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libnvme.map b/src/libnvme.map index c0f7c7ebd9..a2842c17d7 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -59,6 +59,7 @@ nvme_fw_download; nvme_fw_download_seq; nvme_get_ana_log_len; + nvme_get_attr; nvme_get_ctrl_attr; nvme_get_ctrl_telemetry; nvme_get_directive_receive_length; From e0ed2d57ec98f4315be7079b077d8479eb285207 Mon Sep 17 00:00:00 2001 From: Martin Belanger Date: Thu, 7 Oct 2021 12:36:11 -0400 Subject: [PATCH 0177/1564] Fix compiler warning. Signed-off-by: Martin Belanger martin_belanger@dell.com --- src/nvme/tree.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 2c5837a1a7..83c712828f 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -1120,7 +1120,8 @@ int nvme_init_ctrl(nvme_host_t h, nvme_ctrl_t c, int instance) else path = NULL; if (ret < 0) { - nvme_msg(LOG_ERR, "Failed to init subsystem %s\n", path); + nvme_msg(LOG_ERR, "Failed to init subsystem %s/%s\n", + nvme_subsys_sysfs_dir, subsys_name); if (path) free(path); goto out_free_subsys; From 9a70f6332c5703569abbb20fdce0a939c66db4a4 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 30 Sep 2021 10:48:28 +0200 Subject: [PATCH 0178/1564] tree: remove nvme_ctrl_get_host{nqn,id} No point in trying to fetch the host details from the controller; if required the caller can walk up the chain directly. Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 14 -------------- src/nvme/tree.h | 16 ---------------- 2 files changed, 30 deletions(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 83c712828f..937687daeb 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -675,20 +675,6 @@ const char *nvme_ctrl_get_host_iface(nvme_ctrl_t c) return c->host_iface; } -const char *nvme_ctrl_get_hostnqn(nvme_ctrl_t c) -{ - if (!c->s || !c->s->h) - return default_host->hostnqn; - return c->s->h->hostnqn; -} - -const char *nvme_ctrl_get_hostid(nvme_ctrl_t c) -{ - if (!c->s || !c->s->h) - return default_host->hostid; - return c->s->h->hostid; -} - struct nvme_fabrics_config *nvme_ctrl_get_config(nvme_ctrl_t c) { return &c->cfg; diff --git a/src/nvme/tree.h b/src/nvme/tree.h index 68f5cbfca9..7661133453 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -731,22 +731,6 @@ const char *nvme_ctrl_get_transport(nvme_ctrl_t c); */ const char *nvme_ctrl_get_subsysnqn(nvme_ctrl_t c); -/** - * nvme_ctrl_get_hostnqn() - - * @c: - * - * Return: - */ -const char *nvme_ctrl_get_hostnqn(nvme_ctrl_t c); - -/** - * nvme_ctrl_get_hostid() - - * @c: - * - * Return: - */ -const char *nvme_ctrl_get_hostid(nvme_ctrl_t c); - /** * nvme_ctrl_get_subsystem() - * @c: From c7b4f02a68ad79fde71a3b1e4d3af887701313cb Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 30 Sep 2021 10:24:09 +0200 Subject: [PATCH 0179/1564] fabrics: make uuid_from_device_tree and uuid_from_dmi static The functions are internal to fabrics.c, so mark them as 'static'. Signed-off-by: Hannes Reinecke --- src/nvme/fabrics.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 319d66f79d..16e014027c 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -763,7 +763,7 @@ int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, #define PATH_UUID_IBM "/proc/device-tree/ibm,partition-uuid" -int uuid_from_device_tree(char *system_uuid) +static int uuid_from_device_tree(char *system_uuid) { ssize_t len; int f; @@ -781,7 +781,7 @@ int uuid_from_device_tree(char *system_uuid) #define PATH_DMI_ENTRIES "/sys/firmware/dmi/entries" -int uuid_from_dmi(char *system_uuid) +static int uuid_from_dmi(char *system_uuid) { int f; DIR *d; From 2cf88bc1c0f85c37bcff84534050a2664d05c34d Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 30 Sep 2021 11:16:39 +0200 Subject: [PATCH 0180/1564] tree: make nvme_init_ctrl() an internal symbol nvme_init_ctrl() should not be exported, so move it to private.h to indicate it's an internal symbol. Signed-off-by: Hannes Reinecke --- src/nvme/private.h | 2 ++ src/nvme/tree.h | 10 ---------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/nvme/private.h b/src/nvme/private.h index 2a151bf861..29e96bf322 100644 --- a/src/nvme/private.h +++ b/src/nvme/private.h @@ -111,6 +111,8 @@ struct nvme_root { bool modified; }; +int nvme_init_ctrl(nvme_host_t h, nvme_ctrl_t c, int instance); + int nvme_set_attr(const char *dir, const char *attr, const char *value); void json_read_config(nvme_root_t r, const char *config_file); diff --git a/src/nvme/tree.h b/src/nvme/tree.h index 7661133453..702793dafe 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -853,16 +853,6 @@ nvme_ctrl_t nvme_scan_ctrl(nvme_root_t r, const char *name); */ void nvme_rescan_ctrl(nvme_ctrl_t c); -/** - * nvme_init_ctrl() - - * @h: - * @c: - * @instance: - * - * Return: - */ -int nvme_init_ctrl(nvme_host_t h, nvme_ctrl_t c, int instance); - /** * nvme_free_ctrl() - * @c: From d4f104c0311563b15b28049335eeb71c499365a4 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 30 Sep 2021 11:42:37 +0200 Subject: [PATCH 0181/1564] json: allow 'NULL' argument to json_update_config() Allow a 'NULL' argument to json_update_config() to indicate that the contents should be written to stdout. Signed-off-by: Hannes Reinecke --- src/nvme/json.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/nvme/json.c b/src/nvme/json.c index faadf2d383..09791d2a14 100644 --- a/src/nvme/json.c +++ b/src/nvme/json.c @@ -267,10 +267,15 @@ int json_update_config(nvme_root_t r, const char *config_file) json_object_put(subsys_array); json_object_array_add(json_root, host_obj); } - if (json_object_to_file_ext(config_file, json_root, - JSON_C_TO_STRING_PRETTY) < 0) { - nvme_msg(LOG_ERR, "Failed to write %s, %s\n", - config_file, json_util_get_last_err()); + if (!config_file) + ret = json_object_to_fd(1, json_root, JSON_C_TO_STRING_PRETTY); + else + ret = json_object_to_file_ext(config_file, json_root, + JSON_C_TO_STRING_PRETTY); + if (ret < 0) { + nvme_msg(LOG_ERR, "Failed to write to %s, %s\n", + config_file ? "stdout" : config_file, + json_util_get_last_err()); ret = -1; errno = EIO; } From 56df7cec5499173a974fb234042151fdc7e0a52e Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 30 Sep 2021 11:45:43 +0200 Subject: [PATCH 0182/1564] tree: add nvme_dump_config() Add nvme_dump_config() to print out the current tree to stdout. Signed-off-by: Hannes Reinecke --- src/libnvme.map | 1 + src/nvme/tree.c | 10 ++++++++++ src/nvme/tree.h | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/src/libnvme.map b/src/libnvme.map index a2842c17d7..322097f21d 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -48,6 +48,7 @@ nvme_disconnect_ctrl; nvme_dsm; nvme_dsm_range; + nvme_dump_config; nvme_first_host; nvme_first_subsystem; nvme_flush; diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 937687daeb..fb724c9d24 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -130,6 +130,16 @@ int nvme_update_config(nvme_root_t r) #endif } +int nvme_dump_config(nvme_root_t r) +{ +#ifdef CONFIG_JSONC + return json_update_config(r, NULL); +#else + errno = ENOTSUP; + return -1; +#endif +} + nvme_host_t nvme_first_host(nvme_root_t r) { return list_top(&r->hosts, struct nvme_host, entry); diff --git a/src/nvme/tree.h b/src/nvme/tree.h index 702793dafe..f9e7d3713e 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -955,6 +955,14 @@ void nvme_reset_topology(nvme_root_t r); */ int nvme_update_config(nvme_root_t r); +/** + * nvme_dump_config() - + * @r: + * + * Return: + */ +int nvme_dump_config(nvme_root_t r); + /** * nvme_free_tree() - * @r: From 60dac06779349a36e9370a67b8fa43ba7858a102 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 8 Oct 2021 13:36:42 +0200 Subject: [PATCH 0183/1564] Create make.yml --- .github/workflows/make.yml | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 .github/workflows/make.yml diff --git a/.github/workflows/make.yml b/.github/workflows/make.yml new file mode 100644 index 0000000000..92f803c41d --- /dev/null +++ b/.github/workflows/make.yml @@ -0,0 +1,35 @@ +# This is a basic workflow to help you get started with Actions + +name: libnvme CI + +# Controls when the workflow will run +on: + # Triggers the workflow on push or pull request events but only for the master branch + push: + branches: [ master ] + pull_request: + branches: [ master ] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + build: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v2 + + # Install required libraries + - name: install libraries + run: sudo apt-get install libjson-c-dev + + # Build library + - name: Build libnvme + run: make clean && make && make clean + From a1069e5fd82f1b907cf23489fa807a5650ec0072 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 7 Oct 2021 11:51:36 +0200 Subject: [PATCH 0184/1564] Add nvme_identify_active_ns_list_csi() and nvme_identify_allocated_ns_list_csi() Update the command IDs with the values from NVMe base spec v2.0 and implement the missing nvme_identify_active_ns_list_csi() and nvme_identify_allocated_ns_list_csi(). Signed-off-by: Hannes Reinecke --- src/nvme/ioctl.c | 18 +++++++++++++++++ src/nvme/ioctl.h | 50 ++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 64 insertions(+), 4 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 9a8526d652..8fbed44025 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -496,6 +496,24 @@ int nvme_identify_ns_csi(int fd, __u32 nsid, __u8 csi, void *data) NVME_UUID_NONE, csi, data); } +int nvme_identify_active_ns_list_csi(int fd, __u32 nsid, __u8 csi, + struct nvme_ns_list *list) +{ + BUILD_ASSERT(sizeof(struct nvme_ns_list) == 4096); + return nvme_identify(fd, NVME_IDENTIFY_CNS_CSI_NS_ACTIVE_LIST, nsid, + NVME_CNTLID_NONE, NVME_NVMSETID_NONE, + NVME_UUID_NONE, csi, list); +} + +int nvme_identify_allocated_ns_list_css(int fd, __u32 nsid, __u8 csi, + struct nvme_ns_list *list) +{ + return nvme_identify(fd, NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST, nsid, + NVME_CNTLID_NONE, NVME_NVMSETID_NONE, + NVME_UUID_NONE, csi, list); +} + + int nvme_identify_iocs(int fd, __u16 cntlid, struct nvme_id_iocs *iocs) { BUILD_ASSERT(sizeof(struct nvme_id_iocs) == 4096); diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index a040da5d0b..7edfd5f32b 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -442,6 +442,7 @@ enum nvme_admin_opcode { * @NVME_IDENTIFY_CNS_NVMSET_LIST: * @NVME_IDENTIFY_CNS_CSI_NS: * @NVME_IDENTIFY_CNS_CSI_CTRL: + * @NVME_IDENTIFY_CNS_CSI_CSI_NS_ACTIVE_LIST: * @NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST: * @NVME_IDENTIFY_CNS_ALLOCATED_NS: * @NVME_IDENTIFY_CNS_NS_CTRL_LIST: @@ -450,7 +451,7 @@ enum nvme_admin_opcode { * @NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST: * @NVME_IDENTIFY_CNS_NS_GRANULARITY: * @NVME_IDENTIFY_CNS_UUID_LIST: - * @NVME_IDENTIFY_CNS_CSI_ALLOCATED_NS: + * @NVME_IDENTIFY_CNS_CSI_ALLOCATED_NS_LIST: * @NVME_IDENTIFY_CNS_COMMAND_SET_STRUCTURE: Base Specification 2.0a section 5.17.2.21 */ enum nvme_identify_cns { @@ -459,8 +460,9 @@ enum nvme_identify_cns { NVME_IDENTIFY_CNS_NS_ACTIVE_LIST = 0x02, NVME_IDENTIFY_CNS_NS_DESC_LIST = 0x03, NVME_IDENTIFY_CNS_NVMSET_LIST = 0x04, - NVME_IDENTIFY_CNS_CSI_NS = 0x05, /* XXX: Placeholder until assigned */ - NVME_IDENTIFY_CNS_CSI_CTRL = 0x06, /* XXX: Placeholder until assigned */ + NVME_IDENTIFY_CNS_CSI_NS = 0x05, + NVME_IDENTIFY_CNS_CSI_CTRL = 0x06, + NVME_IDENTIFY_CNS_CSI_NS_ACTIVE_LIST = 0x07, NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST = 0x10, NVME_IDENTIFY_CNS_ALLOCATED_NS = 0x11, NVME_IDENTIFY_CNS_NS_CTRL_LIST = 0x12, @@ -469,7 +471,7 @@ enum nvme_identify_cns { NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST = 0x15, NVME_IDENTIFY_CNS_NS_GRANULARITY = 0x16, NVME_IDENTIFY_CNS_UUID_LIST = 0x17, - NVME_IDENTIFY_CNS_CSI_ALLOCATED_NS = 0x18, /* XXX: Placeholder until assigned */ + NVME_IDENTIFY_CNS_CSS_ALLOCATED_NS_LIST = 0x1A, NVME_IDENTIFY_CNS_COMMAND_SET_STRUCTURE = 0x1C, }; @@ -1061,6 +1063,46 @@ int nvme_identify_ns_csi(int fd, __u32 nsid, __u8 csi, void *data); */ int nvme_identify_ctrl_csi(int fd, __u8 csi, void *data); +/** + * nvme_identify_active_ns_list_csi() - + * @fd: File descriptor of nvme device + * @nsid: Return namespaces greater than this identifier + * @csi: Command Set Identifier + * @ns_list: User space destination address to transfer the data + * + * A list of 1024 namespace IDs is returned to the host containing active + * NSIDs in increasing order that are greater than the value specified in + * the Namespace Identifier (nsid) field of the command and matching the + * I/O Command Set specified in the @csi argument. + * + * See &struct nvme_ns_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. + */ +int nvme_identify_active_ns_list_csi(int fd, __u32 nsid, __u8 csi, + struct nvme_ns_list *list); + +/** + * nvme_identify_allocated_ns_list_csi() - + * @fd: File descriptor of nvme device + * @nsid: Return namespaces greater than this identifier + * @csi: Command Set Identifier + * @ns_list: User space destination address to transfer the data + * + * A list of 1024 namespace IDs is returned to the host containing allocated + * NSIDs in increasing order that are greater than the value specified in + * the @nsid field of the command and matching the I/O Command Set + * specified in the @csi argument. + * + * See &struct nvme_ns_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. + */ +int nvme_identify_allocated_ns_list_csi(int fd, __u32 nsid, __u8 csi, + struct nvme_ns_list *list); + /** * nvme_identify_ctrl_nvm() - * @fd: File descriptor of nvme device From 8aefabff6c06de7ec519bacaada17fdd66f6da2e Mon Sep 17 00:00:00 2001 From: Martin Belanger Date: Wed, 6 Oct 2021 20:39:55 -0400 Subject: [PATCH 0185/1564] build: Add support for meson build system [dwagner: updated README.md] Signed-off-by: Daniel Wagner --- .gitignore | 2 + README | 26 ------ README.md | 173 +++++++++++++++++++++++++++++++++++++ ccan/meson.build | 21 +++++ doc/meson.build | 37 ++++++++ examples/meson.build | 25 ++++++ libnvme.spec.in | 53 ++++++++++++ meson.build | 200 +++++++++++++++++++++++++++++++++++++++++++ meson_options.txt | 7 ++ pynvme/__init__.py | 0 pynvme/meson.build | 33 +++++++ src/meson.build | 71 +++++++++++++++ test/meson.build | 40 +++++++++ 13 files changed, 662 insertions(+), 26 deletions(-) delete mode 100644 README create mode 100644 README.md create mode 100644 ccan/meson.build create mode 100644 doc/meson.build create mode 100644 examples/meson.build create mode 100644 libnvme.spec.in create mode 100644 meson.build create mode 100644 meson_options.txt create mode 100644 pynvme/__init__.py create mode 100644 pynvme/meson.build create mode 100644 src/meson.build create mode 100644 test/meson.build diff --git a/.gitignore b/.gitignore index cbf80394b6..29a202e316 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,5 @@ config-host.mak config.log cscope.* + +.build diff --git a/README b/README deleted file mode 100644 index 1b40be2ea1..0000000000 --- a/README +++ /dev/null @@ -1,26 +0,0 @@ -libnvme -------- - -This is the libnvme development C library. libnvme provides type -defintions for NVMe specification structures, enumerations, and bit -fields, helper functions to construct, dispatch, and decode commands -and payloads, and utilities to connect, scan, and manage nvme devices -on a Linux system. - -The public specification is the authority to resolve any protocol -discrepencies with this library. For more info on NVM Express, please see: - - http://nvmexpress.org - -Subscribe to linux-nvme@lists.infradead.org for linux-nvme related discussions -and development for both kernel and userspace. The list is archived here: - - http://lists.infradead.org/mailman/listinfo/linux-nvme - -License -------- - -Except where otherwise stated, all software contained within this repo is -currently licensed LGPL, see COPYING for more information. - -Keith Busch 2020-02-06 diff --git a/README.md b/README.md new file mode 100644 index 0000000000..2613a52848 --- /dev/null +++ b/README.md @@ -0,0 +1,173 @@ +# libnvme + +This is the libnvme development C library. libnvme provides type +defintions for NVMe specification structures, enumerations, and bit +fields, helper functions to construct, dispatch, and decode commands +and payloads, and utilities to connect, scan, and manage nvme devices +on a Linux system. + +The public specification is the authority to resolve any protocol +discrepencies with this library. For more info on NVM Express, please +see: + + http://nvmexpress.org + +Subscribe to linux-nvme@lists.infradead.org for linux-nvme related +discussions and development for both kernel and userspace. The list is +archived here: + + http://lists.infradead.org/mailman/listinfo/linux-nvme + +# License + +Except where otherwise stated, all software contained within this repo +is currently licensed LGPL, see COPYING for more information. + +Keith Busch 2020-02-06 + +------ + +# Building with meson + +## What is the meson build system? + +Here's an excerpt from the meson web site: *Meson is **an open source +build system** meant to be both extremely fast, and, even more +importantly, as user friendly as possible. The main design point of +Meson is that every moment a developer spends writing or debugging +build definitions is a second wasted.* + +Several well-known projects such as `systemd` and `Gnome` use meson as +their build system. A summary of projects using meson can be found +[here](https://mesonbuild.com/Users.html). For more info on meson, +please consult the following sites: + +**Wiki page**: https://en.wikipedia.org/wiki/Meson_(software) + +**meson documentation**: https://mesonbuild.com/ + +**meson repo**: https://github.com/mesonbuild/meson + +## Prerequisite + +First, install meson. + +**Debian / Ubuntu**: + +```bash +sudo apt-get install meson +``` + +**Fedora / Red Hat**: + +```bash +sudo dnf install meson +``` + +## To compile libnvme + +Using meson is similar to projects that use a `configure` script before running `make`. + +To `configure` the project: + +``` +meson .build +``` + +One nice feature of meson is that it doesn't mix build artifacts +(e.g. `*.o`, `*.so`, etc.) with source code. In the above example, +"`.build`" is the name of the directory where the build configuration +as well as all the build artifacts will be saved. This directory can +be named anything as long as it's not an existing source directory. To +completely "clean" all the build artifacts, one need only delete the +`.build` directory. + +To compile: + +``` +cd .build +ninja +``` + +Or: + +``` +ninja -C .build +``` + +## To install libnvme + +To install `libnvme`: + +``` +cd .build +meson install +``` + +## To run unit tests + +To run unit tests: + +``` +cd .build +meson test +``` + +## To clean after a build + +To perform the equivalent of a `make clean` without deleting the build configuration. + +``` +cd .build +ninja -t clean +``` + +Or: + +``` +ninja -C .build -t clean +``` + +## To purge everything + +To completely clean all build artifacts, including the build configuration. + +``` +rm -rf .build +``` + +## Supported build options + +A few build options can be specified on the command line when invoking meson. + +| Option | Values [default] | Description | +| ------- | ------------------- | ------------------------------------------------------------ | +| systemd | [auto], true, false | Whether to link libsystemd to libnvme. When set to `auto`, the default, meson will check for the presence of library and will only link to it if it is found. When set to `true`, meson will make this library a mandatory dependency. When set to `false`, meson will not link the library to libnvme, even if the library is available. | + +### Changing the build options from the command-line (i.e. w/o modifying any files) + +Here's an example where we tell meson that we do not want to link +against the `systemd` library: + +```bash +meson .build -Dsystemd=false +``` + +To configure a build for debugging purposes (i.e. optimization turned +off and debug symbols enabled): + +```bash +meson .build -Dbuildtype=debug +``` + +To enable address sanitizer (advanced debugging of memory issues): + +```bash +meson .build -Db_sanitize=address +``` + +To list configuration options that are available and possible values: + +```bash +meson configure .build +``` diff --git a/ccan/meson.build b/ccan/meson.build new file mode 100644 index 0000000000..f24b94f5b9 --- /dev/null +++ b/ccan/meson.build @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# This file is part of libnvme. +# Copyright (c) 2021 Dell Inc. +# +# Authors: Martin Belanger +# +configurator = executable( + 'configurator', + ['tools/configurator/configurator.c'], + c_args: ['-D_GNU_SOURCE'], +) + +config_h = custom_target( + 'config.h', + output: 'config.h', + capture: true, + command: [configurator, ] +) + + diff --git a/doc/meson.build b/doc/meson.build new file mode 100644 index 0000000000..d4bbf56645 --- /dev/null +++ b/doc/meson.build @@ -0,0 +1,37 @@ +# SPDX-License-Identifier: BSD-3 +# +# This file is part of STorage Appliance Services (STAS). +# Copyright (c) 2021 Dell Inc. +# +# Authors: Martin Belanger +# + +# Requires python3-sphinx and python3-sphinx-rtd-theme + +sphinx_sources = [ + 'conf.py', + 'libnvme.rst', + 'index.rst' +] + +man_pages = [ + 'libnvme.1' +] + +mandir1 = join_paths(get_option('mandir'), 'man1') + +if get_option('man') + sphinx_build = find_program('sphinx-build-3', 'sphinx-build') + + custom_target( + 'man', + command: [sphinx_build, + '-b', 'man', + meson.current_source_dir(), + meson.current_build_dir()], + input: sphinx_sources, + output: man_pages, + install: true, + install_dir: mandir1, + ) +endif diff --git a/examples/meson.build b/examples/meson.build new file mode 100644 index 0000000000..0ed97d001e --- /dev/null +++ b/examples/meson.build @@ -0,0 +1,25 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# This file is part of libnvme. +# Copyright (c) 2021 Dell Inc. +# +# Authors: Martin Belanger +# +executable( + 'telemetry-listen', + ['telemetry-listen.c'], + link_with: libnvme_static, + include_directories: incdir) + +executable( + 'display-columnar', + ['display-columnar.c'], + link_with: libnvme_static, + include_directories: incdir) + +executable( + 'discover-loop', + ['discover-loop.c'], + link_with: libnvme_static, + include_directories: incdir) + diff --git a/libnvme.spec.in b/libnvme.spec.in new file mode 100644 index 0000000000..e2dbd13998 --- /dev/null +++ b/libnvme.spec.in @@ -0,0 +1,53 @@ +Name: @NAME@ +Version: @VERSION@ +Release: 0 +Summary: Linux-native nvme device management library +License: @LICENSE@ +Source: %{name}-%{version}.tar.gz +BuildRoot: %{_tmppath}/%{name}-root +URL: http://github.com/linux-nvme/libnvme +BuildRequires: gcc + +%description +Provides library functions for accessing and managing nvme devices on a Linux +system. + +%package devel +Summary: Development files for Linux-native nvme +Requires: libnvme +Provides: libnvme.so.1 + +%description devel +This package provides header files to include and libraries to link with +for Linux-native nvme device maangement. + +%prep +%autosetup -c + +%build +%meson +%meson_build + +%install +%meson_install + +%check +%meson_test + +%files +%defattr(-,root,root) +%attr(0755,root,root) %{_libdir}/libnvme.so.* +%doc COPYING + +%files devel +%defattr(-,root,root) +%attr(-,root,root) %{_includedir}/nvme/ +%attr(0644,root,root) %{_includedir}/libnvme.h +%attr(0755,root,root) %{_libdir}/libnvme.so +%attr(0644,root,root) %{_libdir}/libnvme.a +%attr(0644,root,root) %{_libdir}/pkgconfig/* +%attr(0644,root,root) %{_mandir}/man2/* + +%changelog +* Thu Dec 12 2019 Keith Busch - 0.1 +- Initial version diff --git a/meson.build b/meson.build new file mode 100644 index 0000000000..1da4c2993d --- /dev/null +++ b/meson.build @@ -0,0 +1,200 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# This file is part of libnvme. +# Copyright (c) 2021 Dell Inc. +# +# Authors: Martin Belanger +# + +################################################################################ +# Building libnvme using meson and ninja: +# meson .build +# ninja -C .build +# +# Installing the code after building: +# cd .build +# sudo meson install +# +# Running unit tests: +# cd .build +# meson test +# +# In these examples, ".build" is the name of the directory where the build +# artifacts are saved. The directory need not be called ".build", but it must +# be a unique (non-existing) directory. +# +# Changing build options from the command line: +# Build options can be changed at the command line without modifying the +# "meson.build" files. This is particularly useful during debugging. For +# example, the "buildtype" option allows to disable optimization to +# facilitate debugging. This option can be specified on the command line as +# follows: +# +# meson .build -Dbuildtype=debug +# +# Doing so overrides the value found in the meson.build, which is set to +# "buildtype=release" below. The buildtype option can take any of the +# following values. +# +# plain: no extra build flags are used, even for compiler warnings, +# useful for distro packagers and other cases where you need +# to specify all arguments by yourself +# +# debug: debug info is generated but the result is not optimized, +# this is the default +# +# debugoptimized: debug info is generated and the code is optimized (on most +# compilers this means -g -O2) +# +# release: full optimization, no debug info +# +# default_options: https://mesonbuild.com/Builtin-options.html#compiler-options +# +# Examples: meson .build -Dbuildtype=debug +# meson .build -Db_sanitize=address +# meson .build -Djson-c=true +# +# References: https://mesonbuild.com/ +# https://ninja-build.org/ +# +################################################################################ +project( + 'libnvme', ['c', 'cpp'], + meson_version: '>= 0.47.0', + version: '0.1', + license: 'LGPLv2+', + default_options: [ + 'buildtype=release', + 'prefix=/usr', + ] +) + +################################################################################ +cc = meson.get_compiler('c') + +prefixdir = get_option('prefix') +libdir = join_paths(prefixdir, get_option('libdir')) +includedir = join_paths(prefixdir, get_option('includedir')) +datadir = join_paths(prefixdir, get_option('datadir')) +mandir = join_paths(prefixdir, get_option('mandir')) +bindir = join_paths(prefixdir, get_option('bindir')) + +pkgconfiglibdir = get_option('pkgconfiglibdir') == '' ? join_paths(libdir, 'pkgconfig') : get_option('pkgconfiglibdir') + +################################################################################ +conf = configuration_data() + +# Check for libuuid availability +libuuid = dependency('uuid', required: true) +conf.set('CONFIG_LIBUUID', libuuid.found(), description: 'Is libuuid required?') + +# Check for libjson-c availability +libjson = dependency('json-c', required: false) +if not libjson.found() + libjson = cc.find_library('json-c', required: true) +endif +conf.set('CONFIG_JSONC', libjson.found(), description: 'Is json-c required?') + +# Check for libsystemd availability +want_systemd = get_option('systemd') +if want_systemd != 'false' + libsystemd = dependency('libsystemd', required: want_systemd == 'true') + have = libsystemd.found() +else + libsystemd = [] + have = false +endif +conf.set('CONFIG_SYSTEMD', have, description: 'Is libsystemd required?') + +################################################################################ +# The following commented-out text is the beginning of an effort to replace +# ccan/tools/configurator. It is not complete yet. Eventually we would like +# to replace everything that ccan/tools/configurator does with meson. +# To be continued... +################################################################################ +#args = ['-g3', '-ggdb', '-Wall', '-Wundef', '-Wmissing-prototypes', '-Wmissing-declarations', '-Wstrict-prototypes', '-Wold-style-definition'] +#conf.set10( +# 'HAVE_STRUCT_TIMESPEC', +# cc.compiles( +# ''' +# #include +# static void func(void) { +# struct timespec ts; +# ts.tv_sec = ts.tv_nsec = 1; +# } +# int main(int argc, char *argv[]) { +# (void)func(); +# return 0; +# } +# ''', +# no_builtin_args: true, +# args: args, +# name: 'struct timespec' +# ), +# description: 'Is struct timespec defined?' +#) +#conf.set10( +# 'HAVE_ASPRINTF', +# cc.compiles( +# ''' +# #define _GNU_SOURCE +# #include +# static char *func(int x) { +# char *p; +# if (asprintf(&p, "%u", x) == -1) +# p = NULL; +# return p; +# } +# int main(int argc, char *argv[]) { +# (void)func(1000); +# return 0; +# } +# ''', +# no_builtin_args: true, +# args: args, +# name: 'asprintf()' +# ), +# description: 'Is asprintf() supported?' +#) + +configure_file( + output: 'config-host.h', + configuration: conf +) + +################################################################################ +substs = configuration_data() +substs.set('NAME', meson.project_name()) +substs.set('VERSION', meson.project_version()) +substs.set('LICENSE', meson.project_license()[0]) +configure_file( + input: 'libnvme.spec.in', + output: 'libnvme.spec', + configuration: substs, +) + +################################################################################ +pkg = import('pkgconfig') +pkg.generate( + filebase: meson.project_name(), + name: meson.project_name(), + version: meson.project_version(), + description: 'Manage "libnvme" subsystem devices (Non-volatile Memory Express)', + url: 'http://github.com/linux-nvme/libnvme/', + libraries: ['-L${libdir}', '-lnvme'], + requires: [libuuid, libjson, libsystemd], +) + +################################################################################ +add_project_arguments('-include', 'config-host.h', language : 'c') +add_global_arguments(['-fomit-frame-pointer', '-D_GNU_SOURCE'], language : 'c') +incdir = include_directories(['ccan', 'src']) + +################################################################################ +subdir('ccan') +subdir('src') +subdir('pynvme') +subdir('test') +subdir('examples') +subdir('doc') + diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 0000000000..f08b27fb3f --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,7 @@ +# -*- mode: meson -*- + +option('pkgconfiglibdir', type : 'string', value : '', description : 'directory for standard pkg-config files') + +option('man', type : 'boolean', value : false, description : 'build and install man pages (requires sphinx-build)') + +option('systemd', type : 'combo', choices : ['auto', 'true', 'false'], description : 'libsystemd support') diff --git a/pynvme/__init__.py b/pynvme/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/pynvme/meson.build b/pynvme/meson.build new file mode 100644 index 0000000000..15d5cc261c --- /dev/null +++ b/pynvme/meson.build @@ -0,0 +1,33 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# This file is part of libnvme. +# Copyright (c) 2021 Dell Inc. +# +# Authors: Martin Belanger +# +python3 = import('python').find_installation('python3') +swig = find_program('swig', required: true) +pymod_swig = custom_target( + 'nvme.py', + input: ['nvme.i', config_h], + output: ['nvme.py', 'nvme_wrap.c'], + command: [swig, '-python', '-py3', '-o', '@OUTPUT1@', '@INPUT0@'], + install: true, + install_dir: [python3.get_install_dir(pure: false, subdir: 'libnvme'), false], +) + +pynvme_clib = python3.extension_module( + '_nvme', + pymod_swig[1], + dependencies : python3.dependency(), + include_directories: incdir, + link_with: libnvme_static, + install: true, + subdir: 'libnvme', +) + +python3.install_sources( + ['__init__.py', ], + pure: false, + subdir: 'libnvme', +) diff --git a/src/meson.build b/src/meson.build new file mode 100644 index 0000000000..db03e0414e --- /dev/null +++ b/src/meson.build @@ -0,0 +1,71 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# This file is part of libnvme. +# Copyright (c) 2021 Dell Inc. +# +# Authors: Martin Belanger +# +sources = [ + 'nvme/cleanup.c', + 'nvme/fabrics.c', + 'nvme/filters.c', + 'nvme/ioctl.c', + 'nvme/log.c', + 'nvme/tree.c', + 'nvme/util.c', + config_h, +] + +if conf.get('CONFIG_JSONC') + sources += 'nvme/json.c' +endif + +deps = [ + libuuid, + libsystemd, + libjson, +] + +source_dir = meson.current_source_dir() +mapfile = 'libnvme.map' +version_script_arg = join_paths(source_dir, mapfile) + +libnvme_shared = shared_library( + 'nvme', # produces libnvme.so + sources, + version: meson.project_version(), + soversion: '1', + link_args: ['-Wl,--version-script=' + version_script_arg], + dependencies: deps, + link_depends: mapfile, + include_directories: incdir, + install: true, +) + +libnvme_static = static_library( + 'nvme', # produces libnvme.a + sources, + link_args: ['-Wl,--version-script=' + version_script_arg], + dependencies: deps, + link_depends: mapfile, + include_directories: incdir, + install : false +) + +mode = ['rw-r--r--', 0, 0] +install_headers('libnvme.h', install_mode: mode) +install_headers([ + 'nvme/fabrics.h', + 'nvme/filters.h', + 'nvme/ioctl.h', + 'nvme/log.h', + 'nvme/tree.h', + 'nvme/types.h', + 'nvme/util.h', + ], + subdir: 'nvme', + install_mode: mode, +) + + + diff --git a/test/meson.build b/test/meson.build new file mode 100644 index 0000000000..61be2ccfc9 --- /dev/null +++ b/test/meson.build @@ -0,0 +1,40 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# This file is part of libnvme. +# Copyright (c) 2021 Dell Inc. +# +# Authors: Martin Belanger +# +main = executable( + 'main-test', + ['test.c'], + link_with: libnvme_static, + include_directories: incdir +) + +cpp = executable( + 'test-cpp', + ['cpp.cc'], + link_with: libnvme_static, + include_directories: incdir +) + +register = executable( + 'test-register', + ['register.c'], + link_with: libnvme_static, + include_directories: incdir +) + +zns = executable( + 'test-zns', + ['zns.c'], + link_with: libnvme_static, + include_directories: incdir +) + +test('main', main) +test('main', main, args: ['nvme10']) +test('cpp', main) +test('register', main, args: ['nvme10']) +test('zns', main) From 0a1ee704285e622dca053497123384f2f98db3a7 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 8 Oct 2021 18:05:21 +0200 Subject: [PATCH 0186/1564] Fix version number for meson build The shared library has the version number '1.0.1', not '0.1'. Signed-off-by: Hannes Reinecke --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 1da4c2993d..aa93901b77 100644 --- a/meson.build +++ b/meson.build @@ -61,7 +61,7 @@ project( 'libnvme', ['c', 'cpp'], meson_version: '>= 0.47.0', - version: '0.1', + version: '1.0.1', license: 'LGPLv2+', default_options: [ 'buildtype=release', From a0bcef5176f32ed391d51cba88baeb28bab92a08 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Mon, 11 Oct 2021 12:10:15 +0200 Subject: [PATCH 0187/1564] build: Add meson CI workflow Based on https://github.com/marketplace/actions/meson-build resolves: #54 Signed-off-by: Daniel Wagner --- .github/workflows/meson.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 .github/workflows/meson.yml diff --git a/.github/workflows/meson.yml b/.github/workflows/meson.yml new file mode 100644 index 0000000000..533a3e45dd --- /dev/null +++ b/.github/workflows/meson.yml @@ -0,0 +1,22 @@ +name: libnvme meson CI + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + + workflow_dispatch: + +jobs: + meson-build: + runs-on: ubuntu-latest + + steps: + - name: install libraries + run: sudo apt-get install libjson-c-dev + - uses: actions/checkout@v2 + - uses: actions/setup-python@v1 + - uses: BSFishy/meson-build@v1.0.3 + with: + action: test From 89c4cc4e66c17b0fbe9a6b2f6766516e6e8604e6 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Mon, 11 Oct 2021 11:57:09 +0200 Subject: [PATCH 0188/1564] fabrics: Do not overflow when reading systemd_uuid MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gcc complains with: ../src/nvme/fabrics.c:774:15: warning: ‘read’ writing 512 bytes into a region of size 37 overflows the destination [-Wstringop-overflow=] 774 | len = read(f, system_uuid, 512); | ^~~~~~~~~~~~~~~~~~~~~~~~~ ../src/nvme/fabrics.c: In function ‘nvmf_hostnqn_generate’: ../src/nvme/fabrics.c:863:14: note: destination object ‘uuid_str’ of size 37 863 | char uuid_str[37]; /* e.g. 1b4e28ba-2fa1-11d2-883f-0016d3cca427 + \0 */ | ^~~~~~~~ Let's limit the read to 37 as we know that's the max size for a UUID. Signed-off-by: Daniel Wagner --- src/nvme/fabrics.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 16e014027c..3ab93210ed 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -40,6 +40,7 @@ #include "private.h" #define NVMF_HOSTID_SIZE 37 +#define UUID_SIZE 37 /* 1b4e28ba-2fa1-11d2-883f-0016d3cca427 + \0 */ const char *nvmf_dev = "/dev/nvme-fabrics"; const char *nvmf_hostnqn_file = "/etc/nvme/hostnqn"; @@ -771,7 +772,9 @@ static int uuid_from_device_tree(char *system_uuid) f = open(PATH_UUID_IBM, O_RDONLY); if (f < 0) return -ENXIO; - len = read(f, system_uuid, 512); + + memset(system_uuid, 0, UUID_SIZE); + len = read(f, system_uuid, UUID_SIZE - 1); close(f); if (len < 0) return -ENXIO; @@ -860,7 +863,7 @@ char *nvmf_hostnqn_generate() { char *hostnqn; int ret; - char uuid_str[37]; /* e.g. 1b4e28ba-2fa1-11d2-883f-0016d3cca427 + \0 */ + char uuid_str[UUID_SIZE]; #ifdef CONFIG_LIBUUID uuid_t uuid; #endif From 113d4e5f733de1279eb0e48510b56614d29a4c51 Mon Sep 17 00:00:00 2001 From: Martin Belanger Date: Mon, 11 Oct 2021 16:09:49 -0400 Subject: [PATCH 0189/1564] Clean up Python exception handling Signed-off-by: Martin Belanger --- pynvme/nvme.i | 40 +++++++++++++++++----------------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/pynvme/nvme.i b/pynvme/nvme.i index 919361727f..ad5a1d8fb7 100644 --- a/pynvme/nvme.i +++ b/pynvme/nvme.i @@ -19,7 +19,6 @@ %rename(ns) nvme_ns; %{ -#include #include #include "nvme/tree.h" #include "nvme/fabrics.h" @@ -58,52 +57,47 @@ static int discover_err = 0; %} %exception host_iter::__next__ { - assert(!host_iter_err); - $action + host_iter_err = 0; + $action /* $action sets host_iter_err to non-zero value on failure */ if (host_iter_err) { - host_iter_err = 0; PyErr_SetString(PyExc_StopIteration, "End of list"); return NULL; } } %exception subsystem_iter::__next__ { - assert(!subsys_iter_err); - $action + subsys_iter_err = 0; + $action /* $action sets subsys_iter_err to non-zero value on failure */ if (subsys_iter_err) { - subsys_iter_err = 0; PyErr_SetString(PyExc_StopIteration, "End of list"); return NULL; } } %exception ctrl_iter::__next__ { - assert(!ctrl_iter_err); - $action + ctrl_iter_err = 0; + $action /* $action sets ctrl_iter_err to non-zero value on failure */ if (ctrl_iter_err) { - ctrl_iter_err = 0; PyErr_SetString(PyExc_StopIteration, "End of list"); return NULL; } } %exception ns_iter::__next__ { - assert(!ns_iter_err); - $action + ns_iter_err = 0; + $action /* $action sets ns_iter_err to non-zero value on failure */ if (ns_iter_err) { - ns_iter_err = 0; PyErr_SetString(PyExc_StopIteration, "End of list"); return NULL; } } %exception nvme_ctrl::connect { - $action + connect_err = 0; + $action /* $action sets connect_err to non-zero value on failure */ if (connect_err == 1) { - connect_err = 0; SWIG_exception(SWIG_AttributeError, "Existing controller connection"); } else if (connect_err) { - connect_err = 0; if (nvme_log_message) SWIG_exception(SWIG_RuntimeError, nvme_log_message); else @@ -112,9 +106,9 @@ static int discover_err = 0; } %exception nvme_ctrl::discover { - $action + discover_err = 0; + $action /* $action sets discover_err to non-zero value on failure */ if (discover_err) { - discover_err = 0; SWIG_exception(SWIG_RuntimeError,"Discover failed"); } } @@ -393,7 +387,7 @@ struct nvme_ns { } struct host_iter __iter__() { struct host_iter ret = { .root = nvme_host_get_root($self), - .pos = $self }; + .pos = $self }; return ret; } struct nvme_subsystem *subsystems() { @@ -452,7 +446,7 @@ struct nvme_ns { } struct subsystem_iter __iter__() { struct subsystem_iter ret = { .host = nvme_subsystem_get_host($self), - .pos = $self }; + .pos = $self }; return ret; } struct nvme_ctrl *controllers() { @@ -550,7 +544,7 @@ struct nvme_ns { } struct ctrl_iter __iter__() { struct ctrl_iter ret = { .subsystem = nvme_ctrl_get_subsystem($self), - .pos = $self }; + .pos = $self }; return ret; } struct nvme_ns *namespaces() { @@ -591,8 +585,8 @@ struct nvme_ns { } struct ns_iter __iter__() { struct ns_iter ret = { .ctrl = nvme_ns_get_ctrl($self), - .subsystem = nvme_ns_get_subsystem($self), - .pos = $self }; + .subsystem = nvme_ns_get_subsystem($self), + .pos = $self }; return ret; } %immutable name; From 3a84d90084b5b2bf8685e814fb3fef04f0bbe311 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Tue, 12 Oct 2021 14:52:03 +0800 Subject: [PATCH 0190/1564] configure: simplify config-host.h & config-host.mak generation Create the configuration files using a here-string, rather than separate commands. While we're at it, fix the configure-command-line formatting in the .h header. Signed-off-by: Jeremy Kerr --- configure | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/configure b/configure index 91a56d0546..feb39caa4c 100755 --- a/configure +++ b/configure @@ -98,18 +98,21 @@ print_config() { CFLAGS="-D_GNU_SOURCE -include config-host.h" BUILD_CFLAGS="" +cmdstr=$(printf " '%s'" "$0" "$@") # Print configure header at the top of $config_host_h -echo "/*" > $config_host_h -echo " * Automatically generated by configure - do not modify" >> $config_host_h -printf " * Configured with:" >> $config_host_h -printf " * '%s'" "$0" "$@" >> $config_host_h -echo "" >> $config_host_h -echo " */" >> $config_host_h - -echo "# Automatically generated by configure - do not modify" > $config_host_mak -printf "# Configured with:" >> $config_host_mak -printf " '%s'" "$0" "$@" >> $config_host_mak -echo >> $config_host_mak +cat > $config_host_h < $config_host_mak < Date: Tue, 12 Oct 2021 12:10:54 +0800 Subject: [PATCH 0191/1564] meson.build: Add ccan-required configuration macros This implements meson-native tests for the conditionals required by ccan. Queried via: git grep -oh 'HAVE_\w\+' ccan/ccan/ | sort -u These are all build-time-only tests, so will work fine while cross-compiling. Signed-off-by: Jeremy Kerr --- meson.build | 128 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 78 insertions(+), 50 deletions(-) diff --git a/meson.build b/meson.build index aa93901b77..b53ad4b8d5 100644 --- a/meson.build +++ b/meson.build @@ -106,56 +106,84 @@ else endif conf.set('CONFIG_SYSTEMD', have, description: 'Is libsystemd required?') -################################################################################ -# The following commented-out text is the beginning of an effort to replace -# ccan/tools/configurator. It is not complete yet. Eventually we would like -# to replace everything that ccan/tools/configurator does with meson. -# To be continued... -################################################################################ -#args = ['-g3', '-ggdb', '-Wall', '-Wundef', '-Wmissing-prototypes', '-Wmissing-declarations', '-Wstrict-prototypes', '-Wold-style-definition'] -#conf.set10( -# 'HAVE_STRUCT_TIMESPEC', -# cc.compiles( -# ''' -# #include -# static void func(void) { -# struct timespec ts; -# ts.tv_sec = ts.tv_nsec = 1; -# } -# int main(int argc, char *argv[]) { -# (void)func(); -# return 0; -# } -# ''', -# no_builtin_args: true, -# args: args, -# name: 'struct timespec' -# ), -# description: 'Is struct timespec defined?' -#) -#conf.set10( -# 'HAVE_ASPRINTF', -# cc.compiles( -# ''' -# #define _GNU_SOURCE -# #include -# static char *func(int x) { -# char *p; -# if (asprintf(&p, "%u", x) == -1) -# p = NULL; -# return p; -# } -# int main(int argc, char *argv[]) { -# (void)func(1000); -# return 0; -# } -# ''', -# no_builtin_args: true, -# args: args, -# name: 'asprintf()' -# ), -# description: 'Is asprintf() supported?' -#) +# local (cross-compilable) implementations of ccan configure steps +conf.set10( + 'HAVE_BUILTIN_TYPES_COMPATIBLE_P', + cc.compiles( + '''int main(void) { + return __builtin_types_compatible_p(int, long); + } + ''', + name: '__builtin_type_compatible_p' + ), + description: 'Is __builtin_types_compatible_p available?' +) +conf.set10( + 'HAVE_TYPEOF', + cc.compiles( + '''int main(void) { + int a = 1; + typeof(a) b; + b = a; + } + ''', + name: 'typeof' + ), + description: 'Is typeof available?' +) +conf.set10( + 'HAVE_BYTESWAP_H', + cc.compiles( + '''#include ''', + name: 'byteswap.h' + ), + description: 'Is byteswap.h include-able?' +) +conf.set10( + 'HAVE_BSWAP64', + cc.links( + '''#include + int main(void) { + return bswap_64(0); + } + ''', + name: 'bswap64' + ), + description: 'Is bswap_64 available?' +) +conf.set10( + 'HAVE_LITTLE_ENDIAN', + build_machine.endian() == 'little', + description: 'Building for little-endian' +) +conf.set10( + 'HAVE_BIG_ENDIAN', + build_machine.endian() == 'big', + description: 'Building for big-endian' +) +conf.set10( + 'HAVE_STATEMENT_EXPR', + cc.compiles( + '''int main(int argc, char **argv) { + return ({ int x = argc; x == 1; }); + } + ''', + name: 'statement-expr' + ), + description: 'Can we use a statement as an expression?' +) +conf.set10( + 'HAVE_ISBLANK', + cc.links( + '''#include + int main(int argc, char **argv) { + return isblank(argv[0][0]); + } + ''', + name: 'isblank' + ), + description: 'Is isblank() available?' +) configure_file( output: 'config-host.h', From 71048b4a965934f12e800a7d1c4ed13252d5a103 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Tue, 12 Oct 2021 14:42:28 +0800 Subject: [PATCH 0192/1564] Unify configuration includes, use meson-generated configuration data Currently, we have two separate configuration includes: ccan/config.h and config-host.h. The first is generated by the ccan configurator, the second by the configuration step (either ./configure, or meson). This change unifies these into a top-level config.h include. For the meson case, we can use the meson configuration file to provide all data. For the configure case, we still use the ccan configurator, but include the resulting file from the top-level config.h This allows us to cross-compile with meson. Signed-off-by: Jeremy Kerr --- configure | 14 +++++++------- meson.build | 9 ++++----- src/Makefile | 11 ++++++----- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/configure b/configure index feb39caa4c..5e0e042051 100755 --- a/configure +++ b/configure @@ -76,16 +76,16 @@ exit 0 fi config_host_mak="config-host.mak" -config_host_h="config-host.h" +config_h="config.h" rm -rf $config_host_mak -rm -rf $config_host_h +rm -rf $config_h fatal() { echo $@ echo "Configure failed, check config.log and/or the above output" rm -rf $config_host_mak - rm -rf $config_host_h + rm -rf $config_h exit 1 } @@ -95,12 +95,12 @@ print_config() { } # Default CFLAGS -CFLAGS="-D_GNU_SOURCE -include config-host.h" +CFLAGS="-D_GNU_SOURCE -include config.h" BUILD_CFLAGS="" cmdstr=$(printf " '%s'" "$0" "$@") -# Print configure header at the top of $config_host_h -cat > $config_host_h < $config_h <> $config_host_h + echo "#define $1" >> $config_h } print_and_output_mak() { diff --git a/meson.build b/meson.build index b53ad4b8d5..c4092cd64f 100644 --- a/meson.build +++ b/meson.build @@ -185,8 +185,8 @@ conf.set10( description: 'Is isblank() available?' ) -configure_file( - output: 'config-host.h', +config_h = configure_file( + output: 'config.h', configuration: conf ) @@ -214,12 +214,11 @@ pkg.generate( ) ################################################################################ -add_project_arguments('-include', 'config-host.h', language : 'c') +add_project_arguments('-include', 'config.h', language : 'c') add_global_arguments(['-fomit-frame-pointer', '-D_GNU_SOURCE'], language : 'c') -incdir = include_directories(['ccan', 'src']) +incdir = include_directories(['.', 'ccan', 'src']) ################################################################################ -subdir('ccan') subdir('src') subdir('pynvme') subdir('test') diff --git a/src/Makefile b/src/Makefile index 40744d4265..0a8cee0818 100644 --- a/src/Makefile +++ b/src/Makefile @@ -12,7 +12,7 @@ libdir ?= $(prefix)/lib CCANDIR=../ccan/ -CFLAGS ?= -g -fomit-frame-pointer -O2 -I/usr/include -Invme/ -I$(CCANDIR) -include ../config-host.h -D_GNU_SOURCE +CFLAGS ?= -g -fomit-frame-pointer -O2 -I/usr/include -Invme/ -I$(CCANDIR) -I.. -include ../config.h -D_GNU_SOURCE override CFLAGS += -Wall -fPIC SO_CFLAGS=-shared $(CFLAGS) L_CFLAGS=$(CFLAGS) @@ -36,15 +36,16 @@ include ../Makefile.quiet all: $(all_targets) -$(CCANDIR)config.h: $(CCANDIR)tools/configurator/configurator +$(CCANDIR)ccan-config.h: $(CCANDIR)tools/configurator/configurator $< > $@ +$(CCANDIR)tools/configurator/configurator: CFLAGS = -D_GNU_SOURCE libccan_headers := $(wildcard $(CCANDIR)ccan/*/*.h) libccan_srcs := $(wildcard $(CCANDIR)ccan/*/*.c) libccan_objs := $(patsubst %.c,%.ol,$(libccan_srcs)) libccan_sobjs := $(patsubst %.c,%.os,$(libccan_srcs)) -$(libccan_objs) $(libccan_sobjs): $(libccan_headers) $(CCANDIR)config.h +$(libccan_objs) $(libccan_sobjs): $(libccan_headers) $(CCANDIR)ccan-config.h libnvme_priv := nvme/private.h libnvme_api := libnvme.h nvme/types.h nvme/ioctl.h nvme/filters.h nvme/tree.h nvme/util.h nvme/fabrics.h nvme/log.h @@ -84,10 +85,10 @@ ifeq ($(ENABLE_SHARED),1) endif $(libnvme_objs): $(libnvme_api) $(libnvme_private) -$(libccan_objs): $(libccan_headers) $(CCANDIR)config.h +$(libccan_objs): $(libccan_headers) $(CCANDIR)ccan-config.h clean: rm -f $(all_targets) $(libnvme_objs) $(libnvme_sobjs) $(libccan_objs) $(libccan_sobjs) $(soname).new - rm -f $(CCANDIR)config.h + rm -f $(CCANDIR)ccan-config.h rm -f $(CCANDIR)tools/configurator/configurator rm -f *.so* *.a *.o From 8cb4d2941527832bf04639a83a55cec51d353507 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Tue, 12 Oct 2021 15:24:38 +0800 Subject: [PATCH 0193/1564] pynvme: Make swig optional & python bindings conditional on swig We may not need have a python environment for some targets; make the python bindings optional. Signed-off-by: Jeremy Kerr --- pynvme/meson.build | 48 ++++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/pynvme/meson.build b/pynvme/meson.build index 15d5cc261c..846e8e3421 100644 --- a/pynvme/meson.build +++ b/pynvme/meson.build @@ -6,28 +6,30 @@ # Authors: Martin Belanger # python3 = import('python').find_installation('python3') -swig = find_program('swig', required: true) -pymod_swig = custom_target( - 'nvme.py', - input: ['nvme.i', config_h], - output: ['nvme.py', 'nvme_wrap.c'], - command: [swig, '-python', '-py3', '-o', '@OUTPUT1@', '@INPUT0@'], - install: true, - install_dir: [python3.get_install_dir(pure: false, subdir: 'libnvme'), false], -) +swig = find_program('swig', required: false) +if swig.found() + pymod_swig = custom_target( + 'nvme.py', + input: ['nvme.i', config_h], + output: ['nvme.py', 'nvme_wrap.c'], + command: [swig, '-python', '-py3', '-o', '@OUTPUT1@', '@INPUT0@'], + install: true, + install_dir: [python3.get_install_dir(pure: false, subdir: 'libnvme'), false], + ) -pynvme_clib = python3.extension_module( - '_nvme', - pymod_swig[1], - dependencies : python3.dependency(), - include_directories: incdir, - link_with: libnvme_static, - install: true, - subdir: 'libnvme', -) + pynvme_clib = python3.extension_module( + '_nvme', + pymod_swig[1], + dependencies : python3.dependency(), + include_directories: incdir, + link_with: libnvme_static, + install: true, + subdir: 'libnvme', + ) -python3.install_sources( - ['__init__.py', ], - pure: false, - subdir: 'libnvme', -) + python3.install_sources( + ['__init__.py', ], + pure: false, + subdir: 'libnvme', + ) +endif From d24048bb02ec29bd2e148d56fef6d345e7ffa7a1 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Tue, 12 Oct 2021 14:26:57 +0200 Subject: [PATCH 0194/1564] fabrics: Remove 'UUID derived from machine-id' feature Commit 3e0520ecad13 ("Read system UUID from DMI and merge hostnqn generation functions") in nvme-cli introduced the feature to create the UUID derived from machine-id using the systemd's sd_id128_get_machine_app_specific function. This adds many library dependencies to libnvme. The feature is not really necessary as we have nvme-gen-hostnqn already in place. So drop the feature entirely. If the feature needs to be added back, it's probably better to reimplement this function (e.g. move the hmac_sha256 function from nvme-cli and use this to derive the UUID from machine-id). Signed-off-by: Daniel Wagner --- README.md | 8 -------- configure | 18 ------------------ meson.build | 13 +------------ meson_options.txt | 2 -- pynvme/setup.py | 2 +- src/meson.build | 1 - src/nvme/fabrics.c | 25 ------------------------- 7 files changed, 2 insertions(+), 67 deletions(-) diff --git a/README.md b/README.md index 2613a52848..70c13a2122 100644 --- a/README.md +++ b/README.md @@ -142,17 +142,9 @@ A few build options can be specified on the command line when invoking meson. | Option | Values [default] | Description | | ------- | ------------------- | ------------------------------------------------------------ | -| systemd | [auto], true, false | Whether to link libsystemd to libnvme. When set to `auto`, the default, meson will check for the presence of library and will only link to it if it is found. When set to `true`, meson will make this library a mandatory dependency. When set to `false`, meson will not link the library to libnvme, even if the library is available. | ### Changing the build options from the command-line (i.e. w/o modifying any files) -Here's an example where we tell meson that we do not want to link -against the `systemd` library: - -```bash -meson .build -Dsystemd=false -``` - To configure a build for debugging purposes (i.e. optimization turned off and debug symbols enabled): diff --git a/configure b/configure index 5e0e042051..b21a09823a 100755 --- a/configure +++ b/configure @@ -27,8 +27,6 @@ for opt do ;; --datadir=*) datadir="$optarg" ;; - --disable-systemd) disable_systemd=1 - ;; --disable-uuid) disable_uuid=1 ;; --disable-json) disable_json=1 @@ -68,7 +66,6 @@ Options: [defaults in brackets after descriptions] --libdir=PATH install libraries in PATH [$libdir] --mandir=PATH install man pages in PATH [$mandir] --datadir=PATH install shared data in PATH [$datadir] - --disable-systemd do not link against libsystemd --disable-uuid do not link against libuuid --disable-json do not link against libjson-c EOF @@ -197,17 +194,6 @@ if [ -z "$disable_uuid" ] ; then fi print_config "libuuid" "${libuuid}" -########################################## -# check for SystemD -systemd="no" -if [ -z "$disable_systemd" ] ; then - pkg-config --exists libsystemd --atleast-version=242 - if [ $? -eq 0 ]; then - systemd="yes" - fi -fi -print_config "systemd" "${systemd}" - ########################################## # check for libjson-c libjsonc="no" @@ -234,10 +220,6 @@ if test "$libuuid" = "yes"; then echo "override LIBS += -luuid" >> $config_host_mak echo "override LIB_DEPENDS += uuid" >> $config_host_mak fi -if test "$systemd" = "yes"; then - output_sym "CONFIG_SYSTEMD" - echo "override LIBS += -lsystemd" >> $config_host_mak -fi if test "$libjsonc" = "yes"; then output_sym "CONFIG_JSONC" echo "override LIBS += -ljson-c" >> $config_host_mak diff --git a/meson.build b/meson.build index c4092cd64f..16f950b9bf 100644 --- a/meson.build +++ b/meson.build @@ -95,17 +95,6 @@ if not libjson.found() endif conf.set('CONFIG_JSONC', libjson.found(), description: 'Is json-c required?') -# Check for libsystemd availability -want_systemd = get_option('systemd') -if want_systemd != 'false' - libsystemd = dependency('libsystemd', required: want_systemd == 'true') - have = libsystemd.found() -else - libsystemd = [] - have = false -endif -conf.set('CONFIG_SYSTEMD', have, description: 'Is libsystemd required?') - # local (cross-compilable) implementations of ccan configure steps conf.set10( 'HAVE_BUILTIN_TYPES_COMPATIBLE_P', @@ -210,7 +199,7 @@ pkg.generate( description: 'Manage "libnvme" subsystem devices (Non-volatile Memory Express)', url: 'http://github.com/linux-nvme/libnvme/', libraries: ['-L${libdir}', '-lnvme'], - requires: [libuuid, libjson, libsystemd], + requires: [libuuid, libjson], ) ################################################################################ diff --git a/meson_options.txt b/meson_options.txt index f08b27fb3f..c83da2914d 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -3,5 +3,3 @@ option('pkgconfiglibdir', type : 'string', value : '', description : 'directory for standard pkg-config files') option('man', type : 'boolean', value : false, description : 'build and install man pages (requires sphinx-build)') - -option('systemd', type : 'combo', choices : ['auto', 'true', 'false'], description : 'libsystemd support') diff --git a/pynvme/setup.py b/pynvme/setup.py index 8db418aef4..b7994ea2d0 100644 --- a/pynvme/setup.py +++ b/pynvme/setup.py @@ -3,7 +3,7 @@ libnvme_module = Extension( '_nvme', sources = ['nvme_wrap.c'], - libraries = ['nvme', 'json-c', 'uuid', 'systemd'], + libraries = ['nvme', 'json-c', 'uuid'], library_dirs = ['../src'], include_dirs = ['../ccan', '../src', '../src/nvme'], ) diff --git a/src/meson.build b/src/meson.build index db03e0414e..09da32bf0f 100644 --- a/src/meson.build +++ b/src/meson.build @@ -22,7 +22,6 @@ endif deps = [ libuuid, - libsystemd, libjson, ] diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 3ab93210ed..21dec686f4 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -25,11 +25,6 @@ #include #include -#ifdef CONFIG_SYSTEMD -#include -#define NVME_HOSTNQN_ID SD_ID128_MAKE(c7,f4,61,81,12,be,49,32,8c,83,10,6f,9d,dd,d8,6b) -#endif - #include #include @@ -841,24 +836,6 @@ static int uuid_from_dmi(char *system_uuid) return strlen(system_uuid) ? 0 : -ENXIO; } -#ifdef CONFIG_SYSTEMD -#include -#define NVME_HOSTNQN_ID SD_ID128_MAKE(c7,f4,61,81,12,be,49,32,8c,83,10,6f,9d,dd,d8,6b) -#endif - -static int uuid_from_systemd(char *system_uuid) -{ - int ret = -ENOTSUP; -#ifdef CONFIG_SYSTEMD - sd_id128_t id; - - ret = sd_id128_get_machine_app_specific(NVME_HOSTNQN_ID, &id); - if (!ret) - sd_id128_to_string(id, system_uuid); -#endif - return ret; -} - char *nvmf_hostnqn_generate() { char *hostnqn; @@ -871,8 +848,6 @@ char *nvmf_hostnqn_generate() ret = uuid_from_dmi(uuid_str); if (ret < 0) { ret = uuid_from_device_tree(uuid_str); - if (ret < 0) - ret = uuid_from_systemd(uuid_str); } #ifdef CONFIG_LIBUUID if (ret < 0) { From a86fe783301c7ab977f2d5cf0d347fd46475d083 Mon Sep 17 00:00:00 2001 From: Martin Belanger Date: Mon, 11 Oct 2021 15:50:23 -0400 Subject: [PATCH 0195/1564] Expose C enums and #defines in Python module. Add persistent_set() method to the Python nvme_ctrl class. Signed-off-by: Martin Belanger --- pynvme/nvme.i | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/pynvme/nvme.i b/pynvme/nvme.i index 919361727f..4e799909cd 100644 --- a/pynvme/nvme.i +++ b/pynvme/nvme.i @@ -297,6 +297,7 @@ struct nvme_ctrl { %immutable queue_count; %immutable serial; %immutable sqsize; + %immutable persistent; char *transport; char *subsysnqn; char *traddr; @@ -309,6 +310,7 @@ struct nvme_ctrl { char *queue_count; char *serial; char *sqsize; + bool persistent; }; struct nvme_ns { @@ -520,6 +522,9 @@ struct nvme_ns { bool connected() { return nvme_ctrl_get_name($self) != NULL; } + void persistent_set(bool persistent) { + nvme_ctrl_set_persistent($self, persistent); + } void rescan() { nvme_rescan_ctrl($self); } @@ -605,3 +610,15 @@ struct nvme_ns { } %}; + +// We want to swig all the #define and enum from types.h, but none of the structs. +%{ +#include "nvme/types.h" +%} +#define __attribute__(x) +%rename($ignore, %$isclass) ""; // ignore all classes/structs +%rename($ignore, %$isfunction) ""; // ignore all functions +%rename($ignore, %$isunion) ""; // ignore all unions +%rename($ignore, %$isvariable ) ""; // ignore all variables + +%include "../src/nvme/types.h" From d16233c452d8f4f0a4ece120ab0222c3f6975f20 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Tue, 12 Oct 2021 17:18:48 +0200 Subject: [PATCH 0196/1564] build: Allow subproject meson builds meson has a very fancy feature called subproject. This allows bundle third party libraries in a project. In order to be able to use this for nvme-cli we need to drop all global config settings and declare all dependencies. Signed-off-by: Daniel Wagner --- meson.build | 3 +-- src/meson.build | 10 ++++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/meson.build b/meson.build index 16f950b9bf..6b4fd7770e 100644 --- a/meson.build +++ b/meson.build @@ -203,8 +203,7 @@ pkg.generate( ) ################################################################################ -add_project_arguments('-include', 'config.h', language : 'c') -add_global_arguments(['-fomit-frame-pointer', '-D_GNU_SOURCE'], language : 'c') +add_project_arguments(['-fomit-frame-pointer', '-D_GNU_SOURCE', '-include', 'config.h'], language : 'c') incdir = include_directories(['.', 'ccan', 'src']) ################################################################################ diff --git a/src/meson.build b/src/meson.build index 09da32bf0f..15949c950a 100644 --- a/src/meson.build +++ b/src/meson.build @@ -51,6 +51,16 @@ libnvme_static = static_library( install : false ) +libnvme_shared_dep = declare_dependency( + include_directories: incdir, + link_with: libnvme_shared, +) + +libnvme_static_dep = declare_dependency( + include_directories: incdir, + link_with: libnvme_static, +) + mode = ['rw-r--r--', 0, 0] install_headers('libnvme.h', install_mode: mode) install_headers([ From 78e7fab58dd48a9f86b1429262e73c4067031a0f Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Fri, 6 Aug 2021 11:40:47 +0800 Subject: [PATCH 0197/1564] log: we use bool, so include stdbool.h The log headers use the bool type, so add an include for stdbool.h, rather than requiring the includer to do so. Signed-off-by: Jeremy Kerr --- src/nvme/log.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/nvme/log.h b/src/nvme/log.h index 4ed695c430..c13def854e 100644 --- a/src/nvme/log.h +++ b/src/nvme/log.h @@ -5,6 +5,7 @@ #ifndef _LOG_H #define _LOG_H +#include #include #ifndef MAX_LOGLEVEL From af3110a5cc0993a07d677383cd158cc77afdd92d Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Mon, 18 Oct 2021 11:24:34 +0200 Subject: [PATCH 0198/1564] build: Set minimum version for json-c Set minimum version for json-c to 0.13. libnvme uses json_util_get_last_err() which got introduced in 0.13, released in December 2017. While at it, drop the cc.find_library() lookup logic. First, we don't do this for libuuid and second, dependency() is using pkg-config to figure out the dependency, thus we can set the minimum version number. Instead, cc.find_library() will try to link a test program with '-libjson-c' and have no way to figure out which version it actually is. Avoid any confusion and make the meson.build script simpler. Signed-off-by: Daniel Wagner --- meson.build | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/meson.build b/meson.build index 6b4fd7770e..271c48a90e 100644 --- a/meson.build +++ b/meson.build @@ -89,10 +89,7 @@ libuuid = dependency('uuid', required: true) conf.set('CONFIG_LIBUUID', libuuid.found(), description: 'Is libuuid required?') # Check for libjson-c availability -libjson = dependency('json-c', required: false) -if not libjson.found() - libjson = cc.find_library('json-c', required: true) -endif +libjson = dependency('json-c', version: '>=0.13', required: true) conf.set('CONFIG_JSONC', libjson.found(), description: 'Is json-c required?') # local (cross-compilable) implementations of ccan configure steps From c69c38516dfd7e5805def54812a68cc778c94ab0 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Mon, 18 Oct 2021 13:58:53 +0200 Subject: [PATCH 0199/1564] build: Split libtool versioning from project versioning As described in GNU autotools manuals, libtool versioning is not the same as the project versioning. The project versioning string is defined in project_version. meson uses this string for all operations such a creating the tarball. I decided against using something fancy as 'git describe' for it, because meson is not supporting this kind of dynamic project versioning. Instead we just need to increment the version after the release and before the first commit. With this scheme we basically know by looking at the version string if it is an official released version. If this is not good enough we can try to adopt the approach other project are doing such as systemd which introduced an additional package versioning which depends on 'git describe'. There is little point in fighting the tool if it can be done quite easily by the described approach from above. Signed-off-by: Daniel Wagner --- meson.build | 18 +++++++++++++++++- src/meson.build | 2 +- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/meson.build b/meson.build index 6b4fd7770e..3935cde114 100644 --- a/meson.build +++ b/meson.build @@ -61,7 +61,7 @@ project( 'libnvme', ['c', 'cpp'], meson_version: '>= 0.47.0', - version: '1.0.1', + version: 'v0.1', license: 'LGPLv2+', default_options: [ 'buildtype=release', @@ -69,6 +69,22 @@ project( ] ) +# https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html +# https://autotools.io/libtool/version.html +# The relation between libtool's current:revison:age interface versioning +# and the .so filename, .so.x.y.z, is +# x = current - age +# y = age +# z = revision +# If libtool_soversion is updated as described in libtool's documentation, +# x.y.z will usually *not* be equal to meson.project_version(). +libtool_soversion = [0, 0, 0] +libnvme_version = '@0@.@1@.@2@'.format( + libtool_soversion[0] - libtool_soversion[2], + libtool_soversion[2], + libtool_soversion[1] +) + ################################################################################ cc = meson.get_compiler('c') diff --git a/src/meson.build b/src/meson.build index 15949c950a..1f932c6db6 100644 --- a/src/meson.build +++ b/src/meson.build @@ -32,7 +32,7 @@ version_script_arg = join_paths(source_dir, mapfile) libnvme_shared = shared_library( 'nvme', # produces libnvme.so sources, - version: meson.project_version(), + version: libnvme_version, soversion: '1', link_args: ['-Wl,--version-script=' + version_script_arg], dependencies: deps, From 808da9bbbe32068e33576c9c4cd9a8ddb3685fc7 Mon Sep 17 00:00:00 2001 From: Klaus Jensen Date: Mon, 18 Oct 2021 22:59:39 +0200 Subject: [PATCH 0200/1564] update libnvme.map Signed-off-by: Klaus Jensen --- src/libnvme.map | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libnvme.map b/src/libnvme.map index 322097f21d..7b999d5a9f 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -35,6 +35,7 @@ nvme_ctrl_next_path; nvme_ctrl_reset; nvme_ctrls_filter; + nvme_default_host; nvme_dev_self_test; nvme_directive_recv; nvme_directive_recv_identify_parameters; @@ -133,6 +134,7 @@ nvme_identify_allocated_ns; nvme_identify_allocated_ns_list; nvme_identify_ctrl; + nvme_identify_ctrl_list; nvme_identify_iocs; nvme_identify_ns; nvme_identify_ns_descs; @@ -161,7 +163,9 @@ nvme_ns_detach_ctrls; nvme_ns_dettach_ctrls; nvme_ns_flush; + nvme_ns_get_csi; nvme_ns_get_ctrl; + nvme_ns_get_eui64; nvme_ns_get_fd; nvme_ns_get_firmware; nvme_ns_get_lba_count; @@ -171,10 +175,12 @@ nvme_ns_get_model; nvme_ns_get_model; nvme_ns_get_name; + nvme_ns_get_nguid; nvme_ns_get_nsid; nvme_ns_get_serial; nvme_ns_get_subsystem; nvme_ns_get_sysfs_dir; + nvme_ns_get_uuid; nvme_ns_identify; nvme_ns_mgmt; nvme_ns_mgmt_create; From c874f669757817fab9eb94155e77904009f013d7 Mon Sep 17 00:00:00 2001 From: Klaus Jensen Date: Mon, 18 Oct 2021 23:00:10 +0200 Subject: [PATCH 0201/1564] meson: use library() and rely on user settings There is no need to have both _static and _shared targets. Just use library(). Project using libnvme as a subproject can now just set default_options: ['default_library=static'] in the subproject statement to choose the library version. For pkgconfig, simplify and let the module figure out Libs and Requires. This has the effect of removing Requires and making it a Requires.private so we don't require libnvme consumers to link with libuuid and json-c (unless they specifically needs to use it like test/test.c). Signed-off-by: Klaus Jensen --- examples/meson.build | 6 +++--- meson.build | 12 ------------ pynvme/meson.build | 2 +- src/meson.build | 29 ++++++++++------------------- test/meson.build | 9 +++++---- 5 files changed, 19 insertions(+), 39 deletions(-) diff --git a/examples/meson.build b/examples/meson.build index 0ed97d001e..0bf911d597 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -8,18 +8,18 @@ executable( 'telemetry-listen', ['telemetry-listen.c'], - link_with: libnvme_static, + link_with: libnvme, include_directories: incdir) executable( 'display-columnar', ['display-columnar.c'], - link_with: libnvme_static, + link_with: libnvme, include_directories: incdir) executable( 'discover-loop', ['discover-loop.c'], - link_with: libnvme_static, + link_with: libnvme, include_directories: incdir) diff --git a/meson.build b/meson.build index 271c48a90e..fc72ff5fbf 100644 --- a/meson.build +++ b/meson.build @@ -187,18 +187,6 @@ configure_file( configuration: substs, ) -################################################################################ -pkg = import('pkgconfig') -pkg.generate( - filebase: meson.project_name(), - name: meson.project_name(), - version: meson.project_version(), - description: 'Manage "libnvme" subsystem devices (Non-volatile Memory Express)', - url: 'http://github.com/linux-nvme/libnvme/', - libraries: ['-L${libdir}', '-lnvme'], - requires: [libuuid, libjson], -) - ################################################################################ add_project_arguments(['-fomit-frame-pointer', '-D_GNU_SOURCE', '-include', 'config.h'], language : 'c') incdir = include_directories(['.', 'ccan', 'src']) diff --git a/pynvme/meson.build b/pynvme/meson.build index 846e8e3421..5e9c96d450 100644 --- a/pynvme/meson.build +++ b/pynvme/meson.build @@ -22,7 +22,7 @@ if swig.found() pymod_swig[1], dependencies : python3.dependency(), include_directories: incdir, - link_with: libnvme_static, + link_with: libnvme, install: true, subdir: 'libnvme', ) diff --git a/src/meson.build b/src/meson.build index 15949c950a..c5673325bf 100644 --- a/src/meson.build +++ b/src/meson.build @@ -29,7 +29,7 @@ source_dir = meson.current_source_dir() mapfile = 'libnvme.map' version_script_arg = join_paths(source_dir, mapfile) -libnvme_shared = shared_library( +libnvme = library( 'nvme', # produces libnvme.so sources, version: meson.project_version(), @@ -41,24 +41,18 @@ libnvme_shared = shared_library( install: true, ) -libnvme_static = static_library( - 'nvme', # produces libnvme.a - sources, - link_args: ['-Wl,--version-script=' + version_script_arg], - dependencies: deps, - link_depends: mapfile, - include_directories: incdir, - install : false +pkg = import('pkgconfig') +pkg.generate(libnvme, + filebase: meson.project_name(), + name: meson.project_name(), + version: meson.project_version(), + description: 'Manage "libnvme" subsystem devices (Non-volatile Memory Express)', + url: 'http://github.com/linux-nvme/libnvme/', ) -libnvme_shared_dep = declare_dependency( +libnvme_dep = declare_dependency( include_directories: incdir, - link_with: libnvme_shared, -) - -libnvme_static_dep = declare_dependency( - include_directories: incdir, - link_with: libnvme_static, + link_with: libnvme, ) mode = ['rw-r--r--', 0, 0] @@ -75,6 +69,3 @@ install_headers([ subdir: 'nvme', install_mode: mode, ) - - - diff --git a/test/meson.build b/test/meson.build index 61be2ccfc9..e89d877831 100644 --- a/test/meson.build +++ b/test/meson.build @@ -8,28 +8,29 @@ main = executable( 'main-test', ['test.c'], - link_with: libnvme_static, + dependencies: libuuid, + link_with: libnvme, include_directories: incdir ) cpp = executable( 'test-cpp', ['cpp.cc'], - link_with: libnvme_static, + link_with: libnvme, include_directories: incdir ) register = executable( 'test-register', ['register.c'], - link_with: libnvme_static, + link_with: libnvme, include_directories: incdir ) zns = executable( 'test-zns', ['zns.c'], - link_with: libnvme_static, + link_with: libnvme, include_directories: incdir ) From 6af90f95fd1bfcf6f7d37605a987e3cd2b860633 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Tue, 19 Oct 2021 10:15:32 +0200 Subject: [PATCH 0202/1564] build: Add fallback dependency for json-c meson supports embedded library build. This is very handy for system which ship outdated an really outdated json-c library. The include path for json.h has to be adapted. The json-c upstream project is not clear which include prefix should be used ('#include " vs '#include '. In order to support embedded builds, we need to use the second version of the include. The source code is added to the build, hence we use the include directory path of the project layout. And json-c has all include files in the root directory. This is no problem when using a installed version of json-c as pkg-config adds '-I/usr/inlude/json-c' to the include paths: $pkg-config --cflags json-c -I/usr/include/json-c So the simplest thing to support both build cased (external/embedded) just drop the include prefix. While at it also fix the 'requires' argument which expects strings not dependencies objects. Signed-off-by: Daniel Wagner --- meson.build | 7 +++---- src/Makefile | 2 ++ src/meson.build | 12 ++++++------ src/nvme/json.c | 2 +- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/meson.build b/meson.build index 8e94cd6872..8251cf4f4c 100644 --- a/meson.build +++ b/meson.build @@ -104,9 +104,9 @@ conf = configuration_data() libuuid = dependency('uuid', required: true) conf.set('CONFIG_LIBUUID', libuuid.found(), description: 'Is libuuid required?') -# Check for libjson-c availability -libjson = dependency('json-c', version: '>=0.13', required: true) -conf.set('CONFIG_JSONC', libjson.found(), description: 'Is json-c required?') +# Check for json-c availability +json_c = dependency('json-c', version: '>=0.13', fallback : ['json-c', 'json_c']) +conf.set('CONFIG_JSONC', json_c.found(), description: 'Is json-c required?') # local (cross-compilable) implementations of ccan configure steps conf.set10( @@ -213,4 +213,3 @@ subdir('pynvme') subdir('test') subdir('examples') subdir('doc') - diff --git a/src/Makefile b/src/Makefile index 0a8cee0818..9c54141d6e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -51,6 +51,8 @@ libnvme_priv := nvme/private.h libnvme_api := libnvme.h nvme/types.h nvme/ioctl.h nvme/filters.h nvme/tree.h nvme/util.h nvme/fabrics.h nvme/log.h libnvme_srcs := nvme/ioctl.c nvme/filters.c nvme/fabrics.c nvme/util.c nvme/tree.c nvme/log.c nvme/cleanup.c ifeq ($(CONFIG_JSONC),y) +override LDFLAGS += $(shell pkg-config --libs json-c) +override CFLAGS += $(shell pkg-config --cflags json-c) override libnvme_srcs += nvme/json.c endif libnvme_objs := $(patsubst %.c,%.ol,$(libnvme_srcs)) diff --git a/src/meson.build b/src/meson.build index 6efac9561e..0d261c21b6 100644 --- a/src/meson.build +++ b/src/meson.build @@ -22,7 +22,7 @@ endif deps = [ libuuid, - libjson, + json_c, ] source_dir = meson.current_source_dir() @@ -43,11 +43,11 @@ libnvme = library( pkg = import('pkgconfig') pkg.generate(libnvme, - filebase: meson.project_name(), - name: meson.project_name(), - version: meson.project_version(), - description: 'Manage "libnvme" subsystem devices (Non-volatile Memory Express)', - url: 'http://github.com/linux-nvme/libnvme/', + filebase: meson.project_name(), + name: meson.project_name(), + version: meson.project_version(), + description: 'Manage "libnvme" subsystem devices (Non-volatile Memory Express)', + url: 'http://github.com/linux-nvme/libnvme/', ) libnvme_dep = declare_dependency( diff --git a/src/nvme/json.c b/src/nvme/json.c index 09791d2a14..5aa09b091c 100644 --- a/src/nvme/json.c +++ b/src/nvme/json.c @@ -10,7 +10,7 @@ #include #include -#include +#include #include "fabrics.h" #include "log.h" From 2b655d5b8407d75abed2fb36d86631b195783720 Mon Sep 17 00:00:00 2001 From: Martin Belanger Date: Tue, 19 Oct 2021 14:34:03 -0400 Subject: [PATCH 0203/1564] Make Python Bindings optional Added a new configuration parameter "python". By default it is set to 'auto', which means that the Python bindings will be built if all dependencies can be found on the host. If not, Python bindings won;t be built. The option can also be set to 'true' or 'false' to force Python bindings to be built or not. Signed-off-by: Martin Belanger --- meson_options.txt | 1 + pynvme/meson.build | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/meson_options.txt b/meson_options.txt index c83da2914d..e87ad76503 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -3,3 +3,4 @@ option('pkgconfiglibdir', type : 'string', value : '', description : 'directory for standard pkg-config files') option('man', type : 'boolean', value : false, description : 'build and install man pages (requires sphinx-build)') +option('python', type : 'combo', choices : ['auto', 'true', 'false'], description : 'Generate libnvme python bindings') diff --git a/pynvme/meson.build b/pynvme/meson.build index 5e9c96d450..bde1536bef 100644 --- a/pynvme/meson.build +++ b/pynvme/meson.build @@ -5,9 +5,18 @@ # # Authors: Martin Belanger # -python3 = import('python').find_installation('python3') -swig = find_program('swig', required: false) -if swig.found() + +want_python = get_option('python') +if want_python != 'false' + python3 = import('python').find_installation('python3') + py3_dep = python3.dependency(required: want_python == 'true') + swig = find_program('swig', required: want_python == 'true') + have_python_support = py3_dep.found() and swig.found() +else + have_python_support = false +endif + +if have_python_support pymod_swig = custom_target( 'nvme.py', input: ['nvme.i', config_h], @@ -20,7 +29,7 @@ if swig.found() pynvme_clib = python3.extension_module( '_nvme', pymod_swig[1], - dependencies : python3.dependency(), + dependencies : py3_dep, include_directories: incdir, link_with: libnvme, install: true, From 91af7fdbb7a4cb2dd39f8f3b398a24d74cd21092 Mon Sep 17 00:00:00 2001 From: Martin Belanger Date: Tue, 19 Oct 2021 08:56:27 -0400 Subject: [PATCH 0204/1564] [Python]: Fix inaccurate Python examples Signed-off-by: Martin Belanger --- examples/discover-loop.py | 8 ++++---- pynvme/README.md | 34 ++++++++++++++++++++++++---------- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/examples/discover-loop.py b/examples/discover-loop.py index 4582e6a9fb..94e8c722d9 100644 --- a/examples/discover-loop.py +++ b/examples/discover-loop.py @@ -16,10 +16,10 @@ under the License. ''' -import libnvme -r = libnvme.nvme_root() -h = libnvme.nvme_host(r) -c = libnvme.nvme_ctrl('nqn.2014-08.org.nvmexpress.discovery','loop') +from libnvme import nvme +r = nvme.root() +h = nvme.host(r) +c = nvme.ctrl(nvme.NVME_DISC_SUBSYS_NAME, 'loop') try: c.connect(h) except: diff --git a/pynvme/README.md b/pynvme/README.md index ac51b387e2..f61e5cc8cb 100644 --- a/pynvme/README.md +++ b/pynvme/README.md @@ -5,28 +5,42 @@ We use [SWIG](http://www.swig.org/) to generate Python bindings for libnvme. ## How to use ```python +#!/usr/bin/env python3 import sys +import pprint from libnvme import nvme -root = nvme.root() # This is a singleton -host = nvme.host(root) # This "may be" a singleton. -ctrl = nvme.ctrl(subsysnqn=, transport=, traddr=, trsvcid=, host_traddr=, host_iface=) +root = nvme.root() # This is a singleton +root.log_level('debug') # Optional: extra debug info + +host = nvme.host(root) # This "may be" a singleton. +sybsysnqn = [string] # e.g. 'nqn.2014-08.org.nvmexpress.discovery', nvme.NVME_DISC_SUBSYS_NAME, ... +transport = [string] # One of: 'tcp, 'rdma', 'fc', 'loop'. +traddr = [IPv4 or IPv6] # e.g. '192.168.10.10', 'fd2e:853b:3cad:e135:506a:65ee:29f2:1b18', ... +trsvcid = [string] # e.g. '8009', '4420', ... +host_iface = [interface] # e.g. 'eth1', ens256', ... +ctrl = nvme.ctrl(subsysnqn=subsysnqn, transport=transport, traddr=traddr, trsvcid=trsvcid, host_iface=host_iface) try: - ctrl.connect(host) + cfg = { + 'hdr_digest': True, # Enable header digests + 'data_digest': False, # Disable data digests + } + ctrl.connect(host, cfg) print(f"connected to {ctrl.name} subsys {ctrl.subsystem.name}") except Exception as e: - sys.exit(f'Failed to connect: {e}') + sys.exit(f'Failed to connect: {e}') try: - log_pages = ctrl.discover() - print(pprint.pformat(log_pages)) + log_pages = ctrl.discover() + print(pprint.pformat(log_pages)) except Exception as e: - sys.exit(f'Failed to retrieve log pages: {e}') + sys.exit(f'Failed to retrieve log pages: {e}') try: - ctrl.disconnect() + ctrl.disconnect() except Exception as e: - sys.exit(f'Failed to disconnect: {e}') + sys.exit(f'Failed to disconnect: {e}') + ``` From 859bd459dee308639eedb490d348d311dc08f859 Mon Sep 17 00:00:00 2001 From: Klaus Jensen Date: Tue, 19 Oct 2021 21:34:38 +0200 Subject: [PATCH 0205/1564] src/Makefile: fix ccan config.h The ccan/ccan-config.h generated by the ccan configurator is never read by the ccan sources which expect config.h. Instead, because of -I.. in src/Makefile, the ccan sources picks up the base config.h (as generated by configure). All kinds of wrong since config.h should actually have been config-host.h. Fix the compiler args to not include the base directory and generate the ccan config file as ccan/config.h. Rename ./config.h to ./config-host.h. Signed-off-by: Klaus Jensen --- configure | 12 ++++++------ src/Makefile | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/configure b/configure index b21a09823a..592e0abfd3 100755 --- a/configure +++ b/configure @@ -73,16 +73,16 @@ exit 0 fi config_host_mak="config-host.mak" -config_h="config.h" +config_host_h="config-host.h" rm -rf $config_host_mak -rm -rf $config_h +rm -rf $config_host_h fatal() { echo $@ echo "Configure failed, check config.log and/or the above output" rm -rf $config_host_mak - rm -rf $config_h + rm -rf $config_host_h exit 1 } @@ -96,8 +96,8 @@ CFLAGS="-D_GNU_SOURCE -include config.h" BUILD_CFLAGS="" cmdstr=$(printf " '%s'" "$0" "$@") -# Print configure header at the top of $config_h -cat > $config_h < $config_host_h <> $config_h + echo "#define $1" >> $config_host_h } print_and_output_mak() { diff --git a/src/Makefile b/src/Makefile index 9c54141d6e..2f269e4343 100644 --- a/src/Makefile +++ b/src/Makefile @@ -12,7 +12,7 @@ libdir ?= $(prefix)/lib CCANDIR=../ccan/ -CFLAGS ?= -g -fomit-frame-pointer -O2 -I/usr/include -Invme/ -I$(CCANDIR) -I.. -include ../config.h -D_GNU_SOURCE +CFLAGS ?= -g -fomit-frame-pointer -O2 -I/usr/include -Invme/ -I$(CCANDIR) -include ../config-host.h -D_GNU_SOURCE override CFLAGS += -Wall -fPIC SO_CFLAGS=-shared $(CFLAGS) L_CFLAGS=$(CFLAGS) @@ -36,7 +36,7 @@ include ../Makefile.quiet all: $(all_targets) -$(CCANDIR)ccan-config.h: $(CCANDIR)tools/configurator/configurator +$(CCANDIR)config.h: $(CCANDIR)tools/configurator/configurator $< > $@ $(CCANDIR)tools/configurator/configurator: CFLAGS = -D_GNU_SOURCE @@ -45,7 +45,7 @@ libccan_srcs := $(wildcard $(CCANDIR)ccan/*/*.c) libccan_objs := $(patsubst %.c,%.ol,$(libccan_srcs)) libccan_sobjs := $(patsubst %.c,%.os,$(libccan_srcs)) -$(libccan_objs) $(libccan_sobjs): $(libccan_headers) $(CCANDIR)ccan-config.h +$(libccan_objs) $(libccan_sobjs): $(libccan_headers) $(CCANDIR)config.h libnvme_priv := nvme/private.h libnvme_api := libnvme.h nvme/types.h nvme/ioctl.h nvme/filters.h nvme/tree.h nvme/util.h nvme/fabrics.h nvme/log.h @@ -87,10 +87,10 @@ ifeq ($(ENABLE_SHARED),1) endif $(libnvme_objs): $(libnvme_api) $(libnvme_private) -$(libccan_objs): $(libccan_headers) $(CCANDIR)ccan-config.h +$(libccan_objs): $(libccan_headers) $(CCANDIR)config.h clean: rm -f $(all_targets) $(libnvme_objs) $(libnvme_sobjs) $(libccan_objs) $(libccan_sobjs) $(soname).new - rm -f $(CCANDIR)ccan-config.h + rm -f $(CCANDIR)config.h rm -f $(CCANDIR)tools/configurator/configurator rm -f *.so* *.a *.o From b66a139f12357757c54adf7f38031f0f9105c501 Mon Sep 17 00:00:00 2001 From: Klaus Jensen Date: Tue, 19 Oct 2021 22:13:53 +0200 Subject: [PATCH 0206/1564] meson: revert to using the ccan configurator Something fishy is going on with the -include config.h and #include "config.h" in the ccan sources. If examples/tests use ccan, they end up with redefinitions caused by the ccan config defines not being properly set. Revert to generating a ccan-specific config.h using the configurator (like the Make-based setup). Signed-off-by: Klaus Jensen --- ccan/meson.build | 2 +- meson.build | 86 +++------------------------------------------- pynvme/meson.build | 2 +- src/meson.build | 3 +- 4 files changed, 8 insertions(+), 85 deletions(-) diff --git a/ccan/meson.build b/ccan/meson.build index f24b94f5b9..c0143427c4 100644 --- a/ccan/meson.build +++ b/ccan/meson.build @@ -11,7 +11,7 @@ configurator = executable( c_args: ['-D_GNU_SOURCE'], ) -config_h = custom_target( +ccan_config_h = custom_target( 'config.h', output: 'config.h', capture: true, diff --git a/meson.build b/meson.build index 8251cf4f4c..b07497af60 100644 --- a/meson.build +++ b/meson.build @@ -108,87 +108,8 @@ conf.set('CONFIG_LIBUUID', libuuid.found(), description: 'Is libuuid required?') json_c = dependency('json-c', version: '>=0.13', fallback : ['json-c', 'json_c']) conf.set('CONFIG_JSONC', json_c.found(), description: 'Is json-c required?') -# local (cross-compilable) implementations of ccan configure steps -conf.set10( - 'HAVE_BUILTIN_TYPES_COMPATIBLE_P', - cc.compiles( - '''int main(void) { - return __builtin_types_compatible_p(int, long); - } - ''', - name: '__builtin_type_compatible_p' - ), - description: 'Is __builtin_types_compatible_p available?' -) -conf.set10( - 'HAVE_TYPEOF', - cc.compiles( - '''int main(void) { - int a = 1; - typeof(a) b; - b = a; - } - ''', - name: 'typeof' - ), - description: 'Is typeof available?' -) -conf.set10( - 'HAVE_BYTESWAP_H', - cc.compiles( - '''#include ''', - name: 'byteswap.h' - ), - description: 'Is byteswap.h include-able?' -) -conf.set10( - 'HAVE_BSWAP64', - cc.links( - '''#include - int main(void) { - return bswap_64(0); - } - ''', - name: 'bswap64' - ), - description: 'Is bswap_64 available?' -) -conf.set10( - 'HAVE_LITTLE_ENDIAN', - build_machine.endian() == 'little', - description: 'Building for little-endian' -) -conf.set10( - 'HAVE_BIG_ENDIAN', - build_machine.endian() == 'big', - description: 'Building for big-endian' -) -conf.set10( - 'HAVE_STATEMENT_EXPR', - cc.compiles( - '''int main(int argc, char **argv) { - return ({ int x = argc; x == 1; }); - } - ''', - name: 'statement-expr' - ), - description: 'Can we use a statement as an expression?' -) -conf.set10( - 'HAVE_ISBLANK', - cc.links( - '''#include - int main(int argc, char **argv) { - return isblank(argv[0][0]); - } - ''', - name: 'isblank' - ), - description: 'Is isblank() available?' -) - -config_h = configure_file( - output: 'config.h', +config_host_h = configure_file( + output: 'config-host.h', configuration: conf ) @@ -204,10 +125,11 @@ configure_file( ) ################################################################################ -add_project_arguments(['-fomit-frame-pointer', '-D_GNU_SOURCE', '-include', 'config.h'], language : 'c') +add_project_arguments(['-fomit-frame-pointer', '-D_GNU_SOURCE', '-include', 'config-host.h'], language : 'c') incdir = include_directories(['.', 'ccan', 'src']) ################################################################################ +subdir('ccan') subdir('src') subdir('pynvme') subdir('test') diff --git a/pynvme/meson.build b/pynvme/meson.build index 5e9c96d450..079536cfd3 100644 --- a/pynvme/meson.build +++ b/pynvme/meson.build @@ -10,7 +10,7 @@ swig = find_program('swig', required: false) if swig.found() pymod_swig = custom_target( 'nvme.py', - input: ['nvme.i', config_h], + input: ['nvme.i', config_host_h, ccan_config_h], output: ['nvme.py', 'nvme_wrap.c'], command: [swig, '-python', '-py3', '-o', '@OUTPUT1@', '@INPUT0@'], install: true, diff --git a/src/meson.build b/src/meson.build index 0d261c21b6..2b8fa63896 100644 --- a/src/meson.build +++ b/src/meson.build @@ -13,7 +13,8 @@ sources = [ 'nvme/log.c', 'nvme/tree.c', 'nvme/util.c', - config_h, + ccan_config_h, + config_host_h, ] if conf.get('CONFIG_JSONC') From bba3b8701948cde8749d89b1e1863722f2b2582e Mon Sep 17 00:00:00 2001 From: Klaus Jensen Date: Wed, 29 Sep 2021 19:44:55 +0200 Subject: [PATCH 0207/1564] types: move command parameters from ioctl.h Move spec-defined command parameters out of nvme/ioctl.h and into nvme/types.h. This allows third-party libraries and applications to use the type definitions of libnvme without potentially clashing with various function prototypes that are ioctl specific. Signed-off-by: Klaus Jensen --- src/nvme/ioctl.h | 719 ----------------------------------------------- src/nvme/types.h | 719 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 719 insertions(+), 719 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 7edfd5f32b..faeae5d8b5 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -370,428 +370,6 @@ int nvme_ns_rescan(int fd); */ int nvme_get_nsid(int fd, __u32 *nsid); -/** - * enum nvme_admin_opcode - Known NVMe admin opcodes - * @nvme_admin_delete_sq: - * @nvme_admin_create_sq: - * @nvme_admin_get_log_page: - * @nvme_admin_delete_cq: - * @nvme_admin_create_cq: - * @nvme_admin_identify: - * @nvme_admin_abort_cmd: - * @nvme_admin_set_features: - * @nvme_admin_get_features: - * @nvme_admin_async_event: - * @nvme_admin_ns_mgmt: - * @nvme_admin_fw_commit: - * @nvme_admin_fw_download: - * @nvme_admin_dev_self_test: - * @nvme_admin_ns_attach: - * @nvme_admin_keep_alive: - * @nvme_admin_directive_send: - * @nvme_admin_directive_recv: - * @nvme_admin_virtual_mgmt: - * @nvme_admin_nvme_mi_send: - * @nvme_admin_nvme_mi_recv: - * @nvme_admin_dbbuf: - * @nvme_admin_fabrics: - * @nvme_admin_format_nvm: - * @nvme_admin_security_send: - * @nvme_admin_security_recv: - * @nvme_admin_sanitize_nvm: - * @nvme_admin_get_lba_status: - */ -enum nvme_admin_opcode { - nvme_admin_delete_sq = 0x00, - nvme_admin_create_sq = 0x01, - nvme_admin_get_log_page = 0x02, - nvme_admin_delete_cq = 0x04, - nvme_admin_create_cq = 0x05, - nvme_admin_identify = 0x06, - nvme_admin_abort_cmd = 0x08, - nvme_admin_set_features = 0x09, - nvme_admin_get_features = 0x0a, - nvme_admin_async_event = 0x0c, - nvme_admin_ns_mgmt = 0x0d, - nvme_admin_fw_commit = 0x10, - nvme_admin_fw_activate = nvme_admin_fw_commit, - nvme_admin_fw_download = 0x11, - nvme_admin_dev_self_test = 0x14, - nvme_admin_ns_attach = 0x15, - nvme_admin_keep_alive = 0x18, - nvme_admin_directive_send = 0x19, - nvme_admin_directive_recv = 0x1a, - nvme_admin_virtual_mgmt = 0x1c, - nvme_admin_nvme_mi_send = 0x1d, - nvme_admin_nvme_mi_recv = 0x1e, - nvme_admin_dbbuf = 0x7c, - nvme_admin_fabrics = 0x7f, - nvme_admin_format_nvm = 0x80, - nvme_admin_security_send = 0x81, - nvme_admin_security_recv = 0x82, - nvme_admin_sanitize_nvm = 0x84, - nvme_admin_get_lba_status = 0x86, -}; - -/** - * enum nvme_identify_cns - - * @NVME_IDENTIFY_CNS_NS: - * @NVME_IDENTIFY_CNS_CTRL: - * @NVME_IDENTIFY_CNS_NS_ACTIVE_LIST: - * @NVME_IDENTIFY_CNS_NS_DESC_LIST: - * @NVME_IDENTIFY_CNS_NVMSET_LIST: - * @NVME_IDENTIFY_CNS_CSI_NS: - * @NVME_IDENTIFY_CNS_CSI_CTRL: - * @NVME_IDENTIFY_CNS_CSI_CSI_NS_ACTIVE_LIST: - * @NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST: - * @NVME_IDENTIFY_CNS_ALLOCATED_NS: - * @NVME_IDENTIFY_CNS_NS_CTRL_LIST: - * @NVME_IDENTIFY_CNS_CTRL_LIST: - * @NVME_IDENTIFY_CNS_PRIMARY_CTRL_CAP: - * @NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST: - * @NVME_IDENTIFY_CNS_NS_GRANULARITY: - * @NVME_IDENTIFY_CNS_UUID_LIST: - * @NVME_IDENTIFY_CNS_CSI_ALLOCATED_NS_LIST: - * @NVME_IDENTIFY_CNS_COMMAND_SET_STRUCTURE: Base Specification 2.0a section 5.17.2.21 - */ -enum nvme_identify_cns { - NVME_IDENTIFY_CNS_NS = 0x00, - NVME_IDENTIFY_CNS_CTRL = 0x01, - NVME_IDENTIFY_CNS_NS_ACTIVE_LIST = 0x02, - NVME_IDENTIFY_CNS_NS_DESC_LIST = 0x03, - NVME_IDENTIFY_CNS_NVMSET_LIST = 0x04, - NVME_IDENTIFY_CNS_CSI_NS = 0x05, - NVME_IDENTIFY_CNS_CSI_CTRL = 0x06, - NVME_IDENTIFY_CNS_CSI_NS_ACTIVE_LIST = 0x07, - NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST = 0x10, - NVME_IDENTIFY_CNS_ALLOCATED_NS = 0x11, - NVME_IDENTIFY_CNS_NS_CTRL_LIST = 0x12, - NVME_IDENTIFY_CNS_CTRL_LIST = 0x13, - NVME_IDENTIFY_CNS_PRIMARY_CTRL_CAP = 0x14, - NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST = 0x15, - NVME_IDENTIFY_CNS_NS_GRANULARITY = 0x16, - NVME_IDENTIFY_CNS_UUID_LIST = 0x17, - NVME_IDENTIFY_CNS_CSS_ALLOCATED_NS_LIST = 0x1A, - NVME_IDENTIFY_CNS_COMMAND_SET_STRUCTURE = 0x1C, -}; - -/** - * enum nvme_cmd_get_log_lid - - * @NVME_LOG_LID_ERROR: - * @NVME_LOG_LID_SMART: - * @NVME_LOG_LID_FW_SLOT: - * @NVME_LOG_LID_CHANGED_NS: - * @NVME_LOG_LID_CMD_EFFECTS: - * @NVME_LOG_LID_DEVICE_SELF_TEST: - * @NVME_LOG_LID_TELEMETRY_HOST: - * @NVME_LOG_LID_TELEMETRY_CTRL: - * @NVME_LOG_LID_ENDURANCE_GROUP: - * @NVME_LOG_LID_PREDICTABLE_LAT_NVMSET: - * @NVME_LOG_LID_PREDICTABLE_LAT_AGG: - * @NVME_LOG_LID_ANA: - * @NVME_LOG_LID_PERSISTENT_EVENT: - * @NVME_LOG_LID_LBA_STATUS: - * @NVME_LOG_LID_ENDURANCE_GRP_EVT: - * @NVME_LOG_LID_DISCOVER: - * @NVME_LOG_LID_RESERVATION: - * @NVME_LOG_LID_SANITIZE: - * @NVME_LOG_LID_ZNS_CHANGED_ZONES: - */ -enum nvme_cmd_get_log_lid { - NVME_LOG_LID_ERROR = 0x01, - NVME_LOG_LID_SMART = 0x02, - NVME_LOG_LID_FW_SLOT = 0x03, - NVME_LOG_LID_CHANGED_NS = 0x04, - NVME_LOG_LID_CMD_EFFECTS = 0x05, - NVME_LOG_LID_DEVICE_SELF_TEST = 0x06, - NVME_LOG_LID_TELEMETRY_HOST = 0x07, - NVME_LOG_LID_TELEMETRY_CTRL = 0x08, - NVME_LOG_LID_ENDURANCE_GROUP = 0x09, - NVME_LOG_LID_PREDICTABLE_LAT_NVMSET = 0x0a, - NVME_LOG_LID_PREDICTABLE_LAT_AGG = 0x0b, - NVME_LOG_LID_ANA = 0x0c, - NVME_LOG_LID_PERSISTENT_EVENT = 0x0d, - NVME_LOG_LID_LBA_STATUS = 0x0e, - NVME_LOG_LID_ENDURANCE_GRP_EVT = 0x0f, - NVME_LOG_LID_DISCOVER = 0x70, - NVME_LOG_LID_RESERVATION = 0x80, - NVME_LOG_LID_SANITIZE = 0x81, - NVME_LOG_LID_ZNS_CHANGED_ZONES = 0xbf, -}; - -/** - * enum nvme_features_id - - * @NVME_FEAT_FID_ARBITRATION: - * @NVME_FEAT_FID_POWER_MGMT: - * @NVME_FEAT_FID_LBA_RANGE: - * @NVME_FEAT_FID_TEMP_THRESH: - * @NVME_FEAT_FID_ERR_RECOVERY: - * @NVME_FEAT_FID_VOLATILE_WC: - * @NVME_FEAT_FID_NUM_QUEUES: - * @NVME_FEAT_FID_IRQ_COALESCE: - * @NVME_FEAT_FID_IRQ_CONFIG: - * @NVME_FEAT_FID_WRITE_ATOMIC: - * @NVME_FEAT_FID_ASYNC_EVENT: - * @NVME_FEAT_FID_AUTO_PST: - * @NVME_FEAT_FID_HOST_MEM_BUF: - * @NVME_FEAT_FID_TIMESTAMP: - * @NVME_FEAT_FID_KATO: - * @NVME_FEAT_FID_HCTM: - * @NVME_FEAT_FID_NOPSC: - * @NVME_FEAT_FID_RRL: - * @NVME_FEAT_FID_PLM_CONFIG: - * @NVME_FEAT_FID_PLM_WINDOW: - * @NVME_FEAT_FID_LBA_STS_INTERVAL: - * @NVME_FEAT_FID_HOST_BEHAVIOR: - * @NVME_FEAT_FID_SANITIZE: - * @NVME_FEAT_FID_ENDURANCE_EVT_CFG: - * @NVME_FEAT_FID_IOCS_PROFILE: - * @NVME_FEAT_FID_SW_PROGRESS: - * @NVME_FEAT_FID_HOST_ID: - * @NVME_FEAT_FID_RESV_MASK: - * @NVME_FEAT_FID_RESV_PERSIST: - * @NVME_FEAT_FID_WRITE_PROTECT: - */ -enum nvme_features_id { - NVME_FEAT_FID_ARBITRATION = 0x01, - NVME_FEAT_FID_POWER_MGMT = 0x02, - NVME_FEAT_FID_LBA_RANGE = 0x03, - NVME_FEAT_FID_TEMP_THRESH = 0x04, - NVME_FEAT_FID_ERR_RECOVERY = 0x05, - NVME_FEAT_FID_VOLATILE_WC = 0x06, - NVME_FEAT_FID_NUM_QUEUES = 0x07, - NVME_FEAT_FID_IRQ_COALESCE = 0x08, - NVME_FEAT_FID_IRQ_CONFIG = 0x09, - NVME_FEAT_FID_WRITE_ATOMIC = 0x0a, - NVME_FEAT_FID_ASYNC_EVENT = 0x0b, - NVME_FEAT_FID_AUTO_PST = 0x0c, - NVME_FEAT_FID_HOST_MEM_BUF = 0x0d, - NVME_FEAT_FID_TIMESTAMP = 0x0e, - NVME_FEAT_FID_KATO = 0x0f, - NVME_FEAT_FID_HCTM = 0x10, - NVME_FEAT_FID_NOPSC = 0x11, - NVME_FEAT_FID_RRL = 0x12, - NVME_FEAT_FID_PLM_CONFIG = 0x13, - NVME_FEAT_FID_PLM_WINDOW = 0x14, - NVME_FEAT_FID_LBA_STS_INTERVAL = 0x15, - NVME_FEAT_FID_HOST_BEHAVIOR = 0x16, - NVME_FEAT_FID_SANITIZE = 0x17, - NVME_FEAT_FID_ENDURANCE_EVT_CFG = 0x18, - NVME_FEAT_FID_IOCS_PROFILE = 0x19, /* XXX: Placeholder until assigned */ - NVME_FEAT_FID_SW_PROGRESS = 0x80, - NVME_FEAT_FID_HOST_ID = 0x81, - NVME_FEAT_FID_RESV_MASK = 0x82, - NVME_FEAT_FID_RESV_PERSIST = 0x83, - NVME_FEAT_FID_WRITE_PROTECT = 0x84, -}; - -/** - * enum nvme_get_features_sel - - * @NVME_GET_FEATURES_SEL_CURRENT: - * @NVME_GET_FEATURES_SEL_DEFAULT: - * @NVME_GET_FEATURES_SEL_SAVED: - */ -enum nvme_get_features_sel { - NVME_GET_FEATURES_SEL_CURRENT = 0, - NVME_GET_FEATURES_SEL_DEFAULT = 1, - NVME_GET_FEATURES_SEL_SAVED = 2, - NVME_GET_FEATURES_SEL_SUPPORTED = 3, -}; - -/** - * enum nvme_cmd_format_mset - - * @NVME_FORMAT_MSET_SEPARATE: - * @NVME_FORMAT_MSET_EXTENEDED: - */ -enum nvme_cmd_format_mset { - NVME_FORMAT_MSET_SEPARATE = 0, - NVME_FORMAT_MSET_EXTENEDED = 1, -}; - -/** - * enum nvme_cmd_format_pi - - * @NVME_FORMAT_PI_DISABLE: - * @NVME_FORMAT_PI_TYPE1: - * @NVME_FORMAT_PI_TYPE2: - * @NVME_FORMAT_PI_TYPE3: - */ -enum nvme_cmd_format_pi { - NVME_FORMAT_PI_DISABLE = 0, - NVME_FORMAT_PI_TYPE1 = 1, - NVME_FORMAT_PI_TYPE2 = 2, - NVME_FORMAT_PI_TYPE3 = 3, -}; - -/** - * @enum nvme_cmd_format_pil - - * @NVME_FORMAT_PIL_LAST: - * @NVME_FORMAT_PIL_FIRST: - */ -enum nvme_cmd_format_pil { - NVME_FORMAT_PIL_LAST = 0, - NVME_FORMAT_PIL_FIRST = 1, -}; - -/** - * enum nvme_cmd_format_ses - - * @NVME_FORMAT_SES_NONE: - * @NVME_FORMAT_SES_USER_DATA_ERASE: - * @NVME_FORMAT_SES_CRYPTO_ERASE: - */ -enum nvme_cmd_format_ses { - NVME_FORMAT_SES_NONE = 0, - NVME_FORMAT_SES_USER_DATA_ERASE = 1, - NVME_FORMAT_SES_CRYPTO_ERASE = 2, -}; - -/** - * enum nvme_ns_mgmt_sel - - * @NVME_NAMESPACE_MGMT_SEL_CREATE: - * @NVME_NAMESPACE_MGMT_SEL_DELETE: - */ -enum nvme_ns_mgmt_sel { - NVME_NS_MGMT_SEL_CREATE = 0, - NVME_NS_MGMT_SEL_DELETE = 1, -}; - -/** - * enum nvme_ns_attach_sel - - * NVME_NS_ATTACH_SEL_CTRL_ATTACH: - * NVME_NP_ATTACH_SEL_CTRL_DEATTACH: - */ -enum nvme_ns_attach_sel { - NVME_NS_ATTACH_SEL_CTRL_ATTACH = 0, - NVME_NS_ATTACH_SEL_CTRL_DEATTACH = 1, -}; - -/** - * enum nvme_fw_commit_ca - - * @NVME_FW_COMMIT_CA_REPLACE: - * @NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE: - * @NVME_FW_COMMIT_CA_SET_ACTIVE: - * @NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE_IMMEDIATE: - * @NVME_FW_COMMIT_CA_REPLACE_BOOT_PARTITION: - * @NVME_FW_COMMIT_CA_ACTIVATE_BOOT_PARTITION: - */ -enum nvme_fw_commit_ca { - NVME_FW_COMMIT_CA_REPLACE = 0, - NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE = 1, - NVME_FW_COMMIT_CA_SET_ACTIVE = 2, - NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE_IMMEDIATE = 3, - NVME_FW_COMMIT_CA_REPLACE_BOOT_PARTITION = 6, - NVME_FW_COMMIT_CA_ACTIVATE_BOOT_PARTITION = 7, -}; - -/** - * enum nvme_directive_dtype - - * @NVME_DIRECTIVE_DTYPE_IDENTIFY: - * @NVME_DIRECTIVE_DTYPE_STREAMS: - */ -enum nvme_directive_dtype { - NVME_DIRECTIVE_DTYPE_IDENTIFY = 0, - NVME_DIRECTIVE_DTYPE_STREAMS = 1, -}; - -/** - * enum nvme_directive_receive_doper - - * @NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM: - * @NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM: - * @NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS: - * @NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE: - */ -enum nvme_directive_receive_doper { - NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM = 0x01, - NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM = 0x01, - NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS = 0x02, - NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE = 0x03, -}; - -/** - * enum nvme_directive_send_doper - - * @NVME_DIRECTIVE_SEND_IDENTIFY_DOPER_ENDIR: - * @NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_IDENTIFIER: - * @NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE: - */ -enum nvme_directive_send_doper { - NVME_DIRECTIVE_SEND_IDENTIFY_DOPER_ENDIR = 0x01, - NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_IDENTIFIER = 0x01, - NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE = 0x02, -}; - -/** - * enum nvme_directive_send_identify_endir - - */ -enum nvme_directive_send_identify_endir { - NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_DISABLE = 0, - NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_ENABLE = 1, -}; - -/** - * enum nvme_sanitize_sanact - - * @NVME_SANITIZE_SANACT_EXIT_FAILURE: - * @NVME_SANITIZE_SANACT_START_BLOCK_ERASE: - * @NVME_SANITIZE_SANACT_START_OVERWRITE: - * @NVME_SANITIZE_SANACT_START_CRYPTO_ERASE: - */ -enum nvme_sanitize_sanact { - NVME_SANITIZE_SANACT_EXIT_FAILURE = 1, - NVME_SANITIZE_SANACT_START_BLOCK_ERASE = 2, - NVME_SANITIZE_SANACT_START_OVERWRITE = 3, - NVME_SANITIZE_SANACT_START_CRYPTO_ERASE = 4, -}; - -/** - * enum nvme_dst_stc - Action taken by the Device Self-test command - * @NVME_DST_STC_SHORT: Start a short device self-test operation - * @NVME_DST_STC_LONG: Start an extended device self-test operation - * @NVME_DST_STC_VS: Start a vendor specific device self-test operation - * @NVME_DST_STC_ABORT: Abort device self-test operation - */ -enum nvme_dst_stc { - NVME_DST_STC_SHORT = 0x1, - NVME_DST_STC_LONG = 0x2, - NVME_DST_STC_VS = 0xe, - NVME_DST_STC_ABORT = 0xf, -}; - -/** - * enum nvme_virt_mgmt_act - - * @NVME_VIRT_MGMT_ACT_PRIM_CTRL_FLEX_ALLOC: - * @NVME_VIRT_MGMT_ACT_OFFLINE_SEC_CTRL: - * @NVME_VIRT_MGMT_ACT_ASSIGN_SEC_CTRL: - * @NVME_VIRT_MGMT_ACT_ONLINE_SEC_CTRL: - */ -enum nvme_virt_mgmt_act { - NVME_VIRT_MGMT_ACT_PRIM_CTRL_FLEX_ALLOC = 1, - NVME_VIRT_MGMT_ACT_OFFLINE_SEC_CTRL = 7, - NVME_VIRT_MGMT_ACT_ASSIGN_SEC_CTRL = 8, - NVME_VIRT_MGMT_ACT_ONLINE_SEC_CTRL = 9, -}; - -/** - * enum nvme_virt_mgmt_rt - - * @NVME_VIRT_MGMT_RT_VQ_RESOURCE: - * @NVME_VIRT_MGMT_RT_VI_RESOURCE: - */ -enum nvme_virt_mgmt_rt { - NVME_VIRT_MGMT_RT_VQ_RESOURCE = 0, - NVME_VIRT_MGMT_RT_VI_RESOURCE = 1, -}; - -/** - * enum nvme_ns_write_protect - - * @NVME_NS_WP_CFG_NONE - * @NVME_NS_WP_CFG_PROTECT - * @NVME_NS_WP_CFG_PROTECT_POWER_CYCLE - * @NVME_NS_WP_CFG_PROTECT_PERMANENT - */ -enum nvme_ns_write_protect_cfg { - NVME_NS_WP_CFG_NONE = 0, - NVME_NS_WP_CFG_PROTECT = 1, - NVME_NS_WP_CFG_PROTECT_POWER_CYCLE = 2, - NVME_NS_WP_CFG_PROTECT_PERMANENT = 3, -}; - /** * nvme_identify() - Send the NVMe Identify command * @fd: File descriptor of nvme device @@ -1347,16 +925,6 @@ int nvme_get_log_predictable_lat_nvmset(int fd, __u16 nvmsetid, int nvme_get_log_predictable_lat_event(int fd, bool rae, __u32 offset, __u32 len, void *log); -/** - * enum nvme_log_ana_lsp - - * @NVME_LOG_ANA_LSP_RGO_NAMESPACES: - * @NVME_LOG_ANA_LSP_RGO_GROUPS_ONLY: - */ -enum nvme_log_ana_lsp { - NVME_LOG_ANA_LSP_RGO_NAMESPACES = 0, - NVME_LOG_ANA_LSP_RGO_GROUPS_ONLY = 1, -}; - /** * nvme_get_log_ana() - * @fd: File descriptor of nvme device @@ -1457,15 +1025,6 @@ int nvme_get_log_sanitize(int fd, bool rae, int nvme_get_log_zns_changed_zones(int fd, __u32 nsid, bool rae, struct nvme_zns_changed_zone_log *log); -/** - * enum nvme_pevent_log_action - - */ -enum nvme_pevent_log_action { - NVME_PEVENT_LOG_READ = 0x0, - NVME_PEVENT_LOG_EST_CTX_AND_READ = 0x1, - NVME_PEVENT_LOG_RELEASE_CTX = 0x2, -}; - /** * nvme_get_log_persistent_event() - * &fd: @@ -1548,14 +1107,6 @@ int nvme_set_features_power_mgmt(int fd, __u8 ps, __u8 wh, bool save, int nvme_set_features_lba_range(int fd, __u32 nsid, __u32 nr_ranges, bool save, struct nvme_lba_range_type *data, __u32 *result); -/** - * enum nvme_feat_tmpthresh_thsel - - */ -enum nvme_feat_tmpthresh_thsel { - NVME_FEATURE_TEMPTHRESH_THSEL_OVER = 0, - NVME_FEATURE_TEMPTHRESH_THSEL_UNDER = 1, -}; - /** * nvme_set_features_temp_thresh() - * @fd: File descriptor of nvme device @@ -1629,26 +1180,6 @@ int nvme_set_features_irq_config(int fd, __u16 iv, bool cd, bool save, int nvme_set_features_write_atomic(int fd, bool dn, bool save, __u32 *result); -/** - * enum nvme_features_async_event_config_flags - - */ -enum nvme_features_async_event_config_flags { - NVME_FEATURE_AENCFG_SMART_CRIT_SPARE = 1 << 0, - NVME_FEATURE_AENCFG_SMART_CRIT_TEMPERATURE = 1 << 1, - NVME_FEATURE_AENCFG_SMART_CRIT_DEGRADED = 1 << 2, - NVME_FEATURE_AENCFG_SMART_CRIT_READ_ONLY = 1 << 3, - NVME_FEATURE_AENCFG_SMART_CRIT_VOLATILE_BACKUP = 1 << 4, - NVME_FEATURE_AENCFG_SMART_CRIT_READ_ONLY_PMR = 1 << 5, - NVME_FEATURE_AENCFG_NOTICE_NAMESPACE_ATTRIBUTES = 1 << 8, - NVME_FEATURE_AENCFG_NOTICE_FIRMWARE_ACTIVATION = 1 << 9, - NVME_FEATURE_AENCFG_NOTICE_TELEMETRY_LOG = 1 << 10, - NVME_FEATURE_AENCFG_NOTICE_ANA_CHANGE = 1 << 11, - NVME_FEATURE_AENCFG_NOTICE_PL_EVENT = 1 << 12, - NVME_FEATURE_AENCFG_NOTICE_LBA_STATUS = 1 << 13, - NVME_FEATURE_AENCFG_NOTICE_EG_EVENT = 1 << 14, - NVME_FEATURE_AENCFG_NOTICE_DISCOVERY_CHANGE = 1 << 31, -}; - /** * nvme_set_features_async_event() - * @fd: File descriptor of nvme device @@ -1733,14 +1264,6 @@ int nvme_set_features_plm_config(int fd, bool enable, __u16 nvmsetid, bool save, struct nvme_plm_config *data, __u32*result); -/** - * enum nvme_feat_plm_window_select - - */ -enum nvme_feat_plm_window_select { - NVME_FEATURE_PLM_DTWIN = 1, - NVME_FEATURE_PLM_NDWIN = 2, -}; - /** * nvme_set_features_plm_window() - * @fd: File descriptor of nvme device @@ -1829,15 +1352,6 @@ 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); -/** - * - */ -enum nvme_feat_resv_notify_flags { - NVME_FEAT_RESV_NOTIFY_REGPRE = 1 << 1, - NVME_FEAT_RESV_NOTIFY_RESREL = 1 << 2, - NVME_FEAT_RESV_NOTIFY_RESPRE = 1 << 3, -}; - /** * nvme_set_features_resv_mask() - * @fd: File descriptor of nvme device @@ -1862,20 +1376,6 @@ 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); -/** - * enum nvme_feat_ns_wp_cfg_state - - * @NVME_FEAT_NS_NO_WRITE_PROTECT: - * @NVME_FEAT_NS_WRITE_PROTECT: - * @NVME_FEAT_NS_WRITE_PROTECT_PWR_CYCLE: - * @NVME_FEAT_NS_WRITE_PROTECT_PERMANENT: - */ -enum nvme_feat_nswpcfg_state { - 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, -}; - /** * nvme_set_features_write_protect() - * @fd: File descriptor of nvme device @@ -2621,24 +2121,6 @@ int nvme_directive_recv_stream_status(int fd, __u32 nsid, unsigned nr_entries, int nvme_directive_recv_stream_allocate(int fd, __u32 nsid, __u16 nsr, __u32 *result); -/** - * enum nvme_fctype - - * @nvme_fabrics_type_property_set: - * @nvme_fabrics_type_connect: - * @nvme_fabrics_type_property_get: - * @nvme_fabrics_type_auth_send: - * @nvme_fabrics_type_auth_receive: - * @nvme_fabrics_type_disconnect: - */ -enum nvme_fctype { - nvme_fabrics_type_property_set = 0x00, - nvme_fabrics_type_connect = 0x01, - nvme_fabrics_type_property_get = 0x04, - nvme_fabrics_type_auth_send = 0x05, - nvme_fabrics_type_auth_receive = 0x06, - nvme_fabrics_type_disconnect = 0x08, -}; - /** * nvme_set_property() - Set controller property * @fd: File descriptor of nvme device @@ -2739,40 +2221,6 @@ int nvme_virtual_mgmt(int fd, enum nvme_virt_mgmt_act act, enum nvme_virt_mgmt_rt rt, __u16 cntlid, __u16 nr, __u32 *result); -/** - * enum nvme_io_opcode - - * @nvme_cmd_flush: - * @nvme_cmd_write: - * @nvme_cmd_read: - * @nvme_cmd_write_uncor: - * @nvme_cmd_compare: - * @nvme_cmd_write_zeroes: - * @nvme_cmd_dsm: - * @nvme_cmd_verify: - * @nvme_cmd_resv_register: - * @nvme_cmd_resv_report: - * @nvme_cmd_resv_acquire: - * @nvme_cmd_resv_release: - */ -enum nvme_io_opcode { - nvme_cmd_flush = 0x00, - nvme_cmd_write = 0x01, - nvme_cmd_read = 0x02, - nvme_cmd_write_uncor = 0x04, - nvme_cmd_compare = 0x05, - nvme_cmd_write_zeroes = 0x08, - nvme_cmd_dsm = 0x09, - nvme_cmd_verify = 0x0c, - nvme_cmd_resv_register = 0x0d, - nvme_cmd_resv_report = 0x0e, - nvme_cmd_resv_acquire = 0x11, - nvme_cmd_resv_release = 0x15, - nvme_cmd_copy = 0x19, - nvme_zns_cmd_mgmt_send = 0x79, - nvme_zns_cmd_mgmt_recv = 0x7a, - nvme_zns_cmd_append = 0x7d, -}; - /** * nvme_flush() - Send an nvme flush command * @fd: File descriptor of nvme device @@ -2786,66 +2234,6 @@ enum nvme_io_opcode { */ int nvme_flush(int fd, __u32 nsid); -/** - * enum nvme_io_control_flags - - * @NVME_IO_DTYPE_STREAMS: - * @NVME_IO_DEAC: - * @NVME_IO_ZNS_APPEND_PIREMAP: - * @NVME_IO_PRINFO_PRCHK_REF: - * @NVME_IO_PRINFO_PRCHK_APP: - * @NVME_IO_PRINFO_PRCHK_GUARD: - * @NVME_IO_PRINFO_PRACT: - * @NVME_IO_FUA: - * @NVME_IO_LR: - */ -enum nvme_io_control_flags { - NVME_IO_DTYPE_STREAMS = 1 << 4, - NVME_IO_DEAC = 1 << 9, - NVME_IO_ZNS_APPEND_PIREMAP = 1 << 9, - NVME_IO_PRINFO_PRCHK_REF = 1 << 10, - NVME_IO_PRINFO_PRCHK_APP = 1 << 11, - NVME_IO_PRINFO_PRCHK_GUARD = 1 << 12, - NVME_IO_PRINFO_PRACT = 1 << 13, - NVME_IO_FUA = 1 << 14, - NVME_IO_LR = 1 << 15, -}; - -/** - * enum nvme_io_dsm_flag - - * @NVME_IO_DSM_FREQ_UNSPEC: - * @NVME_IO_DSM_FREQ_TYPICAL: - * @NVME_IO_DSM_FREQ_RARE: - * @NVME_IO_DSM_FREQ_READS: - * @NVME_IO_DSM_FREQ_WRITES: - * @NVME_IO_DSM_FREQ_RW: - * @NVME_IO_DSM_FREQ_ONCE: - * @NVME_IO_DSM_FREQ_PREFETCH: - * @NVME_IO_DSM_FREQ_TEMP: - * @NVME_IO_DSM_LATENCY_NONE: - * @NVME_IO_DSM_LATENCY_IDLE: - * @NVME_IO_DSM_LATENCY_NORM: - * @NVME_IO_DSM_LATENCY_LOW: - * @NVME_IO_DSM_SEQ_REQ: - * @NVME_IO_DSM_COMPRESSED: - */ -enum nvme_io_dsm_flags { - NVME_IO_DSM_FREQ_UNSPEC = 0, - NVME_IO_DSM_FREQ_TYPICAL = 1, - NVME_IO_DSM_FREQ_RARE = 2, - NVME_IO_DSM_FREQ_READS = 3, - NVME_IO_DSM_FREQ_WRITES = 4, - NVME_IO_DSM_FREQ_RW = 5, - NVME_IO_DSM_FREQ_ONCE = 6, - NVME_IO_DSM_FREQ_PREFETCH = 7, - NVME_IO_DSM_FREQ_TEMP = 8, - NVME_IO_DSM_LATENCY_NONE = 0 << 4, - NVME_IO_DSM_LATENCY_IDLE = 1 << 4, - NVME_IO_DSM_LATENCY_NORM = 2 << 4, - NVME_IO_DSM_LATENCY_LOW = 3 << 4, - NVME_IO_DSM_SEQ_REQ = 1 << 6, - NVME_IO_DSM_COMPRESSED = 1 << 7, -}; - /** * nvme_read() - Submit an nvme user read command * @fd: File descriptor of nvme device @@ -3006,18 +2394,6 @@ int nvme_write_uncorrectable(int fd, __u32 nsid, __u64 slba, __u16 nlb); int nvme_verify(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 reftag, __u16 apptag, __u16 appmask); -/** - * enum nvme_dsm_attributes - - * @NVME_DSMGMT_IDR: - * @NVME_DSMGMT_IDW: - * @NVME_DSMGMT_AD: - */ -enum nvme_dsm_attributes { - NVME_DSMGMT_IDR = 1 << 0, - NVME_DSMGMT_IDW = 1 << 1, - NVME_DSMGMT_AD = 1 << 2, -}; - /** * nvme_dsm() - Send an nvme data set management command * @fd: File descriptor of nvme device @@ -3049,36 +2425,6 @@ int nvme_copy(int fd, __u32 nsid, struct nvme_copy_range *copy, __u64 sdlba, __u8 format, int lr, int fua, __u32 ilbrt, __u16 lbatm, __u16 lbat); -/** - * enum nvme_resv_rtype - - * @NVME_RESERVATION_RTYPE_WE: - * @NVME_RESERVATION_RTYPE_EA: - * @NVME_RESERVATION_RTYPE_WERO: - * @NVME_RESERVATION_RTYPE_EARO: - * @NVME_RESERVATION_RTYPE_WEAR: - * @NVME_RESERVATION_RTYPE_EAAR: - */ -enum nvme_resv_rtype { - NVME_RESERVATION_RTYPE_WE = 1, - NVME_RESERVATION_RTYPE_EA = 2, - NVME_RESERVATION_RTYPE_WERO = 3, - NVME_RESERVATION_RTYPE_EARO = 4, - NVME_RESERVATION_RTYPE_WEAR = 5, - NVME_RESERVATION_RTYPE_EAAR = 6, -}; - -/** - * enum nvme_resv_racqa - - * @NVME_RESERVATION_RACQA_ACQUIRE: - * @NVME_RESERVATION_RACQA_PREEMPT: - * @NVME_RESERVATION_RACQA_PREEMPT_AND_ABORT: - */ -enum nvme_resv_racqa { - NVME_RESERVATION_RACQA_ACQUIRE = 0, - NVME_RESERVATION_RACQA_PREEMPT = 1, - NVME_RESERVATION_RACQA_PREEMPT_AND_ABORT = 2, -}; - /** * nvme_resv_acquire() - Send an nvme reservation acquire * @fd: File descriptor of nvme device @@ -3101,30 +2447,6 @@ int nvme_resv_acquire(int fd, __u32 nsid, enum nvme_resv_rtype rtype, enum nvme_resv_racqa racqa, bool iekey, __u64 crkey, __u64 nrkey); -/** - * enum nvme_resv_rrega - - * @NVME_RESERVATION_RREGA_REGISTER_KEY: - * @NVME_RESERVATION_RREGA_UNREGISTER_KEY: - * @NVME_RESERVATION_RREGA_REPLACE_KEY: - */ -enum nvme_resv_rrega { - NVME_RESERVATION_RREGA_REGISTER_KEY = 0, - NVME_RESERVATION_RREGA_UNREGISTER_KEY = 1, - NVME_RESERVATION_RREGA_REPLACE_KEY = 2, -}; - -/** - * enum nvme_resv_cptpl - - * @NVME_RESERVATION_CPTPL_NO_CHANGE: - * @NVME_RESERVATION_CPTPL_CLEAR: - * @NVME_RESERVATION_CPTPL_PERSIST: - */ -enum nvme_resv_cptpl { - NVME_RESERVATION_CPTPL_NO_CHANGE = 0, - NVME_RESERVATION_CPTPL_CLEAR = 2, - NVME_RESERVATION_CPTPL_PERSIST = 3, -}; - /** * nvme_resv_register() - Send an nvme reservation register * @fd: File descriptor of nvme device @@ -3146,16 +2468,6 @@ int nvme_resv_register(int fd, __u32 nsid, enum nvme_resv_rrega rrega, enum nvme_resv_cptpl cptpl, bool iekey, __u64 crkey, __u64 nrkey); -/** - * enum nvme_resv_rrela - - * @NVME_RESERVATION_RRELA_RELEASE: - * @NVME_RESERVATION_RRELA_CLEAR: - */ -enum nvme_resv_rrela { - NVME_RESERVATION_RRELA_RELEASE = 0, - NVME_RESERVATION_RRELA_CLEAR = 1 -}; - /** * nvme_resv_release() - Send an nvme reservation release * @fd: File descriptor of nvme device @@ -3190,15 +2502,6 @@ int nvme_resv_release(int fd, __u32 nsid, enum nvme_resv_rtype rtype, int nvme_resv_report(int fd, __u32 nsid, bool eds, __u32 len, struct nvme_resv_status *report); -enum nvme_zns_send_action { - NVME_ZNS_ZSA_CLOSE = 0x1, - NVME_ZNS_ZSA_FINISH = 0x2, - NVME_ZNS_ZSA_OPEN = 0x3, - NVME_ZNS_ZSA_RESET = 0x4, - NVME_ZNS_ZSA_OFFLINE = 0x5, - NVME_ZNS_ZSA_SET_DESC_EXT = 0x10, -}; - /** * nvme_zns_mgmt_send() - * @fd: File descriptor of nvme device @@ -3216,14 +2519,6 @@ int nvme_zns_mgmt_send(int fd, __u32 nsid, __u64 slba, bool select_all, enum nvme_zns_send_action zsa, __u32 data_len, void *data); -/** - * enum nvme_zns_recv_action - - */ -enum nvme_zns_recv_action { - NVME_ZNS_ZRA_REPORT_ZONES = 0x0, - NVME_ZNS_ZRA_EXTENDED_REPORT_ZONES = 0x1, -}; - /** * nvme_zns_mgmt_recv() - * @fd: File descriptor of nvme device @@ -3242,20 +2537,6 @@ int nvme_zns_mgmt_recv(int fd, __u32 nsid, __u64 slba, enum nvme_zns_recv_action zra, __u16 zrasf, bool zras_feat, __u32 data_len, void *data); -/** - * enum nvme_zns_report_options - - */ -enum nvme_zns_report_options { - NVME_ZNS_ZRAS_REPORT_ALL = 0x0, - NVME_ZNS_ZRAS_REPORT_EMPTY = 0x1, - NVME_ZNS_ZRAS_REPORT_IMPL_OPENED = 0x2, - NVME_ZNS_ZRAS_REPORT_EXPL_OPENED = 0x3, - NVME_ZNS_ZRAS_REPORT_CLOSED = 0x4, - NVME_ZNS_ZRAS_REPORT_FULL = 0x5, - NVME_ZNS_ZRAS_REPORT_READ_ONLY = 0x6, - NVME_ZNS_ZRAS_REPORT_OFFLINE = 0x7, -}; - int nvme_zns_report_zones(int fd, __u32 nsid, __u64 slba, bool extended, enum nvme_zns_report_options opts, bool partial, __u32 data_len, void *data); diff --git a/src/nvme/types.h b/src/nvme/types.h index 292284e05a..f9ccbe1970 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -4808,4 +4808,723 @@ static inline __u16 nvme_status_code(__u16 status_field) return status_field & NVME_SC_MASK; } +/** + * enum nvme_admin_opcode - Known NVMe admin opcodes + * @nvme_admin_delete_sq: + * @nvme_admin_create_sq: + * @nvme_admin_get_log_page: + * @nvme_admin_delete_cq: + * @nvme_admin_create_cq: + * @nvme_admin_identify: + * @nvme_admin_abort_cmd: + * @nvme_admin_set_features: + * @nvme_admin_get_features: + * @nvme_admin_async_event: + * @nvme_admin_ns_mgmt: + * @nvme_admin_fw_commit: + * @nvme_admin_fw_download: + * @nvme_admin_dev_self_test: + * @nvme_admin_ns_attach: + * @nvme_admin_keep_alive: + * @nvme_admin_directive_send: + * @nvme_admin_directive_recv: + * @nvme_admin_virtual_mgmt: + * @nvme_admin_nvme_mi_send: + * @nvme_admin_nvme_mi_recv: + * @nvme_admin_dbbuf: + * @nvme_admin_fabrics: + * @nvme_admin_format_nvm: + * @nvme_admin_security_send: + * @nvme_admin_security_recv: + * @nvme_admin_sanitize_nvm: + * @nvme_admin_get_lba_status: + */ +enum nvme_admin_opcode { + nvme_admin_delete_sq = 0x00, + nvme_admin_create_sq = 0x01, + nvme_admin_get_log_page = 0x02, + nvme_admin_delete_cq = 0x04, + nvme_admin_create_cq = 0x05, + nvme_admin_identify = 0x06, + nvme_admin_abort_cmd = 0x08, + nvme_admin_set_features = 0x09, + nvme_admin_get_features = 0x0a, + nvme_admin_async_event = 0x0c, + nvme_admin_ns_mgmt = 0x0d, + nvme_admin_fw_commit = 0x10, + nvme_admin_fw_activate = nvme_admin_fw_commit, + nvme_admin_fw_download = 0x11, + nvme_admin_dev_self_test = 0x14, + nvme_admin_ns_attach = 0x15, + nvme_admin_keep_alive = 0x18, + nvme_admin_directive_send = 0x19, + nvme_admin_directive_recv = 0x1a, + nvme_admin_virtual_mgmt = 0x1c, + nvme_admin_nvme_mi_send = 0x1d, + nvme_admin_nvme_mi_recv = 0x1e, + nvme_admin_dbbuf = 0x7c, + nvme_admin_fabrics = 0x7f, + nvme_admin_format_nvm = 0x80, + nvme_admin_security_send = 0x81, + nvme_admin_security_recv = 0x82, + nvme_admin_sanitize_nvm = 0x84, + nvme_admin_get_lba_status = 0x86, +}; + +/** + * enum nvme_identify_cns - + * @NVME_IDENTIFY_CNS_NS: + * @NVME_IDENTIFY_CNS_CTRL: + * @NVME_IDENTIFY_CNS_NS_ACTIVE_LIST: + * @NVME_IDENTIFY_CNS_NS_DESC_LIST: + * @NVME_IDENTIFY_CNS_NVMSET_LIST: + * @NVME_IDENTIFY_CNS_CSI_NS: + * @NVME_IDENTIFY_CNS_CSI_CTRL: + * @NVME_IDENTIFY_CNS_CSI_CSI_NS_ACTIVE_LIST: + * @NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST: + * @NVME_IDENTIFY_CNS_ALLOCATED_NS: + * @NVME_IDENTIFY_CNS_NS_CTRL_LIST: + * @NVME_IDENTIFY_CNS_CTRL_LIST: + * @NVME_IDENTIFY_CNS_PRIMARY_CTRL_CAP: + * @NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST: + * @NVME_IDENTIFY_CNS_NS_GRANULARITY: + * @NVME_IDENTIFY_CNS_UUID_LIST: + * @NVME_IDENTIFY_CNS_CSI_ALLOCATED_NS_LIST: + * @NVME_IDENTIFY_CNS_COMMAND_SET_STRUCTURE: Base Specification 2.0a section 5.17.2.21 + */ +enum nvme_identify_cns { + NVME_IDENTIFY_CNS_NS = 0x00, + NVME_IDENTIFY_CNS_CTRL = 0x01, + NVME_IDENTIFY_CNS_NS_ACTIVE_LIST = 0x02, + NVME_IDENTIFY_CNS_NS_DESC_LIST = 0x03, + NVME_IDENTIFY_CNS_NVMSET_LIST = 0x04, + NVME_IDENTIFY_CNS_CSI_NS = 0x05, + NVME_IDENTIFY_CNS_CSI_CTRL = 0x06, + NVME_IDENTIFY_CNS_CSI_NS_ACTIVE_LIST = 0x07, + NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST = 0x10, + NVME_IDENTIFY_CNS_ALLOCATED_NS = 0x11, + NVME_IDENTIFY_CNS_NS_CTRL_LIST = 0x12, + NVME_IDENTIFY_CNS_CTRL_LIST = 0x13, + NVME_IDENTIFY_CNS_PRIMARY_CTRL_CAP = 0x14, + NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST = 0x15, + NVME_IDENTIFY_CNS_NS_GRANULARITY = 0x16, + NVME_IDENTIFY_CNS_UUID_LIST = 0x17, + NVME_IDENTIFY_CNS_CSS_ALLOCATED_NS_LIST = 0x1A, + NVME_IDENTIFY_CNS_COMMAND_SET_STRUCTURE = 0x1C, +}; + +/** + * enum nvme_cmd_get_log_lid - + * @NVME_LOG_LID_ERROR: + * @NVME_LOG_LID_SMART: + * @NVME_LOG_LID_FW_SLOT: + * @NVME_LOG_LID_CHANGED_NS: + * @NVME_LOG_LID_CMD_EFFECTS: + * @NVME_LOG_LID_DEVICE_SELF_TEST: + * @NVME_LOG_LID_TELEMETRY_HOST: + * @NVME_LOG_LID_TELEMETRY_CTRL: + * @NVME_LOG_LID_ENDURANCE_GROUP: + * @NVME_LOG_LID_PREDICTABLE_LAT_NVMSET: + * @NVME_LOG_LID_PREDICTABLE_LAT_AGG: + * @NVME_LOG_LID_ANA: + * @NVME_LOG_LID_PERSISTENT_EVENT: + * @NVME_LOG_LID_LBA_STATUS: + * @NVME_LOG_LID_ENDURANCE_GRP_EVT: + * @NVME_LOG_LID_DISCOVER: + * @NVME_LOG_LID_RESERVATION: + * @NVME_LOG_LID_SANITIZE: + * @NVME_LOG_LID_ZNS_CHANGED_ZONES: + */ +enum nvme_cmd_get_log_lid { + NVME_LOG_LID_ERROR = 0x01, + NVME_LOG_LID_SMART = 0x02, + NVME_LOG_LID_FW_SLOT = 0x03, + NVME_LOG_LID_CHANGED_NS = 0x04, + NVME_LOG_LID_CMD_EFFECTS = 0x05, + NVME_LOG_LID_DEVICE_SELF_TEST = 0x06, + NVME_LOG_LID_TELEMETRY_HOST = 0x07, + NVME_LOG_LID_TELEMETRY_CTRL = 0x08, + NVME_LOG_LID_ENDURANCE_GROUP = 0x09, + NVME_LOG_LID_PREDICTABLE_LAT_NVMSET = 0x0a, + NVME_LOG_LID_PREDICTABLE_LAT_AGG = 0x0b, + NVME_LOG_LID_ANA = 0x0c, + NVME_LOG_LID_PERSISTENT_EVENT = 0x0d, + NVME_LOG_LID_LBA_STATUS = 0x0e, + NVME_LOG_LID_ENDURANCE_GRP_EVT = 0x0f, + NVME_LOG_LID_DISCOVER = 0x70, + NVME_LOG_LID_RESERVATION = 0x80, + NVME_LOG_LID_SANITIZE = 0x81, + NVME_LOG_LID_ZNS_CHANGED_ZONES = 0xbf, +}; + +/** + * enum nvme_features_id - + * @NVME_FEAT_FID_ARBITRATION: + * @NVME_FEAT_FID_POWER_MGMT: + * @NVME_FEAT_FID_LBA_RANGE: + * @NVME_FEAT_FID_TEMP_THRESH: + * @NVME_FEAT_FID_ERR_RECOVERY: + * @NVME_FEAT_FID_VOLATILE_WC: + * @NVME_FEAT_FID_NUM_QUEUES: + * @NVME_FEAT_FID_IRQ_COALESCE: + * @NVME_FEAT_FID_IRQ_CONFIG: + * @NVME_FEAT_FID_WRITE_ATOMIC: + * @NVME_FEAT_FID_ASYNC_EVENT: + * @NVME_FEAT_FID_AUTO_PST: + * @NVME_FEAT_FID_HOST_MEM_BUF: + * @NVME_FEAT_FID_TIMESTAMP: + * @NVME_FEAT_FID_KATO: + * @NVME_FEAT_FID_HCTM: + * @NVME_FEAT_FID_NOPSC: + * @NVME_FEAT_FID_RRL: + * @NVME_FEAT_FID_PLM_CONFIG: + * @NVME_FEAT_FID_PLM_WINDOW: + * @NVME_FEAT_FID_LBA_STS_INTERVAL: + * @NVME_FEAT_FID_HOST_BEHAVIOR: + * @NVME_FEAT_FID_SANITIZE: + * @NVME_FEAT_FID_ENDURANCE_EVT_CFG: + * @NVME_FEAT_FID_IOCS_PROFILE: + * @NVME_FEAT_FID_SW_PROGRESS: + * @NVME_FEAT_FID_HOST_ID: + * @NVME_FEAT_FID_RESV_MASK: + * @NVME_FEAT_FID_RESV_PERSIST: + * @NVME_FEAT_FID_WRITE_PROTECT: + */ +enum nvme_features_id { + NVME_FEAT_FID_ARBITRATION = 0x01, + NVME_FEAT_FID_POWER_MGMT = 0x02, + NVME_FEAT_FID_LBA_RANGE = 0x03, + NVME_FEAT_FID_TEMP_THRESH = 0x04, + NVME_FEAT_FID_ERR_RECOVERY = 0x05, + NVME_FEAT_FID_VOLATILE_WC = 0x06, + NVME_FEAT_FID_NUM_QUEUES = 0x07, + NVME_FEAT_FID_IRQ_COALESCE = 0x08, + NVME_FEAT_FID_IRQ_CONFIG = 0x09, + NVME_FEAT_FID_WRITE_ATOMIC = 0x0a, + NVME_FEAT_FID_ASYNC_EVENT = 0x0b, + NVME_FEAT_FID_AUTO_PST = 0x0c, + NVME_FEAT_FID_HOST_MEM_BUF = 0x0d, + NVME_FEAT_FID_TIMESTAMP = 0x0e, + NVME_FEAT_FID_KATO = 0x0f, + NVME_FEAT_FID_HCTM = 0x10, + NVME_FEAT_FID_NOPSC = 0x11, + NVME_FEAT_FID_RRL = 0x12, + NVME_FEAT_FID_PLM_CONFIG = 0x13, + NVME_FEAT_FID_PLM_WINDOW = 0x14, + NVME_FEAT_FID_LBA_STS_INTERVAL = 0x15, + NVME_FEAT_FID_HOST_BEHAVIOR = 0x16, + NVME_FEAT_FID_SANITIZE = 0x17, + NVME_FEAT_FID_ENDURANCE_EVT_CFG = 0x18, + NVME_FEAT_FID_IOCS_PROFILE = 0x19, /* XXX: Placeholder until assigned */ + NVME_FEAT_FID_SW_PROGRESS = 0x80, + NVME_FEAT_FID_HOST_ID = 0x81, + NVME_FEAT_FID_RESV_MASK = 0x82, + NVME_FEAT_FID_RESV_PERSIST = 0x83, + NVME_FEAT_FID_WRITE_PROTECT = 0x84, +}; + +/** + * enum nvme_get_features_sel - + * @NVME_GET_FEATURES_SEL_CURRENT: + * @NVME_GET_FEATURES_SEL_DEFAULT: + * @NVME_GET_FEATURES_SEL_SAVED: + */ +enum nvme_get_features_sel { + NVME_GET_FEATURES_SEL_CURRENT = 0, + NVME_GET_FEATURES_SEL_DEFAULT = 1, + NVME_GET_FEATURES_SEL_SAVED = 2, + NVME_GET_FEATURES_SEL_SUPPORTED = 3, +}; + +/** + * enum nvme_cmd_format_mset - + * @NVME_FORMAT_MSET_SEPARATE: + * @NVME_FORMAT_MSET_EXTENEDED: + */ +enum nvme_cmd_format_mset { + NVME_FORMAT_MSET_SEPARATE = 0, + NVME_FORMAT_MSET_EXTENEDED = 1, +}; + +/** + * enum nvme_cmd_format_pi - + * @NVME_FORMAT_PI_DISABLE: + * @NVME_FORMAT_PI_TYPE1: + * @NVME_FORMAT_PI_TYPE2: + * @NVME_FORMAT_PI_TYPE3: + */ +enum nvme_cmd_format_pi { + NVME_FORMAT_PI_DISABLE = 0, + NVME_FORMAT_PI_TYPE1 = 1, + NVME_FORMAT_PI_TYPE2 = 2, + NVME_FORMAT_PI_TYPE3 = 3, +}; + +/** + * @enum nvme_cmd_format_pil - + * @NVME_FORMAT_PIL_LAST: + * @NVME_FORMAT_PIL_FIRST: + */ +enum nvme_cmd_format_pil { + NVME_FORMAT_PIL_LAST = 0, + NVME_FORMAT_PIL_FIRST = 1, +}; + +/** + * enum nvme_cmd_format_ses - + * @NVME_FORMAT_SES_NONE: + * @NVME_FORMAT_SES_USER_DATA_ERASE: + * @NVME_FORMAT_SES_CRYPTO_ERASE: + */ +enum nvme_cmd_format_ses { + NVME_FORMAT_SES_NONE = 0, + NVME_FORMAT_SES_USER_DATA_ERASE = 1, + NVME_FORMAT_SES_CRYPTO_ERASE = 2, +}; + +/** + * enum nvme_ns_mgmt_sel - + * @NVME_NAMESPACE_MGMT_SEL_CREATE: + * @NVME_NAMESPACE_MGMT_SEL_DELETE: + */ +enum nvme_ns_mgmt_sel { + NVME_NS_MGMT_SEL_CREATE = 0, + NVME_NS_MGMT_SEL_DELETE = 1, +}; + +/** + * enum nvme_ns_attach_sel - + * NVME_NS_ATTACH_SEL_CTRL_ATTACH: + * NVME_NP_ATTACH_SEL_CTRL_DEATTACH: + */ +enum nvme_ns_attach_sel { + NVME_NS_ATTACH_SEL_CTRL_ATTACH = 0, + NVME_NS_ATTACH_SEL_CTRL_DEATTACH = 1, +}; + +/** + * enum nvme_fw_commit_ca - + * @NVME_FW_COMMIT_CA_REPLACE: + * @NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE: + * @NVME_FW_COMMIT_CA_SET_ACTIVE: + * @NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE_IMMEDIATE: + * @NVME_FW_COMMIT_CA_REPLACE_BOOT_PARTITION: + * @NVME_FW_COMMIT_CA_ACTIVATE_BOOT_PARTITION: + */ +enum nvme_fw_commit_ca { + NVME_FW_COMMIT_CA_REPLACE = 0, + NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE = 1, + NVME_FW_COMMIT_CA_SET_ACTIVE = 2, + NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE_IMMEDIATE = 3, + NVME_FW_COMMIT_CA_REPLACE_BOOT_PARTITION = 6, + NVME_FW_COMMIT_CA_ACTIVATE_BOOT_PARTITION = 7, +}; + +/** + * enum nvme_directive_dtype - + * @NVME_DIRECTIVE_DTYPE_IDENTIFY: + * @NVME_DIRECTIVE_DTYPE_STREAMS: + */ +enum nvme_directive_dtype { + NVME_DIRECTIVE_DTYPE_IDENTIFY = 0, + NVME_DIRECTIVE_DTYPE_STREAMS = 1, +}; + +/** + * enum nvme_directive_receive_doper - + * @NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM: + * @NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM: + * @NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS: + * @NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE: + */ +enum nvme_directive_receive_doper { + NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM = 0x01, + NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM = 0x01, + NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS = 0x02, + NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE = 0x03, +}; + +/** + * enum nvme_directive_send_doper - + * @NVME_DIRECTIVE_SEND_IDENTIFY_DOPER_ENDIR: + * @NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_IDENTIFIER: + * @NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE: + */ +enum nvme_directive_send_doper { + NVME_DIRECTIVE_SEND_IDENTIFY_DOPER_ENDIR = 0x01, + NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_IDENTIFIER = 0x01, + NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE = 0x02, +}; + +/** + * enum nvme_directive_send_identify_endir - + */ +enum nvme_directive_send_identify_endir { + NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_DISABLE = 0, + NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_ENABLE = 1, +}; + +/** + * enum nvme_sanitize_sanact - + * @NVME_SANITIZE_SANACT_EXIT_FAILURE: + * @NVME_SANITIZE_SANACT_START_BLOCK_ERASE: + * @NVME_SANITIZE_SANACT_START_OVERWRITE: + * @NVME_SANITIZE_SANACT_START_CRYPTO_ERASE: + */ +enum nvme_sanitize_sanact { + NVME_SANITIZE_SANACT_EXIT_FAILURE = 1, + NVME_SANITIZE_SANACT_START_BLOCK_ERASE = 2, + NVME_SANITIZE_SANACT_START_OVERWRITE = 3, + NVME_SANITIZE_SANACT_START_CRYPTO_ERASE = 4, +}; + +/** + * enum nvme_dst_stc - Action taken by the Device Self-test command + * @NVME_DST_STC_SHORT: Start a short device self-test operation + * @NVME_DST_STC_LONG: Start an extended device self-test operation + * @NVME_DST_STC_VS: Start a vendor specific device self-test operation + * @NVME_DST_STC_ABORT: Abort device self-test operation + */ +enum nvme_dst_stc { + NVME_DST_STC_SHORT = 0x1, + NVME_DST_STC_LONG = 0x2, + NVME_DST_STC_VS = 0xe, + NVME_DST_STC_ABORT = 0xf, +}; + +/** + * enum nvme_virt_mgmt_act - + * @NVME_VIRT_MGMT_ACT_PRIM_CTRL_FLEX_ALLOC: + * @NVME_VIRT_MGMT_ACT_OFFLINE_SEC_CTRL: + * @NVME_VIRT_MGMT_ACT_ASSIGN_SEC_CTRL: + * @NVME_VIRT_MGMT_ACT_ONLINE_SEC_CTRL: + */ +enum nvme_virt_mgmt_act { + NVME_VIRT_MGMT_ACT_PRIM_CTRL_FLEX_ALLOC = 1, + NVME_VIRT_MGMT_ACT_OFFLINE_SEC_CTRL = 7, + NVME_VIRT_MGMT_ACT_ASSIGN_SEC_CTRL = 8, + NVME_VIRT_MGMT_ACT_ONLINE_SEC_CTRL = 9, +}; + +/** + * enum nvme_virt_mgmt_rt - + * @NVME_VIRT_MGMT_RT_VQ_RESOURCE: + * @NVME_VIRT_MGMT_RT_VI_RESOURCE: + */ +enum nvme_virt_mgmt_rt { + NVME_VIRT_MGMT_RT_VQ_RESOURCE = 0, + NVME_VIRT_MGMT_RT_VI_RESOURCE = 1, +}; + +/** + * enum nvme_ns_write_protect - + * @NVME_NS_WP_CFG_NONE + * @NVME_NS_WP_CFG_PROTECT + * @NVME_NS_WP_CFG_PROTECT_POWER_CYCLE + * @NVME_NS_WP_CFG_PROTECT_PERMANENT + */ +enum nvme_ns_write_protect_cfg { + NVME_NS_WP_CFG_NONE = 0, + NVME_NS_WP_CFG_PROTECT = 1, + NVME_NS_WP_CFG_PROTECT_POWER_CYCLE = 2, + NVME_NS_WP_CFG_PROTECT_PERMANENT = 3, +}; + +/** + * enum nvme_log_ana_lsp - + * @NVME_LOG_ANA_LSP_RGO_NAMESPACES: + * @NVME_LOG_ANA_LSP_RGO_GROUPS_ONLY: + */ +enum nvme_log_ana_lsp { + NVME_LOG_ANA_LSP_RGO_NAMESPACES = 0, + NVME_LOG_ANA_LSP_RGO_GROUPS_ONLY = 1, +}; + +/** + * enum nvme_pevent_log_action - + */ +enum nvme_pevent_log_action { + NVME_PEVENT_LOG_READ = 0x0, + NVME_PEVENT_LOG_EST_CTX_AND_READ = 0x1, + NVME_PEVENT_LOG_RELEASE_CTX = 0x2, +}; + +/** + * enum nvme_feat_tmpthresh_thsel - + */ +enum nvme_feat_tmpthresh_thsel { + NVME_FEATURE_TEMPTHRESH_THSEL_OVER = 0, + NVME_FEATURE_TEMPTHRESH_THSEL_UNDER = 1, +}; + +/** + * enum nvme_features_async_event_config_flags - + */ +enum nvme_features_async_event_config_flags { + NVME_FEATURE_AENCFG_SMART_CRIT_SPARE = 1 << 0, + NVME_FEATURE_AENCFG_SMART_CRIT_TEMPERATURE = 1 << 1, + NVME_FEATURE_AENCFG_SMART_CRIT_DEGRADED = 1 << 2, + NVME_FEATURE_AENCFG_SMART_CRIT_READ_ONLY = 1 << 3, + NVME_FEATURE_AENCFG_SMART_CRIT_VOLATILE_BACKUP = 1 << 4, + NVME_FEATURE_AENCFG_SMART_CRIT_READ_ONLY_PMR = 1 << 5, + NVME_FEATURE_AENCFG_NOTICE_NAMESPACE_ATTRIBUTES = 1 << 8, + NVME_FEATURE_AENCFG_NOTICE_FIRMWARE_ACTIVATION = 1 << 9, + NVME_FEATURE_AENCFG_NOTICE_TELEMETRY_LOG = 1 << 10, + NVME_FEATURE_AENCFG_NOTICE_ANA_CHANGE = 1 << 11, + NVME_FEATURE_AENCFG_NOTICE_PL_EVENT = 1 << 12, + NVME_FEATURE_AENCFG_NOTICE_LBA_STATUS = 1 << 13, + NVME_FEATURE_AENCFG_NOTICE_EG_EVENT = 1 << 14, + NVME_FEATURE_AENCFG_NOTICE_DISCOVERY_CHANGE = 1 << 31, +}; + +/** + * enum nvme_feat_plm_window_select - + */ +enum nvme_feat_plm_window_select { + NVME_FEATURE_PLM_DTWIN = 1, + NVME_FEATURE_PLM_NDWIN = 2, +}; + +/** + * + */ +enum nvme_feat_resv_notify_flags { + NVME_FEAT_RESV_NOTIFY_REGPRE = 1 << 1, + NVME_FEAT_RESV_NOTIFY_RESREL = 1 << 2, + NVME_FEAT_RESV_NOTIFY_RESPRE = 1 << 3, +}; + +/** + * enum nvme_feat_ns_wp_cfg_state - + * @NVME_FEAT_NS_NO_WRITE_PROTECT: + * @NVME_FEAT_NS_WRITE_PROTECT: + * @NVME_FEAT_NS_WRITE_PROTECT_PWR_CYCLE: + * @NVME_FEAT_NS_WRITE_PROTECT_PERMANENT: + */ +enum nvme_feat_nswpcfg_state { + 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 - + * @nvme_fabrics_type_property_set: + * @nvme_fabrics_type_connect: + * @nvme_fabrics_type_property_get: + * @nvme_fabrics_type_auth_send: + * @nvme_fabrics_type_auth_receive: + * @nvme_fabrics_type_disconnect: + */ +enum nvme_fctype { + nvme_fabrics_type_property_set = 0x00, + nvme_fabrics_type_connect = 0x01, + nvme_fabrics_type_property_get = 0x04, + nvme_fabrics_type_auth_send = 0x05, + nvme_fabrics_type_auth_receive = 0x06, + nvme_fabrics_type_disconnect = 0x08, +}; + +/** + * enum nvme_io_opcode - + * @nvme_cmd_flush: + * @nvme_cmd_write: + * @nvme_cmd_read: + * @nvme_cmd_write_uncor: + * @nvme_cmd_compare: + * @nvme_cmd_write_zeroes: + * @nvme_cmd_dsm: + * @nvme_cmd_verify: + * @nvme_cmd_resv_register: + * @nvme_cmd_resv_report: + * @nvme_cmd_resv_acquire: + * @nvme_cmd_resv_release: + */ +enum nvme_io_opcode { + nvme_cmd_flush = 0x00, + nvme_cmd_write = 0x01, + nvme_cmd_read = 0x02, + nvme_cmd_write_uncor = 0x04, + nvme_cmd_compare = 0x05, + nvme_cmd_write_zeroes = 0x08, + nvme_cmd_dsm = 0x09, + nvme_cmd_verify = 0x0c, + nvme_cmd_resv_register = 0x0d, + nvme_cmd_resv_report = 0x0e, + nvme_cmd_resv_acquire = 0x11, + nvme_cmd_resv_release = 0x15, + nvme_cmd_copy = 0x19, + nvme_zns_cmd_mgmt_send = 0x79, + nvme_zns_cmd_mgmt_recv = 0x7a, + nvme_zns_cmd_append = 0x7d, +}; + +/** + * enum nvme_io_control_flags - + * @NVME_IO_DTYPE_STREAMS: + * @NVME_IO_DEAC: + * @NVME_IO_ZNS_APPEND_PIREMAP: + * @NVME_IO_PRINFO_PRCHK_REF: + * @NVME_IO_PRINFO_PRCHK_APP: + * @NVME_IO_PRINFO_PRCHK_GUARD: + * @NVME_IO_PRINFO_PRACT: + * @NVME_IO_FUA: + * @NVME_IO_LR: + */ +enum nvme_io_control_flags { + NVME_IO_DTYPE_STREAMS = 1 << 4, + NVME_IO_DEAC = 1 << 9, + NVME_IO_ZNS_APPEND_PIREMAP = 1 << 9, + NVME_IO_PRINFO_PRCHK_REF = 1 << 10, + NVME_IO_PRINFO_PRCHK_APP = 1 << 11, + NVME_IO_PRINFO_PRCHK_GUARD = 1 << 12, + NVME_IO_PRINFO_PRACT = 1 << 13, + NVME_IO_FUA = 1 << 14, + NVME_IO_LR = 1 << 15, +}; + +/** + * enum nvme_io_dsm_flag - + * @NVME_IO_DSM_FREQ_UNSPEC: + * @NVME_IO_DSM_FREQ_TYPICAL: + * @NVME_IO_DSM_FREQ_RARE: + * @NVME_IO_DSM_FREQ_READS: + * @NVME_IO_DSM_FREQ_WRITES: + * @NVME_IO_DSM_FREQ_RW: + * @NVME_IO_DSM_FREQ_ONCE: + * @NVME_IO_DSM_FREQ_PREFETCH: + * @NVME_IO_DSM_FREQ_TEMP: + * @NVME_IO_DSM_LATENCY_NONE: + * @NVME_IO_DSM_LATENCY_IDLE: + * @NVME_IO_DSM_LATENCY_NORM: + * @NVME_IO_DSM_LATENCY_LOW: + * @NVME_IO_DSM_SEQ_REQ: + * @NVME_IO_DSM_COMPRESSED: + */ +enum nvme_io_dsm_flags { + NVME_IO_DSM_FREQ_UNSPEC = 0, + NVME_IO_DSM_FREQ_TYPICAL = 1, + NVME_IO_DSM_FREQ_RARE = 2, + NVME_IO_DSM_FREQ_READS = 3, + NVME_IO_DSM_FREQ_WRITES = 4, + NVME_IO_DSM_FREQ_RW = 5, + NVME_IO_DSM_FREQ_ONCE = 6, + NVME_IO_DSM_FREQ_PREFETCH = 7, + NVME_IO_DSM_FREQ_TEMP = 8, + NVME_IO_DSM_LATENCY_NONE = 0 << 4, + NVME_IO_DSM_LATENCY_IDLE = 1 << 4, + NVME_IO_DSM_LATENCY_NORM = 2 << 4, + NVME_IO_DSM_LATENCY_LOW = 3 << 4, + NVME_IO_DSM_SEQ_REQ = 1 << 6, + NVME_IO_DSM_COMPRESSED = 1 << 7, +}; + +/** + * enum nvme_dsm_attributes - + * @NVME_DSMGMT_IDR: + * @NVME_DSMGMT_IDW: + * @NVME_DSMGMT_AD: + */ +enum nvme_dsm_attributes { + NVME_DSMGMT_IDR = 1 << 0, + NVME_DSMGMT_IDW = 1 << 1, + NVME_DSMGMT_AD = 1 << 2, +}; + +/** + * enum nvme_resv_rtype - + * @NVME_RESERVATION_RTYPE_WE: + * @NVME_RESERVATION_RTYPE_EA: + * @NVME_RESERVATION_RTYPE_WERO: + * @NVME_RESERVATION_RTYPE_EARO: + * @NVME_RESERVATION_RTYPE_WEAR: + * @NVME_RESERVATION_RTYPE_EAAR: + */ +enum nvme_resv_rtype { + NVME_RESERVATION_RTYPE_WE = 1, + NVME_RESERVATION_RTYPE_EA = 2, + NVME_RESERVATION_RTYPE_WERO = 3, + NVME_RESERVATION_RTYPE_EARO = 4, + NVME_RESERVATION_RTYPE_WEAR = 5, + NVME_RESERVATION_RTYPE_EAAR = 6, +}; + +/** + * enum nvme_resv_racqa - + * @NVME_RESERVATION_RACQA_ACQUIRE: + * @NVME_RESERVATION_RACQA_PREEMPT: + * @NVME_RESERVATION_RACQA_PREEMPT_AND_ABORT: + */ +enum nvme_resv_racqa { + NVME_RESERVATION_RACQA_ACQUIRE = 0, + NVME_RESERVATION_RACQA_PREEMPT = 1, + NVME_RESERVATION_RACQA_PREEMPT_AND_ABORT = 2, +}; + +/** + * enum nvme_resv_rrega - + * @NVME_RESERVATION_RREGA_REGISTER_KEY: + * @NVME_RESERVATION_RREGA_UNREGISTER_KEY: + * @NVME_RESERVATION_RREGA_REPLACE_KEY: + */ +enum nvme_resv_rrega { + NVME_RESERVATION_RREGA_REGISTER_KEY = 0, + NVME_RESERVATION_RREGA_UNREGISTER_KEY = 1, + NVME_RESERVATION_RREGA_REPLACE_KEY = 2, +}; + +/** + * enum nvme_resv_cptpl - + * @NVME_RESERVATION_CPTPL_NO_CHANGE: + * @NVME_RESERVATION_CPTPL_CLEAR: + * @NVME_RESERVATION_CPTPL_PERSIST: + */ +enum nvme_resv_cptpl { + NVME_RESERVATION_CPTPL_NO_CHANGE = 0, + NVME_RESERVATION_CPTPL_CLEAR = 2, + NVME_RESERVATION_CPTPL_PERSIST = 3, +}; + +/** + * enum nvme_resv_rrela - + * @NVME_RESERVATION_RRELA_RELEASE: + * @NVME_RESERVATION_RRELA_CLEAR: + */ +enum nvme_resv_rrela { + NVME_RESERVATION_RRELA_RELEASE = 0, + NVME_RESERVATION_RRELA_CLEAR = 1 +}; + +enum nvme_zns_send_action { + NVME_ZNS_ZSA_CLOSE = 0x1, + NVME_ZNS_ZSA_FINISH = 0x2, + NVME_ZNS_ZSA_OPEN = 0x3, + NVME_ZNS_ZSA_RESET = 0x4, + NVME_ZNS_ZSA_OFFLINE = 0x5, + NVME_ZNS_ZSA_SET_DESC_EXT = 0x10, +}; + +/** + * enum nvme_zns_recv_action - + */ +enum nvme_zns_recv_action { + NVME_ZNS_ZRA_REPORT_ZONES = 0x0, + NVME_ZNS_ZRA_EXTENDED_REPORT_ZONES = 0x1, +}; + +/** + * enum nvme_zns_report_options - + */ +enum nvme_zns_report_options { + NVME_ZNS_ZRAS_REPORT_ALL = 0x0, + NVME_ZNS_ZRAS_REPORT_EMPTY = 0x1, + NVME_ZNS_ZRAS_REPORT_IMPL_OPENED = 0x2, + NVME_ZNS_ZRAS_REPORT_EXPL_OPENED = 0x3, + NVME_ZNS_ZRAS_REPORT_CLOSED = 0x4, + NVME_ZNS_ZRAS_REPORT_FULL = 0x5, + NVME_ZNS_ZRAS_REPORT_READ_ONLY = 0x6, + NVME_ZNS_ZRAS_REPORT_OFFLINE = 0x7, +}; + #endif /* _LIBNVME_TYPES_H */ From eef02e052c35e604dc481d78d1343934f6cd530e Mon Sep 17 00:00:00 2001 From: Klaus Jensen Date: Mon, 18 Oct 2021 20:48:48 +0200 Subject: [PATCH 0208/1564] types: move the feature shift/masks from util.h Signed-off-by: Klaus Jensen --- src/nvme/types.h | 104 +++++++++++++++++++++++++++++++++++++++++++++++ src/nvme/util.h | 101 --------------------------------------------- 2 files changed, 104 insertions(+), 101 deletions(-) diff --git a/src/nvme/types.h b/src/nvme/types.h index f9ccbe1970..6b0b14716e 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -5023,6 +5023,110 @@ enum nvme_features_id { NVME_FEAT_FID_WRITE_PROTECT = 0x84, }; +/** + * enum nvme_feat - + */ +enum nvme_feat { + NVME_FEAT_ARBITRATION_BURST_SHIFT = 0, + NVME_FEAT_ARBITRATION_BURST_MASK = 0x7, + NVME_FEAT_ARBITRATION_LPW_SHIFT = 8, + NVME_FEAT_ARBITRATION_LPW_MASK = 0xff, + NVME_FEAT_ARBITRATION_MPW_SHIFT = 16, + NVME_FEAT_ARBITRATION_MPW_MASK = 0xff, + NVME_FEAT_ARBITRATION_HPW_SHIFT = 24, + NVME_FEAT_ARBITRATION_HPW_MASK = 0xff, + NVME_FEAT_PWRMGMT_PS_SHIFT = 0, + NVME_FEAT_PWRMGMT_PS_MASK = 0x1f, + NVME_FEAT_PWRMGMT_WH_SHIFT = 5, + NVME_FEAT_PWRMGMT_WH_MASK = 0x7, + NVME_FEAT_LBAR_NR_SHIFT = 0, + NVME_FEAT_LBAR_NR_MASK = 0x3f, + NVME_FEAT_TT_TMPTH_SHIFT = 0, + NVME_FEAT_TT_TMPTH_MASK = 0xffff, + NVME_FEAT_TT_TMPSEL_SHIFT = 16, + NVME_FEAT_TT_TMPSEL_MASK = 0xf, + NVME_FEAT_TT_THSEL_SHIFT = 20, + NVME_FEAT_TT_THSEL_MASK = 0x3, + NVME_FEAT_ERROR_RECOVERY_TLER_SHIFT = 0, + NVME_FEAT_ERROR_RECOVERY_TLER_MASK = 0xffff, + NVME_FEAT_ERROR_RECOVERY_DULBE_SHIFT = 16, + NVME_FEAT_ERROR_RECOVERY_DULBE_MASK = 0x1, + NVME_FEAT_VWC_WCE_SHIFT = 0, + NVME_FEAT_VWC_WCE_MASK = 0x1, + NVME_FEAT_NRQS_NSQR_SHIFT = 0, + NVME_FEAT_NRQS_NSQR_MASK = 0xffff, + NVME_FEAT_NRQS_NCQR_SHIFT = 16, + NVME_FEAT_NRQS_NCQR_MASK = 0xffff, + NVME_FEAT_IRQC_THR_SHIFT = 0, + NVME_FEAT_IRQC_THR_MASK = 0xff, + NVME_FEAT_IRQC_TIME_SHIFT = 8, + NVME_FEAT_IRQC_TIME_MASK = 0xff, + NVME_FEAT_ICFG_IV_SHIFT = 0, + NVME_FEAT_ICFG_IV_MASK = 0xffff, + NVME_FEAT_ICFG_CD_SHIFT = 16, + NVME_FEAT_ICFG_CD_MASK = 0x1, + NVME_FEAT_WA_DN_SHIFT = 0, + NVME_FEAT_WA_DN_MASK = 0x1, + NVME_FEAT_AE_SMART_SHIFT = 0, + NVME_FEAT_AE_SMART_MASK = 0xff, + NVME_FEAT_AE_NAN_SHIFT = 8, + NVME_FEAT_AE_NAN_MASK = 0x1, + NVME_FEAT_AE_FW_SHIFT = 9, + NVME_FEAT_AE_FW_MASK = 0x1, + NVME_FEAT_AE_TELEM_SHIFT = 10, + NVME_FEAT_AE_TELEM_MASK = 0x1, + NVME_FEAT_AE_ANA_SHIFT = 11, + NVME_FEAT_AE_ANA_MASK = 0x1, + NVME_FEAT_AE_PLA_SHIFT = 12, + NVME_FEAT_AE_PLA_MASK = 0x1, + NVME_FEAT_AE_LBAS_SHIFT = 13, + NVME_FEAT_AE_LBAS_MASK = 0x1, + NVME_FEAT_AE_EGA_SHIFT = 14, + NVME_FEAT_AE_EGA_MASK = 0x1, + NVME_FEAT_APST_APSTE_SHIFT = 0, + NVME_FEAT_APST_APSTE_MASK = 0x1, + NVME_FEAT_HMEM_EHM_SHIFT = 0, + NVME_FEAT_HMEM_EHM_MASK = 0x1, + NVME_FEAT_HCTM_TMT2_SHIFT = 0, + NVME_FEAT_HCTM_TMT2_MASK = 0xffff, + NVME_FEAT_HCTM_TMT1_SHIFT = 16, + NVME_FEAT_HCTM_TMT1_MASK = 0xffff, + NVME_FEAT_NOPS_NOPPME_SHIFT = 0, + NVME_FEAT_NOPS_NOPPME_MASK = 0x1, + NVME_FEAT_RRL_RRL_SHIFT = 0, + NVME_FEAT_RRL_RRL_MASK = 0xff, + NVME_FEAT_PLM_PLME_SHIFT = 0, + NVME_FEAT_PLM_PLME_MASK = 0x1, + NVME_FEAT_PLMW_WS_SHIFT = 0, + NVME_FEAT_PLMW_WS_MASK = 0x7, + NVME_FEAT_LBAS_LSIRI_SHIFT = 0, + NVME_FEAT_LBAS_LSIRI_MASK = 0xffff, + NVME_FEAT_LBAS_LSIPI_SHIFT = 16, + NVME_FEAT_LBAS_LSIPI_MASK = 0xffff, + NVME_FEAT_SC_NODRM_SHIFT = 0, + NVME_FEAT_SC_NODRM_MASK = 0x1, + NVME_FEAT_EG_ENDGID_SHIFT = 0, + NVME_FEAT_EG_ENDGID_MASK = 0xffff, + NVME_FEAT_EG_EGCW_SHIFT = 16, + NVME_FEAT_EG_EGCW_MASK = 0xff, + NVME_FEAT_SPM_PBSLC_SHIFT = 0, + NVME_FEAT_SPM_PBSLC_MASK = 0xff, + NVME_FEAT_HOSTID_EXHID_SHIFT = 0, + NVME_FEAT_HOSTID_EXHID_MASK = 0x1, + NVME_FEAT_RM_REGPRE_SHIFT = 1, + NVME_FEAT_RM_REGPRE_MASK = 0x1, + NVME_FEAT_RM_RESREL_SHIFT = 2, + NVME_FEAT_RM_RESREL_MASK = 0x1, + NVME_FEAT_RM_RESPRE_SHIFT = 0x3, + NVME_FEAT_RM_RESPRE_MASK = 0x1, + NVME_FEAT_RP_PTPL_SHIFT = 0, + NVME_FEAT_RP_PTPL_MASK = 0x1, + NVME_FEAT_WP_WPS_SHIFT = 0, + NVME_FEAT_WP_WPS_MASK = 0x7, + NVME_FEAT_IOCSP_IOCSCI_SHIFT = 0, + NVME_FEAT_IOCSP_IOCSCI_MASK = 0xff, +}; + /** * enum nvme_get_features_sel - * @NVME_GET_FEATURES_SEL_CURRENT: diff --git a/src/nvme/util.h b/src/nvme/util.h index f4b3b4095e..b84ccf7a1f 100644 --- a/src/nvme/util.h +++ b/src/nvme/util.h @@ -262,107 +262,6 @@ static inline void nvme_chomp(char *s, int l) s[l--] = '\0'; } -enum { - NVME_FEAT_ARBITRATION_BURST_SHIFT = 0, - NVME_FEAT_ARBITRATION_BURST_MASK = 0x7, - NVME_FEAT_ARBITRATION_LPW_SHIFT = 8, - NVME_FEAT_ARBITRATION_LPW_MASK = 0xff, - NVME_FEAT_ARBITRATION_MPW_SHIFT = 16, - NVME_FEAT_ARBITRATION_MPW_MASK = 0xff, - NVME_FEAT_ARBITRATION_HPW_SHIFT = 24, - NVME_FEAT_ARBITRATION_HPW_MASK = 0xff, - NVME_FEAT_PWRMGMT_PS_SHIFT = 0, - NVME_FEAT_PWRMGMT_PS_MASK = 0x1f, - NVME_FEAT_PWRMGMT_WH_SHIFT = 5, - NVME_FEAT_PWRMGMT_WH_MASK = 0x7, - NVME_FEAT_LBAR_NR_SHIFT = 0, - NVME_FEAT_LBAR_NR_MASK = 0x3f, - NVME_FEAT_TT_TMPTH_SHIFT = 0, - NVME_FEAT_TT_TMPTH_MASK = 0xffff, - NVME_FEAT_TT_TMPSEL_SHIFT = 16, - NVME_FEAT_TT_TMPSEL_MASK = 0xf, - NVME_FEAT_TT_THSEL_SHIFT = 20, - NVME_FEAT_TT_THSEL_MASK = 0x3, - NVME_FEAT_ERROR_RECOVERY_TLER_SHIFT = 0, - NVME_FEAT_ERROR_RECOVERY_TLER_MASK = 0xffff, - NVME_FEAT_ERROR_RECOVERY_DULBE_SHIFT = 16, - NVME_FEAT_ERROR_RECOVERY_DULBE_MASK = 0x1, - NVME_FEAT_VWC_WCE_SHIFT = 0, - NVME_FEAT_VWC_WCE_MASK = 0x1, - NVME_FEAT_NRQS_NSQR_SHIFT = 0, - NVME_FEAT_NRQS_NSQR_MASK = 0xffff, - NVME_FEAT_NRQS_NCQR_SHIFT = 16, - NVME_FEAT_NRQS_NCQR_MASK = 0xffff, - NVME_FEAT_IRQC_THR_SHIFT = 0, - NVME_FEAT_IRQC_THR_MASK = 0xff, - NVME_FEAT_IRQC_TIME_SHIFT = 8, - NVME_FEAT_IRQC_TIME_MASK = 0xff, - NVME_FEAT_ICFG_IV_SHIFT = 0, - NVME_FEAT_ICFG_IV_MASK = 0xffff, - NVME_FEAT_ICFG_CD_SHIFT = 16, - NVME_FEAT_ICFG_CD_MASK = 0x1, - NVME_FEAT_WA_DN_SHIFT = 0, - NVME_FEAT_WA_DN_MASK = 0x1, - NVME_FEAT_AE_SMART_SHIFT = 0, - NVME_FEAT_AE_SMART_MASK = 0xff, - NVME_FEAT_AE_NAN_SHIFT = 8, - NVME_FEAT_AE_NAN_MASK = 0x1, - NVME_FEAT_AE_FW_SHIFT = 9, - NVME_FEAT_AE_FW_MASK = 0x1, - NVME_FEAT_AE_TELEM_SHIFT = 10, - NVME_FEAT_AE_TELEM_MASK = 0x1, - NVME_FEAT_AE_ANA_SHIFT = 11, - NVME_FEAT_AE_ANA_MASK = 0x1, - NVME_FEAT_AE_PLA_SHIFT = 12, - NVME_FEAT_AE_PLA_MASK = 0x1, - NVME_FEAT_AE_LBAS_SHIFT = 13, - NVME_FEAT_AE_LBAS_MASK = 0x1, - NVME_FEAT_AE_EGA_SHIFT = 14, - NVME_FEAT_AE_EGA_MASK = 0x1, - NVME_FEAT_APST_APSTE_SHIFT = 0, - NVME_FEAT_APST_APSTE_MASK = 0x1, - NVME_FEAT_HMEM_EHM_SHIFT = 0, - NVME_FEAT_HMEM_EHM_MASK = 0x1, - NVME_FEAT_HCTM_TMT2_SHIFT = 0, - NVME_FEAT_HCTM_TMT2_MASK = 0xffff, - NVME_FEAT_HCTM_TMT1_SHIFT = 16, - NVME_FEAT_HCTM_TMT1_MASK = 0xffff, - NVME_FEAT_NOPS_NOPPME_SHIFT = 0, - NVME_FEAT_NOPS_NOPPME_MASK = 0x1, - NVME_FEAT_RRL_RRL_SHIFT = 0, - NVME_FEAT_RRL_RRL_MASK = 0xff, - NVME_FEAT_PLM_PLME_SHIFT = 0, - NVME_FEAT_PLM_PLME_MASK = 0x1, - NVME_FEAT_PLMW_WS_SHIFT = 0, - NVME_FEAT_PLMW_WS_MASK = 0x7, - NVME_FEAT_LBAS_LSIRI_SHIFT = 0, - NVME_FEAT_LBAS_LSIRI_MASK = 0xffff, - NVME_FEAT_LBAS_LSIPI_SHIFT = 16, - NVME_FEAT_LBAS_LSIPI_MASK = 0xffff, - NVME_FEAT_SC_NODRM_SHIFT = 0, - NVME_FEAT_SC_NODRM_MASK = 0x1, - NVME_FEAT_EG_ENDGID_SHIFT = 0, - NVME_FEAT_EG_ENDGID_MASK = 0xffff, - NVME_FEAT_EG_EGCW_SHIFT = 16, - NVME_FEAT_EG_EGCW_MASK = 0xff, - NVME_FEAT_SPM_PBSLC_SHIFT = 0, - NVME_FEAT_SPM_PBSLC_MASK = 0xff, - NVME_FEAT_HOSTID_EXHID_SHIFT = 0, - NVME_FEAT_HOSTID_EXHID_MASK = 0x1, - NVME_FEAT_RM_REGPRE_SHIFT = 1, - NVME_FEAT_RM_REGPRE_MASK = 0x1, - NVME_FEAT_RM_RESREL_SHIFT = 2, - NVME_FEAT_RM_RESREL_MASK = 0x1, - NVME_FEAT_RM_RESPRE_SHIFT = 0x3, - NVME_FEAT_RM_RESPRE_MASK = 0x1, - NVME_FEAT_RP_PTPL_SHIFT = 0, - NVME_FEAT_RP_PTPL_MASK = 0x1, - NVME_FEAT_WP_WPS_SHIFT = 0, - NVME_FEAT_WP_WPS_MASK = 0x7, - NVME_FEAT_IOCSP_IOCSCI_SHIFT = 0, - NVME_FEAT_IOCSP_IOCSCI_MASK = 0xff, -}; - #define NVME_FEAT_ARB_BURST(v) NVME_GET(v, FEAT_ARBITRATION_BURST) #define NVME_FEAT_ARB_LPW(v) NVME_GET(v, FEAT_ARBITRATION_LPW) #define NVME_FEAT_ARB_MPW(v) NVME_GET(v, FEAT_ARBITRATION_MPW) From 018e4af269b52f6ea7f8d6321ce19a57c59f0d9e Mon Sep 17 00:00:00 2001 From: Klaus Jensen Date: Wed, 29 Sep 2021 20:20:23 +0200 Subject: [PATCH 0209/1564] linux: move linux specific stuff from util.{c,h} Add the nvme/linux.h header for Linux specific helpers. This leaves util.{c,h} with only system-agnostic utilities. Signed-off-by: Klaus Jensen --- src/Makefile | 4 +- src/libnvme.h | 1 + src/meson.build | 1 + src/nvme/fabrics.c | 1 + src/nvme/fabrics.h | 11 ++ src/nvme/linux.c | 382 +++++++++++++++++++++++++++++++++++++++++++++ src/nvme/linux.h | 156 ++++++++++++++++++ src/nvme/tree.c | 1 + src/nvme/util.c | 372 ------------------------------------------- src/nvme/util.h | 155 +----------------- 10 files changed, 556 insertions(+), 528 deletions(-) create mode 100644 src/nvme/linux.c create mode 100644 src/nvme/linux.h diff --git a/src/Makefile b/src/Makefile index 2f269e4343..23372b0b3e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -48,8 +48,8 @@ libccan_sobjs := $(patsubst %.c,%.os,$(libccan_srcs)) $(libccan_objs) $(libccan_sobjs): $(libccan_headers) $(CCANDIR)config.h libnvme_priv := nvme/private.h -libnvme_api := libnvme.h nvme/types.h nvme/ioctl.h nvme/filters.h nvme/tree.h nvme/util.h nvme/fabrics.h nvme/log.h -libnvme_srcs := nvme/ioctl.c nvme/filters.c nvme/fabrics.c nvme/util.c nvme/tree.c nvme/log.c nvme/cleanup.c +libnvme_api := libnvme.h nvme/types.h nvme/linux.h nvme/ioctl.h nvme/filters.h nvme/tree.h nvme/util.h nvme/fabrics.h nvme/log.h +libnvme_srcs := nvme/linux.c nvme/ioctl.c nvme/filters.c nvme/fabrics.c nvme/util.c nvme/tree.c nvme/log.c nvme/cleanup.c ifeq ($(CONFIG_JSONC),y) override LDFLAGS += $(shell pkg-config --libs json-c) override CFLAGS += $(shell pkg-config --cflags json-c) diff --git a/src/libnvme.h b/src/libnvme.h index 00b1211e70..6be9058122 100644 --- a/src/libnvme.h +++ b/src/libnvme.h @@ -15,6 +15,7 @@ extern "C" { #endif #include "nvme/types.h" +#include "nvme/linux.h" #include "nvme/ioctl.h" #include "nvme/fabrics.h" #include "nvme/filters.h" diff --git a/src/meson.build b/src/meson.build index 2b8fa63896..10acb15ea9 100644 --- a/src/meson.build +++ b/src/meson.build @@ -10,6 +10,7 @@ sources = [ 'nvme/fabrics.c', 'nvme/filters.c', 'nvme/ioctl.c', + 'nvme/linux.c', 'nvme/log.c', 'nvme/tree.c', 'nvme/util.c', diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 21dec686f4..d96f09e97e 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -29,6 +29,7 @@ #include #include "fabrics.h" +#include "linux.h" #include "ioctl.h" #include "util.h" #include "log.h" diff --git a/src/nvme/fabrics.h b/src/nvme/fabrics.h index 10ac2e29a5..9b796be545 100644 --- a/src/nvme/fabrics.h +++ b/src/nvme/fabrics.h @@ -182,4 +182,15 @@ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, struct nvmf_disc_log_entry *e, const struct nvme_fabrics_config *defcfg, bool *discover); +/** + * nvme_chomp() - Strip trailing white space + * &s: String to strip + * @l: Maximum length of string + */ +static inline void nvme_chomp(char *s, int l) +{ + while (l && (s[l] == '\0' || s[l] == ' ')) + s[l--] = '\0'; +} + #endif /* _LIBNVME_FABRICS_H */ diff --git a/src/nvme/linux.c b/src/nvme/linux.c new file mode 100644 index 0000000000..90b9b5cef7 --- /dev/null +++ b/src/nvme/linux.c @@ -0,0 +1,382 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/* + * This file is part of libnvme. + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + * + * Authors: Keith Busch + * Chaitanya Kulkarni + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "linux.h" +#include "tree.h" +#include "log.h" + +static int __nvme_open(const char *name) +{ + char *path; + int fd, ret; + + ret = asprintf(&path, "%s/%s", "/dev", name); + if (ret < 0) { + errno = ENOMEM; + return -1; + } + + fd = open(path, O_RDONLY); + free(path); + return fd; +} + +int nvme_open(const char *name) +{ + int ret, fd, id, ns; + struct stat stat; + bool c; + + ret = sscanf(name, "nvme%dn%d", &id, &ns); + if (ret != 1 && ret != 2) { + errno = EINVAL; + return -1; + } + c = ret == 1; + + fd = __nvme_open(name); + if (fd < 0) + return fd; + + ret = fstat(fd, &stat); + if (ret < 0) + goto close_fd; + + if (c) { + if (!S_ISCHR(stat.st_mode)) { + errno = EINVAL; + goto close_fd; + } + } else if (!S_ISBLK(stat.st_mode)) { + errno = EINVAL; + goto close_fd; + } + + return fd; + +close_fd: + close(fd); + return -1; +} + +int nvme_fw_download_seq(int fd, __u32 size, __u32 xfer, __u32 offset, + void *buf) +{ + int err = 0; + + while (size > 0) { + xfer = MIN(xfer, size); + err = nvme_fw_download(fd, offset, xfer, buf); + if (err) + break; + + buf += xfer; + size -= xfer; + offset += xfer; + } + + return err; +} + +int __nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, + __u32 xfer_len, __u32 data_len, void *data) +{ + __u64 offset = 0, xfer; + bool retain = true; + void *ptr = data; + int ret; + + /* + * 4k is the smallest possible transfer unit, so restricting to 4k + * avoids having to check the MDTS value of the controller. + */ + do { + xfer = data_len - offset; + if (xfer > xfer_len) + xfer = xfer_len; + + /* + * Always retain regardless of the RAE parameter until the very + * last portion of this log page so the data remains latched + * during the fetch sequence. + */ + if (offset + xfer == data_len) + retain = rae; + + ret = nvme_get_log(fd, log_id, nsid, offset, NVME_LOG_LSP_NONE, + NVME_LOG_LSI_NONE, retain, NVME_UUID_NONE, + NVME_CSI_NVM, xfer, ptr); + if (ret) + return ret; + + offset += xfer; + ptr += xfer; + } while (offset < data_len); + + return 0; +} + +int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, + __u32 data_len, void *data) +{ + return __nvme_get_log_page(fd, nsid, log_id, rae, 4096, data_len, data); +} + +static int nvme_get_telemetry_log(int fd, bool create, bool ctrl, bool rae, + struct nvme_telemetry_log **buf) +{ + static const __u32 xfer = NVME_LOG_TELEM_BLOCK_SIZE; + + struct nvme_telemetry_log *telem; + enum nvme_cmd_get_log_lid lid; + void *log, *tmp; + __u32 size; + int err; + + log = malloc(xfer); + if (!log) { + errno = ENOMEM; + return -1; + } + + if (ctrl) { + err = nvme_get_log_telemetry_ctrl(fd, true, 0, xfer, log); + lid = NVME_LOG_LID_TELEMETRY_CTRL; + } else { + lid = NVME_LOG_LID_TELEMETRY_HOST; + if (create) + err = nvme_get_log_create_telemetry_host(fd, log); + else + err = nvme_get_log_telemetry_host(fd, 0, xfer, log); + } + + if (err) + goto free; + + telem = log; + if (ctrl && !telem->ctrlavail) { + *buf = log; + return 0; + } + + /* dalb3 >= dalb2 >= dalb1 */ + size = (le16_to_cpu(telem->dalb3) + 1) * xfer; + tmp = realloc(log, size); + if (!tmp) { + errno = ENOMEM; + err = -1; + goto free; + } + log = tmp; + + err = nvme_get_log_page(fd, NVME_NSID_NONE, lid, rae, size, (void *)log); + if (!err) { + *buf = log; + return 0; + } +free: + free(log); + return err; +} + +int nvme_get_ctrl_telemetry(int fd, bool rae, struct nvme_telemetry_log **log) +{ + return nvme_get_telemetry_log(fd, false, true, rae, log); +} + +int nvme_get_host_telemetry(int fd, struct nvme_telemetry_log **log) +{ + return nvme_get_telemetry_log(fd, false, false, false, log); +} + +int nvme_get_new_host_telemetry(int fd, struct nvme_telemetry_log **log) +{ + return nvme_get_telemetry_log(fd, true, false, false, log); +} + +int nvme_get_lba_status_log(int fd, bool rae, struct nvme_lba_status_log **log) +{ + __u32 size = sizeof(struct nvme_lba_status_log); + void *buf, *tmp; + int err; + + buf = malloc(size); + if (!buf) + return -1; + + *log = buf; + err = nvme_get_log_lba_status(fd, true, 0, size, buf); + if (err) + goto free; + + size = le32_to_cpu((*log)->lslplen); + if (!size) + return 0; + + tmp = realloc(buf, size); + if (!tmp) { + err = -1; + goto free; + } + buf = tmp; + *log = buf; + + err = nvme_get_log_page(fd, NVME_NSID_NONE, NVME_LOG_LID_LBA_STATUS, + rae, size, buf); + if (!err) + return 0; + +free: + *log = NULL; + free(buf); + return err; +} + +static int nvme_ns_attachment(int fd, __u32 nsid, __u16 num_ctrls, + __u16 *ctrlist, bool attach) +{ + enum nvme_ns_attach_sel sel = NVME_NS_ATTACH_SEL_CTRL_DEATTACH; + struct nvme_ctrl_list cntlist = { 0 }; + + if (attach) + sel = NVME_NS_ATTACH_SEL_CTRL_ATTACH; + + nvme_init_ctrl_list(&cntlist, num_ctrls, ctrlist); + return nvme_ns_attach(fd, nsid, sel, &cntlist); +} + +int nvme_namespace_attach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, + __u16 *ctrlist) +{ + return nvme_ns_attachment(fd, nsid, num_ctrls, ctrlist, true); +} + +int nvme_namespace_detach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, + __u16 *ctrlist) +{ + return nvme_ns_attachment(fd, nsid, num_ctrls, ctrlist, false); +} + +int nvme_get_ana_log_len(int fd, size_t *analen) +{ + struct nvme_id_ctrl ctrl; + int ret; + + ret = nvme_identify_ctrl(fd, &ctrl); + if (ret) + return ret; + + *analen = sizeof(struct nvme_ana_log) + + le32_to_cpu(ctrl.nanagrpid) * sizeof(struct nvme_ana_group_desc) + + le32_to_cpu(ctrl.mnan) * sizeof(__le32); + return 0; +} + +static int __nvme_set_attr(const char *path, const char *value) +{ + int ret, fd; + + fd = open(path, O_WRONLY); + if (fd < 0) { +#if 0 + nvme_msg(LOG_DEBUG, "Failed to open %s: %s\n", path, + strerror(errno)); +#endif + return -1; + } + ret = write(fd, value, strlen(value)); + close(fd); + return ret; +} + +int nvme_set_attr(const char *dir, const char *attr, const char *value) +{ + char *path; + int ret; + + ret = asprintf(&path, "%s/%s", dir, attr); + if (ret < 0) + return -1; + + ret = __nvme_set_attr(path, value); + free(path); + return ret; +} + +static char *__nvme_get_attr(const char *path) +{ + char value[4096] = { 0 }; + int ret, fd; + + fd = open(path, O_RDONLY); + if (fd < 0) { +#if 0 + nvme_msg(LOG_DEBUG, "Failed to open %s: %s\n", path, + strerror(errno)); +#endif + return NULL; + } + + ret = read(fd, value, sizeof(value) - 1); + close(fd); + if (ret < 0 || !strlen(value)) { + return NULL; + } + + if (value[strlen(value) - 1] == '\n') + value[strlen(value) - 1] = '\0'; + while (strlen(value) > 0 && value[strlen(value) - 1] == ' ') + value[strlen(value) - 1] = '\0'; + + return strlen(value) ? strdup(value) : NULL; +} + +char *nvme_get_attr(const char *dir, const char *attr) +{ + char *path, *value; + int ret; + + ret = asprintf(&path, "%s/%s", dir, attr); + if (ret < 0) + return NULL; + + value = __nvme_get_attr(path); + free(path); + return value; +} + +char *nvme_get_subsys_attr(nvme_subsystem_t s, const char *attr) +{ + return nvme_get_attr(nvme_subsystem_get_sysfs_dir(s), attr); +} + +char *nvme_get_ctrl_attr(nvme_ctrl_t c, const char *attr) +{ + return nvme_get_attr(nvme_ctrl_get_sysfs_dir(c), attr); +} + +char *nvme_get_ns_attr(nvme_ns_t n, const char *attr) +{ + return nvme_get_attr(nvme_ns_get_sysfs_dir(n), attr); +} + +char *nvme_get_path_attr(nvme_path_t p, const char *attr) +{ + return nvme_get_attr(nvme_path_get_sysfs_dir(p), attr); +} diff --git a/src/nvme/linux.h b/src/nvme/linux.h new file mode 100644 index 0000000000..2a751a1325 --- /dev/null +++ b/src/nvme/linux.h @@ -0,0 +1,156 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/* + * This file is part of libnvme. + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + * + * Authors: Keith Busch + * Chaitanya Kulkarni + */ +#ifndef _LIBNVME_LINUX_H +#define _LIBNVME_LINUX_H + +#include "types.h" + +/** + * nvme_fw_download_seq() - + * @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 + * @buf: Address of buffer containing all or part of the firmware image. + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_fw_download_seq(int fd, __u32 size, __u32 xfer, __u32 offset, + void *buf); + +/** + * nvme_get_ctrl_telemetry() - + * @fd: File descriptor of nvme device + * @rae: Retain asynchronous events + * @log: On success, set to the value of the allocated and retreived log. + * + * The total size allocated can be calculated as: + * (&struct nvme_telemetry_log.dalb3 + 1) * %NVME_LOG_TELEM_BLOCK_SIZE. + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_get_ctrl_telemetry(int fd, bool rae, struct nvme_telemetry_log **log); + +/** + * nvme_get_host_telemetry() - + * @fd: File descriptor of nvme device + * @log: On success, set to the value of the allocated and retreived log. + * + * The total size allocated can be calculated as: + * (&struct nvme_telemetry_log.dalb3 + 1) * %NVME_LOG_TELEM_BLOCK_SIZE. + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_get_host_telemetry(int fd, struct nvme_telemetry_log **log); + +/** + * nvme_get_new_host_telemetry() - + * @fd: File descriptor of nvme device + * @log: On success, set to the value of the allocated and retreived log. + * + * The total size allocated can be calculated as: + * (&struct nvme_telemetry_log.dalb3 + 1) * %NVME_LOG_TELEM_BLOCK_SIZE. + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_get_new_host_telemetry(int fd, struct nvme_telemetry_log **log); + +/** + * __nvme_get_log_page() - + * @fd: File descriptor of nvme device + * @nsid: Namespace Identifier, if applicable. + * @log_id: Log Identifier, see &enum nvme_cmd_get_log_lid. + * @rae: Retain asynchronous events + * @xfer_len: Max log transfer size per request to split the total. + * @data_len: Total length of the log to transfer. + * @data: User address of at least &data_len to store the log. + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int __nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, + __u32 xfer_len, __u32 data_len, void *data); + +/** + * nvme_get_log_page() - + * @fd: File descriptor of nvme device + * @nsid: Namespace Identifier, if applicable. + * @log_id: Log Identifier, see &enum nvme_cmd_get_log_lid. + * @rae: Retain asynchronous events + * @data_len: Total length of the log to transfer. + * @data: User address of at least &data_len to store the log. + * + * Calls __nvme_get_log_page() with a default 4k transfer length, as that is + * guarnateed by the protocol to be a safe transfer size. + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, + __u32 data_len, void *data); + +/** + * nvme_get_ana_log_len() - Retreive size of the current ANA log + * @fd: File descriptor of nvme device + * @analen: Pointer to where the length will be set on success + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_get_ana_log_len(int fd, size_t *analen); + +/** + * nvme_get_lba_status_log() - Retreive 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. + */ +int nvme_get_lba_status_log(int fd, bool rae, struct nvme_lba_status_log **log); + +/** + * nvme_namespace_attach_ctrls() - Attach namespace to controller(s) + * @fd: File descriptor of nvme device + * @nsid: Namespace ID to attach + * @num_ctrls: Number of controllers in ctrlist + * @ctrlist: List of controller IDs to perform the attach action + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_namespace_attach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist); + +/** + * nvme_namespace_detach_ctrls() - Detach namespace from controller(s) + * @fd: File descriptor of nvme device + * @nsid: Namespace ID to detach + * @num_ctrls: Number of controllers in ctrlist + * @ctrlist: List of controller IDs to perform the detach action + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_namespace_detach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist); + +/** + * nvme_open() - Open an nvme controller or namespace device + * @name: The basename of the device to open + * + * This will look for the handle in /dev/ and validate the name and filetype + * match linux conventions. + * + * Return: A file descriptor for the device on a successful open, or -1 with + * errno set otherwise. + */ +int nvme_open(const char *name); + +#endif /* _LIBNVME_LINUX_H */ diff --git a/src/nvme/tree.c b/src/nvme/tree.c index fb724c9d24..552496d800 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -23,6 +23,7 @@ #include #include "ioctl.h" +#include "linux.h" #include "filters.h" #include "tree.h" #include "filters.h" diff --git a/src/nvme/util.c b/src/nvme/util.c index bd82add218..3fd78490fa 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -7,24 +7,12 @@ * Chaitanya Kulkarni */ -#include -#include -#include #include #include -#include -#include -#include -#include #include -#include -#include -#include "filters.h" #include "util.h" -#include "tree.h" -#include "log.h" static inline __u8 nvme_generic_status_to_errno(__u16 status) { @@ -346,233 +334,6 @@ const char *nvme_status_to_string(int status, bool fabrics) return s; } -static int __nvme_open(const char *name) -{ - char *path; - int fd, ret; - - ret = asprintf(&path, "%s/%s", "/dev", name); - if (ret < 0) { - errno = ENOMEM; - return -1; - } - - fd = open(path, O_RDONLY); - free(path); - return fd; -} - -int nvme_open(const char *name) -{ - int ret, fd, id, ns; - struct stat stat; - bool c; - - ret = sscanf(name, "nvme%dn%d", &id, &ns); - if (ret != 1 && ret != 2) { - errno = EINVAL; - return -1; - } - c = ret == 1; - - fd = __nvme_open(name); - if (fd < 0) - return fd; - - ret = fstat(fd, &stat); - if (ret < 0) - goto close_fd; - - if (c) { - if (!S_ISCHR(stat.st_mode)) { - errno = EINVAL; - goto close_fd; - } - } else if (!S_ISBLK(stat.st_mode)) { - errno = EINVAL; - goto close_fd; - } - - return fd; - -close_fd: - close(fd); - return -1; -} - -int nvme_fw_download_seq(int fd, __u32 size, __u32 xfer, __u32 offset, - void *buf) -{ - int err = 0; - - while (size > 0) { - xfer = MIN(xfer, size); - err = nvme_fw_download(fd, offset, xfer, buf); - if (err) - break; - - buf += xfer; - size -= xfer; - offset += xfer; - } - - return err; -} - -int __nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, - __u32 xfer_len, __u32 data_len, void *data) -{ - __u64 offset = 0, xfer; - bool retain = true; - void *ptr = data; - int ret; - - /* - * 4k is the smallest possible transfer unit, so restricting to 4k - * avoids having to check the MDTS value of the controller. - */ - do { - xfer = data_len - offset; - if (xfer > xfer_len) - xfer = xfer_len; - - /* - * Always retain regardless of the RAE parameter until the very - * last portion of this log page so the data remains latched - * during the fetch sequence. - */ - if (offset + xfer == data_len) - retain = rae; - - ret = nvme_get_log(fd, log_id, nsid, offset, NVME_LOG_LSP_NONE, - NVME_LOG_LSI_NONE, retain, NVME_UUID_NONE, - NVME_CSI_NVM, xfer, ptr); - if (ret) - return ret; - - offset += xfer; - ptr += xfer; - } while (offset < data_len); - - return 0; -} - -int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, - __u32 data_len, void *data) -{ - return __nvme_get_log_page(fd, nsid, log_id, rae, 4096, data_len, data); -} - -static int nvme_get_telemetry_log(int fd, bool create, bool ctrl, bool rae, - struct nvme_telemetry_log **buf) -{ - static const __u32 xfer = NVME_LOG_TELEM_BLOCK_SIZE; - - struct nvme_telemetry_log *telem; - enum nvme_cmd_get_log_lid lid; - void *log, *tmp; - __u32 size; - int err; - - log = malloc(xfer); - if (!log) { - errno = ENOMEM; - return -1; - } - - if (ctrl) { - err = nvme_get_log_telemetry_ctrl(fd, true, 0, xfer, log); - lid = NVME_LOG_LID_TELEMETRY_CTRL; - } else { - lid = NVME_LOG_LID_TELEMETRY_HOST; - if (create) - err = nvme_get_log_create_telemetry_host(fd, log); - else - err = nvme_get_log_telemetry_host(fd, 0, xfer, log); - } - - if (err) - goto free; - - telem = log; - if (ctrl && !telem->ctrlavail) { - *buf = log; - return 0; - } - - /* dalb3 >= dalb2 >= dalb1 */ - size = (le16_to_cpu(telem->dalb3) + 1) * xfer; - tmp = realloc(log, size); - if (!tmp) { - errno = ENOMEM; - err = -1; - goto free; - } - log = tmp; - - err = nvme_get_log_page(fd, NVME_NSID_NONE, lid, rae, size, (void *)log); - if (!err) { - *buf = log; - return 0; - } -free: - free(log); - return err; -} - -int nvme_get_ctrl_telemetry(int fd, bool rae, struct nvme_telemetry_log **log) -{ - return nvme_get_telemetry_log(fd, false, true, rae, log); -} - -int nvme_get_host_telemetry(int fd, struct nvme_telemetry_log **log) -{ - return nvme_get_telemetry_log(fd, false, false, false, log); -} - -int nvme_get_new_host_telemetry(int fd, struct nvme_telemetry_log **log) -{ - return nvme_get_telemetry_log(fd, true, false, false, log); -} - -int nvme_get_lba_status_log(int fd, bool rae, struct nvme_lba_status_log **log) -{ - __u32 size = sizeof(struct nvme_lba_status_log); - void *buf, *tmp; - int err; - - buf = malloc(size); - if (!buf) - return -1; - - *log = buf; - err = nvme_get_log_lba_status(fd, true, 0, size, buf); - if (err) - goto free; - - size = le32_to_cpu((*log)->lslplen); - if (!size) - return 0; - - tmp = realloc(buf, size); - if (!tmp) { - err = -1; - goto free; - } - buf = tmp; - *log = buf; - - err = nvme_get_log_page(fd, NVME_NSID_NONE, NVME_LOG_LID_LBA_STATUS, - rae, size, buf); - if (!err) - return 0; - -free: - *log = NULL; - free(buf); - return err; -} - void nvme_init_copy_range(struct nvme_copy_range *copy, __u16 *nlbs, __u64 *slbas, __u32 *eilbrts, __u32 *elbatms, __u32 *elbats, __u16 nr) @@ -623,46 +384,6 @@ void nvme_init_ctrl_list(struct nvme_ctrl_list *cntlist, __u16 num_ctrls, cntlist->identifier[i] = cpu_to_le16(ctrlist[i]); } -static int nvme_ns_attachment(int fd, __u32 nsid, __u16 num_ctrls, - __u16 *ctrlist, bool attach) -{ - enum nvme_ns_attach_sel sel = NVME_NS_ATTACH_SEL_CTRL_DEATTACH; - struct nvme_ctrl_list cntlist = { 0 }; - - if (attach) - sel = NVME_NS_ATTACH_SEL_CTRL_ATTACH; - - nvme_init_ctrl_list(&cntlist, num_ctrls, ctrlist); - return nvme_ns_attach(fd, nsid, sel, &cntlist); -} - -int nvme_namespace_attach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, - __u16 *ctrlist) -{ - return nvme_ns_attachment(fd, nsid, num_ctrls, ctrlist, true); -} - -int nvme_namespace_detach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, - __u16 *ctrlist) -{ - return nvme_ns_attachment(fd, nsid, num_ctrls, ctrlist, false); -} - -int nvme_get_ana_log_len(int fd, size_t *analen) -{ - struct nvme_id_ctrl ctrl; - int ret; - - ret = nvme_identify_ctrl(fd, &ctrl); - if (ret) - return ret; - - *analen = sizeof(struct nvme_ana_log) + - le32_to_cpu(ctrl.nanagrpid) * sizeof(struct nvme_ana_group_desc) + - le32_to_cpu(ctrl.mnan) * sizeof(__le32); - return 0; -} - int nvme_get_feature_length(int fid, __u32 cdw11, __u32 *len) { switch (fid) { @@ -747,96 +468,3 @@ int nvme_get_directive_receive_length(enum nvme_directive_dtype dtype, return -EINVAL; } } - -static int __nvme_set_attr(const char *path, const char *value) -{ - int ret, fd; - - fd = open(path, O_WRONLY); - if (fd < 0) { -#if 0 - nvme_msg(LOG_DEBUG, "Failed to open %s: %s\n", path, - strerror(errno)); -#endif - return -1; - } - ret = write(fd, value, strlen(value)); - close(fd); - return ret; -} - -int nvme_set_attr(const char *dir, const char *attr, const char *value) -{ - char *path; - int ret; - - ret = asprintf(&path, "%s/%s", dir, attr); - if (ret < 0) - return -1; - - ret = __nvme_set_attr(path, value); - free(path); - return ret; -} - -static char *__nvme_get_attr(const char *path) -{ - char value[4096] = { 0 }; - int ret, fd; - - fd = open(path, O_RDONLY); - if (fd < 0) { -#if 0 - nvme_msg(LOG_DEBUG, "Failed to open %s: %s\n", path, - strerror(errno)); -#endif - return NULL; - } - - ret = read(fd, value, sizeof(value) - 1); - close(fd); - if (ret < 0 || !strlen(value)) { - return NULL; - } - - if (value[strlen(value) - 1] == '\n') - value[strlen(value) - 1] = '\0'; - while (strlen(value) > 0 && value[strlen(value) - 1] == ' ') - value[strlen(value) - 1] = '\0'; - - return strlen(value) ? strdup(value) : NULL; -} - -char *nvme_get_attr(const char *dir, const char *attr) -{ - char *path, *value; - int ret; - - ret = asprintf(&path, "%s/%s", dir, attr); - if (ret < 0) - return NULL; - - value = __nvme_get_attr(path); - free(path); - return value; -} - -char *nvme_get_subsys_attr(nvme_subsystem_t s, const char *attr) -{ - return nvme_get_attr(nvme_subsystem_get_sysfs_dir(s), attr); -} - -char *nvme_get_ctrl_attr(nvme_ctrl_t c, const char *attr) -{ - return nvme_get_attr(nvme_ctrl_get_sysfs_dir(c), attr); -} - -char *nvme_get_ns_attr(nvme_ns_t n, const char *attr) -{ - return nvme_get_attr(nvme_ns_get_sysfs_dir(n), attr); -} - -char *nvme_get_path_attr(nvme_path_t p, const char *attr) -{ - return nvme_get_attr(nvme_path_get_sysfs_dir(p), attr); -} diff --git a/src/nvme/util.h b/src/nvme/util.h index b84ccf7a1f..801189558a 100644 --- a/src/nvme/util.h +++ b/src/nvme/util.h @@ -9,7 +9,7 @@ #ifndef _LIBNVME_UTIL_H #define _LIBNVME_UTIL_H -#include "ioctl.h" +#include "types.h" /** * nvme_status_to_errno() - Converts nvme return status to errno @@ -31,60 +31,6 @@ __u8 nvme_status_to_errno(int status, bool fabrics); */ const char *nvme_status_to_string(int status, bool fabrics); -/** - * nvme_fw_download_seq() - - * @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 - * @buf: Address of buffer containing all or part of the firmware image. - * - * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. - */ -int nvme_fw_download_seq(int fd, __u32 size, __u32 xfer, __u32 offset, - void *buf); - -/** - * nvme_get_ctrl_telemetry() - - * @fd: File descriptor of nvme device - * @rae: Retain asynchronous events - * @log: On success, set to the value of the allocated and retreived log. - * - * The total size allocated can be calculated as: - * (&struct nvme_telemetry_log.dalb3 + 1) * %NVME_LOG_TELEM_BLOCK_SIZE. - * - * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. - */ -int nvme_get_ctrl_telemetry(int fd, bool rae, struct nvme_telemetry_log **log); - -/** - * nvme_get_host_telemetry() - - * @fd: File descriptor of nvme device - * @log: On success, set to the value of the allocated and retreived log. - * - * The total size allocated can be calculated as: - * (&struct nvme_telemetry_log.dalb3 + 1) * %NVME_LOG_TELEM_BLOCK_SIZE. - * - * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. - */ -int nvme_get_host_telemetry(int fd, struct nvme_telemetry_log **log); - -/** - * nvme_get_new_host_telemetry() - - * @fd: File descriptor of nvme device - * @log: On success, set to the value of the allocated and retreived log. - * - * The total size allocated can be calculated as: - * (&struct nvme_telemetry_log.dalb3 + 1) * %NVME_LOG_TELEM_BLOCK_SIZE. - * - * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. - */ -int nvme_get_new_host_telemetry(int fd, struct nvme_telemetry_log **log); - /** * nvme_init_id_ns() - Initialize an Identify Namepsace structure for creation. * @ns: Address of the Identify Namespace structure to initialize @@ -138,82 +84,6 @@ void nvme_init_copy_range(struct nvme_copy_range *copy, __u16 *nlbs, __u64 *slbas, __u32 *eilbrts, __u32 *elbatms, __u32 *elbats, __u16 nr); -/** - * __nvme_get_log_page() - - * @fd: File descriptor of nvme device - * @nsid: Namespace Identifier, if applicable. - * @log_id: Log Identifier, see &enum nvme_cmd_get_log_lid. - * @rae: Retain asynchronous events - * @xfer_len: Max log transfer size per request to split the total. - * @data_len: Total length of the log to transfer. - * @data: User address of at least &data_len to store the log. - * - * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. - */ -int __nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, - __u32 xfer_len, __u32 data_len, void *data); - -/** - * nvme_get_log_page() - - * @fd: File descriptor of nvme device - * @nsid: Namespace Identifier, if applicable. - * @log_id: Log Identifier, see &enum nvme_cmd_get_log_lid. - * @rae: Retain asynchronous events - * @data_len: Total length of the log to transfer. - * @data: User address of at least &data_len to store the log. - * - * Calls __nvme_get_log_page() with a default 4k transfer length, as that is - * guarnateed by the protocol to be a safe transfer size. - * - * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. - */ -int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, - __u32 data_len, void *data); - -/** - * nvme_get_ana_log_len() - Retreive size of the current ANA log - * @fd: File descriptor of nvme device - * @analen: Pointer to where the length will be set on success - * - * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. - */ -int nvme_get_ana_log_len(int fd, size_t *analen); - -/** - * nvme_get_lba_status_log() - Retreive 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. - */ -int nvme_get_lba_status_log(int fd, bool rae, struct nvme_lba_status_log **log); - -/** - * nvme_namespace_attach_ctrls() - Attach namespace to controller(s) - * @fd: File descriptor of nvme device - * @nsid: Namespace ID to attach - * @num_ctrls: Number of controllers in ctrlist - * @ctrlist: List of controller IDs to perform the attach action - * - * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. - */ -int nvme_namespace_attach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist); - -/** - * nvme_namespace_detach_ctrls() - Detach namespace from controller(s) - * @fd: File descriptor of nvme device - * @nsid: Namespace ID to detach - * @num_ctrls: Number of controllers in ctrlist - * @ctrlist: List of controller IDs to perform the detach action - * - * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. - */ -int nvme_namespace_detach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist); - /** * nvme_get_feature_length() - Retreive the command payload length for a * specific feature identifier @@ -239,29 +109,6 @@ int nvme_get_feature_length(int fid, __u32 cdw11, __u32 *len); int nvme_get_directive_receive_length(enum nvme_directive_dtype dtype, enum nvme_directive_receive_doper doper, __u32 *len); -/** - * nvme_open() - Open an nvme controller or namespace device - * @name: The basename of the device to open - * - * This will look for the handle in /dev/ and validate the name and filetype - * match linux conventions. - * - * Return: A file descriptor for the device on a successful open, or -1 with - * errno set otherwise. - */ -int nvme_open(const char *name); - -/** - * nvme_chomp() - Strip trailing white space - * &s: String to strip - * @l: Maximum length of string - */ -static inline void nvme_chomp(char *s, int l) -{ - while (l && (s[l] == '\0' || s[l] == ' ')) - s[l--] = '\0'; -} - #define NVME_FEAT_ARB_BURST(v) NVME_GET(v, FEAT_ARBITRATION_BURST) #define NVME_FEAT_ARB_LPW(v) NVME_GET(v, FEAT_ARBITRATION_LPW) #define NVME_FEAT_ARB_MPW(v) NVME_GET(v, FEAT_ARBITRATION_MPW) From 2e3616eaf0ed3c76ad2e5e51bfbaabe14d338173 Mon Sep 17 00:00:00 2001 From: Klaus Jensen Date: Wed, 29 Sep 2021 21:07:41 +0200 Subject: [PATCH 0210/1564] types: remove endian/mmio helpers The endian/mmio helpers do not belong in types.h. Since we are already using ccan and have ccan/endian available, just include that where needed. The implementation is 100% equivalent, even with sparse annotations. Signed-off-by: Klaus Jensen --- examples/Makefile | 2 +- examples/discover-loop.c | 2 + examples/meson.build | 4 +- examples/telemetry-listen.c | 2 + src/nvme/fabrics.c | 1 + src/nvme/ioctl.c | 1 + src/nvme/linux.c | 2 + src/nvme/tree.c | 2 + src/nvme/types.h | 79 ------------------------------------- src/nvme/util.c | 2 + test/Makefile | 2 +- test/meson.build | 6 +-- test/register.c | 20 ++++++++++ test/test.c | 2 + test/zns.c | 2 + 15 files changed, 43 insertions(+), 86 deletions(-) diff --git a/examples/Makefile b/examples/Makefile index 7e3109851d..db06f38656 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -1,5 +1,5 @@ CFLAGS ?= -g -O2 -override CFLAGS += -Wall -D_GNU_SOURCE -I ../src -L ../src +override CFLAGS += -Wall -D_GNU_SOURCE -I ../src -L ../src -I../ccan include ../Makefile.quiet diff --git a/examples/discover-loop.c b/examples/discover-loop.c index 599edd2057..c2a2385080 100644 --- a/examples/discover-loop.c +++ b/examples/discover-loop.c @@ -18,6 +18,8 @@ #include #include +#include + static void print_discover_log(struct nvmf_discovery_log *log) { int i, numrec = le64_to_cpu(log->numrec); diff --git a/examples/meson.build b/examples/meson.build index 0bf911d597..54ebbdac9f 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -7,7 +7,7 @@ # executable( 'telemetry-listen', - ['telemetry-listen.c'], + ['telemetry-listen.c', ccan_config_h], link_with: libnvme, include_directories: incdir) @@ -19,7 +19,7 @@ executable( executable( 'discover-loop', - ['discover-loop.c'], + ['discover-loop.c', ccan_config_h], link_with: libnvme, include_directories: incdir) diff --git a/examples/telemetry-listen.c b/examples/telemetry-listen.c index 374ffa4dbb..d3dcfb0b82 100644 --- a/examples/telemetry-listen.c +++ b/examples/telemetry-listen.c @@ -20,6 +20,8 @@ #include #include +#include + struct events { nvme_ctrl_t c; int uevent_fd; diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index d96f09e97e..94cecd0614 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -25,6 +25,7 @@ #include #include +#include #include #include diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 8fbed44025..5e8066cf91 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -18,6 +18,7 @@ #include #include +#include #include "ioctl.h" #include "util.h" diff --git a/src/nvme/linux.c b/src/nvme/linux.c index 90b9b5cef7..f7668ac6f8 100644 --- a/src/nvme/linux.c +++ b/src/nvme/linux.c @@ -17,6 +17,8 @@ #include #include +#include + #include "linux.h" #include "tree.h" #include "log.h" diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 552496d800..0f72320f17 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -21,7 +21,9 @@ #include #include +#include #include + #include "ioctl.h" #include "linux.h" #include "filters.h" diff --git a/src/nvme/types.h b/src/nvme/types.h index 6b0b14716e..5e5936e9f7 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -10,18 +10,11 @@ #ifndef _LIBNVME_TYPES_H #define _LIBNVME_TYPES_H -#include #include #include #include -#ifdef __CHECKER__ -#define __force __attribute__((force)) -#else -#define __force -#endif - /** * NVME_GET() - extract field from complex value * @value: The original value of a complex field @@ -46,60 +39,6 @@ #define NVME_SET(value, name) \ (((value) & NVME_##name##_MASK) << NVME_##name##_SHIFT) -/** - * cpu_to_le16() - - * @x: 16-bit CPU value to turn to little endian. - */ -static inline __le16 cpu_to_le16(uint16_t x) -{ - return (__force __le16)htole16(x); -} - -/** - * cpu_to_le32() - - * @x: 32-bit CPU value to turn little endian. - */ -static inline __le32 cpu_to_le32(uint32_t x) -{ - return (__force __le32)htole32(x); -} - -/** - * cpu_to_le64() - - * @x: 64-bit CPU value to turn little endian. - */ -static inline __le64 cpu_to_le64(uint64_t x) -{ - return (__force __le64)htole64(x); -} - -/** - * le16_to_cpu() - - * @x: 16-bit little endian value to turn to CPU. - */ -static inline uint16_t le16_to_cpu(__le16 x) -{ - return le16toh((__force __u16)x); -} - -/** - * le32_to_cpu() - - * @x: 32-bit little endian value to turn to CPU. - */ -static inline uint32_t le32_to_cpu(__le32 x) -{ - return le32toh((__force __u32)x); -} - -/** - * le64_to_cpu() - - * @x: 64-bit little endian value to turn to CPU. - */ -static inline uint64_t le64_to_cpu(__le64 x) -{ - return le64toh((__force __u64)x); -} - /** * enum nvme_constants - A place to stash various constant nvme values * @NVME_NSID_ALL: A broadcast value that is used to specify all @@ -251,24 +190,6 @@ static inline bool nvme_is_64bit_reg(__u32 offset) } } -static inline uint32_t nvme_mmio_read32(volatile void *addr) -{ - uint32_t *p = (__le32 *)addr; - - return le32_to_cpu(*p); -} - -static inline uint64_t nvme_mmio_read64(volatile void *addr) -{ - volatile __u32 *p = (__u32 *)addr; - uint32_t low, high; - - low = nvme_mmio_read32(p); - high = nvme_mmio_read32(p + 1); - - return low + ((uint64_t)high << 32); -} - enum nvme_cap { NVME_CAP_MQES_SHIFT = 0, NVME_CAP_CQR_SHIFT = 16, diff --git a/src/nvme/util.c b/src/nvme/util.c index 3fd78490fa..dab6c02b2d 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -12,6 +12,8 @@ #include +#include + #include "util.h" static inline __u8 nvme_generic_status_to_errno(__u16 status) diff --git a/test/Makefile b/test/Makefile index 0c4eb361b1..b7fc2b8bbd 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,5 +1,5 @@ CFLAGS ?= -g -O2 -override CFLAGS += -Wall -D_GNU_SOURCE -L../src/ -I../src/ +override CFLAGS += -Wall -D_GNU_SOURCE -L../src/ -I../src/ -I../ccan include ../Makefile.quiet diff --git a/test/meson.build b/test/meson.build index e89d877831..6b776aa4d2 100644 --- a/test/meson.build +++ b/test/meson.build @@ -7,7 +7,7 @@ # main = executable( 'main-test', - ['test.c'], + ['test.c', ccan_config_h], dependencies: libuuid, link_with: libnvme, include_directories: incdir @@ -22,14 +22,14 @@ cpp = executable( register = executable( 'test-register', - ['register.c'], + ['register.c', ccan_config_h], link_with: libnvme, include_directories: incdir ) zns = executable( 'test-zns', - ['zns.c'], + ['zns.c', ccan_config_h], link_with: libnvme, include_directories: incdir ) diff --git a/test/register.c b/test/register.c index 06244dfd5c..8791083e2b 100644 --- a/test/register.c +++ b/test/register.c @@ -21,6 +21,26 @@ #include +#include + +static inline uint32_t nvme_mmio_read32(volatile void *addr) +{ + uint32_t *p = (__le32 *)addr; + + return le32_to_cpu(*p); +} + +static inline uint64_t nvme_mmio_read64(volatile void *addr) +{ + volatile __u32 *p = (__u32 *)addr; + uint32_t low, high; + + low = nvme_mmio_read32(p); + high = nvme_mmio_read32(p + 1); + + return low + ((uint64_t)high << 32); +} + void nvme_print_registers(void *regs) { __u64 cap = nvme_mmio_read64(regs + NVME_REG_CAP); diff --git a/test/test.c b/test/test.c index 7c6a5cb835..34d7c7da59 100644 --- a/test/test.c +++ b/test/test.c @@ -23,6 +23,8 @@ #endif #include +#include + static char *nqn_match; static bool nvme_match_subsysnqn_filter(nvme_subsystem_t s) diff --git a/test/zns.c b/test/zns.c index 3ca55dfc75..54a6779ad9 100644 --- a/test/zns.c +++ b/test/zns.c @@ -16,6 +16,8 @@ #include #include +#include + static void show_zns_properties(nvme_ns_t n) { struct nvme_zns_id_ns zns_ns; From 0b6e87d001043f24b2bd09446a1f9eb109aabc2a Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Wed, 20 Oct 2021 11:59:03 +0800 Subject: [PATCH 0211/1564] types.h: heal -> health We currently have an abbreviation 'heal' in nvme_mi_ctrl_heal_status; while the subsystem health status uses the full 'health'. This change unifies these by using the full term instead of the abbreviation. Signed-off-by: Jeremy Kerr --- src/nvme/types.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nvme/types.h b/src/nvme/types.h index 292284e05a..004dc316a8 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -3995,7 +3995,7 @@ enum nvme_mi_css { }; /** - * struct nvme_mi_ctrl_heal_status - + * struct nvme_mi_ctrl_health_status - * @ctlid: * @csts: * @ctemp: @@ -4003,7 +4003,7 @@ enum nvme_mi_css { * @spare: * @cwarn: */ -struct nvme_mi_ctrl_heal_status { +struct nvme_mi_ctrl_health_status { __le16 ctlid; __le16 csts; __le16 ctemp; From 978d3e98e4f9ac8a9e63ec4ffe753f7d2d07e2cf Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Wed, 20 Oct 2021 12:21:13 +0800 Subject: [PATCH 0212/1564] private.h: Add required includes In private.h, we use the list, nvme_fabrics_config and (optional) UUID types, so add their appropriate #includes. Signed-off-by: Jeremy Kerr --- src/nvme/private.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/nvme/private.h b/src/nvme/private.h index 29e96bf322..355e2436f4 100644 --- a/src/nvme/private.h +++ b/src/nvme/private.h @@ -9,6 +9,15 @@ #ifndef _LIBNVME_PRIVATE_H #define _LIBNVME_PRIVATE_H +#include + +#include "fabrics.h" + +#ifdef CONFIG_LIBUUID +#include +#endif + + extern const char *nvme_ctrl_sysfs_dir; extern const char *nvme_subsys_sysfs_dir; extern const char *nvme_ns_sysfs_dir; From 6cbf1fb958747fdf4088519df01ab4206f3b5393 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 21 Oct 2021 09:16:58 +0200 Subject: [PATCH 0213/1564] build: Add missing json-c.wrap Commit 6af90f95fd1b ("build: Add fallback dependency for json-c") is missing the wrap file. Signed-off-by: Daniel Wagner --- subprojects/json-c.wrap | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 subprojects/json-c.wrap diff --git a/subprojects/json-c.wrap b/subprojects/json-c.wrap new file mode 100644 index 0000000000..db391e0604 --- /dev/null +++ b/subprojects/json-c.wrap @@ -0,0 +1,9 @@ +[wrap-file] +directory = json-c-0.13.1 +source_url = https://s3.amazonaws.com/json-c_releases/releases/json-c-0.13.1.tar.gz +source_filename = json-c-0.13.1.tar.gz +source_hash = b87e608d4d3f7bfdd36ef78d56d53c74e66ab278d318b71e6002a369d36f4873 +patch_url = https://wrapdb.mesonbuild.com/v2/json-c_0.13.1-1/get_patch +patch_filename = json-c-0.13.1-1-wrap.zip +patch_hash = 213a735c3c5f7ff4aa38850cd7bf236337c47fd553b9fcded64e709cab66b9fd + From 39b9fa618cf4b66bc5cb5ded6a9f1c7b876722ad Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Thu, 21 Oct 2021 16:07:08 +0800 Subject: [PATCH 0214/1564] Revert "src/Makefile: fix ccan config.h" This reverts commit 859bd459dee308639eedb490d348d311dc08f859. We have the proper fixes in progress, no need for the revert-workaround. Signed-off-by: Jeremy Kerr --- configure | 12 ++++++------ src/Makefile | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/configure b/configure index 592e0abfd3..b21a09823a 100755 --- a/configure +++ b/configure @@ -73,16 +73,16 @@ exit 0 fi config_host_mak="config-host.mak" -config_host_h="config-host.h" +config_h="config.h" rm -rf $config_host_mak -rm -rf $config_host_h +rm -rf $config_h fatal() { echo $@ echo "Configure failed, check config.log and/or the above output" rm -rf $config_host_mak - rm -rf $config_host_h + rm -rf $config_h exit 1 } @@ -96,8 +96,8 @@ CFLAGS="-D_GNU_SOURCE -include config.h" BUILD_CFLAGS="" cmdstr=$(printf " '%s'" "$0" "$@") -# Print configure header at the top of $config_host_h -cat > $config_host_h < $config_h <> $config_host_h + echo "#define $1" >> $config_h } print_and_output_mak() { diff --git a/src/Makefile b/src/Makefile index 23372b0b3e..4af6551af1 100644 --- a/src/Makefile +++ b/src/Makefile @@ -12,7 +12,7 @@ libdir ?= $(prefix)/lib CCANDIR=../ccan/ -CFLAGS ?= -g -fomit-frame-pointer -O2 -I/usr/include -Invme/ -I$(CCANDIR) -include ../config-host.h -D_GNU_SOURCE +CFLAGS ?= -g -fomit-frame-pointer -O2 -I/usr/include -Invme/ -I$(CCANDIR) -I.. -include ../config.h -D_GNU_SOURCE override CFLAGS += -Wall -fPIC SO_CFLAGS=-shared $(CFLAGS) L_CFLAGS=$(CFLAGS) @@ -36,7 +36,7 @@ include ../Makefile.quiet all: $(all_targets) -$(CCANDIR)config.h: $(CCANDIR)tools/configurator/configurator +$(CCANDIR)ccan-config.h: $(CCANDIR)tools/configurator/configurator $< > $@ $(CCANDIR)tools/configurator/configurator: CFLAGS = -D_GNU_SOURCE @@ -45,7 +45,7 @@ libccan_srcs := $(wildcard $(CCANDIR)ccan/*/*.c) libccan_objs := $(patsubst %.c,%.ol,$(libccan_srcs)) libccan_sobjs := $(patsubst %.c,%.os,$(libccan_srcs)) -$(libccan_objs) $(libccan_sobjs): $(libccan_headers) $(CCANDIR)config.h +$(libccan_objs) $(libccan_sobjs): $(libccan_headers) $(CCANDIR)ccan-config.h libnvme_priv := nvme/private.h libnvme_api := libnvme.h nvme/types.h nvme/linux.h nvme/ioctl.h nvme/filters.h nvme/tree.h nvme/util.h nvme/fabrics.h nvme/log.h @@ -87,10 +87,10 @@ ifeq ($(ENABLE_SHARED),1) endif $(libnvme_objs): $(libnvme_api) $(libnvme_private) -$(libccan_objs): $(libccan_headers) $(CCANDIR)config.h +$(libccan_objs): $(libccan_headers) $(CCANDIR)ccan-config.h clean: rm -f $(all_targets) $(libnvme_objs) $(libnvme_sobjs) $(libccan_objs) $(libccan_sobjs) $(soname).new - rm -f $(CCANDIR)config.h + rm -f $(CCANDIR)ccan-config.h rm -f $(CCANDIR)tools/configurator/configurator rm -f *.so* *.a *.o From c07d7745b2e8611a68673699dca43a21f9e45bf7 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Thu, 21 Oct 2021 16:08:01 +0800 Subject: [PATCH 0215/1564] Revert "meson: revert to using the ccan configurator" We have a fix queued for the issue that the original revert is working-around. This also includes adjustments to the examples/ & tests/ meson definitions to suit. This reverts commit b66a139f12357757c54adf7f38031f0f9105c501. Signed-off-by: Jeremy Kerr --- ccan/meson.build | 2 +- examples/meson.build | 4 +-- meson.build | 86 +++++++++++++++++++++++++++++++++++++++++--- pynvme/meson.build | 2 +- src/meson.build | 3 +- test/meson.build | 6 ++-- 6 files changed, 90 insertions(+), 13 deletions(-) diff --git a/ccan/meson.build b/ccan/meson.build index c0143427c4..f24b94f5b9 100644 --- a/ccan/meson.build +++ b/ccan/meson.build @@ -11,7 +11,7 @@ configurator = executable( c_args: ['-D_GNU_SOURCE'], ) -ccan_config_h = custom_target( +config_h = custom_target( 'config.h', output: 'config.h', capture: true, diff --git a/examples/meson.build b/examples/meson.build index 54ebbdac9f..7c86c9d20a 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -7,7 +7,7 @@ # executable( 'telemetry-listen', - ['telemetry-listen.c', ccan_config_h], + ['telemetry-listen.c', config_h], link_with: libnvme, include_directories: incdir) @@ -19,7 +19,7 @@ executable( executable( 'discover-loop', - ['discover-loop.c', ccan_config_h], + ['discover-loop.c', config_h], link_with: libnvme, include_directories: incdir) diff --git a/meson.build b/meson.build index b07497af60..8251cf4f4c 100644 --- a/meson.build +++ b/meson.build @@ -108,8 +108,87 @@ conf.set('CONFIG_LIBUUID', libuuid.found(), description: 'Is libuuid required?') json_c = dependency('json-c', version: '>=0.13', fallback : ['json-c', 'json_c']) conf.set('CONFIG_JSONC', json_c.found(), description: 'Is json-c required?') -config_host_h = configure_file( - output: 'config-host.h', +# local (cross-compilable) implementations of ccan configure steps +conf.set10( + 'HAVE_BUILTIN_TYPES_COMPATIBLE_P', + cc.compiles( + '''int main(void) { + return __builtin_types_compatible_p(int, long); + } + ''', + name: '__builtin_type_compatible_p' + ), + description: 'Is __builtin_types_compatible_p available?' +) +conf.set10( + 'HAVE_TYPEOF', + cc.compiles( + '''int main(void) { + int a = 1; + typeof(a) b; + b = a; + } + ''', + name: 'typeof' + ), + description: 'Is typeof available?' +) +conf.set10( + 'HAVE_BYTESWAP_H', + cc.compiles( + '''#include ''', + name: 'byteswap.h' + ), + description: 'Is byteswap.h include-able?' +) +conf.set10( + 'HAVE_BSWAP64', + cc.links( + '''#include + int main(void) { + return bswap_64(0); + } + ''', + name: 'bswap64' + ), + description: 'Is bswap_64 available?' +) +conf.set10( + 'HAVE_LITTLE_ENDIAN', + build_machine.endian() == 'little', + description: 'Building for little-endian' +) +conf.set10( + 'HAVE_BIG_ENDIAN', + build_machine.endian() == 'big', + description: 'Building for big-endian' +) +conf.set10( + 'HAVE_STATEMENT_EXPR', + cc.compiles( + '''int main(int argc, char **argv) { + return ({ int x = argc; x == 1; }); + } + ''', + name: 'statement-expr' + ), + description: 'Can we use a statement as an expression?' +) +conf.set10( + 'HAVE_ISBLANK', + cc.links( + '''#include + int main(int argc, char **argv) { + return isblank(argv[0][0]); + } + ''', + name: 'isblank' + ), + description: 'Is isblank() available?' +) + +config_h = configure_file( + output: 'config.h', configuration: conf ) @@ -125,11 +204,10 @@ configure_file( ) ################################################################################ -add_project_arguments(['-fomit-frame-pointer', '-D_GNU_SOURCE', '-include', 'config-host.h'], language : 'c') +add_project_arguments(['-fomit-frame-pointer', '-D_GNU_SOURCE', '-include', 'config.h'], language : 'c') incdir = include_directories(['.', 'ccan', 'src']) ################################################################################ -subdir('ccan') subdir('src') subdir('pynvme') subdir('test') diff --git a/pynvme/meson.build b/pynvme/meson.build index 2955959f3a..bde1536bef 100644 --- a/pynvme/meson.build +++ b/pynvme/meson.build @@ -19,7 +19,7 @@ endif if have_python_support pymod_swig = custom_target( 'nvme.py', - input: ['nvme.i', config_host_h, ccan_config_h], + input: ['nvme.i', config_h], output: ['nvme.py', 'nvme_wrap.c'], command: [swig, '-python', '-py3', '-o', '@OUTPUT1@', '@INPUT0@'], install: true, diff --git a/src/meson.build b/src/meson.build index 10acb15ea9..2a6069c65e 100644 --- a/src/meson.build +++ b/src/meson.build @@ -14,8 +14,7 @@ sources = [ 'nvme/log.c', 'nvme/tree.c', 'nvme/util.c', - ccan_config_h, - config_host_h, + config_h, ] if conf.get('CONFIG_JSONC') diff --git a/test/meson.build b/test/meson.build index 6b776aa4d2..7adb963f64 100644 --- a/test/meson.build +++ b/test/meson.build @@ -7,7 +7,7 @@ # main = executable( 'main-test', - ['test.c', ccan_config_h], + ['test.c', config_h], dependencies: libuuid, link_with: libnvme, include_directories: incdir @@ -22,14 +22,14 @@ cpp = executable( register = executable( 'test-register', - ['register.c', ccan_config_h], + ['register.c', config_h], link_with: libnvme, include_directories: incdir ) zns = executable( 'test-zns', - ['zns.c', ccan_config_h], + ['zns.c', config_h], link_with: libnvme, include_directories: incdir ) From 4dc750724cf2261c47407bb4cb05e5b45f6d5c33 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Thu, 21 Oct 2021 16:20:42 +0800 Subject: [PATCH 0216/1564] makefiles: use config.h in examples/ & tests/ After the recent reverts, we now need to use the proper config.h in examples/ and tests/ too. Signed-off-by: Jeremy Kerr --- examples/Makefile | 2 +- test/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/Makefile b/examples/Makefile index db06f38656..4916494dd4 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -1,5 +1,5 @@ CFLAGS ?= -g -O2 -override CFLAGS += -Wall -D_GNU_SOURCE -I ../src -L ../src -I../ccan +override CFLAGS += -Wall -D_GNU_SOURCE -I .. -I ../src -L ../src -I../ccan --include "config.h" include ../Makefile.quiet diff --git a/test/Makefile b/test/Makefile index b7fc2b8bbd..90e89e0b08 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,5 +1,5 @@ CFLAGS ?= -g -O2 -override CFLAGS += -Wall -D_GNU_SOURCE -L../src/ -I../src/ -I../ccan +override CFLAGS += -Wall -D_GNU_SOURCE -L../src/ -I .. -I../src/ -I../ccan --include "config.h" include ../Makefile.quiet From 3ea263357470b08659fed45bb82a323b15b3621c Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Wed, 20 Oct 2021 21:14:25 +0800 Subject: [PATCH 0217/1564] configure: include ccan config from top-level config.h In 3a84d900, we moved the ccan config.h to ccan-config.h, but didn't end up including it in the top-level config.h. To complete the simplification, config.h should include the (configurator-generated) ccan-config.h. Fixes: 3a84d90084b5 ("configure: simplify config-host.h & config-host.mak generation") Reported-by: Klaus Jensen Signed-off-by: Jeremy Kerr --- configure | 1 + 1 file changed, 1 insertion(+) diff --git a/configure b/configure index b21a09823a..dcf1699131 100755 --- a/configure +++ b/configure @@ -103,6 +103,7 @@ cat > $config_h < $config_host_mak < Date: Thu, 21 Oct 2021 09:44:18 +0800 Subject: [PATCH 0218/1564] meson: use correct byteswap macro name We're declaring HAVE_BSWAP64, but ccan expects HAVE_BSWAP_64. Fixes: bb84156 ("meson.build: Add ccan-required configuration macros") Reported-by: Klaus Jensen Signed-off-by: Jeremy Kerr --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 8251cf4f4c..ea7c516515 100644 --- a/meson.build +++ b/meson.build @@ -142,7 +142,7 @@ conf.set10( description: 'Is byteswap.h include-able?' ) conf.set10( - 'HAVE_BSWAP64', + 'HAVE_BSWAP_64', cc.links( '''#include int main(void) { From 3f1d3ca9c681770a7e5d2736e7bc06a5fd8c27b5 Mon Sep 17 00:00:00 2001 From: Klaus Jensen Date: Thu, 21 Oct 2021 12:43:46 +0200 Subject: [PATCH 0219/1564] src/meson.build: install missing linux.h src/nvme/linux.h is missing from install_headers. Signed-off-by: Klaus Jensen --- src/meson.build | 1 + 1 file changed, 1 insertion(+) diff --git a/src/meson.build b/src/meson.build index 2a6069c65e..1fe04e7fe4 100644 --- a/src/meson.build +++ b/src/meson.build @@ -62,6 +62,7 @@ install_headers([ 'nvme/fabrics.h', 'nvme/filters.h', 'nvme/ioctl.h', + 'nvme/linux.h', 'nvme/log.h', 'nvme/tree.h', 'nvme/types.h', From cb26ce200ab2b568dc581f70ecd24f0f691e09a8 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Fri, 22 Oct 2021 08:13:52 +0200 Subject: [PATCH 0220/1564] libnvme.map: Expose symbols for Python binding There a few missing symbols for the Python binding. Add them to the libnvme.map. Signed-off-by: Daniel Wagner --- src/libnvme.map | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/libnvme.map b/src/libnvme.map index 7b999d5a9f..125b541fd3 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -34,6 +34,7 @@ nvme_ctrl_next_ns; nvme_ctrl_next_path; nvme_ctrl_reset; + nvme_ctrl_set_persistent; nvme_ctrls_filter; nvme_default_host; nvme_dev_self_test; @@ -55,7 +56,9 @@ nvme_flush; nvme_format_nvm; nvme_free_ctrl; + nvme_free_host; nvme_free_ns; + nvme_free_subsystem; nvme_free_tree; nvme_fw_commit; nvme_fw_download; @@ -129,6 +132,7 @@ nvme_get_telemetry_log; nvme_host_get_hostid; nvme_host_get_hostnqn; + nvme_host_get_root; nvme_identify; nvme_identify_active_ns_list; nvme_identify_allocated_ns; @@ -151,7 +155,9 @@ nvme_io_passthru64; nvme_io_passthru; nvme_log_level; + nvme_log_message; nvme_lookup_host; + nvme_lookup_subsystem; nvme_namespace_attach_ctrls; nvme_namespace_detach_ctrls; nvme_namespace_filter; @@ -202,6 +208,7 @@ nvme_paths_filter; nvme_read; nvme_refresh_topology; + nvme_rescan_ctrl; nvme_reset_topology; nvme_resv_acquire; nvme_resv_register; @@ -267,10 +274,12 @@ nvme_subsystem_get_nqn; nvme_subsystem_get_nqn; nvme_subsystem_get_sysfs_dir; + nvme_subsystem_lookup_namespace; nvme_subsystem_next_ctrl; nvme_subsystem_next_ns; nvme_subsystem_reset; nvme_unlink_ctrl; + nvme_update_config; nvme_verify; nvme_virtual_mgmt; nvme_write; From b44bbc505a8f73dcb6d2cdbe21b935a4b16a74c0 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Fri, 22 Oct 2021 09:15:39 +0200 Subject: [PATCH 0221/1564] ccan: Add *.c files to the build We are missing the *.c files from the ccan code base in the build. As we currently don't use any function implemented in the *.c files all just works. Signed-off-by: Daniel Wagner --- ccan/meson.build | 7 +++++++ meson.build | 2 ++ src/meson.build | 2 +- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ccan/meson.build b/ccan/meson.build index f24b94f5b9..7268710da6 100644 --- a/ccan/meson.build +++ b/ccan/meson.build @@ -5,6 +5,13 @@ # # Authors: Martin Belanger # + +sources += files([ + 'ccan/list/list.c', + 'ccan/str/debug.c', + 'ccan/str/str.c', +]) + configurator = executable( 'configurator', ['tools/configurator/configurator.c'], diff --git a/meson.build b/meson.build index ea7c516515..74a89513cb 100644 --- a/meson.build +++ b/meson.build @@ -208,6 +208,8 @@ add_project_arguments(['-fomit-frame-pointer', '-D_GNU_SOURCE', '-include', 'con incdir = include_directories(['.', 'ccan', 'src']) ################################################################################ +sources = [] +subdir('ccan') subdir('src') subdir('pynvme') subdir('test') diff --git a/src/meson.build b/src/meson.build index 1fe04e7fe4..3651aa12c9 100644 --- a/src/meson.build +++ b/src/meson.build @@ -5,7 +5,7 @@ # # Authors: Martin Belanger # -sources = [ +sources += [ 'nvme/cleanup.c', 'nvme/fabrics.c', 'nvme/filters.c', From 12653554de0d593b8d760beaf959248d87b6c078 Mon Sep 17 00:00:00 2001 From: Martin Belanger Date: Thu, 21 Oct 2021 08:42:24 -0400 Subject: [PATCH 0222/1564] Add Python init() method. Move nvme_init_ctrl() from private.h to tree.h Addess review comments. Signed-off-by: Martin Belanger --- pynvme/nvme.i | 5 +++++ src/libnvme.map | 1 + src/nvme/private.h | 2 -- src/nvme/tree.h | 10 ++++++++++ 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/pynvme/nvme.i b/pynvme/nvme.i index 919361727f..ca7fb5a7dc 100644 --- a/pynvme/nvme.i +++ b/pynvme/nvme.i @@ -502,6 +502,11 @@ struct nvme_ns { ~nvme_ctrl() { nvme_free_ctrl($self); } + + bool init(struct nvme_host *h, int instance) { + return nvme_init_ctrl(h, $self, instance) == 0; + } + void connect(struct nvme_host *h, struct nvme_fabrics_config *cfg = NULL) { int ret; const char *dev; diff --git a/src/libnvme.map b/src/libnvme.map index 322097f21d..d8fff8b635 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -143,6 +143,7 @@ nvme_identify_secondary_ctrl_list; nvme_identify_uuid; nvme_init_copy_range; + nvme_init_ctrl; nvme_init_ctrl_list; nvme_init_dsm_range; nvme_init_id_ns; diff --git a/src/nvme/private.h b/src/nvme/private.h index 29e96bf322..2a151bf861 100644 --- a/src/nvme/private.h +++ b/src/nvme/private.h @@ -111,8 +111,6 @@ struct nvme_root { bool modified; }; -int nvme_init_ctrl(nvme_host_t h, nvme_ctrl_t c, int instance); - int nvme_set_attr(const char *dir, const char *attr, const char *value); void json_read_config(nvme_root_t r, const char *config_file); diff --git a/src/nvme/tree.h b/src/nvme/tree.h index f9e7d3713e..fc01b5ef88 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -853,6 +853,16 @@ nvme_ctrl_t nvme_scan_ctrl(nvme_root_t r, const char *name); */ void nvme_rescan_ctrl(nvme_ctrl_t c); +/** + * nvme_init_ctrl() - Initialize control for an existing nvme device. + * @h: host + * @c: ctrl + * @instance: Instance number (e.g. 1 for nvme1) + * + * Return: The ioctl() return code. Typically 0 on success. + */ +int nvme_init_ctrl(nvme_host_t h, nvme_ctrl_t c, int instance); + /** * nvme_free_ctrl() - * @c: From e22acbb9a20d90ef7ed57e9af136cca7798070fd Mon Sep 17 00:00:00 2001 From: Klaus Jensen Date: Tue, 26 Oct 2021 20:12:36 +0200 Subject: [PATCH 0223/1564] ioctl: fix mask values for virt mgmt Fix the the Virtualization Managemtn CDW10 masks for ACT, RT and CNTLID. Signed-off-by: Klaus Jensen --- src/nvme/ioctl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 5e8066cf91..1cd8d22a5d 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -256,9 +256,9 @@ enum nvme_cmd_dword_fields { NVME_VIRT_MGMT_CDW10_RT_SHIFT = 8, NVME_VIRT_MGMT_CDW10_CNTLID_SHIFT = 16, NVME_VIRT_MGMT_CDW11_NR_SHIFT = 0, - NVME_VIRT_MGMT_CDW10_ACT_MASK = 0, - NVME_VIRT_MGMT_CDW10_RT_MASK = 8, - NVME_VIRT_MGMT_CDW10_CNTLID_MASK = 16, + NVME_VIRT_MGMT_CDW10_ACT_MASK = 0xf, + NVME_VIRT_MGMT_CDW10_RT_MASK = 0x7, + NVME_VIRT_MGMT_CDW10_CNTLID_MASK = 0xffff, NVME_VIRT_MGMT_CDW11_NR_MASK = 0xffff, NVME_FORMAT_CDW10_LBAF_SHIFT = 0, NVME_FORMAT_CDW10_MSET_SHIFT = 4, From b37d353fd237234333e00d7a901f2eae9d157508 Mon Sep 17 00:00:00 2001 From: Martin Belanger Date: Wed, 27 Oct 2021 08:20:10 -0400 Subject: [PATCH 0224/1564] Add Python tests to meson framework. Python has this strict directory layout requirement. A Python package is a directory that must contain a __init__.py file in addition to containing modules. To be able to run Python tests and load modules directly from the build directory, the Python package (libnvme) and module (nvme.py) must be organized in the build directory the same way they would be in the install directory. And the PYTHONPATH must be set to point to the build directory. In other words, like this: .build <- PYTHONPATH points to here. \_ libnvme <- Package \_ nvme.py <- Module \_ __init__.py \_ _nvme.cpython-38-x86_64-linux-gnu.so This patch changes the directory layout so that meson will organize the Python package and module as shown above. The patch also defines Python tests and sets the PYTHONPATH to allow importing directly from the build directory. Signed-off-by: Martin Belanger --- .gitignore | 2 + Makefile | 4 +- {pynvme => libnvme}/.gitignore | 1 + {pynvme => libnvme}/Makefile | 0 {pynvme => libnvme}/README.md | 0 {pynvme => libnvme}/__init__.py | 0 libnvme/meson.build | 70 ++++++++++++++++++++++++++++++++ {pynvme => libnvme}/nvme.i | 0 {pynvme => libnvme}/setup.py | 0 libnvme/tests/create-ctrl-obj.py | 14 +++++++ meson.build | 2 +- pynvme/meson.build | 44 -------------------- 12 files changed, 90 insertions(+), 47 deletions(-) rename {pynvme => libnvme}/.gitignore (67%) rename {pynvme => libnvme}/Makefile (100%) rename {pynvme => libnvme}/README.md (100%) rename {pynvme => libnvme}/__init__.py (100%) create mode 100644 libnvme/meson.build rename {pynvme => libnvme}/nvme.i (100%) rename {pynvme => libnvme}/setup.py (100%) create mode 100755 libnvme/tests/create-ctrl-obj.py delete mode 100644 pynvme/meson.build diff --git a/.gitignore b/.gitignore index 29a202e316..d52a35ac5b 100644 --- a/.gitignore +++ b/.gitignore @@ -19,7 +19,9 @@ examples/display-columnar examples/telemetry-listen examples/discover-loop +config.h ccan/config.h +ccan/ccan-config.h ccan/tools/configurator/configurator doc/_build diff --git a/Makefile b/Makefile index 6cc8338645..d416c2db9d 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ INSTALL=install default: all python: all - @$(MAKE) -C pynvme python + @$(MAKE) -C libnvme python all: $(NAME).pc @$(MAKE) -C src @@ -55,7 +55,7 @@ install-tests: @$(MAKE) -C test install prefix=$(DESTDIR)$(prefix) datadir=$(DESTDIR)$(datadir) install-python: - @$(MAKE) -C pynvme install prefix=$(DESTDIR)$(prefix) + @$(MAKE) -C libnvme install prefix=$(DESTDIR)$(prefix) clean: @rm -f config-host.mak config-host.h cscope.out $(NAME).pc diff --git a/pynvme/.gitignore b/libnvme/.gitignore similarity index 67% rename from pynvme/.gitignore rename to libnvme/.gitignore index 44ac4fefc0..e943f50cdf 100644 --- a/pynvme/.gitignore +++ b/libnvme/.gitignore @@ -1,3 +1,4 @@ build/ +__pycache__/ nvme.py nvme_wrap.c diff --git a/pynvme/Makefile b/libnvme/Makefile similarity index 100% rename from pynvme/Makefile rename to libnvme/Makefile diff --git a/pynvme/README.md b/libnvme/README.md similarity index 100% rename from pynvme/README.md rename to libnvme/README.md diff --git a/pynvme/__init__.py b/libnvme/__init__.py similarity index 100% rename from pynvme/__init__.py rename to libnvme/__init__.py diff --git a/libnvme/meson.build b/libnvme/meson.build new file mode 100644 index 0000000000..554d4e3e37 --- /dev/null +++ b/libnvme/meson.build @@ -0,0 +1,70 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# This file is part of libnvme. +# Copyright (c) 2021 Dell Inc. +# +# Authors: Martin Belanger +# + +want_python = get_option('python') +if want_python != 'false' + python3 = import('python').find_installation('python3') + py3_dep = python3.dependency(required: want_python == 'true') + swig = find_program('swig', required: want_python == 'true') + have_python_support = py3_dep.found() and swig.found() +else + have_python_support = false +endif + +if have_python_support + pymod_swig = custom_target( + 'nvme.py', + input: ['nvme.i', config_h], + output: ['nvme.py', 'nvme_wrap.c'], + command: [swig, '-python', '-py3', '-o', '@OUTPUT1@', '@INPUT0@'], + install: true, + install_dir: [python3.get_install_dir(pure: false, subdir: 'libnvme'), false], + ) + + pynvme_clib = python3.extension_module( + '_nvme', + pymod_swig[1], + dependencies : py3_dep, + include_directories: incdir, + link_with: libnvme, + install: true, + subdir: 'libnvme', + ) + + # Little hack to copy file __init__.py to the build directory. + # This is needed to create the proper directory layout to run the tests. + # It's a hack because we don't really "configure" file __init__.py and we + # could simply install directly from the source tree with: + # python3.install_sources(['__init__.py', ], pure:false, subdir:'libnvme') + # However, since we need __init__.py in the build directory to run the tests + # we resort to this hack to copy it. + configure_file( + input: '__init__.py', + output: '__init__.py', + copy: true, + install_dir: python3.get_install_dir(pure: false, subdir: 'libnvme'), + ) + + # Set the PYTHONPATH so that we can run the + # tests directly from the build directory. + test_env = environment() + test_env.append('MALLOC_PERTURB_', '0') + test_env.append('PYTHONPATH', meson.build_root()) + + # Test section + test('[Python] import libnvme', python3, args: ['-c', 'from libnvme import nvme'], env: test_env) + + py_tests = [ + [ 'create ctrl object', files('tests/create-ctrl-obj.py') ], + ] + foreach test: py_tests + description = test[0] + py_script = test[1] + test('[Python] ' + description, python3, args: [py_script, ], env: test_env) + endforeach +endif diff --git a/pynvme/nvme.i b/libnvme/nvme.i similarity index 100% rename from pynvme/nvme.i rename to libnvme/nvme.i diff --git a/pynvme/setup.py b/libnvme/setup.py similarity index 100% rename from pynvme/setup.py rename to libnvme/setup.py diff --git a/libnvme/tests/create-ctrl-obj.py b/libnvme/tests/create-ctrl-obj.py new file mode 100755 index 0000000000..186c6013fc --- /dev/null +++ b/libnvme/tests/create-ctrl-obj.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python3 +import sys +import pprint +from libnvme import nvme + +root = nvme.root() +root.log_level('debug') + +host = nvme.host(root) +subsysnqn = nvme.NVME_DISC_SUBSYS_NAME +transport = 'loop' +traddr = '127.0.0.1' +trsvcid = '8009' +ctrl = nvme.ctrl(subsysnqn=subsysnqn, transport=transport, traddr=traddr, trsvcid=trsvcid) diff --git a/meson.build b/meson.build index ea7c516515..06f191283f 100644 --- a/meson.build +++ b/meson.build @@ -209,7 +209,7 @@ incdir = include_directories(['.', 'ccan', 'src']) ################################################################################ subdir('src') -subdir('pynvme') +subdir('libnvme') subdir('test') subdir('examples') subdir('doc') diff --git a/pynvme/meson.build b/pynvme/meson.build deleted file mode 100644 index bde1536bef..0000000000 --- a/pynvme/meson.build +++ /dev/null @@ -1,44 +0,0 @@ -# SPDX-License-Identifier: LGPL-2.1-or-later -# -# This file is part of libnvme. -# Copyright (c) 2021 Dell Inc. -# -# Authors: Martin Belanger -# - -want_python = get_option('python') -if want_python != 'false' - python3 = import('python').find_installation('python3') - py3_dep = python3.dependency(required: want_python == 'true') - swig = find_program('swig', required: want_python == 'true') - have_python_support = py3_dep.found() and swig.found() -else - have_python_support = false -endif - -if have_python_support - pymod_swig = custom_target( - 'nvme.py', - input: ['nvme.i', config_h], - output: ['nvme.py', 'nvme_wrap.c'], - command: [swig, '-python', '-py3', '-o', '@OUTPUT1@', '@INPUT0@'], - install: true, - install_dir: [python3.get_install_dir(pure: false, subdir: 'libnvme'), false], - ) - - pynvme_clib = python3.extension_module( - '_nvme', - pymod_swig[1], - dependencies : py3_dep, - include_directories: incdir, - link_with: libnvme, - install: true, - subdir: 'libnvme', - ) - - python3.install_sources( - ['__init__.py', ], - pure: false, - subdir: 'libnvme', - ) -endif From 1f274f613c0f64d36a761983cd595d3f216b3b15 Mon Sep 17 00:00:00 2001 From: Martin Belanger Date: Tue, 2 Nov 2021 08:19:52 -0400 Subject: [PATCH 0225/1564] Removed a duplicate line (read from file). I checked with Hannes and he confirmed that the line was added by mistake. Signed-off-by: Martin Belanger --- src/nvme/fabrics.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 94cecd0614..9757d8f2db 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -803,7 +803,6 @@ static int uuid_from_dmi(char *system_uuid) if (f < 0) continue; len = read(f, buf, 512); - len = read(f, buf, 512); close(f); if (len < 0) continue; From 6ef2c5540431d277a8da79a474d2191b4d7ccba3 Mon Sep 17 00:00:00 2001 From: Martin Belanger Date: Wed, 3 Nov 2021 05:03:24 -0400 Subject: [PATCH 0226/1564] Fix python unit tests when run as a subproject of another project (#91) * Fix python unit tests when run as a subproject of another project, i.e. nvme-cli. Signed-off-by: Martin Belanger --- .github/workflows/meson.yml | 7 +++++++ libnvme/meson.build | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/meson.yml b/.github/workflows/meson.yml index 533a3e45dd..e1fbdbd113 100644 --- a/.github/workflows/meson.yml +++ b/.github/workflows/meson.yml @@ -20,3 +20,10 @@ jobs: - uses: BSFishy/meson-build@v1.0.3 with: action: test + options: --verbose + # Preserve meson's log file on failure + - uses: actions/upload-artifact@v1 + if: failure() + with: + name: Linux_Meson_Testlog + path: build/meson-logs/testlog.txt diff --git a/libnvme/meson.build b/libnvme/meson.build index 554d4e3e37..76797cc78a 100644 --- a/libnvme/meson.build +++ b/libnvme/meson.build @@ -54,7 +54,7 @@ if have_python_support # tests directly from the build directory. test_env = environment() test_env.append('MALLOC_PERTURB_', '0') - test_env.append('PYTHONPATH', meson.build_root()) + test_env.append('PYTHONPATH', join_paths(meson.current_build_dir(), '..')) # Test section test('[Python] import libnvme', python3, args: ['-c', 'from libnvme import nvme'], env: test_env) From d63abf207959b9fb7c0bbbae1ead5e46c433e5e8 Mon Sep 17 00:00:00 2001 From: Martin Belanger Date: Tue, 2 Nov 2021 15:21:50 -0400 Subject: [PATCH 0227/1564] Fix reading of system UUID on Debian The system UUID can be read from the sysfs in two different locations: 1) /sys/class/dmi/id/product_uuid 2) /sys/firmware/dmi/entries Location 1) is present on all the systems I've tested: SUSE, Red Hat, Fedora, and Ubuntu. Unfortunately, location 2) does not exist on Debian-based systems. Currently, uuid_from_dmi() only reads from location 2), which fails on Debian. This patch adds code that reads from location 1) first, and will only try location 2) if reading from 1) fails. Signed-off-by: Martin Belanger [dwagner: Updated return value from -1 to -ENXIO] Signed-off-by: Daniel Wagner --- src/nvme/fabrics.c | 62 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 94cecd0614..21bcf2ab3d 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -781,7 +781,7 @@ static int uuid_from_device_tree(char *system_uuid) #define PATH_DMI_ENTRIES "/sys/firmware/dmi/entries" -static int uuid_from_dmi(char *system_uuid) +static int uuid_from_dmi_entries(char *system_uuid) { int f; DIR *d; @@ -838,6 +838,66 @@ static int uuid_from_dmi(char *system_uuid) return strlen(system_uuid) ? 0 : -ENXIO; } +/** + * @brief Get system UUID from /sys/class/dmi/id/product_uuid and fix + * endianess. + * + * @param system_uuid - Where to save the system UUID. + * + * @return 0 on success, -ENXIO otherwise. + */ +#define PATH_DMI_PROD_UUID "/sys/class/dmi/id/product_uuid" +static int uuid_from_product_uuid(char *system_uuid) +{ + FILE *stream = NULL; + int ret = -ENXIO; + + system_uuid[0] = '\0'; + + if ((stream = fopen(PATH_DMI_PROD_UUID, "re")) != NULL) { + char *line = NULL; + size_t len = 0; + ssize_t nread = getline(&line, &len, stream); + + if (nread == UUID_SIZE) { + /* Per "DMTF SMBIOS 3.0 Section 7.2.1 System UUID", the + * UUID retrieved from the DMI has the wrong endianess. + * The following copies "line" to "system_uuid" while + * swapping from little-endian to network-endian. */ + static const int swaptbl[] = { + 6,7,4,5,2,3,0,1,8,11,12,9,10,13,16,17,14,15,18,19, + 20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35, + -1 /* sentinel */ + }; + for (unsigned int i = 0; swaptbl[i] != -1; i++) + system_uuid[i] = line[swaptbl[i]]; + system_uuid[UUID_SIZE-1] = '\0'; + ret = 0; + } + + free(line); + fclose(stream); + } + + return ret; +} + +/** + * @brief The system UUID can be read from two different locations: + * + * 1) /sys/class/dmi/id/product_uuid + * 2) /sys/firmware/dmi/entries + * + * Note that the second location is not present on Debian-based systems. + */ +static int uuid_from_dmi(char *system_uuid) +{ + int ret = uuid_from_product_uuid(system_uuid); + if (ret != 0) + ret = uuid_from_dmi_entries(system_uuid); + return ret; +} + char *nvmf_hostnqn_generate() { char *hostnqn; From 2e7a1e88cd481484cc5c4120d64f2d82fd71e16e Mon Sep 17 00:00:00 2001 From: Tomas Bzatek Date: Thu, 4 Nov 2021 13:01:30 +0100 Subject: [PATCH 0228/1564] types: Fix a typo in the NVME_FORMAT_MSET_EXTENEDED constant --- src/nvme/types.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nvme/types.h b/src/nvme/types.h index dc154c37c4..6f790d230e 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -5064,11 +5064,11 @@ enum nvme_get_features_sel { /** * enum nvme_cmd_format_mset - * @NVME_FORMAT_MSET_SEPARATE: - * @NVME_FORMAT_MSET_EXTENEDED: + * @NVME_FORMAT_MSET_EXTENDED: */ enum nvme_cmd_format_mset { NVME_FORMAT_MSET_SEPARATE = 0, - NVME_FORMAT_MSET_EXTENEDED = 1, + NVME_FORMAT_MSET_EXTENDED = 1, }; /** From b5fc24a6d0f29f85eb8b17fdb8a51c64d6e68fc9 Mon Sep 17 00:00:00 2001 From: Tomas Bzatek Date: Thu, 4 Nov 2021 17:34:29 +0100 Subject: [PATCH 0229/1564] types: Doc strings update for Sanitize and Format operations --- src/nvme/types.h | 175 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 138 insertions(+), 37 deletions(-) diff --git a/src/nvme/types.h b/src/nvme/types.h index 6f790d230e..5118d7f518 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -3109,16 +3109,71 @@ enum nvme_resv_notify_rnlpt { }; /** - * struct nvme_sanitize_log_page - - * @sprog: - * @sstat: - * @scdw10: - * @eto: - * @etbe: - * @etce: - * @etond: - * @etbend: - * @etcend: + * 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. + * @sstat: Sanitize Status (SSTAT): indicates the status associated with + * 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. + * @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. + * @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. + * @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. + * @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. + * @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. + * @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. */ struct nvme_sanitize_log_page { __le16 sprog; @@ -3134,13 +3189,46 @@ struct nvme_sanitize_log_page { }; /** - * enum nvme_sanitize_sstat - - * @NVME_SANITIZE_SSTAT_STATUS_MASK: - * @NVME_SANITIZE_SSTAT_STATUS_NEVER_SANITIZED: - * @NVME_SANITIZE_SSTAT_STATUS_COMPLETE_SUCCESS: - * @NVME_SANITIZE_SSTAT_STATUS_IN_PROGESS: - * @NVME_SANITIZE_SSTAT_STATUS_COMPLETED_FAILED: - * @NVME_SANITIZE_SSTAT_STATUS_ND_COMPLETE_SUCCESS: + * 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. + * @NVME_SANITIZE_SSTAT_STATUS_MASK: Mask to get the status value of the most + * recent sanitize operation. + * @NVME_SANITIZE_SSTAT_STATUS_NEVER_SANITIZED: The NVM subsystem has never been + * sanitized. + * @NVME_SANITIZE_SSTAT_STATUS_COMPLETE_SUCCESS: The most recent sanitize operation + * 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. + * @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. + * @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. + * @NVME_SANITIZE_SSTAT_COMPLETED_PASSES_MASK: Mask to get the number of completed + * 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. + * @NVME_SANITIZE_SSTAT_GLOBAL_DATA_ERASED_MASK: Mask to get the Global Data Erased + * 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. */ enum nvme_sanitize_sstat { NVME_SANITIZE_SSTAT_STATUS_SHIFT = 0, @@ -5062,9 +5150,11 @@ enum nvme_get_features_sel { }; /** - * enum nvme_cmd_format_mset - - * @NVME_FORMAT_MSET_SEPARATE: - * @NVME_FORMAT_MSET_EXTENDED: + * 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. + * @NVME_FORMAT_MSET_EXTENDED: indicates that the metadata is transferred + * as part of an extended data LBA. */ enum nvme_cmd_format_mset { NVME_FORMAT_MSET_SEPARATE = 0, @@ -5072,11 +5162,11 @@ enum nvme_cmd_format_mset { }; /** - * enum nvme_cmd_format_pi - - * @NVME_FORMAT_PI_DISABLE: - * @NVME_FORMAT_PI_TYPE1: - * @NVME_FORMAT_PI_TYPE2: - * @NVME_FORMAT_PI_TYPE3: + * enum nvme_cmd_format_pi - Format NVM - Protection Information + * @NVME_FORMAT_PI_DISABLE: Protection information is not enabled. + * @NVME_FORMAT_PI_TYPE1: Protection information is enabled, Type 1. + * @NVME_FORMAT_PI_TYPE2: Protection information is enabled, Type 2. + * @NVME_FORMAT_PI_TYPE3: Protection information is enabled, Type 3. */ enum nvme_cmd_format_pi { NVME_FORMAT_PI_DISABLE = 0, @@ -5086,9 +5176,11 @@ enum nvme_cmd_format_pi { }; /** - * @enum nvme_cmd_format_pil - - * @NVME_FORMAT_PIL_LAST: - * @NVME_FORMAT_PIL_FIRST: + * @enum nvme_cmd_format_pil - Format NVM - Protection Information Location + * @NVME_FORMAT_PIL_LAST: Protection information is transferred as the last + * bytes of metadata. + * @NVME_FORMAT_PIL_FIRST: Protection information is transferred as the first + * bytes of metadata. */ enum nvme_cmd_format_pil { NVME_FORMAT_PIL_LAST = 0, @@ -5096,10 +5188,19 @@ enum nvme_cmd_format_pil { }; /** - * enum nvme_cmd_format_ses - - * @NVME_FORMAT_SES_NONE: - * @NVME_FORMAT_SES_USER_DATA_ERASE: - * @NVME_FORMAT_SES_CRYPTO_ERASE: + * 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. + * @NVME_FORMAT_SES_CRYPTO_ERASE: Cryptographic Erase: All user data shall + * be erased cryptographically. This is + * accomplished by deleting the encryption key. */ enum nvme_cmd_format_ses { NVME_FORMAT_SES_NONE = 0, @@ -5190,11 +5291,11 @@ enum nvme_directive_send_identify_endir { }; /** - * enum nvme_sanitize_sanact - - * @NVME_SANITIZE_SANACT_EXIT_FAILURE: - * @NVME_SANITIZE_SANACT_START_BLOCK_ERASE: - * @NVME_SANITIZE_SANACT_START_OVERWRITE: - * @NVME_SANITIZE_SANACT_START_CRYPTO_ERASE: + * enum nvme_sanitize_sanact - Sanitize Action + * @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. */ enum nvme_sanitize_sanact { NVME_SANITIZE_SANACT_EXIT_FAILURE = 1, From 753a7eede27fb6fbd8548552a2b236066d5ab152 Mon Sep 17 00:00:00 2001 From: Tomas Bzatek Date: Thu, 4 Nov 2021 17:43:02 +0100 Subject: [PATCH 0230/1564] build: Change library version to be a valid number pkg-config file version number should be a valid number to make version comparison actually work. --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index be7d5a7210..9c2c3834e8 100644 --- a/meson.build +++ b/meson.build @@ -61,7 +61,7 @@ project( 'libnvme', ['c', 'cpp'], meson_version: '>= 0.47.0', - version: 'v0.1', + version: '0.1', license: 'LGPLv2+', default_options: [ 'buildtype=release', From e6b2258454f51910881bb274d50a02f4d74874c4 Mon Sep 17 00:00:00 2001 From: Martin Belanger Date: Thu, 11 Nov 2021 10:07:00 -0500 Subject: [PATCH 0231/1564] Fix host_iface offset. This was a copy-paste typo. Signed-off-by: Martin Belanger --- src/nvme/tree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 0f72320f17..7a9637e391 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -1193,7 +1193,7 @@ static nvme_ctrl_t nvme_ctrl_alloc(nvme_subsystem_t s, const char *path, else if (!strncmp(a, "host_traddr=", 12)) host_traddr = a + 12; else if (!strncmp(a, "host_iface=", 11)) - host_iface = a + 12; + host_iface = a + 11; a = strtok_r(NULL, ",", &e); } } From d7c2dd59633fb0485edb5f6093d87154b19ace72 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 11 Nov 2021 16:09:41 -0500 Subject: [PATCH 0232/1564] libnvme: core dump when running nvme persistent-event-log MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [root@ltczz405-lp2 nvme-cli]# ./nvme persistent-event-log -a 0 /dev/nvme0>out [20748.494262] nvme[9059]: segfault (11) at 7fff8cf20007 nip 10024828 lr 10024824 code 2 in nvme[10000000+c0000] [20748.494288] nvme[9059]: code: 3b9c0024 3b7b0001 4bfddb41 e8410018 889cffe6 7e439378 4bfddb31 e8410018 [20748.494295] nvme[9059]: code: 889cffe7 e8610068 4bfddb21 e8410018 <809cfff4> e8610070 4bfddb11 e8410018 Segmentation fault (core dumped) Saw the segmentation fault. Also looks only the first event is good. Other events are like random stuff. Persistent Event Log for device: nvme0 Action for Persistent Event Log: 0 Log Identifier: 13 Total Number of Events: 6963 Total Log Length : 674496 Log Revision: 1 Log Header Length: 492 Timestamp: 564586531692487 Power On Hours (POH): 5,576 Power Cycle Count: 92 PCI Vendor ID (VID): 5197 PCI Subsystem Vendor ID (SSVID): 4116 Serial Number (SN): S4WANE0N300041 Model Number (MN): PCIe4 1.6TB NVMe Flash Adapter x8 NVM Subsystem NVMe Qualified Name (SUBNQN): nqn.1994-11.com.samsung:nvme:PM1735:: HHHL:S4WANE0N300041 Supported Events Bitmap: BitMap[0] is 0xfe BitMap[1] is 0x3f Persistent Event Entries: Event Type: 1 Event Type Revision: 1 Event Header Length: 21 Controller Identifier: 66 Event Timestamp: 0 Vendor Specific Information Length: 512 Event Length: 10496 Smart Health Event: Smart Log for NVME device:nvme0 namespace-id:ffffffff critical_warning : 0 temperature : 24°C (297 Kelvin) available_spare : 100% available_spare_threshold : 10% percentage_used : 1% endurance group critical warning summary: 0 data_units_read : 0 data_units_written Event Type: 82 --------------->wrong event type?? Event Type Revision: 69 Event Header Length: 86 Controller Identifier: 20563 Event Timestamp: 65 Vendor Specific Information Length: 0 Event Length: 88 Reserved Event Event Type: 242 -------->wrong event type? Event Type Revision: 206 Event Header Length: 4 Controller Identifier: 0 Event Timestamp: 5039920509769225473 Vendor Specific Information Length: 0 Event Length: 0 Reserved Event Signed-off-by: Wen Xiong --- src/nvme/types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nvme/types.h b/src/nvme/types.h index 5118d7f518..3b9e2b0963 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -2919,7 +2919,7 @@ struct nvme_persistent_event_entry { __u8 rsvd14[6]; __le16 vsil; __le16 el; -}; +} __attribute__((packed)); enum nvme_persistent_event_types { NVME_PEL_SMART_HEALTH_EVENT = 0x01, From 5d14afb8dbae88a71c8d2d627914071b445f7110 Mon Sep 17 00:00:00 2001 From: Steven Seungcheol Lee Date: Thu, 28 Oct 2021 12:39:30 +0900 Subject: [PATCH 0233/1564] types: fix wrong bits nvme_id_psd apw[178:176], aps[183:182] Signed-off-by: Steven Seungcheol Lee --- doc/libnvme.rst | 15 ++++++--------- doc/man/struct nvme_id_psd.2 | 15 ++++++--------- src/nvme/types.h | 13 ++++++------- 3 files changed, 18 insertions(+), 25 deletions(-) diff --git a/doc/libnvme.rst b/doc/libnvme.rst index d52462fd5a..f9e1cc9ada 100644 --- a/doc/libnvme.rst +++ b/doc/libnvme.rst @@ -6280,9 +6280,8 @@ Returns true if given offset is 64bit register, otherwise it returns false. __u8 ips; __u8 rsvd19; __le16 actp; - __u8 apw; - __u8 aps; - __u8 rsvd23[8]; + __u8 apws; + __u8 rsvd23[9]; }; **Members** @@ -6340,15 +6339,13 @@ Returns true if given offset is 64bit register, otherwise it returns false. NVM subsystem over a 10 second period in this power state with the workload indicated in the Active Power Workload field. -``apw`` - Active Power Workload indicates the workload used to calculate +``apws`` + Bits 7-6: Active Power Scale(APS) indicates the scale for the :c:type:`struct + nvme_id_psd `.actp, see :c:type:`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 :c:type:`enum nvme_psd_workload ` for decoding this field. -``aps`` - Active Power Scale indicates the scale for the :c:type:`struct - nvme_id_psd `.actp, see :c:type:`enum nvme_psd_ps ` for decoding this value. - diff --git a/doc/man/struct nvme_id_psd.2 b/doc/man/struct nvme_id_psd.2 index d990aeb9e3..561845ec31 100644 --- a/doc/man/struct nvme_id_psd.2 +++ b/doc/man/struct nvme_id_psd.2 @@ -30,11 +30,9 @@ struct nvme_id_psd { .br .BI " __le16 actp;" .br -.BI " __u8 apw;" +.BI " __u8 apws;" .br -.BI " __u8 aps;" -.br -.BI " __u8 rsvd23[8];" +.BI " __u8 rsvd23[9];" .br .BI " }; @@ -83,10 +81,9 @@ see \fIenum nvme_psd_ps\fP for decoding this field. 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. -.IP "apw" 12 -Active Power Workload indicates the workload used to calculate +.IP "apws" 12 +Bits 7-6: Active Power Scale(APS) indicates the scale for the \fIstruct +nvme_id_psd\fP.actp, see \fIenum nvme_psd_ps\fP for decoding this value. +Bits 2-0: Active Power Workload(APW) indicates the workload used to calculate maximum power for this power state. See \fIenum nvme_psd_workload\fP for decoding this field. -.IP "aps" 12 -Active Power Scale indicates the scale for the \fIstruct -nvme_id_psd\fP.actp, see \fIenum nvme_psd_ps\fP for decoding this value. diff --git a/src/nvme/types.h b/src/nvme/types.h index 5118d7f518..6b157cc3bc 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -652,11 +652,11 @@ enum nvme_psd_workload { * @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. - * @apw: Active Power Workload indicates the workload used to calculate - * maximum power for this power state. See &enum nvme_psd_workload for - * decoding this field. - * @aps: Active Power Scale indicates the scale for the &struct + * @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. */ struct nvme_id_psd { __le16 mp; @@ -672,9 +672,8 @@ struct nvme_id_psd { __u8 ips; __u8 rsvd19; __le16 actp; - __u8 apw; - __u8 aps; - __u8 rsvd23[8]; + __u8 apws; + __u8 rsvd23[9]; }; /** From 616a26c396db2ce8e8c9230d7de094653392d91c Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 15 Nov 2021 15:29:46 +0100 Subject: [PATCH 0234/1564] Add json config schema Add a schema file to describe the JSON configuration file format. Signed-off-by: Hannes Reinecke Reviewed-by: Keith Busch --- doc/config-schema.json | 143 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 doc/config-schema.json diff --git a/doc/config-schema.json b/doc/config-schema.json new file mode 100644 index 0000000000..53e6ffb78b --- /dev/null +++ b/doc/config-schema.json @@ -0,0 +1,143 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://github.com/linux-nvme/libnvme/doc/config-schema.json", + "title": "config.json", + "description": "libnvme JSON configuration", + "type": "object", + "properties": { + "hosts": { + "description": "Array of NVMe Host properties", + "type": "array", + "items": { "$ref": "#/$defs/host" } + } + }, + "$defs": { + "host": { + "description": "NVMe Host properties", + "type": "object", + "properties": { + "hostnqn": { + "description": "NVMe host NQN", + "type": "string", + "maxLength": 223 + }, + "hostid": { + "description": "NVMe host ID", + "type": "string" + }, + "required": [ "hostnqn" ], + "subsystems": { + "description": "Array of NVMe subsystem properties", + "type": "array", + "items": { "$ref": "#/$defs/subsystem" } + } + } + }, + "subsystem": { + "description": "NVMe subsystem properties", + "type": "object", + "properties": { + "nqn": { + "description": "Subsystem NQN", + "type": "string", + "maxLength": 223 + }, + "ports": { + "description": "Array of NVMe subsystem ports", + "type": "array", + "items": { "$ref": "#/$defs/port" } + }, + "required": [ "nqn" ] + } + }, + "port": { + "description": "NVMe subsystem port", + "type": "object", + "properties": { + "transport": { + "description": "Transport type", + "type": "string" + }, + "traddr": { + "description": "Transport address", + "type": "string" + }, + "host_traddr": { + "description": "Host transport address", + "type": "string" + }, + "host_iface": { + "description": "Host interface name", + "type": "string" + }, + "trsvcid": { + "description": "Transport service identifier", + "type": "string" + }, + "nr_io_queues": { + "description": "Number of I/O queues", + "type": "integer" + }, + "nr_write_queues": { + "description": "Number of write queues", + "type": "integer" + }, + "nr_poll_queues": { + "description": "Number of poll queues", + "type": "integer" + }, + "queue_size": { + "description": "Queue size", + "type": "integer" + }, + "keep_alive_tmo": { + "description": "Keep-Alive timeout (in seconds)", + "type": "integer" + }, + "reconnect_delay": { + "description": "Reconnect delay (in seconds)", + "type": "integer" + }, + "ctrl_loss_tmo": { + "description": "Controller loss timeout (in seconds)", + "type": "integer" + }, + "fast_io_fail_tmo": { + "description": "Fast I/O Fail timeout (in seconds)", + "type": "integer", + "default": 600 + }, + "tos": { + "description": "Type of service", + "type": "integer", + "default": -1 + }, + "duplicate_connect": { + "description": "Allow duplicate connections", + "type": "boolean", + "default": false + }, + "disable_sqflow": { + "description": "Explicitly disable SQ flow control", + "type": "boolean", + "default": false + }, + "hdr_digest": { + "description": "Enable header digest", + "type": "boolean", + "default": false + }, + "data_digest": { + "description": "Enable data digest", + "type": "boolean", + "default": false + }, + "persistent": { + "description": "Create persistent discovery connection", + "type": "boolean" + } + }, + "required": [ "transport" ] + } + } +} From 1fd588dcef1881544251bc465468fa5fb6fcc392 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 16 Nov 2021 10:21:18 +0100 Subject: [PATCH 0235/1564] Remove references to nvme_ctrl_get_nqn() Stale reference, function is not implemented. Signed-off-by: Hannes Reinecke --- doc/libnvme.rst | 8 -------- doc/man/nvme_ctrl_get_nqn.2 | 8 -------- src/libnvme.map | 1 - 3 files changed, 17 deletions(-) delete mode 100644 doc/man/nvme_ctrl_get_nqn.2 diff --git a/doc/libnvme.rst b/doc/libnvme.rst index d52462fd5a..aa2e08b2d8 100644 --- a/doc/libnvme.rst +++ b/doc/libnvme.rst @@ -5763,14 +5763,6 @@ The nvme command status if a response was received (see ``nvme_ctrl_t c`` -.. c:function:: const char * nvme_ctrl_get_nqn (nvme_ctrl_t c) - - -**Parameters** - -``nvme_ctrl_t c`` - - .. c:function:: const char * nvme_ctrl_get_subsysnqn (nvme_ctrl_t c) diff --git a/doc/man/nvme_ctrl_get_nqn.2 b/doc/man/nvme_ctrl_get_nqn.2 deleted file mode 100644 index 47180ac2c9..0000000000 --- a/doc/man/nvme_ctrl_get_nqn.2 +++ /dev/null @@ -1,8 +0,0 @@ -.TH "nvme_ctrl_get_nqn" 2 "nvme_ctrl_get_nqn" "February 2020" "libnvme Manual" -.SH NAME -nvme_ctrl_get_nqn \- -.SH SYNOPSIS -.B "const char *" nvme_ctrl_get_nqn -.BI "(nvme_ctrl_t " c ");" -.SH ARGUMENTS -.IP "c" 12 diff --git a/src/libnvme.map b/src/libnvme.map index 40050cff91..36adfc68bf 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -18,7 +18,6 @@ nvme_ctrl_get_host_traddr; nvme_ctrl_get_model; nvme_ctrl_get_name; - nvme_ctrl_get_nqn; nvme_ctrl_get_numa_node; nvme_ctrl_get_queue_count; nvme_ctrl_get_serial; From ad12800c3993566bc6eddd5afd238fd2ad1bbe97 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 16 Nov 2021 10:25:49 +0100 Subject: [PATCH 0236/1564] fabrics: use nvme_msg() instead of fprintf() Commit d569afca ("fabrics: restore hostname traddr support") used fprintf() instead of nvme_msg(). Fix it up. Signed-off-by: Hannes Reinecke --- src/nvme/fabrics.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 43c4fb1f2f..64ba10d41e 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -338,7 +338,7 @@ static int hostname2traddr(nvme_ctrl_t c) ret = getaddrinfo(c->traddr, NULL, &hints, &host_info); if (ret) { - fprintf(stderr, "failed to resolve host %s info\n", c->traddr); + nvme_msg(LOG_ERR, "failed to resolve host %s info\n", c->traddr); return ret; } @@ -354,14 +354,14 @@ static int hostname2traddr(nvme_ctrl_t c) addrstr, NVMF_TRADDR_SIZE); break; default: - fprintf(stderr, "unrecognized address family (%d) %s\n", + nvme_msg(LOG_ERR, "unrecognized address family (%d) %s\n", host_info->ai_family, c->traddr); ret = -EINVAL; goto free_addrinfo; } if (!p) { - fprintf(stderr, "failed to get traddr for %s\n", c->traddr); + nvme_msg(LOG_ERR, "failed to get traddr for %s\n", c->traddr); ret = -errno; goto free_addrinfo; } From 34fae2c9c28db833d75753ba23cc7a8bbe486cad Mon Sep 17 00:00:00 2001 From: Jonathan Teh Date: Mon, 15 Nov 2021 18:02:00 +0000 Subject: [PATCH 0237/1564] tree: fix memory leak in nvme_ctrl_lookup_subsystem_name Ensure all dirents are freed when a successful stat(2) causes an early break out of the loop. Reproduced with valgrind running "nvme discover" against an NVMe-oF target: ==34612== 32 bytes in 1 blocks are definitely lost in loss record 2 of 2 ==34612== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==34612== by 0x4963A4C: __scandir64_tail (scandir-tail-common.c:69) ==34612== by 0x16E77D: nvme_ctrl_lookup_subsystem_name.isra.0 (tree.c:1024) ==34612== by 0x170081: nvme_init_ctrl (tree.c:1100) ==34612== by 0x16DA1F: nvmf_add_ctrl (fabrics.c:558) ==34612== by 0x136B03: nvmf_discover (fabrics.c:516) ==34612== by 0x139999: handle_plugin (plugin.c:155) ==34612== by 0x1131E9: main (nvme.c:5967) Signed-off-by: Jonathan Teh Reviewed-by: Keith Busch Signed-off-by: Daniel Wagner --- src/nvme/tree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 7a9637e391..2950ddf51b 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -1035,7 +1035,7 @@ static char *nvme_ctrl_lookup_subsystem_name(nvme_ctrl_t c) subsys_name = strdup(subsys[i]->d_name); break; } - nvme_free_dirents(subsys, i); + nvme_free_dirents(subsys, ret); return subsys_name; } From a91e97340febf07eef64af46574ae230c73280fb Mon Sep 17 00:00:00 2001 From: Gollu Appalanaidu Date: Sat, 12 Jun 2021 02:54:56 +0530 Subject: [PATCH 0238/1564] nvme: add identify controller structure 2.0 spec. fields Signed-off-by: Gollu Appalanaidu [dwagner: ported from nvme-cli-monolithic] Signed-off-by: Daniel Wagner --- src/nvme/types.h | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/nvme/types.h b/src/nvme/types.h index 6b157cc3bc..7b95cf8bb9 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -814,6 +814,10 @@ struct nvme_id_psd { * groups supported by this controller. * @pels: Persistent Event Log Size indicates the maximum reportable size * for the Persistent Event Log. + * @domainid: Domain Identifier indicates the identifier of the domain + * that contains this controller. + * @megcap: Max Endurance Group Capacity indicates the maximum capacity + * of a single Endurance Group. * @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 @@ -849,6 +853,12 @@ struct nvme_id_psd { * @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. + * @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. + * @maxcna: Maximum I/O Controller Namespace Attachments indicates the + * maximum number of namespaces that are allowed to be attached to + * this I/O controller. * @subnqn: NVM Subsystem NVMe Qualified Name, UTF-8 null terminated string * @ioccsz: I/O Queue Command Capsule Supported Size, defines the maximum * I/O command capsule size in 16 byte units. @@ -926,7 +936,10 @@ struct nvme_id_ctrl { __le32 anagrpmax; __le32 nanagrpid; __le32 pels; - __u8 rsvd356[156]; + __le16 domainid; + __u8 rsvd358[10]; + __u8 megcap[16]; + __u8 rsvd384[128]; __u8 sqes; __u8 cqes; __le16 maxcmd; @@ -943,7 +956,9 @@ struct nvme_id_ctrl { __u8 rsvd534[2]; __le32 sgls; __le32 mnan; - __u8 rsvd544[224]; + __u8 maxdna[16]; + __le32 maxcna; + __u8 rsvd564[204]; char subnqn[NVME_NQN_LENGTH]; __u8 rsvd1024[768]; From b262da477ad144b467b71671572b67f829520179 Mon Sep 17 00:00:00 2001 From: Gollu Appalanaidu Date: Wed, 3 Nov 2021 14:13:46 +0100 Subject: [PATCH 0239/1564] ioctl: add CDW2 and CDW3 support for Write Zeroes and Verify Command Added support for the Variable Sized Expected Logical Block Storage Tag(ELBST) and Expected Logical Block Reference Tag (ELBRT), CDW2 and CDW3 (00:47) bits for NVM commands Write Zeroes and Verify commands. Signed-off-by: Gollu Appalanaidu [dwagner: ported from nvme-cli-monolithic] Signed-off-by: Daniel Wagner --- src/nvme/ioctl.c | 24 +++++++++++++++--------- src/nvme/ioctl.h | 11 +++++++++-- src/nvme/tree.c | 4 ++-- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 1cd8d22a5d..5b0705cfa4 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -1666,8 +1666,11 @@ int nvme_flush(int fd, __u32 nsid) static int nvme_io(int fd, __u8 opcode, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 flags, __u32 reftag, __u16 apptag, __u16 appmask, - __u32 data_len, void *data, __u32 metadata_len, void *metadata) + __u64 storage_tag, __u32 data_len, void *data, __u32 metadata_len, + void *metadata) { + __u32 cdw2 = storage_tag & 0xffffffff; + __u32 cdw3 = (storage_tag >> 32) & 0xffff; __u32 cdw10 = slba & 0xffffffff; __u32 cdw11 = slba >> 32; __u32 cdw12 = nlb | (control << 16); @@ -1678,6 +1681,8 @@ static int nvme_io(int fd, __u8 opcode, __u32 nsid, __u64 slba, __u16 nlb, struct nvme_passthru_cmd cmd = { .opcode = opcode, .nsid = nsid, + .cdw2 = cdw2, + .cdw3 = cdw3, .cdw10 = cdw10, .cdw11 = cdw11, .cdw12 = cdw12, @@ -1698,7 +1703,7 @@ int nvme_read(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 data_len, void *data, __u32 metadata_len, void *metadata) { return nvme_io(fd, nvme_cmd_read, nsid, slba, nlb, control, dsm, - reftag, apptag, appmask, data_len, data, metadata_len, + reftag, apptag, appmask, 0, data_len, data, metadata_len, metadata); } @@ -1710,7 +1715,7 @@ int nvme_write(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 flags = dsm | dspec << 16; return nvme_io(fd, nvme_cmd_write, nsid, slba, nlb, control, flags, - reftag, apptag, appmask, data_len, data, metadata_len, + reftag, apptag, appmask, 0, data_len, data, metadata_len, metadata); } @@ -1719,28 +1724,29 @@ int nvme_compare(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, void *data, __u32 metadata_len, void *metadata) { return nvme_io(fd, nvme_cmd_compare, nsid, slba, nlb, control, 0, - reftag, apptag, appmask, data_len, data, metadata_len, + reftag, apptag, appmask, 0, data_len, data, metadata_len, metadata); } int nvme_write_zeros(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, - __u32 reftag, __u16 apptag, __u16 appmask) + __u32 reftag, __u16 apptag, __u16 appmask, + __u64 storage_tag) { return nvme_io(fd, nvme_cmd_write_zeroes, nsid, slba, nlb, control, 0, - reftag, apptag, appmask, 0, NULL, 0, NULL); + reftag, apptag, appmask, storage_tag, 0, NULL, 0, NULL); } int nvme_verify(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, - __u32 reftag, __u16 apptag, __u16 appmask) + __u32 reftag, __u16 apptag, __u16 appmask, __u64 storage_tag) { return nvme_io(fd, nvme_cmd_verify, nsid, slba, nlb, control, 0, - reftag, apptag, appmask, 0, NULL, 0, NULL); + reftag, apptag, appmask, 0, 0, NULL, 0, NULL); } int nvme_write_uncorrectable(int fd, __u32 nsid, __u64 slba, __u16 nlb) { return nvme_io(fd, nvme_cmd_write_uncor, nsid, slba, nlb, 0, 0, 0, 0, - 0, 0, NULL, 0, NULL); + 0, 0, 0, NULL, 0, NULL); } int nvme_dsm(int fd, __u32 nsid, __u32 attrs, __u16 nr_ranges, diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index faeae5d8b5..f473721256 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -2338,6 +2338,9 @@ int nvme_compare(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, * @appmask: This field specifies the Application Tag expected value. Used * only if the namespace is formatted to use end-to-end protection * information. + * @storage_tag: This filed specifies Variable Sized Expected Logical Block + * Storage Tag (ELBST) and Expected Logical Block Reference + * Tag (ELBRT) * * The Write Zeroes command sets a range of logical blocks to zero. After * successful completion of this command, the value returned by subsequent @@ -2348,7 +2351,8 @@ int nvme_compare(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_write_zeros(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, - __u32 reftag, __u16 apptag, __u16 appmask); + __u32 reftag, __u16 apptag, __u16 appmask, + __u64 storage_tag); /** * nvme_write_uncorrectable() - Submit an nvme write uncorrectable command @@ -2383,6 +2387,9 @@ int nvme_write_uncorrectable(int fd, __u32 nsid, __u64 slba, __u16 nlb); * @appmask: This field specifies the Application Tag expected value. Used * only if the namespace is formatted to use end-to-end protection * information. + * @storage_tag: This filed specifies Variable Sized Expected Logical Block + * Storage Tag (ELBST) and Expected Logical Block Reference + * Tag (ELBRT) * * The Verify command verifies integrity of stored information by reading data * and metadata, if applicable, for the LBAs indicated without transferring any @@ -2392,7 +2399,7 @@ int nvme_write_uncorrectable(int fd, __u32 nsid, __u64 slba, __u16 nlb); * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_verify(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, - __u32 reftag, __u16 apptag, __u16 appmask); + __u32 reftag, __u16 apptag, __u16 appmask, __u64 storage_tag); /** * nvme_dsm() - Send an nvme data set management command diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 2950ddf51b..8613f23589 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -1418,7 +1418,7 @@ int nvme_ns_verify(nvme_ns_t n, off_t offset, size_t count) return -1; return nvme_verify(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), slba, nlb, - 0, 0, 0, 0); + 0, 0, 0, 0, 0); } int nvme_ns_write_uncorrectable(nvme_ns_t n, off_t offset, size_t count) @@ -1442,7 +1442,7 @@ int nvme_ns_write_zeros(nvme_ns_t n, off_t offset, size_t count) return -1; return nvme_write_zeros(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), slba, - nlb, 0, 0, 0, 0); + nlb, 0, 0, 0, 0, 0); } int nvme_ns_write(nvme_ns_t n, void *buf, off_t offset, size_t count) From 3c1339c09c327d3a50097602e9c6d58e3516d727 Mon Sep 17 00:00:00 2001 From: Gollu Appalanaidu Date: Wed, 3 Nov 2021 15:31:45 +0100 Subject: [PATCH 0240/1564] ioctl: Change IOCTL for read, write and compare commands Change the IOCTL and depricate SQE structure for NVM commands Read, Write and Compare Commands to add support for the Storage Tag field (CDW2 and CDW3). Signed-off-by: Gollu Appalanaidu [dwagner: ported from nvme-cli-monolithic] Signed-off-by: Daniel Wagner --- src/nvme/ioctl.c | 15 ++++++++------- src/nvme/ioctl.h | 13 ++++++++++--- src/nvme/tree.c | 4 ++-- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 5b0705cfa4..b14f6f6f32 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -1700,23 +1700,24 @@ static int nvme_io(int fd, __u8 opcode, __u32 nsid, __u64 slba, __u16 nlb, int nvme_read(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u8 dsm, __u32 reftag, __u16 apptag, __u16 appmask, - __u32 data_len, void *data, __u32 metadata_len, void *metadata) + __u64 storage_tag, __u32 data_len, void *data, + __u32 metadata_len, void *metadata) { return nvme_io(fd, nvme_cmd_read, nsid, slba, nlb, control, dsm, - reftag, apptag, appmask, 0, data_len, data, metadata_len, - metadata); + reftag, apptag, appmask, storage_tag, data_len, data, + metadata_len, metadata); } int nvme_write(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u8 dsm, __u16 dspec, __u32 reftag, __u16 apptag, - __u16 appmask, __u32 data_len, void *data, __u32 metadata_len, - void *metadata) + __u16 appmask, __u64 storage_tag, __u32 data_len, void *data, + __u32 metadata_len, void *metadata) { __u32 flags = dsm | dspec << 16; return nvme_io(fd, nvme_cmd_write, nsid, slba, nlb, control, flags, - reftag, apptag, appmask, 0, data_len, data, metadata_len, - metadata); + reftag, apptag, appmask, storage_tag, data_len, data, + metadata_len, metadata); } int nvme_compare(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index f473721256..a5f8c80555 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -2251,6 +2251,9 @@ int nvme_flush(int fd, __u32 nsid); * @appmask: This field specifies the Application Tag expected value. Used * only if the namespace is formatted to use end-to-end protection * information. + * @storage_tag: This filed specifies Variable Sized Expected Logical Block + * Storage Tag (ELBST) and Expected Logical Block Reference + * Tag (ELBRT) * @data_len: Length of user buffer, @data, in bytes * @data: Pointer to user address of the data buffer * metadata_len:Length of user buffer, @metadata, in bytes @@ -2261,7 +2264,8 @@ int nvme_flush(int fd, __u32 nsid); */ int nvme_read(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u8 dsm, __u32 reftag, __u16 apptag, __u16 appmask, - __u32 data_len, void *data, __u32 metadata_len, void *metadata); + __u64 storage_tag, __u32 data_len, void *data, + __u32 metadata_len, void *metadata); /** * nvme_write() - Submit an nvme user write command @@ -2281,6 +2285,9 @@ int nvme_read(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, * @appmask: This field specifies the Application Tag expected value. Used * only if the namespace is formatted to use end-to-end protection * information. + * @storage_tag: This filed specifies Variable Sized Expected Logical Block + * Storage Tag (ELBST) and Expected Logical Block Reference + * Tag (ELBRT) * @data_len: Length of user buffer, @data, in bytes * @data: Pointer to user address of the data buffer * metadata_len:Length of user buffer, @metadata, in bytes @@ -2291,8 +2298,8 @@ int nvme_read(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, */ int nvme_write(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u8 dsm, __u16 dspec, __u32 reftag, __u16 apptag, - __u16 appmask, __u32 data_len, void *data, __u32 metadata_len, - void *metadata); + __u16 appmask, __u64 storage_tag, __u32 data_len, void *data, + __u32 metadata_len, void *metadata); /** * nvme_compare() - Submit an nvme user compare command diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 8613f23589..48b3919cfb 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -1454,7 +1454,7 @@ int nvme_ns_write(nvme_ns_t n, void *buf, off_t offset, size_t count) return -1; return nvme_write(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), slba, nlb, 0, - 0, 0, 0, 0, 0, count, buf, 0, NULL); + 0, 0, 0, 0, 0, 0, count, buf, 0, NULL); } int nvme_ns_read(nvme_ns_t n, void *buf, off_t offset, size_t count) @@ -1466,7 +1466,7 @@ int nvme_ns_read(nvme_ns_t n, void *buf, off_t offset, size_t count) return -1; return nvme_read(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), slba, nlb, 0, - 0, 0, 0, 0, count, buf, 0, NULL); + 0, 0, 0, 0, 0, count, buf, 0, NULL); } int nvme_ns_compare(nvme_ns_t n, void *buf, off_t offset, size_t count) From 82c2f3db87823ea2ceae09928916d8b96ef3dd74 Mon Sep 17 00:00:00 2001 From: Gollu Appalanaidu Date: Wed, 3 Nov 2021 17:05:19 +0100 Subject: [PATCH 0241/1564] ioctl: add multiple update detected result value in fw commit Add Multiple Update Detected (MUD) field in FW Commit command CQE CDW0 as per NVMe 2.0 Spec. Signed-off-by: Gollu Appalanaidu [dwagner: ported from nvme-cli-monolithic] Signed-off-by: Daniel Wagner --- src/nvme/ioctl.c | 5 +++-- src/nvme/ioctl.h | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index b14f6f6f32..deb0c8dc22 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -1342,7 +1342,8 @@ int nvme_fw_download(int fd, __u32 offset, __u32 data_len, void *data) return nvme_submit_admin_passthru(fd, &cmd, NULL); } -int nvme_fw_commit(int fd, __u8 slot, enum nvme_fw_commit_ca action, bool bpid) +int nvme_fw_commit(int fd, __u8 slot, enum nvme_fw_commit_ca action, bool bpid, + __u32 *result) { __u32 cdw10 = NVME_SET(slot, FW_COMMIT_CDW10_FS) | NVME_SET(action, FW_COMMIT_CDW10_CA) | @@ -1353,7 +1354,7 @@ int nvme_fw_commit(int fd, __u8 slot, enum nvme_fw_commit_ca action, bool bpid) .cdw10 = cdw10, }; - return nvme_submit_admin_passthru(fd, &cmd, NULL); + return nvme_submit_admin_passthru(fd, &cmd, result); } int nvme_security_send(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index a5f8c80555..0949e5a60e 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -1917,6 +1917,7 @@ int nvme_fw_download(int fd, __u32 offset, __u32 data_len, void *data); * @slot: Firmware slot to commit the downloaded image * @action: Action to use for the firmware image, see &enum nvme_fw_commit_ca * @bpid: Set to true to select the boot partition id + * @result: The command completion result from CQE dword0 * * The Firmware Commit command modifies the firmware image or Boot Partitions. * @@ -1926,7 +1927,8 @@ int nvme_fw_download(int fd, __u32 offset, __u32 data_len, void *data); * response may specify additional * reset actions required to complete the commit process. */ -int nvme_fw_commit(int fd, __u8 slot, enum nvme_fw_commit_ca action, bool bpid); +int nvme_fw_commit(int fd, __u8 slot, enum nvme_fw_commit_ca action, bool bpid, + __u32 *result); /** * nvme_security_send() - From c8d94574c02dc468836e24f7c4f843166d21646d Mon Sep 17 00:00:00 2001 From: Gollu Appalanaidu Date: Wed, 3 Nov 2021 17:32:37 +0100 Subject: [PATCH 0242/1564] types: add capacity management command support Host software issues this Capacity Management command to configure/Create/Delete Endurance Groups and NVM Sets in an NVM subsystem. Signed-off-by: Gollu Appalanaidu Signed-off-by: Karthik Balan [dwagner: - ported from nvme-cli-monolithic - renamed nvme_cap_mgmt to nmve_capacity_mgmt] Signed-off-by: Daniel Wagner --- src/libnvme.map | 1 + src/nvme/ioctl.c | 15 +++++++++++++++ src/nvme/ioctl.h | 17 +++++++++++++++++ src/nvme/types.h | 2 ++ 4 files changed, 35 insertions(+) diff --git a/src/libnvme.map b/src/libnvme.map index 36adfc68bf..03cd6b2060 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -5,6 +5,7 @@ nvme_admin_passthru64; nvme_admin_passthru; nvme_attach_ns; + nvme_capacity_mgmt; nvme_compare; nvme_copy; nvme_create_ctrl; diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index deb0c8dc22..4d4b88dcba 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -1542,6 +1542,21 @@ int nvme_directive_recv_stream_allocate(int fd, __u32 nsid, __u16 nsr, dtype, nsr, 0, NULL, result); } +int nvme_capacity_mgmt(int fd, __u8 op, __u16 element_id, __u32 dw11, __u32 dw12, + __u32 *result) +{ + __u32 dw10 = op | element_id << 16; + + struct nvme_passthru_cmd cmd = { + .opcode = nvme_admin_capacity_mgmt, + .cdw10 = dw10, + .cdw11 = dw11, + .cdw12 = dw12, + }; + + return nvme_submit_admin_passthru(fd, &cmd, result); +} + int nvme_set_property(int fd, int offset, __u64 value) { __u32 cdw10 = nvme_is_64bit_reg(offset); diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 0949e5a60e..41ae115eba 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -2123,6 +2123,23 @@ int nvme_directive_recv_stream_status(int fd, __u32 nsid, unsigned nr_entries, int nvme_directive_recv_stream_allocate(int fd, __u32 nsid, __u16 nsr, __u32 *result); +/** + * nvme_capacity_mgmt() - + * @fd: File descriptor of nvme device + * @op: Operation to be performed by the controller + * @element_id: Value specific to the value of the Operation field + * @dw11: Least significant 32 bits of the capacity in bytes of the + * Endurance Group or NVM Set to be created + * @dw12: Most significant 32 bits of the capacity in bytes of the + * Endurance Group or NVM Set to be created + * @result: If successful, the CQE dword0 value + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_capacity_mgmt(int fd, __u8 op, __u16 element_id, __u32 dw11, __u32 dw12, + __u32 *result); + /** * nvme_set_property() - Set controller property * @fd: File descriptor of nvme device diff --git a/src/nvme/types.h b/src/nvme/types.h index 7b95cf8bb9..7121c57ff4 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -4854,6 +4854,7 @@ static inline __u16 nvme_status_code(__u16 status_field) * @nvme_admin_virtual_mgmt: * @nvme_admin_nvme_mi_send: * @nvme_admin_nvme_mi_recv: + * @nvme_admin_capacity_mgmt: * @nvme_admin_dbbuf: * @nvme_admin_fabrics: * @nvme_admin_format_nvm: @@ -4885,6 +4886,7 @@ enum nvme_admin_opcode { nvme_admin_virtual_mgmt = 0x1c, nvme_admin_nvme_mi_send = 0x1d, nvme_admin_nvme_mi_recv = 0x1e, + nvme_admin_capacity_mgmt = 0x20, nvme_admin_dbbuf = 0x7c, nvme_admin_fabrics = 0x7f, nvme_admin_format_nvm = 0x80, From 71ff409421f14b09f1beadad76b97f16863053e0 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 4 Nov 2021 10:32:46 +0100 Subject: [PATCH 0243/1564] types: Add Identify CNS 0x18 Domain List Support Signed-off-by: Daniel Wagner --- src/libnvme.map | 1 + src/nvme/ioctl.c | 50 ++++++++++++++++++++++++++++++++---------------- src/nvme/ioctl.h | 24 +++++++++++++++++++++-- src/nvme/types.h | 34 ++++++++++++++++++++++++++++++++ 4 files changed, 91 insertions(+), 18 deletions(-) diff --git a/src/libnvme.map b/src/libnvme.map index 03cd6b2060..841dc0bb26 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -139,6 +139,7 @@ nvme_identify_allocated_ns_list; nvme_identify_ctrl; nvme_identify_ctrl_list; + nvme_identify_domain_list; nvme_identify_iocs; nvme_identify_ns; nvme_identify_ns_descs; diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 4d4b88dcba..3f00f3cf7f 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -239,11 +239,13 @@ enum nvme_cmd_dword_fields { NVME_IDENTIFY_CDW10_CNS_SHIFT = 0, NVME_IDENTIFY_CDW10_CNTID_SHIFT = 16, NVME_IDENTIFY_CDW11_NVMSETID_SHIFT = 0, + NVME_IDENTIFY_CDW11_DOMID_SHIFT = 0, NVME_IDENTIFY_CDW14_UUID_SHIFT = 0, NVME_IDENTIFY_CDW11_CSI_SHIFT = 24, NVME_IDENTIFY_CDW10_CNS_MASK = 0xff, NVME_IDENTIFY_CDW10_CNTID_MASK = 0xffff, NVME_IDENTIFY_CDW11_NVMSETID_MASK = 0xffff, + NVME_IDENTIFY_CDW11_DOMID_MASK = 0xffff, NVME_IDENTIFY_CDW14_UUID_MASK = 0x7f, NVME_IDENTIFY_CDW11_CSI_MASK = 0xff, NVME_NAMESPACE_ATTACH_CDW10_SEL_SHIFT = 0, @@ -360,11 +362,12 @@ enum features { }; int nvme_identify(int fd, enum nvme_identify_cns cns, __u32 nsid, __u16 cntid, - __u16 nvmsetid, __u8 uuidx, __u8 csi, void *data) + __u16 nvmsetid, __u16 domid, __u8 uuidx, __u8 csi, void *data) { __u32 cdw10 = NVME_SET(cntid, IDENTIFY_CDW10_CNTID) | NVME_SET(cns, IDENTIFY_CDW10_CNS); __u32 cdw11 = NVME_SET(nvmsetid, IDENTIFY_CDW11_NVMSETID) | + NVME_SET(domid, IDENTIFY_CDW11_DOMID) | NVME_SET(csi, IDENTIFY_CDW11_CSI); __u32 cdw14 = NVME_SET(uuidx, IDENTIFY_CDW14_UUID); @@ -384,7 +387,8 @@ int nvme_identify(int fd, enum nvme_identify_cns cns, __u32 nsid, __u16 cntid, static int __nvme_identify(int fd, __u8 cns, __u32 nsid, void *data) { return nvme_identify(fd, cns, nsid, NVME_CNTLID_NONE, - NVME_NVMSETID_NONE, NVME_UUID_NONE, NVME_CSI_NVM, + NVME_NVMSETID_NONE, NVME_DOMID_NONE, + NVME_UUID_NONE, NVME_CSI_NVM, data); } @@ -425,15 +429,16 @@ int nvme_identify_ctrl_list(int fd, __u16 cntid, BUILD_ASSERT(sizeof(struct nvme_ctrl_list) == 4096); return nvme_identify(fd, NVME_IDENTIFY_CNS_CTRL_LIST, NVME_NSID_NONE, cntid, NVME_NVMSETID_NONE, - NVME_UUID_NONE, NVME_CSI_NVM, ctrlist); + NVME_DOMID_NONE, NVME_UUID_NONE, NVME_CSI_NVM, + ctrlist); } int nvme_identify_nsid_ctrl_list(int fd, __u32 nsid, __u16 cntid, struct nvme_ctrl_list *ctrlist) { return nvme_identify(fd, NVME_IDENTIFY_CNS_NS_CTRL_LIST, nsid, - cntid, NVME_NVMSETID_NONE, NVME_UUID_NONE, - NVME_CSI_NVM, ctrlist); + cntid, NVME_NVMSETID_NONE, NVME_DOMID_NONE, + NVME_UUID_NONE, NVME_CSI_NVM, ctrlist); } int nvme_identify_ns_descs(int fd, __u32 nsid, struct nvme_ns_id_desc *descs) @@ -447,7 +452,8 @@ int nvme_identify_nvmset_list(int fd, __u16 nvmsetid, BUILD_ASSERT(sizeof(struct nvme_id_nvmset_list) == 4096); return nvme_identify(fd, NVME_IDENTIFY_CNS_NVMSET_LIST, NVME_NSID_NONE, NVME_CNTLID_NONE, nvmsetid, - NVME_UUID_NONE, NVME_CSI_NVM, nvmset); + NVME_DOMID_NONE, NVME_UUID_NONE, NVME_CSI_NVM, + nvmset); } int nvme_identify_primary_ctrl(int fd, __u16 cntid, @@ -456,7 +462,8 @@ int nvme_identify_primary_ctrl(int fd, __u16 cntid, BUILD_ASSERT(sizeof(struct nvme_primary_ctrl_cap) == 4096); return nvme_identify(fd, NVME_IDENTIFY_CNS_PRIMARY_CTRL_CAP, NVME_NSID_NONE, cntid, NVME_NVMSETID_NONE, - NVME_UUID_NONE, NVME_CSI_NVM, cap); + NVME_DOMID_NONE, NVME_UUID_NONE, NVME_CSI_NVM, + cap); } int nvme_identify_secondary_ctrl_list(int fd, __u32 nsid, __u16 cntid, @@ -465,7 +472,8 @@ int nvme_identify_secondary_ctrl_list(int fd, __u32 nsid, __u16 cntid, BUILD_ASSERT(sizeof(struct nvme_secondary_ctrl_list) == 4096); return nvme_identify(fd, NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST, nsid, cntid, NVME_NVMSETID_NONE, - NVME_UUID_NONE, NVME_CSI_NVM, list); + NVME_DOMID_NONE, NVME_UUID_NONE, NVME_CSI_NVM, + list); } int nvme_identify_ns_granularity(int fd, @@ -487,14 +495,14 @@ int nvme_identify_ctrl_csi(int fd, __u8 csi, void *data) { return nvme_identify(fd, NVME_IDENTIFY_CNS_CSI_CTRL, NVME_NSID_NONE, NVME_CNTLID_NONE, NVME_NVMSETID_NONE, - NVME_UUID_NONE, csi, data); + NVME_DOMID_NONE, NVME_UUID_NONE, csi, data); } int nvme_identify_ns_csi(int fd, __u32 nsid, __u8 csi, void *data) { return nvme_identify(fd, NVME_IDENTIFY_CNS_CSI_NS, nsid, NVME_CNTLID_NONE, NVME_NVMSETID_NONE, - NVME_UUID_NONE, csi, data); + NVME_DOMID_NONE, NVME_UUID_NONE, csi, data); } int nvme_identify_active_ns_list_csi(int fd, __u32 nsid, __u8 csi, @@ -503,7 +511,7 @@ int nvme_identify_active_ns_list_csi(int fd, __u32 nsid, __u8 csi, BUILD_ASSERT(sizeof(struct nvme_ns_list) == 4096); return nvme_identify(fd, NVME_IDENTIFY_CNS_CSI_NS_ACTIVE_LIST, nsid, NVME_CNTLID_NONE, NVME_NVMSETID_NONE, - NVME_UUID_NONE, csi, list); + NVME_DOMID_NONE, NVME_UUID_NONE, csi, list); } int nvme_identify_allocated_ns_list_css(int fd, __u32 nsid, __u8 csi, @@ -511,16 +519,25 @@ int nvme_identify_allocated_ns_list_css(int fd, __u32 nsid, __u8 csi, { return nvme_identify(fd, NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST, nsid, NVME_CNTLID_NONE, NVME_NVMSETID_NONE, - NVME_UUID_NONE, csi, list); + NVME_DOMID_NONE, NVME_UUID_NONE, csi, list); } +int nvme_identify_domain_list(int fd, __u16 domid, + struct nvme_id_domain_list *list) +{ + BUILD_ASSERT(sizeof(struct nvme_id_domain_list) == 4096); + return nvme_identify(fd, NVME_IDENTIFY_CNS_DOMAIN_LIST, NVME_NSID_NONE, + NVME_CNTLID_NONE, NVME_NVMSETID_NONE, + domid, NVME_UUID_NONE, NVME_CSI_NVM, list); +} int nvme_identify_iocs(int fd, __u16 cntlid, struct nvme_id_iocs *iocs) { BUILD_ASSERT(sizeof(struct nvme_id_iocs) == 4096); - return nvme_identify(fd, NVME_IDENTIFY_CNS_COMMAND_SET_STRUCTURE, NVME_NSID_NONE, - cntlid, NVME_NVMSETID_NONE, NVME_UUID_NONE, - NVME_CSI_NVM, iocs); + return nvme_identify(fd, NVME_IDENTIFY_CNS_COMMAND_SET_STRUCTURE, + NVME_NSID_NONE, cntlid, NVME_NVMSETID_NONE, + NVME_DOMID_NONE, NVME_UUID_NONE, NVME_CSI_NVM, + iocs); } int nvme_zns_identify_ns(int fd, __u32 nsid, struct nvme_zns_id_ns *data) @@ -528,7 +545,8 @@ int nvme_zns_identify_ns(int fd, __u32 nsid, struct nvme_zns_id_ns *data) BUILD_ASSERT(sizeof(struct nvme_zns_id_ns) == 4096); return nvme_identify(fd, NVME_IDENTIFY_CNS_CSI_NS, nsid, NVME_CNTLID_NONE, NVME_NVMSETID_NONE, - NVME_UUID_NONE, NVME_CSI_ZNS, data); + NVME_DOMID_NONE, NVME_UUID_NONE, NVME_CSI_ZNS, + data); } int nvme_zns_identify_ctrl(int fd, struct nvme_zns_id_ctrl *id) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 41ae115eba..4b5d77cd3d 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -375,6 +375,7 @@ int nvme_get_nsid(int fd, __u32 *nsid); * @fd: File descriptor of nvme device * @cns: The Controller or Namespace structure, see @enum nvme_identify_cns * @nsid: Namespace identifier, if applicable + * @domid: Domain identifier, if applicable * @cntid: The Controller Identifier, if applicable * @nvmsetid: The NVMe Set ID if CNS is 04h * @uuidx: UUID Index if controller supports this id selection method @@ -388,8 +389,8 @@ int nvme_get_nsid(int fd, __u32 *nsid); * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify(int fd, enum nvme_identify_cns cns, __u32 nsid, - __u16 cntid, __u16 nvmsetid, __u8 uuidx, __u8 csi, - void *data); + __u16 cntid, __u16 nvmsetid, __u16 domid, + __u8 uuidx, __u8 csi, void *data); /** * nvme_identify_ctrl() - Retrieves nvme identify controller @@ -691,6 +692,25 @@ int nvme_identify_allocated_ns_list_csi(int fd, __u32 nsid, __u8 csi, */ int nvme_nvm_identify_ctrl(int fd, struct nvme_id_ctrl_nvm *id); +/** + * nvme_idnetifY_domain_list() - + * @fd: File descriptor of nvme device + * @domid: Domain ID + * @list: User space destiantion 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 + * specified in the @domid field. + * + * See @struct nvme_identify_domain_attr 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. + */ +int nvme_identify_domain_list(int fd, __u16 domid, + struct nvme_id_domain_list *list); + /** * nvme_identify_iocs() - * @fd: File descriptor of nvme device diff --git a/src/nvme/types.h b/src/nvme/types.h index 7121c57ff4..33383fea76 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -48,6 +48,7 @@ * @NVME_UUID_NONE: Use to omit a uuid command parameter * @NVME_CNTLID_NONE: Use to omit a cntlid command parameter * @NVME_NVMSETID_NONE: Use to omit a nvmsetid command parameter + * @NVME_DOMID_NONE: Use to omit a domid 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 @@ -62,6 +63,8 @@ * identify namespace list * @NVME_ID_SECONDARY_CTRL_MAX: The largest possible secondary controller index * in identify secondary controller + * @NMVE_ID_DOMAIN_LIST_MAX: The largest possible domain index in the + * in domain list * @NVME_FEAT_LBA_RANGE_MAX: The largest possible LBA range index in feature * lba range type * @NVME_LOG_ST_MAX_RESULTS: The largest possible self test result index in the @@ -79,6 +82,7 @@ enum nvme_constants { NVME_UUID_NONE = 0, NVME_CNTLID_NONE = 0, NVME_NVMSETID_NONE = 0, + NVME_DOMID_NONE = 0, NVME_LOG_LSP_NONE = 0, NVME_LOG_LSI_NONE = 0, NVME_LOG_LPO_NONE = 0, @@ -88,6 +92,7 @@ enum nvme_constants { NVME_ID_CTRL_LIST_MAX = 2047, NVME_ID_NS_LIST_MAX = 1024, NVME_ID_SECONDARY_CTRL_MAX = 127, + NVME_ID_DOMAIN_LIST_MAX = 31, NVME_ID_ND_DESCRIPTOR_MAX = 16, NVME_FEAT_LBA_RANGE_MAX = 64, NVME_LOG_ST_MAX_RESULTS = 20, @@ -2140,6 +2145,33 @@ struct nvme_id_iocs { __u64 iocsc[512]; }; +/** + * struct nvme_id_domain_attr - Domain Attributes Entry + * @dom_id: + * @dom_cap: + * @unalloc_dom_cap: + * @max_egrp_dom_cap: + */ +struct nvme_id_domain_attr { + __le16 dom_id; + __u8 rsvd2[14]; + __u8 dom_cap[16]; + __u8 unalloc_dom_cap[16]; + __u8 max_egrp_dom_cap[16]; + __u8 rsvd64[64]; +}; + +/** + * struct nvme_id_domain_list - + * @num: + * @domain_attr: List of domain attributes + */ +struct nvme_id_domain_list { + __u8 num; + __u8 rsvd[127]; + struct nvme_id_domain_attr domain_attr[NVME_ID_DOMAIN_LIST_MAX]; +}; + /** * struct nvme_error_log_page - Error Information Log Entry (Log Identifier 01h) * @error_count: Error Count: a 64-bit incrementing error count, @@ -4914,6 +4946,7 @@ enum nvme_admin_opcode { * @NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST: * @NVME_IDENTIFY_CNS_NS_GRANULARITY: * @NVME_IDENTIFY_CNS_UUID_LIST: + * @NVME_IDENTIFY_CNS_DOMAIN_LIST: * @NVME_IDENTIFY_CNS_CSI_ALLOCATED_NS_LIST: * @NVME_IDENTIFY_CNS_COMMAND_SET_STRUCTURE: Base Specification 2.0a section 5.17.2.21 */ @@ -4934,6 +4967,7 @@ enum nvme_identify_cns { NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST = 0x15, NVME_IDENTIFY_CNS_NS_GRANULARITY = 0x16, NVME_IDENTIFY_CNS_UUID_LIST = 0x17, + NVME_IDENTIFY_CNS_DOMAIN_LIST = 0x18, NVME_IDENTIFY_CNS_CSS_ALLOCATED_NS_LIST = 0x1A, NVME_IDENTIFY_CNS_COMMAND_SET_STRUCTURE = 0x1C, }; From db2f8cdf1e088ccf731938b7796c0d8abcec1304 Mon Sep 17 00:00:00 2001 From: Steven Seungcheol Lee Date: Thu, 4 Nov 2021 11:16:03 +0100 Subject: [PATCH 0244/1564] types: Add New fields on PEL based on NVMe 2.0a Persistent Event Log header got new fields below [373:372] Generation Number [377:374] Reporting Context Information (RCI) Signed-off-by: Steven Seungcheol Lee [dwagner: ported from nvme-cli-monolithic] Signed-off-by: Daniel Wagner --- src/nvme/types.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/nvme/types.h b/src/nvme/types.h index 33383fea76..9ccb39e8d2 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -2933,6 +2933,8 @@ struct nvme_ana_log { * @sn: * @mn: * @subnqn: + * @gen_number: + * @rci: * @seb: */ struct nvme_persistent_event_log { @@ -2951,7 +2953,9 @@ struct nvme_persistent_event_log { char sn[20]; char mn[40]; char subnqn[NVME_NQN_LENGTH]; - __u8 rsvd372[108]; + __le16 gen_number; + __le32 rci; + __u8 rsvd378[102]; __u8 seb[32]; } __attribute__((packed)); From 6b525404497a8ba3e88722629b4c074ac0294be9 Mon Sep 17 00:00:00 2001 From: Gollu Appalanaidu Date: Thu, 4 Nov 2021 14:26:45 +0100 Subject: [PATCH 0245/1564] types: add spinup control feature (fid=0x1A) Signed-off-by: Gollu Appalanaidu [dwagner: ported from nvme-cli-monolithic] Signed-off-by: Daniel Wagner --- src/nvme/types.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/nvme/types.h b/src/nvme/types.h index 9ccb39e8d2..d02a78362e 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -5047,6 +5047,7 @@ enum nvme_cmd_get_log_lid { * @NVME_FEAT_FID_SANITIZE: * @NVME_FEAT_FID_ENDURANCE_EVT_CFG: * @NVME_FEAT_FID_IOCS_PROFILE: + * @NVME_FEAT_FID_SPINUP_CONTROL: * @NVME_FEAT_FID_SW_PROGRESS: * @NVME_FEAT_FID_HOST_ID: * @NVME_FEAT_FID_RESV_MASK: @@ -5079,6 +5080,7 @@ enum nvme_features_id { NVME_FEAT_FID_SANITIZE = 0x17, NVME_FEAT_FID_ENDURANCE_EVT_CFG = 0x18, NVME_FEAT_FID_IOCS_PROFILE = 0x19, /* XXX: Placeholder until assigned */ + NVME_FEAT_FID_SPINUP_CONTROL = 0x1a, NVME_FEAT_FID_SW_PROGRESS = 0x80, NVME_FEAT_FID_HOST_ID = 0x81, NVME_FEAT_FID_RESV_MASK = 0x82, From 4948dd9717b35203a8532e59f825a3c3f418c1fa Mon Sep 17 00:00:00 2001 From: Steven Seungcheol Lee Date: Thu, 4 Nov 2021 15:19:38 +0100 Subject: [PATCH 0246/1564] types: Add Identify for CNS 08h NVMe spec 2.0a based I/O Command Set Independent Identify Namespace data structure (CNS 08h) Most of data comes from existing data of id-ns which is common from All I/O command set Signed-off-by: Steven Seungcheol Lee [dwagner: ported from nvme-cli-monolithic] Signed-off-by: Daniel Wagner --- src/libnvme.map | 1 + src/nvme/ioctl.c | 11 ++++++++++- src/nvme/ioctl.h | 13 +++++++++++++ src/nvme/types.h | 28 ++++++++++++++++++++++++++++ 4 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/libnvme.map b/src/libnvme.map index 841dc0bb26..ed3319c96d 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -140,6 +140,7 @@ nvme_identify_ctrl; nvme_identify_ctrl_list; nvme_identify_domain_list; + nvme_identify_independent_identify_ns; nvme_identify_iocs; nvme_identify_ns; nvme_identify_ns_descs; diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 3f00f3cf7f..44ea8488e3 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -531,6 +531,16 @@ int nvme_identify_domain_list(int fd, __u16 domid, domid, NVME_UUID_NONE, NVME_CSI_NVM, list); } +int nvme_identify_independent_identify_ns(int fd, __u32 nsid, + struct nvme_id_independent_id_ns *ns) +{ + BUILD_ASSERT(sizeof(struct nvme_id_independent_id_ns) == 4096); + return nvme_identify(fd, NVME_IDENTIFY_CNS_CSI_INDEPENDENT_ID_NS, + nsid, NVME_CNTLID_NONE, NVME_NVMSETID_NONE, + NVME_DOMID_NONE, NVME_UUID_NONE, NVME_CSI_NVM, + ns); +} + int nvme_identify_iocs(int fd, __u16 cntlid, struct nvme_id_iocs *iocs) { BUILD_ASSERT(sizeof(struct nvme_id_iocs) == 4096); @@ -555,7 +565,6 @@ int nvme_zns_identify_ctrl(int fd, struct nvme_zns_id_ctrl *id) return nvme_identify_ctrl_csi(fd, NVME_CSI_ZNS, id); } - int nvme_nvm_identify_ctrl(int fd, struct nvme_id_ctrl_nvm *id) { BUILD_ASSERT(sizeof(struct nvme_id_ctrl_nvm ) == 4096); diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 4b5d77cd3d..41e3274e5b 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -682,6 +682,19 @@ int nvme_identify_active_ns_list_csi(int fd, __u32 nsid, __u8 csi, int nvme_identify_allocated_ns_list_csi(int fd, __u32 nsid, __u8 csi, struct nvme_ns_list *list); +/** + * nvme_identify_independent_identify_ns() - + * @fd: File descriptor of nvme device + * @nsid: Return namespaces greater than this identifier + * @ns: I/O Command Set Independent Identify Namespace data + * structure + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_identify_independent_identify_ns(int fd, __u32 nsid, + struct nvme_id_independent_id_ns *ns); + /** * nvme_identify_ctrl_nvm() - * @fd: File descriptor of nvme device diff --git a/src/nvme/types.h b/src/nvme/types.h index d02a78362e..b0fdc9f14f 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -1928,6 +1928,32 @@ struct nvme_id_nvmset_list { struct nvme_nvmset_attr ent[NVME_ID_NVMSET_LIST_MAX]; }; +/** + * struct nvme_id_independent_id_ns - + * @nsfeat: + * @nmic: + * @rescap: + * @fpi: + * @anagrpid: + * @nsattr: + * @nvmsetid: + * @endgid: + * @nstat: + */ +struct nvme_id_independent_id_ns { + __u8 nsfeat; + __u8 nmic; + __u8 rescap; + __u8 fpi; + __le32 anagrpid; + __u8 nsattr; + __u8 rsvd9; + __le16 nvmsetid; + __le16 endgid; + __u8 nstat; + __u8 rsvd15[4081]; +}; + /** * struct nvme_id_ns_granularity_desc - * @nszegran: @@ -4942,6 +4968,7 @@ enum nvme_admin_opcode { * @NVME_IDENTIFY_CNS_CSI_NS: * @NVME_IDENTIFY_CNS_CSI_CTRL: * @NVME_IDENTIFY_CNS_CSI_CSI_NS_ACTIVE_LIST: + * @NVME_IDENTIFY_CNS_CSI_INDEPENDENT_ID_NS: * @NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST: * @NVME_IDENTIFY_CNS_ALLOCATED_NS: * @NVME_IDENTIFY_CNS_NS_CTRL_LIST: @@ -4963,6 +4990,7 @@ enum nvme_identify_cns { NVME_IDENTIFY_CNS_CSI_NS = 0x05, NVME_IDENTIFY_CNS_CSI_CTRL = 0x06, NVME_IDENTIFY_CNS_CSI_NS_ACTIVE_LIST = 0x07, + NVME_IDENTIFY_CNS_CSI_INDEPENDENT_ID_NS = 0x08, NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST = 0x10, NVME_IDENTIFY_CNS_ALLOCATED_NS = 0x11, NVME_IDENTIFY_CNS_NS_CTRL_LIST = 0x12, From 21acd638c4c9ce0e10a741c7c33b53b9d001fa16 Mon Sep 17 00:00:00 2001 From: Gollu Appalanaidu Date: Thu, 4 Nov 2021 18:35:48 +0100 Subject: [PATCH 0247/1564] types: add boot partition log support Signed-off-by: Gollu Appalanaidu [dwagner: ported from nvme-cli-monolithic] Signed-off-by: Daniel Wagner --- src/libnvme.map | 1 + src/nvme/ioctl.c | 11 +++++++++++ src/nvme/ioctl.h | 14 ++++++++++++++ src/nvme/types.h | 16 ++++++++++++++++ 4 files changed, 42 insertions(+) diff --git a/src/libnvme.map b/src/libnvme.map index ed3319c96d..ed6a4582a5 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -104,6 +104,7 @@ nvme_get_log; nvme_get_log_ana; nvme_get_log_ana_groups; + nvme_get_log_boot_partition; nvme_get_log_changed_ns_list; nvme_get_log_cmd_effects; nvme_get_log_create_telemetry_host; diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 44ea8488e3..57027f71e3 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -747,6 +747,17 @@ int nvme_get_log_endurance_grp_evt(int fd, bool rae, __u32 offset, __u32 len, NVME_CSI_NVM, len, log); } +int nvme_get_log_boot_partition(int fd, bool rae, __u8 lsp, __u32 len, + struct nvme_boot_partition *part) +{ + BUILD_ASSERT(sizeof(struct nvme_boot_partition) == 16); + return nvme_get_log(fd, NVME_LOG_LID_BOOT_PARTITION, + NVME_NSID_NONE, 0, NVME_LOG_LSP_NONE, + NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, + NVME_CSI_NVM, len, part); + +} + int nvme_get_log_discovery(int fd, bool rae, __u32 offset, __u32 len, void *log) { return nvme_get_log(fd, NVME_LOG_LID_DISCOVER, NVME_NSID_NONE, offset, diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 41e3274e5b..df7be66aa9 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -1004,6 +1004,20 @@ int nvme_get_log_lba_status(int fd, bool rae, __u64 offset, __u32 len, int nvme_get_log_endurance_grp_evt(int fd, bool rae, __u32 offset, __u32 len, void *log); +/** + * nvme_get_log_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 + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise + */ +int nvme_get_log_boot_partition(int fd, bool rae, __u8 lsp, __u32 len, + struct nvme_boot_partition *part); + /** * nvme_get_log_discovery() - * @fd: File descriptor of nvme device diff --git a/src/nvme/types.h b/src/nvme/types.h index b0fdc9f14f..80f57c611d 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -3154,6 +3154,20 @@ struct nvme_eg_event_aggregate_log { __le16 egids[]; }; +/** + * struct nvme_boot_paritition - + * @lid: + * @bpinfo: + * @boot_partitiion_data: + */ +struct nvme_boot_partition { + __u8 lid; + __u8 rsvd1[3]; + __le32 bpinfo; + __u8 rsvd8[8]; + __u8 boot_partition_data[]; +}; + /** * struct nvme_resv_notification_log - * @lpc: @@ -5021,6 +5035,7 @@ enum nvme_identify_cns { * @NVME_LOG_LID_PERSISTENT_EVENT: * @NVME_LOG_LID_LBA_STATUS: * @NVME_LOG_LID_ENDURANCE_GRP_EVT: + * @NVME_LOG_LID_BOOT_PARTITION: * @NVME_LOG_LID_DISCOVER: * @NVME_LOG_LID_RESERVATION: * @NVME_LOG_LID_SANITIZE: @@ -5042,6 +5057,7 @@ enum nvme_cmd_get_log_lid { NVME_LOG_LID_PERSISTENT_EVENT = 0x0d, NVME_LOG_LID_LBA_STATUS = 0x0e, NVME_LOG_LID_ENDURANCE_GRP_EVT = 0x0f, + NVME_LOG_LID_BOOT_PARTITION = 0x15, NVME_LOG_LID_DISCOVER = 0x70, NVME_LOG_LID_RESERVATION = 0x80, NVME_LOG_LID_SANITIZE = 0x81, From 9bc60749db33decd1258e106c19c91ac2c2fd5ce Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 4 Nov 2021 18:36:32 +0100 Subject: [PATCH 0248/1564] ioctl: Fix rae parameter order in __nvme_get_log __nvme_get_log() is a wrapper for nvme_get_log(). Though it got the position for the rae arguemtn wrong. Signed-off-by: Daniel Wagner --- src/nvme/ioctl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 57027f71e3..6990dc2f3f 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -608,8 +608,8 @@ static int __nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, bool rae, __u32 len, void *log) { return nvme_get_log(fd, lid, NVME_NSID_ALL, 0, NVME_LOG_LSP_NONE, - NVME_LOG_LSI_NONE, NVME_UUID_NONE, NVME_CSI_NVM, - rae, len, log); + NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, + NVME_CSI_NVM, len, log); } int nvme_get_log_error(int fd, unsigned nr_entries, bool rae, From a4b89211c0565757fc41d8e8a6eec50456a1a7a1 Mon Sep 17 00:00:00 2001 From: Gollu Appalanaidu Date: Fri, 5 Nov 2021 09:47:11 +0100 Subject: [PATCH 0249/1564] types: add support for fid supported and effects log(lid = 0x12) Signed-off-by: Gollu Appalanaidu [dwagner: - ported from nvme-cli-monolithic - changed naming scheme to nvme_get_log_fid_supported_effects] Signed-off-by: Daniel Wagner --- src/libnvme.map | 1 + src/nvme/ioctl.c | 10 +++++ src/nvme/ioctl.h | 12 ++++++ src/nvme/types.h | 101 +++++++++++++++++++++++++++++++++++------------ 4 files changed, 99 insertions(+), 25 deletions(-) diff --git a/src/libnvme.map b/src/libnvme.map index ed6a4582a5..d425ef0a03 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -113,6 +113,7 @@ nvme_get_log_endurance_group; nvme_get_log_endurance_grp_evt; nvme_get_log_error; + nvme_get_log_fid_supported_effects; nvme_get_log_fw_slot; nvme_get_log_lba_status; nvme_get_log_page; diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 6990dc2f3f..392c519032 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -747,6 +747,16 @@ int nvme_get_log_endurance_grp_evt(int fd, bool rae, __u32 offset, __u32 len, NVME_CSI_NVM, len, log); } +int nvme_get_log_fid_supported_effects(int fd, bool rae, + struct nvme_fid_supported_effects_log *log) +{ + BUILD_ASSERT(sizeof(struct nvme_fid_supported_effects_log) == 1024); + return nvme_get_log(fd, NVME_LOG_LID_FID_SUPPORTED_EFFECTS, + NVME_NSID_NONE, 0, NVME_LOG_LSP_NONE, + NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, + NVME_CSI_NVM, sizeof(*log), log); +} + int nvme_get_log_boot_partition(int fd, bool rae, __u8 lsp, __u32 len, struct nvme_boot_partition *part) { diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index df7be66aa9..d6025415bd 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -1004,6 +1004,18 @@ int nvme_get_log_lba_status(int fd, bool rae, __u64 offset, __u32 len, int nvme_get_log_endurance_grp_evt(int fd, bool rae, __u32 offset, __u32 len, void *log); +/** + * nvme_get_log_fid_supported_effects() - + * @fd: File descriptor of nvme device + * @rae: Retain asynchronous events + * @log: FID Supported and Effects data structure + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise + */ +int nvme_get_log_fid_supported_effects(int fd, bool rae, + struct nvme_fid_supported_effects_log *log); + /** * nvme_get_log_boot_partition() - * @fd: File descriptor of nvme device diff --git a/src/nvme/types.h b/src/nvme/types.h index 80f57c611d..7b7cd9ac08 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -69,6 +69,8 @@ * 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 + * feature identifiers 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 @@ -77,31 +79,32 @@ * @NVMF_TSAS_SIZE: Max Transport Specific Address Subtype size */ enum nvme_constants { - NVME_NSID_ALL = 0xffffffff, - NVME_NSID_NONE = 0, - NVME_UUID_NONE = 0, - NVME_CNTLID_NONE = 0, - NVME_NVMSETID_NONE = 0, - NVME_DOMID_NONE = 0, - NVME_LOG_LSP_NONE = 0, - NVME_LOG_LSI_NONE = 0, - NVME_LOG_LPO_NONE = 0, - NVME_IDENTIFY_DATA_SIZE = 4096, - NVME_ID_NVMSET_LIST_MAX = 31, - NVME_ID_UUID_LIST_MAX = 127, - NVME_ID_CTRL_LIST_MAX = 2047, - NVME_ID_NS_LIST_MAX = 1024, - NVME_ID_SECONDARY_CTRL_MAX = 127, - NVME_ID_DOMAIN_LIST_MAX = 31, - NVME_ID_ND_DESCRIPTOR_MAX = 16, - NVME_FEAT_LBA_RANGE_MAX = 64, - NVME_LOG_ST_MAX_RESULTS = 20, - NVME_LOG_TELEM_BLOCK_SIZE = 512, - NVME_DSM_MAX_RANGES = 256, - NVME_NQN_LENGTH = 256, - NVMF_TRADDR_SIZE = 256, - NVMF_TSAS_SIZE = 256, - NVME_ZNS_CHANGED_ZONES_MAX = 511, + NVME_NSID_ALL = 0xffffffff, + NVME_NSID_NONE = 0, + NVME_UUID_NONE = 0, + NVME_CNTLID_NONE = 0, + NVME_NVMSETID_NONE = 0, + NVME_DOMID_NONE = 0, + NVME_LOG_LSP_NONE = 0, + NVME_LOG_LSI_NONE = 0, + NVME_LOG_LPO_NONE = 0, + NVME_IDENTIFY_DATA_SIZE = 4096, + NVME_ID_NVMSET_LIST_MAX = 31, + NVME_ID_UUID_LIST_MAX = 127, + NVME_ID_CTRL_LIST_MAX = 2047, + NVME_ID_NS_LIST_MAX = 1024, + NVME_ID_SECONDARY_CTRL_MAX = 127, + NVME_ID_DOMAIN_LIST_MAX = 31, + NVME_ID_ND_DESCRIPTOR_MAX = 16, + NVME_FEAT_LBA_RANGE_MAX = 64, + NVME_LOG_ST_MAX_RESULTS = 20, + NVME_LOG_TELEM_BLOCK_SIZE = 512, + NVME_LOG_FID_SUPPORTED_EFFECTS_MAX = 256, + NVME_DSM_MAX_RANGES = 256, + NVME_NQN_LENGTH = 256, + NVMF_TRADDR_SIZE = 256, + NVMF_TSAS_SIZE = 256, + NVME_ZNS_CHANGED_ZONES_MAX = 511, }; /** @@ -3154,6 +3157,52 @@ struct nvme_eg_event_aggregate_log { __le16 egids[]; }; +/** + * 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 { + NVME_FID_SUPPORTED_EFFECTS_FSUPP = 1 << 0, + NVME_FID_SUPPORTED_EFFECTS_UDCC = 1 << 1, + NVME_FID_SUPPORTED_EFFECTS_NCC = 1 << 2, + NVME_FID_SUPPORTED_EFFECTS_NIC = 1 << 3, + NVME_FID_SUPPORTED_EFFECTS_CCC = 1 << 4, + NVME_FID_SUPPORTED_EFFECTS_UUID_SEL = 1 << 19, + NVME_FID_SUPPORTED_EFFECTS_SCOPE_SHIFT = 20, + NVME_FID_SUPPORTED_EFFECTS_SCOPE_MASK = 0xfff, + NVME_FID_SUPPORTED_EFFECTS_SCOPE_NS = 1 << 0, + NVME_FID_SUPPORTED_EFFECTS_SCOPE_CTRL = 1 << 1, + NVME_FID_SUPPORTED_EFFECTS_SCOPE_NVM_SET= 1 << 2, + NVME_FID_SUPPORTED_EFFECTS_SCOPE_ENDGRP = 1 << 3, + NVME_FID_SUPPORTED_EFFECTS_SCOPE_DOMAIN = 1 << 4, + NVME_FID_SUPPORTED_EFFECTS_SCOPE_NSS = 1 << 5, +}; + +/** + * struct nvme_fid_supported_effects_log - + * @fid_support: + * + * Feature Identifiers Supported and Effects (Log Identifier 12h) + */ +struct nvme_fid_supported_effects_log { + __le32 fid_support[NVME_LOG_FID_SUPPORTED_EFFECTS_MAX]; +}; + /** * struct nvme_boot_paritition - * @lid: @@ -5035,6 +5084,7 @@ enum nvme_identify_cns { * @NVME_LOG_LID_PERSISTENT_EVENT: * @NVME_LOG_LID_LBA_STATUS: * @NVME_LOG_LID_ENDURANCE_GRP_EVT: + * @NVME_LOG_LID_FID_SUPPORTED_EFFECTS: * @NVME_LOG_LID_BOOT_PARTITION: * @NVME_LOG_LID_DISCOVER: * @NVME_LOG_LID_RESERVATION: @@ -5057,6 +5107,7 @@ enum nvme_cmd_get_log_lid { NVME_LOG_LID_PERSISTENT_EVENT = 0x0d, NVME_LOG_LID_LBA_STATUS = 0x0e, NVME_LOG_LID_ENDURANCE_GRP_EVT = 0x0f, + NVME_LOG_LID_FID_SUPPORTED_EFFECTS = 0x12, NVME_LOG_LID_BOOT_PARTITION = 0x15, NVME_LOG_LID_DISCOVER = 0x70, NVME_LOG_LID_RESERVATION = 0x80, From d588b59e2539c3a952233294efab192de3f7d2b8 Mon Sep 17 00:00:00 2001 From: Brandon Paupore Date: Fri, 5 Nov 2021 10:24:13 +0100 Subject: [PATCH 0250/1564] ioctl: Add Timeout Parameter for Zone Management Commands Signed-off-by: Brandon Paupore [dwagner: ported from nvme-cli-monolithic] Signed-off-by: Daniel Wagner --- src/nvme/ioctl.c | 5 +++-- src/nvme/ioctl.h | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 392c519032..c638a61b16 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -1927,8 +1927,8 @@ int nvme_resv_report(int fd, __u32 nsid, bool eds, __u32 len, } int nvme_zns_mgmt_send(int fd, __u32 nsid, __u64 slba, bool select_all, - enum nvme_zns_send_action zsa, __u32 data_len, - void *data) + __u32 timeout, enum nvme_zns_send_action zsa, + __u32 data_len, void *data) { __u32 cdw10 = slba & 0xffffffff; __u32 cdw11 = slba >> 32; @@ -1943,6 +1943,7 @@ int nvme_zns_mgmt_send(int fd, __u32 nsid, __u64 slba, bool select_all, .cdw13 = cdw13, .addr = (__u64)(uintptr_t)data, .data_len = data_len, + .timeout_ms = timeout, }; return nvme_submit_io_passthru(fd, &cmd, NULL); diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index d6025415bd..72fd02ca17 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -2600,6 +2600,7 @@ int nvme_resv_report(int fd, __u32 nsid, bool eds, __u32 len, * @nsid: Namespace ID * @slba: * @select_all: + * @timeout: timeout in ms * @zsa: * @data_len: * @data: @@ -2608,8 +2609,9 @@ int nvme_resv_report(int fd, __u32 nsid, bool eds, __u32 len, * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_zns_mgmt_send(int fd, __u32 nsid, __u64 slba, bool select_all, - enum nvme_zns_send_action zsa, __u32 data_len, - void *data); + __u32 timeout, enum nvme_zns_send_action zsa, + __u32 data_len, void *data); + /** * nvme_zns_mgmt_recv() - From 27f45627861c087ee0a2fb680b8ce5599e6cb09f Mon Sep 17 00:00:00 2001 From: Gollu Appalanaidu Date: Fri, 5 Nov 2021 14:05:37 +0100 Subject: [PATCH 0251/1564] types: add supported log pages log page (lid = 0x00) Signed-off-by: Gollu Appalanaidu [dwagner: - ported from nvme-cli-monolithic - changed naming scheme to nvme_get_log_supported_log_pages] Signed-off-by: Daniel Wagner --- src/libnvme.map | 1 + src/nvme/ioctl.c | 8 ++++++++ src/nvme/ioctl.h | 11 +++++++++++ src/nvme/types.h | 15 +++++++++++++++ 4 files changed, 35 insertions(+) diff --git a/src/libnvme.map b/src/libnvme.map index d425ef0a03..1b495099a0 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -123,6 +123,7 @@ nvme_get_log_reservation; nvme_get_log_sanitize; nvme_get_log_smart; + nvme_get_log_supported_log_pages; nvme_get_log_telemetry_ctrl; nvme_get_log_telemetry_host; nvme_get_new_host_telemetry; diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index c638a61b16..b7a8b27e81 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -612,6 +612,14 @@ static int __nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, bool rae, NVME_CSI_NVM, len, log); } +int nvme_get_log_supported_log_pages(int fd, bool rae, + struct nvme_supported_log_pages *log) +{ + BUILD_ASSERT(sizeof(struct nvme_supported_log_pages) == 1024); + return __nvme_get_log(fd, NVME_LOG_LID_SUPPORTED_LOG_PAGES, rae, + sizeof(*log), log); +} + int nvme_get_log_error(int fd, unsigned nr_entries, bool rae, struct nvme_error_log_page *log) { diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 72fd02ca17..310b7a1150 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -793,6 +793,17 @@ static inline int nvme_get_log_simple(int fd, enum nvme_cmd_get_log_lid lid, return nvme_get_nsid_log(fd, lid, NVME_NSID_ALL, len, log); } +/** nvme_get_log_supported_log_pages() - Retrieve nmve supported log pages + * @fd: File descriptor of nvme device + * @rae: Retain asynchronous events + * @log: Array of LID supported and Effects data structures + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_get_log_supported_log_pages(int fd, bool rae, + struct nvme_supported_log_pages *log); + /** * nvme_get_log_error() - Retrieve nvme error log * @fd: File descriptor of nvme device diff --git a/src/nvme/types.h b/src/nvme/types.h index 7b7cd9ac08..a8f4dd40c4 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -53,6 +53,8 @@ * @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 + * log pages log. * @NVME_ID_NVMSET_LIST_MAX: The largest possible nvmset index in identify * nvmeset * @NVME_ID_UUID_LIST_MAX: The largest possible uuid index in identify @@ -89,6 +91,7 @@ enum nvme_constants { NVME_LOG_LSI_NONE = 0, NVME_LOG_LPO_NONE = 0, NVME_IDENTIFY_DATA_SIZE = 4096, + NVME_LOG_SUPPORTED_LOG_PAGES_MAX = 256, NVME_ID_NVMSET_LIST_MAX = 31, NVME_ID_UUID_LIST_MAX = 127, NVME_ID_CTRL_LIST_MAX = 2047, @@ -2201,6 +2204,16 @@ struct nvme_id_domain_list { struct nvme_id_domain_attr domain_attr[NVME_ID_DOMAIN_LIST_MAX]; }; +/** + * struct nvme_supported_log_pages - + * @lid_support: + * + * Supported Log Pages (Log Identifier 00h) + */ +struct nvme_supported_log_pages { + __le32 lid_support[NVME_LOG_SUPPORTED_LOG_PAGES_MAX]; +}; + /** * struct nvme_error_log_page - Error Information Log Entry (Log Identifier 01h) * @error_count: Error Count: a 64-bit incrementing error count, @@ -5069,6 +5082,7 @@ enum nvme_identify_cns { /** * enum nvme_cmd_get_log_lid - + * @NVME_LOG_LID_SUPPORTED_LOG_PAGES: * @NVME_LOG_LID_ERROR: * @NVME_LOG_LID_SMART: * @NVME_LOG_LID_FW_SLOT: @@ -5092,6 +5106,7 @@ enum nvme_identify_cns { * @NVME_LOG_LID_ZNS_CHANGED_ZONES: */ enum nvme_cmd_get_log_lid { + NVME_LOG_LID_SUPPORTED_LOG_PAGES = 0x00, NVME_LOG_LID_ERROR = 0x01, NVME_LOG_LID_SMART = 0x02, NVME_LOG_LID_FW_SLOT = 0x03, From 102e4a380bf184ad9458b419ad1c210e0e71a3c8 Mon Sep 17 00:00:00 2001 From: Brandon Paupore Date: Fri, 5 Nov 2021 14:22:16 +0100 Subject: [PATCH 0252/1564] types: Enable telemetry data area 4 in base Signed-off-by: Brandon Paupore [dwagner: ported from nvme-cli-monolithic] Signed-off-by: Daniel Wagner --- src/nvme/types.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/nvme/types.h b/src/nvme/types.h index a8f4dd40c4..d9a1c9eaad 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -2759,6 +2759,8 @@ struct nvme_self_test_log { * 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. + * @dalb4: Telemetry Controller-Initiated Data Area 4 Last Block is + * the value of the last block in this area. * @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 @@ -2784,7 +2786,9 @@ struct nvme_telemetry_log { __le16 dalb1; __le16 dalb2; __le16 dalb3; - __u8 rsvd14[368]; + __u8 rsvd14[2]; + __le32 dalb4; + __u8 rsvd20[362]; __u8 ctrlavail; __u8 ctrldgn; __u8 rsnident[128]; From 5593d3de96a591cbc72e64832dad70b33b45b961 Mon Sep 17 00:00:00 2001 From: Gollu Appalanaidu Date: Fri, 5 Nov 2021 17:16:59 +0100 Subject: [PATCH 0253/1564] ioctl: add lockdown command support Signed-off-by: Karthik Balan karthik.b82@samsung.com Signed-off-by: Gollu Appalanaidu [dwagner: ported from nvme-cli-monolithic] Signed-off-by: Daniel Wagner --- src/libnvme.map | 1 + src/nvme/ioctl.c | 14 ++++++++++++++ src/nvme/ioctl.h | 15 +++++++++++++++ src/nvme/types.h | 2 ++ 4 files changed, 32 insertions(+) diff --git a/src/libnvme.map b/src/libnvme.map index 1b495099a0..82304c837a 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -160,6 +160,7 @@ nvme_init_id_ns; nvme_io_passthru64; nvme_io_passthru; + nvme_lockdown; nvme_log_level; nvme_log_message; nvme_lookup_host; diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index b7a8b27e81..d5d8207da2 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -1613,6 +1613,20 @@ int nvme_capacity_mgmt(int fd, __u8 op, __u16 element_id, __u32 dw11, __u32 dw12 return nvme_submit_admin_passthru(fd, &cmd, result); } +int nvme_lockdown(int fd, __u8 scp, __u8 prhbt, __u8 ifc, __u8 ofi, + __u8 uuid) +{ + __u32 cdw10 = ofi << 8 | (ifc & 0x3) << 5 | (prhbt & 0x1) << 4 | (scp & 0xF); + + struct nvme_passthru_cmd cmd = { + .opcode = nvme_admin_lockdown, + .cdw10 = cdw10, + .cdw14 = uuid & 0x3F, + }; + + return nvme_submit_admin_passthru(fd, &cmd, NULL); +} + int nvme_set_property(int fd, int offset, __u64 value) { __u32 cdw10 = nvme_is_64bit_reg(offset); diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 310b7a1150..82c1ea0dad 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -2210,6 +2210,21 @@ int nvme_directive_recv_stream_allocate(int fd, __u32 nsid, __u16 nsr, int nvme_capacity_mgmt(int fd, __u8 op, __u16 element_id, __u32 dw11, __u32 dw12, __u32 *result); +/** + * nvme_lockdown() - Issue lockdown command + * @fd: File descriptor of nvme device + * @scp: + * @prhbt: + * @ifc: + * @ofi: + * @uuid: + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_lockdown(int fd, __u8 scp, __u8 prhbt, __u8 ifc, __u8 ofi, + __u8 uuid); + /** * nvme_set_property() - Set controller property * @fd: File descriptor of nvme device diff --git a/src/nvme/types.h b/src/nvme/types.h index d9a1c9eaad..ba8b31c5cf 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -4997,6 +4997,7 @@ static inline __u16 nvme_status_code(__u16 status_field) * @nvme_admin_nvme_mi_send: * @nvme_admin_nvme_mi_recv: * @nvme_admin_capacity_mgmt: + * @nvme_admin_lockdown: * @nvme_admin_dbbuf: * @nvme_admin_fabrics: * @nvme_admin_format_nvm: @@ -5029,6 +5030,7 @@ enum nvme_admin_opcode { nvme_admin_nvme_mi_send = 0x1d, nvme_admin_nvme_mi_recv = 0x1e, nvme_admin_capacity_mgmt = 0x20, + nvme_admin_lockdown = 0x24, nvme_admin_dbbuf = 0x7c, nvme_admin_fabrics = 0x7f, nvme_admin_format_nvm = 0x80, From 65b3fc884e7f28384210832b1b732498e5dce758 Mon Sep 17 00:00:00 2001 From: Steven Seungcheol Lee Date: Fri, 5 Nov 2021 17:24:18 +0100 Subject: [PATCH 0254/1564] types: fix(Add missing fields rrl, frl, lbafe) Based on NVMe-Zoned-Namespace-Command-Set-Specification-1.1a-2021.07.26-Ratified Signed-off-by: Steven Seungcheol Lee [dwagner: ported from nvme-cli-monolithic] Signed-off-by: Daniel Wagner --- src/nvme/types.h | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/nvme/types.h b/src/nvme/types.h index ba8b31c5cf..bdbcb7b9aa 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -2067,15 +2067,16 @@ struct nvme_zns_lbafe { }; /** - * struct nvme_zns_id_ns - - * @zoc: - * @ozcs: - * @mar: - * @mor: - * @rrl: - * @frl: - * @lbafe: - * @vs: + * 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 + * @mor: Maximum Open Resources + * @rrl: Reset Recommended Limit + * @frl: Finish Recommended Limit + * @lbafe: LBA Format Extension + * @vs: Vendor Specific * struct nvme_zns_id_ns - */ struct nvme_zns_id_ns { __le16 zoc; @@ -2084,9 +2085,14 @@ struct nvme_zns_id_ns { __le32 mor; __le32 rrl; __le32 frl; - __u8 rsvd20[2796]; - struct nvme_zns_lbafe lbafe[16]; - __u8 rsvd3072[768]; + __le32 rrl1; + __le32 rrl2; + __le32 rrl3; + __le32 frl1; + __le32 frl2; + __le32 frl3; + __u8 rsvd44[2772]; + struct nvme_zns_lbafe lbafe[64]; __u8 vs[256]; }; From b35d13046bd65e104cd5b41a7fd00a0718fc489c Mon Sep 17 00:00:00 2001 From: Gollu Appalanaidu Date: Fri, 5 Nov 2021 17:35:24 +0100 Subject: [PATCH 0255/1564] types: add identify endurance group list (cns 0x19) support Signed-off-by: Gollu Appalanaidu [dwagner: ported from nvme-cli-monolithic] Signed-off-by: Daniel Wagner --- src/libnvme.map | 1 + src/nvme/ioctl.c | 10 ++++++++++ src/nvme/ioctl.h | 12 ++++++++++++ src/nvme/types.h | 13 +++++++++++++ 4 files changed, 36 insertions(+) diff --git a/src/libnvme.map b/src/libnvme.map index 82304c837a..aeed21c010 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -143,6 +143,7 @@ nvme_identify_ctrl; nvme_identify_ctrl_list; nvme_identify_domain_list; + nvme_identify_endurance_group_list; nvme_identify_independent_identify_ns; nvme_identify_iocs; nvme_identify_ns; diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index d5d8207da2..d1060dedaf 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -531,6 +531,16 @@ int nvme_identify_domain_list(int fd, __u16 domid, domid, NVME_UUID_NONE, NVME_CSI_NVM, list); } +int nvme_identify_endurance_group_list(int fd, __u16 endgrp_id, + struct nvme_id_endurance_group_list *list) +{ + BUILD_ASSERT(sizeof(struct nvme_id_endurance_group_list) == 4096); + return nvme_identify(fd, NVME_IDENTIFY_CNS_ENDURANCE_GROUP_ID, + NVME_NSID_NONE, NVME_CNTLID_NONE, + NVME_NVMSETID_NONE, endgrp_id, NVME_UUID_NONE, + NVME_CSI_NVM, list); +} + int nvme_identify_independent_identify_ns(int fd, __u32 nsid, struct nvme_id_independent_id_ns *ns) { diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 82c1ea0dad..0a0e304692 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -724,6 +724,18 @@ int nvme_nvm_identify_ctrl(int fd, struct nvme_id_ctrl_nvm *id); int nvme_identify_domain_list(int fd, __u16 domid, struct nvme_id_domain_list *list); +/** + * nvme_identifiy_endurance_group_list() - + * @fd: File descriptor of nvme device + * @endgrp_id: Endurance group identifier + * @list: Array of endurance group identifiers + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_identify_endurance_group_list(int fd, __u16 endgrp_id, + struct nvme_id_endurance_group_list *list); + /** * nvme_identify_iocs() - * @fd: File descriptor of nvme device diff --git a/src/nvme/types.h b/src/nvme/types.h index bdbcb7b9aa..f020bab05e 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -98,6 +98,7 @@ enum nvme_constants { NVME_ID_NS_LIST_MAX = 1024, NVME_ID_SECONDARY_CTRL_MAX = 127, NVME_ID_DOMAIN_LIST_MAX = 31, + NVME_ID_ENDURANCE_GROUP_LIST_MAX = 2047, NVME_ID_ND_DESCRIPTOR_MAX = 16, NVME_FEAT_LBA_RANGE_MAX = 64, NVME_LOG_ST_MAX_RESULTS = 20, @@ -2210,6 +2211,16 @@ struct nvme_id_domain_list { struct nvme_id_domain_attr domain_attr[NVME_ID_DOMAIN_LIST_MAX]; }; +/** + * struct nvme_id_endurance_group_list - + * @num: + * @identifier: + */ +struct nvme_id_endurance_group_list { + __le16 num; + __le16 identifier[NVME_ID_ENDURANCE_GROUP_LIST_MAX]; +}; + /** * struct nvme_supported_log_pages - * @lid_support: @@ -5066,6 +5077,7 @@ enum nvme_admin_opcode { * @NVME_IDENTIFY_CNS_NS_GRANULARITY: * @NVME_IDENTIFY_CNS_UUID_LIST: * @NVME_IDENTIFY_CNS_DOMAIN_LIST: + * @NVME_IDENTIFY_CNS_ENDURANCE_GROUP_ID: * @NVME_IDENTIFY_CNS_CSI_ALLOCATED_NS_LIST: * @NVME_IDENTIFY_CNS_COMMAND_SET_STRUCTURE: Base Specification 2.0a section 5.17.2.21 */ @@ -5088,6 +5100,7 @@ enum nvme_identify_cns { NVME_IDENTIFY_CNS_NS_GRANULARITY = 0x16, NVME_IDENTIFY_CNS_UUID_LIST = 0x17, NVME_IDENTIFY_CNS_DOMAIN_LIST = 0x18, + NVME_IDENTIFY_CNS_ENDURANCE_GROUP_ID = 0x19, NVME_IDENTIFY_CNS_CSS_ALLOCATED_NS_LIST = 0x1A, NVME_IDENTIFY_CNS_COMMAND_SET_STRUCTURE = 0x1C, }; From 689f7808cc0bd0d586a71f47d4fa8806bb0a2a01 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Fri, 5 Nov 2021 18:36:38 +0100 Subject: [PATCH 0256/1564] types: nvme_id_ns rsvd area modified as lbaf fields Based spec : NVMe-NVM-Command-Set-Specification-1.0a-2021.07.26-Ratified [dwagner: ported from nvme-cli-monolithic] Signed-off-by: Daniel Wagner --- src/nvme/types.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/nvme/types.h b/src/nvme/types.h index f020bab05e..855bf6e58b 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -1659,8 +1659,7 @@ struct nvme_id_ns { __le16 endgid; __u8 nguid[16]; __u8 eui64[8]; - struct nvme_lbaf lbaf[16]; - __u8 rsvd192[192]; + struct nvme_lbaf lbaf[64]; __u8 vs[3712]; }; From 019db8a21b08a21e1c12a1a5e75559beb7fa21ef Mon Sep 17 00:00:00 2001 From: Steven Seungcheol Lee Date: Fri, 5 Nov 2021 18:42:56 +0100 Subject: [PATCH 0257/1564] types: Add missing Zone Attributes Information on zone descriptor NVMe-Zoned-Namespace-Command-Set-Specification-1.1a-2021.07.26-Ratified Figure 37: Zone Descriptor Data Structure - Zone Attributes Information Signed-off-by: Steven Seungcheol Lee [dwagner: ported from nvme-cli-monolithic] Signed-off-by: Daniel Wagner --- src/nvme/types.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/nvme/types.h b/src/nvme/types.h index 855bf6e58b..88d19f900c 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -3465,7 +3465,8 @@ struct nvme_zns_desc { __u8 zt; __u8 zs; __u8 za; - __u8 rsvd3[5]; + __u8 zai; + __u8 rsvd4[4]; __le64 zcap; __le64 zslba; __le64 wp; From 253d71f8d9403fc5cdee7badff6983bf8171b802 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Wed, 10 Nov 2021 18:22:21 +0100 Subject: [PATCH 0258/1564] build: Remove meson help text from meson.build The generic meson documentation is cluttering the meson.build file. This is already in README.md file, so let's just remove it completely. Signed-off-by: Daniel Wagner --- meson.build | 53 ----------------------------------------------------- 1 file changed, 53 deletions(-) diff --git a/meson.build b/meson.build index 9c2c3834e8..2383b679be 100644 --- a/meson.build +++ b/meson.build @@ -5,59 +5,6 @@ # # Authors: Martin Belanger # - -################################################################################ -# Building libnvme using meson and ninja: -# meson .build -# ninja -C .build -# -# Installing the code after building: -# cd .build -# sudo meson install -# -# Running unit tests: -# cd .build -# meson test -# -# In these examples, ".build" is the name of the directory where the build -# artifacts are saved. The directory need not be called ".build", but it must -# be a unique (non-existing) directory. -# -# Changing build options from the command line: -# Build options can be changed at the command line without modifying the -# "meson.build" files. This is particularly useful during debugging. For -# example, the "buildtype" option allows to disable optimization to -# facilitate debugging. This option can be specified on the command line as -# follows: -# -# meson .build -Dbuildtype=debug -# -# Doing so overrides the value found in the meson.build, which is set to -# "buildtype=release" below. The buildtype option can take any of the -# following values. -# -# plain: no extra build flags are used, even for compiler warnings, -# useful for distro packagers and other cases where you need -# to specify all arguments by yourself -# -# debug: debug info is generated but the result is not optimized, -# this is the default -# -# debugoptimized: debug info is generated and the code is optimized (on most -# compilers this means -g -O2) -# -# release: full optimization, no debug info -# -# default_options: https://mesonbuild.com/Builtin-options.html#compiler-options -# -# Examples: meson .build -Dbuildtype=debug -# meson .build -Db_sanitize=address -# meson .build -Djson-c=true -# -# References: https://mesonbuild.com/ -# https://ninja-build.org/ -# -################################################################################ project( 'libnvme', ['c', 'cpp'], meson_version: '>= 0.47.0', From 84756acd12e1681ac0ec51573784d603a586e292 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 11 Nov 2021 11:57:16 +0100 Subject: [PATCH 0259/1564] build: Adopt libsystemd versioning scheme systemd increases the micro version for every release which is compatible to what libtool expects. This means we just have to add the patch level to the version string which happens to be always 0. Signed-off-by: Daniel Wagner --- meson.build | 18 ++---------------- src/libnvme.map | 2 +- src/meson.build | 3 +-- 3 files changed, 4 insertions(+), 19 deletions(-) diff --git a/meson.build b/meson.build index 2383b679be..be02a289ee 100644 --- a/meson.build +++ b/meson.build @@ -8,7 +8,7 @@ project( 'libnvme', ['c', 'cpp'], meson_version: '>= 0.47.0', - version: '0.1', + version: '1.0', license: 'LGPLv2+', default_options: [ 'buildtype=release', @@ -16,21 +16,7 @@ project( ] ) -# https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html -# https://autotools.io/libtool/version.html -# The relation between libtool's current:revison:age interface versioning -# and the .so filename, .so.x.y.z, is -# x = current - age -# y = age -# z = revision -# If libtool_soversion is updated as described in libtool's documentation, -# x.y.z will usually *not* be equal to meson.project_version(). -libtool_soversion = [0, 0, 0] -libnvme_version = '@0@.@1@.@2@'.format( - libtool_soversion[0] - libtool_soversion[2], - libtool_soversion[2], - libtool_soversion[1] -) +library_version = meson.project_version() + '.0' ################################################################################ cc = meson.get_compiler('c') diff --git a/src/libnvme.map b/src/libnvme.map index aeed21c010..418f2892d6 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -1,4 +1,4 @@ -{ +LIBNVME_1_0 { global: __nvme_get_log_page; __nvme_msg; diff --git a/src/meson.build b/src/meson.build index 3651aa12c9..8d2e0d3541 100644 --- a/src/meson.build +++ b/src/meson.build @@ -33,8 +33,7 @@ version_script_arg = join_paths(source_dir, mapfile) libnvme = library( 'nvme', # produces libnvme.so sources, - version: libnvme_version, - soversion: '1', + version: library_version, link_args: ['-Wl,--version-script=' + version_script_arg], dependencies: deps, link_depends: mapfile, From 298d8aabb536b5d834d0c9c474d8757b75b58ab9 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Tue, 16 Nov 2021 22:47:18 +0100 Subject: [PATCH 0260/1564] build: Update json-c dependencies nvme-cli has a minimum dependency to json-c 0.14. Let's update libnvme accordingly to avoid any confusions. Signed-off-by: Daniel Wagner --- meson.build | 2 +- subprojects/json-c.wrap | 17 ++++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/meson.build b/meson.build index be02a289ee..afa86a68f4 100644 --- a/meson.build +++ b/meson.build @@ -38,7 +38,7 @@ libuuid = dependency('uuid', required: true) conf.set('CONFIG_LIBUUID', libuuid.found(), description: 'Is libuuid required?') # Check for json-c availability -json_c = dependency('json-c', version: '>=0.13', fallback : ['json-c', 'json_c']) +json_c = dependency('json-c', version: '>=0.14', fallback : ['json-c', 'json_c_dep']) conf.set('CONFIG_JSONC', json_c.found(), description: 'Is json-c required?') # local (cross-compilable) implementations of ccan configure steps diff --git a/subprojects/json-c.wrap b/subprojects/json-c.wrap index db391e0604..90089e2399 100644 --- a/subprojects/json-c.wrap +++ b/subprojects/json-c.wrap @@ -1,9 +1,12 @@ [wrap-file] -directory = json-c-0.13.1 -source_url = https://s3.amazonaws.com/json-c_releases/releases/json-c-0.13.1.tar.gz -source_filename = json-c-0.13.1.tar.gz -source_hash = b87e608d4d3f7bfdd36ef78d56d53c74e66ab278d318b71e6002a369d36f4873 -patch_url = https://wrapdb.mesonbuild.com/v2/json-c_0.13.1-1/get_patch -patch_filename = json-c-0.13.1-1-wrap.zip -patch_hash = 213a735c3c5f7ff4aa38850cd7bf236337c47fd553b9fcded64e709cab66b9fd +directory = json-c-0.15 +source_url = https://s3.amazonaws.com/json-c_releases/releases/json-c-0.15.tar.gz +source_filename = json-c-0.15.tar.gz +source_hash = b8d80a1ddb718b3ba7492916237bbf86609e9709fb007e7f7d4322f02341a4c6 +patch_filename = json-c_0.15-1_patch.zip +patch_url = https://wrapdb.mesonbuild.com/v2/json-c_0.15-1/get_patch +patch_hash = 002b44f87063a129b5f518ffb2dba7d107ecc665ba29f97e5547ffcae41de3a9 + +[provide] +json-c = json_c_dep From 4c489d0dbb23bad6ec681dc9483f201a4d7f3dd8 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Tue, 16 Nov 2021 22:48:41 +0100 Subject: [PATCH 0261/1564] workflows: Don't install libjson-c-dev ubuntu-latest ships an old version of json-c (0.13). Let's use the version from meson's wrapdb which is bit newer (0.15). Signed-off-by: Daniel Wagner --- .github/workflows/meson.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/meson.yml b/.github/workflows/meson.yml index e1fbdbd113..1ef39b7584 100644 --- a/.github/workflows/meson.yml +++ b/.github/workflows/meson.yml @@ -13,8 +13,6 @@ jobs: runs-on: ubuntu-latest steps: - - name: install libraries - run: sudo apt-get install libjson-c-dev - uses: actions/checkout@v2 - uses: actions/setup-python@v1 - uses: BSFishy/meson-build@v1.0.3 From 0d2daaacf08d0cd38a9ed12a3fbd7795bea06a3f Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 12 Aug 2021 13:23:13 +0200 Subject: [PATCH 0262/1564] fabrics: decode new discovery log entry type '3' TP8014 adds a new discovery log entry type '3' to describe the current discovery controller. Signed-off-by: Hannes Reinecke --- libnvme/nvme.i | 5 ++++- src/nvme/fabrics.c | 4 +++- src/nvme/types.h | 2 ++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/libnvme/nvme.i b/libnvme/nvme.i index cfab8a2a41..2572e930a6 100644 --- a/libnvme/nvme.i +++ b/libnvme/nvme.i @@ -219,11 +219,14 @@ static int discover_err = 0; PyDict_SetItemString(entry, "subnqn", val); switch (e->subtype) { case NVME_NQN_DISC: - val = PyUnicode_FromString("discovery"); + val = PyUnicode_FromString("referral"); break; case NVME_NQN_NVME: val = PyUnicode_FromString("nvme"); break; + case NVME_NQN_CURR: + val = PyUnicode_FromString("discovery"); + break; default: val = PyLong_FromLong(e->subtype); } diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 64ba10d41e..79239ab550 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -77,8 +77,9 @@ const char *nvmf_adrfam_str(__u8 adrfam) } static const char * const subtypes[] = { - [NVME_NQN_DISC] = "discovery subsystem", + [NVME_NQN_DISC] = "discovery subsystem referral", [NVME_NQN_NVME] = "nvme subsystem", + [NVME_NQN_CURR] = "current discovery subsystem", }; const char *nvmf_subtype_str(__u8 subtype) @@ -571,6 +572,7 @@ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, switch (e->subtype) { case NVME_NQN_DISC: + case NVME_NQN_CURR: if (discover) *discover = true; break; diff --git a/src/nvme/types.h b/src/nvme/types.h index 88d19f900c..023e3f3185 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -3831,10 +3831,12 @@ enum nvme_ae_info_notice { * enum nvme_subsys_type - * @NVME_NQN_DISC: Discovery type target subsystem * @NVME_NQN_NVME: NVME type target subsystem + * @NVME_NQN_CURR: Current Discovery type target subsystem */ enum nvme_subsys_type { NVME_NQN_DISC = 1, NVME_NQN_NVME = 2, + NVME_NQN_CURR = 3, }; #define NVME_DISC_SUBSYS_NAME "nqn.2014-08.org.nvmexpress.discovery" From bd8340f556eadc1730b7429a4d2c7391ace6691e Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 15 Nov 2021 15:27:27 +0100 Subject: [PATCH 0263/1564] fabrics: decode discover log page flags TP8014 defines a new discovery log page entry field 'eflags', which carries information about the returned entries. This patch decodes the new field. Signed-off-by: Hannes Reinecke --- src/nvme/fabrics.c | 13 +++++++++++++ src/nvme/fabrics.h | 11 +++++++++++ src/nvme/types.h | 9 ++++++++- 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 79239ab550..b944cd5520 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -100,6 +100,19 @@ const char *nvmf_treq_str(__u8 treq) return arg_str(treqs, ARRAY_SIZE(treqs), treq); } +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, " + "duplicate discovery information", +}; + +const char *nvmf_eflags_str(__u16 eflags) +{ + return arg_str(eflags_strings, ARRAY_SIZE(eflags_strings), eflags); +} + static const char * const sectypes[] = { [NVMF_TCP_SECTYPE_NONE] = "none", [NVMF_TCP_SECTYPE_TLS] = "tls", diff --git a/src/nvme/fabrics.h b/src/nvme/fabrics.h index 9b796be545..b037544ece 100644 --- a/src/nvme/fabrics.h +++ b/src/nvme/fabrics.h @@ -81,6 +81,17 @@ const char *nvmf_subtype_str(__u8 subtype); */ const char *nvmf_treq_str(__u8 treq); +/** + * nvmf_eflags_str() - Decode EFLAGS field + * @eflags: value to be decoded + * + * Decode the EFLAGS field in the discovery log page + * entry. + * + * Return: decoded string + */ +const char *nvmf_eflags_str(__u16 eflags); + /** * nvmf_sectype_str() - * @sectype: diff --git a/src/nvme/types.h b/src/nvme/types.h index 023e3f3185..b7f3fcc678 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -3847,6 +3847,11 @@ enum nvme_subsys_type { #define NVMF_NQN_SIZE 223 #define NVMF_TRSVCID_SIZE 32 +#define NVMF_DISC_EFLAGS_NONE 0 +#define NVMF_DISC_EFLAGS_DUPRETINFO 1 +#define NVMF_DISC_EFLAGS_EPCSD 2 +#define NVMF_DISC_EFLAGS_BOTH 3 + /** * struct nvmf_disc_log_entry - Discovery log page entry * @trtype: @@ -3856,6 +3861,7 @@ enum nvme_subsys_type { * @portid: * @cntlid: * @asqsz: + * @eflags: * @trsvcid: * @subnqn: * @traddr: @@ -3874,7 +3880,8 @@ struct nvmf_disc_log_entry { __le16 portid; __le16 cntlid; __le16 asqsz; - __u8 rsvd10[22]; + __le16 eflags; + __u8 rsvd12[20]; char trsvcid[NVMF_TRSVCID_SIZE]; __u8 rsvd64[192]; char subnqn[NVME_NQN_LENGTH]; From 66bb4e1c73d566c5048beab1345df6519700a946 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 15 Nov 2021 15:27:27 +0100 Subject: [PATCH 0264/1564] Distinguish between 'nvm' and 'discovery' subsystems Add a 'subsystype' value to the subsystem to determine if a given subsystem is a 'discovery' or a 'nvm' subsystem. And also add a flags 'discovery_ctrl' to specify if a given controller is a discovery controller; this allows connection to discovery controllers with unique subsystem NQNs, as these cannot distinguished by the NQN anymore. Signed-off-by: Hannes Reinecke --- src/nvme/fabrics.c | 34 +++++++++++++++++++--------------- src/nvme/private.h | 2 ++ src/nvme/tree.c | 28 ++++++++++++++++++++++++++++ src/nvme/tree.h | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 81 insertions(+), 15 deletions(-) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index b944cd5520..d6926e1635 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -417,6 +417,8 @@ static int build_options(nvme_host_t h, nvme_ctrl_t c, char **argstr) return -1; } if (!strcmp(nvme_ctrl_get_subsysnqn(c), NVME_DISC_SUBSYS_NAME)) + nvme_ctrl_set_discovery_ctrl(c, true); + if (nvme_ctrl_is_discovery_ctrl(c)) discover = true; hostnqn = nvme_host_get_hostnqn(h); hostid = nvme_host_get_hostid(h); @@ -583,21 +585,6 @@ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, bool disable_sqflow = false; int ret; - switch (e->subtype) { - case NVME_NQN_DISC: - case NVME_NQN_CURR: - if (discover) - *discover = true; - break; - case NVME_NQN_NVME: - break; - default: - nvme_msg(LOG_ERR, "skipping unsupported subtype %d\n", - e->subtype); - errno = EINVAL; - return NULL; - } - switch (e->trtype) { case NVMF_TRTYPE_RDMA: case NVMF_TRTYPE_TCP: @@ -651,6 +638,23 @@ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, errno = ENOMEM; return NULL; } + + switch (e->subtype) { + case NVME_NQN_DISC: + case NVME_NQN_CURR: + if (discover) + *discover = true; + nvme_ctrl_set_discovery_ctrl(c, true); + break; + default: + nvme_msg(LOG_ERR, "unsupported subtype %d\n", + e->subtype); + /* fallthrough */ + case NVME_NQN_NVME: + nvme_ctrl_set_discovery_ctrl(c, false); + break; + } + if (nvme_ctrl_is_discovered(c)) { errno = EAGAIN; return NULL; diff --git a/src/nvme/private.h b/src/nvme/private.h index 93770d43c3..46a8bebf67 100644 --- a/src/nvme/private.h +++ b/src/nvme/private.h @@ -86,6 +86,7 @@ struct nvme_ctrl { char *trsvcid; char *host_traddr; char *host_iface; + bool discovery_ctrl; bool discovered; bool persistent; struct nvme_fabrics_config cfg; @@ -103,6 +104,7 @@ struct nvme_subsystem { char *model; char *serial; char *firmware; + char *subsystype; }; struct nvme_host { diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 48b3919cfb..12b42d444b 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -222,6 +222,11 @@ const char *nvme_subsystem_get_name(nvme_subsystem_t s) return s->name; } +const char *nvme_subsystem_get_type(nvme_subsystem_t s) +{ + return s->subsystype; +} + nvme_ctrl_t nvme_subsystem_first_ctrl(nvme_subsystem_t s) { return list_top(&s->ctrls, struct nvme_ctrl, entry); @@ -283,6 +288,8 @@ static void __nvme_free_subsystem(struct nvme_subsystem *s) free(s->serial); if (s->firmware) free(s->firmware); + if (s->subsystype) + free(s->subsystype); free(s); } @@ -428,6 +435,13 @@ static int nvme_init_subsystem(nvme_subsystem_t s, const char *name, s->model = strdup("undefined"); s->serial = nvme_get_attr(path, "serial"); s->firmware = nvme_get_attr(path, "firmware_rev"); + s->subsystype = nvme_get_attr(path, "subsystype"); + if (!s->subsystype) { + if (!strcmp(s->subsysnqn, NVME_DISC_SUBSYS_NAME)) + s->subsystype = strdup("discovery"); + else + s->subsystype = strdup("nvm"); + } s->name = strdup(name); s->sysfs_dir = (char *)path; @@ -720,6 +734,16 @@ bool nvme_ctrl_is_persistent(nvme_ctrl_t c) return c->persistent; } +void nvme_ctrl_set_discovery_ctrl(nvme_ctrl_t c, bool discovery) +{ + c->discovery_ctrl = discovery; +} + +bool nvme_ctrl_is_discovery_ctrl(nvme_ctrl_t c) +{ + return c->discovery_ctrl; +} + int nvme_ctrl_identify(nvme_ctrl_t c, struct nvme_id_ctrl *id) { return nvme_identify_ctrl(nvme_ctrl_get_fd(c), id); @@ -1126,6 +1150,8 @@ int nvme_init_ctrl(nvme_host_t h, nvme_ctrl_t c, int instance) goto out_free_subsys; } } + if (s->subsystype && !strcmp(s->subsystype, "discovery")) + c->discovery_ctrl = true; c->s = s; list_add(&s->ctrls, &c->entry); out_free_subsys: @@ -1207,6 +1233,8 @@ static nvme_ctrl_t nvme_ctrl_alloc(nvme_subsystem_t s, const char *path, return NULL; } c->address = addr; + if (s->subsystype && !strcmp(s->subsystype, "discovery")) + c->discovery_ctrl = true; ret = nvme_configure_ctrl(c, path, name); return (ret < 0) ? NULL : c; } diff --git a/src/nvme/tree.h b/src/nvme/tree.h index fc01b5ef88..fb96f459bf 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -813,6 +813,28 @@ void nvme_ctrl_set_persistent(nvme_ctrl_t c, bool persistent); */ bool nvme_ctrl_is_persistent(nvme_ctrl_t c); +/** + * nvme_ctrl_set_discovery_ctrl() - Set the 'discovery_ctrl' flag + * @c: Controller to be modified + * @discovery: value of the discovery_ctrl flag + * + * Sets the 'discovery_ctrl' flag in @c to specify whether + * @c connects to a discovery subsystem. + * + */ +void nvme_ctrl_set_discovery_ctrl(nvme_ctrl_t c, bool discovery); + +/** + * nvme_ctrl_is_discovery_ctrl() - Check the 'discovery_ctrl' flag + * @c: Controller to be checked + * + * Returns the value of the 'discovery_ctrl' flag which specifies whether + * @c connects to a discovery subsystem. + * + * Return: value of the 'discover_ctrl' flag + */ +bool nvme_ctrl_is_discovery_ctrl(nvme_ctrl_t c); + /** * nvme_ctrl_disable_sqflow() - * @c: @@ -899,6 +921,16 @@ const char *nvme_subsystem_get_sysfs_dir(nvme_subsystem_t s); */ const char *nvme_subsystem_get_name(nvme_subsystem_t s); +/** + * nvme_subsystem_get_type() - Returns the type of a subsystem + * @s: Subsystem + * + * Returns the subsystem type of @s. + * + * Return: 'nvm' or 'discovery' + */ +const char *nvme_subsystem_get_type(nvme_subsystem_t s); + /** * nvme_scan_filter() - * @f: From 8ddfa217600040e0f915375dc13b762a8a8d2aee Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 16 Nov 2021 09:59:42 +0100 Subject: [PATCH 0265/1564] fabrics: set 'discovery' argument for unique discovery controllers Discovery controllers providing a unique NQN cannot be distinguished by the NQN from 'normal' I/O controllers, so we need to add the keyword 'discovery' when creating the connection to indicate that this is a disocvery connection. Signed-off-by: Hannes Reinecke --- doc/config-schema.json | 4 ++++ src/nvme/fabrics.c | 8 ++++++-- src/nvme/json.c | 5 +++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/doc/config-schema.json b/doc/config-schema.json index 53e6ffb78b..ed0fa5082e 100644 --- a/doc/config-schema.json +++ b/doc/config-schema.json @@ -135,6 +135,10 @@ "persistent": { "description": "Create persistent discovery connection", "type": "boolean" + }, + "discovery": { + "description": "Connect to a discovery controller", + "type": "boolean" } }, "required": [ "transport" ] diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index d6926e1635..c6b40d134f 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -391,7 +391,7 @@ static int build_options(nvme_host_t h, nvme_ctrl_t c, char **argstr) struct nvme_fabrics_config *cfg = nvme_ctrl_get_config(c); const char *transport = nvme_ctrl_get_transport(c); const char *hostnqn, *hostid; - bool discover = false; + bool discover = false, discovery_nqn = false; if (!transport) { nvme_msg(LOG_ERR, "need a transport (-t) argument\n"); @@ -416,8 +416,10 @@ static int build_options(nvme_host_t h, nvme_ctrl_t c, char **argstr) errno = ENOMEM; return -1; } - if (!strcmp(nvme_ctrl_get_subsysnqn(c), NVME_DISC_SUBSYS_NAME)) + if (!strcmp(nvme_ctrl_get_subsysnqn(c), NVME_DISC_SUBSYS_NAME)) { nvme_ctrl_set_discovery_ctrl(c, true); + discovery_nqn = true; + } if (nvme_ctrl_is_discovery_ctrl(c)) discover = true; hostnqn = nvme_host_get_hostnqn(h); @@ -433,6 +435,8 @@ static int build_options(nvme_host_t h, nvme_ctrl_t c, char **argstr) nvme_ctrl_get_trsvcid(c)) || (hostnqn && add_argument(argstr, "hostnqn", hostnqn)) || (hostid && add_argument(argstr, "hostid", hostid)) || + (discover && !discovery_nqn && + add_bool_argument(argstr, "discovery", true)) || (!discover && add_int_argument(argstr, "nr_io_queues", cfg->nr_io_queues, false)) || diff --git a/src/nvme/json.c b/src/nvme/json.c index 5aa09b091c..acf472c2e9 100644 --- a/src/nvme/json.c +++ b/src/nvme/json.c @@ -65,6 +65,9 @@ static void json_update_attributes(nvme_ctrl_t c, if (!strcmp("persistent", key_str) && !nvme_ctrl_is_persistent(c)) nvme_ctrl_set_persistent(c, true); + if (!strcmp("discovery", key_str) && + !nvme_ctrl_is_discovery_ctrl(c)) + nvme_ctrl_set_discovery_ctrl(c, true); } } @@ -209,6 +212,8 @@ static void json_update_port(struct json_object *ctrl_array, nvme_ctrl_t c) JSON_BOOL_OPTION(cfg, port_obj, data_digest); if (nvme_ctrl_is_persistent(c)) json_object_add_value_bool(port_obj, "persistent", true); + if (nvme_ctrl_is_discovery_ctrl(c)) + json_object_add_value_bool(port_obj, "discovery", true); json_object_array_add(ctrl_array, port_obj); } From 2a3ec9d8caced6384428dd7246030ec5740d7562 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Wed, 17 Nov 2021 13:38:30 +0100 Subject: [PATCH 0266/1564] build: Lower json-c dependencies libnvme has no hard requirement on json-c 0.14. It was updated to match to min version for nvme-cli. But nvme-cli has added a workaround, to avoid requiring a newer version of json-c. Let's drop the requirement here too. Signed-off-by: Daniel Wagner --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index afa86a68f4..cd573a615d 100644 --- a/meson.build +++ b/meson.build @@ -38,7 +38,7 @@ libuuid = dependency('uuid', required: true) conf.set('CONFIG_LIBUUID', libuuid.found(), description: 'Is libuuid required?') # Check for json-c availability -json_c = dependency('json-c', version: '>=0.14', fallback : ['json-c', 'json_c_dep']) +json_c = dependency('json-c', version: '>=0.13', fallback : ['json-c', 'json_c_dep']) conf.set('CONFIG_JSONC', json_c.found(), description: 'Is json-c required?') # local (cross-compilable) implementations of ccan configure steps From 7645d108f5e43753f321c673d5db56fd5dcfc4aa Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Wed, 17 Nov 2021 13:40:20 +0100 Subject: [PATCH 0267/1564] workflows: Install libjson-c-dev Since libnvme is able to use the 0.13 version provided by gitlabs CI, let's use it. Signed-off-by: Daniel Wagner --- .github/workflows/meson.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/meson.yml b/.github/workflows/meson.yml index 1ef39b7584..e1fbdbd113 100644 --- a/.github/workflows/meson.yml +++ b/.github/workflows/meson.yml @@ -13,6 +13,8 @@ jobs: runs-on: ubuntu-latest steps: + - name: install libraries + run: sudo apt-get install libjson-c-dev - uses: actions/checkout@v2 - uses: actions/setup-python@v1 - uses: BSFishy/meson-build@v1.0.3 From 262b5b75f6269adf6aea04834c153ae2f603b3eb Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 17 Nov 2021 14:01:02 +0100 Subject: [PATCH 0268/1564] fabrics: add nvmf_default_config() 'struct nvme_fabrics_config' has some default values, and the output functions key off these values to filter the values being printed. So to avoid applications having to know these default values this patch introduces a function nvmf_default_config() to ensure that every application is using the same defaults. Signed-off-by: Hannes Reinecke --- examples/discover-loop.c | 5 ++--- src/libnvme.map | 1 + src/nvme/fabrics.c | 7 +++++++ src/nvme/fabrics.h | 8 ++++++++ src/nvme/tree.c | 2 +- 5 files changed, 19 insertions(+), 4 deletions(-) diff --git a/examples/discover-loop.c b/examples/discover-loop.c index c2a2385080..b28edfa0df 100644 --- a/examples/discover-loop.c +++ b/examples/discover-loop.c @@ -53,10 +53,9 @@ int main() nvme_host_t h; nvme_ctrl_t c; int ret; + struct nvme_fabrics_config cfg; - struct nvme_fabrics_config cfg = { - .tos = -1, - }; + nvmf_default_config(&cfg); r = nvme_scan(NULL); h = nvme_default_host(r); diff --git a/src/libnvme.map b/src/libnvme.map index 418f2892d6..15cc566ccc 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -305,6 +305,7 @@ LIBNVME_1_0 { nvmf_adrfam_str; nvmf_cms_str; nvmf_connect_disc_entry; + nvmf_default_config; nvmf_get_discovery_log; nvmf_hostid_from_file; nvmf_hostnqn_from_file; diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index c6b40d134f..ddc6d6c7fb 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -155,6 +155,13 @@ const char *nvmf_cms_str(__u8 cm) return arg_str(cms, ARRAY_SIZE(cms), cm); } +void nvmf_default_config(struct nvme_fabrics_config *cfg) +{ + memset(cfg, 0, sizeof(*cfg)); + cfg->tos = -1; + cfg->ctrl_loss_tmo = NVMF_DEF_CTRL_LOSS_TMO; +} + #define UPDATE_CFG_OPTION(c, n, o, d) \ if ((c)->o == d) (c)->o = (n)->o static struct nvme_fabrics_config *merge_config(nvme_ctrl_t c, diff --git a/src/nvme/fabrics.h b/src/nvme/fabrics.h index b037544ece..9812db2f61 100644 --- a/src/nvme/fabrics.h +++ b/src/nvme/fabrics.h @@ -124,6 +124,14 @@ const char *nvmf_qptype_str(__u8 qptype); */ const char *nvmf_cms_str(__u8 cms); +/** + * nvmf_default_config - Default values for fabrics configuration + * @cfg: config values to set + * + * Initializes @cfg with default values. + */ +void nvmf_default_config(struct nvme_fabrics_config *cfg); + /** * nvmf_add_ctrl_opts() - * @c: diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 12b42d444b..f4b5528a3b 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -942,7 +942,7 @@ struct nvme_ctrl *nvme_create_ctrl(const char *subsysnqn, const char *transport, return NULL; } c->fd = -1; - c->cfg.tos = -1; + nvmf_default_config(&c->cfg); list_head_init(&c->namespaces); list_head_init(&c->paths); list_node_init(&c->entry); From f2b98a90077282279e589d1bc0823e258b264d0e Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 17 Nov 2021 15:58:03 +0100 Subject: [PATCH 0269/1564] Add missing symbols for discovery to map file Adding support for discovery controller discovery did not add the new symbols to the map file. --- src/libnvme.map | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libnvme.map b/src/libnvme.map index 15cc566ccc..b5ed2e157f 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -13,6 +13,7 @@ LIBNVME_1_0 { nvme_ctrl_first_ns; nvme_ctrl_first_path; nvme_ctrl_get_address; + nvme_ctrl_get_discovery_ctrl; nvme_ctrl_get_fd; nvme_ctrl_get_firmware; nvme_ctrl_get_host_iface; @@ -31,6 +32,7 @@ LIBNVME_1_0 { nvme_ctrl_get_transport; nvme_ctrl_get_trsvcid; nvme_ctrl_identify; + nvme_ctrl_is_discovery_ctrl; nvme_ctrl_next_ns; nvme_ctrl_next_path; nvme_ctrl_reset; @@ -280,7 +282,7 @@ LIBNVME_1_0 { nvme_subsystem_get_host; nvme_subsystem_get_name; nvme_subsystem_get_nqn; - nvme_subsystem_get_nqn; + nvme_subsystem_get_type; nvme_subsystem_get_sysfs_dir; nvme_subsystem_lookup_namespace; nvme_subsystem_next_ctrl; From 0155402e2d7516e4702319626ea31667fb72d4a3 Mon Sep 17 00:00:00 2001 From: Martin Belanger Date: Wed, 17 Nov 2021 10:20:28 -0500 Subject: [PATCH 0270/1564] Add discovery_ctrl_set() to Python bindings. Following Hannes' recent TP8013 changes, we need to add this method to the Python bindings. Signed-off-by: Martin Belanger --- libnvme/nvme.i | 6 ++++++ src/libnvme.map | 1 + 2 files changed, 7 insertions(+) diff --git a/libnvme/nvme.i b/libnvme/nvme.i index 2572e930a6..0432d00714 100644 --- a/libnvme/nvme.i +++ b/libnvme/nvme.i @@ -295,6 +295,7 @@ struct nvme_ctrl { %immutable serial; %immutable sqsize; %immutable persistent; + %immutable discovery_ctrl; char *transport; char *subsysnqn; char *traddr; @@ -308,6 +309,7 @@ struct nvme_ctrl { char *serial; char *sqsize; bool persistent; + bool discovery_ctrl; }; struct nvme_ns { @@ -502,6 +504,10 @@ struct nvme_ns { nvme_free_ctrl($self); } + void discovery_ctrl_set(bool discovery) { + nvme_ctrl_set_discovery_ctrl($self, discovery); + } + bool init(struct nvme_host *h, int instance) { return nvme_init_ctrl(h, $self, instance) == 0; } diff --git a/src/libnvme.map b/src/libnvme.map index 15cc566ccc..c81cff810e 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -34,6 +34,7 @@ LIBNVME_1_0 { nvme_ctrl_next_ns; nvme_ctrl_next_path; nvme_ctrl_reset; + nvme_ctrl_set_discovery_ctrl; nvme_ctrl_set_persistent; nvme_ctrls_filter; nvme_default_host; From 2891c7e770d21695c3c9b02ad31b5347a9fe5ebc Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 17 Nov 2021 18:23:51 +0100 Subject: [PATCH 0271/1564] fabrics: add missing function documentation and mapfile update Add some function documentation and the missing symbol nvmf_eflags_str to the mapfile. Signed-off-by: Hannes Reinecke --- src/libnvme.map | 1 + src/nvme/fabrics.h | 36 ++++++++++++++++++++++++------------ 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/libnvme.map b/src/libnvme.map index cb3c2dfb3b..a746feaad0 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -319,6 +319,7 @@ LIBNVME_1_0 { nvmf_subtype_str; nvmf_treq_str; nvmf_trtype_str; + nvmf_eflags_str; local: *; }; diff --git a/src/nvme/fabrics.h b/src/nvme/fabrics.h index 9812db2f61..4a7481a83f 100644 --- a/src/nvme/fabrics.h +++ b/src/nvme/fabrics.h @@ -50,34 +50,46 @@ struct nvme_fabrics_config { }; /** - * nvmf_trtype_str() - - * @trtype: + * nvmf_trtype_str() - Decode TRTYPE field + * @trtype: value to be decoded * - * Return: + * Decode the transport type field in the discovery + * log page entry. + * + * Return: decoded string */ const char *nvmf_trtype_str(__u8 trtype); /** - * nvmf_adrfam_str() - - * @adrfam: + * nvmf_adrfam_str() - Decode ADRFAM field + * @adrfam: value to be decoded * - * Return: + * Decode the address family field in the discovery + * log page entry. + * + * Return: decoded string */ const char *nvmf_adrfam_str(__u8 adrfam); /** - * nvmf_subtype_str() - - * @subtype: + * nvmf_subtype_str() - Decode SUBTYPE field + * @subtype: value to be decoded * - * Return: + * Decode the subsystem type field in the discovery + * log page entry. + * + * Return: decoded string */ const char *nvmf_subtype_str(__u8 subtype); /** - * nvmf_treq_str() - - * @treq: + * nvmf_treq_str() - Decode TREQ field + * @treq: value to be decoded * - * Return: + * Decode the transport requirements field in the + * discovery log page entry. + * + * Return: decoded string */ const char *nvmf_treq_str(__u8 treq); From e05fc01f0be7d78f6cc80739d05473a03bababa3 Mon Sep 17 00:00:00 2001 From: Minwoo Im Date: Mon, 15 Nov 2021 23:46:00 +0900 Subject: [PATCH 0272/1564] tree: add namespace chrdev name to nvme_ns Namespace device node is initialized into two different nodes: block device and character device which is a generic device used when block device is not available due to initialization failure in the kernel. This can be directly retrieved from the `struct nvme_ns` to print out the generic node in somewhere like `nvme list` command in nvme-cli. Signed-off-by: Minwoo Im --- src/libnvme.map | 1 + src/nvme/private.h | 1 + src/nvme/tree.c | 21 +++++++++++++++++++++ src/nvme/tree.h | 8 ++++++++ 4 files changed, 31 insertions(+) diff --git a/src/libnvme.map b/src/libnvme.map index 40050cff91..07672d6246 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -182,6 +182,7 @@ nvme_ns_get_model; nvme_ns_get_model; nvme_ns_get_name; + nvme_ns_get_generic_name; nvme_ns_get_nguid; nvme_ns_get_nsid; nvme_ns_get_serial; diff --git a/src/nvme/private.h b/src/nvme/private.h index 93770d43c3..20742fb559 100644 --- a/src/nvme/private.h +++ b/src/nvme/private.h @@ -45,6 +45,7 @@ struct nvme_ns { int fd; __u32 nsid; char *name; + char *generic_name; char *sysfs_dir; int lba_shift; diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 7a9637e391..0c7d66604d 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -1337,6 +1337,11 @@ const char *nvme_ns_get_name(nvme_ns_t n) return n->name; } +const char *nvme_ns_get_generic_name(nvme_ns_t n) +{ + return n->generic_name; +} + const char *nvme_ns_get_model(nvme_ns_t n) { return n->c ? n->c->model : n->s->model; @@ -1541,6 +1546,20 @@ static int nvme_ns_init(struct nvme_ns *n) return 0; } +static void nvme_ns_set_chrdev_name(struct nvme_ns *n, const char *name) +{ + char generic_name[PATH_MAX]; + int instance, head_instance; + int ret; + + ret = sscanf(name, "nvme%dn%d", &instance, &head_instance); + if (ret != 2) + return; + + sprintf(generic_name, "ng%dn%d", instance, head_instance); + n->generic_name = strdup(generic_name); +} + static nvme_ns_t nvme_ns_open(const char *name) { struct nvme_ns *n; @@ -1556,6 +1575,8 @@ static nvme_ns_t nvme_ns_open(const char *name) if (n->fd < 0) goto free_ns; + nvme_ns_set_chrdev_name(n, name); + if (nvme_get_nsid(n->fd, &n->nsid) < 0) goto close_fd; diff --git a/src/nvme/tree.h b/src/nvme/tree.h index fc01b5ef88..f6fc3521b9 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -452,6 +452,14 @@ const char *nvme_ns_get_sysfs_dir(nvme_ns_t n); */ const char *nvme_ns_get_name(nvme_ns_t n); +/** + * nvme_ns_get_generic_name() - Returns name of generic namesapce chardev. + * @n: Namespace instance + * + * Return: Name of generic namespace chardev + */ +const char *nvme_ns_get_generic_name(nvme_ns_t n); + /** * nvme_ns_get_firmware() - * @n: From ea0f1b66a004d1cdf7745779a0954ac5454983a1 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 18 Nov 2021 09:30:57 +0100 Subject: [PATCH 0273/1564] Add 'timeout' parameter to ioctl function Lift the 'timeout' parameter from the basic ioctl to the various ioctl command abstractions to get a better flexibility when using these commands. Signed-off-by: Hannes Reinecke --- src/nvme/ioctl.c | 273 +++++++++++++++++++++++++++++------------------ src/nvme/ioctl.h | 184 +++++++++++++++++++++++--------- src/nvme/linux.c | 16 +-- src/nvme/tree.c | 15 +-- test/zns.c | 4 +- 5 files changed, 329 insertions(+), 163 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index d1060dedaf..db12c546e7 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -362,7 +362,8 @@ enum features { }; int nvme_identify(int fd, enum nvme_identify_cns cns, __u32 nsid, __u16 cntid, - __u16 nvmsetid, __u16 domid, __u8 uuidx, __u8 csi, void *data) + __u16 nvmsetid, __u16 domid, __u8 uuidx, __u8 csi, + void *data, __u32 timeout) { __u32 cdw10 = NVME_SET(cntid, IDENTIFY_CDW10_CNTID) | NVME_SET(cns, IDENTIFY_CDW10_CNS); @@ -379,6 +380,7 @@ int nvme_identify(int fd, enum nvme_identify_cns cns, __u32 nsid, __u16 cntid, .cdw10 = cdw10, .cdw11 = cdw11, .cdw14 = cdw14, + .timeout_ms = timeout, }; return nvme_submit_admin_passthru(fd, &cmd, NULL); @@ -389,7 +391,7 @@ static int __nvme_identify(int fd, __u8 cns, __u32 nsid, void *data) return nvme_identify(fd, cns, nsid, NVME_CNTLID_NONE, NVME_NVMSETID_NONE, NVME_DOMID_NONE, NVME_UUID_NONE, NVME_CSI_NVM, - data); + data, NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_identify_ctrl(int fd, struct nvme_id_ctrl *id) @@ -430,7 +432,7 @@ int nvme_identify_ctrl_list(int fd, __u16 cntid, return nvme_identify(fd, NVME_IDENTIFY_CNS_CTRL_LIST, NVME_NSID_NONE, cntid, NVME_NVMSETID_NONE, NVME_DOMID_NONE, NVME_UUID_NONE, NVME_CSI_NVM, - ctrlist); + ctrlist, NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_identify_nsid_ctrl_list(int fd, __u32 nsid, __u16 cntid, @@ -438,7 +440,8 @@ int nvme_identify_nsid_ctrl_list(int fd, __u32 nsid, __u16 cntid, { return nvme_identify(fd, NVME_IDENTIFY_CNS_NS_CTRL_LIST, nsid, cntid, NVME_NVMSETID_NONE, NVME_DOMID_NONE, - NVME_UUID_NONE, NVME_CSI_NVM, ctrlist); + NVME_UUID_NONE, NVME_CSI_NVM, ctrlist, + NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_identify_ns_descs(int fd, __u32 nsid, struct nvme_ns_id_desc *descs) @@ -453,7 +456,7 @@ int nvme_identify_nvmset_list(int fd, __u16 nvmsetid, return nvme_identify(fd, NVME_IDENTIFY_CNS_NVMSET_LIST, NVME_NSID_NONE, NVME_CNTLID_NONE, nvmsetid, NVME_DOMID_NONE, NVME_UUID_NONE, NVME_CSI_NVM, - nvmset); + nvmset, NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_identify_primary_ctrl(int fd, __u16 cntid, @@ -463,7 +466,7 @@ int nvme_identify_primary_ctrl(int fd, __u16 cntid, return nvme_identify(fd, NVME_IDENTIFY_CNS_PRIMARY_CTRL_CAP, NVME_NSID_NONE, cntid, NVME_NVMSETID_NONE, NVME_DOMID_NONE, NVME_UUID_NONE, NVME_CSI_NVM, - cap); + cap, NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_identify_secondary_ctrl_list(int fd, __u32 nsid, __u16 cntid, @@ -473,7 +476,7 @@ int nvme_identify_secondary_ctrl_list(int fd, __u32 nsid, __u16 cntid, return nvme_identify(fd, NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST, nsid, cntid, NVME_NVMSETID_NONE, NVME_DOMID_NONE, NVME_UUID_NONE, NVME_CSI_NVM, - list); + list, NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_identify_ns_granularity(int fd, @@ -495,14 +498,16 @@ int nvme_identify_ctrl_csi(int fd, __u8 csi, void *data) { return nvme_identify(fd, NVME_IDENTIFY_CNS_CSI_CTRL, NVME_NSID_NONE, NVME_CNTLID_NONE, NVME_NVMSETID_NONE, - NVME_DOMID_NONE, NVME_UUID_NONE, csi, data); + NVME_DOMID_NONE, NVME_UUID_NONE, csi, data, + NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_identify_ns_csi(int fd, __u32 nsid, __u8 csi, void *data) { return nvme_identify(fd, NVME_IDENTIFY_CNS_CSI_NS, nsid, NVME_CNTLID_NONE, NVME_NVMSETID_NONE, - NVME_DOMID_NONE, NVME_UUID_NONE, csi, data); + NVME_DOMID_NONE, NVME_UUID_NONE, csi, data, + NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_identify_active_ns_list_csi(int fd, __u32 nsid, __u8 csi, @@ -511,7 +516,8 @@ int nvme_identify_active_ns_list_csi(int fd, __u32 nsid, __u8 csi, BUILD_ASSERT(sizeof(struct nvme_ns_list) == 4096); return nvme_identify(fd, NVME_IDENTIFY_CNS_CSI_NS_ACTIVE_LIST, nsid, NVME_CNTLID_NONE, NVME_NVMSETID_NONE, - NVME_DOMID_NONE, NVME_UUID_NONE, csi, list); + NVME_DOMID_NONE, NVME_UUID_NONE, csi, list, + NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_identify_allocated_ns_list_css(int fd, __u32 nsid, __u8 csi, @@ -519,7 +525,8 @@ int nvme_identify_allocated_ns_list_css(int fd, __u32 nsid, __u8 csi, { return nvme_identify(fd, NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST, nsid, NVME_CNTLID_NONE, NVME_NVMSETID_NONE, - NVME_DOMID_NONE, NVME_UUID_NONE, csi, list); + NVME_DOMID_NONE, NVME_UUID_NONE, csi, list, + NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_identify_domain_list(int fd, __u16 domid, @@ -528,7 +535,8 @@ int nvme_identify_domain_list(int fd, __u16 domid, BUILD_ASSERT(sizeof(struct nvme_id_domain_list) == 4096); return nvme_identify(fd, NVME_IDENTIFY_CNS_DOMAIN_LIST, NVME_NSID_NONE, NVME_CNTLID_NONE, NVME_NVMSETID_NONE, - domid, NVME_UUID_NONE, NVME_CSI_NVM, list); + domid, NVME_UUID_NONE, NVME_CSI_NVM, list, + NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_identify_endurance_group_list(int fd, __u16 endgrp_id, @@ -538,7 +546,7 @@ int nvme_identify_endurance_group_list(int fd, __u16 endgrp_id, return nvme_identify(fd, NVME_IDENTIFY_CNS_ENDURANCE_GROUP_ID, NVME_NSID_NONE, NVME_CNTLID_NONE, NVME_NVMSETID_NONE, endgrp_id, NVME_UUID_NONE, - NVME_CSI_NVM, list); + NVME_CSI_NVM, list, NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_identify_independent_identify_ns(int fd, __u32 nsid, @@ -548,7 +556,7 @@ int nvme_identify_independent_identify_ns(int fd, __u32 nsid, return nvme_identify(fd, NVME_IDENTIFY_CNS_CSI_INDEPENDENT_ID_NS, nsid, NVME_CNTLID_NONE, NVME_NVMSETID_NONE, NVME_DOMID_NONE, NVME_UUID_NONE, NVME_CSI_NVM, - ns); + ns, NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_identify_iocs(int fd, __u16 cntlid, struct nvme_id_iocs *iocs) @@ -557,7 +565,7 @@ int nvme_identify_iocs(int fd, __u16 cntlid, struct nvme_id_iocs *iocs) return nvme_identify(fd, NVME_IDENTIFY_CNS_COMMAND_SET_STRUCTURE, NVME_NSID_NONE, cntlid, NVME_NVMSETID_NONE, NVME_DOMID_NONE, NVME_UUID_NONE, NVME_CSI_NVM, - iocs); + iocs, NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_zns_identify_ns(int fd, __u32 nsid, struct nvme_zns_id_ns *data) @@ -566,7 +574,7 @@ int nvme_zns_identify_ns(int fd, __u32 nsid, struct nvme_zns_id_ns *data) return nvme_identify(fd, NVME_IDENTIFY_CNS_CSI_NS, nsid, NVME_CNTLID_NONE, NVME_NVMSETID_NONE, NVME_DOMID_NONE, NVME_UUID_NONE, NVME_CSI_ZNS, - data); + data, NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_zns_identify_ctrl(int fd, struct nvme_zns_id_ctrl *id) @@ -583,7 +591,7 @@ int nvme_nvm_identify_ctrl(int fd, struct nvme_id_ctrl_nvm *id) int nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, __u8 lsp, __u16 lsi, bool rae, __u8 uuidx, enum nvme_csi csi, - __u32 len, void *log) + __u32 len, void *log, __u32 timeout) { __u32 numd = (len >> 2) - 1; __u16 numdu = numd >> 16, numdl = numd & 0xffff; @@ -609,6 +617,7 @@ int nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, .cdw12 = cdw12, .cdw13 = cdw13, .cdw14 = cdw14, + .timeout_ms = timeout, }; return nvme_submit_admin_passthru(fd, &cmd, NULL); @@ -619,7 +628,7 @@ static int __nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, bool rae, { return nvme_get_log(fd, lid, NVME_NSID_ALL, 0, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, - NVME_CSI_NVM, len, log); + NVME_CSI_NVM, len, log, NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_get_log_supported_log_pages(int fd, bool rae, @@ -643,7 +652,8 @@ int nvme_get_log_smart(int fd, __u32 nsid, bool rae, struct nvme_smart_log *log) BUILD_ASSERT(sizeof(struct nvme_smart_log) == 512); return nvme_get_log(fd, NVME_LOG_LID_SMART, nsid, 0, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, - NVME_UUID_NONE, NVME_CSI_NVM, sizeof(*log), log); + NVME_UUID_NONE, NVME_CSI_NVM, sizeof(*log), log, + NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_get_log_fw_slot(int fd, bool rae, struct nvme_firmware_slot *log) @@ -666,7 +676,7 @@ int nvme_get_log_cmd_effects(int fd, enum nvme_csi csi, return nvme_get_log(fd, NVME_LOG_LID_CMD_EFFECTS, NVME_NSID_ALL, 0, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, NVME_UUID_NONE, csi, false, sizeof(*log), - log); + log, NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_get_log_device_self_test(int fd, struct nvme_self_test_log *log) @@ -687,7 +697,7 @@ int nvme_get_log_create_telemetry_host(int fd, struct nvme_telemetry_log *log) return nvme_get_log(fd, NVME_LOG_LID_TELEMETRY_HOST, NVME_NSID_NONE, 0, NVME_LOG_TELEM_HOST_LSP_CREATE, NVME_LOG_LSI_NONE, false, NVME_UUID_NONE, NVME_CSI_NVM, sizeof(*log), - log); + log, NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_get_log_telemetry_host(int fd, __u64 offset, __u32 len, void *log) @@ -695,7 +705,7 @@ int nvme_get_log_telemetry_host(int fd, __u64 offset, __u32 len, void *log) return nvme_get_log(fd, NVME_LOG_LID_TELEMETRY_HOST, NVME_NSID_NONE, offset, NVME_LOG_TELEM_HOST_LSP_RETAIN, NVME_LOG_LSI_NONE, false, NVME_UUID_NONE, - NVME_CSI_NVM, len, log); + NVME_CSI_NVM, len, log, NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_get_log_telemetry_ctrl(int fd, bool rae, __u64 offset, __u32 len, @@ -703,7 +713,8 @@ int nvme_get_log_telemetry_ctrl(int fd, bool rae, __u64 offset, __u32 len, { return nvme_get_log(fd, NVME_LOG_LID_TELEMETRY_CTRL, NVME_NSID_NONE, offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, - NVME_UUID_NONE, NVME_CSI_NVM, len, log); + NVME_UUID_NONE, NVME_CSI_NVM, len, log, + NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_get_log_endurance_group(int fd, __u16 endgid, @@ -712,7 +723,8 @@ int nvme_get_log_endurance_group(int fd, __u16 endgid, BUILD_ASSERT(sizeof(struct nvme_endurance_group_log) == 512); return nvme_get_log(fd, NVME_LOG_LID_ENDURANCE_GROUP, NVME_NSID_NONE, 0, NVME_LOG_LSP_NONE, endgid, false, NVME_UUID_NONE, - NVME_CSI_NVM, sizeof(*log), log); + NVME_CSI_NVM, sizeof(*log), log, + NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_get_log_predictable_lat_nvmset(int fd, __u16 nvmsetid, @@ -722,7 +734,7 @@ int nvme_get_log_predictable_lat_nvmset(int fd, __u16 nvmsetid, return nvme_get_log(fd, NVME_LOG_LID_PREDICTABLE_LAT_NVMSET, NVME_NSID_NONE, 0, NVME_LOG_LSP_NONE, nvmsetid, false, NVME_UUID_NONE, NVME_CSI_NVM, sizeof(*log), - log); + log, NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_get_log_predictable_lat_event(int fd, bool rae, __u32 offset, @@ -730,7 +742,8 @@ int nvme_get_log_predictable_lat_event(int fd, bool rae, __u32 offset, { return nvme_get_log(fd, NVME_LOG_LID_PREDICTABLE_LAT_AGG, NVME_NSID_NONE, offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, - rae, NVME_UUID_NONE, NVME_CSI_NVM, len, log); + rae, NVME_UUID_NONE, NVME_CSI_NVM, len, log, + NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_get_log_ana(int fd, enum nvme_log_ana_lsp lsp, bool rae, __u64 offset, @@ -738,7 +751,7 @@ int nvme_get_log_ana(int fd, enum nvme_log_ana_lsp lsp, bool rae, __u64 offset, { return nvme_get_log(fd, NVME_LOG_LID_ANA, NVME_NSID_NONE, offset, lsp,NVME_LOG_LSI_NONE, false, NVME_UUID_NONE, - NVME_CSI_NVM, len, log); + NVME_CSI_NVM, len, log, NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_get_log_ana_groups(int fd, bool rae, __u32 len, @@ -753,7 +766,8 @@ int nvme_get_log_lba_status(int fd, bool rae, __u64 offset, __u32 len, { return nvme_get_log(fd, NVME_LOG_LID_LBA_STATUS, NVME_NSID_NONE, offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, - NVME_UUID_NONE, NVME_CSI_NVM, len, log); + NVME_UUID_NONE, NVME_CSI_NVM, len, log, + NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_get_log_endurance_grp_evt(int fd, bool rae, __u32 offset, __u32 len, @@ -762,7 +776,7 @@ int nvme_get_log_endurance_grp_evt(int fd, bool rae, __u32 offset, __u32 len, return nvme_get_log(fd, NVME_LOG_LID_ENDURANCE_GRP_EVT, NVME_NSID_NONE, offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, - NVME_CSI_NVM, len, log); + NVME_CSI_NVM, len, log, NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_get_log_fid_supported_effects(int fd, bool rae, @@ -772,7 +786,8 @@ int nvme_get_log_fid_supported_effects(int fd, bool rae, return nvme_get_log(fd, NVME_LOG_LID_FID_SUPPORTED_EFFECTS, NVME_NSID_NONE, 0, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, - NVME_CSI_NVM, sizeof(*log), log); + NVME_CSI_NVM, sizeof(*log), log, + NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_get_log_boot_partition(int fd, bool rae, __u8 lsp, __u32 len, @@ -782,7 +797,8 @@ int nvme_get_log_boot_partition(int fd, bool rae, __u8 lsp, __u32 len, return nvme_get_log(fd, NVME_LOG_LID_BOOT_PARTITION, NVME_NSID_NONE, 0, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, - NVME_CSI_NVM, len, part); + NVME_CSI_NVM, len, part, + NVME_DEFAULT_IOCTL_TIMEOUT); } @@ -790,7 +806,8 @@ int nvme_get_log_discovery(int fd, bool rae, __u32 offset, __u32 len, void *log) { return nvme_get_log(fd, NVME_LOG_LID_DISCOVER, NVME_NSID_NONE, offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, - NVME_UUID_NONE, NVME_CSI_NVM, len, log); + NVME_UUID_NONE, NVME_CSI_NVM, len, log, + NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_get_log_reservation(int fd, bool rae, @@ -822,12 +839,13 @@ int nvme_get_log_zns_changed_zones(int fd, __u32 nsid, bool rae, BUILD_ASSERT(sizeof(struct nvme_zns_changed_zone_log) == 4096); return nvme_get_log(fd, NVME_LOG_LID_ZNS_CHANGED_ZONES, nsid, 0, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, - NVME_UUID_NONE, NVME_CSI_ZNS, sizeof(*log), log); + NVME_UUID_NONE, NVME_CSI_ZNS, sizeof(*log), log, + NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_set_features(int fd, __u8 fid, __u32 nsid, __u32 cdw11, __u32 cdw12, bool save, __u8 uuidx, __u32 cdw15, __u32 data_len, - void *data, __u32 *result) + void *data, __u32 timeout, __u32 *result) { __u32 cdw10 = NVME_SET(fid, FEATURES_CDW10_FID) | NVME_SET(!!save, SET_FEATURES_CDW10_SAVE); @@ -843,6 +861,7 @@ int nvme_set_features(int fd, __u8 fid, __u32 nsid, __u32 cdw11, __u32 cdw12, .cdw12 = cdw12, .cdw14 = cdw14, .cdw15 = cdw15, + .timeout_ms = timeout, }; return nvme_submit_admin_passthru(fd, &cmd, result); @@ -852,7 +871,8 @@ static int __nvme_set_features(int fd, __u8 fid, __u32 cdw11, bool save, __u32 *result) { return nvme_set_features(fd, fid, NVME_NSID_NONE, cdw11, 0, save, - NVME_UUID_NONE, 0, 0, NULL, result); + NVME_UUID_NONE, 0, 0, NULL, + NVME_DEFAULT_IOCTL_TIMEOUT, result); } int nvme_set_features_arbitration(int fd, __u8 ab, __u8 lpw, __u8 mpw, @@ -964,7 +984,8 @@ int nvme_set_features_timestamp(int fd, bool save, __u64 timestamp) memcpy(&t, ts.timestamp, sizeof(ts.timestamp)); return nvme_set_features(fd, NVME_FEAT_FID_TIMESTAMP, NVME_NSID_NONE, 0, 0, save, NVME_UUID_NONE, 0, - sizeof(ts), &ts, NULL); + sizeof(ts), &ts, + NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_set_features_hctm(int fd, __u16 tmt2, __u16 tmt1, @@ -990,7 +1011,7 @@ int nvme_set_features_rrl(int fd, __u8 rrl, __u16 nvmsetid, { return nvme_set_features(fd, NVME_FEAT_FID_RRL, NVME_NSID_NONE, nvmsetid, rrl, save, NVME_UUID_NONE, 0, 0, - NULL, result); + NULL, NVME_DEFAULT_IOCTL_TIMEOUT, result); } int nvme_set_features_plm_config(int fd, bool plm, __u16 nvmsetid, bool save, @@ -998,7 +1019,8 @@ int nvme_set_features_plm_config(int fd, bool plm, __u16 nvmsetid, bool save, { return nvme_set_features(fd, NVME_FEAT_FID_PLM_CONFIG, NVME_NSID_NONE, nvmsetid, !!plm, save, - NVME_UUID_NONE, 0, 0, NULL, result); + NVME_UUID_NONE, 0, 0, NULL, + NVME_DEFAULT_IOCTL_TIMEOUT, result); } int nvme_set_features_plm_window(int fd, enum nvme_feat_plm_window_select sel, @@ -1008,7 +1030,7 @@ int nvme_set_features_plm_window(int fd, enum nvme_feat_plm_window_select sel, return nvme_set_features(fd, NVME_FEAT_FID_PLM_WINDOW, NVME_NSID_NONE, nvmsetid, cdw12, save, NVME_UUID_NONE, 0, 0, - NULL, result); + NULL, NVME_DEFAULT_IOCTL_TIMEOUT, result); } int nvme_set_features_lba_sts_interval(int fd, __u16 lsiri, __u16 lsipi, @@ -1026,7 +1048,8 @@ int nvme_set_features_host_behavior(int fd, bool save, { return nvme_set_features(fd, NVME_FEAT_FID_HOST_BEHAVIOR, NVME_NSID_NONE, save, 0, 0, NVME_UUID_NONE, 0, - sizeof(*data), data, NULL); + sizeof(*data), data, + NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_set_features_sanitize(int fd, bool nodrm, bool save, __u32 *result) @@ -1057,7 +1080,8 @@ int nvme_set_features_host_id(int fd, bool save, bool exhid, __u8 *hostid) __u32 value = !!exhid; return nvme_set_features(fd, NVME_FEAT_FID_HOST_ID, NVME_NSID_NONE, - save, value, 0, NVME_UUID_NONE, 0, len, hostid, NULL); + save, value, 0, NVME_UUID_NONE, 0, len, + hostid, NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_set_features_resv_mask(int fd, __u32 mask, bool save, __u32 *result) @@ -1089,7 +1113,7 @@ int nvme_set_features_iocs_profile(int fd, __u8 iocsi, bool save) int nvme_get_features(int fd, enum nvme_features_id fid, __u32 nsid, enum nvme_get_features_sel sel, __u32 cdw11, __u8 uuidx, - __u32 data_len, void *data, __u32 *result) + __u32 data_len, void *data, __u32 timeout, __u32 *result) { __u32 cdw10 = NVME_SET(fid, FEATURES_CDW10_FID) | NVME_SET(sel, GET_FEATURES_CDW10_SEL); @@ -1103,6 +1127,7 @@ int nvme_get_features(int fd, enum nvme_features_id fid, __u32 nsid, .cdw10 = cdw10, .cdw11 = cdw11, .cdw14 = cdw14, + .timeout_ms = timeout, }; return nvme_submit_admin_passthru(fd, &cmd, result); @@ -1112,7 +1137,8 @@ static int __nvme_get_features(int fd, enum nvme_features_id fid, enum nvme_get_features_sel sel, __u32 *result) { return nvme_get_features(fd, fid, NVME_NSID_NONE, sel, 0, - NVME_UUID_NONE, 0, NULL, result); + NVME_UUID_NONE, 0, NULL, + NVME_DEFAULT_IOCTL_TIMEOUT, result); } int nvme_get_features_arbitration(int fd, enum nvme_get_features_sel sel, @@ -1132,7 +1158,8 @@ int nvme_get_features_lba_range(int fd, enum nvme_get_features_sel sel, __u32 *result) { return nvme_get_features(fd, NVME_FEAT_FID_LBA_RANGE, NVME_NSID_NONE, - sel, 0, NVME_UUID_NONE, 0, NULL, result); + sel, 0, NVME_UUID_NONE, 0, NULL, + NVME_DEFAULT_IOCTL_TIMEOUT, result); } int nvme_get_features_temp_thresh(int fd, enum nvme_get_features_sel sel, @@ -1171,7 +1198,8 @@ int nvme_get_features_irq_config(int fd, enum nvme_get_features_sel sel, __u16 iv, __u32 *result) { return nvme_get_features(fd, NVME_FEAT_FID_IRQ_CONFIG, NVME_NSID_NONE, - sel, iv, NVME_UUID_NONE, 0, NULL, result); + sel, iv, NVME_UUID_NONE, 0, NULL, + NVME_DEFAULT_IOCTL_TIMEOUT, result); } int nvme_get_features_write_atomic(int fd, enum nvme_get_features_sel sel, @@ -1191,7 +1219,8 @@ int nvme_get_features_auto_pst(int fd, enum nvme_get_features_sel sel, struct nvme_feat_auto_pst *apst, __u32 *result) { return nvme_get_features(fd, NVME_FEAT_FID_AUTO_PST, NVME_NSID_NONE, - sel, 0, NVME_UUID_NONE, 0, NULL, result); + sel, 0, NVME_UUID_NONE, 0, NULL, + NVME_DEFAULT_IOCTL_TIMEOUT, result); } int nvme_get_features_host_mem_buf(int fd, enum nvme_get_features_sel sel, @@ -1204,7 +1233,8 @@ int nvme_get_features_timestamp(int fd, enum nvme_get_features_sel sel, struct nvme_timestamp *ts) { return nvme_get_features(fd, NVME_FEAT_FID_TIMESTAMP, NVME_NSID_NONE, - sel, 0, NVME_UUID_NONE, 0, NULL, NULL); + sel, 0, NVME_UUID_NONE, 0, NULL, + NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_get_features_kato(int fd, enum nvme_get_features_sel sel, __u32 *result) @@ -1232,7 +1262,7 @@ int nvme_get_features_plm_config(int fd, enum nvme_get_features_sel sel, { return nvme_get_features(fd, NVME_FEAT_FID_PLM_CONFIG, NVME_NSID_NONE, sel, nvmsetid, NVME_UUID_NONE, 0, NULL, - result); + NVME_DEFAULT_IOCTL_TIMEOUT, result); } int nvme_get_features_plm_window(int fd, enum nvme_get_features_sel sel, @@ -1240,7 +1270,7 @@ int nvme_get_features_plm_window(int fd, enum nvme_get_features_sel sel, { return nvme_get_features(fd, NVME_FEAT_FID_PLM_WINDOW, NVME_NSID_NONE, sel, nvmsetid, NVME_UUID_NONE, 0, NULL, - result); + NVME_DEFAULT_IOCTL_TIMEOUT, result); } int nvme_get_features_lba_sts_interval(int fd, enum nvme_get_features_sel sel, @@ -1255,7 +1285,8 @@ int nvme_get_features_host_behavior(int fd, enum nvme_get_features_sel sel, __u32 *result) { return nvme_get_features(fd, NVME_FEAT_FID_HOST_BEHAVIOR, - NVME_NSID_NONE, sel, 0, NVME_UUID_NONE, 0, NULL, result); + NVME_NSID_NONE, sel, 0, NVME_UUID_NONE, 0, + NULL, NVME_DEFAULT_IOCTL_TIMEOUT, result); } int nvme_get_features_sanitize(int fd, enum nvme_get_features_sel sel, @@ -1269,7 +1300,7 @@ int nvme_get_features_endurance_event_cfg(int fd, enum nvme_get_features_sel sel { return nvme_get_features(fd, NVME_FEAT_FID_ENDURANCE_EVT_CFG, NVME_NSID_NONE, sel, 0, NVME_UUID_NONE, 0, - NULL, result); + NULL, NVME_DEFAULT_IOCTL_TIMEOUT, result); } int nvme_get_features_sw_progress(int fd, enum nvme_get_features_sel sel, @@ -1282,7 +1313,8 @@ int nvme_get_features_host_id(int fd, enum nvme_get_features_sel sel, bool exhid, __u32 len, __u8 *hostid) { return nvme_get_features(fd, NVME_FEAT_FID_HOST_ID, NVME_NSID_NONE, sel, - !!exhid, NVME_UUID_NONE, len, hostid, NULL); + !!exhid, NVME_UUID_NONE, len, hostid, + NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_get_features_resv_mask(int fd, enum nvme_get_features_sel sel, @@ -1302,7 +1334,8 @@ int nvme_get_features_write_protect(int fd, __u32 nsid, __u32 *result) { return nvme_get_features(fd, NVME_FEAT_FID_WRITE_PROTECT, nsid, sel, 0, - NVME_UUID_NONE, 0, NULL, result); + NVME_UUID_NONE, 0, NULL, + NVME_DEFAULT_IOCTL_TIMEOUT, result); } int nvme_get_features_iocs_profile(int fd, enum nvme_get_features_sel sel, @@ -1366,7 +1399,7 @@ int nvme_ns_mgmt_delete(int fd, __u32 nsid) } int nvme_ns_attach(int fd, __u32 nsid, enum nvme_ns_attach_sel sel, - struct nvme_ctrl_list *ctrlist) + struct nvme_ctrl_list *ctrlist, __u32 timeout) { __u32 cdw10 = NVME_SET(sel, NAMESPACE_ATTACH_CDW10_SEL); @@ -1376,6 +1409,7 @@ int nvme_ns_attach(int fd, __u32 nsid, enum nvme_ns_attach_sel sel, .cdw10 = cdw10, .data_len = sizeof(*ctrlist), .addr = (__u64)(uintptr_t)ctrlist, + .timeout_ms = timeout, }; return nvme_submit_admin_passthru(fd, &cmd, NULL); @@ -1383,16 +1417,18 @@ int nvme_ns_attach(int fd, __u32 nsid, enum nvme_ns_attach_sel sel, int nvme_ns_attach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist) { - return nvme_ns_attach(fd, nsid, NVME_NS_ATTACH_SEL_CTRL_ATTACH, ctrlist); + return nvme_ns_attach(fd, nsid, NVME_NS_ATTACH_SEL_CTRL_ATTACH, + ctrlist, NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_ns_detach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist) { return nvme_ns_attach(fd, nsid, NVME_NS_ATTACH_SEL_CTRL_DEATTACH, - ctrlist); + ctrlist, NVME_DEFAULT_IOCTL_TIMEOUT); } -int nvme_fw_download(int fd, __u32 offset, __u32 data_len, void *data) +int nvme_fw_download(int fd, __u32 offset, __u32 data_len, void *data, + __u32 timeout) { __u32 cdw10 = (data_len >> 2) - 1; __u32 cdw11 = offset >> 2; @@ -1403,6 +1439,7 @@ int nvme_fw_download(int fd, __u32 offset, __u32 data_len, void *data) .cdw11 = cdw11, .data_len = data_len, .addr = (__u64)(uintptr_t)data, + .timeout_ms = timeout, }; return nvme_submit_admin_passthru(fd, &cmd, NULL); @@ -1425,7 +1462,7 @@ int nvme_fw_commit(int fd, __u8 slot, enum nvme_fw_commit_ca action, bool bpid, int nvme_security_send(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, __u8 secp, __u32 tl, __u32 data_len, void *data, - __u32 *result) + __u32 timeout, __u32 *result) { __u32 cdw10 = NVME_SET(secp, SECURITY_SECP) | NVME_SET(spsp0, SECURITY_SPSP0) | @@ -1440,6 +1477,7 @@ int nvme_security_send(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, .cdw11 = cdw11, .data_len = data_len, .addr = (__u64)(uintptr_t)data, + .timeout_ms = timeout, }; return nvme_submit_admin_passthru(fd, &cmd, result); @@ -1447,7 +1485,7 @@ int nvme_security_send(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, int nvme_security_receive(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, __u8 secp, __u32 al, __u32 data_len, - void *data, __u32 *result) + void *data, __u32 timeout, __u32 *result) { __u32 cdw10 = NVME_SET(secp, SECURITY_SECP) | NVME_SET(spsp0, SECURITY_SPSP0) | @@ -1462,13 +1500,14 @@ int nvme_security_receive(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, .cdw11 = cdw11, .data_len = data_len, .addr = (__u64)(uintptr_t)data, + .timeout_ms = timeout, }; return nvme_submit_admin_passthru(fd, &cmd, result); } int nvme_get_lba_status(int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl, - enum nvme_lba_status_atype atype, + enum nvme_lba_status_atype atype, __u32 timeout, struct nvme_lba_status *lbas) { __u32 cdw10 = slba & 0xffffffff; @@ -1485,6 +1524,7 @@ int nvme_get_lba_status(int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl, .cdw11 = cdw11, .cdw12 = cdw12, .cdw13 = cdw13, + .timeout_ms = timeout, }; return nvme_submit_admin_passthru(fd, &cmd, NULL); @@ -1493,7 +1533,8 @@ int nvme_get_lba_status(int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl, int nvme_directive_send(int fd, __u32 nsid, __u16 dspec, enum nvme_directive_send_doper doper, enum nvme_directive_dtype dtype, __u32 cdw12, - __u32 data_len, void *data, __u32 *result) + __u32 data_len, void *data, __u32 timeout, + __u32 *result) { __u32 cdw10 = data_len ? (data_len >> 2) - 1 : 0; __u32 cdw11 = NVME_SET(doper, DIRECTIVE_CDW11_DOPER) | @@ -1508,6 +1549,7 @@ int nvme_directive_send(int fd, __u32 nsid, __u16 dspec, .cdw12 = cdw12, .data_len = data_len, .addr = (__u64)(uintptr_t)data, + .timeout_ms = timeout, }; return nvme_submit_admin_passthru(fd, &cmd, result); @@ -1522,7 +1564,8 @@ int nvme_directive_send_id_endir(int fd, __u32 nsid, bool endir, return nvme_directive_send(fd, nsid, 0, NVME_DIRECTIVE_DTYPE_IDENTIFY, NVME_DIRECTIVE_SEND_IDENTIFY_DOPER_ENDIR, - cdw12, sizeof(*id), id, NULL); + cdw12, sizeof(*id), id, + NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_directive_send_stream_release_identifier(int fd, __u32 nsid, @@ -1533,7 +1576,8 @@ int nvme_directive_send_stream_release_identifier(int fd, __u32 nsid, return nvme_directive_send(fd, nsid, stream_id, NVME_DIRECTIVE_DTYPE_STREAMS, - dtype, 0, 0, NULL, NULL); + dtype, 0, 0, NULL, + NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_directive_send_stream_release_resource(int fd, __u32 nsid) @@ -1542,13 +1586,15 @@ int nvme_directive_send_stream_release_resource(int fd, __u32 nsid) NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE; return nvme_directive_send(fd, nsid, 0, NVME_DIRECTIVE_DTYPE_STREAMS, - dtype, 0, 0, NULL, NULL); + dtype, 0, 0, NULL, + NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_directive_recv(int fd, __u32 nsid, __u16 dspec, enum nvme_directive_receive_doper doper, enum nvme_directive_dtype dtype, __u32 cdw12, - __u32 data_len, void *data, __u32 *result) + __u32 data_len, void *data, __u32 timeout, + __u32 *result) { __u32 cdw10 = data_len ? (data_len >> 2) - 1 : 0; __u32 cdw11 = NVME_SET(doper, DIRECTIVE_CDW11_DOPER) | @@ -1563,6 +1609,7 @@ int nvme_directive_recv(int fd, __u32 nsid, __u16 dspec, .cdw12 = cdw12, .data_len = data_len, .addr = (__u64)(uintptr_t)data, + .timeout_ms = timeout, }; return nvme_submit_admin_passthru(fd, &cmd, result); @@ -1575,7 +1622,8 @@ int nvme_directive_recv_identify_parameters(int fd, __u32 nsid, NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM; return nvme_directive_recv(fd, nsid, 0, NVME_DIRECTIVE_DTYPE_IDENTIFY, - dtype, 0, sizeof(*id), id, NULL); + dtype, 0, sizeof(*id), id, + NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_directive_recv_stream_parameters(int fd, __u32 nsid, @@ -1585,7 +1633,8 @@ int nvme_directive_recv_stream_parameters(int fd, __u32 nsid, NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM; return nvme_directive_recv(fd, nsid, 0, NVME_DIRECTIVE_DTYPE_STREAMS, - dtype, 0, sizeof(*parms), parms, NULL); + dtype, 0, sizeof(*parms), parms, + NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_directive_recv_stream_status(int fd, __u32 nsid, unsigned nr_entries, @@ -1595,7 +1644,8 @@ int nvme_directive_recv_stream_status(int fd, __u32 nsid, unsigned nr_entries, NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS; return nvme_directive_recv(fd, nsid, 0, NVME_DIRECTIVE_DTYPE_STREAMS, - dtype, 0, sizeof(*id), id, NULL); + dtype, 0, sizeof(*id), id, + NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_directive_recv_stream_allocate(int fd, __u32 nsid, __u16 nsr, @@ -1605,11 +1655,13 @@ int nvme_directive_recv_stream_allocate(int fd, __u32 nsid, __u16 nsr, NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE; return nvme_directive_recv(fd, nsid, 0, NVME_DIRECTIVE_DTYPE_STREAMS, - dtype, nsr, 0, NULL, result); + dtype, nsr, 0, NULL, + NVME_DEFAULT_IOCTL_TIMEOUT, result); } -int nvme_capacity_mgmt(int fd, __u8 op, __u16 element_id, __u32 dw11, __u32 dw12, - __u32 *result) +int nvme_capacity_mgmt(int fd, __u8 op, __u16 element_id, + __u32 dw11, __u32 dw12, + __u32 timeout, __u32 *result) { __u32 dw10 = op | element_id << 16; @@ -1618,6 +1670,7 @@ int nvme_capacity_mgmt(int fd, __u8 op, __u16 element_id, __u32 dw11, __u32 dw12 .cdw10 = dw10, .cdw11 = dw11, .cdw12 = dw12, + .timeout_ms = timeout, }; return nvme_submit_admin_passthru(fd, &cmd, result); @@ -1637,7 +1690,7 @@ int nvme_lockdown(int fd, __u8 scp, __u8 prhbt, __u8 ifc, __u8 ofi, return nvme_submit_admin_passthru(fd, &cmd, NULL); } -int nvme_set_property(int fd, int offset, __u64 value) +int nvme_set_property(int fd, int offset, __u64 value, __u32 timeout) { __u32 cdw10 = nvme_is_64bit_reg(offset); @@ -1648,12 +1701,13 @@ int nvme_set_property(int fd, int offset, __u64 value) .cdw11 = offset, .cdw12 = value & 0xffffffff, .cdw13 = value >> 32, + .timeout_ms = timeout, }; return nvme_submit_admin_passthru(fd, &cmd, NULL); } -int nvme_get_property(int fd, int offset, __u64 *value) +int nvme_get_property(int fd, int offset, __u64 *value, __u32 timeout) { __u32 cdw10 = nvme_is_64bit_reg(offset); @@ -1662,13 +1716,15 @@ int nvme_get_property(int fd, int offset, __u64 *value) .nsid = nvme_fabrics_type_property_get, .cdw10 = cdw10, .cdw11 = offset, + .timeout_ms = timeout, }; return nvme_submit_admin_passthru64(fd, &cmd, value); } int nvme_sanitize_nvm(int fd, enum nvme_sanitize_sanact sanact, bool ause, - __u8 owpass, bool oipbp, bool nodas, __u32 ovrpat) + __u8 owpass, bool oipbp, bool nodas, __u32 ovrpat, + __u32 timeout) { __u32 cdw10 = NVME_SET(sanact, SANITIZE_CDW10_SANACT) | NVME_SET(!!ause, SANITIZE_CDW10_AUSE) | @@ -1681,6 +1737,7 @@ int nvme_sanitize_nvm(int fd, enum nvme_sanitize_sanact sanact, bool ause, .opcode = nvme_admin_sanitize_nvm, .cdw10 = cdw10, .cdw11 = cdw11, + .timeout_ms = timeout, }; return nvme_submit_admin_passthru(fd, &cmd, NULL); @@ -1763,7 +1820,7 @@ int nvme_flush(int fd, __u32 nsid) static int nvme_io(int fd, __u8 opcode, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 flags, __u32 reftag, __u16 apptag, __u16 appmask, __u64 storage_tag, __u32 data_len, void *data, __u32 metadata_len, - void *metadata) + void *metadata, __u32 timeout) { __u32 cdw2 = storage_tag & 0xffffffff; __u32 cdw3 = (storage_tag >> 32) & 0xffff; @@ -1789,6 +1846,7 @@ static int nvme_io(int fd, __u8 opcode, __u32 nsid, __u64 slba, __u16 nlb, .metadata_len = metadata_len, .addr = (__u64)(uintptr_t)data, .metadata = (__u64)(uintptr_t)metadata, + .timeout_ms = timeout, }; return nvme_submit_io_passthru(fd, &cmd, NULL); @@ -1796,58 +1854,61 @@ static int nvme_io(int fd, __u8 opcode, __u32 nsid, __u64 slba, __u16 nlb, int nvme_read(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u8 dsm, __u32 reftag, __u16 apptag, __u16 appmask, - __u64 storage_tag, __u32 data_len, void *data, - __u32 metadata_len, void *metadata) + __u64 storage_tag, __u32 data_len, void *data, + __u32 metadata_len, void *metadata, __u32 timeout) { return nvme_io(fd, nvme_cmd_read, nsid, slba, nlb, control, dsm, reftag, apptag, appmask, storage_tag, data_len, data, - metadata_len, metadata); + metadata_len, metadata, timeout); } int nvme_write(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u8 dsm, __u16 dspec, __u32 reftag, __u16 apptag, __u16 appmask, __u64 storage_tag, __u32 data_len, void *data, - __u32 metadata_len, void *metadata) + __u32 metadata_len, void *metadata, __u32 timeout) { __u32 flags = dsm | dspec << 16; return nvme_io(fd, nvme_cmd_write, nsid, slba, nlb, control, flags, reftag, apptag, appmask, storage_tag, data_len, data, - metadata_len, metadata); + metadata_len, metadata, timeout); } int nvme_compare(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 reftag, __u16 apptag, __u16 appmask, __u32 data_len, - void *data, __u32 metadata_len, void *metadata) + void *data, __u32 metadata_len, void *metadata, __u32 timeout) { return nvme_io(fd, nvme_cmd_compare, nsid, slba, nlb, control, 0, reftag, apptag, appmask, 0, data_len, data, metadata_len, - metadata); + metadata, timeout); } int nvme_write_zeros(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 reftag, __u16 apptag, __u16 appmask, - __u64 storage_tag) + __u64 storage_tag, __u32 timeout) { return nvme_io(fd, nvme_cmd_write_zeroes, nsid, slba, nlb, control, 0, - reftag, apptag, appmask, storage_tag, 0, NULL, 0, NULL); + reftag, apptag, appmask, storage_tag, 0, NULL, 0, NULL, + timeout); } int nvme_verify(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, - __u32 reftag, __u16 apptag, __u16 appmask, __u64 storage_tag) + __u32 reftag, __u16 apptag, __u16 appmask, __u64 storage_tag, + __u32 timeout) { return nvme_io(fd, nvme_cmd_verify, nsid, slba, nlb, control, 0, - reftag, apptag, appmask, 0, 0, NULL, 0, NULL); + reftag, apptag, appmask, 0, 0, NULL, 0, NULL, timeout); } -int nvme_write_uncorrectable(int fd, __u32 nsid, __u64 slba, __u16 nlb) +int nvme_write_uncorrectable(int fd, __u32 nsid, __u64 slba, __u16 nlb, + __u32 timeout) { return nvme_io(fd, nvme_cmd_write_uncor, nsid, slba, nlb, 0, 0, 0, 0, - 0, 0, 0, NULL, 0, NULL); + 0, 0, 0, NULL, 0, NULL, timeout); } int nvme_dsm(int fd, __u32 nsid, __u32 attrs, __u16 nr_ranges, - struct nvme_dsm_range *dsm) + struct nvme_dsm_range *dsm, __u32 timeout) { __u32 cdw11 = attrs; @@ -1858,15 +1919,16 @@ int nvme_dsm(int fd, __u32 nsid, __u32 attrs, __u16 nr_ranges, .data_len = nr_ranges * sizeof(*dsm), .cdw10 = nr_ranges - 1, .cdw11 = cdw11, + .timeout_ms = timeout, }; return nvme_submit_io_passthru(fd, &cmd, NULL); } int nvme_copy(int fd, __u32 nsid, struct nvme_copy_range *copy, __u64 sdlba, - __u16 nr, __u8 prinfor, __u8 prinfow, __u8 dtype, __u16 dspec, - __u8 format, int lr, int fua, __u32 ilbrt, __u16 lbatm, - __u16 lbat) + __u16 nr, __u8 prinfor, __u8 prinfow, __u8 dtype, __u16 dspec, + __u8 format, int lr, int fua, __u32 ilbrt, __u16 lbatm, + __u16 lbat, __u32 timeout) { __u32 cdw12 = ((nr - 1) & 0xff) | ((format & 0xf) << 8) | ((prinfor & 0xf) << 12) | ((dtype & 0xf) << 20) | @@ -1884,6 +1946,7 @@ int nvme_copy(int fd, __u32 nsid, struct nvme_copy_range *copy, __u64 sdlba, .cdw13 = (dspec & 0xffff) << 16, .cdw14 = ilbrt, .cdw15 = (lbatm << 16) | lbat, + .timeout_ms = timeout, }; return nvme_submit_io_passthru(fd, &cmd, NULL); @@ -1891,7 +1954,7 @@ int nvme_copy(int fd, __u32 nsid, struct nvme_copy_range *copy, __u64 sdlba, int nvme_resv_acquire(int fd, __u32 nsid, enum nvme_resv_rtype rtype, enum nvme_resv_racqa racqa, bool iekey, - __u64 crkey, __u64 nrkey) + __u64 crkey, __u64 nrkey, __u32 timeout) { __le64 payload[2] = { cpu_to_le64(crkey), cpu_to_le64(nrkey) }; __u32 cdw10 = (racqa & 0x7) | (iekey ? 1 << 3 : 0) | rtype << 8; @@ -1902,6 +1965,7 @@ int nvme_resv_acquire(int fd, __u32 nsid, enum nvme_resv_rtype rtype, .cdw10 = cdw10, .data_len = sizeof(payload), .addr = (__u64)(uintptr_t)(payload), + .timeout_ms = timeout, }; return nvme_submit_io_passthru(fd, &cmd, NULL); @@ -1909,7 +1973,7 @@ int nvme_resv_acquire(int fd, __u32 nsid, enum nvme_resv_rtype rtype, int nvme_resv_register(int fd, __u32 nsid, enum nvme_resv_rrega rrega, enum nvme_resv_cptpl cptpl, bool iekey, - __u64 crkey, __u64 nrkey) + __u64 crkey, __u64 nrkey, __u32 timeout) { __le64 payload[2] = { cpu_to_le64(crkey), cpu_to_le64(nrkey) }; __u32 cdw10 = (rrega & 0x7) | (iekey ? 1 << 3 : 0) | cptpl << 30; @@ -1920,6 +1984,7 @@ int nvme_resv_register(int fd, __u32 nsid, enum nvme_resv_rrega rrega, .cdw10 = cdw10, .data_len = sizeof(payload), .addr = (__u64)(uintptr_t)(payload), + .timeout_ms = timeout, }; return nvme_submit_io_passthru(fd, &cmd, NULL); @@ -1927,7 +1992,7 @@ int nvme_resv_register(int fd, __u32 nsid, enum nvme_resv_rrega rrega, int nvme_resv_release(int fd, __u32 nsid, enum nvme_resv_rtype rtype, enum nvme_resv_rrela rrela, bool iekey, - __u64 crkey) + __u64 crkey, __u32 timeout) { __le64 payload[1] = { cpu_to_le64(crkey) }; __u32 cdw10 = (rrela & 0x7) | (iekey ? 1 << 3 : 0) | rtype << 8; @@ -1938,13 +2003,14 @@ int nvme_resv_release(int fd, __u32 nsid, enum nvme_resv_rtype rtype, .cdw10 = cdw10, .addr = (__u64)(uintptr_t)(payload), .data_len = sizeof(payload), + .timeout_ms = timeout, }; return nvme_submit_io_passthru(fd, &cmd, NULL); } int nvme_resv_report(int fd, __u32 nsid, bool eds, __u32 len, - struct nvme_resv_status *report) + struct nvme_resv_status *report, __u32 timeout) { struct nvme_passthru_cmd cmd = { .opcode = nvme_cmd_resv_report, @@ -1953,6 +2019,7 @@ int nvme_resv_report(int fd, __u32 nsid, bool eds, __u32 len, .cdw11 = eds ? 1 : 0, .addr = (__u64)(uintptr_t)report, .data_len = len, + .timeout_ms = timeout, }; return nvme_submit_io_passthru(fd, &cmd, NULL); @@ -1981,7 +2048,7 @@ int nvme_zns_mgmt_send(int fd, __u32 nsid, __u64 slba, bool select_all, return nvme_submit_io_passthru(fd, &cmd, NULL); } -int nvme_zns_mgmt_recv(int fd, __u32 nsid, __u64 slba, +int nvme_zns_mgmt_recv(int fd, __u32 nsid, __u64 slba, __u32 timeout, enum nvme_zns_recv_action zra, __u16 zrasf, bool zras_feat, __u32 data_len, void *data) { @@ -2001,14 +2068,15 @@ int nvme_zns_mgmt_recv(int fd, __u32 nsid, __u64 slba, .cdw13 = cdw13, .addr = (__u64)(uintptr_t)data, .data_len = data_len, + .timeout_ms = timeout, }; return nvme_submit_io_passthru(fd, &cmd, NULL); } -int nvme_zns_report_zones(int fd, __u32 nsid, __u64 slba, bool extended, - enum nvme_zns_report_options opts, bool partial, - __u32 data_len, void *data) +int nvme_zns_report_zones(int fd, __u32 nsid, __u64 slba, __u32 timeout, + bool extended, enum nvme_zns_report_options opts, + bool partial, __u32 data_len, void *data) { BUILD_ASSERT(sizeof(struct nvme_zns_desc) == 64); enum nvme_zns_recv_action zra; @@ -2018,14 +2086,14 @@ int nvme_zns_report_zones(int fd, __u32 nsid, __u64 slba, bool extended, else zra = NVME_ZNS_ZRA_REPORT_ZONES; - return nvme_zns_mgmt_recv(fd, nsid, slba, zra, opts, partial, + return nvme_zns_mgmt_recv(fd, nsid, slba, timeout, zra, opts, partial, data_len, data); } int nvme_zns_append(int fd, __u32 nsid, __u64 zslba, __u16 nlb, __u16 control, __u32 ilbrt, __u16 lbat, __u16 lbatm, __u32 data_len, void *data, __u32 metadata_len, void *metadata, - __u64 *result) + __u32 timeout, __u64 *result) { __u32 cdw10 = zslba & 0xffffffff; __u32 cdw11 = zslba >> 32; @@ -2045,6 +2113,7 @@ int nvme_zns_append(int fd, __u32 nsid, __u64 zslba, __u16 nlb, __u16 control, .addr = (__u64)(uintptr_t)data, .metadata_len = metadata_len, .data_len = data_len, + .timeout_ms = timeout, }; return nvme_submit_io_passthru64(fd, &cmd, result); diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 0a0e304692..f524756c79 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -24,6 +24,9 @@ #ifndef _LINUX_NVME_IOCTL_H #define _LINUX_NVME_IOCTL_H +/* '0' is interpreted by the kernel to mean 'apply the default timeout' */ +#define NVME_DEFAULT_IOCTL_TIMEOUT 0 + /** * struct nvme_passthru_cmd - * @opcode: Operation code, see &enum nvme_io_opcodes and &enum nvme_admin_opcodes @@ -381,6 +384,7 @@ int nvme_get_nsid(int fd, __u32 *nsid); * @uuidx: UUID Index if controller supports this id selection method * @csi: Command Set Identifier * @data: User space destination address to transfer the data + * @timeout: Timeout in ms (0 for default timeout) * * The Identify command returns a data buffer that describes information about * the NVM subsystem, the controller or the namespace(s). @@ -390,7 +394,7 @@ int nvme_get_nsid(int fd, __u32 *nsid); */ int nvme_identify(int fd, enum nvme_identify_cns cns, __u32 nsid, __u16 cntid, __u16 nvmsetid, __u16 domid, - __u8 uuidx, __u8 csi, void *data); + __u8 uuidx, __u8 csi, void *data, __u32 timeout); /** * nvme_identify_ctrl() - Retrieves nvme identify controller @@ -778,25 +782,26 @@ int nvme_zns_identify_ctrl(int fd, struct nvme_zns_id_ctrl *id); * values * @nsid: Namespace identifier, if applicable * @lpo: Log page offset for partial log transfers - * @lsp: Log specific field - * @lsi: Endurance group information - * @rae: Retain asynchronous events - * @uuidx: UUID selection, if supported - * @len: Length of provided user buffer to hold the log data in bytes - * @log: User space destination address to transfer the data + * @lsp: Log specific field + * @lsi: Endurance group information + * @rae: Retain asynchronous events + * @uuidx: UUID selection, if supported + * @len: Length of provided user buffer to hold the log data in bytes + * @log: User space destination address to transfer the data + * @timeout: Timeout in ms * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, __u8 lsp, __u16 lsi, bool rae, __u8 uuidx, enum nvme_csi csi, - __u32 len, void *log); + __u32 len, void *log, __u32 timeout); static inline int nvme_get_nsid_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u32 len, void *log) { return nvme_get_log(fd, lid, nsid, 0, 0, 0, false, 0, NVME_CSI_NVM, len, - log); + log, NVME_DEFAULT_IOCTL_TIMEOUT); } static inline int nvme_get_log_simple(int fd, enum nvme_cmd_get_log_lid lid, @@ -1129,6 +1134,7 @@ int nvme_get_log_persistent_event(int fd, enum nvme_pevent_log_action action, * @cdw14: Feature specific command dword15 field * @data_len: Length of feature data, if applicable, in bytes * @data: User address of feature data, if applicable + * @timeout: Timeout in ms * @result: The command completion result from CQE dword0 * * Return: The nvme command status if a response was received (see @@ -1136,14 +1142,14 @@ int nvme_get_log_persistent_event(int fd, enum nvme_pevent_log_action action, */ int nvme_set_features(int fd, __u8 fid, __u32 nsid, __u32 cdw11, __u32 cdw12, bool save, __u8 uuidx, __u32 cdw15, __u32 data_len, - void *data, __u32 *result); + void *data, __u32 timeout, __u32 *result); static inline int nvme_set_features_data(int fd, __u8 fid, __u32 nsid, __u32 cdw11, bool save, __u32 data_len, void *data, __u32 *result) { return nvme_set_features(fd, fid, nsid, cdw11, 0, save, 0, 0, data_len, - data, result); + data, NVME_DEFAULT_IOCTL_TIMEOUT, result); } static inline int nvme_set_features_simple(int fd, __u8 fid, __u32 nsid, @@ -1492,6 +1498,7 @@ int nvme_set_features_iocs_profile(int fd, __u8 iocsi, bool save); * @uuidx: UUID Index for differentiating vendor specific encoding * @data_len: Length of feature data, if applicable, in bytes * @data: User address of feature data, if applicable + * @timeout: Timeout in ms * @result: The command completion result from CQE dword0 * * Return: The nvme command status if a response was received (see @@ -1499,13 +1506,14 @@ int nvme_set_features_iocs_profile(int fd, __u8 iocsi, bool save); */ int nvme_get_features(int fd, enum nvme_features_id fid, __u32 nsid, enum nvme_get_features_sel sel, __u32 cdw11, __u8 uuidx, - __u32 data_len, void *data, __u32 *result); + __u32 data_len, void *data, __u32 timeout, __u32 *result); static inline int nvme_get_features_data(int fd, enum nvme_features_id fid, __u32 nsid, __u32 data_len, void *data, __u32 *result) { return nvme_get_features(fd, fid, nsid, NVME_GET_FEATURES_SEL_CURRENT, - 0, 0, data_len, data, result); + 0, 0, data_len, data, + NVME_DEFAULT_IOCTL_TIMEOUT, result); } static inline int nvme_get_features_simple(int fd, enum nvme_features_id fid, __u32 nsid, __u32 *result) @@ -1903,7 +1911,12 @@ int nvme_format_nvm(int fd, __u32 nsid, __u8 lbaf, /** * nvme_ns_mgmt() - * @fd: File descriptor of nvme device - * @csi: Command Set Identifier + * @nsid: Namespace identifier + * @sel: + * @ns: Namespace identication descriptors + * @result: NVMe command result + * @timeout: Timeout in ms + * @csi: Command Set Identifier */ int nvme_ns_mgmt(int fd, __u32 nsid, enum nvme_ns_mgmt_sel sel, struct nvme_id_ns *ns, __u32 *result, __u32 timeout, __u8 csi); @@ -1947,9 +1960,10 @@ int nvme_ns_mgmt_delete(int fd, __u32 nsid); * @nsid: Namespace ID to execute attach selection * @sel: Attachment selection, see &enum nvme_ns_attach_sel * @ctrlist: Controller list to modify attachment state of nsid + * @timeout: Timeout in ms */ int nvme_ns_attach(int fd, __u32 nsid, enum nvme_ns_attach_sel sel, - struct nvme_ctrl_list *ctrlist); + struct nvme_ctrl_list *ctrlist, __u32 timeout); /** * nvme_ns_attach_ctrls() - @@ -1974,6 +1988,7 @@ int nvme_ns_detach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist); * @offset: Offset in the firmware data * @data_len: Length of data in this command in bytes * @data: Userspace address of the firmware data + * @timeout: Timeout in ms * * The Firmware Image Download command downloads all or a portion of an image * for a future update to the controller. The Firmware Image Download command @@ -1991,7 +2006,8 @@ int nvme_ns_detach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist); * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_fw_download(int fd, __u32 offset, __u32 data_len, void *data); +int nvme_fw_download(int fd, __u32 offset, __u32 data_len, void *data, + __u32 timeout); /** * nvme_fw_commit() - Commit firmware using the specified action @@ -2023,6 +2039,7 @@ int nvme_fw_commit(int fd, __u8 slot, enum nvme_fw_commit_ca action, bool bpid, * @tl: Protocol specific transfer length * @data_len: Data length of the payload in bytes * @data: Security data payload to send + * @timeout: Timeout in ms * @result: The command completion result from CQE dword0 * * The Security Send command transfers security protocol data to the @@ -2039,7 +2056,7 @@ int nvme_fw_commit(int fd, __u8 slot, enum nvme_fw_commit_ca action, bool bpid, */ int nvme_security_send(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, __u8 secp, __u32 tl, __u32 data_len, void *data, - __u32 *result); + __u32 timeout, __u32 *result); /** * nvme_security_receive() - @@ -2052,6 +2069,7 @@ int nvme_security_send(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, * @al: Protocol specific allocation length * @data_len: Data length of the payload in bytes * @data: Security data payload to send + * @timeout: Timeout in ms * @result: The command completion result from CQE dword0 * * Return: The nvme command status if a response was received (see @@ -2059,7 +2077,7 @@ int nvme_security_send(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, */ int nvme_security_receive(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, __u8 secp, __u32 al, __u32 data_len, - void *data, __u32 *result); + void *data, __u32 timeout, __u32 *result); /** * nvme_get_lba_status() - Retrieve information on possibly unrecoverable LBAs @@ -2070,6 +2088,7 @@ int nvme_security_receive(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, * @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 + * @timeout: Timeout in ms * @lbas: Data payload to return status descriptors * * The Get LBA Status command requests information about Potentially @@ -2079,7 +2098,7 @@ int nvme_security_receive(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_lba_status(int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl, - enum nvme_lba_status_atype atype, + enum nvme_lba_status_atype atype, __u32 timeout, struct nvme_lba_status *lbas); /** @@ -2092,6 +2111,7 @@ int nvme_get_lba_status(int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl, * @dw12: Directive specific command dword12 * @data_len: Length of data payload in bytes * @data: Usespace address of data payload + * @timeout: Timeout in ms * @result: If successful, the CQE dword0 value * * Directives is a mechanism to enable host and NVM subsystem or controller @@ -2106,7 +2126,8 @@ int nvme_get_lba_status(int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl, int nvme_directive_send(int fd, __u32 nsid, __u16 dspec, enum nvme_directive_send_doper doper, enum nvme_directive_dtype dtype, __u32 cdw12, - __u32 data_len, void *data, __u32 *result); + __u32 data_len, void *data, __u32 timeout, + __u32 *result); /** * nvme_directive_send_id_endir() - @@ -2151,6 +2172,7 @@ int nvme_directive_send_stream_release_resource(int fd, __u32 nsid); * @dw12: Directive specific command dword12 * @data_len: Length of data payload * @data: Usespace address of data payload in bytes + * @timeout: Timeout in ms * @result: If successful, the CQE dword0 value * * Return: The nvme command status if a response was received (see @@ -2159,7 +2181,8 @@ int nvme_directive_send_stream_release_resource(int fd, __u32 nsid); int nvme_directive_recv(int fd, __u32 nsid, __u16 dspec, enum nvme_directive_receive_doper doper, enum nvme_directive_dtype dtype, __u32 cdw12, - __u32 data_len, void *data, __u32 *result); + __u32 data_len, void *data, __u32 timeout, + __u32 *result); /** * nvme_directive_recv_identify_parameters() - @@ -2214,13 +2237,15 @@ int nvme_directive_recv_stream_allocate(int fd, __u32 nsid, __u16 nsr, * Endurance Group or NVM Set to be created * @dw12: Most significant 32 bits of the capacity in bytes of the * Endurance Group or NVM Set to be created + * @timeout: Timeout in ms * @result: If successful, the CQE dword0 value * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_capacity_mgmt(int fd, __u8 op, __u16 element_id, __u32 dw11, __u32 dw12, - __u32 *result); +int nvme_capacity_mgmt(int fd, __u8 op, __u16 element_id, + __u32 dw11, __u32 dw12, + __u32 timeout, __u32 *result); /** * nvme_lockdown() - Issue lockdown command @@ -2242,6 +2267,7 @@ int nvme_lockdown(int fd, __u8 scp, __u8 prhbt, __u8 ifc, __u8 ofi, * @fd: File descriptor of nvme device * @offset: Property offset from the base to set * @value: The value to set the property + * @timeout: Timeout in ms * * This is an NVMe-over-Fabrics specific command, not applicable to PCIe. These * properties align to the PCI MMIO controller registers. @@ -2249,13 +2275,14 @@ int nvme_lockdown(int fd, __u8 scp, __u8 prhbt, __u8 ifc, __u8 ofi, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_set_property(int fd, int offset, __u64 value); +int nvme_set_property(int fd, int offset, __u64 value, __u32 timeout); /** * nvme_get_property() - Get a controller property * @fd: File descriptor of nvme device * @offset: Property offset from the base to retrieve * @value: Where the property's value will be stored on success + * @timeout: Timeout in ms * * This is an NVMe-over-Fabrics specific command, not applicable to PCIe. These * properties align to the PCI MMIO controller registers. @@ -2263,7 +2290,7 @@ int nvme_set_property(int fd, int offset, __u64 value); * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_get_property(int fd, int offset, __u64 *value); +int nvme_get_property(int fd, int offset, __u64 *value, __u32 timeout); /** * nvme_sanitize_nvm() - Start a sanitize operation @@ -2274,6 +2301,7 @@ int nvme_get_property(int fd, int offset, __u64 *value); * @oipbp: Set to overwrite invert pattern between passes * @nodas: Set to not deallocate blocks after sanitizing * @ovrpat: Overwrite pattern + * @timeout: Timeout in ms * * A sanitize operation alters all user data in the NVM subsystem such that * recovery of any previous user data from any cache, the non-volatile media, @@ -2289,7 +2317,8 @@ int nvme_get_property(int fd, int offset, __u64 *value); * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_sanitize_nvm(int fd, enum nvme_sanitize_sanact sanact, bool ause, - __u8 owpass, bool oipbp, bool nodas, __u32 ovrpat); + __u8 owpass, bool oipbp, bool nodas, __u32 ovrpat, + __u32 timeout); /** * nvme_dev_self_test() - Start or abort a self test @@ -2372,8 +2401,9 @@ int nvme_flush(int fd, __u32 nsid); * Tag (ELBRT) * @data_len: Length of user buffer, @data, in bytes * @data: Pointer to user address of the data buffer - * metadata_len:Length of user buffer, @metadata, in bytes + * @metadata_len:Length of user buffer, @metadata, in bytes * @metadata: Pointer to user address of the metadata buffer + * @timeout: Timeout in ms * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. @@ -2381,7 +2411,7 @@ int nvme_flush(int fd, __u32 nsid); int nvme_read(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u8 dsm, __u32 reftag, __u16 apptag, __u16 appmask, __u64 storage_tag, __u32 data_len, void *data, - __u32 metadata_len, void *metadata); + __u32 metadata_len, void *metadata, __u32 timeout); /** * nvme_write() - Submit an nvme user write command @@ -2406,8 +2436,9 @@ int nvme_read(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, * Tag (ELBRT) * @data_len: Length of user buffer, @data, in bytes * @data: Pointer to user address of the data buffer - * metadata_len:Length of user buffer, @metadata, in bytes + * @metadata_len:Length of user buffer, @metadata, in bytes * @metadata: Pointer to user address of the metadata buffer + * @timeout: Timeout in ms * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. @@ -2415,7 +2446,7 @@ int nvme_read(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, int nvme_write(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u8 dsm, __u16 dspec, __u32 reftag, __u16 apptag, __u16 appmask, __u64 storage_tag, __u32 data_len, void *data, - __u32 metadata_len, void *metadata); + __u32 metadata_len, void *metadata, __u32 timeout); /** * nvme_compare() - Submit an nvme user compare command @@ -2435,15 +2466,16 @@ int nvme_write(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, * information. * @data_len: Length of user buffer, @data, in bytes * @data: Pointer to user address of the data buffer - * metadata_len:Length of user buffer, @metadata, in bytes + * @metadata_len:Length of user buffer, @metadata, in bytes * @metadata: Pointer to user address of the metadata buffer + * @timeout: Timeout in ms * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_compare(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 reftag, __u16 apptag, __u16 appmask, __u32 data_len, - void *data, __u32 metadata_len, void *metadata); + void *data, __u32 metadata_len, void *metadata, __u32 timeout); /** * nvme_write_zeros() - Submit an nvme write zeroes command @@ -2464,6 +2496,7 @@ int nvme_compare(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, * @storage_tag: This filed specifies Variable Sized Expected Logical Block * Storage Tag (ELBST) and Expected Logical Block Reference * Tag (ELBRT) + * @timeout: Timeout in ms * * The Write Zeroes command sets a range of logical blocks to zero. After * successful completion of this command, the value returned by subsequent @@ -2475,7 +2508,7 @@ int nvme_compare(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, */ int nvme_write_zeros(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 reftag, __u16 apptag, __u16 appmask, - __u64 storage_tag); + __u64 storage_tag, __u32 timeout); /** * nvme_write_uncorrectable() - Submit an nvme write uncorrectable command @@ -2483,6 +2516,7 @@ int nvme_write_zeros(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, * @nsid: Namespace identifier * @slba: Starting logical block * @nlb: Number of logical blocks to invalidate (0's based value) + * @timeout: Timeout in ms * * The Write Uncorrectable command marks a range of logical blocks as invalid. * When the specified logical block(s) are read after this operation, a failure @@ -2492,7 +2526,8 @@ int nvme_write_zeros(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_write_uncorrectable(int fd, __u32 nsid, __u64 slba, __u16 nlb); +int nvme_write_uncorrectable(int fd, __u32 nsid, __u64 slba, __u16 nlb, + __u32 timeout); /** * nvme_verify() - Send an nvme verify command @@ -2513,6 +2548,7 @@ int nvme_write_uncorrectable(int fd, __u32 nsid, __u64 slba, __u16 nlb); * @storage_tag: This filed specifies Variable Sized Expected Logical Block * Storage Tag (ELBST) and Expected Logical Block Reference * Tag (ELBRT) + * @timeout: Timeout in ms * * The Verify command verifies integrity of stored information by reading data * and metadata, if applicable, for the LBAs indicated without transferring any @@ -2522,15 +2558,17 @@ int nvme_write_uncorrectable(int fd, __u32 nsid, __u64 slba, __u16 nlb); * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_verify(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, - __u32 reftag, __u16 apptag, __u16 appmask, __u64 storage_tag); + __u32 reftag, __u16 apptag, __u16 appmask, __u64 storage_tag, + __u32 timeout); /** * nvme_dsm() - Send an nvme data set management command * @fd: File descriptor of nvme device * @nsid: Namespace identifier * @attrs: DSM attributes, see &enum nvme_dsm_attributes - * &nr_ranges: Number of block ranges in the data set management attributes + * @nr_ranges: Number of block ranges in the data set management attributes * @dsm: The data set management attributes + * @timeout: Timeout in ms * * The Dataset Management command is used by the host to indicate attributes * for ranges of logical blocks. This includes attributes like frequency that @@ -2542,18 +2580,35 @@ int nvme_verify(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_dsm(int fd, __u32 nsid, __u32 attrs, __u16 nr_ranges, - struct nvme_dsm_range *dsm); + struct nvme_dsm_range *dsm, __u32 timeout); /** * nvme_copy() - * + * @fd: File descriptor of the nvme device + * @nsid: Namespace identifier + * @copy: Range descriptior + * @sdlba: Start destination LBA + * @nr: Number of ranges + * @prinfor: Protection information field for read + * @prinfow: Protection information field for write + * @dtype: Directive type + * @dspec: Directive specific value + * @format: Descriptor format + * @lr: Limited retry + * @fua: Force unit access + * @ilbrt: Initial logical block reference tag + * @lbatm: Logical block application tag mask + * @lbat: Logical block application tag + * @timeout: Timeout in ms + * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_copy(int fd, __u32 nsid, struct nvme_copy_range *copy, __u64 sdlba, __u16 nr, __u8 prinfor, __u8 prinfow, __u8 dtype, __u16 dspec, __u8 format, int lr, int fua, __u32 ilbrt, __u16 lbatm, - __u16 lbat); + __u16 lbat, __u32 timeout); /** * nvme_resv_acquire() - Send an nvme reservation acquire @@ -2565,6 +2620,7 @@ int nvme_copy(int fd, __u32 nsid, struct nvme_copy_range *copy, __u64 sdlba, * @crkey: The current reservation key associated with the host * @nrkey: The reservation key to be unregistered from the namespace if * the action is preempt + * @timeout: Timeout in ms * * The Reservation Acquire command acquires a reservation on a namespace, * preempt a reservation held on a namespace, and abort a reservation held on a @@ -2575,7 +2631,7 @@ int nvme_copy(int fd, __u32 nsid, struct nvme_copy_range *copy, __u64 sdlba, */ int nvme_resv_acquire(int fd, __u32 nsid, enum nvme_resv_rtype rtype, enum nvme_resv_racqa racqa, bool iekey, - __u64 crkey, __u64 nrkey); + __u64 crkey, __u64 nrkey, __u32 timeout); /** * nvme_resv_register() - Send an nvme reservation register @@ -2587,6 +2643,7 @@ int nvme_resv_acquire(int fd, __u32 nsid, enum nvme_resv_rtype rtype, * @crkey: The current reservation key associated with the host * @nrkey: The new reservation key to be register if action is register or * replace + * @timeout: Timeout in ms * * The Reservation Register command registers, unregisters, or replaces a * reservation key. @@ -2596,7 +2653,7 @@ int nvme_resv_acquire(int fd, __u32 nsid, enum nvme_resv_rtype rtype, */ int nvme_resv_register(int fd, __u32 nsid, enum nvme_resv_rrega rrega, enum nvme_resv_cptpl cptpl, bool iekey, - __u64 crkey, __u64 nrkey); + __u64 crkey, __u64 nrkey, __u32 timeout); /** * nvme_resv_release() - Send an nvme reservation release @@ -2606,13 +2663,14 @@ int nvme_resv_register(int fd, __u32 nsid, enum nvme_resv_rrega rrega, * @rrela: Reservation releast action, see &enum nvme_resv_rrela * @iekey: Set to ignore the existing key * @crkey: The current reservation key to release + * @timeout: Timeout in ms * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_resv_release(int fd, __u32 nsid, enum nvme_resv_rtype rtype, enum nvme_resv_rrela rrela, bool iekey, - __u64 crkey); + __u64 crkey, __u32 timeout); /** * nvme_resv_report() - Send an nvme reservation report @@ -2620,7 +2678,9 @@ int nvme_resv_release(int fd, __u32 nsid, enum nvme_resv_rtype rtype, * @nsid: Namespace identifier * @eds: Request extended Data Structure * @len: Number of bytes to request transfered with this command - * @report: The user space destination address to store the reservation report + * @report: The user space destination address to store the reservation + * report + * @timeout: Timeout in ms * * Returns a Reservation Status data structure to memory that describes the * registration and reservation status of a namespace. See the defintion for @@ -2630,7 +2690,7 @@ int nvme_resv_release(int fd, __u32 nsid, enum nvme_resv_rtype rtype, * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_resv_report(int fd, __u32 nsid, bool eds, __u32 len, - struct nvme_resv_status *report); + struct nvme_resv_status *report, __u32 timeout); /** * nvme_zns_mgmt_send() - @@ -2656,6 +2716,7 @@ int nvme_zns_mgmt_send(int fd, __u32 nsid, __u64 slba, bool select_all, * @fd: File descriptor of nvme device * @nsid: Namespace ID * @slba: + * @timeout: timeout in ms * @zra: * @zrasf: * @zras_feat: @@ -2665,18 +2726,45 @@ int nvme_zns_mgmt_send(int fd, __u32 nsid, __u64 slba, bool select_all, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_zns_mgmt_recv(int fd, __u32 nsid, __u64 slba, +int nvme_zns_mgmt_recv(int fd, __u32 nsid, __u64 slba, __u32 timeout, enum nvme_zns_recv_action zra, __u16 zrasf, bool zras_feat, __u32 data_len, void *data); -int nvme_zns_report_zones(int fd, __u32 nsid, __u64 slba, bool extended, - enum nvme_zns_report_options opts, bool partial, - __u32 data_len, void *data); +/** + * nvme_zns_report_zones() - Return the list of zones + * @fd: File descriptor of nvme device + * @nsid: Namespace ID + * @slba: Starting LBA + * @timeout: timeout in ms + * @extended: Extended report + * @opts: Reporting options + * @partial: Partial report requested + * @data_len: Length of the data buffer + * @data: Data buffer + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_zns_report_zones(int fd, __u32 nsid, __u64 slba, __u32 timeout, + bool extended, enum nvme_zns_report_options opts, + bool partial, __u32 data_len, void *data); /** * nvme_zns_append() - * @fd: File descriptor of nvme device * @nsid: Namespace ID + * @zslba: + * @nlb: + * @control: + * @ilbrt: + * @lbat: + * @lbam: + * @data_len: + * @data: + * @metadata_len: + * @metadata: + * @timeout: + * @result: * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. @@ -2684,6 +2772,6 @@ int nvme_zns_report_zones(int fd, __u32 nsid, __u64 slba, bool extended, int nvme_zns_append(int fd, __u32 nsid, __u64 zslba, __u16 nlb, __u16 control, __u32 ilbrt, __u16 lbat, __u16 lbatm, __u32 data_len, void *data, __u32 metadata_len, void *metadata, - __u64 *result); + __u32 timeout, __u64 *result); #endif /* _LIBNVME_IOCTL_H */ diff --git a/src/nvme/linux.c b/src/nvme/linux.c index f7668ac6f8..9b26eb969a 100644 --- a/src/nvme/linux.c +++ b/src/nvme/linux.c @@ -84,7 +84,8 @@ int nvme_fw_download_seq(int fd, __u32 size, __u32 xfer, __u32 offset, while (size > 0) { xfer = MIN(xfer, size); - err = nvme_fw_download(fd, offset, xfer, buf); + err = nvme_fw_download(fd, offset, xfer, buf, + NVME_DEFAULT_IOCTL_TIMEOUT); if (err) break; @@ -123,7 +124,8 @@ int __nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, ret = nvme_get_log(fd, log_id, nsid, offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, retain, NVME_UUID_NONE, - NVME_CSI_NVM, xfer, ptr); + NVME_CSI_NVM, xfer, ptr, + NVME_DEFAULT_IOCTL_TIMEOUT); if (ret) return ret; @@ -251,7 +253,7 @@ int nvme_get_lba_status_log(int fd, bool rae, struct nvme_lba_status_log **log) } static int nvme_ns_attachment(int fd, __u32 nsid, __u16 num_ctrls, - __u16 *ctrlist, bool attach) + __u16 *ctrlist, bool attach, __u32 timeout) { enum nvme_ns_attach_sel sel = NVME_NS_ATTACH_SEL_CTRL_DEATTACH; struct nvme_ctrl_list cntlist = { 0 }; @@ -260,19 +262,21 @@ static int nvme_ns_attachment(int fd, __u32 nsid, __u16 num_ctrls, sel = NVME_NS_ATTACH_SEL_CTRL_ATTACH; nvme_init_ctrl_list(&cntlist, num_ctrls, ctrlist); - return nvme_ns_attach(fd, nsid, sel, &cntlist); + return nvme_ns_attach(fd, nsid, sel, &cntlist, timeout); } int nvme_namespace_attach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist) { - return nvme_ns_attachment(fd, nsid, num_ctrls, ctrlist, true); + return nvme_ns_attachment(fd, nsid, num_ctrls, ctrlist, true, + NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_namespace_detach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist) { - return nvme_ns_attachment(fd, nsid, num_ctrls, ctrlist, false); + return nvme_ns_attachment(fd, nsid, num_ctrls, ctrlist, false, + NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_get_ana_log_len(int fd, size_t *analen) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index f4b5528a3b..9740972a19 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -1446,7 +1446,7 @@ int nvme_ns_verify(nvme_ns_t n, off_t offset, size_t count) return -1; return nvme_verify(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), slba, nlb, - 0, 0, 0, 0, 0); + 0, 0, 0, 0, 0, NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_ns_write_uncorrectable(nvme_ns_t n, off_t offset, size_t count) @@ -1458,7 +1458,7 @@ int nvme_ns_write_uncorrectable(nvme_ns_t n, off_t offset, size_t count) return -1; return nvme_write_uncorrectable(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), - slba, nlb); + slba, nlb, NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_ns_write_zeros(nvme_ns_t n, off_t offset, size_t count) @@ -1470,7 +1470,7 @@ int nvme_ns_write_zeros(nvme_ns_t n, off_t offset, size_t count) return -1; return nvme_write_zeros(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), slba, - nlb, 0, 0, 0, 0, 0); + nlb, 0, 0, 0, 0, 0, NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_ns_write(nvme_ns_t n, void *buf, off_t offset, size_t count) @@ -1482,7 +1482,8 @@ int nvme_ns_write(nvme_ns_t n, void *buf, off_t offset, size_t count) return -1; return nvme_write(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), slba, nlb, 0, - 0, 0, 0, 0, 0, 0, count, buf, 0, NULL); + 0, 0, 0, 0, 0, 0, count, buf, 0, NULL, + NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_ns_read(nvme_ns_t n, void *buf, off_t offset, size_t count) @@ -1494,7 +1495,8 @@ int nvme_ns_read(nvme_ns_t n, void *buf, off_t offset, size_t count) return -1; return nvme_read(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), slba, nlb, 0, - 0, 0, 0, 0, 0, count, buf, 0, NULL); + 0, 0, 0, 0, 0, count, buf, 0, NULL, + NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_ns_compare(nvme_ns_t n, void *buf, off_t offset, size_t count) @@ -1506,7 +1508,8 @@ int nvme_ns_compare(nvme_ns_t n, void *buf, off_t offset, size_t count) return -1; return nvme_compare(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), slba, nlb, - 0, 0, 0, 0, count, buf, 0, NULL); + 0, 0, 0, 0, count, buf, 0, NULL, + NVME_DEFAULT_IOCTL_TIMEOUT); } int nvme_ns_flush(nvme_ns_t n) diff --git a/test/zns.c b/test/zns.c index 54a6779ad9..95cb006840 100644 --- a/test/zns.c +++ b/test/zns.c @@ -45,7 +45,9 @@ static void show_zns_properties(nvme_ns_t n) printf("zasl:%u\n", zns_ctrl.zasl); if (nvme_zns_mgmt_recv(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), 0, - NVME_ZNS_ZRA_REPORT_ZONES, NVME_ZNS_ZRAS_REPORT_ALL, + NVME_DEFAULT_IOCTL_TIMEOUT, + NVME_ZNS_ZRA_REPORT_ZONES, + NVME_ZNS_ZRAS_REPORT_ALL, 0, 0x1000, (void *)zr)) { fprintf(stderr, "failed to report zones\n");; return; From 86a356e66f85866c7a17cf4607ced4f3ae2f14b1 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 18 Nov 2021 09:53:54 +0100 Subject: [PATCH 0274/1564] build: Update json-c.wrap The json-c wrap was updated to fix a deprecation warnings issued by meson. Signed-off-by: Daniel Wagner --- subprojects/json-c.wrap | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/subprojects/json-c.wrap b/subprojects/json-c.wrap index 90089e2399..4ce9ab8692 100644 --- a/subprojects/json-c.wrap +++ b/subprojects/json-c.wrap @@ -3,9 +3,9 @@ directory = json-c-0.15 source_url = https://s3.amazonaws.com/json-c_releases/releases/json-c-0.15.tar.gz source_filename = json-c-0.15.tar.gz source_hash = b8d80a1ddb718b3ba7492916237bbf86609e9709fb007e7f7d4322f02341a4c6 -patch_filename = json-c_0.15-1_patch.zip -patch_url = https://wrapdb.mesonbuild.com/v2/json-c_0.15-1/get_patch -patch_hash = 002b44f87063a129b5f518ffb2dba7d107ecc665ba29f97e5547ffcae41de3a9 +patch_filename = json-c_0.15-2_patch.zip +patch_url = https://wrapdb.mesonbuild.com/v2/json-c_0.15-2/get_patch +patch_hash = 2c5c95cf463804ac61309930c76ba9f57b157fef6247d1c6da4395b31a5bfac7 [provide] json-c = json_c_dep From b5d5485f3ce86b7918d44b9dc4c86a9fad03c4b2 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 18 Nov 2021 10:04:13 +0100 Subject: [PATCH 0275/1564] build: Rename config.h to libnvme-config.h The meson documentation recommends not to put a config.h file in the external search path. This will clash with any project consuming this library. There are two ways to workaround, either renaming the config header file or put it under a different path which isn't added into the default include path. Renaming is way simpler, let's do this. Signed-off-by: Daniel Wagner --- meson.build | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/meson.build b/meson.build index cd573a615d..15ad8eb284 100644 --- a/meson.build +++ b/meson.build @@ -120,8 +120,8 @@ conf.set10( description: 'Is isblank() available?' ) -config_h = configure_file( - output: 'config.h', +configure_file( + output: 'libnvme-config.h', configuration: conf ) @@ -137,7 +137,8 @@ configure_file( ) ################################################################################ -add_project_arguments(['-fomit-frame-pointer', '-D_GNU_SOURCE', '-include', 'config.h'], language : 'c') +add_project_arguments(['-fomit-frame-pointer', '-D_GNU_SOURCE', + '-include', 'libnvme-config.h'], language : 'c') incdir = include_directories(['.', 'ccan', 'src']) ################################################################################ From 91884e90022ce7393e8730fd52bc7f58d68ca46f Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 18 Nov 2021 10:23:04 +0100 Subject: [PATCH 0276/1564] build: Set include dirs when buidling configurator The default include paths are not set when building the configurator, hence the build fails when libnvme is consumed by an project as wrap. Signed-off-by: Daniel Wagner --- ccan/meson.build | 1 + 1 file changed, 1 insertion(+) diff --git a/ccan/meson.build b/ccan/meson.build index 7268710da6..253c139ca7 100644 --- a/ccan/meson.build +++ b/ccan/meson.build @@ -16,6 +16,7 @@ configurator = executable( 'configurator', ['tools/configurator/configurator.c'], c_args: ['-D_GNU_SOURCE'], + include_directories: incdir, ) config_h = custom_target( From f362556f26316b3f7b0c3f92e81e3fa64b7d4087 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 18 Nov 2021 10:29:10 +0100 Subject: [PATCH 0277/1564] Add 'result' argument to ioctl wrapper functions The ioctl wrapper function are pretty inconsistent as to whether the NVME cqe result is returned or not. We'd better add it to every function to have a consistent interface. Signed-off-by: Hannes Reinecke --- src/nvme/ioctl.c | 142 +++++++++++++++++++++++++---------------------- src/nvme/ioctl.h | 58 ++++++++++++------- src/nvme/linux.c | 4 +- test/zns.c | 6 +- 4 files changed, 121 insertions(+), 89 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index db12c546e7..b28fa22a6a 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -363,7 +363,7 @@ enum features { int nvme_identify(int fd, enum nvme_identify_cns cns, __u32 nsid, __u16 cntid, __u16 nvmsetid, __u16 domid, __u8 uuidx, __u8 csi, - void *data, __u32 timeout) + void *data, __u32 timeout, __u32 *result) { __u32 cdw10 = NVME_SET(cntid, IDENTIFY_CDW10_CNTID) | NVME_SET(cns, IDENTIFY_CDW10_CNS); @@ -383,7 +383,7 @@ int nvme_identify(int fd, enum nvme_identify_cns cns, __u32 nsid, __u16 cntid, .timeout_ms = timeout, }; - return nvme_submit_admin_passthru(fd, &cmd, NULL); + return nvme_submit_admin_passthru(fd, &cmd, result); } static int __nvme_identify(int fd, __u8 cns, __u32 nsid, void *data) @@ -391,7 +391,7 @@ static int __nvme_identify(int fd, __u8 cns, __u32 nsid, void *data) return nvme_identify(fd, cns, nsid, NVME_CNTLID_NONE, NVME_NVMSETID_NONE, NVME_DOMID_NONE, NVME_UUID_NONE, NVME_CSI_NVM, - data, NVME_DEFAULT_IOCTL_TIMEOUT); + data, NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_identify_ctrl(int fd, struct nvme_id_ctrl *id) @@ -432,7 +432,7 @@ int nvme_identify_ctrl_list(int fd, __u16 cntid, return nvme_identify(fd, NVME_IDENTIFY_CNS_CTRL_LIST, NVME_NSID_NONE, cntid, NVME_NVMSETID_NONE, NVME_DOMID_NONE, NVME_UUID_NONE, NVME_CSI_NVM, - ctrlist, NVME_DEFAULT_IOCTL_TIMEOUT); + ctrlist, NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_identify_nsid_ctrl_list(int fd, __u32 nsid, __u16 cntid, @@ -441,7 +441,7 @@ int nvme_identify_nsid_ctrl_list(int fd, __u32 nsid, __u16 cntid, return nvme_identify(fd, NVME_IDENTIFY_CNS_NS_CTRL_LIST, nsid, cntid, NVME_NVMSETID_NONE, NVME_DOMID_NONE, NVME_UUID_NONE, NVME_CSI_NVM, ctrlist, - NVME_DEFAULT_IOCTL_TIMEOUT); + NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_identify_ns_descs(int fd, __u32 nsid, struct nvme_ns_id_desc *descs) @@ -456,7 +456,7 @@ int nvme_identify_nvmset_list(int fd, __u16 nvmsetid, return nvme_identify(fd, NVME_IDENTIFY_CNS_NVMSET_LIST, NVME_NSID_NONE, NVME_CNTLID_NONE, nvmsetid, NVME_DOMID_NONE, NVME_UUID_NONE, NVME_CSI_NVM, - nvmset, NVME_DEFAULT_IOCTL_TIMEOUT); + nvmset, NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_identify_primary_ctrl(int fd, __u16 cntid, @@ -466,7 +466,7 @@ int nvme_identify_primary_ctrl(int fd, __u16 cntid, return nvme_identify(fd, NVME_IDENTIFY_CNS_PRIMARY_CTRL_CAP, NVME_NSID_NONE, cntid, NVME_NVMSETID_NONE, NVME_DOMID_NONE, NVME_UUID_NONE, NVME_CSI_NVM, - cap, NVME_DEFAULT_IOCTL_TIMEOUT); + cap, NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_identify_secondary_ctrl_list(int fd, __u32 nsid, __u16 cntid, @@ -476,7 +476,7 @@ int nvme_identify_secondary_ctrl_list(int fd, __u32 nsid, __u16 cntid, return nvme_identify(fd, NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST, nsid, cntid, NVME_NVMSETID_NONE, NVME_DOMID_NONE, NVME_UUID_NONE, NVME_CSI_NVM, - list, NVME_DEFAULT_IOCTL_TIMEOUT); + list, NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_identify_ns_granularity(int fd, @@ -499,7 +499,7 @@ int nvme_identify_ctrl_csi(int fd, __u8 csi, void *data) return nvme_identify(fd, NVME_IDENTIFY_CNS_CSI_CTRL, NVME_NSID_NONE, NVME_CNTLID_NONE, NVME_NVMSETID_NONE, NVME_DOMID_NONE, NVME_UUID_NONE, csi, data, - NVME_DEFAULT_IOCTL_TIMEOUT); + NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_identify_ns_csi(int fd, __u32 nsid, __u8 csi, void *data) @@ -507,7 +507,7 @@ int nvme_identify_ns_csi(int fd, __u32 nsid, __u8 csi, void *data) return nvme_identify(fd, NVME_IDENTIFY_CNS_CSI_NS, nsid, NVME_CNTLID_NONE, NVME_NVMSETID_NONE, NVME_DOMID_NONE, NVME_UUID_NONE, csi, data, - NVME_DEFAULT_IOCTL_TIMEOUT); + NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_identify_active_ns_list_csi(int fd, __u32 nsid, __u8 csi, @@ -517,7 +517,7 @@ int nvme_identify_active_ns_list_csi(int fd, __u32 nsid, __u8 csi, return nvme_identify(fd, NVME_IDENTIFY_CNS_CSI_NS_ACTIVE_LIST, nsid, NVME_CNTLID_NONE, NVME_NVMSETID_NONE, NVME_DOMID_NONE, NVME_UUID_NONE, csi, list, - NVME_DEFAULT_IOCTL_TIMEOUT); + NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_identify_allocated_ns_list_css(int fd, __u32 nsid, __u8 csi, @@ -526,7 +526,7 @@ int nvme_identify_allocated_ns_list_css(int fd, __u32 nsid, __u8 csi, return nvme_identify(fd, NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST, nsid, NVME_CNTLID_NONE, NVME_NVMSETID_NONE, NVME_DOMID_NONE, NVME_UUID_NONE, csi, list, - NVME_DEFAULT_IOCTL_TIMEOUT); + NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_identify_domain_list(int fd, __u16 domid, @@ -536,7 +536,7 @@ int nvme_identify_domain_list(int fd, __u16 domid, return nvme_identify(fd, NVME_IDENTIFY_CNS_DOMAIN_LIST, NVME_NSID_NONE, NVME_CNTLID_NONE, NVME_NVMSETID_NONE, domid, NVME_UUID_NONE, NVME_CSI_NVM, list, - NVME_DEFAULT_IOCTL_TIMEOUT); + NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_identify_endurance_group_list(int fd, __u16 endgrp_id, @@ -546,7 +546,8 @@ int nvme_identify_endurance_group_list(int fd, __u16 endgrp_id, return nvme_identify(fd, NVME_IDENTIFY_CNS_ENDURANCE_GROUP_ID, NVME_NSID_NONE, NVME_CNTLID_NONE, NVME_NVMSETID_NONE, endgrp_id, NVME_UUID_NONE, - NVME_CSI_NVM, list, NVME_DEFAULT_IOCTL_TIMEOUT); + NVME_CSI_NVM, list, NVME_DEFAULT_IOCTL_TIMEOUT, + NULL); } int nvme_identify_independent_identify_ns(int fd, __u32 nsid, @@ -556,7 +557,7 @@ int nvme_identify_independent_identify_ns(int fd, __u32 nsid, return nvme_identify(fd, NVME_IDENTIFY_CNS_CSI_INDEPENDENT_ID_NS, nsid, NVME_CNTLID_NONE, NVME_NVMSETID_NONE, NVME_DOMID_NONE, NVME_UUID_NONE, NVME_CSI_NVM, - ns, NVME_DEFAULT_IOCTL_TIMEOUT); + ns, NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_identify_iocs(int fd, __u16 cntlid, struct nvme_id_iocs *iocs) @@ -565,7 +566,7 @@ int nvme_identify_iocs(int fd, __u16 cntlid, struct nvme_id_iocs *iocs) return nvme_identify(fd, NVME_IDENTIFY_CNS_COMMAND_SET_STRUCTURE, NVME_NSID_NONE, cntlid, NVME_NVMSETID_NONE, NVME_DOMID_NONE, NVME_UUID_NONE, NVME_CSI_NVM, - iocs, NVME_DEFAULT_IOCTL_TIMEOUT); + iocs, NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_zns_identify_ns(int fd, __u32 nsid, struct nvme_zns_id_ns *data) @@ -574,7 +575,7 @@ int nvme_zns_identify_ns(int fd, __u32 nsid, struct nvme_zns_id_ns *data) return nvme_identify(fd, NVME_IDENTIFY_CNS_CSI_NS, nsid, NVME_CNTLID_NONE, NVME_NVMSETID_NONE, NVME_DOMID_NONE, NVME_UUID_NONE, NVME_CSI_ZNS, - data, NVME_DEFAULT_IOCTL_TIMEOUT); + data, NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_zns_identify_ctrl(int fd, struct nvme_zns_id_ctrl *id) @@ -591,7 +592,7 @@ int nvme_nvm_identify_ctrl(int fd, struct nvme_id_ctrl_nvm *id) int nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, __u8 lsp, __u16 lsi, bool rae, __u8 uuidx, enum nvme_csi csi, - __u32 len, void *log, __u32 timeout) + __u32 len, void *log, __u32 timeout, __u32 *result) { __u32 numd = (len >> 2) - 1; __u16 numdu = numd >> 16, numdl = numd & 0xffff; @@ -620,7 +621,7 @@ int nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, .timeout_ms = timeout, }; - return nvme_submit_admin_passthru(fd, &cmd, NULL); + return nvme_submit_admin_passthru(fd, &cmd, result); } static int __nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, bool rae, @@ -628,7 +629,8 @@ static int __nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, bool rae, { return nvme_get_log(fd, lid, NVME_NSID_ALL, 0, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, - NVME_CSI_NVM, len, log, NVME_DEFAULT_IOCTL_TIMEOUT); + NVME_CSI_NVM, len, log, NVME_DEFAULT_IOCTL_TIMEOUT, + NULL); } int nvme_get_log_supported_log_pages(int fd, bool rae, @@ -653,7 +655,7 @@ int nvme_get_log_smart(int fd, __u32 nsid, bool rae, struct nvme_smart_log *log) return nvme_get_log(fd, NVME_LOG_LID_SMART, nsid, 0, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, NVME_CSI_NVM, sizeof(*log), log, - NVME_DEFAULT_IOCTL_TIMEOUT); + NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_get_log_fw_slot(int fd, bool rae, struct nvme_firmware_slot *log) @@ -676,7 +678,7 @@ int nvme_get_log_cmd_effects(int fd, enum nvme_csi csi, return nvme_get_log(fd, NVME_LOG_LID_CMD_EFFECTS, NVME_NSID_ALL, 0, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, NVME_UUID_NONE, csi, false, sizeof(*log), - log, NVME_DEFAULT_IOCTL_TIMEOUT); + log, NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_get_log_device_self_test(int fd, struct nvme_self_test_log *log) @@ -697,7 +699,7 @@ int nvme_get_log_create_telemetry_host(int fd, struct nvme_telemetry_log *log) return nvme_get_log(fd, NVME_LOG_LID_TELEMETRY_HOST, NVME_NSID_NONE, 0, NVME_LOG_TELEM_HOST_LSP_CREATE, NVME_LOG_LSI_NONE, false, NVME_UUID_NONE, NVME_CSI_NVM, sizeof(*log), - log, NVME_DEFAULT_IOCTL_TIMEOUT); + log, NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_get_log_telemetry_host(int fd, __u64 offset, __u32 len, void *log) @@ -705,7 +707,8 @@ int nvme_get_log_telemetry_host(int fd, __u64 offset, __u32 len, void *log) return nvme_get_log(fd, NVME_LOG_LID_TELEMETRY_HOST, NVME_NSID_NONE, offset, NVME_LOG_TELEM_HOST_LSP_RETAIN, NVME_LOG_LSI_NONE, false, NVME_UUID_NONE, - NVME_CSI_NVM, len, log, NVME_DEFAULT_IOCTL_TIMEOUT); + NVME_CSI_NVM, len, log, NVME_DEFAULT_IOCTL_TIMEOUT, + NULL); } int nvme_get_log_telemetry_ctrl(int fd, bool rae, __u64 offset, __u32 len, @@ -714,7 +717,7 @@ int nvme_get_log_telemetry_ctrl(int fd, bool rae, __u64 offset, __u32 len, return nvme_get_log(fd, NVME_LOG_LID_TELEMETRY_CTRL, NVME_NSID_NONE, offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, NVME_CSI_NVM, len, log, - NVME_DEFAULT_IOCTL_TIMEOUT); + NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_get_log_endurance_group(int fd, __u16 endgid, @@ -724,7 +727,7 @@ int nvme_get_log_endurance_group(int fd, __u16 endgid, return nvme_get_log(fd, NVME_LOG_LID_ENDURANCE_GROUP, NVME_NSID_NONE, 0, NVME_LOG_LSP_NONE, endgid, false, NVME_UUID_NONE, NVME_CSI_NVM, sizeof(*log), log, - NVME_DEFAULT_IOCTL_TIMEOUT); + NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_get_log_predictable_lat_nvmset(int fd, __u16 nvmsetid, @@ -734,24 +737,26 @@ int nvme_get_log_predictable_lat_nvmset(int fd, __u16 nvmsetid, return nvme_get_log(fd, NVME_LOG_LID_PREDICTABLE_LAT_NVMSET, NVME_NSID_NONE, 0, NVME_LOG_LSP_NONE, nvmsetid, false, NVME_UUID_NONE, NVME_CSI_NVM, sizeof(*log), - log, NVME_DEFAULT_IOCTL_TIMEOUT); + log, NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_get_log_predictable_lat_event(int fd, bool rae, __u32 offset, __u32 len, void *log) { return nvme_get_log(fd, NVME_LOG_LID_PREDICTABLE_LAT_AGG, - NVME_NSID_NONE, offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, - rae, NVME_UUID_NONE, NVME_CSI_NVM, len, log, - NVME_DEFAULT_IOCTL_TIMEOUT); + NVME_NSID_NONE, offset, NVME_LOG_LSP_NONE, + NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, + NVME_CSI_NVM, len, log, + NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_get_log_ana(int fd, enum nvme_log_ana_lsp lsp, bool rae, __u64 offset, __u32 len, void *log) { return nvme_get_log(fd, NVME_LOG_LID_ANA, NVME_NSID_NONE, offset, - lsp,NVME_LOG_LSI_NONE, false, NVME_UUID_NONE, - NVME_CSI_NVM, len, log, NVME_DEFAULT_IOCTL_TIMEOUT); + lsp, NVME_LOG_LSI_NONE, false, NVME_UUID_NONE, + NVME_CSI_NVM, len, log, NVME_DEFAULT_IOCTL_TIMEOUT, + NULL); } int nvme_get_log_ana_groups(int fd, bool rae, __u32 len, @@ -767,7 +772,7 @@ int nvme_get_log_lba_status(int fd, bool rae, __u64 offset, __u32 len, return nvme_get_log(fd, NVME_LOG_LID_LBA_STATUS, NVME_NSID_NONE, offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, NVME_CSI_NVM, len, log, - NVME_DEFAULT_IOCTL_TIMEOUT); + NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_get_log_endurance_grp_evt(int fd, bool rae, __u32 offset, __u32 len, @@ -776,7 +781,8 @@ int nvme_get_log_endurance_grp_evt(int fd, bool rae, __u32 offset, __u32 len, return nvme_get_log(fd, NVME_LOG_LID_ENDURANCE_GRP_EVT, NVME_NSID_NONE, offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, - NVME_CSI_NVM, len, log, NVME_DEFAULT_IOCTL_TIMEOUT); + NVME_CSI_NVM, len, log, NVME_DEFAULT_IOCTL_TIMEOUT, + NULL); } int nvme_get_log_fid_supported_effects(int fd, bool rae, @@ -787,7 +793,7 @@ int nvme_get_log_fid_supported_effects(int fd, bool rae, NVME_NSID_NONE, 0, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, NVME_CSI_NVM, sizeof(*log), log, - NVME_DEFAULT_IOCTL_TIMEOUT); + NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_get_log_boot_partition(int fd, bool rae, __u8 lsp, __u32 len, @@ -798,7 +804,7 @@ int nvme_get_log_boot_partition(int fd, bool rae, __u8 lsp, __u32 len, NVME_NSID_NONE, 0, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, NVME_CSI_NVM, len, part, - NVME_DEFAULT_IOCTL_TIMEOUT); + NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } @@ -807,7 +813,7 @@ int nvme_get_log_discovery(int fd, bool rae, __u32 offset, __u32 len, void *log) return nvme_get_log(fd, NVME_LOG_LID_DISCOVER, NVME_NSID_NONE, offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, NVME_CSI_NVM, len, log, - NVME_DEFAULT_IOCTL_TIMEOUT); + NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_get_log_reservation(int fd, bool rae, @@ -840,7 +846,7 @@ int nvme_get_log_zns_changed_zones(int fd, __u32 nsid, bool rae, return nvme_get_log(fd, NVME_LOG_LID_ZNS_CHANGED_ZONES, nsid, 0, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, NVME_CSI_ZNS, sizeof(*log), log, - NVME_DEFAULT_IOCTL_TIMEOUT); + NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_set_features(int fd, __u8 fid, __u32 nsid, __u32 cdw11, __u32 cdw12, @@ -1347,7 +1353,7 @@ int nvme_get_features_iocs_profile(int fd, enum nvme_get_features_sel sel, int nvme_format_nvm(int fd, __u32 nsid, __u8 lbaf, enum nvme_cmd_format_mset mset, enum nvme_cmd_format_pi pi, enum nvme_cmd_format_pil pil, enum nvme_cmd_format_ses ses, - __u32 timeout) + __u32 timeout, __u32 *result) { __u32 cdw10 = NVME_SET(lbaf, FORMAT_CDW10_LBAF) | NVME_SET(mset, FORMAT_CDW10_MSET) | @@ -1362,7 +1368,7 @@ int nvme_format_nvm(int fd, __u32 nsid, __u8 lbaf, .timeout_ms = timeout, }; - return nvme_submit_admin_passthru(fd, &cmd, NULL); + return nvme_submit_admin_passthru(fd, &cmd, result); } int nvme_ns_mgmt(int fd, __u32 nsid, enum nvme_ns_mgmt_sel sel, @@ -1428,7 +1434,7 @@ int nvme_ns_detach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist) } int nvme_fw_download(int fd, __u32 offset, __u32 data_len, void *data, - __u32 timeout) + __u32 timeout, __u32 *result) { __u32 cdw10 = (data_len >> 2) - 1; __u32 cdw11 = offset >> 2; @@ -1442,7 +1448,7 @@ int nvme_fw_download(int fd, __u32 offset, __u32 data_len, void *data, .timeout_ms = timeout, }; - return nvme_submit_admin_passthru(fd, &cmd, NULL); + return nvme_submit_admin_passthru(fd, &cmd, result); } int nvme_fw_commit(int fd, __u8 slot, enum nvme_fw_commit_ca action, bool bpid, @@ -1508,7 +1514,7 @@ int nvme_security_receive(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, int nvme_get_lba_status(int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl, enum nvme_lba_status_atype atype, __u32 timeout, - struct nvme_lba_status *lbas) + struct nvme_lba_status *lbas, __u32 *result) { __u32 cdw10 = slba & 0xffffffff; __u32 cdw11 = slba >> 32; @@ -1527,7 +1533,7 @@ int nvme_get_lba_status(int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl, .timeout_ms = timeout, }; - return nvme_submit_admin_passthru(fd, &cmd, NULL); + return nvme_submit_admin_passthru(fd, &cmd, result); } int nvme_directive_send(int fd, __u32 nsid, __u16 dspec, @@ -1690,7 +1696,8 @@ int nvme_lockdown(int fd, __u8 scp, __u8 prhbt, __u8 ifc, __u8 ofi, return nvme_submit_admin_passthru(fd, &cmd, NULL); } -int nvme_set_property(int fd, int offset, __u64 value, __u32 timeout) +int nvme_set_property(int fd, int offset, __u64 value, + __u32 timeout, __u32 *result) { __u32 cdw10 = nvme_is_64bit_reg(offset); @@ -1704,7 +1711,7 @@ int nvme_set_property(int fd, int offset, __u64 value, __u32 timeout) .timeout_ms = timeout, }; - return nvme_submit_admin_passthru(fd, &cmd, NULL); + return nvme_submit_admin_passthru(fd, &cmd, result); } int nvme_get_property(int fd, int offset, __u64 *value, __u32 timeout) @@ -1724,7 +1731,7 @@ int nvme_get_property(int fd, int offset, __u64 *value, __u32 timeout) int nvme_sanitize_nvm(int fd, enum nvme_sanitize_sanact sanact, bool ause, __u8 owpass, bool oipbp, bool nodas, __u32 ovrpat, - __u32 timeout) + __u32 timeout, __u32 *result) { __u32 cdw10 = NVME_SET(sanact, SANITIZE_CDW10_SANACT) | NVME_SET(!!ause, SANITIZE_CDW10_AUSE) | @@ -1740,7 +1747,7 @@ int nvme_sanitize_nvm(int fd, enum nvme_sanitize_sanact sanact, bool ause, .timeout_ms = timeout, }; - return nvme_submit_admin_passthru(fd, &cmd, NULL); + return nvme_submit_admin_passthru(fd, &cmd, result); } int nvme_dev_self_test(int fd, __u32 nsid, enum nvme_dst_stc stc) @@ -1908,7 +1915,7 @@ int nvme_write_uncorrectable(int fd, __u32 nsid, __u64 slba, __u16 nlb, } int nvme_dsm(int fd, __u32 nsid, __u32 attrs, __u16 nr_ranges, - struct nvme_dsm_range *dsm, __u32 timeout) + struct nvme_dsm_range *dsm, __u32 timeout, __u32 *result) { __u32 cdw11 = attrs; @@ -1922,13 +1929,13 @@ int nvme_dsm(int fd, __u32 nsid, __u32 attrs, __u16 nr_ranges, .timeout_ms = timeout, }; - return nvme_submit_io_passthru(fd, &cmd, NULL); + return nvme_submit_io_passthru(fd, &cmd, result); } int nvme_copy(int fd, __u32 nsid, struct nvme_copy_range *copy, __u64 sdlba, __u16 nr, __u8 prinfor, __u8 prinfow, __u8 dtype, __u16 dspec, __u8 format, int lr, int fua, __u32 ilbrt, __u16 lbatm, - __u16 lbat, __u32 timeout) + __u16 lbat, __u32 timeout, __u32 *result) { __u32 cdw12 = ((nr - 1) & 0xff) | ((format & 0xf) << 8) | ((prinfor & 0xf) << 12) | ((dtype & 0xf) << 20) | @@ -1949,12 +1956,12 @@ int nvme_copy(int fd, __u32 nsid, struct nvme_copy_range *copy, __u64 sdlba, .timeout_ms = timeout, }; - return nvme_submit_io_passthru(fd, &cmd, NULL); + return nvme_submit_io_passthru(fd, &cmd, result); } int nvme_resv_acquire(int fd, __u32 nsid, enum nvme_resv_rtype rtype, enum nvme_resv_racqa racqa, bool iekey, - __u64 crkey, __u64 nrkey, __u32 timeout) + __u64 crkey, __u64 nrkey, __u32 timeout, __u32 *result) { __le64 payload[2] = { cpu_to_le64(crkey), cpu_to_le64(nrkey) }; __u32 cdw10 = (racqa & 0x7) | (iekey ? 1 << 3 : 0) | rtype << 8; @@ -1968,12 +1975,12 @@ int nvme_resv_acquire(int fd, __u32 nsid, enum nvme_resv_rtype rtype, .timeout_ms = timeout, }; - return nvme_submit_io_passthru(fd, &cmd, NULL); + return nvme_submit_io_passthru(fd, &cmd, result); } int nvme_resv_register(int fd, __u32 nsid, enum nvme_resv_rrega rrega, enum nvme_resv_cptpl cptpl, bool iekey, - __u64 crkey, __u64 nrkey, __u32 timeout) + __u64 crkey, __u64 nrkey, __u32 timeout, __u32 *result) { __le64 payload[2] = { cpu_to_le64(crkey), cpu_to_le64(nrkey) }; __u32 cdw10 = (rrega & 0x7) | (iekey ? 1 << 3 : 0) | cptpl << 30; @@ -1987,12 +1994,12 @@ int nvme_resv_register(int fd, __u32 nsid, enum nvme_resv_rrega rrega, .timeout_ms = timeout, }; - return nvme_submit_io_passthru(fd, &cmd, NULL); + return nvme_submit_io_passthru(fd, &cmd, result); } int nvme_resv_release(int fd, __u32 nsid, enum nvme_resv_rtype rtype, enum nvme_resv_rrela rrela, bool iekey, - __u64 crkey, __u32 timeout) + __u64 crkey, __u32 timeout, __u32 *result) { __le64 payload[1] = { cpu_to_le64(crkey) }; __u32 cdw10 = (rrela & 0x7) | (iekey ? 1 << 3 : 0) | rtype << 8; @@ -2006,11 +2013,12 @@ int nvme_resv_release(int fd, __u32 nsid, enum nvme_resv_rtype rtype, .timeout_ms = timeout, }; - return nvme_submit_io_passthru(fd, &cmd, NULL); + return nvme_submit_io_passthru(fd, &cmd, result); } int nvme_resv_report(int fd, __u32 nsid, bool eds, __u32 len, - struct nvme_resv_status *report, __u32 timeout) + struct nvme_resv_status *report, __u32 timeout, + __u32 *result) { struct nvme_passthru_cmd cmd = { .opcode = nvme_cmd_resv_report, @@ -2022,12 +2030,12 @@ int nvme_resv_report(int fd, __u32 nsid, bool eds, __u32 len, .timeout_ms = timeout, }; - return nvme_submit_io_passthru(fd, &cmd, NULL); + return nvme_submit_io_passthru(fd, &cmd, result); } int nvme_zns_mgmt_send(int fd, __u32 nsid, __u64 slba, bool select_all, __u32 timeout, enum nvme_zns_send_action zsa, - __u32 data_len, void *data) + __u32 data_len, void *data, __u32 *result) { __u32 cdw10 = slba & 0xffffffff; __u32 cdw11 = slba >> 32; @@ -2045,12 +2053,13 @@ int nvme_zns_mgmt_send(int fd, __u32 nsid, __u64 slba, bool select_all, .timeout_ms = timeout, }; - return nvme_submit_io_passthru(fd, &cmd, NULL); + return nvme_submit_io_passthru(fd, &cmd, result); } int nvme_zns_mgmt_recv(int fd, __u32 nsid, __u64 slba, __u32 timeout, enum nvme_zns_recv_action zra, __u16 zrasf, - bool zras_feat, __u32 data_len, void *data) + bool zras_feat, __u32 data_len, void *data, + __u32 *result) { __u32 cdw10 = slba & 0xffffffff; __u32 cdw11 = slba >> 32; @@ -2071,12 +2080,13 @@ int nvme_zns_mgmt_recv(int fd, __u32 nsid, __u64 slba, __u32 timeout, .timeout_ms = timeout, }; - return nvme_submit_io_passthru(fd, &cmd, NULL); + return nvme_submit_io_passthru(fd, &cmd, result); } int nvme_zns_report_zones(int fd, __u32 nsid, __u64 slba, __u32 timeout, bool extended, enum nvme_zns_report_options opts, - bool partial, __u32 data_len, void *data) + bool partial, __u32 data_len, void *data, + __u32 *result) { BUILD_ASSERT(sizeof(struct nvme_zns_desc) == 64); enum nvme_zns_recv_action zra; @@ -2087,7 +2097,7 @@ int nvme_zns_report_zones(int fd, __u32 nsid, __u64 slba, __u32 timeout, zra = NVME_ZNS_ZRA_REPORT_ZONES; return nvme_zns_mgmt_recv(fd, nsid, slba, timeout, zra, opts, partial, - data_len, data); + data_len, data, result); } int nvme_zns_append(int fd, __u32 nsid, __u64 zslba, __u16 nlb, __u16 control, diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index f524756c79..f045187dea 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -385,6 +385,7 @@ int nvme_get_nsid(int fd, __u32 *nsid); * @csi: Command Set Identifier * @data: User space destination address to transfer the data * @timeout: Timeout in ms (0 for default timeout) + * @result: The command completion result from CQE dword0 * * The Identify command returns a data buffer that describes information about * the NVM subsystem, the controller or the namespace(s). @@ -394,7 +395,8 @@ int nvme_get_nsid(int fd, __u32 *nsid); */ int nvme_identify(int fd, enum nvme_identify_cns cns, __u32 nsid, __u16 cntid, __u16 nvmsetid, __u16 domid, - __u8 uuidx, __u8 csi, void *data, __u32 timeout); + __u8 uuidx, __u8 csi, void *data, __u32 timeout, + __u32 *result); /** * nvme_identify_ctrl() - Retrieves nvme identify controller @@ -789,19 +791,20 @@ int nvme_zns_identify_ctrl(int fd, struct nvme_zns_id_ctrl *id); * @len: Length of provided user buffer to hold the log data in bytes * @log: User space destination address to transfer the data * @timeout: Timeout in ms + * @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. */ int nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, __u8 lsp, __u16 lsi, bool rae, __u8 uuidx, enum nvme_csi csi, - __u32 len, void *log, __u32 timeout); + __u32 len, void *log, __u32 timeout, __u32 *result); static inline int nvme_get_nsid_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u32 len, void *log) { return nvme_get_log(fd, lid, nsid, 0, 0, 0, false, 0, NVME_CSI_NVM, len, - log, NVME_DEFAULT_IOCTL_TIMEOUT); + log, NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } static inline int nvme_get_log_simple(int fd, enum nvme_cmd_get_log_lid lid, @@ -1892,6 +1895,7 @@ int nvme_get_features_iocs_profile(int fd, enum nvme_get_features_sel sel, * @ses: Secure erase settings * @timeout: Set to override default timeout to this value in milliseconds; * useful for long running formats. 0 will use system default. + * @result: The command completion result from CQE dword0 * * The Format NVM command low level formats the NVM media. This command is used * by the host to change the LBA data size and/or metadata size. A low level @@ -1906,7 +1910,7 @@ int nvme_format_nvm(int fd, __u32 nsid, __u8 lbaf, enum nvme_cmd_format_pi pi, enum nvme_cmd_format_pil pil, enum nvme_cmd_format_ses ses, - __u32 timeout); + __u32 timeout, __u32 *result); /** * nvme_ns_mgmt() - @@ -1989,6 +1993,7 @@ int nvme_ns_detach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist); * @data_len: Length of data in this command in bytes * @data: Userspace address of the firmware data * @timeout: Timeout in ms + * @result: The command completion result from CQE dword0 * * The Firmware Image Download command downloads all or a portion of an image * for a future update to the controller. The Firmware Image Download command @@ -2007,7 +2012,7 @@ int nvme_ns_detach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist); * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_fw_download(int fd, __u32 offset, __u32 data_len, void *data, - __u32 timeout); + __u32 timeout, __u32 *result); /** * nvme_fw_commit() - Commit firmware using the specified action @@ -2090,6 +2095,7 @@ int nvme_security_receive(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, * @rl: Range length from slba to perform the action * @timeout: Timeout in ms * @lbas: Data payload to return status descriptors + * @result: The command completion result from CQE dword0 * * The Get LBA Status command requests information about Potentially * Unrecoverable LBAs. Refer to the specification for action type descriptions. @@ -2099,7 +2105,7 @@ int nvme_security_receive(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, */ int nvme_get_lba_status(int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl, enum nvme_lba_status_atype atype, __u32 timeout, - struct nvme_lba_status *lbas); + struct nvme_lba_status *lbas, __u32 *result); /** * nvme_directive_send() - Send directive command @@ -2268,6 +2274,7 @@ int nvme_lockdown(int fd, __u8 scp, __u8 prhbt, __u8 ifc, __u8 ofi, * @offset: Property offset from the base to set * @value: The value to set the property * @timeout: Timeout in ms + * @result: The command completion result from CQE dword0 * * This is an NVMe-over-Fabrics specific command, not applicable to PCIe. These * properties align to the PCI MMIO controller registers. @@ -2275,7 +2282,8 @@ int nvme_lockdown(int fd, __u8 scp, __u8 prhbt, __u8 ifc, __u8 ofi, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_set_property(int fd, int offset, __u64 value, __u32 timeout); +int nvme_set_property(int fd, int offset, __u64 value, + __u32 timeout, __u32 *result); /** * nvme_get_property() - Get a controller property @@ -2302,6 +2310,7 @@ int nvme_get_property(int fd, int offset, __u64 *value, __u32 timeout); * @nodas: Set to not deallocate blocks after sanitizing * @ovrpat: Overwrite pattern * @timeout: Timeout in ms + * @result: The command completion result from CQE dword0 * * A sanitize operation alters all user data in the NVM subsystem such that * recovery of any previous user data from any cache, the non-volatile media, @@ -2318,7 +2327,7 @@ int nvme_get_property(int fd, int offset, __u64 *value, __u32 timeout); */ int nvme_sanitize_nvm(int fd, enum nvme_sanitize_sanact sanact, bool ause, __u8 owpass, bool oipbp, bool nodas, __u32 ovrpat, - __u32 timeout); + __u32 timeout, __u32 *result); /** * nvme_dev_self_test() - Start or abort a self test @@ -2569,6 +2578,7 @@ int nvme_verify(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, * @nr_ranges: Number of block ranges in the data set management attributes * @dsm: The data set management attributes * @timeout: Timeout in ms + * @result: The command completion result from CQE dword0 * * The Dataset Management command is used by the host to indicate attributes * for ranges of logical blocks. This includes attributes like frequency that @@ -2580,7 +2590,7 @@ int nvme_verify(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_dsm(int fd, __u32 nsid, __u32 attrs, __u16 nr_ranges, - struct nvme_dsm_range *dsm, __u32 timeout); + struct nvme_dsm_range *dsm, __u32 timeout, __u32 *result); /** * nvme_copy() - @@ -2601,14 +2611,15 @@ int nvme_dsm(int fd, __u32 nsid, __u32 attrs, __u16 nr_ranges, * @lbatm: Logical block application tag mask * @lbat: Logical block application tag * @timeout: Timeout in ms + * @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. */ int nvme_copy(int fd, __u32 nsid, struct nvme_copy_range *copy, __u64 sdlba, - __u16 nr, __u8 prinfor, __u8 prinfow, __u8 dtype, __u16 dspec, - __u8 format, int lr, int fua, __u32 ilbrt, __u16 lbatm, - __u16 lbat, __u32 timeout); + __u16 nr, __u8 prinfor, __u8 prinfow, __u8 dtype, __u16 dspec, + __u8 format, int lr, int fua, __u32 ilbrt, __u16 lbatm, + __u16 lbat, __u32 timeout, __u32 *result); /** * nvme_resv_acquire() - Send an nvme reservation acquire @@ -2621,6 +2632,7 @@ int nvme_copy(int fd, __u32 nsid, struct nvme_copy_range *copy, __u64 sdlba, * @nrkey: The reservation key to be unregistered from the namespace if * the action is preempt * @timeout: Timeout in ms + * @result: The command completion result from CQE dword0 * * The Reservation Acquire command acquires a reservation on a namespace, * preempt a reservation held on a namespace, and abort a reservation held on a @@ -2631,7 +2643,7 @@ int nvme_copy(int fd, __u32 nsid, struct nvme_copy_range *copy, __u64 sdlba, */ int nvme_resv_acquire(int fd, __u32 nsid, enum nvme_resv_rtype rtype, enum nvme_resv_racqa racqa, bool iekey, - __u64 crkey, __u64 nrkey, __u32 timeout); + __u64 crkey, __u64 nrkey, __u32 timeout, __u32 *result); /** * nvme_resv_register() - Send an nvme reservation register @@ -2653,7 +2665,7 @@ int nvme_resv_acquire(int fd, __u32 nsid, enum nvme_resv_rtype rtype, */ int nvme_resv_register(int fd, __u32 nsid, enum nvme_resv_rrega rrega, enum nvme_resv_cptpl cptpl, bool iekey, - __u64 crkey, __u64 nrkey, __u32 timeout); + __u64 crkey, __u64 nrkey, __u32 timeout, __u32 *result); /** * nvme_resv_release() - Send an nvme reservation release @@ -2664,13 +2676,14 @@ int nvme_resv_register(int fd, __u32 nsid, enum nvme_resv_rrega rrega, * @iekey: Set to ignore the existing key * @crkey: The current reservation key to release * @timeout: Timeout in ms + * @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. */ int nvme_resv_release(int fd, __u32 nsid, enum nvme_resv_rtype rtype, enum nvme_resv_rrela rrela, bool iekey, - __u64 crkey, __u32 timeout); + __u64 crkey, __u32 timeout, __u32 *result); /** * nvme_resv_report() - Send an nvme reservation report @@ -2681,6 +2694,7 @@ int nvme_resv_release(int fd, __u32 nsid, enum nvme_resv_rtype rtype, * @report: The user space destination address to store the reservation * report * @timeout: Timeout in ms + * @result: The command completion result from CQE dword0 * * Returns a Reservation Status data structure to memory that describes the * registration and reservation status of a namespace. See the defintion for @@ -2690,7 +2704,8 @@ int nvme_resv_release(int fd, __u32 nsid, enum nvme_resv_rtype rtype, * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_resv_report(int fd, __u32 nsid, bool eds, __u32 len, - struct nvme_resv_status *report, __u32 timeout); + struct nvme_resv_status *report, + __u32 timeout, __u32 *result); /** * nvme_zns_mgmt_send() - @@ -2702,13 +2717,14 @@ int nvme_resv_report(int fd, __u32 nsid, bool eds, __u32 len, * @zsa: * @data_len: * @data: + * @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. */ int nvme_zns_mgmt_send(int fd, __u32 nsid, __u64 slba, bool select_all, __u32 timeout, enum nvme_zns_send_action zsa, - __u32 data_len, void *data); + __u32 data_len, void *data, __u32 *result); /** @@ -2722,13 +2738,15 @@ int nvme_zns_mgmt_send(int fd, __u32 nsid, __u64 slba, bool select_all, * @zras_feat: * @data_len: * @data: + * @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. */ int nvme_zns_mgmt_recv(int fd, __u32 nsid, __u64 slba, __u32 timeout, enum nvme_zns_recv_action zra, __u16 zrasf, - bool zras_feat, __u32 data_len, void *data); + bool zras_feat, __u32 data_len, void *data, + __u32 *result); /** * nvme_zns_report_zones() - Return the list of zones @@ -2741,13 +2759,15 @@ int nvme_zns_mgmt_recv(int fd, __u32 nsid, __u64 slba, __u32 timeout, * @partial: Partial report requested * @data_len: Length of the data buffer * @data: Data buffer + * @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. */ int nvme_zns_report_zones(int fd, __u32 nsid, __u64 slba, __u32 timeout, bool extended, enum nvme_zns_report_options opts, - bool partial, __u32 data_len, void *data); + bool partial, __u32 data_len, void *data, + __u32 *result); /** * nvme_zns_append() - diff --git a/src/nvme/linux.c b/src/nvme/linux.c index 9b26eb969a..47de1a01a8 100644 --- a/src/nvme/linux.c +++ b/src/nvme/linux.c @@ -85,7 +85,7 @@ int nvme_fw_download_seq(int fd, __u32 size, __u32 xfer, __u32 offset, while (size > 0) { xfer = MIN(xfer, size); err = nvme_fw_download(fd, offset, xfer, buf, - NVME_DEFAULT_IOCTL_TIMEOUT); + NVME_DEFAULT_IOCTL_TIMEOUT, NULL); if (err) break; @@ -125,7 +125,7 @@ int __nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, ret = nvme_get_log(fd, log_id, nsid, offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, retain, NVME_UUID_NONE, NVME_CSI_NVM, xfer, ptr, - NVME_DEFAULT_IOCTL_TIMEOUT); + NVME_DEFAULT_IOCTL_TIMEOUT, NULL); if (ret) return ret; diff --git a/test/zns.c b/test/zns.c index 95cb006840..ed992585ec 100644 --- a/test/zns.c +++ b/test/zns.c @@ -23,6 +23,7 @@ static void show_zns_properties(nvme_ns_t n) struct nvme_zns_id_ns zns_ns; struct nvme_zns_id_ctrl zns_ctrl; struct nvme_zone_report *zr; + __u32 result; zr = calloc(1, 0x1000); if (!zr) @@ -48,8 +49,9 @@ static void show_zns_properties(nvme_ns_t n) NVME_DEFAULT_IOCTL_TIMEOUT, NVME_ZNS_ZRA_REPORT_ZONES, NVME_ZNS_ZRAS_REPORT_ALL, - 0, 0x1000, (void *)zr)) { - fprintf(stderr, "failed to report zones\n");; + 0, 0x1000, (void *)zr, &result)) { + fprintf(stderr, "failed to report zones, result %x\n", + le32_to_cpu(result)); return; } From a38fd199c542defa2a97707860807673419abb5a Mon Sep 17 00:00:00 2001 From: Minwoo Im Date: Thu, 18 Nov 2021 22:09:05 +0900 Subject: [PATCH 0278/1564] tree: rename namespace function name chrdev to generic The attribute in `struct nvme_ns` is `generic_name`, not chrdev. So rename the function name of this attribute. Signed-off-by: Minwoo Im --- src/nvme/tree.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index adef39415e..4ecb8af445 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -1577,7 +1577,7 @@ static int nvme_ns_init(struct nvme_ns *n) return 0; } -static void nvme_ns_set_chrdev_name(struct nvme_ns *n, const char *name) +static void nvme_ns_set_generic_name(struct nvme_ns *n, const char *name) { char generic_name[PATH_MAX]; int instance, head_instance; @@ -1606,7 +1606,7 @@ static nvme_ns_t nvme_ns_open(const char *name) if (n->fd < 0) goto free_ns; - nvme_ns_set_chrdev_name(n, name); + nvme_ns_set_generic_name(n, name); if (nvme_get_nsid(n->fd, &n->nsid) < 0) goto close_fd; From 0ae08e1075bb66693e2f4427d176316e42daccd4 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 18 Nov 2021 14:22:04 +0100 Subject: [PATCH 0279/1564] log: fixup SPDX license --- src/nvme/log.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nvme/log.h b/src/nvme/log.h index c13def854e..5848764e47 100644 --- a/src/nvme/log.h +++ b/src/nvme/log.h @@ -1,6 +1,6 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later /* * Copyright (c) 2021 Martin Wilck, SUSE LLC - * SPDX-License-Identifier: LGPL-2.1-or-newer */ #ifndef _LOG_H #define _LOG_H From b547cdb6f37e98255412356cadde69cfd55b0c10 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 11 Aug 2021 08:04:38 +0200 Subject: [PATCH 0280/1564] Implement 'dhchap_key' host and controller attributes Implement a 'dhchap_key' attribute for the nvme_host structure to support the 'dhchap_secret' connection argument, and a 'dhchap_key' attribute for the nvme_controller structure to support the 'dhchap_ctrl_secret' connection argument. Signed-off-by: Hannes Reinecke --- libnvme/nvme.i | 2 ++ src/libnvme.map | 4 ++++ src/nvme/fabrics.c | 8 +++++++- src/nvme/json.c | 16 +++++++++++++++- src/nvme/private.h | 2 ++ src/nvme/tree.c | 43 +++++++++++++++++++++++++++++++++++++++++++ src/nvme/tree.h | 30 ++++++++++++++++++++++++++++++ 7 files changed, 103 insertions(+), 2 deletions(-) diff --git a/libnvme/nvme.i b/libnvme/nvme.i index 0432d00714..04e8c3c307 100644 --- a/libnvme/nvme.i +++ b/libnvme/nvme.i @@ -268,6 +268,7 @@ struct nvme_host { %immutable hostid; char *hostnqn; char *hostid; + char *dhchap_key; }; struct nvme_subsystem { @@ -301,6 +302,7 @@ struct nvme_ctrl { char *traddr; char *host_traddr; char *trsvcid; + char *dhchap_key; char *address; char *firmware; char *model; diff --git a/src/libnvme.map b/src/libnvme.map index 0d8d45fbe6..c732757e49 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -13,6 +13,7 @@ LIBNVME_1_0 { nvme_ctrl_first_ns; nvme_ctrl_first_path; nvme_ctrl_get_address; + nvme_ctrl_get_dhchap_key; nvme_ctrl_get_discovery_ctrl; nvme_ctrl_get_fd; nvme_ctrl_get_firmware; @@ -36,6 +37,7 @@ LIBNVME_1_0 { nvme_ctrl_next_ns; nvme_ctrl_next_path; nvme_ctrl_reset; + nvme_ctrl_set_dhchap_key; nvme_ctrl_set_discovery_ctrl; nvme_ctrl_set_persistent; nvme_ctrls_filter; @@ -136,9 +138,11 @@ LIBNVME_1_0 { nvme_get_property; nvme_get_subsys_attr; nvme_get_telemetry_log; + nvme_host_get_dhchap_key; nvme_host_get_hostid; nvme_host_get_hostnqn; nvme_host_get_root; + nvme_host_set_dhchap_key; nvme_identify; nvme_identify_active_ns_list; nvme_identify_allocated_ns; diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index ddc6d6c7fb..686a5641aa 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -397,7 +397,7 @@ static int build_options(nvme_host_t h, nvme_ctrl_t c, char **argstr) { struct nvme_fabrics_config *cfg = nvme_ctrl_get_config(c); const char *transport = nvme_ctrl_get_transport(c); - const char *hostnqn, *hostid; + const char *hostnqn, *hostid, *hostkey, *ctrlkey; bool discover = false, discovery_nqn = false; if (!transport) { @@ -431,6 +431,8 @@ static int build_options(nvme_host_t h, nvme_ctrl_t c, char **argstr) discover = true; hostnqn = nvme_host_get_hostnqn(h); hostid = nvme_host_get_hostid(h); + hostkey = nvme_host_get_dhchap_key(h); + ctrlkey = nvme_ctrl_get_dhchap_key(c); if (add_argument(argstr, "transport", transport) || add_argument(argstr, "traddr", nvme_ctrl_get_traddr(c)) || @@ -444,6 +446,10 @@ static int build_options(nvme_host_t h, nvme_ctrl_t c, char **argstr) (hostid && add_argument(argstr, "hostid", hostid)) || (discover && !discovery_nqn && add_bool_argument(argstr, "discovery", true)) || + (!discover && hostkey && + add_argument(argstr, "dhchap_secret", hostkey)) || + (!discover && ctrlkey && + add_argument(argstr, "dhchap_ctrl_secret", ctrlkey)) || (!discover && add_int_argument(argstr, "nr_io_queues", cfg->nr_io_queues, false)) || diff --git a/src/nvme/json.c b/src/nvme/json.c index acf472c2e9..e93b7a30ae 100644 --- a/src/nvme/json.c +++ b/src/nvme/json.c @@ -97,6 +97,9 @@ static void json_parse_port(nvme_subsystem_t s, struct json_object *port_obj) c = nvme_lookup_ctrl(s, transport, traddr, host_traddr, host_iface, trsvcid); if (c) { + attr_obj = json_object_object_get(port_obj, "dhchap_key"); + if (attr_obj) + nvme_ctrl_set_dhchap_key(c, json_object_get_string(attr_obj)); json_update_attributes(c, port_obj); } } @@ -139,6 +142,9 @@ static void json_parse_host(nvme_root_t r, struct json_object *host_obj) if (attr_obj) hostid = json_object_get_string(attr_obj); h = nvme_lookup_host(r, hostnqn, hostid); + attr_obj = json_object_object_get(host_obj, "dhchap_key"); + if (attr_obj) + nvme_host_set_dhchap_key(h, json_object_get_string(attr_obj)); subsys_array = json_object_object_get(host_obj, "subsystems"); if (!subsys_array) return; @@ -194,6 +200,10 @@ static void json_update_port(struct json_object *ctrl_array, nvme_ctrl_t c) value = nvme_ctrl_get_trsvcid(c); if (value) json_object_add_value_string(port_obj, "trsvcid", value); + value = nvme_ctrl_get_dhchap_key(c); + if (value) + json_object_add_value_string(port_obj, "dhchap_key", + value); JSON_INT_OPTION(cfg, port_obj, nr_io_queues, 0); JSON_INT_OPTION(cfg, port_obj, nr_write_queues, 0); JSON_INT_OPTION(cfg, port_obj, nr_poll_queues, 0); @@ -252,7 +262,7 @@ int json_update_config(nvme_root_t r, const char *config_file) json_root = json_object_new_array(); nvme_for_each_host(r, h) { nvme_subsystem_t s; - const char *hostid; + const char *hostid, *dhchap_key; host_obj = json_object_new_object(); json_object_add_value_string(host_obj, "hostnqn", @@ -261,6 +271,10 @@ int json_update_config(nvme_root_t r, const char *config_file) if (hostid) json_object_add_value_string(host_obj, "hostid", hostid); + dhchap_key = nvme_host_get_dhchap_key(h); + if (dhchap_key) + json_object_add_value_string(host_obj, "dhchap_key", + dhchap_key); subsys_array = json_object_new_array(); nvme_for_each_subsystem(h, s) { json_update_subsys(subsys_array, s); diff --git a/src/nvme/private.h b/src/nvme/private.h index 33040a5470..d6abb3e9c9 100644 --- a/src/nvme/private.h +++ b/src/nvme/private.h @@ -87,6 +87,7 @@ struct nvme_ctrl { char *trsvcid; char *host_traddr; char *host_iface; + char *dhchap_key; bool discovery_ctrl; bool discovered; bool persistent; @@ -115,6 +116,7 @@ struct nvme_host { char *hostnqn; char *hostid; + char *dhchap_key; }; struct nvme_root { diff --git a/src/nvme/tree.c b/src/nvme/tree.c index adef39415e..de70f43747 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -168,6 +168,21 @@ const char *nvme_host_get_hostid(nvme_host_t h) return h->hostid; } +const char *nvme_host_get_dhchap_key(nvme_host_t h) +{ + return h->dhchap_key; +} + +void nvme_host_set_dhchap_key(nvme_host_t h, const char *key) +{ + if (h->dhchap_key) { + free(h->dhchap_key); + h->dhchap_key = NULL; + } + if (key) + h->dhchap_key = strdup(key); +} + nvme_subsystem_t nvme_first_subsystem(nvme_host_t h) { return list_top(&h->subsystems, struct nvme_subsystem, entry); @@ -338,6 +353,8 @@ static void __nvme_free_host(struct nvme_host *h) free(h->hostnqn); if (h->hostid) free(h->hostid); + if (h->dhchap_key) + free(h->dhchap_key); h->r->modified = true; free(h); } @@ -468,6 +485,11 @@ static int nvme_scan_subsystem(struct nvme_root *r, char *name, free(hostnqn); if (hostid) free(hostid); + if (h) { + if (h->dhchap_key) + free(h->dhchap_key); + h->dhchap_key = nvme_get_attr(path, "dhchap_secret"); + } } if (!h) h = nvme_default_host(r); @@ -707,6 +729,21 @@ struct nvme_fabrics_config *nvme_ctrl_get_config(nvme_ctrl_t c) return &c->cfg; } +const char *nvme_ctrl_get_dhchap_key(nvme_ctrl_t c) +{ + return c->dhchap_key; +} + +void nvme_ctrl_set_dhchap_key(nvme_ctrl_t c, const char *key) +{ + if (c->dhchap_key) { + free(c->dhchap_key); + c->dhchap_key = NULL; + } + if (key) + c->dhchap_key = strdup(key); +} + void nvme_ctrl_disable_sqflow(nvme_ctrl_t c, bool disable_sqflow) { c->cfg.disable_sqflow = disable_sqflow; @@ -1088,6 +1125,7 @@ static int nvme_configure_ctrl(nvme_ctrl_t c, const char *path, c->queue_count = nvme_get_ctrl_attr(c, "queue_count"); c->serial = nvme_get_ctrl_attr(c, "serial"); c->sqsize = nvme_get_ctrl_attr(c, "sqsize"); + c->dhchap_key = nvme_get_ctrl_attr(c, "dhchap_ctrl_secret"); return 0; } @@ -1261,6 +1299,11 @@ nvme_ctrl_t nvme_scan_ctrl(nvme_root_t r, const char *name) free(hostnqn); if (hostid) free(hostid); + if (h) { + if (h->dhchap_key) + free(h->dhchap_key); + h->dhchap_key = nvme_get_attr(path, "dhchap_secret"); + } if (!h) { h = nvme_default_host(r); if (!h) { diff --git a/src/nvme/tree.h b/src/nvme/tree.h index efafb6fd29..06500ea45a 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -105,6 +105,21 @@ const char *nvme_host_get_hostnqn(nvme_host_t h); */ const char *nvme_host_get_hostid(nvme_host_t h); +/** + * nvme_host_get_dhchap_key() - return host key + * @h: Host for which the key should be returned + * + * Return: DH-HMAC-CHAP host key or NULL if not set + */ +const char *nvme_host_get_dhchap_key(nvme_host_t h); + +/** + * nvme_host_set_dhchap_key() - set host key + * @h: Host for which the key should be set + * @key: DH-HMAC-CHAP Key to set or NULL to clear existing key + */ +void nvme_host_set_dhchap_key(nvme_host_t h, const char *key); + /** * nvme_default_host() - * @r: @@ -779,6 +794,21 @@ const char *nvme_ctrl_get_host_traddr(nvme_ctrl_t c); */ const char *nvme_ctrl_get_host_iface(nvme_ctrl_t c); +/** + * nvme_ctrl_get_dhchap_key() - return controller key + * @c: controller for which the key should be returned + * + * Return: DH-HMAC-CHAP controller key or NULL if not set + */ +const char *nvme_ctrl_get_dhchap_key(nvme_ctrl_t c); + +/** + * nvme_ctrl_set_dhchap_key() - set controller key + * @c: Controller for which the key should be set + * @key: DH-HMAC-CHAP Key to set or NULL to clear existing key + */ +void nvme_ctrl_set_dhchap_key(nvme_ctrl_t c, const char *key); + /** * nvme_ctrl_get_config() - * @c: From d71c2903fee4921a232d064f02d33c283b65d0c3 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 18 Nov 2021 17:01:20 +0100 Subject: [PATCH 0281/1564] Add authentication keys to JSON schema Add the authentication key definitions to the JSON schema. Signed-off-by: Hannes Reinecke --- doc/config-schema.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/config-schema.json b/doc/config-schema.json index ed0fa5082e..2eda3af7ab 100644 --- a/doc/config-schema.json +++ b/doc/config-schema.json @@ -74,6 +74,14 @@ "description": "Transport service identifier", "type": "string" }, + "dhchap_key": { + "description": "Host DH-HMAC-CHAP key", + "type": "string" + }, + "dhchap_ctrl_key": { + "description": "Controller DH-HMAC-CHAP key", + "type": "string" + }, "nr_io_queues": { "description": "Number of I/O queues", "type": "integer" From 9ba8091a90efc79e874ddbd076f91ae31623ad8d Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 18 Nov 2021 17:35:53 +0100 Subject: [PATCH 0282/1564] Sanitize zns command arguments With the recent up the calling convention has been sanitzed to always have the 'timeout' argument as second-to-last, and the 'result' as the laster argument. Modify the zns commands accordingly. Signed-off-by: Hannes Reinecke --- src/nvme/ioctl.c | 24 ++++++++-------- src/nvme/ioctl.h | 72 +++++++++++++++++++++++++----------------------- test/zns.c | 4 +-- 3 files changed, 52 insertions(+), 48 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index b28fa22a6a..58be713096 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -2033,9 +2033,10 @@ int nvme_resv_report(int fd, __u32 nsid, bool eds, __u32 len, return nvme_submit_io_passthru(fd, &cmd, result); } -int nvme_zns_mgmt_send(int fd, __u32 nsid, __u64 slba, bool select_all, - __u32 timeout, enum nvme_zns_send_action zsa, - __u32 data_len, void *data, __u32 *result) +int nvme_zns_mgmt_send(int fd, __u32 nsid, __u64 slba, + enum nvme_zns_send_action zsa, + bool select_all, __u32 data_len, + void *data, __u32 timeout, __u32 *result) { __u32 cdw10 = slba & 0xffffffff; __u32 cdw11 = slba >> 32; @@ -2056,10 +2057,10 @@ int nvme_zns_mgmt_send(int fd, __u32 nsid, __u64 slba, bool select_all, return nvme_submit_io_passthru(fd, &cmd, result); } -int nvme_zns_mgmt_recv(int fd, __u32 nsid, __u64 slba, __u32 timeout, +int nvme_zns_mgmt_recv(int fd, __u32 nsid, __u64 slba, enum nvme_zns_recv_action zra, __u16 zrasf, bool zras_feat, __u32 data_len, void *data, - __u32 *result) + __u32 timeout, __u32 *result) { __u32 cdw10 = slba & 0xffffffff; __u32 cdw11 = slba >> 32; @@ -2083,10 +2084,11 @@ int nvme_zns_mgmt_recv(int fd, __u32 nsid, __u64 slba, __u32 timeout, return nvme_submit_io_passthru(fd, &cmd, result); } -int nvme_zns_report_zones(int fd, __u32 nsid, __u64 slba, __u32 timeout, - bool extended, enum nvme_zns_report_options opts, - bool partial, __u32 data_len, void *data, - __u32 *result) +int nvme_zns_report_zones(int fd, __u32 nsid, __u64 slba, + enum nvme_zns_report_options opts, + bool extended, bool partial, + __u32 data_len, void *data, + __u32 timeout, __u32 *result) { BUILD_ASSERT(sizeof(struct nvme_zns_desc) == 64); enum nvme_zns_recv_action zra; @@ -2096,8 +2098,8 @@ int nvme_zns_report_zones(int fd, __u32 nsid, __u64 slba, __u32 timeout, else zra = NVME_ZNS_ZRA_REPORT_ZONES; - return nvme_zns_mgmt_recv(fd, nsid, slba, timeout, zra, opts, partial, - data_len, data, result); + return nvme_zns_mgmt_recv(fd, nsid, slba, zra, opts, partial, + data_len, data, timeout, result); } int nvme_zns_append(int fd, __u32 nsid, __u64 zslba, __u16 nlb, __u16 control, diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index f045187dea..fa74740a31 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -2711,80 +2711,82 @@ int nvme_resv_report(int fd, __u32 nsid, bool eds, __u32 len, * nvme_zns_mgmt_send() - * @fd: File descriptor of nvme device * @nsid: Namespace ID - * @slba: - * @select_all: + * @slba: Starting logical block address + * @zsa: Zone send action + * @select_all: Select all flag + * @data_len: Length of @data + * @data: Userspace address of the data * @timeout: timeout in ms - * @zsa: - * @data_len: - * @data: * @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. */ -int nvme_zns_mgmt_send(int fd, __u32 nsid, __u64 slba, bool select_all, - __u32 timeout, enum nvme_zns_send_action zsa, - __u32 data_len, void *data, __u32 *result); +int nvme_zns_mgmt_send(int fd, __u32 nsid, __u64 slba, + enum nvme_zns_send_action zsa, bool select_all, + __u32 data_len, void *data, + __u32 timeout, __u32 *result); /** * nvme_zns_mgmt_recv() - * @fd: File descriptor of nvme device * @nsid: Namespace ID - * @slba: + * @slba: Starting logical block address + * @zra: zone receive action + * @zrasf: Zone receive action specific field + * @zras_feat: Zone receive action specific features + * @data_len: Length of @data + * @data: Userspace address of the data * @timeout: timeout in ms - * @zra: - * @zrasf: - * @zras_feat: - * @data_len: - * @data: * @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. */ -int nvme_zns_mgmt_recv(int fd, __u32 nsid, __u64 slba, __u32 timeout, +int nvme_zns_mgmt_recv(int fd, __u32 nsid, __u64 slba, enum nvme_zns_recv_action zra, __u16 zrasf, bool zras_feat, __u32 data_len, void *data, - __u32 *result); + __u32 timeout, __u32 *result); /** * nvme_zns_report_zones() - Return the list of zones * @fd: File descriptor of nvme device * @nsid: Namespace ID * @slba: Starting LBA - * @timeout: timeout in ms - * @extended: Extended report * @opts: Reporting options + * @extended: Extended report * @partial: Partial report requested * @data_len: Length of the data buffer - * @data: Data buffer + * @data: Userspace address of the report zones data + * @timeout: timeout in ms * @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. */ -int nvme_zns_report_zones(int fd, __u32 nsid, __u64 slba, __u32 timeout, - bool extended, enum nvme_zns_report_options opts, - bool partial, __u32 data_len, void *data, - __u32 *result); +int nvme_zns_report_zones(int fd, __u32 nsid, __u64 slba, + enum nvme_zns_report_options opts, + bool extended, bool partial, + __u32 data_len, void *data, + __u32 timeout, __u32 *result); /** - * nvme_zns_append() - + * nvme_zns_append() - Append data to a zone * @fd: File descriptor of nvme device * @nsid: Namespace ID - * @zslba: - * @nlb: + * @zslba: Zone start logical block address + * @nlb: Number of logical blocks * @control: - * @ilbrt: - * @lbat: - * @lbam: - * @data_len: - * @data: - * @metadata_len: - * @metadata: - * @timeout: - * @result: + * @ilbrt: Initial logical block reference tag + * @lbat: Logical block application tag + * @lbatm: Logical block application tag mask + * @data_len: Length of @data + * @data: Userspace address of the data + * @metadata_len: Length of @metadata + * @metadata: Userspace address of the metadata + * @timeout: Timeout in ms + * @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. diff --git a/test/zns.c b/test/zns.c index ed992585ec..997765b44b 100644 --- a/test/zns.c +++ b/test/zns.c @@ -46,10 +46,10 @@ static void show_zns_properties(nvme_ns_t n) printf("zasl:%u\n", zns_ctrl.zasl); if (nvme_zns_mgmt_recv(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), 0, - NVME_DEFAULT_IOCTL_TIMEOUT, NVME_ZNS_ZRA_REPORT_ZONES, NVME_ZNS_ZRAS_REPORT_ALL, - 0, 0x1000, (void *)zr, &result)) { + true, 0x1000, (void *)zr, + NVME_DEFAULT_IOCTL_TIMEOUT, &result)) { fprintf(stderr, "failed to report zones, result %x\n", le32_to_cpu(result)); return; From aed3fc2e4529441d065d2574f2786a6e2e6ea4eb Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Fri, 19 Nov 2021 11:25:37 +0100 Subject: [PATCH 0283/1564] build: Do not use the configurator for meson meson does the feature detection itself and we don't have to rely on the configurator. So don't use it. To avoid touching the ccan files, we have to rethink our config.h to libnvme-config.h rename change. Since the ccan files include 'config.h' we have to use the second option to avoid including it into external include paths. This is moving the config.h file into a private folder and drop the include path '.'. Signed-off-by: Daniel Wagner --- ccan/meson.build | 16 ---------------- examples/meson.build | 4 ++-- libnvme/meson.build | 2 +- meson.build | 9 ++------- src/meson.build | 6 +++++- test/meson.build | 6 +++--- 6 files changed, 13 insertions(+), 30 deletions(-) diff --git a/ccan/meson.build b/ccan/meson.build index 253c139ca7..4536b43636 100644 --- a/ccan/meson.build +++ b/ccan/meson.build @@ -11,19 +11,3 @@ sources += files([ 'ccan/str/debug.c', 'ccan/str/str.c', ]) - -configurator = executable( - 'configurator', - ['tools/configurator/configurator.c'], - c_args: ['-D_GNU_SOURCE'], - include_directories: incdir, -) - -config_h = custom_target( - 'config.h', - output: 'config.h', - capture: true, - command: [configurator, ] -) - - diff --git a/examples/meson.build b/examples/meson.build index 7c86c9d20a..0bf911d597 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -7,7 +7,7 @@ # executable( 'telemetry-listen', - ['telemetry-listen.c', config_h], + ['telemetry-listen.c'], link_with: libnvme, include_directories: incdir) @@ -19,7 +19,7 @@ executable( executable( 'discover-loop', - ['discover-loop.c', config_h], + ['discover-loop.c'], link_with: libnvme, include_directories: incdir) diff --git a/libnvme/meson.build b/libnvme/meson.build index 76797cc78a..b8eda4c8dd 100644 --- a/libnvme/meson.build +++ b/libnvme/meson.build @@ -19,7 +19,7 @@ endif if have_python_support pymod_swig = custom_target( 'nvme.py', - input: ['nvme.i', config_h], + input: ['nvme.i'], output: ['nvme.py', 'nvme_wrap.c'], command: [swig, '-python', '-py3', '-o', '@OUTPUT1@', '@INPUT0@'], install: true, diff --git a/meson.build b/meson.build index 15ad8eb284..25c80747db 100644 --- a/meson.build +++ b/meson.build @@ -120,11 +120,6 @@ conf.set10( description: 'Is isblank() available?' ) -configure_file( - output: 'libnvme-config.h', - configuration: conf -) - ################################################################################ substs = configuration_data() substs.set('NAME', meson.project_name()) @@ -138,8 +133,8 @@ configure_file( ################################################################################ add_project_arguments(['-fomit-frame-pointer', '-D_GNU_SOURCE', - '-include', 'libnvme-config.h'], language : 'c') -incdir = include_directories(['.', 'ccan', 'src']) + '-include', 'config.h'], language : 'c') +incdir = include_directories(['ccan', 'src']) ################################################################################ sources = [] diff --git a/src/meson.build b/src/meson.build index 8d2e0d3541..27246f3f14 100644 --- a/src/meson.build +++ b/src/meson.build @@ -5,6 +5,11 @@ # # Authors: Martin Belanger # +configure_file( + output: 'config.h', + configuration: conf +) + sources += [ 'nvme/cleanup.c', 'nvme/fabrics.c', @@ -14,7 +19,6 @@ sources += [ 'nvme/log.c', 'nvme/tree.c', 'nvme/util.c', - config_h, ] if conf.get('CONFIG_JSONC') diff --git a/test/meson.build b/test/meson.build index 7adb963f64..e89d877831 100644 --- a/test/meson.build +++ b/test/meson.build @@ -7,7 +7,7 @@ # main = executable( 'main-test', - ['test.c', config_h], + ['test.c'], dependencies: libuuid, link_with: libnvme, include_directories: incdir @@ -22,14 +22,14 @@ cpp = executable( register = executable( 'test-register', - ['register.c', config_h], + ['register.c'], link_with: libnvme, include_directories: incdir ) zns = executable( 'test-zns', - ['zns.c', config_h], + ['zns.c'], link_with: libnvme, include_directories: incdir ) From 0a3d6d86a7234fd754ecf0a23183965945c962f1 Mon Sep 17 00:00:00 2001 From: Martin Belanger Date: Fri, 19 Nov 2021 10:51:13 -0500 Subject: [PATCH 0284/1564] Document meson's -Db_sanitize=address option Describe how to use the -Db_sanitize=address and document how to invoke executables with the LD_PRELOAD option. Signed-off-by: Martin Belanger --- README.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 70c13a2122..683c1328ba 100644 --- a/README.md +++ b/README.md @@ -140,8 +140,10 @@ rm -rf .build A few build options can be specified on the command line when invoking meson. -| Option | Values [default] | Description | -| ------- | ------------------- | ------------------------------------------------------------ | +| Option | Values [default] | Description | +| ------ | ------------------- | ------------------------------------------------------------ | +| man | true, [false] | Instruct meson to configure the project to build the `libnvme` documentation.
Example: `meson .build -Dman=true` | +| python | [auto], true, false | Whether to build the Python bindings. When set to `auto`, the default, meson will check for the presence of the tools and libraries (e.g. `swig`) required to build the Python bindings. If found, meson will configure the project to build the Python bindings. If a tool or library is missing, then the Python bindings won't be built. Setting this to `true`, forces the Python bindings to be built. When set to `false`, meson will configure the project to not build the Python bindings.
Example: `meson .build -Dpython=false` | ### Changing the build options from the command-line (i.e. w/o modifying any files) @@ -158,8 +160,15 @@ To enable address sanitizer (advanced debugging of memory issues): meson .build -Db_sanitize=address ``` +This option adds `-fsanitize=address` to the gcc options. Note that when using the sanitize feature, the library `libasan.so` must be available and must be the very first library loaded when running an executable. Ensuring that `libasan.so` gets loaded first can be achieved with the `LD_PRELOAD` environment variable as follows: + +``` +meson .build -Db_sanitize=address && LD_PRELOAD=/lib64/libasan.so.6 ninja -C .build test +``` + To list configuration options that are available and possible values: ```bash meson configure .build ``` + From 6aac238b5395c3608c9735141e194a6555c48504 Mon Sep 17 00:00:00 2001 From: Steven Seungcheol Lee Date: Wed, 3 Nov 2021 19:17:33 +0900 Subject: [PATCH 0285/1564] doc: There is no nvme_host_mem_buf_desc in source files Signed-off-by: Steven Seungcheol Lee --- doc/libnvme.rst | 18 ------------------ doc/man/struct nvme_host_mem_buf_desc.2 | 17 ----------------- 2 files changed, 35 deletions(-) delete mode 100644 doc/man/struct nvme_host_mem_buf_desc.2 diff --git a/doc/libnvme.rst b/doc/libnvme.rst index 0e649ee29f..2eaca93191 100644 --- a/doc/libnvme.rst +++ b/doc/libnvme.rst @@ -9535,24 +9535,6 @@ bytes, in size. This log captures the controller’s internal state. -.. c:type:: struct nvme_host_mem_buf_desc - - -**Definition** - -:: - - struct nvme_host_mem_buf_desc { - __le64 addr; - __le32 size; - __u32 rsvd; - }; - -**Members** - - - - .. c:type:: enum nvme_ae_type diff --git a/doc/man/struct nvme_host_mem_buf_desc.2 b/doc/man/struct nvme_host_mem_buf_desc.2 deleted file mode 100644 index 66bead31bb..0000000000 --- a/doc/man/struct nvme_host_mem_buf_desc.2 +++ /dev/null @@ -1,17 +0,0 @@ -.TH "libnvme" 2 "struct nvme_host_mem_buf_desc" "February 2020" "LIBNVME API Manual" LINUX -.SH NAME -struct nvme_host_mem_buf_desc \- -.SH SYNOPSIS -struct nvme_host_mem_buf_desc { -.br -.BI " __le64 addr;" -.br -.BI " __le32 size;" -.br -.BI " __u32 rsvd;" -.br -.BI " -}; -.br - -.SH Members From 986c5a9dd4f7e381da1d9f044768762e367124f7 Mon Sep 17 00:00:00 2001 From: Steven Seungcheol Lee Date: Thu, 14 Oct 2021 12:48:36 +0900 Subject: [PATCH 0286/1564] Add libjson version check on configure to fix build error json_util_get_last_err, json_object_to_fd are supported from json-c-0.13-20171207 if json-c version is lower than 0.13, build without it Signed-off-by: Steven Seungcheol Lee --- configure | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/configure b/configure index dcf1699131..d67ed8e5e1 100755 --- a/configure +++ b/configure @@ -199,9 +199,8 @@ print_config "libuuid" "${libuuid}" # check for libjson-c libjsonc="no" if [ -z "$disable_json" ] ; then - ${ld} -o /dev/null -ljson-c >/dev/null 2>&1 - if [ $? -eq 0 ]; then - libjsonc="yes" + if pkg-config --atleast-version=0.13 json-c; then + libjsonc="yes" fi fi print_config "libjson-c" "${libjsonc}" From 9365e4ee64c197be3314732ec09a12aacc97a486 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 22 Nov 2021 17:35:36 +0100 Subject: [PATCH 0287/1564] tree: fixup loop address handling 'loop' controllers have an empty 'address' sysfs attribute, so we need to check for loop to avoid failures due to an invalid controller address. Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 966464ed53..c1e58f9371 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -1153,12 +1153,15 @@ int nvme_init_ctrl(nvme_host_t h, nvme_ctrl_t c, int instance) goto out_free_name; } - c->address = nvme_get_attr(path, "address"); - if (!c->address) { - errno = ENXIO; - ret = -1; - goto out_free_name; + if (strcmp(c->transport, "loop")) { + c->address = nvme_get_attr(path, "address"); + if (!c->address) { + errno = ENXIO; + ret = -1; + goto out_free_name; + } } + subsys_name = nvme_ctrl_lookup_subsystem_name(c); if (!subsys_name) { nvme_msg(LOG_ERR, "Failed to lookup subsystem name for %s\n", @@ -1203,7 +1206,7 @@ static nvme_ctrl_t nvme_ctrl_alloc(nvme_subsystem_t s, const char *path, const char *name) { nvme_ctrl_t c; - char *addr, *address = NULL, *a, *e; + char *addr = NULL, *address = NULL, *a, *e; char *transport, *traddr = NULL, *trsvcid = NULL; char *host_traddr = NULL, *host_iface = NULL; int ret; @@ -1213,6 +1216,8 @@ static nvme_ctrl_t nvme_ctrl_alloc(nvme_subsystem_t s, const char *path, errno = ENXIO; return NULL; } + if (!strcmp(transport, "loop")) + goto skip_address; /* Parse 'address' string into components */ addr = nvme_get_attr(path, "address"); if (!addr) { @@ -1261,6 +1266,7 @@ static nvme_ctrl_t nvme_ctrl_alloc(nvme_subsystem_t s, const char *path, a = strtok_r(NULL, ",", &e); } } +skip_address: c = nvme_lookup_ctrl(s, transport, traddr, host_traddr, host_iface, trsvcid); free(transport); From 35250695141f269e5dce1c54df6029f192ca194b Mon Sep 17 00:00:00 2001 From: Gollu Appalanaidu Date: Fri, 28 May 2021 10:40:40 +0530 Subject: [PATCH 0288/1564] nvme: add optional copy format support id ctrl field Add the OCFS field in Identify Controller Structure, as per the Ratified TP 4065b (Simple Copy Command). Signed-off-by: Gollu Appalanaidu --- src/nvme/types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nvme/types.h b/src/nvme/types.h index a82ed3f2a6..4b4c5ddbc5 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -965,7 +965,7 @@ struct nvme_id_ctrl { __u8 icsvscc; __u8 nwpc; __le16 acwu; - __u8 rsvd534[2]; + __le16 ocfs; __le32 sgls; __le32 mnan; __u8 maxdna[16]; From 95708cb1ba215e2b26c0817a426b55ed2bb9dbc6 Mon Sep 17 00:00:00 2001 From: Steven Seungcheol Lee Date: Wed, 24 Nov 2021 18:51:16 +0900 Subject: [PATCH 0289/1564] doc: Add ocfs explaination Signed-off-by: Steven Seungcheol Lee --- doc/libnvme.rst | 6 +++++- doc/man/struct nvme_id_ctrl.2 | 5 ++++- src/nvme/types.h | 2 ++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/doc/libnvme.rst b/doc/libnvme.rst index 0e649ee29f..5d1d44defd 100644 --- a/doc/libnvme.rst +++ b/doc/libnvme.rst @@ -6425,7 +6425,7 @@ Returns true if given offset is 64bit register, otherwise it returns false. __u8 nvscc; __u8 nwpc; __le16 acwu; - __u8 rsvd534[2]; + __le16 ocfs; __le32 sgls; __le32 mnan; __u8 rsvd544[224]; @@ -6750,6 +6750,10 @@ Returns true if given offset is 64bit register, otherwise it returns false. 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. + ``sgls`` SGL Support, see :c:type:`enum nvme_id_ctrl_sgls ` diff --git a/doc/man/struct nvme_id_ctrl.2 b/doc/man/struct nvme_id_ctrl.2 index f3dab11b4c..6beae9a41d 100644 --- a/doc/man/struct nvme_id_ctrl.2 +++ b/doc/man/struct nvme_id_ctrl.2 @@ -152,7 +152,7 @@ struct nvme_id_ctrl { .br .BI " __le16 acwu;" .br -.BI " __u8 rsvd534[2];" +.BI " __le16 ocfs;" .br .BI " __le32 sgls;" .br @@ -424,6 +424,9 @@ 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. +.IP "ocfs" 12 +Optional Copy Formats Supported, each bit n means controller +supports Copy Format n. .IP "sgls" 12 SGL Support, see \fIenum nvme_id_ctrl_sgls\fP .IP "mnan" 12 diff --git a/src/nvme/types.h b/src/nvme/types.h index 4b4c5ddbc5..f762c0ff71 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -862,6 +862,8 @@ struct nvme_id_psd { * 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. * @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. From 02489f250655146e73cf7b54036bde53bcb5bb4b Mon Sep 17 00:00:00 2001 From: Sagi Grimberg Date: Sun, 28 Nov 2021 15:03:03 +0200 Subject: [PATCH 0290/1564] fabrics: fix endless loop in connect-all for NVME_NQN_CURR For a discovery log page entry that indicates the discovery controller that returned it (i.e. itself), we need to set the controller as discovered (because we got the discovery log page by connecting to it). Without this connect-all goes in an endless loop keep connecting and retrieving the log page from the same discovery subsystem port. Fixes: 06a8f001d314 ("tree,fabrics: detect discovery loops") Signed-off-by: Sagi Grimberg --- src/nvme/fabrics.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 686a5641aa..9207296ba9 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -657,8 +657,10 @@ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, } switch (e->subtype) { - case NVME_NQN_DISC: case NVME_NQN_CURR: + nvme_ctrl_set_discovered(c, true); + break; + case NVME_NQN_DISC: if (discover) *discover = true; nvme_ctrl_set_discovery_ctrl(c, true); From ae234c5e139a50b8c12e1fe95fb9b85f93b76c1f Mon Sep 17 00:00:00 2001 From: Martin Belanger Date: Tue, 30 Nov 2021 14:50:29 -0500 Subject: [PATCH 0291/1564] Fix memory leak. The API PyDict_SetItemString() does not steal references when adding objects to a dictionary. Therefore, the caller must decrement the reference count after adding objects to the dictionary if those objects are no longer needed. Signed-off-by: Martin Belanger --- libnvme/nvme.i | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/libnvme/nvme.i b/libnvme/nvme.i index 04e8c3c307..5458d3cc49 100644 --- a/libnvme/nvme.i +++ b/libnvme/nvme.i @@ -161,6 +161,13 @@ static int discover_err = 0; if ($1) free($1); } +%{ +static void PyDict_SetItemStringDecRef(PyObject *p, const char *key, PyObject *val) { + PyDict_SetItemString(p, key, val); /* Does NOT steal reference to val .. */ + Py_XDECREF(val); /* .. therefore decrement ref. count. */ +} +%} + %typemap(out) struct nvmf_discovery_log * { struct nvmf_discovery_log *log = $1; int numrec = log? log->numrec : 0, i; @@ -190,7 +197,7 @@ static int discover_err = 0; default: val = PyLong_FromLong(e->trtype); } - PyDict_SetItemString(entry, "trtype", val); + PyDict_SetItemStringDecRef(entry, "trtype", val); switch (e->adrfam) { case NVMF_ADDR_FAMILY_PCI: val = PyUnicode_FromString("pci"); @@ -210,13 +217,13 @@ static int discover_err = 0; default: val = PyLong_FromLong(e->adrfam); } - PyDict_SetItemString(entry, "adrfam", val); + PyDict_SetItemStringDecRef(entry, "adrfam", val); val = PyUnicode_FromString(e->traddr); - PyDict_SetItemString(entry, "traddr", val); + PyDict_SetItemStringDecRef(entry, "traddr", val); val = PyUnicode_FromString(e->trsvcid); - PyDict_SetItemString(entry, "trsvcid", val); + PyDict_SetItemStringDecRef(entry, "trsvcid", val); val = PyUnicode_FromString(e->subnqn); - PyDict_SetItemString(entry, "subnqn", val); + PyDict_SetItemStringDecRef(entry, "subnqn", val); switch (e->subtype) { case NVME_NQN_DISC: val = PyUnicode_FromString("referral"); @@ -230,7 +237,7 @@ static int discover_err = 0; default: val = PyLong_FromLong(e->subtype); } - PyDict_SetItemString(entry, "subtype", val); + PyDict_SetItemStringDecRef(entry, "subtype", val); switch (e->treq) { case NVMF_TREQ_NOT_SPECIFIED: val = PyUnicode_FromString("not specified"); @@ -247,14 +254,14 @@ static int discover_err = 0; default: val = PyLong_FromLong(e->treq); } - PyDict_SetItemString(entry, "treq", val); + PyDict_SetItemStringDecRef(entry, "treq", val); val = PyLong_FromLong(e->portid); - PyDict_SetItemString(entry, "portid", val); + PyDict_SetItemStringDecRef(entry, "portid", val); val = PyLong_FromLong(e->cntlid); - PyDict_SetItemString(entry, "cntlid", val); + PyDict_SetItemStringDecRef(entry, "cntlid", val); val = PyLong_FromLong(e->asqsz); - PyDict_SetItemString(entry, "asqsz", val); - PyList_SetItem(obj, i, entry); + PyDict_SetItemStringDecRef(entry, "asqsz", val); + PyList_SetItem(obj, i, entry); /* steals ref. to entry */ } $result = obj; }; From 5488fcf3bfd34f3d081fd071367245146a0e1a6f Mon Sep 17 00:00:00 2001 From: Tomas Bzatek Date: Wed, 1 Dec 2021 16:41:53 +0100 Subject: [PATCH 0292/1564] types: Fabrics doc strings updates Includes a typo correction, prefix changes, transition away from anonymous enums and added some more enum members according to the standard. All subtle API breaks. --- src/nvme/types.h | 144 +++++++++++++++++++++++++++++++---------------- 1 file changed, 95 insertions(+), 49 deletions(-) diff --git a/src/nvme/types.h b/src/nvme/types.h index f762c0ff71..6bf064449f 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -3830,7 +3830,7 @@ enum nvme_ae_info_notice { }; /** - * enum nvme_subsys_type - + * enum nvme_subsys_type - Type of the NVM subsystem. * @NVME_NQN_DISC: Discovery type target subsystem * @NVME_NQN_NVME: NVME type target subsystem * @NVME_NQN_CURR: Current Discovery type target subsystem @@ -3855,24 +3855,54 @@ enum nvme_subsys_type { #define NVMF_DISC_EFLAGS_BOTH 3 /** - * struct nvmf_disc_log_entry - Discovery log page entry - * @trtype: - * @adrfam: - * @subtype: - * @treq: - * @portid: - * @cntlid: - * @asqsz: + * struct nvmf_disc_log_entry - Discovery Log Page entry + * @trtype: Transport Type (TRTYPE): Specifies the NVMe Transport type. + * See &enum nvmf_trtype. + * @adrfam: Address Family (ADRFAM): Specifies the address 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. + * @treq: Transport Requirements (TREQ): Indicates requirements for the NVMe + * 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). + * @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. + * @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. * @eflags: - * @trsvcid: - * @subnqn: - * @traddr: + * @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. + * @subnqn: NVM Subsystem Qualified Name (SUBNQN): NVMe Qualified Name (NQN) + * that uniquely identifies the NVM subsystem. For a Discovery Service, + * 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. * @common: - * @qptype: - * @prtype: - * @cms: - * @pkey: - * @sectype: + * @qptype: RDMA QP Service Type (RDMA_QPTYPE): Specifies the type of RDMA + * Queue Pair. See &enum nvmf_rdma_qptype. + * @prtype: RDMA Provider Type (RDMA_PRTYPE): Specifies the type of RDMA + * provider. See &enum nvmf_rdma_prtype. + * @cms: RDMA Connection Management Service (RDMA_CMS): Specifies the type + * of RDMA IP Connection Management Service. See &enum nvmf_rdma_cms. + * @pkey: RDMA_PKEY: Specifies the Partition Key when AF_IB (InfiniBand) + * address family type is used. + * @sectype: Security Type (SECTYPE): Specifies the type of security used by the + * NVMe/TCP port. If SECTYPE is a value of 0h (No Security), then the + * host shall set up a normal TCP connection. See &enum nvmf_tcp_sectype. */ struct nvmf_disc_log_entry { __u8 trtype; @@ -3905,14 +3935,15 @@ struct nvmf_disc_log_entry { }; /** - * enum - Transport Type codes for Discovery Log Page entry TRTYPE field + * enum nvmf_trtype - Transport Type codes for Discovery Log Page entry TRTYPE field * @NVMF_TRTYPE_UNSPECIFIED: Not indicated * @NVMF_TRTYPE_RDMA: RDMA * @NVMF_TRTYPE_FC: Fibre Channel * @NVMF_TRTYPE_TCP: TCP - * @NVMF_TRTYPE_LOOP: Reserved for host usage + * @NVMF_TRTYPE_LOOP: Intra-host Transport (i.e., loopback), reserved + * for host usage. */ -enum nvme_trtype { +enum nvmf_trtype { NVMF_TRTYPE_UNSPECIFIED = 0, NVMF_TRTYPE_RDMA = 1, NVMF_TRTYPE_FC = 2, @@ -3922,23 +3953,26 @@ enum nvme_trtype { }; /** - * enum - Address Family codes for Discovery Log Page entry ADRFAM field + * enum nvmf_addr_family - Address Family codes for Discovery Log Page entry ADRFAM field * @NVMF_ADDR_FAMILY_PCI: PCIe - * @NVMF_ADDR_FAMILY_IP4: IPv4 - * @NVMF_ADDR_FAMILY_IP6: IPv6 - * @NVMF_ADDR_FAMILY_IB: InfiniBand - * @NVMF_ADDR_FAMILY_FC: Fibre Channel - */ -enum nvmf_addr_familiy { + * @NVMF_ADDR_FAMILY_IP4: AF_INET: IPv4 address family. + * @NVMF_ADDR_FAMILY_IP6: AF_INET6: IPv6 address family. + * @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. + */ +enum nvmf_addr_family { NVMF_ADDR_FAMILY_PCI = 0, NVMF_ADDR_FAMILY_IP4 = 1, NVMF_ADDR_FAMILY_IP6 = 2, NVMF_ADDR_FAMILY_IB = 3, NVMF_ADDR_FAMILY_FC = 4, + NVMF_ADDR_FAMILY_LOOP = 254, }; /** - * enum - Transport Requirements codes for Discovery Log Page entry TREQ field + * enum nvmf_treq - Transport Requirements codes for Discovery Log Page entry TREQ field * @NVMF_TREQ_NOT_SPECIFIED: Not specified * @NVMF_TREQ_REQUIRED: Required * @NVMF_TREQ_NOT_REQUIRED: Not Required @@ -3952,26 +3986,26 @@ enum nvmf_treq { }; /** - * enum - RDMA QP Service Type codes for Discovery Log Page entry TSAS - * RDMA_QPTYPE field + * enum nvmf_rdma_qptype - RDMA QP Service Type codes for Discovery Log Page + * entry TSAS RDMA_QPTYPE field * @NVMF_RDMA_QPTYPE_CONNECTED: Reliable Connected * @NVMF_RDMA_QPTYPE_DATAGRAM: Reliable Datagram */ -enum { +enum nvmf_rdma_qptype { NVMF_RDMA_QPTYPE_CONNECTED = 1, NVMF_RDMA_QPTYPE_DATAGRAM = 2, }; /** - * enum - RDMA Provider Type codes for Discovery Log Page entry TSAS - * RDMA_PRTYPE field + * enum nvmf_rdma_prtype - RDMA Provider Type codes for Discovery Log Page + * entry TSAS RDMA_PRTYPE field * @NVMF_RDMA_PRTYPE_NOT_SPECIFIED: No Provider Specified * @NVMF_RDMA_PRTYPE_IB: InfiniBand * @NVMF_RDMA_PRTYPE_ROCE: InfiniBand RoCE * @NVMF_RDMA_PRTYPE_ROCEV2: InfiniBand RoCEV2 * @NVMF_RDMA_PRTYPE_IWARP: iWARP */ -enum nvme_rdma_prtype { +enum nvmf_rdma_prtype { NVMF_RDMA_PRTYPE_NOT_SPECIFIED = 1, NVMF_RDMA_PRTYPE_IB = 2, NVMF_RDMA_PRTYPE_ROCE = 3, @@ -3980,31 +4014,43 @@ enum nvme_rdma_prtype { }; /** - * enum - RDMA Connection Management Service Type codes for Discovery Log Page - * entry TSAS RDMA_CMS field + * enum nvmf_rdma_cms - RDMA Connection Management Service Type codes for + * Discovery Log Page entry TSAS RDMA_CMS field * @NVMF_RDMA_CMS_RDMA_CM: Sockets based endpoint addressing * */ -enum { +enum nvmf_rdma_cms { NVMF_RDMA_CMS_RDMA_CM = 1, }; /** - * enum - - * @NVMF_TCP_SECTYPE_NONE: No Security - * @NVMF_TCP_SECTYPE_TLS: Transport Layer Security + * enum nvmf_tcp_sectype - Transport Specific Address Subtype Definition for + * 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. */ -enum { +enum nvmf_tcp_sectype { NVMF_TCP_SECTYPE_NONE = 0, NVMF_TCP_SECTYPE_TLS = 1, -}; - -/** - * struct nvmf_discovery_log - - * @genctr: - * @numrec: - * @recfmt: - * @entries: + NVMF_TCP_SECTYPE_TLS13 = 2, +}; + +/** + * 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). + * @numrec: Number of Records (NUMREC): Indicates the number of records + * 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. + * @entries: Discovery Log Page Entries - see &struct nvmf_disc_log_entry. */ struct nvmf_discovery_log { __le64 genctr; From e104b997a796a4794819d1825905aafe97bbd16f Mon Sep 17 00:00:00 2001 From: Tomas Bzatek Date: Wed, 1 Dec 2021 17:38:12 +0100 Subject: [PATCH 0293/1564] fabrics: Don't include trailing newline in nvmf_hostnqn_generate() The generated string is directly used in nvme_lookup_host() and might cause mismatches due to the inclusion of a trailing newline. --- src/nvme/fabrics.c | 2 +- src/nvme/fabrics.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 9207296ba9..9f0b005987 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -958,7 +958,7 @@ char *nvmf_hostnqn_generate() if (ret < 0) return NULL; - if (asprintf(&hostnqn, "nqn.2014-08.org.nvmexpress:uuid:%s\n", uuid_str) < 0) + if (asprintf(&hostnqn, "nqn.2014-08.org.nvmexpress:uuid:%s", uuid_str) < 0) return NULL; return hostnqn; diff --git a/src/nvme/fabrics.h b/src/nvme/fabrics.h index 4a7481a83f..73932ff382 100644 --- a/src/nvme/fabrics.h +++ b/src/nvme/fabrics.h @@ -179,7 +179,7 @@ int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, /** * nvmf_hostnqn_generate() - Generate a machine specific host nqn - * Returns: An nvm namespace qualifieid name string based on the machine + * Returns: An nvm namespace qualified name string based on the machine * identifier, or NULL if not successful. */ char *nvmf_hostnqn_generate(); From 6e9b35774807f99a437aa267a5d68dd12e1db6fe Mon Sep 17 00:00:00 2001 From: Tomas Bzatek Date: Wed, 1 Dec 2021 18:15:59 +0100 Subject: [PATCH 0294/1564] tree: Handle NULL hostid in nvme_lookup_host() When hostid is specified for lookup and some of the tree host records carry a NULL, avoid a segfault here on strcmp(). --- src/nvme/tree.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index c1e58f9371..a782f04a2e 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -374,8 +374,8 @@ struct nvme_host *nvme_lookup_host(nvme_root_t r, const char *hostnqn, nvme_for_each_host(r, h) { if (strcmp(h->hostnqn, hostnqn)) continue; - if (hostid && - strcmp(h->hostid, hostid)) + if (hostid && (!h->hostid || + strcmp(h->hostid, hostid))) continue; return h; } From 71160deb6305ac7a8ef6989a373bfe72fc3d1de6 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 9 Dec 2021 11:37:20 +0100 Subject: [PATCH 0295/1564] build: Enable ccan debug code for debug build The ccan library has support debugging, let's enable this when building the debug version of the library. Signed-off-by: Daniel Wagner --- ccan/meson.build | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ccan/meson.build b/ccan/meson.build index 4536b43636..05d10c9d03 100644 --- a/ccan/meson.build +++ b/ccan/meson.build @@ -11,3 +11,8 @@ sources += files([ 'ccan/str/debug.c', 'ccan/str/str.c', ]) + +if get_option('buildtype') == 'debug' + add_project_arguments('-DCCAN_LIST_DEBUG=1', language : ['c', 'cpp']) + add_project_arguments('-DCCAN_STR_DEBUG=1', language : ['c', 'cpp']) +endif From 14f42f7720a5647f95260070712d7d685cbbd061 Mon Sep 17 00:00:00 2001 From: Steven Seungcheol Lee Date: Thu, 9 Dec 2021 20:17:09 +0900 Subject: [PATCH 0296/1564] Add missing function(nvme_get_log_zns_changed_zones) to map file Signed-off-by: Steven Seungcheol Lee --- src/libnvme.map | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libnvme.map b/src/libnvme.map index c732757e49..7f2b35d1e1 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -131,6 +131,7 @@ LIBNVME_1_0 { nvme_get_log_supported_log_pages; nvme_get_log_telemetry_ctrl; nvme_get_log_telemetry_host; + nvme_get_log_zns_changed_zones; nvme_get_new_host_telemetry; nvme_get_ns_attr; nvme_get_nsid; From fe906ff48b2f4ff00916d2daede3a7a89641d021 Mon Sep 17 00:00:00 2001 From: Steven Seungcheol Lee Date: Wed, 8 Dec 2021 12:49:14 +0900 Subject: [PATCH 0297/1564] zns: Add support for zone random write area (zrwa) NVMe - TP 4076 Zoned Random Write Area 2021.08.23 - Ratified Signed-off-by: Steven Seungcheol Lee Co-authored-by: Klaus Jensen --- src/nvme/ioctl.c | 9 +++++--- src/nvme/ioctl.h | 3 ++- src/nvme/types.h | 54 +++++++++++++++++++++++++++++++++--------------- src/nvme/util.c | 2 ++ 4 files changed, 47 insertions(+), 21 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 58be713096..9bf3cf187a 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -294,6 +294,8 @@ enum nvme_cmd_dword_fields { NVME_GET_LBA_STATUS_CDW13_ATYPE_SHIFT = 24, NVME_GET_LBA_STATUS_CDW13_RL_MASK = 0xffff, NVME_GET_LBA_STATUS_CDW13_ATYPE_MASK = 0xff, + NVME_ZNS_MGMT_SEND_ZSASO_SHIFT = 9, + NVME_ZNS_MGMT_SEND_ZSASO_MASK = 0x1, NVME_ZNS_MGMT_SEND_SEL_SHIFT = 8, NVME_ZNS_MGMT_SEND_SEL_MASK = 0x1, NVME_ZNS_MGMT_SEND_ZSA_SHIFT = 0, @@ -2034,13 +2036,14 @@ int nvme_resv_report(int fd, __u32 nsid, bool eds, __u32 len, } int nvme_zns_mgmt_send(int fd, __u32 nsid, __u64 slba, - enum nvme_zns_send_action zsa, - bool select_all, __u32 data_len, + enum nvme_zns_send_action zsa, bool select_all, + __u8 zsaso, __u32 data_len, void *data, __u32 timeout, __u32 *result) { __u32 cdw10 = slba & 0xffffffff; __u32 cdw11 = slba >> 32; - __u32 cdw13 = NVME_SET(!!select_all, ZNS_MGMT_SEND_SEL) | + __u32 cdw13 = NVME_SET(zsaso, ZNS_MGMT_SEND_ZSASO) | + NVME_SET(!!select_all, ZNS_MGMT_SEND_SEL) | NVME_SET(zsa, ZNS_MGMT_SEND_ZSA); struct nvme_passthru_cmd cmd = { diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index fa74740a31..a44d405093 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -2714,6 +2714,7 @@ int nvme_resv_report(int fd, __u32 nsid, bool eds, __u32 len, * @slba: Starting logical block address * @zsa: Zone send action * @select_all: Select all flag + * @zsaso: Zone Send Action Specific Option * @data_len: Length of @data * @data: Userspace address of the data * @timeout: timeout in ms @@ -2723,7 +2724,7 @@ int nvme_resv_report(int fd, __u32 nsid, bool eds, __u32 len, * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_zns_mgmt_send(int fd, __u32 nsid, __u64 slba, - enum nvme_zns_send_action zsa, bool select_all, + enum nvme_zns_send_action zsa, bool select_all, __u8 zsaso, __u32 data_len, void *data, __u32 timeout, __u32 *result); diff --git a/src/nvme/types.h b/src/nvme/types.h index 6bf064449f..ea2f5ac741 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -2071,14 +2071,18 @@ struct nvme_zns_lbafe { /** * 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 - * @mor: Maximum Open Resources - * @rrl: Reset Recommended Limit - * @frl: Finish Recommended Limit - * @lbafe: LBA Format Extension - * @vs: Vendor Specific * struct nvme_zns_id_ns - + * @zoc: Zone Operation Characteristics + * @ozcs: Optional Zoned Command Support + * @mar: Maximum Active Resources + * @mor: Maximum Open Resources + * @rrl: Reset Recommended Limit + * @frl: Finish Recommended Limit + * @numzrwa: Number of ZRWA Resources + * @zrwafg: ZRWA Flush Granularity + * @zrwasz: ZRWA Size + * @zrwacap: ZRWA Capability + * @lbafe: LBA Format Extension + * @vs: Vendor Specific */ struct nvme_zns_id_ns { __le16 zoc; @@ -2093,7 +2097,11 @@ struct nvme_zns_id_ns { __le32 frl1; __le32 frl2; __le32 frl3; - __u8 rsvd44[2772]; + __le32 numzrwa; + __le16 zrwafg; + __le16 zrwasz; + __u8 zrwacap; + __u8 rsvd53[2763]; struct nvme_zns_lbafe lbafe[64]; __u8 vs[256]; }; @@ -3444,6 +3452,7 @@ enum nvme_zns_za { NVME_ZNS_ZA_ZFC = 1 << 0, NVME_ZNS_ZA_FZR = 1 << 1, NVME_ZNS_ZA_RZR = 1 << 2, + NVME_ZNS_ZA_ZRWAV = 1 << 3, NVME_ZNS_ZA_ZDEV = 1 << 7, }; @@ -4830,6 +4839,14 @@ struct nvme_mi_vpd_hdr { * 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. + * @NVME_SC_ZNS_ZRWA_RESOURCES_UNAVAILABLE: ZRWA Resources Unavailable: + * No ZRWAs are available. * @NVME_SC_ZNS_BOUNDARY_ERROR: Zone Boundary Error: The command specifies * logical blocks in more than one zone. * @NVME_SC_ZNS_FULL: Zone Is Full: The accessed zone is in the @@ -4984,14 +5001,16 @@ enum nvme_status_field { /* * I/O Command Set Specific - ZNS commands: */ - 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_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, /* * Media and Data Integrity Errors: @@ -5877,6 +5896,7 @@ enum nvme_zns_send_action { NVME_ZNS_ZSA_RESET = 0x4, NVME_ZNS_ZSA_OFFLINE = 0x5, NVME_ZNS_ZSA_SET_DESC_EXT = 0x10, + NVME_ZNS_ZSA_ZRWA_FLUSH = 0x11, }; /** diff --git a/src/nvme/util.c b/src/nvme/util.c index dab6c02b2d..b2a7b86bed 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -243,6 +243,8 @@ static const char * const nvm_status[] = { [NVME_SC_INVALID_PI] = "Invalid Protection Information: The command's Protection Information Field settings are invalid for the namespace's Protection Information format", [NVME_SC_READ_ONLY] = "Attempted Write to Read Only Range: The LBA range specified contains read-only blocks", [NVME_SC_CMD_SIZE_LIMIT_EXCEEDED] = "Command Size Limit Exceeded", + [NVME_SC_ZNS_INVALID_OP_REQUEST] = "Invalid Zone Operation Request: The operation requested is invalid", + [NVME_SC_ZNS_ZRWA_RESOURCES_UNAVAILABLE] = "ZRWA Resources Unavailable: No ZRWAs are available", [NVME_SC_ZNS_BOUNDARY_ERROR] = "Zoned Boundary Error: Invalid Zone Boundary crossing", [NVME_SC_ZNS_FULL] = "Zone Is Full: The accessed zone is in ZSF:Full state", [NVME_SC_ZNS_READ_ONLY] = "Zone Is Read Only: The accessed zone is in ZSRO:Read Only state", From 42a2ddbd9aff73f95b13c70807a77f4fb3e044d3 Mon Sep 17 00:00:00 2001 From: Wen Xiong Date: Wed, 1 Dec 2021 17:15:50 -0500 Subject: [PATCH 0298/1564] libnvme: Add new events support in PEL Add two new events support in header file. Signed-off-by: Wen Xiong --- src/nvme/types.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/nvme/types.h b/src/nvme/types.h index ea2f5ac741..a636f743a1 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -3054,6 +3054,8 @@ enum nvme_persistent_event_types { 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, }; @@ -3132,6 +3134,12 @@ struct nvme_sanitize_compln_event { __u8 rsvd6[2]; }; +/* persistent event type 0Bh */ +struct nvme_set_feature_event { + __le32 layout; + __le32 cdw_mem[0]; +}; + struct nvme_thermal_exc_event { __u8 over_temp; __u8 threshold; From 971fe6376c9e3c81f58bdd967d738c1439740af2 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Mon, 13 Dec 2021 14:23:07 +0100 Subject: [PATCH 0299/1564] types: Add documentation to enum nvme_csi Signed-off-by: Daniel Wagner --- src/nvme/types.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/nvme/types.h b/src/nvme/types.h index a636f743a1..a9cf415cfb 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -114,6 +114,7 @@ enum nvme_constants { /** * enum nvme_csi - Defined command set indicators * @NVME_CSI_NVM: NVM Command Set Indicator + * @NVME_CSI_ZNS: Zoned Namespace Command Set */ enum nvme_csi { NVME_CSI_NVM = 0, From c35c684e4849e0e537456b39800ca661090f8288 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Fri, 10 Dec 2021 17:33:49 +0100 Subject: [PATCH 0300/1564] ioctl: Add Offset Type to get_log_page() Port of the "add get log page 2.0 spec fields" patch. Signed-off-by: Daniel Wagner --- src/nvme/ioctl.c | 59 +++++++++++++++++++++++++++--------------------- src/nvme/ioctl.h | 14 +++++++++--- src/nvme/linux.c | 2 +- 3 files changed, 45 insertions(+), 30 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 9bf3cf187a..934e6d57f4 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -228,6 +228,7 @@ enum nvme_cmd_dword_fields { NVME_LOG_CDW11_LSI_SHIFT = 16, NVME_LOG_CDW14_UUID_SHIFT = 0, 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_RAE_MASK = 0x1, @@ -236,6 +237,7 @@ enum nvme_cmd_dword_fields { NVME_LOG_CDW11_LSI_MASK = 0xff, NVME_LOG_CDW14_UUID_MASK = 0x7f, NVME_LOG_CDW14_CSI_MASK = 0xff, + NVME_LOG_CDW14_OT_MASK = 0x1, NVME_IDENTIFY_CDW10_CNS_SHIFT = 0, NVME_IDENTIFY_CDW10_CNTID_SHIFT = 16, NVME_IDENTIFY_CDW11_NVMSETID_SHIFT = 0, @@ -594,7 +596,7 @@ int nvme_nvm_identify_ctrl(int fd, struct nvme_id_ctrl_nvm *id) int nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, __u8 lsp, __u16 lsi, bool rae, __u8 uuidx, enum nvme_csi csi, - __u32 len, void *log, __u32 timeout, __u32 *result) + bool ot, __u32 len, void *log, __u32 timeout, __u32 *result) { __u32 numd = (len >> 2) - 1; __u16 numdu = numd >> 16, numdl = numd & 0xffff; @@ -608,7 +610,8 @@ int nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, __u32 cdw12 = lpo & 0xffffffff; __u32 cdw13 = lpo >> 32; __u32 cdw14 = NVME_SET(uuidx, LOG_CDW14_UUID) | - NVME_SET(csi, LOG_CDW14_CSI); + NVME_SET(csi, LOG_CDW14_CSI) | + NVME_SET(!!ot, LOG_CDW14_OT); struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_get_log_page, @@ -631,8 +634,8 @@ static int __nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, bool rae, { return nvme_get_log(fd, lid, NVME_NSID_ALL, 0, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, - NVME_CSI_NVM, len, log, NVME_DEFAULT_IOCTL_TIMEOUT, - NULL); + NVME_CSI_NVM, false, len, log, + NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_get_log_supported_log_pages(int fd, bool rae, @@ -656,8 +659,9 @@ int nvme_get_log_smart(int fd, __u32 nsid, bool rae, struct nvme_smart_log *log) BUILD_ASSERT(sizeof(struct nvme_smart_log) == 512); return nvme_get_log(fd, NVME_LOG_LID_SMART, nsid, 0, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, - NVME_UUID_NONE, NVME_CSI_NVM, sizeof(*log), log, - NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + NVME_UUID_NONE, NVME_CSI_NVM, false, + sizeof(*log), log, NVME_DEFAULT_IOCTL_TIMEOUT, + NULL); } int nvme_get_log_fw_slot(int fd, bool rae, struct nvme_firmware_slot *log) @@ -679,7 +683,7 @@ int nvme_get_log_cmd_effects(int fd, enum nvme_csi csi, BUILD_ASSERT(sizeof(struct nvme_cmd_effects_log) == 4096); return nvme_get_log(fd, NVME_LOG_LID_CMD_EFFECTS, NVME_NSID_ALL, 0, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, - NVME_UUID_NONE, csi, false, sizeof(*log), + NVME_UUID_NONE, csi, false, false, sizeof(*log), log, NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } @@ -700,8 +704,9 @@ int nvme_get_log_create_telemetry_host(int fd, struct nvme_telemetry_log *log) BUILD_ASSERT(sizeof(struct nvme_telemetry_log) == 512); return nvme_get_log(fd, NVME_LOG_LID_TELEMETRY_HOST, NVME_NSID_NONE, 0, NVME_LOG_TELEM_HOST_LSP_CREATE, NVME_LOG_LSI_NONE, - false, NVME_UUID_NONE, NVME_CSI_NVM, sizeof(*log), - log, NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + false, NVME_UUID_NONE, NVME_CSI_NVM, false, + sizeof(*log), log, NVME_DEFAULT_IOCTL_TIMEOUT, + NULL); } int nvme_get_log_telemetry_host(int fd, __u64 offset, __u32 len, void *log) @@ -709,8 +714,8 @@ int nvme_get_log_telemetry_host(int fd, __u64 offset, __u32 len, void *log) return nvme_get_log(fd, NVME_LOG_LID_TELEMETRY_HOST, NVME_NSID_NONE, offset, NVME_LOG_TELEM_HOST_LSP_RETAIN, NVME_LOG_LSI_NONE, false, NVME_UUID_NONE, - NVME_CSI_NVM, len, log, NVME_DEFAULT_IOCTL_TIMEOUT, - NULL); + NVME_CSI_NVM, false, len, log, + NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_get_log_telemetry_ctrl(int fd, bool rae, __u64 offset, __u32 len, @@ -718,7 +723,7 @@ int nvme_get_log_telemetry_ctrl(int fd, bool rae, __u64 offset, __u32 len, { return nvme_get_log(fd, NVME_LOG_LID_TELEMETRY_CTRL, NVME_NSID_NONE, offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, - NVME_UUID_NONE, NVME_CSI_NVM, len, log, + NVME_UUID_NONE, NVME_CSI_NVM, false, len, log, NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } @@ -728,7 +733,7 @@ int nvme_get_log_endurance_group(int fd, __u16 endgid, BUILD_ASSERT(sizeof(struct nvme_endurance_group_log) == 512); return nvme_get_log(fd, NVME_LOG_LID_ENDURANCE_GROUP, NVME_NSID_NONE, 0, NVME_LOG_LSP_NONE, endgid, false, NVME_UUID_NONE, - NVME_CSI_NVM, sizeof(*log), log, + NVME_CSI_NVM, false, sizeof(*log), log, NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } @@ -738,8 +743,9 @@ int nvme_get_log_predictable_lat_nvmset(int fd, __u16 nvmsetid, BUILD_ASSERT(sizeof(struct nvme_nvmset_predictable_lat_log) == 512); return nvme_get_log(fd, NVME_LOG_LID_PREDICTABLE_LAT_NVMSET, NVME_NSID_NONE, 0, NVME_LOG_LSP_NONE, nvmsetid, - false, NVME_UUID_NONE, NVME_CSI_NVM, sizeof(*log), - log, NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + false, NVME_UUID_NONE, NVME_CSI_NVM, false, + sizeof(*log),log, NVME_DEFAULT_IOCTL_TIMEOUT, + NULL); } int nvme_get_log_predictable_lat_event(int fd, bool rae, __u32 offset, @@ -748,7 +754,7 @@ int nvme_get_log_predictable_lat_event(int fd, bool rae, __u32 offset, return nvme_get_log(fd, NVME_LOG_LID_PREDICTABLE_LAT_AGG, NVME_NSID_NONE, offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, - NVME_CSI_NVM, len, log, + NVME_CSI_NVM, false, len, log, NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } @@ -757,8 +763,8 @@ int nvme_get_log_ana(int fd, enum nvme_log_ana_lsp lsp, bool rae, __u64 offset, { return nvme_get_log(fd, NVME_LOG_LID_ANA, NVME_NSID_NONE, offset, lsp, NVME_LOG_LSI_NONE, false, NVME_UUID_NONE, - NVME_CSI_NVM, len, log, NVME_DEFAULT_IOCTL_TIMEOUT, - NULL); + NVME_CSI_NVM, false, len, log, + NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_get_log_ana_groups(int fd, bool rae, __u32 len, @@ -773,7 +779,7 @@ int nvme_get_log_lba_status(int fd, bool rae, __u64 offset, __u32 len, { return nvme_get_log(fd, NVME_LOG_LID_LBA_STATUS, NVME_NSID_NONE, offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, - NVME_UUID_NONE, NVME_CSI_NVM, len, log, + NVME_UUID_NONE, NVME_CSI_NVM, false, len, log, NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } @@ -783,8 +789,8 @@ int nvme_get_log_endurance_grp_evt(int fd, bool rae, __u32 offset, __u32 len, return nvme_get_log(fd, NVME_LOG_LID_ENDURANCE_GRP_EVT, NVME_NSID_NONE, offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, - NVME_CSI_NVM, len, log, NVME_DEFAULT_IOCTL_TIMEOUT, - NULL); + NVME_CSI_NVM, false, len, log, + NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } int nvme_get_log_fid_supported_effects(int fd, bool rae, @@ -794,7 +800,7 @@ int nvme_get_log_fid_supported_effects(int fd, bool rae, return nvme_get_log(fd, NVME_LOG_LID_FID_SUPPORTED_EFFECTS, NVME_NSID_NONE, 0, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, - NVME_CSI_NVM, sizeof(*log), log, + NVME_CSI_NVM, false, sizeof(*log), log, NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } @@ -805,7 +811,7 @@ int nvme_get_log_boot_partition(int fd, bool rae, __u8 lsp, __u32 len, return nvme_get_log(fd, NVME_LOG_LID_BOOT_PARTITION, NVME_NSID_NONE, 0, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, - NVME_CSI_NVM, len, part, + NVME_CSI_NVM, false, len, part, NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } @@ -814,7 +820,7 @@ int nvme_get_log_discovery(int fd, bool rae, __u32 offset, __u32 len, void *log) { return nvme_get_log(fd, NVME_LOG_LID_DISCOVER, NVME_NSID_NONE, offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, - NVME_UUID_NONE, NVME_CSI_NVM, len, log, + NVME_UUID_NONE, NVME_CSI_NVM, false, len, log, NVME_DEFAULT_IOCTL_TIMEOUT, NULL); } @@ -847,8 +853,9 @@ int nvme_get_log_zns_changed_zones(int fd, __u32 nsid, bool rae, BUILD_ASSERT(sizeof(struct nvme_zns_changed_zone_log) == 4096); return nvme_get_log(fd, NVME_LOG_LID_ZNS_CHANGED_ZONES, nsid, 0, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, - NVME_UUID_NONE, NVME_CSI_ZNS, sizeof(*log), log, - NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + NVME_UUID_NONE, NVME_CSI_ZNS, false, + sizeof(*log), log, NVME_DEFAULT_IOCTL_TIMEOUT, + NULL); } int nvme_set_features(int fd, __u8 fid, __u32 nsid, __u32 cdw11, __u32 cdw12, diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index a44d405093..79db6a18a6 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -788,6 +788,13 @@ int nvme_zns_identify_ctrl(int fd, struct nvme_zns_id_ctrl *id); * @lsi: Endurance group information * @rae: Retain asynchronous events * @uuidx: UUID selection, if supported + * @csi: Command Set Identifier + * @ot: Offset Type. If set to false, the Log Page Offset Lower + * field and the Log Page Offset Upper field specify the + * byte offset into the log page to be returned. + * If set to true, the Log Page Offset Lower field and the + * Log Page Offset Upper field specify the index into the + * list of data structures in the log page to be returned. * @len: Length of provided user buffer to hold the log data in bytes * @log: User space destination address to transfer the data * @timeout: Timeout in ms @@ -798,13 +805,14 @@ int nvme_zns_identify_ctrl(int fd, struct nvme_zns_id_ctrl *id); */ int nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, __u8 lsp, __u16 lsi, bool rae, __u8 uuidx, enum nvme_csi csi, - __u32 len, void *log, __u32 timeout, __u32 *result); + bool ot, __u32 len, void *log, __u32 timeout, __u32 *result); static inline int nvme_get_nsid_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u32 len, void *log) { - return nvme_get_log(fd, lid, nsid, 0, 0, 0, false, 0, NVME_CSI_NVM, len, - log, NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + return nvme_get_log(fd, lid, nsid, 0, 0, 0, false, 0, NVME_CSI_NVM, + false, len, log, NVME_DEFAULT_IOCTL_TIMEOUT, + NULL); } static inline int nvme_get_log_simple(int fd, enum nvme_cmd_get_log_lid lid, diff --git a/src/nvme/linux.c b/src/nvme/linux.c index 47de1a01a8..fe4aad33d3 100644 --- a/src/nvme/linux.c +++ b/src/nvme/linux.c @@ -124,7 +124,7 @@ int __nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, ret = nvme_get_log(fd, log_id, nsid, offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, retain, NVME_UUID_NONE, - NVME_CSI_NVM, xfer, ptr, + NVME_CSI_NVM, false, xfer, ptr, NVME_DEFAULT_IOCTL_TIMEOUT, NULL); if (ret) return ret; From f90724e745e5cc3c92fc798dfc7b3e20891ac6b7 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Tue, 14 Dec 2021 02:37:21 +0900 Subject: [PATCH 0301/1564] types: Add Controller Metadata and Namespace Metadata Port and extent the libnvme part from the commit "Add NVMe MI Features: Controller Metadata (0x7E) and Namespace Metadata (0x7F)." from the nvme-cli monolithic branch. While at it add the missing definitions and add some documentation. This is based on Tokunori Ikegami first port attempt. Signed-off-by: Daniel Wagner --- src/nvme/types.h | 94 ++++++++++++++++++++++++++++++++++++++++++++++++ src/nvme/util.c | 4 +++ 2 files changed, 98 insertions(+) diff --git a/src/nvme/types.h b/src/nvme/types.h index a9cf415cfb..251ca68ad7 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -3547,6 +3547,96 @@ enum nvme_apst_entry { NVME_APST_ENTRY_ITPT_MASK = 0xffffff, }; +/** + * struct nvme_metadata_element_desc - Metadata Element Descriptor + * @type: Element Type (ET) + * @rev: Element Revision (ER) + * @len: Element Length (ELEN) + * @val: Element Value (EVAL), UTF-8 string + */ +struct nvme_metadata_element_desc { + __u8 type; + __u8 rev; + __u16 len; + __u8 val[0]; +}; + +/** + * struct nvme_host_metadata - Host Metadata Data Structure + * @ndesc: Number of metadata element descriptors + * @descs: Metadata element descriptors + */ +struct nvme_host_metadata { + __u8 ndesc; + __u8 rsvd1; + union { + struct nvme_metadata_element_desc descs[0]; + __u8 descs_buf[4094]; + }; +}; + +/** + * enum nvme_ctrl_metadata_type - Controller Metadata Element Types + * @NVME_CTRL_METADATA_OS_CTRL_NAME: Name of the controller in + * the operating system. + * @NVME_CTRL_METADATA_OS_DRIVER_NAME: Name of the driver in the + * operating system. + * @NVME_CTRL_METADATA_OS_DRIVER_VER: Version of the driver in + * the operating system. + * @NVME_CTRL_METADATA_PRE_BOOT_CTRL_NAME: Name of the controller in + * the pre-boot environment. + * @NVME_CTRL_METADATA_PRE_BOOT_DRIVER_NAME: Name of the driver in the + * pre-boot environment. + * @NVME_CTRL_METADATA_PRE_BOOT_DRIVER_VER: Version of the driver in the + * 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_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_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. + * @NVME_CTRL_METADATA_HOST_DET_FAIL_REC: Failure record. + */ +enum nvme_ctrl_metadata_type { + NVME_CTRL_METADATA_OS_CTRL_NAME = 0x01, + NVME_CTRL_METADATA_OS_DRIVER_NAME = 0x02, + NVME_CTRL_METADATA_OS_DRIVER_VER = 0x03, + NVME_CTRL_METADATA_PRE_BOOT_CTRL_NAME = 0x04, + NVME_CTRL_METADATA_PRE_BOOT_DRIVER_NAME = 0x05, + NVME_CTRL_METADATA_PRE_BOOT_DRIVER_VER = 0x06, + NVME_CTRL_METADATA_SYS_PROC_MODEL = 0x07, + NVME_CTRL_METADATA_CHIPSET_DRV_NAME = 0x08, + NVME_CTRL_METADATA_CHIPSET_DRV_VERSION = 0x09, + NVME_CTRL_METADATA_OS_NAME_AND_BUILD = 0x0a, + NVME_CTRL_METADATA_SYS_PROD_NAME = 0x0b, + NVME_CTRL_METADATA_FIRMWARE_VERSION = 0x0c, + NVME_CTRL_METADATA_OS_DRIVER_FILENAME = 0x0d, + NVME_CTRL_METADATA_DISPLAY_DRV_NAME = 0x0e, + NVME_CTRL_METADATA_DISPLAY_DRV_VERSION = 0x0f, + NVME_CTRL_METADATA_HOST_DET_FAIL_REC = 0x10, +}; + +/** + * enum nvme_ns_metadata_type - Namespace Metadata Element Types + * @NVME_NS_METADATA_OS_NS_NAME: Name of the namespace in the the + * operating system + * @NVME_NS_METADATA_PRE_BOOT_NS_NAME: Name of the namespace in the pre-boot + * environment. + * @NVME_NS_METADATA_OS_NS_QUAL_1: First qualifier of the Operating System + * Namespace Name. + * @NVME_NS_METADATA_OS_NS_QUAL_2: Second qualifier of the Operating System + * Namespace Name. + */ +enum nvme_ns_metadata_type { + NVME_NS_METADATA_OS_NS_NAME = 0x01, + NVME_NS_METADATA_PRE_BOOT_NS_NAME = 0x02, + NVME_NS_METADATA_OS_NS_QUAL_1 = 0x03, + NVME_NS_METADATA_OS_NS_QUAL_2 = 0x04, +}; + /** * struct nvme_timestamp - * timestamp: @@ -5268,6 +5358,8 @@ enum nvme_cmd_get_log_lid { * @NVME_FEAT_FID_ENDURANCE_EVT_CFG: * @NVME_FEAT_FID_IOCS_PROFILE: * @NVME_FEAT_FID_SPINUP_CONTROL: + * @NVME_FEAT_FID_CTRL_METADATA: Controller Metadata + * @NVME_FEAT_FID_NS_METADATA: Namespace Metadata * @NVME_FEAT_FID_SW_PROGRESS: * @NVME_FEAT_FID_HOST_ID: * @NVME_FEAT_FID_RESV_MASK: @@ -5301,6 +5393,8 @@ enum nvme_features_id { NVME_FEAT_FID_ENDURANCE_EVT_CFG = 0x18, NVME_FEAT_FID_IOCS_PROFILE = 0x19, /* XXX: Placeholder until assigned */ NVME_FEAT_FID_SPINUP_CONTROL = 0x1a, + NVME_FEAT_FID_CTRL_METADATA = 0x7e, + NVME_FEAT_FID_NS_METADATA = 0x7f, NVME_FEAT_FID_SW_PROGRESS = 0x80, NVME_FEAT_FID_HOST_ID = 0x81, NVME_FEAT_FID_RESV_MASK = 0x82, diff --git a/src/nvme/util.c b/src/nvme/util.c index b2a7b86bed..f8da8f3cfd 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -434,6 +434,10 @@ int nvme_get_feature_length(int fid, __u32 cdw11, __u32 *len) case NVME_FEAT_FID_WRITE_PROTECT: *len = 0; break; + case NVME_FEAT_FID_CTRL_METADATA: + case NVME_FEAT_FID_NS_METADATA: + *len = sizeof(struct nvme_host_metadata); + break; default: errno = EINVAL; return -1; From 3617eac2c56edb1115ee4257a3629901c290a154 Mon Sep 17 00:00:00 2001 From: Steven Seungcheol Lee Date: Thu, 16 Dec 2021 14:58:09 +0900 Subject: [PATCH 0302/1564] build: Add subpackages contents to .gitignore we just need to maintain .wrap files for dependencies Signed-off-by: Steven Seungcheol Lee --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index d52a35ac5b..384f25fe04 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,6 @@ config.log cscope.* .build + +subprojects +!subprojects/*.wrap From facee1b662b80b092c47ae94807cd827f3adcafe Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 21 Dec 2021 08:55:15 +0100 Subject: [PATCH 0303/1564] Decode TLS1.3 transport security Add the definition for TLS1.3 in the transport security attribute settings (tsas) field. Signed-off-by: Hannes Reinecke --- src/nvme/fabrics.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 9f0b005987..39b7c6c7ed 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -116,6 +116,7 @@ const char *nvmf_eflags_str(__u16 eflags) static const char * const sectypes[] = { [NVMF_TCP_SECTYPE_NONE] = "none", [NVMF_TCP_SECTYPE_TLS] = "tls", + [NVMF_TCP_SECTYPE_TLS13] = "tls13", }; const char *nvmf_sectype_str(__u8 sectype) From a71ba6136503f113c6781b7b4910873b72609c65 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Tue, 21 Dec 2021 15:56:14 +0100 Subject: [PATCH 0304/1564] fabrics: Declare loop index at the beginning of the block MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The gcc in Centos 6.10 complains with nvme/fabrics.c:909: error: ‘for’ loop initial declarations are only allowed in C99 mode nvme/fabrics.c:909: note: use option -std=c99 or -std=gnu99 to compileyour code Let's declare the index at the beginning of the basic block. Signed-off-by: Daniel Wagner --- src/nvme/fabrics.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 9f0b005987..1aaa94ca41 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -906,9 +906,12 @@ static int uuid_from_product_uuid(char *system_uuid) 20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35, -1 /* sentinel */ }; - for (unsigned int i = 0; swaptbl[i] != -1; i++) + int i; + + for (i = 0; swaptbl[i] != -1; i++) system_uuid[i] = line[swaptbl[i]]; system_uuid[UUID_SIZE-1] = '\0'; + ret = 0; } From 3b4a8b46b87358a09b0307fd1e042f385bc76ed0 Mon Sep 17 00:00:00 2001 From: Martin Belanger Date: Tue, 21 Dec 2021 15:36:38 -0500 Subject: [PATCH 0305/1564] Replacing make by meson. This involves replacing all Makefiles by meson.build files. Also the top-level configure script now simply invokes meson. The top-level Makefile is just a wrapper for meson. It supports the following operations: make make test make install make clean # Remove build artifacts but keep configuration make purge # Remove build artifacts and configuration Signed-off-by: Martin Belanger --- .github/workflows/make.yml | 35 ------ Makefile | 110 ++++++------------ Makefile.quiet | 10 -- configure | 230 ------------------------------------- doc/Makefile | 20 ---- examples/Makefile | 18 --- libnvme/Makefile | 20 ---- src/Makefile | 96 ---------------- test/Makefile | 32 ------ 9 files changed, 35 insertions(+), 536 deletions(-) delete mode 100644 .github/workflows/make.yml delete mode 100644 Makefile.quiet delete mode 100755 configure delete mode 100644 doc/Makefile delete mode 100644 examples/Makefile delete mode 100644 libnvme/Makefile delete mode 100644 src/Makefile delete mode 100644 test/Makefile diff --git a/.github/workflows/make.yml b/.github/workflows/make.yml deleted file mode 100644 index 92f803c41d..0000000000 --- a/.github/workflows/make.yml +++ /dev/null @@ -1,35 +0,0 @@ -# This is a basic workflow to help you get started with Actions - -name: libnvme CI - -# Controls when the workflow will run -on: - # Triggers the workflow on push or pull request events but only for the master branch - push: - branches: [ master ] - pull_request: - branches: [ master ] - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - # This workflow contains a single job called "build" - build: - # The type of runner that the job will run on - runs-on: ubuntu-latest - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 - - # Install required libraries - - name: install libraries - run: sudo apt-get install libjson-c-dev - - # Build library - - name: Build libnvme - run: make clean && make && make clean - diff --git a/Makefile b/Makefile index d416c2db9d..0f15d30d80 100644 --- a/Makefile +++ b/Makefile @@ -1,79 +1,39 @@ -NAME=libnvme -SPECFILE=$(NAME).spec -VERSION=$(shell awk '/Version:/ { print $$2 }' $(SPECFILE)) -TAG = $(NAME)-$(VERSION) -RPMBUILD=$(shell `which rpmbuild >&/dev/null` && echo "rpmbuild" || echo "rpm") - -INSTALL=install - -default: all - -python: all - @$(MAKE) -C libnvme python - -all: $(NAME).pc - @$(MAKE) -C src - @$(MAKE) -C test - @$(MAKE) -C examples - -runtests: all - @$(MAKE) -C test runtests -runtests-loop: - @$(MAKE) -C test runtests-loop - -config-host.mak: configure - @if [ ! -e "$@" ]; then \ - echo "Running configure ..."; \ - ./configure; \ - else \ - echo "$@ is out-of-date, running configure"; \ - sed -n "/.*Configured with/s/[^:]*: //p" "$@" | sh; \ - fi - -ifneq ($(MAKECMDGOALS),clean) -include config-host.mak -endif - -SED_PROCESS = \ - sed -e "s%@prefix@%$(prefix)%g" \ - -e "s%@libdir@%$(libdir)%g" \ - -e "s%@includedir@%$(includedir)%g" \ - -e "s%@NAME@%$(NAME)%g" \ - -e "s%@VERSION@%$(VERSION)%g" \ - $< >$@ - -%.pc: %.pc.in config-host.mak $(SPECFILE) - $(SED_PROCESS) - -install: $(NAME).pc - @$(MAKE) -C src install prefix=$(DESTDIR)$(prefix) includedir=$(DESTDIR)$(includedir) libdir=$(DESTDIR)$(libdir) - $(INSTALL) -D -m 644 $(NAME).pc $(DESTDIR)$(libdir)/pkgconfig/$(NAME).pc - $(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man2 - $(INSTALL) -m 644 doc/man/*.2 $(DESTDIR)$(mandir)/man2 - -install-tests: - @$(MAKE) -C test install prefix=$(DESTDIR)$(prefix) datadir=$(DESTDIR)$(datadir) - -install-python: - @$(MAKE) -C libnvme install prefix=$(DESTDIR)$(prefix) - +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# This file is part of libnvme. +# Copyright (c) 2021 Dell Inc. +# +# Authors: Martin Belanger +# +NAME := libnvme +.DEFAULT_GOAL := ${NAME} +BUILD-DIR := .build + +${BUILD-DIR}: + meson $@ + @echo "Configuration located in: $@" + @echo "-------------------------------------------------------" + +.PHONY: ${NAME} +${NAME}: ${BUILD-DIR} + ninja -C ${BUILD-DIR} + +.PHONY: clean clean: - @rm -f config-host.mak config-host.h cscope.out $(NAME).pc - @$(MAKE) -C src clean - @$(MAKE) -C test clean - @$(MAKE) -C examples clean - -cscope: - @cscope -b -R - -tag-archive: - @git tag $(TAG) +ifneq ("$(wildcard ${BUILD-DIR})","") + ninja -C ${BUILD-DIR} -t $@ +endif -create-archive: - @git archive --prefix=$(NAME)-$(VERSION)/ -o $(NAME)-$(VERSION).tar.gz $(TAG) - @echo "The final archive is ./$(NAME)-$(VERSION).tar.gz." +.PHONY: purge +purge: +ifneq ("$(wildcard ${BUILD-DIR})","") + rm -rf ${BUILD-DIR} +endif -archive: clean tag-archive create-archive +.PHONY: install dist +install dist: ${BUILD-DIR} + cd ${BUILD-DIR} && meson $@ -srpm: create-archive - $(RPMBUILD) --define "_sourcedir `pwd`" --define "_srcrpmdir `pwd`" --nodeps -bs $(SPECFILE) +.PHONY: test +test: ${BUILD-DIR} + ninja -C ${BUILD-DIR} $@ diff --git a/Makefile.quiet b/Makefile.quiet deleted file mode 100644 index 8eac349a84..0000000000 --- a/Makefile.quiet +++ /dev/null @@ -1,10 +0,0 @@ -ifneq ($(findstring $(MAKEFLAGS),s),s) -ifndef V - QUIET_CC = @echo ' ' CC $@; - QUIET_LINK = @echo ' ' LINK $@; - QUIET_AR = @echo ' ' AR $@; - QUIET_RANLIB = @echo '' RANLIB $@; -endif -endif - - diff --git a/configure b/configure deleted file mode 100755 index d67ed8e5e1..0000000000 --- a/configure +++ /dev/null @@ -1,230 +0,0 @@ -#!/bin/sh -# -# -if test ! -z "$TMPDIR" ; then - TMPDIR1="${TMPDIR}" -elif test ! -z "$TEMPDIR" ; then - TMPDIR1="${TEMPDIR}" -else - TMPDIR1="/tmp" -fi - -cc=gcc -ld=ld - -for opt do - optarg=$(expr "x$opt" : 'x[^=]*=\(.*\)') - case "$opt" in - --help|-h) show_help=yes - ;; - --prefix=*) prefix="$optarg" - ;; - --includedir=*) includedir="$optarg" - ;; - --libdir=*) libdir="$optarg" - ;; - --mandir=*) mandir="$optarg" - ;; - --datadir=*) datadir="$optarg" - ;; - --disable-uuid) disable_uuid=1 - ;; - --disable-json) disable_json=1 - ;; - *) - echo "ERROR: unkown option $opt" - echo "Try '$0 --help' for more information" - exit 1 - ;; - esac -done - -if test -z "$prefix"; then - prefix=/usr -fi -if test -z "$includedir"; then - includedir="$prefix/include" -fi -if test -z "$libdir"; then - libdir="$prefix/lib" -fi -if test -z "$mandir"; then - mandir="$prefix/man" -fi -if test -z "$datadir"; then - datadir="$prefix/share" -fi - -if test "$show_help" = "yes"; then -cat < $config_h < $config_host_mak <> config.log - $cc "$@" >> config.log 2>&1 || return $? - # Test passed. If this is an --enable-werror build, rerun - # the test with -Werror and bail out if it fails. This - # makes warning-generating-errors in configure test code - # obvious to developers. - if test "$werror" != "yes"; then - return 0 - fi - # Don't bother rerunning the compile if we were already using -Werror - case "$*" in - *-Werror*) - return 0 - ;; - esac - echo $cc -Werror "$@" >> config.log - $cc -Werror "$@" >> config.log 2>&1 && return $? - echo "ERROR: configure test passed without -Werror but failed with -Werror." - echo "This is probably a bug in the configure script. The failing command" - echo "will be at the bottom of config.log." - fatal "You can run configure with --disable-werror to bypass this check." -} - -compile_object() { - do_cc $CFLAGS -c -o $TMPO $TMPC -} - -compile_prog() { - local_cflags="$1" - local_ldflags="$2 $LIBS" - echo "Compiling test case $3" >> config.log - do_cc $CFLAGS $local_cflags -o $TMPE $TMPC $LDFLAGS $local_ldflags -} - -feature_not_found() { - feature=$1 - packages=$2 - - echo "" - echo "ERROR: $feature package requirements not met" - if test ! -z "$packages" ; then - echo "ERROR: needs $packages installed" - fi - fatal "" -} - -has() { - type "$1" >/dev/null 2>&1 -} - -output_mak() { - echo "$1=$2" >> $config_host_mak -} - -output_sym() { - output_mak "$1" "y" - echo "#define $1" >> $config_h -} - -print_and_output_mak() { - print_config "$1" "$2" - output_mak "$1" "$2" -} - -print_and_output_mak "prefix" "$prefix" -print_and_output_mak "includedir" "$includedir" -print_and_output_mak "libdir" "$libdir" -print_and_output_mak "mandir" "$mandir" -print_and_output_mak "datadir" "$datadir" - -########################################## -# check for libuuid -libuuid="no" -if [ -z "$disable_uuid" ] ; then - ${ld} -o /dev/null -luuid >/dev/null 2>&1 - if [ $? -eq 0 ]; then - libuuid="yes" - fi -fi -print_config "libuuid" "${libuuid}" - -########################################## -# check for libjson-c -libjsonc="no" -if [ -z "$disable_json" ] ; then - if pkg-config --atleast-version=0.13 json-c; then - libjsonc="yes" - fi -fi -print_config "libjson-c" "${libjsonc}" - -########################################## -# check for c++ -cpp="no" -which g++ > /dev/null 2> /dev/null -if [ $? -eq 0 ]; then - cpp="yes" -fi -print_config "cpp" "${cpp}" - - -if test "$libuuid" = "yes"; then - output_sym "CONFIG_LIBUUID" - echo "override LIBS += -luuid" >> $config_host_mak - echo "override LIB_DEPENDS += uuid" >> $config_host_mak -fi -if test "$libjsonc" = "yes"; then - output_sym "CONFIG_JSONC" - echo "override LIBS += -ljson-c" >> $config_host_mak - echo "override LIB_DEPENDS += json-c" >> $config_host_mak -fi -if test "$cpp" = "yes"; then - output_mak "CONFIG_CPLUSPLUS" "y" -fi diff --git a/doc/Makefile b/doc/Makefile deleted file mode 100644 index d4bb2cbb9e..0000000000 --- a/doc/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line, and also -# from the environment for the first two. -SPHINXOPTS ?= -SPHINXBUILD ?= sphinx-build -SOURCEDIR = . -BUILDDIR = _build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/examples/Makefile b/examples/Makefile deleted file mode 100644 index 4916494dd4..0000000000 --- a/examples/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -CFLAGS ?= -g -O2 -override CFLAGS += -Wall -D_GNU_SOURCE -I .. -I ../src -L ../src -I../ccan --include "config.h" - -include ../Makefile.quiet - -ifneq ($(MAKECMDGOALS),clean) -include ../config-host.mak -endif - -all_targets += telemetry-listen display-tree display-columnar discover-loop - -all: $(all_targets) - -%: %.c ../src/libnvme.a - $(QUIET_CC)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lnvme $(LIBS) - -clean: - rm -f $(all_targets) diff --git a/libnvme/Makefile b/libnvme/Makefile deleted file mode 100644 index 5f2640738a..0000000000 --- a/libnvme/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -.DEFAULT_GOAL := python - -SWIG ?= swig -PYTHON ?= python3 - -prefix ?= /usr - -nvme_swig := nvme.i - -nvme_wrap.c: $(nvme_swig) - $(SWIG) -python -py3 -outdir . $< - -python: nvme_wrap.c setup.py - $(PYTHON) setup.py build - -install: - $(PYTHON) setup.py install --prefix=$(prefix) - -clean: - rm -rf nvme_wrap.c nvme.py build diff --git a/src/Makefile b/src/Makefile deleted file mode 100644 index 4af6551af1..0000000000 --- a/src/Makefile +++ /dev/null @@ -1,96 +0,0 @@ -NAME=libnvme -SPECFILE=$(NAME).spec -VERSION=$(shell awk '/Version:/ { print $$2 }' $(SPECFILE)) - -ifneq ($(MAKECMDGOALS),clean) -include ../config-host.mak -endif - -prefix ?= /usr -includedir ?= $(prefix)/include -libdir ?= $(prefix)/lib - -CCANDIR=../ccan/ - -CFLAGS ?= -g -fomit-frame-pointer -O2 -I/usr/include -Invme/ -I$(CCANDIR) -I.. -include ../config.h -D_GNU_SOURCE -override CFLAGS += -Wall -fPIC -SO_CFLAGS=-shared $(CFLAGS) -L_CFLAGS=$(CFLAGS) -LINK_FLAGS= -L /usr/lib64 -LINK_FLAGS+=$(LDFLAGS) -ENABLE_SHARED ?= 1 -SED ?= sed -INSTALL ?= install - -soname=$(NAME).so.1 -minor=0 -micro=1 -libname=$(soname).$(minor).$(micro) -all_targets += $(NAME).a - -ifeq ($(ENABLE_SHARED),1) -all_targets += $(libname) -endif - -include ../Makefile.quiet - -all: $(all_targets) - -$(CCANDIR)ccan-config.h: $(CCANDIR)tools/configurator/configurator - $< > $@ -$(CCANDIR)tools/configurator/configurator: CFLAGS = -D_GNU_SOURCE - -libccan_headers := $(wildcard $(CCANDIR)ccan/*/*.h) -libccan_srcs := $(wildcard $(CCANDIR)ccan/*/*.c) -libccan_objs := $(patsubst %.c,%.ol,$(libccan_srcs)) -libccan_sobjs := $(patsubst %.c,%.os,$(libccan_srcs)) - -$(libccan_objs) $(libccan_sobjs): $(libccan_headers) $(CCANDIR)ccan-config.h - -libnvme_priv := nvme/private.h -libnvme_api := libnvme.h nvme/types.h nvme/linux.h nvme/ioctl.h nvme/filters.h nvme/tree.h nvme/util.h nvme/fabrics.h nvme/log.h -libnvme_srcs := nvme/linux.c nvme/ioctl.c nvme/filters.c nvme/fabrics.c nvme/util.c nvme/tree.c nvme/log.c nvme/cleanup.c -ifeq ($(CONFIG_JSONC),y) -override LDFLAGS += $(shell pkg-config --libs json-c) -override CFLAGS += $(shell pkg-config --cflags json-c) -override libnvme_srcs += nvme/json.c -endif -libnvme_objs := $(patsubst %.c,%.ol,$(libnvme_srcs)) -libnvme_sobjs := $(patsubst %.c,%.os,$(libnvme_srcs)) - -$(libnvme_objs) $(libnvme_sobjs): $(libnvme_api) $(libnvme_priv) $(libccan_objs) - -%.os: %.c - $(QUIET_CC)$(CC) $(SO_CFLAGS) -c -o $@ $< - -%.ol: %.c - $(QUIET_CC)$(CC) $(L_CFLAGS) -c -o $@ $< - -AR ?= ar -RANLIB ?= ranlib - -libnvme.a: $(libnvme_objs) $(libccan_objs) - @rm -f libnvme.a - $(QUIET_AR)$(AR) r libnvme.a $^ - $(QUIET_RANLIB)$(RANLIB) libnvme.a - -$(libname): $(libnvme_sobjs) $(libccan_sobjs) libnvme.map - $(QUIET_CC)$(CC) $(SO_CFLAGS) -Wl,--version-script=libnvme.map -Wl,-soname=$(soname) -o $@ $(libnvme_sobjs) $(libccan_sobjs) $(LINK_FLAGS) $(LIBS) - -install: $(all_targets) - $(INSTALL) -D -m 644 libnvme.a $(libdir)/libnvme.a - for i in $(libnvme_api); do $(INSTALL) -D -m 644 $$i $(includedir)/$$i; done -ifeq ($(ENABLE_SHARED),1) - $(INSTALL) -D -m 755 $(libname) $(libdir)/$(libname) - ln -sf $(libname) $(libdir)/$(soname) - ln -sf $(libname) $(libdir)/libnvme.so -endif - -$(libnvme_objs): $(libnvme_api) $(libnvme_private) -$(libccan_objs): $(libccan_headers) $(CCANDIR)ccan-config.h - -clean: - rm -f $(all_targets) $(libnvme_objs) $(libnvme_sobjs) $(libccan_objs) $(libccan_sobjs) $(soname).new - rm -f $(CCANDIR)ccan-config.h - rm -f $(CCANDIR)tools/configurator/configurator - rm -f *.so* *.a *.o diff --git a/test/Makefile b/test/Makefile deleted file mode 100644 index 90e89e0b08..0000000000 --- a/test/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -CFLAGS ?= -g -O2 -override CFLAGS += -Wall -D_GNU_SOURCE -L../src/ -I .. -I../src/ -I../ccan --include "config.h" - -include ../Makefile.quiet - -ifneq ($(MAKECMDGOALS),clean) -include ../config-host.mak -else -CONFIG_CPLUSPLUS=y -endif - -c_targets += test register zns - -ifdef CONFIG_CPLUSPLUS -cpp_targets += cpp -else -cpp_targets += -endif - -all_targets += $(c_targets) $(cpp_targets) -all: $(all_targets) - -CXXFLAGS ?= -lstdc++ - -%: %.cc ../src/libnvme.a - $(QUIET_CC)$(CXX) $(CFLAGS) $(LDFLAGS) $(CXXFLAGS) -o $@ $< -lnvme $(LIBS) - -%: %.c ../src/libnvme.a - $(QUIET_CC)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lnvme $(LIBS) - -clean: - rm -f $(all_targets) From 3d04b2c45c09a9206f0c2749102d97fc2d42204f Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Wed, 22 Dec 2021 08:34:03 +0100 Subject: [PATCH 0306/1564] util: Define inline function as static inline The gcc in Centos 6.10 complains with src/nvme/util.h:120: multiple definition of `nvme_feature_decode_arbitration' 'inline' alone does not guarantee that the function gets inlined. The compiler is still free to decide, thus in this case it doesn't inline and that's why we having multiple implementation with the same name (in different compile units). 'static inline' forces the inline which was the indent of this code. Signed-off-by: Daniel Wagner --- src/nvme/util.h | 85 +++++++++++++++++++++++++++++++------------------ 1 file changed, 54 insertions(+), 31 deletions(-) diff --git a/src/nvme/util.h b/src/nvme/util.h index 801189558a..d55307fa81 100644 --- a/src/nvme/util.h +++ b/src/nvme/util.h @@ -114,8 +114,9 @@ int nvme_get_directive_receive_length(enum nvme_directive_dtype dtype, #define NVME_FEAT_ARB_MPW(v) NVME_GET(v, FEAT_ARBITRATION_MPW) #define NVME_FEAT_ARB_HPW(v) NVME_GET(v, FEAT_ARBITRATION_HPW) -inline void nvme_feature_decode_arbitration(__u32 value, __u8 *ab, __u8 *lpw, - __u8 *mpw, __u8 *hpw) +static inline void nvme_feature_decode_arbitration(__u32 value, __u8 *ab, + __u8 *lpw, __u8 *mpw, + __u8 *hpw) { *ab = NVME_FEAT_ARB_BURST(value); *lpw = NVME_FEAT_ARB_LPW(value); @@ -126,7 +127,8 @@ inline void nvme_feature_decode_arbitration(__u32 value, __u8 *ab, __u8 *lpw, #define NVME_FEAT_PM_PS(v) NVME_GET(v, FEAT_PWRMGMT_PS) #define NVME_FEAT_PM_WH(v) NVME_GET(v, FEAT_PWRMGMT_WH) -inline void nvme_feature_decode_power_mgmt(__u32 value, __u8 *ps, __u8 *wh) +static inline void nvme_feature_decode_power_mgmt(__u32 value, __u8 *ps, + __u8 *wh) { *ps = NVME_FEAT_PM_PS(value); *wh = NVME_FEAT_PM_WH(value); @@ -134,7 +136,7 @@ inline void nvme_feature_decode_power_mgmt(__u32 value, __u8 *ps, __u8 *wh) #define NVME_FEAT_LBAR_NR(v) NVME_GET(v, FEAT_LBAR_NR) -inline void nvme_feature_decode_lba_range(__u32 value, __u8 *num) +static inline void nvme_feature_decode_lba_range(__u32 value, __u8 *num) { *num = NVME_FEAT_LBAR_NR(value); } @@ -143,8 +145,8 @@ inline void nvme_feature_decode_lba_range(__u32 value, __u8 *num) #define NVME_FEAT_TT_TMPSEL(v) NVME_GET(v, FEAT_TT_TMPSEL) #define NVME_FEAT_TT_THSEL(v) NVME_GET(v, FEAT_TT_THSEL) -inline void nvme_feature_decode_temp_threshold(__u32 value, __u16 *tmpth, - __u8 *tmpsel, __u8 *thsel) +static inline void nvme_feature_decode_temp_threshold(__u32 value, __u16 *tmpth, + __u8 *tmpsel, __u8 *thsel) { *tmpth = NVME_FEAT_TT_TMPTH(value); *tmpsel = NVME_FEAT_TT_TMPSEL(value); @@ -154,7 +156,8 @@ inline void nvme_feature_decode_temp_threshold(__u32 value, __u16 *tmpth, #define NVME_FEAT_ER_TLER(v) NVME_GET(v, FEAT_ERROR_RECOVERY_TLER) #define NVME_FEAT_ER_DULBE(v) NVME_GET(v, FEAT_ERROR_RECOVERY_DULBE) -inline void nvme_feature_decode_error_recovery(__u32 value, __u16 *tler, bool *dulbe) +static inline void nvme_feature_decode_error_recovery(__u32 value, __u16 *tler, + bool *dulbe) { *tler = NVME_FEAT_ER_TLER(value); *dulbe = NVME_FEAT_ER_DULBE(value); @@ -162,7 +165,8 @@ inline void nvme_feature_decode_error_recovery(__u32 value, __u16 *tler, bool *d #define NVME_FEAT_VWC_WCE(v) NVME_GET(v, FEAT_VWC_WCE) -inline void nvme_feature_decode_volatile_write_cache(__u32 value, bool *wce) +static inline void nvme_feature_decode_volatile_write_cache(__u32 value, + bool *wce) { *wce = NVME_FEAT_VWC_WCE(value); } @@ -170,7 +174,9 @@ inline void nvme_feature_decode_volatile_write_cache(__u32 value, bool *wce) #define NVME_FEAT_NRQS_NSQR(v) NVME_GET(v, FEAT_NRQS_NSQR) #define NVME_FEAT_NRQS_NCQR(v) NVME_GET(v, FEAT_NRQS_NCQR) -inline void nvme_feature_decode_number_of_queues(__u32 value, __u16 *nsqr, __u16 *ncqr) +static inline void nvme_feature_decode_number_of_queues(__u32 value, + __u16 *nsqr, + __u16 *ncqr) { *nsqr = NVME_FEAT_NRQS_NSQR(value); *ncqr = NVME_FEAT_NRQS_NCQR(value); @@ -179,7 +185,9 @@ inline void nvme_feature_decode_number_of_queues(__u32 value, __u16 *nsqr, __u16 #define NVME_FEAT_IRQC_THR(v) NVME_GET(v, FEAT_IRQC_THR) #define NVME_FEAT_IRQC_TIME(v) NVME_GET(v, FEAT_IRQC_TIME) -inline void nvme_feature_decode_interrupt_coalescing(__u32 value, __u8 *thr, __u8 *time) +static inline void nvme_feature_decode_interrupt_coalescing(__u32 value, + __u8 *thr, + __u8 *time) { *thr = NVME_FEAT_IRQC_THR(value); *time = NVME_FEAT_IRQC_TIME(value); @@ -188,7 +196,8 @@ inline void nvme_feature_decode_interrupt_coalescing(__u32 value, __u8 *thr, __u #define NVME_FEAT_ICFG_IV(v) NVME_GET(v, FEAT_ICFG_IV) #define NVME_FEAT_ICFG_CD(v) NVME_GET(v, FEAT_ICFG_CD) -inline void nvme_feature_decode_interrupt_config(__u32 value, __u16 *iv, bool *cd) +static inline void nvme_feature_decode_interrupt_config(__u32 value, __u16 *iv, + bool *cd) { *iv = NVME_FEAT_ICFG_IV(value); *cd = NVME_FEAT_ICFG_CD(value); @@ -196,7 +205,7 @@ inline void nvme_feature_decode_interrupt_config(__u32 value, __u16 *iv, bool *c #define NVME_FEAT_WA_DN(v) NVME_GET(v, FEAT_WA_DN) -inline void nvme_feature_decode_write_atomicity(__u32 value, bool *dn) +static inline void nvme_feature_decode_write_atomicity(__u32 value, bool *dn) { *dn = NVME_FEAT_WA_DN(value); } @@ -210,9 +219,9 @@ inline void nvme_feature_decode_write_atomicity(__u32 value, bool *dn) #define NVME_FEAT_AE_LBAS(v) NVME_GET(v, FEAT_AE_LBAS) #define NVME_FEAT_AE_EGA(v) NVME_GET(v, FEAT_AE_EGA) -inline void nvme_feature_decode_async_event_config(__u32 value, __u8 *smart, - bool *nan, bool *fw, bool *telem, bool *ana, bool *pla, bool *lbas, - bool *ega) +static inline void nvme_feature_decode_async_event_config(__u32 value, + __u8 *smart, bool *nan, bool *fw, bool *telem, + bool *ana, bool *pla, bool *lbas, bool *ega) { *smart = NVME_FEAT_AE_SMART(value); *nan = NVME_FEAT_AE_NAN(value); @@ -226,14 +235,15 @@ inline void nvme_feature_decode_async_event_config(__u32 value, __u8 *smart, #define NVME_FEAT_APST_APSTE(v) NVME_GET(v, FEAT_APST_APSTE) -inline void nvme_feature_decode_auto_power_state(__u32 value, bool *apste) +static inline void nvme_feature_decode_auto_power_state(__u32 value, + bool *apste) { *apste = NVME_FEAT_APST_APSTE(value); } #define NVME_FEAT_HMEM_EHM(v) NVME_GET(v, FEAT_HMEM_EHM) -inline void nvme_feature_decode_host_memory_buffer(__u32 value, bool *ehm) +static inline void nvme_feature_decode_host_memory_buffer(__u32 value, bool *ehm) { *ehm = NVME_FEAT_HMEM_EHM(value); } @@ -241,7 +251,9 @@ inline void nvme_feature_decode_host_memory_buffer(__u32 value, bool *ehm) #define NVME_FEAT_HCTM_TMT2(v) NVME_GET(v, FEAT_HCTM_TMT2) #define NVME_FEAT_HCTM_TMT1(v) NVME_GET(v, FEAT_HCTM_TMT1) -inline void nvme_feature_decode_host_thermal_mgmt(__u32 value, __u16 *tmt2, __u16 *tmt1) +static inline void nvme_feature_decode_host_thermal_mgmt(__u32 value, + __u16 *tmt2, + __u16 *tmt1) { *tmt2 = NVME_FEAT_HCTM_TMT2(value); *tmt1 = NVME_FEAT_HCTM_TMT1(value); @@ -249,28 +261,32 @@ inline void nvme_feature_decode_host_thermal_mgmt(__u32 value, __u16 *tmt2, __u1 #define NVME_FEAT_NOPS_NOPPME(v) NVME_GET(v, FEAT_NOPS_NOPPME) -inline void nvme_feature_decode_non_op_power_config(__u32 value, bool *noppme) +static inline void nvme_feature_decode_non_op_power_config(__u32 value, + bool *noppme) { *noppme = NVME_FEAT_NOPS_NOPPME(value); } #define NVME_FEAT_RRL_RRL(v) NVME_GET(v, FEAT_RRL_RRL) -inline void nvme_feature_decode_read_recovery_level_config(__u32 value, __u8 *rrl) +static inline void nvme_feature_decode_read_recovery_level_config(__u32 value, + __u8 *rrl) { *rrl = NVME_FEAT_RRL_RRL(value); } #define NVME_FEAT_PLM_PLME(v) NVME_GET(v, FEAT_PLM_PLME) -inline void nvme_feature_decode_predictable_latency_mode_config(__u32 value, bool *plme) +static inline void nvme_feature_decode_predictable_latency_mode_config(__u32 value, + bool *plme) { *plme = NVME_FEAT_PLM_PLME(value); } #define NVME_FEAT_PLMW_WS(v) NVME_GET(v, FEAT_PLMW_WS) -inline void nvme_feature_decode_predictable_latency_mode_window(__u32 value, __u8 *ws) +static inline void nvme_feature_decode_predictable_latency_mode_window(__u32 value, + __u8 *ws) { *ws = NVME_FEAT_PLMW_WS(value); } @@ -278,7 +294,9 @@ inline void nvme_feature_decode_predictable_latency_mode_window(__u32 value, __u #define NVME_FEAT_LBAS_LSIRI(v) NVME_GET(v, FEAT_LBAS_LSIRI) #define NVME_FEAT_LBAS_LSIPI(v) NVME_GET(v, FEAT_LBAS_LSIPI) -inline void nvme_feature_decode_lba_status_attributes(__u32 value, __u16 *lsiri, __u16 *lsipi) +static inline void nvme_feature_decode_lba_status_attributes(__u32 value, + __u16 *lsiri, + __u16 *lsipi) { *lsiri = NVME_FEAT_LBAS_LSIRI(value); *lsipi = NVME_FEAT_LBAS_LSIPI(value); @@ -286,7 +304,7 @@ inline void nvme_feature_decode_lba_status_attributes(__u32 value, __u16 *lsiri, #define NVME_FEAT_SC_NODRM(v) NVME_GET(v, FEAT_SC_NODRM) -inline void nvme_feature_decode_sanitize_config(__u32 value, bool *nodrm) +static inline void nvme_feature_decode_sanitize_config(__u32 value, bool *nodrm) { *nodrm = NVME_FEAT_SC_NODRM(value); } @@ -294,7 +312,7 @@ inline void nvme_feature_decode_sanitize_config(__u32 value, bool *nodrm) #define NVME_FEAT_EG_ENDGID(v) NVME_GET(v, FEAT_EG_ENDGID) #define NVME_FEAT_EG_EGCW(v) NVME_GET(v, FEAT_EG_EGCW) -inline void nvme_feature_decode_endurance_group_event_config(__u32 value, +static inline void nvme_feature_decode_endurance_group_event_config(__u32 value, __u16 *endgid, __u8 *endgcw) { *endgid = NVME_FEAT_EG_ENDGID(value); @@ -303,14 +321,15 @@ inline void nvme_feature_decode_endurance_group_event_config(__u32 value, #define NVME_FEAT_SPM_PBSLC(v) NVME_GET(v, FEAT_SPM_PBSLC) -inline void nvme_feature_decode_software_progress_marker(__u32 value, __u8 *pbslc) +static inline void nvme_feature_decode_software_progress_marker(__u32 value, + __u8 *pbslc) { *pbslc = NVME_FEAT_SPM_PBSLC(value); } #define NVME_FEAT_HOSTID_EXHID(v) NVME_GET(v, FEAT_HOSTID_EXHID) -inline void nvme_feature_decode_host_identifier(__u32 value, bool *exhid) +static inline void nvme_feature_decode_host_identifier(__u32 value, bool *exhid) { *exhid = NVME_FEAT_HOSTID_EXHID(value); } @@ -319,8 +338,10 @@ inline void nvme_feature_decode_host_identifier(__u32 value, bool *exhid) #define NVME_FEAT_RM_RESREL(v) NVME_GET(v, FEAT_RM_RESREL) #define NVME_FEAT_RM_RESPRE(v) NVME_GET(v, FEAT_RM_RESPRE) -inline void nvme_feature_decode_reservation_notification(__u32 value, bool *regpre, - bool *resrel, bool *respre) +static inline void nvme_feature_decode_reservation_notification(__u32 value, + bool *regpre, + bool *resrel, + bool *respre) { *regpre = NVME_FEAT_RM_REGPRE(value); *resrel = NVME_FEAT_RM_RESREL(value); @@ -329,14 +350,16 @@ inline void nvme_feature_decode_reservation_notification(__u32 value, bool *regp #define NVME_FEAT_RP_PTPL(v) NVME_GET(v, FEAT_RP_PTPL) -inline void nvme_feature_decode_reservation_persistance(__u32 value, bool *ptpl) +static inline void nvme_feature_decode_reservation_persistance(__u32 value, + bool *ptpl) { *ptpl = NVME_FEAT_RP_PTPL(value); } #define NVME_FEAT_WP_WPS(v) NVME_GET(v, FEAT_WP_WPS) -inline void nvme_feature_decode_namespace_write_protect(__u32 value, __u8 *wps) +static inline void nvme_feature_decode_namespace_write_protect(__u32 value, + __u8 *wps) { *wps = NVME_FEAT_WP_WPS(value); } From 704a17f74209fbc054cd4415adb179c1637dbc5c Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 23 Dec 2021 15:03:49 +0100 Subject: [PATCH 0307/1564] lib: Resort libnvme.map Signed-off-by: Daniel Wagner --- src/libnvme.map | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libnvme.map b/src/libnvme.map index 7f2b35d1e1..ac920f1565 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -190,6 +190,7 @@ LIBNVME_1_0 { nvme_ns_get_eui64; nvme_ns_get_fd; nvme_ns_get_firmware; + nvme_ns_get_generic_name; nvme_ns_get_lba_count; nvme_ns_get_lba_size; nvme_ns_get_lba_util; @@ -197,7 +198,6 @@ LIBNVME_1_0 { nvme_ns_get_model; nvme_ns_get_model; nvme_ns_get_name; - nvme_ns_get_generic_name; nvme_ns_get_nguid; nvme_ns_get_nsid; nvme_ns_get_serial; @@ -289,8 +289,8 @@ LIBNVME_1_0 { nvme_subsystem_get_host; nvme_subsystem_get_name; nvme_subsystem_get_nqn; - nvme_subsystem_get_type; nvme_subsystem_get_sysfs_dir; + nvme_subsystem_get_type; nvme_subsystem_lookup_namespace; nvme_subsystem_next_ctrl; nvme_subsystem_next_ns; @@ -315,6 +315,7 @@ LIBNVME_1_0 { nvmf_cms_str; nvmf_connect_disc_entry; nvmf_default_config; + nvmf_eflags_str; nvmf_get_discovery_log; nvmf_hostid_from_file; nvmf_hostnqn_from_file; @@ -325,7 +326,6 @@ LIBNVME_1_0 { nvmf_subtype_str; nvmf_treq_str; nvmf_trtype_str; - nvmf_eflags_str; local: *; }; From 809e00bc485703038ef984f2fc9fe3589a5ff6e6 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 23 Dec 2021 16:38:04 +0100 Subject: [PATCH 0308/1564] build: Avoid including wrong config.h as subpackage In case the consuming project also uses a config.h we need to hide our config.h file. By using the path to our config.h we avoid this confusion. Obviously, 'src' is a bit too generic, thus move the generated config.h under libnvme. Introduce also a private include path because ccan has '#include "config.h"' in its sources. So we need to present a config.h in the lookup path but it needs to be the one from this project and not the one from the consuming project. Signed-off-by: Daniel Wagner --- examples/meson.build | 9 ++++++--- libnvme/meson.build | 4 ++++ meson.build | 5 +++-- src/meson.build | 7 +------ test/meson.build | 8 ++++---- 5 files changed, 18 insertions(+), 15 deletions(-) diff --git a/examples/meson.build b/examples/meson.build index 0bf911d597..92e05a9a55 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -9,17 +9,20 @@ executable( 'telemetry-listen', ['telemetry-listen.c'], link_with: libnvme, - include_directories: incdir) + include_directories: [incdir, internal_incdir] +) executable( 'display-columnar', ['display-columnar.c'], link_with: libnvme, - include_directories: incdir) + include_directories: [incdir, internal_incdir] +) executable( 'discover-loop', ['discover-loop.c'], link_with: libnvme, - include_directories: incdir) + include_directories: [incdir, internal_incdir] +) diff --git a/libnvme/meson.build b/libnvme/meson.build index b8eda4c8dd..4e0f98472c 100644 --- a/libnvme/meson.build +++ b/libnvme/meson.build @@ -5,6 +5,10 @@ # # Authors: Martin Belanger # +configure_file( + output: 'config.h', + configuration: conf +) want_python = get_option('python') if want_python != 'false' diff --git a/meson.build b/meson.build index 25c80747db..919fd50f7a 100644 --- a/meson.build +++ b/meson.build @@ -133,8 +133,9 @@ configure_file( ################################################################################ add_project_arguments(['-fomit-frame-pointer', '-D_GNU_SOURCE', - '-include', 'config.h'], language : 'c') -incdir = include_directories(['ccan', 'src']) + '-include', 'libnvme/config.h'], language : 'c') +incdir = include_directories(['.', 'ccan', 'src']) +internal_incdir = include_directories('libnvme') ################################################################################ sources = [] diff --git a/src/meson.build b/src/meson.build index 27246f3f14..15a45b2f6c 100644 --- a/src/meson.build +++ b/src/meson.build @@ -5,11 +5,6 @@ # # Authors: Martin Belanger # -configure_file( - output: 'config.h', - configuration: conf -) - sources += [ 'nvme/cleanup.c', 'nvme/fabrics.c', @@ -41,7 +36,7 @@ libnvme = library( link_args: ['-Wl,--version-script=' + version_script_arg], dependencies: deps, link_depends: mapfile, - include_directories: incdir, + include_directories: [incdir, internal_incdir], install: true, ) diff --git a/test/meson.build b/test/meson.build index e89d877831..224e8b9534 100644 --- a/test/meson.build +++ b/test/meson.build @@ -10,28 +10,28 @@ main = executable( ['test.c'], dependencies: libuuid, link_with: libnvme, - include_directories: incdir + include_directories: [incdir, internal_incdir] ) cpp = executable( 'test-cpp', ['cpp.cc'], link_with: libnvme, - include_directories: incdir + include_directories: [incdir, internal_incdir] ) register = executable( 'test-register', ['register.c'], link_with: libnvme, - include_directories: incdir + include_directories: [incdir, internal_incdir] ) zns = executable( 'test-zns', ['zns.c'], link_with: libnvme, - include_directories: incdir + include_directories: [incdir, internal_incdir] ) test('main', main) From 8ebfcfe544f561db875604a053957123208a0084 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 23 Dec 2021 14:51:35 +0100 Subject: [PATCH 0309/1564] build: Use _dep postfix for all dependency objects Use consistently _dep postfix for all dependency objects. Signed-off-by: Daniel Wagner --- meson.build | 8 ++++---- src/meson.build | 4 ++-- test/meson.build | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/meson.build b/meson.build index 919fd50f7a..37d21ec4b1 100644 --- a/meson.build +++ b/meson.build @@ -34,12 +34,12 @@ pkgconfiglibdir = get_option('pkgconfiglibdir') == '' ? join_paths(libdir, 'pkgc conf = configuration_data() # Check for libuuid availability -libuuid = dependency('uuid', required: true) -conf.set('CONFIG_LIBUUID', libuuid.found(), description: 'Is libuuid required?') +libuuid_dep = dependency('uuid', required: true) +conf.set('CONFIG_LIBUUID', libuuid_dep.found(), description: 'Is libuuid required?') # Check for json-c availability -json_c = dependency('json-c', version: '>=0.13', fallback : ['json-c', 'json_c_dep']) -conf.set('CONFIG_JSONC', json_c.found(), description: 'Is json-c required?') +json_c_dep = dependency('json-c', version: '>=0.13', fallback : ['json-c', 'json_c_dep']) +conf.set('CONFIG_JSONC', json_c_dep.found(), description: 'Is json-c required?') # local (cross-compilable) implementations of ccan configure steps conf.set10( diff --git a/src/meson.build b/src/meson.build index 15a45b2f6c..d69e865e86 100644 --- a/src/meson.build +++ b/src/meson.build @@ -21,8 +21,8 @@ if conf.get('CONFIG_JSONC') endif deps = [ - libuuid, - json_c, + libuuid_dep, + json_c_dep, ] source_dir = meson.current_source_dir() diff --git a/test/meson.build b/test/meson.build index 224e8b9534..59cf547aa5 100644 --- a/test/meson.build +++ b/test/meson.build @@ -8,7 +8,7 @@ main = executable( 'main-test', ['test.c'], - dependencies: libuuid, + dependencies: libuuid_dep, link_with: libnvme, include_directories: [incdir, internal_incdir] ) From efe2585a3052111dd84d8586b1ac73ac64e2a072 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Mon, 27 Dec 2021 16:09:04 +0100 Subject: [PATCH 0310/1564] build: Set C dialect and warning level Currently, the Makefile is not setting the C dialect but the code was carved out from the nvme-cli code base which relies on gnu99. Let's define the C dialect to avoid any confusion and make the build more consistent. Without defining the default warning level the build system will use the default level, which is implementation depended. For example muon sets it to 3 which includes '-Wpendantic'. This results in a lot of ISO-C non compliant warnings. Let's define the warning level so that all build systems are using the same values. Signed-off-by: Daniel Wagner --- meson.build | 2 ++ 1 file changed, 2 insertions(+) diff --git a/meson.build b/meson.build index 37d21ec4b1..c3e941a87b 100644 --- a/meson.build +++ b/meson.build @@ -11,6 +11,8 @@ project( version: '1.0', license: 'LGPLv2+', default_options: [ + 'c_std=gnu99', + 'warning_level=1', 'buildtype=release', 'prefix=/usr', ] From ea1dbccbddbe77ca6d7eb78239810714ca46cd3b Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Fri, 7 Jan 2022 11:20:16 +0100 Subject: [PATCH 0311/1564] build: Remove unused configurator The configurator tool was used for the Makefile based build. Not needed for meson builds. Remove it. Signed-off-by: Daniel Wagner --- ccan/tools/configurator/configurator.c | 563 ------------------------- 1 file changed, 563 deletions(-) delete mode 100644 ccan/tools/configurator/configurator.c diff --git a/ccan/tools/configurator/configurator.c b/ccan/tools/configurator/configurator.c deleted file mode 100644 index dd5587c3b5..0000000000 --- a/ccan/tools/configurator/configurator.c +++ /dev/null @@ -1,563 +0,0 @@ -/* Simple tool to create config.h. - * Would be much easier with ccan modules, but deliberately standalone. - * - * Copyright 2011 Rusty Russell . MIT license. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DEFAULT_COMPILER "cc" -#define DEFAULT_FLAGS "-g3 -ggdb -Wall -Wundef -Wmissing-prototypes -Wmissing-declarations -Wstrict-prototypes -Wold-style-definition" - -#define OUTPUT_FILE "configurator.out" -#define INPUT_FILE "configuratortest.c" - -static int verbose; - -enum test_style { - OUTSIDE_MAIN = 0x1, - DEFINES_FUNC = 0x2, - INSIDE_MAIN = 0x4, - DEFINES_EVERYTHING = 0x8, - MAY_NOT_COMPILE = 0x10, - EXECUTE = 0x8000 -}; - -struct test { - const char *name; - enum test_style style; - const char *depends; - const char *link; - const char *fragment; - const char *overrides; /* On success, force this to '1' */ - bool done; - bool answer; -}; - -static struct test tests[] = { - { "HAVE_32BIT_OFF_T", DEFINES_EVERYTHING|EXECUTE, NULL, NULL, - "#include \n" - "int main(int argc, char *argv[]) {\n" - " return sizeof(off_t) == 4 ? 0 : 1;\n" - "}\n" }, - { "HAVE_ALIGNOF", INSIDE_MAIN, NULL, NULL, - "return __alignof__(double) > 0 ? 0 : 1;" }, - { "HAVE_ASPRINTF", DEFINES_FUNC, NULL, NULL, - "#define _GNU_SOURCE\n" - "#include \n" - "static char *func(int x) {" - " char *p;\n" - " if (asprintf(&p, \"%u\", x) == -1) p = NULL;" - " return p;\n" - "}" }, - { "HAVE_ATTRIBUTE_COLD", DEFINES_FUNC, NULL, NULL, - "static int __attribute__((cold)) func(int x) { return x; }" }, - { "HAVE_ATTRIBUTE_CONST", DEFINES_FUNC, NULL, NULL, - "static int __attribute__((const)) func(int x) { return x; }" }, - { "HAVE_ATTRIBUTE_PURE", DEFINES_FUNC, NULL, NULL, - "static int __attribute__((pure)) func(int x) { return x; }" }, - { "HAVE_ATTRIBUTE_MAY_ALIAS", OUTSIDE_MAIN, NULL, NULL, - "typedef short __attribute__((__may_alias__)) short_a;" }, - { "HAVE_ATTRIBUTE_NORETURN", DEFINES_FUNC, NULL, NULL, - "#include \n" - "static void __attribute__((noreturn)) func(int x) { exit(x); }" }, - { "HAVE_ATTRIBUTE_PRINTF", DEFINES_FUNC, NULL, NULL, - "static void __attribute__((format(__printf__, 1, 2))) func(const char *fmt, ...) { }" }, - { "HAVE_ATTRIBUTE_UNUSED", OUTSIDE_MAIN, NULL, NULL, - "static int __attribute__((unused)) func(int x) { return x; }" }, - { "HAVE_ATTRIBUTE_USED", OUTSIDE_MAIN, NULL, NULL, - "static int __attribute__((used)) func(int x) { return x; }" }, - { "HAVE_BACKTRACE", DEFINES_FUNC, NULL, NULL, - "#include \n" - "static int func(int x) {" - " void *bt[10];\n" - " return backtrace(bt, 10) < x;\n" - "}" }, - { "HAVE_BIG_ENDIAN", INSIDE_MAIN|EXECUTE, NULL, NULL, - "union { int i; char c[sizeof(int)]; } u;\n" - "u.i = 0x01020304;\n" - "return u.c[0] == 0x01 && u.c[1] == 0x02 && u.c[2] == 0x03 && u.c[3] == 0x04 ? 0 : 1;" }, - { "HAVE_BSWAP_64", DEFINES_FUNC, "HAVE_BYTESWAP_H", NULL, - "#include \n" - "static int func(int x) { return bswap_64(x); }" }, - { "HAVE_BUILTIN_CHOOSE_EXPR", INSIDE_MAIN, NULL, NULL, - "return __builtin_choose_expr(1, 0, \"garbage\");" }, - { "HAVE_BUILTIN_CLZ", INSIDE_MAIN, NULL, NULL, - "return __builtin_clz(1) == (sizeof(int)*8 - 1) ? 0 : 1;" }, - { "HAVE_BUILTIN_CLZL", INSIDE_MAIN, NULL, NULL, - "return __builtin_clzl(1) == (sizeof(long)*8 - 1) ? 0 : 1;" }, - { "HAVE_BUILTIN_CLZLL", INSIDE_MAIN, NULL, NULL, - "return __builtin_clzll(1) == (sizeof(long long)*8 - 1) ? 0 : 1;" }, - { "HAVE_BUILTIN_CTZ", INSIDE_MAIN, NULL, NULL, - "return __builtin_ctz(1 << (sizeof(int)*8 - 1)) == (sizeof(int)*8 - 1) ? 0 : 1;" }, - { "HAVE_BUILTIN_CTZL", INSIDE_MAIN, NULL, NULL, - "return __builtin_ctzl(1UL << (sizeof(long)*8 - 1)) == (sizeof(long)*8 - 1) ? 0 : 1;" }, - { "HAVE_BUILTIN_CTZLL", INSIDE_MAIN, NULL, NULL, - "return __builtin_ctzll(1ULL << (sizeof(long long)*8 - 1)) == (sizeof(long long)*8 - 1) ? 0 : 1;" }, - { "HAVE_BUILTIN_CONSTANT_P", INSIDE_MAIN, NULL, NULL, - "return __builtin_constant_p(1) ? 0 : 1;" }, - { "HAVE_BUILTIN_EXPECT", INSIDE_MAIN, NULL, NULL, - "return __builtin_expect(argc == 1, 1) ? 0 : 1;" }, - { "HAVE_BUILTIN_FFS", INSIDE_MAIN, NULL, NULL, - "return __builtin_ffs(0) == 0 ? 0 : 1;" }, - { "HAVE_BUILTIN_FFSL", INSIDE_MAIN, NULL, NULL, - "return __builtin_ffsl(0L) == 0 ? 0 : 1;" }, - { "HAVE_BUILTIN_FFSLL", INSIDE_MAIN, NULL, NULL, - "return __builtin_ffsll(0LL) == 0 ? 0 : 1;" }, - { "HAVE_BUILTIN_POPCOUNTL", INSIDE_MAIN, NULL, NULL, - "return __builtin_popcountl(255L) == 8 ? 0 : 1;" }, - { "HAVE_BUILTIN_TYPES_COMPATIBLE_P", INSIDE_MAIN, NULL, NULL, - "return __builtin_types_compatible_p(char *, int) ? 1 : 0;" }, - { "HAVE_ICCARM_INTRINSICS", DEFINES_FUNC, NULL, NULL, - "#include \n" - "int func(int v) {\n" - " return __CLZ(__RBIT(v));\n" - "}" }, - { "HAVE_BYTESWAP_H", OUTSIDE_MAIN, NULL, NULL, - "#include \n" }, - { "HAVE_CLOCK_GETTIME", - DEFINES_FUNC, "HAVE_STRUCT_TIMESPEC", NULL, - "#include \n" - "static struct timespec func(void) {\n" - " struct timespec ts;\n" - " clock_gettime(CLOCK_REALTIME, &ts);\n" - " return ts;\n" - "}\n" }, - { "HAVE_CLOCK_GETTIME_IN_LIBRT", - DEFINES_FUNC, - "HAVE_STRUCT_TIMESPEC !HAVE_CLOCK_GETTIME", - "-lrt", - "#include \n" - "static struct timespec func(void) {\n" - " struct timespec ts;\n" - " clock_gettime(CLOCK_REALTIME, &ts);\n" - " return ts;\n" - "}\n", - /* This means HAVE_CLOCK_GETTIME, too */ - "HAVE_CLOCK_GETTIME" }, - { "HAVE_COMPOUND_LITERALS", INSIDE_MAIN, NULL, NULL, - "int *foo = (int[]) { 1, 2, 3, 4 };\n" - "return foo[0] ? 0 : 1;" }, - { "HAVE_FCHDIR", DEFINES_EVERYTHING|EXECUTE, NULL, NULL, - "#include \n" - "#include \n" - "#include \n" - "#include \n" - "int main(void) {\n" - " int fd = open(\"..\", O_RDONLY);\n" - " return fchdir(fd) == 0 ? 0 : 1;\n" - "}\n" }, - { "HAVE_ERR_H", DEFINES_FUNC, NULL, NULL, - "#include \n" - "static void func(int arg) {\n" - " if (arg == 0)\n" - " err(1, \"err %u\", arg);\n" - " if (arg == 1)\n" - " errx(1, \"err %u\", arg);\n" - " if (arg == 3)\n" - " warn(\"warn %u\", arg);\n" - " if (arg == 4)\n" - " warnx(\"warn %u\", arg);\n" - "}\n" }, - { "HAVE_FILE_OFFSET_BITS", DEFINES_EVERYTHING|EXECUTE, - "HAVE_32BIT_OFF_T", NULL, - "#define _FILE_OFFSET_BITS 64\n" - "#include \n" - "int main(int argc, char *argv[]) {\n" - " return sizeof(off_t) == 8 ? 0 : 1;\n" - "}\n" }, - { "HAVE_FOR_LOOP_DECLARATION", INSIDE_MAIN, NULL, NULL, - "for (int i = 0; i < argc; i++) { return 0; };\n" - "return 1;" }, - { "HAVE_FLEXIBLE_ARRAY_MEMBER", OUTSIDE_MAIN, NULL, NULL, - "struct foo { unsigned int x; int arr[]; };" }, - { "HAVE_GETPAGESIZE", DEFINES_FUNC, NULL, NULL, - "#include \n" - "static int func(void) { return getpagesize(); }" }, - { "HAVE_ISBLANK", DEFINES_FUNC, NULL, NULL, - "#define _GNU_SOURCE\n" - "#include \n" - "static int func(void) { return isblank(' '); }" }, - { "HAVE_LITTLE_ENDIAN", INSIDE_MAIN|EXECUTE, NULL, NULL, - "union { int i; char c[sizeof(int)]; } u;\n" - "u.i = 0x01020304;\n" - "return u.c[0] == 0x04 && u.c[1] == 0x03 && u.c[2] == 0x02 && u.c[3] == 0x01 ? 0 : 1;" }, - { "HAVE_MEMMEM", DEFINES_FUNC, NULL, NULL, - "#define _GNU_SOURCE\n" - "#include \n" - "static void *func(void *h, size_t hl, void *n, size_t nl) {\n" - "return memmem(h, hl, n, nl);" - "}\n", }, - { "HAVE_MEMRCHR", DEFINES_FUNC, NULL, NULL, - "#define _GNU_SOURCE\n" - "#include \n" - "static void *func(void *s, int c, size_t n) {\n" - "return memrchr(s, c, n);" - "}\n", }, - { "HAVE_MMAP", DEFINES_FUNC, NULL, NULL, - "#include \n" - "static void *func(int fd) {\n" - " return mmap(0, 65536, PROT_READ, MAP_SHARED, fd, 0);\n" - "}" }, - { "HAVE_PROC_SELF_MAPS", DEFINES_EVERYTHING|EXECUTE, NULL, NULL, - "#include \n" - "#include \n" - "#include \n" - "int main(void) {\n" - " return open(\"/proc/self/maps\", O_RDONLY) != -1 ? 0 : 1;\n" - "}\n" }, - { "HAVE_QSORT_R_PRIVATE_LAST", - DEFINES_EVERYTHING|EXECUTE|MAY_NOT_COMPILE, NULL, NULL, - "#define _GNU_SOURCE 1\n" - "#include \n" - "static int cmp(const void *lp, const void *rp, void *priv) {\n" - " *(unsigned int *)priv = 1;\n" - " return *(const int *)lp - *(const int *)rp; }\n" - "int main(void) {\n" - " int array[] = { 9, 2, 5 };\n" - " unsigned int called = 0;\n" - " qsort_r(array, 3, sizeof(int), cmp, &called);\n" - " return called && array[0] == 2 && array[1] == 5 && array[2] == 9 ? 0 : 1;\n" - "}\n" }, - { "HAVE_STRUCT_TIMESPEC", - DEFINES_FUNC, NULL, NULL, - "#include \n" - "static void func(void) {\n" - " struct timespec ts;\n" - " ts.tv_sec = ts.tv_nsec = 1;\n" - "}\n" }, - { "HAVE_SECTION_START_STOP", - DEFINES_FUNC, NULL, NULL, - "static void *__attribute__((__section__(\"mysec\"))) p = &p;\n" - "static int func(void) {\n" - " extern void *__start_mysec[], *__stop_mysec[];\n" - " return __stop_mysec - __start_mysec;\n" - "}\n" }, - { "HAVE_STACK_GROWS_UPWARDS", DEFINES_EVERYTHING|EXECUTE, NULL, NULL, - "static long nest(const void *base, unsigned int i)\n" - "{\n" - " if (i == 0)\n" - " return (const char *)&i - (const char *)base;\n" - " return nest(base, i-1);\n" - "}\n" - "int main(int argc, char *argv[]) {\n" - " return (nest(&argc, argc) > 0) ? 0 : 1\n;" - "}\n" }, - { "HAVE_STATEMENT_EXPR", INSIDE_MAIN, NULL, NULL, - "return ({ int x = argc; x == argc ? 0 : 1; });" }, - { "HAVE_SYS_FILIO_H", OUTSIDE_MAIN, NULL, NULL, /* Solaris needs this for FIONREAD */ - "#include \n" }, - { "HAVE_SYS_TERMIOS_H", OUTSIDE_MAIN, NULL, NULL, - "#include \n" }, - { "HAVE_TYPEOF", INSIDE_MAIN, NULL, NULL, - "__typeof__(argc) i; i = argc; return i == argc ? 0 : 1;" }, - { "HAVE_UTIME", DEFINES_FUNC, NULL, NULL, - "#include \n" - "#include \n" - "static int func(const char *filename) {\n" - " struct utimbuf times = { 0 };\n" - " return utime(filename, ×);\n" - "}" }, - { "HAVE_WARN_UNUSED_RESULT", DEFINES_FUNC, NULL, NULL, - "#include \n" - "#include \n" - "static __attribute__((warn_unused_result)) int func(int i) {\n" - " return i + 1;\n" - "}" }, -}; - -static char *grab_fd(int fd) -{ - int ret; - size_t max, size = 0; - char *buffer; - - max = 16384; - buffer = malloc(max+1); - while ((ret = read(fd, buffer + size, max - size)) > 0) { - size += ret; - if (size == max) - buffer = realloc(buffer, max *= 2); - } - if (ret < 0) - err(1, "reading from command"); - buffer[size] = '\0'; - return buffer; -} - -static char *run(const char *cmd, int *exitstatus) -{ - pid_t pid; - int p[2]; - char *ret; - int status; - - if (pipe(p) != 0) - err(1, "creating pipe"); - - pid = fork(); - if (pid == -1) - err(1, "forking"); - - if (pid == 0) { - if (dup2(p[1], STDOUT_FILENO) != STDOUT_FILENO - || dup2(p[1], STDERR_FILENO) != STDERR_FILENO - || close(p[0]) != 0 - || close(STDIN_FILENO) != 0 - || open("/dev/null", O_RDONLY) != STDIN_FILENO) - exit(128); - - status = system(cmd); - if (WIFEXITED(status)) - exit(WEXITSTATUS(status)); - /* Here's a hint... */ - exit(128 + WTERMSIG(status)); - } - - close(p[1]); - ret = grab_fd(p[0]); - /* This shouldn't fail... */ - if (waitpid(pid, &status, 0) != pid) - err(1, "Failed to wait for child"); - close(p[0]); - if (WIFEXITED(status)) - *exitstatus = WEXITSTATUS(status); - else - *exitstatus = -WTERMSIG(status); - return ret; -} - -static char *connect_args(const char *argv[], const char *extra) -{ - unsigned int i, len = strlen(extra) + 1; - char *ret; - - for (i = 1; argv[i]; i++) - len += 1 + strlen(argv[i]); - - ret = malloc(len); - len = 0; - for (i = 1; argv[i]; i++) { - strcpy(ret + len, argv[i]); - len += strlen(argv[i]); - if (argv[i+1]) - ret[len++] = ' '; - } - strcpy(ret + len, extra); - return ret; -} - -static struct test *find_test(const char *name) -{ - unsigned int i; - - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { - if (strcmp(tests[i].name, name) == 0) - return &tests[i]; - } - abort(); -} - -#define PRE_BOILERPLATE "/* Test program generated by configurator. */\n" -#define MAIN_START_BOILERPLATE "int main(int argc, char *argv[]) {\n" -#define USE_FUNC_BOILERPLATE "(void)func;\n" -#define MAIN_BODY_BOILERPLATE "return 0;\n" -#define MAIN_END_BOILERPLATE "}\n" - -static bool run_test(const char *cmd, struct test *test) -{ - char *output; - FILE *outf; - int status; - - if (test->done) - return test->answer; - - if (test->depends) { - size_t len; - const char *deps = test->depends; - char *dep; - - /* Space-separated dependencies, could be ! for inverse. */ - while ((len = strcspn(deps, " "))) { - bool positive = true; - if (deps[len]) { - dep = strdup(deps); - dep[len] = '\0'; - } else { - dep = (char *)deps; - } - - if (dep[0] == '!') { - dep++; - positive = false; - } - if (run_test(cmd, find_test(dep)) != positive) { - test->answer = false; - test->done = true; - return test->answer; - } - deps += len; - deps += strspn(deps, " "); - } - } - - outf = fopen(INPUT_FILE, "w"); - if (!outf) - err(1, "creating %s", INPUT_FILE); - - fprintf(outf, "%s", PRE_BOILERPLATE); - switch (test->style & ~(EXECUTE|MAY_NOT_COMPILE)) { - case INSIDE_MAIN: - fprintf(outf, "%s", MAIN_START_BOILERPLATE); - fprintf(outf, "%s", test->fragment); - fprintf(outf, "%s", MAIN_END_BOILERPLATE); - break; - case OUTSIDE_MAIN: - fprintf(outf, "%s", test->fragment); - fprintf(outf, "%s", MAIN_START_BOILERPLATE); - fprintf(outf, "%s", MAIN_BODY_BOILERPLATE); - fprintf(outf, "%s", MAIN_END_BOILERPLATE); - break; - case DEFINES_FUNC: - fprintf(outf, "%s", test->fragment); - fprintf(outf, "%s", MAIN_START_BOILERPLATE); - fprintf(outf, "%s", USE_FUNC_BOILERPLATE); - fprintf(outf, "%s", MAIN_BODY_BOILERPLATE); - fprintf(outf, "%s", MAIN_END_BOILERPLATE); - break; - case DEFINES_EVERYTHING: - fprintf(outf, "%s", test->fragment); - break; - default: - abort(); - - } - fclose(outf); - - if (verbose > 1) - if (system("cat " INPUT_FILE) == -1); - - if (test->link) { - char *newcmd; - newcmd = malloc(strlen(cmd) + strlen(" ") - + strlen(test->link) + 1); - sprintf(newcmd, "%s %s", cmd, test->link); - if (verbose > 1) - printf("Extra link line: %s", newcmd); - cmd = newcmd; - } - - output = run(cmd, &status); - if (status != 0 || strstr(output, "warning")) { - if (verbose) - printf("Compile %s for %s, status %i: %s\n", - status ? "fail" : "warning", - test->name, status, output); - if ((test->style & EXECUTE) && !(test->style & MAY_NOT_COMPILE)) - errx(1, "Test for %s did not compile:\n%s", - test->name, output); - test->answer = false; - free(output); - } else { - /* Compile succeeded. */ - free(output); - /* We run INSIDE_MAIN tests for sanity checking. */ - if ((test->style & EXECUTE) || (test->style & INSIDE_MAIN)) { - output = run("./" OUTPUT_FILE, &status); - if (!(test->style & EXECUTE) && status != 0) - errx(1, "Test for %s failed with %i:\n%s", - test->name, status, output); - if (verbose && status) - printf("%s exited %i\n", test->name, status); - free(output); - } - test->answer = (status == 0); - } - test->done = true; - - if (test->answer && test->overrides) { - struct test *override = find_test(test->overrides); - override->done = true; - override->answer = true; - } - return test->answer; -} - -int main(int argc, const char *argv[]) -{ - char *cmd; - unsigned int i; - const char *default_args[] - = { "", DEFAULT_COMPILER, DEFAULT_FLAGS, NULL }; - - if (argc > 1) { - if (strcmp(argv[1], "--help") == 0) { - printf("Usage: configurator [-v] [ ...]\n" - " will have \"-o \" appended\n" - "Default: %s %s\n", - DEFAULT_COMPILER, DEFAULT_FLAGS); - exit(0); - } - if (strcmp(argv[1], "-v") == 0) { - argc--; - argv++; - verbose = 1; - } else if (strcmp(argv[1], "-vv") == 0) { - argc--; - argv++; - verbose = 2; - } - } - - if (argc == 1) - argv = default_args; - - cmd = connect_args(argv, " -o " OUTPUT_FILE " " INPUT_FILE); - for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) - run_test(cmd, &tests[i]); - - unlink(OUTPUT_FILE); - unlink(INPUT_FILE); - - printf("/* Generated by CCAN configurator */\n" - "#ifndef CCAN_CONFIG_H\n" - "#define CCAN_CONFIG_H\n"); - printf("#ifndef _GNU_SOURCE\n"); - printf("#define _GNU_SOURCE /* Always use GNU extensions. */\n"); - printf("#endif\n"); - printf("#define CCAN_COMPILER \"%s\"\n", argv[1]); - printf("#define CCAN_CFLAGS \"%s\"\n\n", connect_args(argv+1, "")); - /* This one implies "#include Date: Mon, 20 Dec 2021 16:28:03 +0100 Subject: [PATCH 0312/1564] linux: Add nvme_get_logical_block_size() Add helper to retrieve logical block size using nvme_identify_ns(). Signed-off-by: Daniel Wagner --- src/libnvme.map | 1 + src/nvme/linux.c | 16 ++++++++++++++++ src/nvme/linux.h | 10 ++++++++++ 3 files changed, 27 insertions(+) diff --git a/src/libnvme.map b/src/libnvme.map index ac920f1565..382be28df9 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -132,6 +132,7 @@ LIBNVME_1_0 { nvme_get_log_telemetry_ctrl; nvme_get_log_telemetry_host; nvme_get_log_zns_changed_zones; + nvme_get_logical_block_size; nvme_get_new_host_telemetry; nvme_get_ns_attr; nvme_get_nsid; diff --git a/src/nvme/linux.c b/src/nvme/linux.c index fe4aad33d3..8fa92468be 100644 --- a/src/nvme/linux.c +++ b/src/nvme/linux.c @@ -294,6 +294,22 @@ int nvme_get_ana_log_len(int fd, size_t *analen) return 0; } +int nvme_get_logical_block_size(int fd, __u32 nsid, int *blksize) +{ + struct nvme_id_ns ns; + int flbas; + int ret; + + ret = nvme_identify_ns(fd, nsid, &ns); + if (ret) + return ret; + + flbas = ns.flbas & NVME_NS_FLBAS_LBA_MASK; + *blksize = 1 << ns.lbaf[flbas].ds; + + return 0; +} + static int __nvme_set_attr(const char *path, const char *value) { int ret, fd; diff --git a/src/nvme/linux.h b/src/nvme/linux.h index 2a751a1325..9842d43dbf 100644 --- a/src/nvme/linux.h +++ b/src/nvme/linux.h @@ -109,6 +109,16 @@ int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, */ int nvme_get_ana_log_len(int fd, size_t *analen); +/** + * nvme_get_logical_block_size() - Retrieve block size + * @fd: File descriptor of nvme device + * @blksize: Pointer to where the block size will be set on success + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_get_logical_block_size(int fd, __u32 nsid, int *blksize); + /** * nvme_get_lba_status_log() - Retreive the LBA Status log page * @fd: File descriptor of the nvme device From 436898e756d9eed09d50471c7ca84206c282c756 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 23 Dec 2021 14:59:01 +0100 Subject: [PATCH 0313/1564] linux: Add support to generate DH-HMAC-CHAP keys Initially the DH-HMAC-CHAP key generation code was part of the nvme-cli repository and depended on OpenSSL 1. Move the key generation code into the library. While at it also add support for OpenSSL 3. Signed-off-by: Daniel Wagner --- meson.build | 15 +++ meson_options.txt | 1 + src/libnvme.map | 1 + src/meson.build | 2 + src/nvme/linux.c | 209 +++++++++++++++++++++++++++++++++++++++ src/nvme/linux.h | 29 ++++++ subprojects/openssl.wrap | 14 +++ 7 files changed, 271 insertions(+) create mode 100644 subprojects/openssl.wrap diff --git a/meson.build b/meson.build index c3e941a87b..6e25e47346 100644 --- a/meson.build +++ b/meson.build @@ -43,6 +43,21 @@ conf.set('CONFIG_LIBUUID', libuuid_dep.found(), description: 'Is libuuid require json_c_dep = dependency('json-c', version: '>=0.13', fallback : ['json-c', 'json_c_dep']) conf.set('CONFIG_JSONC', json_c_dep.found(), description: 'Is json-c required?') +# Check for OpenSSL availability +openssl_dep = dependency('openssl', + required: get_option('openssl'), + fallback : ['openssl', 'openssl_dep']) +if openssl_dep.found() + conf.set('CONFIG_OPENSSL', true, description: 'Is OpenSSL available?') + conf.set('CONFIG_OPENSSL_1', + openssl_dep.version().version_compare('<2.0.0') and + openssl_dep.version().version_compare('>=1.1.0'), + description: 'OpenSSL version 1.x') + conf.set('CONFIG_OPENSSL_3', + openssl_dep.version().version_compare('>=3.0.0'), + description: 'OpenSSL version 3.x') +endif + # local (cross-compilable) implementations of ccan configure steps conf.set10( 'HAVE_BUILTIN_TYPES_COMPATIBLE_P', diff --git a/meson_options.txt b/meson_options.txt index e87ad76503..cff41d480b 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -4,3 +4,4 @@ option('pkgconfiglibdir', type : 'string', value : '', description : 'directory option('man', type : 'boolean', value : false, description : 'build and install man pages (requires sphinx-build)') option('python', type : 'combo', choices : ['auto', 'true', 'false'], description : 'Generate libnvme python bindings') +option('openssl', type : 'feature', value: 'auto', description : 'OpenSSL support') diff --git a/src/libnvme.map b/src/libnvme.map index ac920f1565..1812f42ece 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -68,6 +68,7 @@ LIBNVME_1_0 { nvme_fw_commit; nvme_fw_download; nvme_fw_download_seq; + nvme_gen_dhchap_key; nvme_get_ana_log_len; nvme_get_attr; nvme_get_ctrl_attr; diff --git a/src/meson.build b/src/meson.build index d69e865e86..4f78f63e7d 100644 --- a/src/meson.build +++ b/src/meson.build @@ -23,6 +23,7 @@ endif deps = [ libuuid_dep, json_c_dep, + openssl_dep, ] source_dir = meson.current_source_dir() @@ -51,6 +52,7 @@ pkg.generate(libnvme, libnvme_dep = declare_dependency( include_directories: incdir, + dependencies: deps, link_with: libnvme, ) diff --git a/src/nvme/linux.c b/src/nvme/linux.c index fe4aad33d3..6cb47a93d6 100644 --- a/src/nvme/linux.c +++ b/src/nvme/linux.c @@ -17,6 +17,17 @@ #include #include +#ifdef CONFIG_OPENSSL +#include +#include +#include + +#ifdef CONFIG_OPENSSL_3 +#include +#include +#endif +#endif + #include #include "linux.h" @@ -386,3 +397,201 @@ char *nvme_get_path_attr(nvme_path_t p, const char *attr) { return nvme_get_attr(nvme_path_get_sysfs_dir(p), attr); } + +#ifndef CONFIG_OPENSSL +int nvme_gen_dhchap_key(char *hostnqn, enum nvme_hmac_alg hmac, + unsigned int key_len, unsigned char *secret, + unsigned char *key) +{ + if (hmac != NVME_HMAC_ALG_NONE) { + nvme_msg(LOG_ERR, "HMAC transformation not supported; " \ + "recompile with OpenSSL support.\n"); + errno = -EINVAL; + return -1; + } + + memcpy(key, secret, key_len); + return 0; +} +#endif /* !CONFIG_OPENSSL */ + +#ifdef CONFIG_OPENSSL_1 +int nvme_gen_dhchap_key(char *hostnqn, enum nvme_hmac_alg hmac, + unsigned int key_len, unsigned char *secret, + unsigned char *key) +{ + const char hmac_seed[] = "NVMe-over-Fabrics"; + HMAC_CTX *hmac_ctx; + const EVP_MD *md; + int err = -1; + + ENGINE_load_builtin_engines(); + ENGINE_register_all_complete(); + + hmac_ctx = HMAC_CTX_new(); + if (!hmac_ctx) { + nvme_msg(LOG_ERR, "OpenSSL: could not create HMAC context\n"); + errno = ENOENT; + return err; + } + + switch (hmac) { + case NVME_HMAC_ALG_NONE: + memcpy(key, secret, key_len); + err = 0; + goto out; + case NVME_HMAC_ALG_SHA2_256: + md = EVP_sha256(); + break; + case NVME_HMAC_ALG_SHA2_384: + md = EVP_sha384(); + break; + case NVME_HMAC_ALG_SHA2_512: + md = EVP_sha512(); + break; + default: + errno = EINVAL; + goto out; + } + + if (!md) { + nvme_msg(LOG_ERR, "OpenSSL: could not fetch hash function\n"); + errno = ENOENT; + goto out; + } + + if (!HMAC_Init_ex(hmac_ctx, secret, key_len, md, NULL)) { + nvme_msg(LOG_ERR, "OpenSSL: initializing HMAC context failed\n"); + errno = ENOENT; + goto out; + } + + if (!HMAC_Update(hmac_ctx, (unsigned char *)hostnqn, + strlen(hostnqn))) { + nvme_msg(LOG_ERR, "OpenSSL: HMAC for hostnqn failed\n"); + errno = ENOENT; + goto out; + } + + if (!HMAC_Update(hmac_ctx, (unsigned char *)hmac_seed, + strlen(hmac_seed))) { + nvme_msg(LOG_ERR, "OpenSSL: HMAC for seed failed\n"); + errno = ENOENT; + goto out; + } + + if (!HMAC_Final(hmac_ctx, key, &key_len)) { + nvme_msg(LOG_ERR, "OpenSSL: finializing MAC failed\n"); + errno = ENOENT; + goto out; + } + + err = 0; + +out: + HMAC_CTX_free(hmac_ctx); + return err; +} +#endif /* !CONFIG_OPENSSL_1 */ + +#ifdef CONFIG_OPENSSL_3 +int nvme_gen_dhchap_key(char *hostnqn, enum nvme_hmac_alg hmac, + unsigned int key_len, unsigned char *secret, + unsigned char *key) +{ + const char hmac_seed[] = "NVMe-over-Fabrics"; + OSSL_PARAM params[2], *p = params; + OSSL_LIB_CTX *lib_ctx; + EVP_MAC_CTX *mac_ctx = NULL; + EVP_MAC *mac = NULL; + char *progq = NULL; + char *digest; + size_t len; + int err = -1; + + lib_ctx = OSSL_LIB_CTX_new(); + if (!lib_ctx) { + nvme_msg(LOG_ERR, "OpenSSL: Library initializing failed\n"); + errno = ENOENT; + return err; + } + + mac = EVP_MAC_fetch(lib_ctx, OSSL_MAC_NAME_HMAC, progq); + if (!mac) { + nvme_msg(LOG_ERR, "OpenSSL: could not fetch HMAC algorithm\n"); + errno = EINVAL; + goto out; + } + + mac_ctx = EVP_MAC_CTX_new(mac); + if (!mac_ctx) { + nvme_msg(LOG_ERR, "OpenSSL: could not create HMAC context\n"); + errno = ENOENT; + goto out; + } + + switch (hmac) { + case NVME_HMAC_ALG_NONE: + memcpy(key, secret, key_len); + err = 0; + goto out; + case NVME_HMAC_ALG_SHA2_256: + digest = OSSL_DIGEST_NAME_SHA2_256; + break; + case NVME_HMAC_ALG_SHA2_384: + digest = OSSL_DIGEST_NAME_SHA2_384; + break; + case NVME_HMAC_ALG_SHA2_512: + digest = OSSL_DIGEST_NAME_SHA2_512; + break; + default: + errno = EINVAL; + goto out; + } + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, + digest, + 0); + *p = OSSL_PARAM_construct_end(); + + if (!EVP_MAC_init(mac_ctx, secret, key_len, params)) { + nvme_msg(LOG_ERR, "OpenSSL: could not initialize HMAC context\n"); + errno = EINVAL; + goto out; + } + + if (!EVP_MAC_update(mac_ctx, (unsigned char *)hostnqn, + strlen(hostnqn))) { + nvme_msg(LOG_ERR, "OpenSSL: HMAC for hostnqn failed\n"); + errno = ENOENT; + goto out; + } + + if (!EVP_MAC_update(mac_ctx, (unsigned char *)hmac_seed, + strlen(hmac_seed))) { + nvme_msg(LOG_ERR, "OpenSSL: HMAC for seed failed\n"); + errno = ENOENT; + goto out; + } + + if (!EVP_MAC_final(mac_ctx, key, &len, key_len)) { + nvme_msg(LOG_ERR, "OpenSSL: finializing MAC failed\n"); + errno = ENOENT; + goto out; + } + + if (len != key_len) { + nvme_msg(LOG_ERR, "OpenSSL: generated HMAC has an unexpected lenght\n"); + errno = EINVAL; + goto out; + } + + err = 0; + +out: + EVP_MAC_CTX_free(mac_ctx); + EVP_MAC_free(mac); + OSSL_LIB_CTX_free(lib_ctx); + + return err; +} +#endif /* !CONFIG_OPENSSL_3 */ diff --git a/src/nvme/linux.h b/src/nvme/linux.h index 2a751a1325..376a831d0c 100644 --- a/src/nvme/linux.h +++ b/src/nvme/linux.h @@ -153,4 +153,33 @@ int nvme_namespace_detach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrl */ int nvme_open(const char *name); +/** + * enum nvme_hmac_alg - HMAC algorithm + * NVME_HMAC_ALG_NONE: No HMAC algorithm + * NVME_HMAC_ALG_SHA2_256: SHA2-256 + * NVME_HMAC_ALG_SHA2_384: SHA2-384 + * NVME_HMAC_ALG_SHA2_512: SHA2-512 + */ +enum nvme_hmac_alg { + NVME_HMAC_ALG_NONE = 0, + NVME_HMAC_ALG_SHA2_256 = 1, + NVME_HMAC_ALG_SHA2_384 = 2, + NVME_HMAC_ALG_SHA2_512 = 3, +}; + +/** + * nvme_gen_dhchap_key() - DH-HMAC-CHAP key generation + * @hostnqn: Host NVMe Qualified Name + * @hmac: HMAC algorithm + * @key_len: Output key lenght + * @secret: Secret to used for digest + * @key: Generated DH-HMAC-CHAP key + * + * Return: If key generation was successful the function returns 0 or + * -1 with errno set otherwise. + */ +int nvme_gen_dhchap_key(char *hostnqn, enum nvme_hmac_alg hmac, + unsigned int key_len, unsigned char *secret, + unsigned char *key); + #endif /* _LIBNVME_LINUX_H */ diff --git a/subprojects/openssl.wrap b/subprojects/openssl.wrap new file mode 100644 index 0000000000..c4c1412838 --- /dev/null +++ b/subprojects/openssl.wrap @@ -0,0 +1,14 @@ +[wrap-file] +directory = openssl-1.1.1l +source_url = https://www.openssl.org/source/openssl-1.1.1l.tar.gz +source_filename = openssl-1.1.1l.tar.gz +source_hash = 0b7a3e5e59c34827fe0c3a74b7ec8baef302b98fa80088d7f9153aa16fa76bd1 +patch_filename = openssl_1.1.1l-2_patch.zip +patch_url = https://wrapdb.mesonbuild.com/v2/openssl_1.1.1l-2/get_patch +patch_hash = 852521fb016fa2deee8ebf9ffeeee0292c6de86a03c775cf72ac04e86f9f177e + +[provide] +libcrypto = libcrypto_dep +libssl = libssl_dep +openssl = openssl_dep + From 085e60fc747096e5f8ad449621694c5890cd2efe Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Fri, 7 Jan 2022 14:29:50 +0100 Subject: [PATCH 0314/1564] build: Remove in-tree config files from gitignore meson doesn't do any in tree builds. Remove the old Makefile generated config files from gitignore. Signed-off-by: Daniel Wagner --- .gitignore | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.gitignore b/.gitignore index 384f25fe04..304d2a60ad 100644 --- a/.gitignore +++ b/.gitignore @@ -19,11 +19,6 @@ examples/display-columnar examples/telemetry-listen examples/discover-loop -config.h -ccan/config.h -ccan/ccan-config.h -ccan/tools/configurator/configurator - doc/_build config-host.h From 0aa9527acc876b00b1164973ff2818830b69d71e Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Fri, 7 Jan 2022 12:41:33 +0100 Subject: [PATCH 0315/1564] build: Detect if Python.h header is present Make sure the devel package is also installed not just the the Python interpreter. Signed-off-by: Daniel Wagner --- libnvme/meson.build | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libnvme/meson.build b/libnvme/meson.build index 4e0f98472c..284c408fe5 100644 --- a/libnvme/meson.build +++ b/libnvme/meson.build @@ -15,7 +15,8 @@ if want_python != 'false' python3 = import('python').find_installation('python3') py3_dep = python3.dependency(required: want_python == 'true') swig = find_program('swig', required: want_python == 'true') - have_python_support = py3_dep.found() and swig.found() + header_found = cc.has_header('Python.h', dependencies: py3_dep) + have_python_support = py3_dep.found() and swig.found() and header_found else have_python_support = false endif From c1526aea5ca50a66e11362fe1b450f6ab844dba8 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Fri, 7 Jan 2022 16:53:50 +0100 Subject: [PATCH 0316/1564] build: Fix *.wrap exclude pattern in .gitignore The current rules trigger git to to complain with $ git add subprojects/openssl.wrap The following paths are ignored by one of your .gitignore files: subprojects We need to keep the parent directory in the tracking domain and just filter out all sub directories and files except the wrap files. Signed-off-by: Daniel Wagner --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 304d2a60ad..2fafa12112 100644 --- a/.gitignore +++ b/.gitignore @@ -29,5 +29,5 @@ cscope.* .build -subprojects +subprojects/* !subprojects/*.wrap From 35936185e376082cb26da205fd923c0f1c417c12 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Fri, 7 Jan 2022 16:57:10 +0100 Subject: [PATCH 0317/1564] build: Remove more in tree build artifacts meson doesn't do any in tree builds. Remove the old Makefile generated config files from gitignore. Signed-off-by: Daniel Wagner --- .gitignore | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/.gitignore b/.gitignore index 2fafa12112..2b640a0316 100644 --- a/.gitignore +++ b/.gitignore @@ -7,24 +7,6 @@ a.out *.a *.so.* -libnvme.pc - -test/register -test/test -test/cpp -test/zns - -examples/display-tree -examples/display-columnar -examples/telemetry-listen -examples/discover-loop - -doc/_build - -config-host.h -config-host.mak -config.log - cscope.* .build From e7eca9e14cda1e6cb97d9538dcbf3fd678b0c9d9 Mon Sep 17 00:00:00 2001 From: Martin Belanger Date: Mon, 10 Jan 2022 08:23:59 -0500 Subject: [PATCH 0318/1564] fix error building the man pages --- doc/conf.py | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/conf.py b/doc/conf.py index c1233e91c2..8e10c92b33 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -20,6 +20,7 @@ project = 'libnvme' copyright = '2020, Keith Busch' author = 'Keith Busch ' +master_doc = 'libnvme' # The full version, including alpha/beta/rc tags release = '0.1' From b47ef9c16566d5e672508650b2d7170af03c1720 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 17 Dec 2021 08:03:42 +0100 Subject: [PATCH 0319/1564] Use argument structure for nvme_get_log() Use an argument structure instead of passing all arguments one by one. This allows for a future expansion of the argument list without having to change the library ABI. Signed-off-by: Hannes Reinecke --- src/nvme/ioctl.c | 382 +++++++++++++++++++++++++++++++++++------------ src/nvme/ioctl.h | 63 ++++++-- src/nvme/linux.c | 22 ++- 3 files changed, 357 insertions(+), 110 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 934e6d57f4..fe7f2713a6 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -594,48 +594,61 @@ int nvme_nvm_identify_ctrl(int fd, struct nvme_id_ctrl_nvm *id) return nvme_identify_ctrl_csi(fd, NVME_CSI_NVM, id); } -int nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, - __u8 lsp, __u16 lsi, bool rae, __u8 uuidx, enum nvme_csi csi, - bool ot, __u32 len, void *log, __u32 timeout, __u32 *result) +int nvme_get_log(struct nvme_get_log_args *args) { - __u32 numd = (len >> 2) - 1; + __u32 numd = (args->len >> 2) - 1; __u16 numdu = numd >> 16, numdl = numd & 0xffff; - __u32 cdw10 = NVME_SET(lid, LOG_CDW10_LID) | - NVME_SET(lsp, LOG_CDW10_LSP) | - NVME_SET(!!rae, LOG_CDW10_RAE) | + __u32 cdw10 = NVME_SET(args->lid, LOG_CDW10_LID) | + NVME_SET(args->lsp, LOG_CDW10_LSP) | + NVME_SET(!!args->rae, LOG_CDW10_RAE) | NVME_SET(numdl, LOG_CDW10_NUMDL); __u32 cdw11 = NVME_SET(numdu, LOG_CDW11_NUMDU) | - NVME_SET(lsi, LOG_CDW11_LSI); - __u32 cdw12 = lpo & 0xffffffff; - __u32 cdw13 = lpo >> 32; - __u32 cdw14 = NVME_SET(uuidx, LOG_CDW14_UUID) | - NVME_SET(csi, LOG_CDW14_CSI) | - NVME_SET(!!ot, LOG_CDW14_OT); + NVME_SET(args->lsi, LOG_CDW11_LSI); + __u32 cdw12 = args->lpo & 0xffffffff; + __u32 cdw13 = args->lpo >> 32; + __u32 cdw14 = NVME_SET(args->uuidx, LOG_CDW14_UUID) | + NVME_SET(!!args->ot, LOG_CDW14_OT) | + NVME_SET(args->csi, LOG_CDW14_CSI); struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_get_log_page, - .nsid = nsid, - .addr = (__u64)(uintptr_t)log, - .data_len = len, + .nsid = args->nsid, + .addr = (__u64)(uintptr_t)args->log, + .data_len = args->len, .cdw10 = cdw10, .cdw11 = cdw11, .cdw12 = cdw12, .cdw13 = cdw13, .cdw14 = cdw14, - .timeout_ms = timeout, + .timeout_ms = args->timeout, }; - return nvme_submit_admin_passthru(fd, &cmd, result); + if (args->args_size < sizeof(struct nvme_get_log_args)) + return -EINVAL; + return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } static int __nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, bool rae, __u32 len, void *log) { - return nvme_get_log(fd, lid, NVME_NSID_ALL, 0, NVME_LOG_LSP_NONE, - NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, - NVME_CSI_NVM, false, len, log, - NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + struct nvme_get_log_args args = { + .fd = fd, + .lid = lid, + .nsid = NVME_NSID_ALL, + .lpo = 0, + .lsp = NVME_LOG_LSP_NONE, + .lsi = NVME_LOG_LSI_NONE, + .rae = rae, + .uuidx = NVME_UUID_NONE, + .len = len, + .log = log, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + .csi = NVME_CSI_NVM, + .ot = false, + }; + return nvme_get_log(&args); } int nvme_get_log_supported_log_pages(int fd, bool rae, @@ -656,12 +669,24 @@ int nvme_get_log_error(int fd, unsigned nr_entries, bool rae, int nvme_get_log_smart(int fd, __u32 nsid, bool rae, struct nvme_smart_log *log) { + struct nvme_get_log_args args = { + .fd = fd, + .lid = NVME_LOG_LID_SMART, + .nsid = nsid, + .lpo = 0, + .lsp = NVME_LOG_LSP_NONE, + .lsi = NVME_LOG_LSI_NONE, + .rae = rae, + .uuidx = NVME_UUID_NONE, + .len = sizeof(*log), + .log = log, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + .csi = NVME_CSI_NVM, + .ot = false, + }; BUILD_ASSERT(sizeof(struct nvme_smart_log) == 512); - return nvme_get_log(fd, NVME_LOG_LID_SMART, nsid, 0, - NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, - NVME_UUID_NONE, NVME_CSI_NVM, false, - sizeof(*log), log, NVME_DEFAULT_IOCTL_TIMEOUT, - NULL); + return nvme_get_log(&args); } int nvme_get_log_fw_slot(int fd, bool rae, struct nvme_firmware_slot *log) @@ -680,11 +705,24 @@ int nvme_get_log_changed_ns_list(int fd, bool rae, struct nvme_ns_list *log) int nvme_get_log_cmd_effects(int fd, enum nvme_csi csi, struct nvme_cmd_effects_log *log) { + struct nvme_get_log_args args = { + .fd = fd, + .lid = NVME_LOG_LID_CMD_EFFECTS, + .nsid = NVME_NSID_ALL, + .lpo = 0, + .lsp = NVME_LOG_LSP_NONE, + .lsi = NVME_LOG_LSI_NONE, + .rae = false, + .uuidx = NVME_UUID_NONE, + .len = sizeof(*log), + .log = log, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + .csi = NVME_CSI_NVM, + .ot = false, + }; BUILD_ASSERT(sizeof(struct nvme_cmd_effects_log) == 4096); - return nvme_get_log(fd, NVME_LOG_LID_CMD_EFFECTS, NVME_NSID_ALL, 0, - NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, - NVME_UUID_NONE, csi, false, false, sizeof(*log), - log, NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + return nvme_get_log(&args); } int nvme_get_log_device_self_test(int fd, struct nvme_self_test_log *log) @@ -701,70 +739,157 @@ enum nvme_cmd_get_log_telemetry_host_lsp { int nvme_get_log_create_telemetry_host(int fd, struct nvme_telemetry_log *log) { + struct nvme_get_log_args args = { + .fd = fd, + .lid = NVME_LOG_LID_TELEMETRY_HOST, + .nsid = NVME_NSID_NONE, + .lpo = 0, + .lsp = NVME_LOG_TELEM_HOST_LSP_CREATE, + .lsi = NVME_LOG_LSI_NONE, + .rae = false, + .uuidx = NVME_UUID_NONE, + .len = sizeof(*log), + .log = log, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + .csi = NVME_CSI_NVM, + .ot = false, + }; BUILD_ASSERT(sizeof(struct nvme_telemetry_log) == 512); - return nvme_get_log(fd, NVME_LOG_LID_TELEMETRY_HOST, NVME_NSID_NONE, 0, - NVME_LOG_TELEM_HOST_LSP_CREATE, NVME_LOG_LSI_NONE, - false, NVME_UUID_NONE, NVME_CSI_NVM, false, - sizeof(*log), log, NVME_DEFAULT_IOCTL_TIMEOUT, - NULL); + return nvme_get_log(&args); } int nvme_get_log_telemetry_host(int fd, __u64 offset, __u32 len, void *log) { - return nvme_get_log(fd, NVME_LOG_LID_TELEMETRY_HOST, NVME_NSID_NONE, - offset, NVME_LOG_TELEM_HOST_LSP_RETAIN, - NVME_LOG_LSI_NONE, false, NVME_UUID_NONE, - NVME_CSI_NVM, false, len, log, - NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + struct nvme_get_log_args args = { + .fd = fd, + .lid = NVME_LOG_LID_TELEMETRY_HOST, + .nsid = NVME_NSID_NONE, + .lpo = 0, + .lsp = NVME_LOG_TELEM_HOST_LSP_RETAIN, + .lsi = NVME_LOG_LSI_NONE, + .rae = false, + .uuidx = NVME_UUID_NONE, + .len = len, + .log = log, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + .csi = NVME_CSI_NVM, + .ot = false, + }; + return nvme_get_log(&args); } int nvme_get_log_telemetry_ctrl(int fd, bool rae, __u64 offset, __u32 len, void *log) { - return nvme_get_log(fd, NVME_LOG_LID_TELEMETRY_CTRL, NVME_NSID_NONE, - offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, - NVME_UUID_NONE, NVME_CSI_NVM, false, len, log, - NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + struct nvme_get_log_args args = { + .fd = fd, + .lid = NVME_LOG_LID_TELEMETRY_CTRL, + .nsid = NVME_NSID_NONE, + .lpo = offset, + .lsp = NVME_LOG_LSP_NONE, + .lsi = NVME_LOG_LSI_NONE, + .rae = rae, + .uuidx = NVME_UUID_NONE, + .len = len, + .log = log, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + .csi = NVME_CSI_NVM, + .ot = false, + }; + return nvme_get_log(&args); } int nvme_get_log_endurance_group(int fd, __u16 endgid, struct nvme_endurance_group_log *log) { + struct nvme_get_log_args args = { + .fd = fd, + .lid = NVME_LOG_LID_ENDURANCE_GROUP, + .nsid = NVME_NSID_NONE, + .lpo = 0, + .lsp = NVME_LOG_LSP_NONE, + .lsi = endgid, + .rae = false, + .uuidx = NVME_UUID_NONE, + .len = sizeof(*log), + .log = log, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + .csi = NVME_CSI_NVM, + .ot = false, + }; BUILD_ASSERT(sizeof(struct nvme_endurance_group_log) == 512); - return nvme_get_log(fd, NVME_LOG_LID_ENDURANCE_GROUP, NVME_NSID_NONE, - 0, NVME_LOG_LSP_NONE, endgid, false, NVME_UUID_NONE, - NVME_CSI_NVM, false, sizeof(*log), log, - NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + return nvme_get_log(&args); } int nvme_get_log_predictable_lat_nvmset(int fd, __u16 nvmsetid, struct nvme_nvmset_predictable_lat_log *log) { + struct nvme_get_log_args args = { + .fd = fd, + .lid = NVME_LOG_LID_PREDICTABLE_LAT_NVMSET, + .nsid = NVME_NSID_NONE, + .lpo = 0, + .lsp = NVME_LOG_LSP_NONE, + .lsi = nvmsetid, + .rae = false, + .uuidx = NVME_UUID_NONE, + .len = sizeof(*log), + .log = log, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + .csi = NVME_CSI_NVM, + .ot = false, + }; BUILD_ASSERT(sizeof(struct nvme_nvmset_predictable_lat_log) == 512); - return nvme_get_log(fd, NVME_LOG_LID_PREDICTABLE_LAT_NVMSET, - NVME_NSID_NONE, 0, NVME_LOG_LSP_NONE, nvmsetid, - false, NVME_UUID_NONE, NVME_CSI_NVM, false, - sizeof(*log),log, NVME_DEFAULT_IOCTL_TIMEOUT, - NULL); + return nvme_get_log(&args); } int nvme_get_log_predictable_lat_event(int fd, bool rae, __u32 offset, __u32 len, void *log) { - return nvme_get_log(fd, NVME_LOG_LID_PREDICTABLE_LAT_AGG, - NVME_NSID_NONE, offset, NVME_LOG_LSP_NONE, - NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, - NVME_CSI_NVM, false, len, log, - NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + struct nvme_get_log_args args = { + .fd = fd, + .lid = NVME_LOG_LID_PREDICTABLE_LAT_AGG, + .nsid = NVME_NSID_NONE, + .lpo = offset, + .lsp = NVME_LOG_LSP_NONE, + .lsi = NVME_LOG_LSI_NONE, + .rae = rae, + .uuidx = NVME_UUID_NONE, + .len = len, + .log = log, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + .csi = NVME_CSI_NVM, + .ot = false, + }; + return nvme_get_log(&args); } int nvme_get_log_ana(int fd, enum nvme_log_ana_lsp lsp, bool rae, __u64 offset, __u32 len, void *log) { - return nvme_get_log(fd, NVME_LOG_LID_ANA, NVME_NSID_NONE, offset, - lsp, NVME_LOG_LSI_NONE, false, NVME_UUID_NONE, - NVME_CSI_NVM, false, len, log, - NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + struct nvme_get_log_args args = { + .fd = fd, + .lid = NVME_LOG_LID_ANA, + .nsid = NVME_NSID_NONE, + .lpo = offset, + .lsp = lsp, + .lsi = NVME_LOG_LSI_NONE, + .rae = false, + .uuidx = NVME_UUID_NONE, + .len = len, + .log = log, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + .csi = NVME_CSI_NVM, + .ot = false, + }; + return nvme_get_log(&args); } int nvme_get_log_ana_groups(int fd, bool rae, __u32 len, @@ -777,51 +902,112 @@ int nvme_get_log_ana_groups(int fd, bool rae, __u32 len, int nvme_get_log_lba_status(int fd, bool rae, __u64 offset, __u32 len, void *log) { - return nvme_get_log(fd, NVME_LOG_LID_LBA_STATUS, NVME_NSID_NONE, - offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, - NVME_UUID_NONE, NVME_CSI_NVM, false, len, log, - NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + struct nvme_get_log_args args = { + .fd = fd, + .lid = NVME_LOG_LID_LBA_STATUS, + .nsid = NVME_NSID_NONE, + .lpo = offset, + .lsp = NVME_LOG_LSP_NONE, + .lsi = NVME_LOG_LSI_NONE, + .rae = rae, + .uuidx = NVME_UUID_NONE, + .len = len, + .log = log, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + .csi = NVME_CSI_NVM, + .ot = false, + }; + return nvme_get_log(&args); } int nvme_get_log_endurance_grp_evt(int fd, bool rae, __u32 offset, __u32 len, void *log) { - return nvme_get_log(fd, NVME_LOG_LID_ENDURANCE_GRP_EVT, - NVME_NSID_NONE, offset, NVME_LOG_LSP_NONE, - NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, - NVME_CSI_NVM, false, len, log, - NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + struct nvme_get_log_args args = { + .fd = fd, + .lid = NVME_LOG_LID_ENDURANCE_GRP_EVT, + .nsid = NVME_NSID_NONE, + .lpo = offset, + .lsp = NVME_LOG_LSP_NONE, + .lsi = NVME_LOG_LSI_NONE, + .rae = rae, + .uuidx = NVME_UUID_NONE, + .len = len, + .log = log, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + .csi = NVME_CSI_NVM, + .ot = false, + }; + return nvme_get_log(&args); } int nvme_get_log_fid_supported_effects(int fd, bool rae, struct nvme_fid_supported_effects_log *log) { + struct nvme_get_log_args args = { + .fd = fd, + .lid = NVME_LOG_LID_FID_SUPPORTED_EFFECTS, + .nsid = NVME_NSID_NONE, + .lpo = 0, + .lsp = NVME_LOG_LSP_NONE, + .lsi = NVME_LOG_LSI_NONE, + .rae = rae, + .uuidx = NVME_UUID_NONE, + .len = sizeof(*log), + .log = log, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + .csi = NVME_CSI_NVM, + .ot = false, + }; BUILD_ASSERT(sizeof(struct nvme_fid_supported_effects_log) == 1024); - return nvme_get_log(fd, NVME_LOG_LID_FID_SUPPORTED_EFFECTS, - NVME_NSID_NONE, 0, NVME_LOG_LSP_NONE, - NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, - NVME_CSI_NVM, false, sizeof(*log), log, - NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + return nvme_get_log(&args); } int nvme_get_log_boot_partition(int fd, bool rae, __u8 lsp, __u32 len, struct nvme_boot_partition *part) { + struct nvme_get_log_args args = { + .fd = fd, + .lid = NVME_LOG_LID_BOOT_PARTITION, + .nsid = NVME_NSID_NONE, + .lpo = 0, + .lsp = NVME_LOG_LSP_NONE, + .lsi = NVME_LOG_LSI_NONE, + .rae = rae, + .uuidx = NVME_UUID_NONE, + .len = len, + .log = part, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + .csi = NVME_CSI_NVM, + .ot = false, + }; BUILD_ASSERT(sizeof(struct nvme_boot_partition) == 16); - return nvme_get_log(fd, NVME_LOG_LID_BOOT_PARTITION, - NVME_NSID_NONE, 0, NVME_LOG_LSP_NONE, - NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, - NVME_CSI_NVM, false, len, part, - NVME_DEFAULT_IOCTL_TIMEOUT, NULL); - + return nvme_get_log(&args); } int nvme_get_log_discovery(int fd, bool rae, __u32 offset, __u32 len, void *log) { - return nvme_get_log(fd, NVME_LOG_LID_DISCOVER, NVME_NSID_NONE, offset, - NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, - NVME_UUID_NONE, NVME_CSI_NVM, false, len, log, - NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + struct nvme_get_log_args args = { + .fd = fd, + .lid = NVME_LOG_LID_DISCOVER, + .nsid = NVME_NSID_NONE, + .lpo = offset, + .lsp = NVME_LOG_LSP_NONE, + .lsi = NVME_LOG_LSI_NONE, + .rae = rae, + .uuidx = NVME_UUID_NONE, + .len = len, + .log = log, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + .csi = NVME_CSI_NVM, + .ot = false, + }; + return nvme_get_log(&args); } int nvme_get_log_reservation(int fd, bool rae, @@ -850,12 +1036,24 @@ int nvme_get_log_persistent_event(int fd, enum nvme_pevent_log_action action, int nvme_get_log_zns_changed_zones(int fd, __u32 nsid, bool rae, struct nvme_zns_changed_zone_log *log) { + struct nvme_get_log_args args = { + .fd = fd, + .lid = NVME_LOG_LID_ZNS_CHANGED_ZONES, + .nsid = nsid, + .lpo = 0, + .lsp = NVME_LOG_LSP_NONE, + .lsi = NVME_LOG_LSI_NONE, + .rae = rae, + .uuidx = NVME_UUID_NONE, + .len = sizeof(*log), + .log = log, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + .csi = NVME_CSI_ZNS, + .ot = false, + }; BUILD_ASSERT(sizeof(struct nvme_zns_changed_zone_log) == 4096); - return nvme_get_log(fd, NVME_LOG_LID_ZNS_CHANGED_ZONES, nsid, 0, - NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, - NVME_UUID_NONE, NVME_CSI_ZNS, false, - sizeof(*log), log, NVME_DEFAULT_IOCTL_TIMEOUT, - NULL); + return nvme_get_log(&args); } int nvme_set_features(int fd, __u8 fid, __u32 nsid, __u32 cdw11, __u32 cdw12, diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 79db6a18a6..0c235adfd7 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -778,7 +778,8 @@ int nvme_zns_identify_ns(int fd, __u32 nsid, struct nvme_zns_id_ns *data); int nvme_zns_identify_ctrl(int fd, struct nvme_zns_id_ctrl *id); /** - * nvme_get_log() - NVMe Admin Get Log command + * nvme_get_log_args - Arguments for the NVMe Admin Get Log command + * @args_size: Length of the structure * @fd: File descriptor of nvme device * @lid: Log page identifier, see &enum nvme_cmd_get_log_lid for known * values @@ -788,31 +789,65 @@ int nvme_zns_identify_ctrl(int fd, struct nvme_zns_id_ctrl *id); * @lsi: Endurance group information * @rae: Retain asynchronous events * @uuidx: UUID selection, if supported - * @csi: Command Set Identifier - * @ot: Offset Type. If set to false, the Log Page Offset Lower - * field and the Log Page Offset Upper field specify the - * byte offset into the log page to be returned. - * If set to true, the Log Page Offset Lower field and the - * Log Page Offset Upper field specify the index into the - * list of data structures in the log page to be returned. * @len: Length of provided user buffer to hold the log data in bytes * @log: User space destination address to transfer the data * @timeout: Timeout in ms * @result: The command completion result from CQE dword0 + * @csi: Command set identifier, see &enum nvme_csi for known values + * @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 { + int args_size; + int fd; + enum nvme_cmd_get_log_lid lid; + __u32 nsid; + __u64 lpo; + __u8 lsp; + __u16 lsi; + bool rae; + __u8 uuidx; + __u32 len; + void *log; + __u32 timeout; + __u32 *result; + enum nvme_csi csi; + bool ot; +}; + +/** + * nvme_get_log() - NVMe Admin Get Log command + * @args: &struct nvme_get_log_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_get_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, - __u8 lsp, __u16 lsi, bool rae, __u8 uuidx, enum nvme_csi csi, - bool ot, __u32 len, void *log, __u32 timeout, __u32 *result); +int nvme_get_log(struct nvme_get_log_args *args); static inline int nvme_get_nsid_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u32 len, void *log) { - return nvme_get_log(fd, lid, nsid, 0, 0, 0, false, 0, NVME_CSI_NVM, - false, len, log, NVME_DEFAULT_IOCTL_TIMEOUT, - NULL); + struct nvme_get_log_args args = { + .args_size = sizeof(args), + .fd = fd, + .lid = lid, + .nsid = nsid, + .lpo = 0, + .lsp = NVME_LOG_LSP_NONE, + .lsi = NVME_LOG_LSI_NONE, + .rae = false, + .uuidx = NVME_UUID_NONE, + .len = len, + .log = log, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + .csi = NVME_CSI_NVM, + .ot = false, + }; + + return nvme_get_log(&args); } static inline int nvme_get_log_simple(int fd, enum nvme_cmd_get_log_lid lid, diff --git a/src/nvme/linux.c b/src/nvme/linux.c index f6b2ae6ff7..84786110bf 100644 --- a/src/nvme/linux.c +++ b/src/nvme/linux.c @@ -115,6 +115,19 @@ int __nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, bool retain = true; void *ptr = data; int ret; + struct nvme_get_log_args args = { + .args_size = sizeof(args), + .fd = fd, + .nsid = nsid, + .lid = log_id, + .lsp = NVME_LOG_LSP_NONE, + .lsi = NVME_LOG_LSI_NONE, + .uuidx = NVME_UUID_NONE, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + .csi = NVME_CSI_NVM, + .ot = false, + }; /* * 4k is the smallest possible transfer unit, so restricting to 4k @@ -133,10 +146,11 @@ int __nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, if (offset + xfer == data_len) retain = rae; - ret = nvme_get_log(fd, log_id, nsid, offset, NVME_LOG_LSP_NONE, - NVME_LOG_LSI_NONE, retain, NVME_UUID_NONE, - NVME_CSI_NVM, false, xfer, ptr, - NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + args.lpo = offset; + args.len = xfer; + args.log = ptr; + args.rae = retain; + ret = nvme_get_log(&args); if (ret) return ret; From 803d59dc2658e44a4914ff5194853cfbe46148b2 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 17 Dec 2021 13:43:19 +0100 Subject: [PATCH 0320/1564] Inline nvme_get_log() wrapper functions No point in having wrapper functions as part of the libnvme library. Signed-off-by: Hannes Reinecke --- src/nvme/ioctl.c | 427 --------------------------------------------- src/nvme/ioctl.h | 439 +++++++++++++++++++++++++++++++++++++++++------ src/nvme/types.h | 5 + 3 files changed, 396 insertions(+), 475 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index fe7f2713a6..7b6038c09b 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -629,433 +629,6 @@ int nvme_get_log(struct nvme_get_log_args *args) return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } -static int __nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, bool rae, - __u32 len, void *log) -{ - struct nvme_get_log_args args = { - .fd = fd, - .lid = lid, - .nsid = NVME_NSID_ALL, - .lpo = 0, - .lsp = NVME_LOG_LSP_NONE, - .lsi = NVME_LOG_LSI_NONE, - .rae = rae, - .uuidx = NVME_UUID_NONE, - .len = len, - .log = log, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - .csi = NVME_CSI_NVM, - .ot = false, - }; - return nvme_get_log(&args); -} - -int nvme_get_log_supported_log_pages(int fd, bool rae, - struct nvme_supported_log_pages *log) -{ - BUILD_ASSERT(sizeof(struct nvme_supported_log_pages) == 1024); - return __nvme_get_log(fd, NVME_LOG_LID_SUPPORTED_LOG_PAGES, rae, - sizeof(*log), log); -} - -int nvme_get_log_error(int fd, unsigned nr_entries, bool rae, - struct nvme_error_log_page *log) -{ - BUILD_ASSERT(sizeof(struct nvme_error_log_page) == 64); - return __nvme_get_log(fd, NVME_LOG_LID_ERROR, rae, - sizeof(*log) * nr_entries, log); -} - -int nvme_get_log_smart(int fd, __u32 nsid, bool rae, struct nvme_smart_log *log) -{ - struct nvme_get_log_args args = { - .fd = fd, - .lid = NVME_LOG_LID_SMART, - .nsid = nsid, - .lpo = 0, - .lsp = NVME_LOG_LSP_NONE, - .lsi = NVME_LOG_LSI_NONE, - .rae = rae, - .uuidx = NVME_UUID_NONE, - .len = sizeof(*log), - .log = log, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - .csi = NVME_CSI_NVM, - .ot = false, - }; - BUILD_ASSERT(sizeof(struct nvme_smart_log) == 512); - return nvme_get_log(&args); -} - -int nvme_get_log_fw_slot(int fd, bool rae, struct nvme_firmware_slot *log) -{ - BUILD_ASSERT(sizeof(struct nvme_firmware_slot) == 512); - return __nvme_get_log(fd, NVME_LOG_LID_FW_SLOT, rae, sizeof(*log), - log); -} - -int nvme_get_log_changed_ns_list(int fd, bool rae, struct nvme_ns_list *log) -{ - return __nvme_get_log(fd, NVME_LOG_LID_CHANGED_NS, rae, - sizeof(*log), log); -} - -int nvme_get_log_cmd_effects(int fd, enum nvme_csi csi, - struct nvme_cmd_effects_log *log) -{ - struct nvme_get_log_args args = { - .fd = fd, - .lid = NVME_LOG_LID_CMD_EFFECTS, - .nsid = NVME_NSID_ALL, - .lpo = 0, - .lsp = NVME_LOG_LSP_NONE, - .lsi = NVME_LOG_LSI_NONE, - .rae = false, - .uuidx = NVME_UUID_NONE, - .len = sizeof(*log), - .log = log, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - .csi = NVME_CSI_NVM, - .ot = false, - }; - BUILD_ASSERT(sizeof(struct nvme_cmd_effects_log) == 4096); - return nvme_get_log(&args); -} - -int nvme_get_log_device_self_test(int fd, struct nvme_self_test_log *log) -{ - BUILD_ASSERT(sizeof(struct nvme_self_test_log) == 564); - return __nvme_get_log(fd, NVME_LOG_LID_DEVICE_SELF_TEST, false, - sizeof(*log), log); -} - -enum nvme_cmd_get_log_telemetry_host_lsp { - NVME_LOG_TELEM_HOST_LSP_RETAIN = 0, - NVME_LOG_TELEM_HOST_LSP_CREATE = 1, -}; - -int nvme_get_log_create_telemetry_host(int fd, struct nvme_telemetry_log *log) -{ - struct nvme_get_log_args args = { - .fd = fd, - .lid = NVME_LOG_LID_TELEMETRY_HOST, - .nsid = NVME_NSID_NONE, - .lpo = 0, - .lsp = NVME_LOG_TELEM_HOST_LSP_CREATE, - .lsi = NVME_LOG_LSI_NONE, - .rae = false, - .uuidx = NVME_UUID_NONE, - .len = sizeof(*log), - .log = log, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - .csi = NVME_CSI_NVM, - .ot = false, - }; - BUILD_ASSERT(sizeof(struct nvme_telemetry_log) == 512); - return nvme_get_log(&args); -} - -int nvme_get_log_telemetry_host(int fd, __u64 offset, __u32 len, void *log) -{ - struct nvme_get_log_args args = { - .fd = fd, - .lid = NVME_LOG_LID_TELEMETRY_HOST, - .nsid = NVME_NSID_NONE, - .lpo = 0, - .lsp = NVME_LOG_TELEM_HOST_LSP_RETAIN, - .lsi = NVME_LOG_LSI_NONE, - .rae = false, - .uuidx = NVME_UUID_NONE, - .len = len, - .log = log, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - .csi = NVME_CSI_NVM, - .ot = false, - }; - return nvme_get_log(&args); -} - -int nvme_get_log_telemetry_ctrl(int fd, bool rae, __u64 offset, __u32 len, - void *log) -{ - struct nvme_get_log_args args = { - .fd = fd, - .lid = NVME_LOG_LID_TELEMETRY_CTRL, - .nsid = NVME_NSID_NONE, - .lpo = offset, - .lsp = NVME_LOG_LSP_NONE, - .lsi = NVME_LOG_LSI_NONE, - .rae = rae, - .uuidx = NVME_UUID_NONE, - .len = len, - .log = log, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - .csi = NVME_CSI_NVM, - .ot = false, - }; - return nvme_get_log(&args); -} - -int nvme_get_log_endurance_group(int fd, __u16 endgid, - struct nvme_endurance_group_log *log) -{ - struct nvme_get_log_args args = { - .fd = fd, - .lid = NVME_LOG_LID_ENDURANCE_GROUP, - .nsid = NVME_NSID_NONE, - .lpo = 0, - .lsp = NVME_LOG_LSP_NONE, - .lsi = endgid, - .rae = false, - .uuidx = NVME_UUID_NONE, - .len = sizeof(*log), - .log = log, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - .csi = NVME_CSI_NVM, - .ot = false, - }; - BUILD_ASSERT(sizeof(struct nvme_endurance_group_log) == 512); - return nvme_get_log(&args); -} - -int nvme_get_log_predictable_lat_nvmset(int fd, __u16 nvmsetid, - struct nvme_nvmset_predictable_lat_log *log) -{ - struct nvme_get_log_args args = { - .fd = fd, - .lid = NVME_LOG_LID_PREDICTABLE_LAT_NVMSET, - .nsid = NVME_NSID_NONE, - .lpo = 0, - .lsp = NVME_LOG_LSP_NONE, - .lsi = nvmsetid, - .rae = false, - .uuidx = NVME_UUID_NONE, - .len = sizeof(*log), - .log = log, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - .csi = NVME_CSI_NVM, - .ot = false, - }; - BUILD_ASSERT(sizeof(struct nvme_nvmset_predictable_lat_log) == 512); - return nvme_get_log(&args); -} - -int nvme_get_log_predictable_lat_event(int fd, bool rae, __u32 offset, - __u32 len, void *log) -{ - struct nvme_get_log_args args = { - .fd = fd, - .lid = NVME_LOG_LID_PREDICTABLE_LAT_AGG, - .nsid = NVME_NSID_NONE, - .lpo = offset, - .lsp = NVME_LOG_LSP_NONE, - .lsi = NVME_LOG_LSI_NONE, - .rae = rae, - .uuidx = NVME_UUID_NONE, - .len = len, - .log = log, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - .csi = NVME_CSI_NVM, - .ot = false, - }; - return nvme_get_log(&args); -} - -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 = { - .fd = fd, - .lid = NVME_LOG_LID_ANA, - .nsid = NVME_NSID_NONE, - .lpo = offset, - .lsp = lsp, - .lsi = NVME_LOG_LSI_NONE, - .rae = false, - .uuidx = NVME_UUID_NONE, - .len = len, - .log = log, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - .csi = NVME_CSI_NVM, - .ot = false, - }; - return nvme_get_log(&args); -} - -int nvme_get_log_ana_groups(int fd, bool rae, __u32 len, - struct nvme_ana_group_desc *log) -{ - return nvme_get_log_ana(fd, NVME_LOG_ANA_LSP_RGO_GROUPS_ONLY, rae, 0, - len, log); -} - -int nvme_get_log_lba_status(int fd, bool rae, __u64 offset, __u32 len, - void *log) -{ - struct nvme_get_log_args args = { - .fd = fd, - .lid = NVME_LOG_LID_LBA_STATUS, - .nsid = NVME_NSID_NONE, - .lpo = offset, - .lsp = NVME_LOG_LSP_NONE, - .lsi = NVME_LOG_LSI_NONE, - .rae = rae, - .uuidx = NVME_UUID_NONE, - .len = len, - .log = log, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - .csi = NVME_CSI_NVM, - .ot = false, - }; - return nvme_get_log(&args); -} - -int nvme_get_log_endurance_grp_evt(int fd, bool rae, __u32 offset, __u32 len, - void *log) -{ - struct nvme_get_log_args args = { - .fd = fd, - .lid = NVME_LOG_LID_ENDURANCE_GRP_EVT, - .nsid = NVME_NSID_NONE, - .lpo = offset, - .lsp = NVME_LOG_LSP_NONE, - .lsi = NVME_LOG_LSI_NONE, - .rae = rae, - .uuidx = NVME_UUID_NONE, - .len = len, - .log = log, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - .csi = NVME_CSI_NVM, - .ot = false, - }; - return nvme_get_log(&args); -} - -int nvme_get_log_fid_supported_effects(int fd, bool rae, - struct nvme_fid_supported_effects_log *log) -{ - struct nvme_get_log_args args = { - .fd = fd, - .lid = NVME_LOG_LID_FID_SUPPORTED_EFFECTS, - .nsid = NVME_NSID_NONE, - .lpo = 0, - .lsp = NVME_LOG_LSP_NONE, - .lsi = NVME_LOG_LSI_NONE, - .rae = rae, - .uuidx = NVME_UUID_NONE, - .len = sizeof(*log), - .log = log, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - .csi = NVME_CSI_NVM, - .ot = false, - }; - BUILD_ASSERT(sizeof(struct nvme_fid_supported_effects_log) == 1024); - return nvme_get_log(&args); -} - -int nvme_get_log_boot_partition(int fd, bool rae, __u8 lsp, __u32 len, - struct nvme_boot_partition *part) -{ - struct nvme_get_log_args args = { - .fd = fd, - .lid = NVME_LOG_LID_BOOT_PARTITION, - .nsid = NVME_NSID_NONE, - .lpo = 0, - .lsp = NVME_LOG_LSP_NONE, - .lsi = NVME_LOG_LSI_NONE, - .rae = rae, - .uuidx = NVME_UUID_NONE, - .len = len, - .log = part, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - .csi = NVME_CSI_NVM, - .ot = false, - }; - BUILD_ASSERT(sizeof(struct nvme_boot_partition) == 16); - return nvme_get_log(&args); -} - -int nvme_get_log_discovery(int fd, bool rae, __u32 offset, __u32 len, void *log) -{ - struct nvme_get_log_args args = { - .fd = fd, - .lid = NVME_LOG_LID_DISCOVER, - .nsid = NVME_NSID_NONE, - .lpo = offset, - .lsp = NVME_LOG_LSP_NONE, - .lsi = NVME_LOG_LSI_NONE, - .rae = rae, - .uuidx = NVME_UUID_NONE, - .len = len, - .log = log, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - .csi = NVME_CSI_NVM, - .ot = false, - }; - return nvme_get_log(&args); -} - -int nvme_get_log_reservation(int fd, bool rae, - struct nvme_resv_notification_log *log) -{ - BUILD_ASSERT(sizeof(struct nvme_resv_notification_log) == 64); - return __nvme_get_log(fd, NVME_LOG_LID_RESERVATION, rae, - sizeof(*log), log); -} - -int nvme_get_log_sanitize(int fd, bool rae, - struct nvme_sanitize_log_page *log) -{ - BUILD_ASSERT(sizeof(struct nvme_sanitize_log_page) == 512); - return __nvme_get_log(fd, NVME_LOG_LID_SANITIZE, rae, sizeof(*log), - log); -} - -int nvme_get_log_persistent_event(int fd, enum nvme_pevent_log_action action, - __u32 size, void *pevent_log) -{ - return __nvme_get_log(fd, NVME_LOG_LID_PERSISTENT_EVENT, false, size, - pevent_log); -} - -int nvme_get_log_zns_changed_zones(int fd, __u32 nsid, bool rae, - struct nvme_zns_changed_zone_log *log) -{ - struct nvme_get_log_args args = { - .fd = fd, - .lid = NVME_LOG_LID_ZNS_CHANGED_ZONES, - .nsid = nsid, - .lpo = 0, - .lsp = NVME_LOG_LSP_NONE, - .lsi = NVME_LOG_LSI_NONE, - .rae = rae, - .uuidx = NVME_UUID_NONE, - .len = sizeof(*log), - .log = log, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - .csi = NVME_CSI_ZNS, - .ot = false, - }; - BUILD_ASSERT(sizeof(struct nvme_zns_changed_zone_log) == 4096); - return nvme_get_log(&args); -} - int nvme_set_features(int fd, __u8 fid, __u32 nsid, __u32 cdw11, __u32 cdw12, bool save, __u8 uuidx, __u32 cdw15, __u32 data_len, void *data, __u32 timeout, __u32 *result) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 0c235adfd7..66fd952c8a 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -826,8 +826,9 @@ struct nvme_get_log_args { */ int nvme_get_log(struct nvme_get_log_args *args); -static inline int nvme_get_nsid_log(int fd, enum nvme_cmd_get_log_lid lid, - __u32 nsid, __u32 len, void *log) +static inline int nvme_get_nsid_log(int fd, bool rae, + enum nvme_cmd_get_log_lid lid, + __u32 nsid, __u32 len, void *log) { struct nvme_get_log_args args = { .args_size = sizeof(args), @@ -853,7 +854,7 @@ static inline int nvme_get_nsid_log(int fd, enum nvme_cmd_get_log_lid lid, static inline int nvme_get_log_simple(int fd, enum nvme_cmd_get_log_lid lid, __u32 len, void *log) { - return nvme_get_nsid_log(fd, lid, NVME_NSID_ALL, len, log); + return nvme_get_nsid_log(fd, false, lid, NVME_NSID_ALL, len, log); } /** nvme_get_log_supported_log_pages() - Retrieve nmve supported log pages @@ -864,8 +865,12 @@ static inline int nvme_get_log_simple(int fd, enum nvme_cmd_get_log_lid lid, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_get_log_supported_log_pages(int fd, bool rae, - struct nvme_supported_log_pages *log); +static inline int nvme_get_log_supported_log_pages(int fd, bool rae, + struct nvme_supported_log_pages *log) +{ + return nvme_get_nsid_log(fd, rae, NVME_LOG_LID_SUPPORTED_LOG_PAGES, + NVME_NSID_ALL, sizeof(*log), log); +} /** * nvme_get_log_error() - Retrieve nvme error log @@ -881,8 +886,13 @@ 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. */ -int nvme_get_log_error(int fd, unsigned nr_entries, bool rae, - struct nvme_error_log_page *log); +static inline int nvme_get_log_error(int fd, unsigned nr_entries, bool rae, + struct nvme_error_log_page *log) +{ + return nvme_get_nsid_log(fd, rae, NVME_LOG_LID_ERROR, + NVME_NSID_ALL, sizeof(*log) * nr_entries, log); +} + /** * nvme_get_log_smart() - Retrieve nvme smart log @@ -901,7 +911,12 @@ int nvme_get_log_error(int fd, unsigned nr_entries, bool rae, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_get_log_smart(int fd, __u32 nsid, bool rae, struct nvme_smart_log *log); +static inline int nvme_get_log_smart(int fd, __u32 nsid, bool rae, + struct nvme_smart_log *log) +{ + return nvme_get_nsid_log(fd, rae, NVME_LOG_LID_SMART, + nsid, sizeof(*log), log); +} /** * nvme_get_log_fw_slot() - Retrieves the controller firmware log @@ -916,7 +931,13 @@ int nvme_get_log_smart(int fd, __u32 nsid, bool rae, struct nvme_smart_log *log) * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_get_log_fw_slot(int fd, bool rae, struct nvme_firmware_slot *log); +static inline int nvme_get_log_fw_slot(int fd, bool rae, + struct nvme_firmware_slot *log) +{ + return nvme_get_nsid_log(fd, rae, NVME_LOG_LID_SMART, + NVME_NSID_ALL, sizeof(*log), log); +} + /** * nvme_get_log_changed_ns_list() - Retrieve namespace changed list @@ -931,7 +952,13 @@ int nvme_get_log_fw_slot(int fd, bool rae, struct nvme_firmware_slot *log); * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_get_log_changed_ns_list(int fd, bool rae, struct nvme_ns_list *log); +static inline int nvme_get_log_changed_ns_list(int fd, bool rae, + struct nvme_ns_list *log) +{ + return nvme_get_nsid_log(fd, rae, NVME_LOG_LID_CHANGED_NS, + NVME_NSID_ALL, sizeof(*log), log); +} + /** * nvme_get_log_cmd_effects() - Retrieve nvme command effects log @@ -945,8 +972,28 @@ int nvme_get_log_changed_ns_list(int fd, bool rae, struct nvme_ns_list *log); * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_get_log_cmd_effects(int fd, enum nvme_csi csi, - struct nvme_cmd_effects_log *log); +static inline int nvme_get_log_cmd_effects(int fd, enum nvme_csi csi, + struct nvme_cmd_effects_log *log) +{ + struct nvme_get_log_args args = { + .args_size = sizeof(args), + .fd = fd, + .lid = NVME_LOG_LID_CMD_EFFECTS, + .nsid = NVME_NSID_ALL, + .lpo = 0, + .lsp = NVME_LOG_LSP_NONE, + .lsi = NVME_LOG_LSI_NONE, + .rae = false, + .uuidx = NVME_UUID_NONE, + .len = sizeof(*log), + .log = log, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + .csi = csi, + .ot = false, + }; + return nvme_get_log(&args); +} /** * nvme_get_log_device_self_test() - Retrieve the device self test log @@ -961,12 +1008,40 @@ int nvme_get_log_cmd_effects(int fd, enum nvme_csi csi, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_get_log_device_self_test(int fd, struct nvme_self_test_log *log); +static inline int nvme_get_log_device_self_test(int fd, + struct nvme_self_test_log *log) +{ + return nvme_get_nsid_log(fd, false, NVME_LOG_LID_DEVICE_SELF_TEST, + NVME_NSID_ALL, sizeof(*log), log); +} + /** * nvme_get_log_create_telemetry_host() - */ -int nvme_get_log_create_telemetry_host(int fd, struct nvme_telemetry_log *log); +static inline int nvme_get_log_create_telemetry_host(int fd, + struct nvme_telemetry_log *log) +{ + struct nvme_get_log_args args = { + .args_size = sizeof(args), + .fd = fd, + .lid = NVME_LOG_LID_TELEMETRY_HOST, + .nsid = NVME_NSID_NONE, + .lpo = 0, + .lsp = NVME_LOG_TELEM_HOST_LSP_CREATE, + .lsi = NVME_LOG_LSI_NONE, + .rae = false, + .uuidx = NVME_UUID_NONE, + .len = sizeof(*log), + .log = log, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + .csi = NVME_CSI_NVM, + .ot = false, + }; + return nvme_get_log(&args); +} + /** * nvme_get_log_telemetry_host() - @@ -981,7 +1056,28 @@ int nvme_get_log_create_telemetry_host(int fd, struct nvme_telemetry_log *log); * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_get_log_telemetry_host(int fd, __u64 offset, __u32 len, void *log); +static inline int nvme_get_log_telemetry_host(int fd, __u64 offset, + __u32 len, void *log) +{ + struct nvme_get_log_args args = { + .args_size = sizeof(args), + .fd = fd, + .lid = NVME_LOG_LID_TELEMETRY_HOST, + .nsid = NVME_NSID_NONE, + .lpo = 0, + .lsp = NVME_LOG_TELEM_HOST_LSP_RETAIN, + .lsi = NVME_LOG_LSI_NONE, + .rae = false, + .uuidx = NVME_UUID_NONE, + .len = len, + .log = log, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + .csi = NVME_CSI_NVM, + .ot = false, + }; + return nvme_get_log(&args); +} /** * nvme_get_log_telemetry_ctrl() - @@ -991,8 +1087,28 @@ int nvme_get_log_telemetry_host(int fd, __u64 offset, __u32 len, void *log); * @len: Length of provided user buffer to hold the log data in bytes * @log: User address for log page data */ -int nvme_get_log_telemetry_ctrl(int fd, bool rae, __u64 offset, __u32 len, - void *log); +static inline int nvme_get_log_telemetry_ctrl(int fd, bool rae, + __u64 offset, __u32 len, void *log) +{ + struct nvme_get_log_args args = { + .args_size = sizeof(args), + .fd = fd, + .lid = NVME_LOG_LID_TELEMETRY_CTRL, + .nsid = NVME_NSID_NONE, + .lpo = offset, + .lsp = NVME_LOG_LSP_NONE, + .lsi = NVME_LOG_LSI_NONE, + .rae = rae, + .uuidx = NVME_UUID_NONE, + .len = len, + .log = log, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + .csi = NVME_CSI_NVM, + .ot = false, + }; + return nvme_get_log(&args); +} /** * nvme_get_log_endurance_group() - @@ -1010,8 +1126,28 @@ int nvme_get_log_telemetry_ctrl(int fd, bool rae, __u64 offset, __u32 len, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_get_log_endurance_group(int fd, __u16 endgid, - struct nvme_endurance_group_log *log); +static inline int nvme_get_log_endurance_group(int fd, __u16 endgid, + struct nvme_endurance_group_log *log) +{ + struct nvme_get_log_args args = { + .args_size = sizeof(args), + .fd = fd, + .lid = NVME_LOG_LID_ENDURANCE_GROUP, + .nsid = NVME_NSID_NONE, + .lpo = 0, + .lsp = NVME_LOG_LSP_NONE, + .lsi = endgid, + .rae = false, + .uuidx = NVME_UUID_NONE, + .len = sizeof(*log), + .log = log, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + .csi = NVME_CSI_NVM, + .ot = false, + }; + return nvme_get_log(&args); +} /** * nvme_get_log_predictable_lat_nvmset() - @@ -1021,16 +1157,56 @@ int nvme_get_log_endurance_group(int fd, __u16 endgid, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_get_log_predictable_lat_nvmset(int fd, __u16 nvmsetid, - struct nvme_nvmset_predictable_lat_log *log); +static inline int nvme_get_log_predictable_lat_nvmset(int fd, __u16 nvmsetid, + struct nvme_nvmset_predictable_lat_log *log) +{ + struct nvme_get_log_args args = { + .args_size = sizeof(args), + .fd = fd, + .lid = NVME_LOG_LID_PREDICTABLE_LAT_NVMSET, + .nsid = NVME_NSID_NONE, + .lpo = 0, + .lsp = NVME_LOG_LSP_NONE, + .lsi = nvmsetid, + .rae = false, + .uuidx = NVME_UUID_NONE, + .len = sizeof(*log), + .log = log, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + .csi = NVME_CSI_NVM, + .ot = false, + }; + return nvme_get_log(&args); +} /** * nvme_get_log_predictable_lat_event() - * @fd: File descriptor of nvme device * @rae: Retain asynchronous events */ -int nvme_get_log_predictable_lat_event(int fd, bool rae, __u32 offset, - __u32 len, void *log); +static inline int nvme_get_log_predictable_lat_event(int fd, bool rae, + __u32 offset, __u32 len, void *log) +{ + struct nvme_get_log_args args = { + .args_size = sizeof(args), + .fd = fd, + .lid = NVME_LOG_LID_PREDICTABLE_LAT_AGG, + .nsid = NVME_NSID_NONE, + .lpo = offset, + .lsp = NVME_LOG_LSP_NONE, + .lsi = NVME_LOG_LSI_NONE, + .rae = rae, + .uuidx = NVME_UUID_NONE, + .len = len, + .log = log, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + .csi = NVME_CSI_NVM, + .ot = false, + }; + return nvme_get_log(&args); +} /** * nvme_get_log_ana() - @@ -1049,8 +1225,29 @@ int nvme_get_log_predictable_lat_event(int fd, bool rae, __u32 offset, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_get_log_ana(int fd, enum nvme_log_ana_lsp lsp, bool rae, __u64 offset, - __u32 len, void *log); +static 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 = { + .args_size = sizeof(args), + .fd = fd, + .lid = NVME_LOG_LID_ANA, + .nsid = NVME_NSID_NONE, + .lpo = offset, + .lsp = lsp, + .lsi = NVME_LOG_LSI_NONE, + .rae = false, + .uuidx = NVME_UUID_NONE, + .len = len, + .log = log, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + .csi = NVME_CSI_NVM, + .ot = false, + }; + return nvme_get_log(&args); +} + /** * nvme_get_log_ana_groups() - @@ -1059,24 +1256,69 @@ int nvme_get_log_ana(int fd, enum nvme_log_ana_lsp lsp, bool rae, __u64 offset, * * See &struct nvme_ana_group_desc for the defintion of the returned structure. */ -int nvme_get_log_ana_groups(int fd, bool rae, __u32 len, - struct nvme_ana_group_desc *log); +static inline int nvme_get_log_ana_groups(int fd, bool rae, __u32 len, + struct nvme_ana_group_desc *log) +{ + return nvme_get_log_ana(fd, NVME_LOG_ANA_LSP_RGO_GROUPS_ONLY, rae, 0, + len, log); +} + /** * nvme_get_log_lba_status() - * @fd: File descriptor of nvme device * @rae: Retain asynchronous events */ -int nvme_get_log_lba_status(int fd, bool rae, __u64 offset, __u32 len, - void *log); +static inline int nvme_get_log_lba_status(int fd, bool rae, + __u64 offset, __u32 len, void *log) +{ + struct nvme_get_log_args args = { + .args_size = sizeof(args), + .fd = fd, + .lid = NVME_LOG_LID_LBA_STATUS, + .nsid = NVME_NSID_NONE, + .lpo = offset, + .lsp = NVME_LOG_LSP_NONE, + .lsi = NVME_LOG_LSI_NONE, + .rae = rae, + .uuidx = NVME_UUID_NONE, + .len = len, + .log = log, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + .csi = NVME_CSI_NVM, + .ot = false, + }; + return nvme_get_log(&args); +} /** * nvme_get_log_endurance_grp_evt() - * @fd: File descriptor of nvme device * @rae: Retain asynchronous events */ -int nvme_get_log_endurance_grp_evt(int fd, bool rae, __u32 offset, __u32 len, - void *log); +static inline int nvme_get_log_endurance_grp_evt(int fd, bool rae, + __u32 offset, __u32 len, void *log) +{ + struct nvme_get_log_args args = { + .args_size = sizeof(args), + .fd = fd, + .lid = NVME_LOG_LID_ENDURANCE_GRP_EVT, + .nsid = NVME_NSID_NONE, + .lpo = offset, + .lsp = NVME_LOG_LSP_NONE, + .lsi = NVME_LOG_LSI_NONE, + .rae = rae, + .uuidx = NVME_UUID_NONE, + .len = len, + .log = log, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + .csi = NVME_CSI_NVM, + .ot = false, + }; + return nvme_get_log(&args); +} /** * nvme_get_log_fid_supported_effects() - @@ -1087,8 +1329,13 @@ int nvme_get_log_endurance_grp_evt(int fd, bool rae, __u32 offset, __u32 len, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise */ -int nvme_get_log_fid_supported_effects(int fd, bool rae, - struct nvme_fid_supported_effects_log *log); +static inline int nvme_get_log_fid_supported_effects(int fd, bool rae, + struct nvme_fid_supported_effects_log *log) +{ + return nvme_get_nsid_log(fd, rae, NVME_LOG_LID_FID_SUPPORTED_EFFECTS, + NVME_NSID_NONE, sizeof(*log), log); +} + /** * nvme_get_log_boot_partition() - @@ -1101,8 +1348,29 @@ int nvme_get_log_fid_supported_effects(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 */ -int nvme_get_log_boot_partition(int fd, bool rae, __u8 lsp, __u32 len, - struct nvme_boot_partition *part); +static inline int nvme_get_log_boot_partition(int fd, bool rae, + __u8 lsp, __u32 len, struct nvme_boot_partition *part) +{ + struct nvme_get_log_args args = { + .args_size = sizeof(args), + .fd = fd, + .lid = NVME_LOG_LID_BOOT_PARTITION, + .nsid = NVME_NSID_NONE, + .lpo = 0, + .lsp = NVME_LOG_LSP_NONE, + .lsi = NVME_LOG_LSI_NONE, + .rae = rae, + .uuidx = NVME_UUID_NONE, + .len = len, + .log = part, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + .csi = NVME_CSI_NVM, + .ot = false, + }; + return nvme_get_log(&args); +} + /** * nvme_get_log_discovery() - @@ -1118,15 +1386,42 @@ int nvme_get_log_boot_partition(int fd, bool rae, __u8 lsp, __u32 len, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_get_log_discovery(int fd, bool rae, __u32 offset, __u32 len, void *log); +static inline int nvme_get_log_discovery(int fd, bool rae, + __u32 offset, __u32 len, void *log) +{ + struct nvme_get_log_args args = { + .args_size = sizeof(args), + .fd = fd, + .lid = NVME_LOG_LID_DISCOVER, + .nsid = NVME_NSID_NONE, + .lpo = offset, + .lsp = NVME_LOG_LSP_NONE, + .lsi = NVME_LOG_LSI_NONE, + .rae = rae, + .uuidx = NVME_UUID_NONE, + .len = len, + .log = log, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + .csi = NVME_CSI_NVM, + .ot = false, + }; + return nvme_get_log(&args); +} + /** * nvme_get_log_reservation() - * @fd: File descriptor of nvme device * @rae: Retain asynchronous events */ -int nvme_get_log_reservation(int fd, bool rae, - struct nvme_resv_notification_log *log); +static inline int nvme_get_log_reservation(int fd, bool rae, + struct nvme_resv_notification_log *log) +{ + return nvme_get_nsid_log(fd, rae, NVME_LOG_LID_RESERVATION, + NVME_NSID_ALL, sizeof(*log), log); +} + /** * nvme_get_log_sanitize() - @@ -1140,8 +1435,13 @@ int nvme_get_log_reservation(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. */ -int nvme_get_log_sanitize(int fd, bool rae, - struct nvme_sanitize_log_page *log); +static inline int nvme_get_log_sanitize(int fd, bool rae, + struct nvme_sanitize_log_page *log) +{ + return nvme_get_nsid_log(fd, rae, NVME_LOG_LID_SANITIZE, + NVME_NSID_ALL, sizeof(*log), log); +} + /** * nvme_get_log_zns_changed_zones() - @@ -1155,18 +1455,61 @@ int nvme_get_log_sanitize(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. */ -int nvme_get_log_zns_changed_zones(int fd, __u32 nsid, bool rae, - struct nvme_zns_changed_zone_log *log); +static inline int nvme_get_log_zns_changed_zones(int fd, __u32 nsid, bool rae, + struct nvme_zns_changed_zone_log *log) +{ + struct nvme_get_log_args args = { + .args_size = sizeof(args), + .fd = fd, + .lid = NVME_LOG_LID_ZNS_CHANGED_ZONES, + .nsid = nsid, + .lpo = 0, + .lsp = NVME_LOG_LSP_NONE, + .lsi = NVME_LOG_LSI_NONE, + .rae = rae, + .uuidx = NVME_UUID_NONE, + .len = sizeof(*log), + .log = log, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + .csi = NVME_CSI_ZNS, + .ot = false, + }; + return nvme_get_log(&args); +} + /** * nvme_get_log_persistent_event() - - * &fd: - * &action: - * @size: - * @pevent_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 */ -int nvme_get_log_persistent_event(int fd, enum nvme_pevent_log_action action, - __u32 size, void *pevent_log); +static inline int nvme_get_log_persistent_event(int fd, + enum nvme_pevent_log_action action, + __u32 size, void *pevent_log) +{ + struct nvme_get_log_args args = { + .args_size = sizeof(args), + .fd = fd, + .lid = NVME_LOG_LID_PERSISTENT_EVENT, + .nsid = NVME_NSID_ALL, + .lpo = 0, + .lsp = NVME_LOG_LSP_NONE, + .lsi = NVME_LOG_LSI_NONE, + .rae = false, + .uuidx = NVME_UUID_NONE, + .len = size, + .log = pevent_log, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + .csi = NVME_CSI_NVM, + .ot = false, + }; + return nvme_get_log(&args); +} + /** * nvme_set_features() - Set a feature attribute diff --git a/src/nvme/types.h b/src/nvme/types.h index 251ca68ad7..35fc37ff94 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -2773,6 +2773,11 @@ struct nvme_self_test_log { struct nvme_st_result result[NVME_LOG_ST_MAX_RESULTS]; } __attribute__((packed)); +enum nvme_cmd_get_log_telemetry_host_lsp { + NVME_LOG_TELEM_HOST_LSP_RETAIN = 0, + NVME_LOG_TELEM_HOST_LSP_CREATE = 1, +}; + /** * struct nvme_telemetry_log - Retrieve internal data specific to the * manufacturer. From b9fe7a8d54fda56ff1de8f6363f1c0c5636f65a1 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 17 Dec 2021 08:03:42 +0100 Subject: [PATCH 0321/1564] Use argument structure for nvme_set_features() and nvme_get_features() Use an argument structure instead of passing all arguments one by one. This allows for a future expansion of the argument list without having to change the library ABI. Also convert zns.c to use nvme_zns_report_zones() instead of calling nvme_zns_mgmt_recv() directly. Signed-off-by: Hannes Reinecke --- src/nvme/ioctl.c | 389 +++++++++++++++++++++++++++++++++++++---------- src/nvme/ioctl.h | 90 +++++++++-- 2 files changed, 381 insertions(+), 98 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 7b6038c09b..8349ad2196 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -629,36 +629,48 @@ int nvme_get_log(struct nvme_get_log_args *args) return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } -int nvme_set_features(int fd, __u8 fid, __u32 nsid, __u32 cdw11, __u32 cdw12, - bool save, __u8 uuidx, __u32 cdw15, __u32 data_len, - void *data, __u32 timeout, __u32 *result) +int nvme_set_features(struct nvme_set_features_args *args) { - __u32 cdw10 = NVME_SET(fid, FEATURES_CDW10_FID) | - NVME_SET(!!save, SET_FEATURES_CDW10_SAVE); - __u32 cdw14 = NVME_SET(uuidx, FEATURES_CDW14_UUID); + __u32 cdw10 = NVME_SET(args->fid, FEATURES_CDW10_FID) | + NVME_SET(!!args->save, SET_FEATURES_CDW10_SAVE); + __u32 cdw14 = NVME_SET(args->uuidx, FEATURES_CDW14_UUID); struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_set_features, - .nsid = nsid, - .addr = (__u64)(uintptr_t)data, - .data_len = data_len, + .nsid = args->nsid, + .addr = (__u64)(uintptr_t)args->data, + .data_len = args->data_len, .cdw10 = cdw10, - .cdw11 = cdw11, - .cdw12 = cdw12, + .cdw11 = args->cdw11, + .cdw12 = args->cdw12, .cdw14 = cdw14, - .cdw15 = cdw15, - .timeout_ms = timeout, + .cdw15 = args->cdw15, + .timeout_ms = args->timeout, }; - - return nvme_submit_admin_passthru(fd, &cmd, result); + if (args->args_size < sizeof(*args)) + return -EINVAL; + return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } static int __nvme_set_features(int fd, __u8 fid, __u32 cdw11, bool save, __u32 *result) { - return nvme_set_features(fd, fid, NVME_NSID_NONE, cdw11, 0, save, - NVME_UUID_NONE, 0, 0, NULL, - NVME_DEFAULT_IOCTL_TIMEOUT, result); + struct nvme_set_features_args args = { + .args_size = sizeof(args), + .fd = fd, + .fid = fid, + .nsid = NVME_NSID_NONE, + .cdw11 = cdw11, + .cdw12 = 0, + .save = save, + .uuidx = NVME_UUID_NONE, + .cdw15 = 0, + .data_len = 0, + .data = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = result, + }; + return nvme_set_features(&args); } int nvme_set_features_arbitration(int fd, __u8 ab, __u8 lpw, __u8 mpw, @@ -766,12 +778,23 @@ int nvme_set_features_timestamp(int fd, bool save, __u64 timestamp) { __le64 t = cpu_to_le64(timestamp); struct nvme_timestamp ts; + struct nvme_set_features_args args = { + .args_size = sizeof(args), + .fd = fd, + .nsid = NVME_NSID_NONE, + .cdw11 = 0, + .cdw12 = 0, + .save = save, + .uuidx = NVME_UUID_NONE, + .cdw15 = 0, + .data_len = sizeof(ts), + .data = &ts, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; memcpy(&t, ts.timestamp, sizeof(ts.timestamp)); - return nvme_set_features(fd, NVME_FEAT_FID_TIMESTAMP, - NVME_NSID_NONE, 0, 0, save, NVME_UUID_NONE, 0, - sizeof(ts), &ts, - NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + return nvme_set_features(&args); } int nvme_set_features_hctm(int fd, __u16 tmt2, __u16 tmt1, @@ -795,28 +818,68 @@ int nvme_set_features_nopsc(int fd, bool noppme, bool save, __u32 *result) int nvme_set_features_rrl(int fd, __u8 rrl, __u16 nvmsetid, bool save, __u32 *result) { - return nvme_set_features(fd, NVME_FEAT_FID_RRL, NVME_NSID_NONE, - nvmsetid, rrl, save, NVME_UUID_NONE, 0, 0, - NULL, NVME_DEFAULT_IOCTL_TIMEOUT, result); + struct nvme_set_features_args args = { + .args_size = sizeof(args), + .fd = fd, + .fid = NVME_FEAT_FID_RRL, + .nsid = NVME_NSID_NONE, + .cdw11 = nvmsetid, + .cdw12 = rrl, + .save = save, + .uuidx = NVME_UUID_NONE, + .cdw15 = 0, + .data_len = 0, + .data = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = result, + }; + + return nvme_set_features(&args); } int nvme_set_features_plm_config(int fd, bool plm, __u16 nvmsetid, bool save, struct nvme_plm_config *data, __u32 *result) { - return nvme_set_features(fd, NVME_FEAT_FID_PLM_CONFIG, - NVME_NSID_NONE, nvmsetid, !!plm, save, - NVME_UUID_NONE, 0, 0, NULL, - NVME_DEFAULT_IOCTL_TIMEOUT, result); + struct nvme_set_features_args args = { + .args_size = sizeof(args), + .fd = fd, + .fid = NVME_FEAT_FID_PLM_CONFIG, + .nsid = NVME_NSID_NONE, + .cdw11 = nvmsetid, + .cdw12 = !!plm, + .save = save, + .uuidx = NVME_UUID_NONE, + .cdw15 = 0, + .data_len = 0, + .data = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = result, + }; + + return nvme_set_features(&args); } int nvme_set_features_plm_window(int fd, enum nvme_feat_plm_window_select sel, __u16 nvmsetid, bool save, __u32 *result) { __u32 cdw12 = NVME_SET(sel, FEAT_PLMW_WS); + struct nvme_set_features_args args = { + .args_size = sizeof(args), + .fd = fd, + .fid = NVME_FEAT_FID_PLM_WINDOW, + .nsid = NVME_NSID_NONE, + .cdw11 = nvmsetid, + .cdw12 = cdw12, + .save = save, + .uuidx = NVME_UUID_NONE, + .cdw15 = 0, + .data_len = 0, + .data = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = result, + }; - return nvme_set_features(fd, NVME_FEAT_FID_PLM_WINDOW, NVME_NSID_NONE, - nvmsetid, cdw12, save, NVME_UUID_NONE, 0, 0, - NULL, NVME_DEFAULT_IOCTL_TIMEOUT, result); + return nvme_set_features(&args); } int nvme_set_features_lba_sts_interval(int fd, __u16 lsiri, __u16 lsipi, @@ -832,10 +895,23 @@ int nvme_set_features_lba_sts_interval(int fd, __u16 lsiri, __u16 lsipi, int nvme_set_features_host_behavior(int fd, bool save, struct nvme_feat_host_behavior *data) { - return nvme_set_features(fd, NVME_FEAT_FID_HOST_BEHAVIOR, - NVME_NSID_NONE, save, 0, 0, NVME_UUID_NONE, 0, - sizeof(*data), data, - NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + struct nvme_set_features_args args = { + .args_size = sizeof(args), + .fd = fd, + .fid = NVME_FEAT_FID_HOST_BEHAVIOR, + .nsid = NVME_NSID_NONE, + .cdw11 = 0, + .cdw12 = 0, + .save = save, + .uuidx = NVME_UUID_NONE, + .cdw15 = 0, + .data_len = sizeof(*data), + .data = data, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + + return nvme_set_features(&args); } int nvme_set_features_sanitize(int fd, bool nodrm, bool save, __u32 *result) @@ -864,10 +940,23 @@ int nvme_set_features_host_id(int fd, bool save, bool exhid, __u8 *hostid) { __u32 len = exhid ? 16 : 8; __u32 value = !!exhid; + struct nvme_set_features_args args = { + .args_size = sizeof(args), + .fd = fd, + .fid = NVME_FEAT_FID_HOST_ID, + .nsid = NVME_NSID_NONE, + .cdw11 = value, + .cdw12 = 0, + .save = save, + .uuidx = NVME_UUID_NONE, + .cdw15 = 0, + .data_len = len, + .data = hostid, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; - return nvme_set_features(fd, NVME_FEAT_FID_HOST_ID, NVME_NSID_NONE, - save, value, 0, NVME_UUID_NONE, 0, len, - hostid, NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + return nvme_set_features(&args); } int nvme_set_features_resv_mask(int fd, __u32 mask, bool save, __u32 *result) @@ -897,34 +986,46 @@ int nvme_set_features_iocs_profile(int fd, __u8 iocsi, bool save) save, NULL); } -int nvme_get_features(int fd, enum nvme_features_id fid, __u32 nsid, - enum nvme_get_features_sel sel, __u32 cdw11, __u8 uuidx, - __u32 data_len, void *data, __u32 timeout, __u32 *result) +int nvme_get_features(struct nvme_get_features_args *args) { - __u32 cdw10 = NVME_SET(fid, FEATURES_CDW10_FID) | - NVME_SET(sel, GET_FEATURES_CDW10_SEL); - __u32 cdw14 = NVME_SET(uuidx, FEATURES_CDW14_UUID); + __u32 cdw10 = NVME_SET(args->fid, FEATURES_CDW10_FID) | + NVME_SET(args->sel, GET_FEATURES_CDW10_SEL); + __u32 cdw14 = NVME_SET(args->uuidx, FEATURES_CDW14_UUID); struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_get_features, - .nsid = nsid, - .addr = (__u64)(uintptr_t)data, - .data_len = data_len, + .nsid = args->nsid, + .addr = (__u64)(uintptr_t)args->data, + .data_len = args->data_len, .cdw10 = cdw10, - .cdw11 = cdw11, + .cdw11 = args->cdw11, .cdw14 = cdw14, - .timeout_ms = timeout, + .timeout_ms = args->timeout, }; - return nvme_submit_admin_passthru(fd, &cmd, result); + if (args->args_size < sizeof(*args)) + return -EINVAL; + return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } static int __nvme_get_features(int fd, enum nvme_features_id fid, enum nvme_get_features_sel sel, __u32 *result) { - return nvme_get_features(fd, fid, NVME_NSID_NONE, sel, 0, - NVME_UUID_NONE, 0, NULL, - NVME_DEFAULT_IOCTL_TIMEOUT, result); + struct nvme_get_features_args args = { + .args_size = sizeof(args), + .fd = fd, + .fid = fid, + .nsid = NVME_NSID_NONE, + .sel = sel, + .cdw11 = 0, + .uuidx = NVME_UUID_NONE, + .data_len = 0, + .data = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = result, + }; + + return nvme_get_features(&args); } int nvme_get_features_arbitration(int fd, enum nvme_get_features_sel sel, @@ -943,9 +1044,21 @@ int nvme_get_features_lba_range(int fd, enum nvme_get_features_sel sel, struct nvme_lba_range_type *data, __u32 *result) { - return nvme_get_features(fd, NVME_FEAT_FID_LBA_RANGE, NVME_NSID_NONE, - sel, 0, NVME_UUID_NONE, 0, NULL, - NVME_DEFAULT_IOCTL_TIMEOUT, result); + struct nvme_get_features_args args = { + .args_size = sizeof(args), + .fd = fd, + .fid = NVME_FEAT_FID_LBA_RANGE, + .nsid = NVME_NSID_NONE, + .sel = sel, + .cdw11 = 0, + .uuidx = NVME_UUID_NONE, + .data_len = 0, + .data = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = result, + }; + + return nvme_get_features(&args); } int nvme_get_features_temp_thresh(int fd, enum nvme_get_features_sel sel, @@ -983,9 +1096,21 @@ int nvme_get_features_irq_coalesce(int fd, enum nvme_get_features_sel sel, int nvme_get_features_irq_config(int fd, enum nvme_get_features_sel sel, __u16 iv, __u32 *result) { - return nvme_get_features(fd, NVME_FEAT_FID_IRQ_CONFIG, NVME_NSID_NONE, - sel, iv, NVME_UUID_NONE, 0, NULL, - NVME_DEFAULT_IOCTL_TIMEOUT, result); + struct nvme_get_features_args args = { + .args_size = sizeof(args), + .fd = fd, + .fid = NVME_FEAT_FID_LBA_RANGE, + .nsid = NVME_NSID_NONE, + .sel = sel, + .cdw11 = iv, + .uuidx = NVME_UUID_NONE, + .data_len = 0, + .data = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = result, + }; + + return nvme_get_features(&args); } int nvme_get_features_write_atomic(int fd, enum nvme_get_features_sel sel, @@ -1004,9 +1129,21 @@ int nvme_get_features_async_event(int fd, enum nvme_get_features_sel sel, int nvme_get_features_auto_pst(int fd, enum nvme_get_features_sel sel, struct nvme_feat_auto_pst *apst, __u32 *result) { - return nvme_get_features(fd, NVME_FEAT_FID_AUTO_PST, NVME_NSID_NONE, - sel, 0, NVME_UUID_NONE, 0, NULL, - NVME_DEFAULT_IOCTL_TIMEOUT, result); + struct nvme_get_features_args args = { + .args_size = sizeof(args), + .fd = fd, + .fid = NVME_FEAT_FID_LBA_RANGE, + .nsid = NVME_NSID_NONE, + .sel = sel, + .cdw11 = 0, + .uuidx = NVME_UUID_NONE, + .data_len = 0, + .data = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = result, + }; + + return nvme_get_features(&args); } int nvme_get_features_host_mem_buf(int fd, enum nvme_get_features_sel sel, @@ -1018,9 +1155,21 @@ int nvme_get_features_host_mem_buf(int fd, enum nvme_get_features_sel sel, int nvme_get_features_timestamp(int fd, enum nvme_get_features_sel sel, struct nvme_timestamp *ts) { - return nvme_get_features(fd, NVME_FEAT_FID_TIMESTAMP, NVME_NSID_NONE, - sel, 0, NVME_UUID_NONE, 0, NULL, - NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + struct nvme_get_features_args args = { + .args_size = sizeof(args), + .fd = fd, + .fid = NVME_FEAT_FID_TIMESTAMP, + .nsid = NVME_NSID_NONE, + .sel = sel, + .cdw11 = 0, + .uuidx = NVME_UUID_NONE, + .data_len = sizeof(*ts), + .data = ts, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + + return nvme_get_features(&args); } int nvme_get_features_kato(int fd, enum nvme_get_features_sel sel, __u32 *result) @@ -1046,17 +1195,41 @@ int nvme_get_features_rrl(int fd, enum nvme_get_features_sel sel, __u32 *result) int nvme_get_features_plm_config(int fd, enum nvme_get_features_sel sel, __u16 nvmsetid, struct nvme_plm_config *data, __u32 *result) { - return nvme_get_features(fd, NVME_FEAT_FID_PLM_CONFIG, NVME_NSID_NONE, - sel, nvmsetid, NVME_UUID_NONE, 0, NULL, - NVME_DEFAULT_IOCTL_TIMEOUT, result); + struct nvme_get_features_args args = { + .args_size = sizeof(args), + .fd = fd, + .fid = NVME_FEAT_FID_PLM_CONFIG, + .nsid = NVME_NSID_NONE, + .sel = sel, + .cdw11 = nvmsetid, + .uuidx = NVME_UUID_NONE, + .data_len = 0, + .data = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = result, + }; + + return nvme_get_features(&args); } int nvme_get_features_plm_window(int fd, enum nvme_get_features_sel sel, __u16 nvmsetid, __u32 *result) { - return nvme_get_features(fd, NVME_FEAT_FID_PLM_WINDOW, NVME_NSID_NONE, - sel, nvmsetid, NVME_UUID_NONE, 0, NULL, - NVME_DEFAULT_IOCTL_TIMEOUT, result); + struct nvme_get_features_args args = { + .args_size = sizeof(args), + .fd = fd, + .fid = NVME_FEAT_FID_PLM_WINDOW, + .nsid = NVME_NSID_NONE, + .sel = sel, + .cdw11 = nvmsetid, + .uuidx = NVME_UUID_NONE, + .data_len = 0, + .data = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = result, + }; + + return nvme_get_features(&args); } int nvme_get_features_lba_sts_interval(int fd, enum nvme_get_features_sel sel, @@ -1070,9 +1243,21 @@ int nvme_get_features_host_behavior(int fd, enum nvme_get_features_sel sel, struct nvme_feat_host_behavior *data, __u32 *result) { - return nvme_get_features(fd, NVME_FEAT_FID_HOST_BEHAVIOR, - NVME_NSID_NONE, sel, 0, NVME_UUID_NONE, 0, - NULL, NVME_DEFAULT_IOCTL_TIMEOUT, result); + struct nvme_get_features_args args = { + .args_size = sizeof(args), + .fd = fd, + .fid = NVME_FEAT_FID_HOST_BEHAVIOR, + .nsid = NVME_NSID_NONE, + .sel = sel, + .cdw11 = 0, + .uuidx = NVME_UUID_NONE, + .data_len = 0, + .data = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = result, + }; + + return nvme_get_features(&args); } int nvme_get_features_sanitize(int fd, enum nvme_get_features_sel sel, @@ -1084,9 +1269,21 @@ int nvme_get_features_sanitize(int fd, enum nvme_get_features_sel sel, int nvme_get_features_endurance_event_cfg(int fd, enum nvme_get_features_sel sel, __u16 endgid, __u32 *result) { - return nvme_get_features(fd, NVME_FEAT_FID_ENDURANCE_EVT_CFG, - NVME_NSID_NONE, sel, 0, NVME_UUID_NONE, 0, - NULL, NVME_DEFAULT_IOCTL_TIMEOUT, result); + struct nvme_get_features_args args = { + .args_size = sizeof(args), + .fd = fd, + .fid = NVME_FEAT_FID_ENDURANCE_EVT_CFG, + .nsid = NVME_NSID_NONE, + .sel = sel, + .cdw11 = 0, + .uuidx = NVME_UUID_NONE, + .data_len = 0, + .data = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = result, + }; + + return nvme_get_features(&args); } int nvme_get_features_sw_progress(int fd, enum nvme_get_features_sel sel, @@ -1098,9 +1295,21 @@ int nvme_get_features_sw_progress(int fd, enum nvme_get_features_sel sel, int nvme_get_features_host_id(int fd, enum nvme_get_features_sel sel, bool exhid, __u32 len, __u8 *hostid) { - return nvme_get_features(fd, NVME_FEAT_FID_HOST_ID, NVME_NSID_NONE, sel, - !!exhid, NVME_UUID_NONE, len, hostid, - NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + struct nvme_get_features_args args = { + .args_size = sizeof(args), + .fd = fd, + .fid = NVME_FEAT_FID_HOST_ID, + .nsid = NVME_NSID_NONE, + .sel = sel, + .cdw11 = !!exhid, + .uuidx = NVME_UUID_NONE, + .data_len = len, + .data = hostid, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + + return nvme_get_features(&args); } int nvme_get_features_resv_mask(int fd, enum nvme_get_features_sel sel, @@ -1119,9 +1328,21 @@ int nvme_get_features_write_protect(int fd, __u32 nsid, enum nvme_get_features_sel sel, __u32 *result) { - return nvme_get_features(fd, NVME_FEAT_FID_WRITE_PROTECT, nsid, sel, 0, - NVME_UUID_NONE, 0, NULL, - NVME_DEFAULT_IOCTL_TIMEOUT, result); + struct nvme_get_features_args args = { + .args_size = sizeof(args), + .fd = fd, + .fid = NVME_FEAT_FID_WRITE_PROTECT, + .nsid = nsid, + .sel = sel, + .cdw11 = 0, + .uuidx = NVME_UUID_NONE, + .data_len = 0, + .data = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = result, + }; + + return nvme_get_features(&args); } int nvme_get_features_iocs_profile(int fd, enum nvme_get_features_sel sel, diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 66fd952c8a..13b5df9bab 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -1512,7 +1512,7 @@ static inline int nvme_get_log_persistent_event(int fd, /** - * nvme_set_features() - Set a feature attribute + * nvme_set_features_args - Arguments for the NVMe Admin Set Feature command * @fd: File descriptor of nvme device * @fid: Feature identifier * @nsid: Namespace ID, if applicable @@ -1525,20 +1525,53 @@ static inline int nvme_get_log_persistent_event(int fd, * @data: User address of feature data, if applicable * @timeout: Timeout in ms * @result: The command completion result from CQE dword0 + */ + +struct nvme_set_features_args { + int args_size; + int fd; + __u8 fid; + __u32 nsid; + __u32 cdw11; + __u32 cdw12; + bool save; + __u8 uuidx; + __u32 cdw15; + __u32 data_len; + void *data; + __u32 timeout; + __u32 *result; +}; + +/** + * nvme_set_features_args() - Set a feature attribute + * @args: &struct nvme_set_features_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_set_features(int fd, __u8 fid, __u32 nsid, __u32 cdw11, __u32 cdw12, - bool save, __u8 uuidx, __u32 cdw15, __u32 data_len, - void *data, __u32 timeout, __u32 *result); +int nvme_set_features(struct nvme_set_features_args *args); static inline int nvme_set_features_data(int fd, __u8 fid, __u32 nsid, __u32 cdw11, bool save, __u32 data_len, void *data, __u32 *result) { - return nvme_set_features(fd, fid, nsid, cdw11, 0, save, 0, 0, data_len, - data, NVME_DEFAULT_IOCTL_TIMEOUT, result); + struct nvme_set_features_args args = { + .args_size = sizeof(args), + .fd = fd, + .fid = fid, + .nsid = nsid, + .cdw11 = cdw11, + .cdw12 = 0, + .save = save, + .uuidx = 0, + .cdw15 = 0, + .data_len = data_len, + .data = data, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = result, + }; + return nvme_set_features(&args); } static inline int nvme_set_features_simple(int fd, __u8 fid, __u32 nsid, @@ -1878,31 +1911,60 @@ int nvme_set_features_write_protect(int fd, enum nvme_feat_nswpcfg_state state, int nvme_set_features_iocs_profile(int fd, __u8 iocsi, bool save); /** - * nvme_get_features() - Retrieve a feature attribute + * nvme_get_features_args - Arguments for the NVMe Admin Get Feature command * @fd: File descriptor of nvme device * @fid: Feature identifier, see &enum nvme_features_id * @nsid: Namespace ID, if applicable - * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @sel: Select which type of attribute to return, + * see &enum nvme_get_features_sel * @cdw11: Feature specific command dword11 field * @uuidx: UUID Index for differentiating vendor specific encoding * @data_len: Length of feature data, if applicable, in bytes * @data: User address of feature data, if applicable * @timeout: Timeout in ms * @result: The command completion result from CQE dword0 + */ +struct nvme_get_features_args { + int args_size; + int fd; + __u8 fid; + __u32 nsid; + enum nvme_get_features_sel sel; + __u32 cdw11; + __u8 uuidx; + __u32 data_len; + void *data; + __u32 timeout; + __u32 *result; +}; + +/** + * nvme_get_features() - Retrieve a feature attribute + * @args: &struct nvme_get_features_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_get_features(int fd, enum nvme_features_id fid, __u32 nsid, - enum nvme_get_features_sel sel, __u32 cdw11, __u8 uuidx, - __u32 data_len, void *data, __u32 timeout, __u32 *result); +int nvme_get_features(struct nvme_get_features_args *args); static inline int nvme_get_features_data(int fd, enum nvme_features_id fid, __u32 nsid, __u32 data_len, void *data, __u32 *result) { - return nvme_get_features(fd, fid, nsid, NVME_GET_FEATURES_SEL_CURRENT, - 0, 0, data_len, data, - NVME_DEFAULT_IOCTL_TIMEOUT, result); + struct nvme_get_features_args args = { + .args_size = sizeof(args), + .fd = fd, + .fid = fid, + .nsid = nsid, + .sel = NVME_GET_FEATURES_SEL_CURRENT, + .cdw11 = 0, + .uuidx = NVME_UUID_NONE, + .data_len = data_len, + .data = data, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = result, + }; + + return nvme_get_features(&args); } static inline int nvme_get_features_simple(int fd, enum nvme_features_id fid, __u32 nsid, __u32 *result) From 44cd480d99c16c27296a04c22e1af8158c24efe4 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 17 Dec 2021 08:03:42 +0100 Subject: [PATCH 0322/1564] Use argument structure for nvme_identify() Use an argument structure instead of passing all arguments one by one. This allows for a future expansion of the argument list without having to change the library ABI. Signed-off-by: Hannes Reinecke --- src/nvme/ioctl.c | 327 ++++++++++++++++++++++++++++++++++++----------- src/nvme/ioctl.h | 26 +++- 2 files changed, 274 insertions(+), 79 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 8349ad2196..9c87b9667b 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -365,37 +365,49 @@ enum features { NVME_FEATURES_IOCSP_IOCSCI_MASK = 0xff, }; -int nvme_identify(int fd, enum nvme_identify_cns cns, __u32 nsid, __u16 cntid, - __u16 nvmsetid, __u16 domid, __u8 uuidx, __u8 csi, - void *data, __u32 timeout, __u32 *result) +int nvme_identify(struct nvme_identify_args *args) { - __u32 cdw10 = NVME_SET(cntid, IDENTIFY_CDW10_CNTID) | - NVME_SET(cns, IDENTIFY_CDW10_CNS); - __u32 cdw11 = NVME_SET(nvmsetid, IDENTIFY_CDW11_NVMSETID) | - NVME_SET(domid, IDENTIFY_CDW11_DOMID) | - NVME_SET(csi, IDENTIFY_CDW11_CSI); - __u32 cdw14 = NVME_SET(uuidx, IDENTIFY_CDW14_UUID); + __u32 cdw10 = NVME_SET(args->cntid, IDENTIFY_CDW10_CNTID) | + NVME_SET(args->cns, IDENTIFY_CDW10_CNS); + __u32 cdw11 = NVME_SET(args->nvmsetid, IDENTIFY_CDW11_NVMSETID) | + NVME_SET(args->domid, IDENTIFY_CDW11_DOMID) | + NVME_SET(args->csi, IDENTIFY_CDW11_CSI); + __u32 cdw14 = NVME_SET(args->uuidx, IDENTIFY_CDW14_UUID); struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_identify, - .nsid = nsid, - .addr = (__u64)(uintptr_t)data, + .nsid = args->nsid, + .addr = (__u64)(uintptr_t)args->data, .data_len = NVME_IDENTIFY_DATA_SIZE, .cdw10 = cdw10, .cdw11 = cdw11, .cdw14 = cdw14, - .timeout_ms = timeout, + .timeout_ms = args->timeout, }; - return nvme_submit_admin_passthru(fd, &cmd, result); + if (args->args_size < sizeof(*args)) + return -EINVAL; + return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } static int __nvme_identify(int fd, __u8 cns, __u32 nsid, void *data) { - return nvme_identify(fd, cns, nsid, NVME_CNTLID_NONE, - NVME_NVMSETID_NONE, NVME_DOMID_NONE, - NVME_UUID_NONE, NVME_CSI_NVM, - data, NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + struct nvme_identify_args args = { + .args_size = sizeof(args), + .fd = fd, + .cns = cns, + .nsid = nsid, + .cntid = NVME_CNTLID_NONE, + .nvmsetid = NVME_NVMSETID_NONE, + .domid = NVME_DOMID_NONE, + .uuidx = NVME_UUID_NONE, + .csi = NVME_CSI_NVM, + .data = data, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + + return nvme_identify(&args); } int nvme_identify_ctrl(int fd, struct nvme_id_ctrl *id) @@ -432,20 +444,44 @@ int nvme_identify_allocated_ns_list(int fd, __u32 nsid, int nvme_identify_ctrl_list(int fd, __u16 cntid, struct nvme_ctrl_list *ctrlist) { + struct nvme_identify_args args = { + .args_size = sizeof(args), + .fd = fd, + .cns = NVME_IDENTIFY_CNS_CTRL_LIST, + .nsid = NVME_NSID_NONE, + .cntid = NVME_CNTLID_NONE, + .nvmsetid = NVME_NVMSETID_NONE, + .domid = NVME_DOMID_NONE, + .uuidx = NVME_UUID_NONE, + .csi = NVME_CSI_NVM, + .data = ctrlist, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + BUILD_ASSERT(sizeof(struct nvme_ctrl_list) == 4096); - return nvme_identify(fd, NVME_IDENTIFY_CNS_CTRL_LIST, - NVME_NSID_NONE, cntid, NVME_NVMSETID_NONE, - NVME_DOMID_NONE, NVME_UUID_NONE, NVME_CSI_NVM, - ctrlist, NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + return nvme_identify(&args); } int nvme_identify_nsid_ctrl_list(int fd, __u32 nsid, __u16 cntid, struct nvme_ctrl_list *ctrlist) { - return nvme_identify(fd, NVME_IDENTIFY_CNS_NS_CTRL_LIST, nsid, - cntid, NVME_NVMSETID_NONE, NVME_DOMID_NONE, - NVME_UUID_NONE, NVME_CSI_NVM, ctrlist, - NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + struct nvme_identify_args args = { + .args_size = sizeof(args), + .fd = fd, + .cns = NVME_IDENTIFY_CNS_NS_CTRL_LIST, + .nsid = nsid, + .cntid = cntid, + .nvmsetid = NVME_NVMSETID_NONE, + .domid = NVME_DOMID_NONE, + .uuidx = NVME_UUID_NONE, + .csi = NVME_CSI_NVM, + .data = ctrlist, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + + return nvme_identify(&args); } int nvme_identify_ns_descs(int fd, __u32 nsid, struct nvme_ns_id_desc *descs) @@ -456,31 +492,67 @@ int nvme_identify_ns_descs(int fd, __u32 nsid, struct nvme_ns_id_desc *descs) int nvme_identify_nvmset_list(int fd, __u16 nvmsetid, struct nvme_id_nvmset_list *nvmset) { + struct nvme_identify_args args = { + .args_size = sizeof(args), + .fd = fd, + .cns = NVME_IDENTIFY_CNS_NVMSET_LIST, + .nsid = NVME_NSID_NONE, + .cntid = NVME_CNTLID_NONE, + .nvmsetid = nvmsetid, + .domid = NVME_DOMID_NONE, + .uuidx = NVME_UUID_NONE, + .csi = NVME_CSI_NVM, + .data = nvmset, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + BUILD_ASSERT(sizeof(struct nvme_id_nvmset_list) == 4096); - return nvme_identify(fd, NVME_IDENTIFY_CNS_NVMSET_LIST, - NVME_NSID_NONE, NVME_CNTLID_NONE, nvmsetid, - NVME_DOMID_NONE, NVME_UUID_NONE, NVME_CSI_NVM, - nvmset, NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + return nvme_identify(&args); } int nvme_identify_primary_ctrl(int fd, __u16 cntid, struct nvme_primary_ctrl_cap *cap) { + struct nvme_identify_args args = { + .args_size = sizeof(args), + .fd = fd, + .cns = NVME_IDENTIFY_CNS_PRIMARY_CTRL_CAP, + .nsid = NVME_NSID_NONE, + .cntid = cntid, + .nvmsetid = NVME_NVMSETID_NONE, + .domid = NVME_DOMID_NONE, + .uuidx = NVME_UUID_NONE, + .csi = NVME_CSI_NVM, + .data = cap, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + BUILD_ASSERT(sizeof(struct nvme_primary_ctrl_cap) == 4096); - return nvme_identify(fd, NVME_IDENTIFY_CNS_PRIMARY_CTRL_CAP, - NVME_NSID_NONE, cntid, NVME_NVMSETID_NONE, - NVME_DOMID_NONE, NVME_UUID_NONE, NVME_CSI_NVM, - cap, NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + return nvme_identify(&args); } int nvme_identify_secondary_ctrl_list(int fd, __u32 nsid, __u16 cntid, struct nvme_secondary_ctrl_list *list) { + struct nvme_identify_args args = { + .args_size = sizeof(args), + .fd = fd, + .cns = NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST, + .nsid = nsid, + .cntid = cntid, + .nvmsetid = NVME_NVMSETID_NONE, + .domid = NVME_DOMID_NONE, + .uuidx = NVME_UUID_NONE, + .csi = NVME_CSI_NVM, + .data = list, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + BUILD_ASSERT(sizeof(struct nvme_secondary_ctrl_list) == 4096); - return nvme_identify(fd, NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST, - nsid, cntid, NVME_NVMSETID_NONE, - NVME_DOMID_NONE, NVME_UUID_NONE, NVME_CSI_NVM, - list, NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + return nvme_identify(&args); } int nvme_identify_ns_granularity(int fd, @@ -500,86 +572,193 @@ int nvme_identify_uuid(int fd, struct nvme_id_uuid_list *list) int nvme_identify_ctrl_csi(int fd, __u8 csi, void *data) { - return nvme_identify(fd, NVME_IDENTIFY_CNS_CSI_CTRL, NVME_NSID_NONE, - NVME_CNTLID_NONE, NVME_NVMSETID_NONE, - NVME_DOMID_NONE, NVME_UUID_NONE, csi, data, - NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + struct nvme_identify_args args = { + .args_size = sizeof(args), + .fd = fd, + .cns = NVME_IDENTIFY_CNS_CSI_CTRL, + .nsid = NVME_NSID_NONE, + .cntid = NVME_CNTLID_NONE, + .nvmsetid = NVME_NVMSETID_NONE, + .domid = NVME_DOMID_NONE, + .uuidx = NVME_UUID_NONE, + .csi = csi, + .data = data, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + + return nvme_identify(&args); } int nvme_identify_ns_csi(int fd, __u32 nsid, __u8 csi, void *data) { - return nvme_identify(fd, NVME_IDENTIFY_CNS_CSI_NS, nsid, - NVME_CNTLID_NONE, NVME_NVMSETID_NONE, - NVME_DOMID_NONE, NVME_UUID_NONE, csi, data, - NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + struct nvme_identify_args args = { + .args_size = sizeof(args), + .fd = fd, + .cns = NVME_IDENTIFY_CNS_CSI_NS, + .nsid = nsid, + .cntid = NVME_CNTLID_NONE, + .nvmsetid = NVME_NVMSETID_NONE, + .domid = NVME_DOMID_NONE, + .uuidx = NVME_UUID_NONE, + .csi = csi, + .data = data, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + + return nvme_identify(&args); } int nvme_identify_active_ns_list_csi(int fd, __u32 nsid, __u8 csi, struct nvme_ns_list *list) { + struct nvme_identify_args args = { + .args_size = sizeof(args), + .fd = fd, + .cns = NVME_IDENTIFY_CNS_NS_ACTIVE_LIST, + .nsid = nsid, + .cntid = NVME_CNTLID_NONE, + .nvmsetid = NVME_NVMSETID_NONE, + .domid = NVME_DOMID_NONE, + .uuidx = NVME_UUID_NONE, + .csi = csi, + .data = list, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + BUILD_ASSERT(sizeof(struct nvme_ns_list) == 4096); - return nvme_identify(fd, NVME_IDENTIFY_CNS_CSI_NS_ACTIVE_LIST, nsid, - NVME_CNTLID_NONE, NVME_NVMSETID_NONE, - NVME_DOMID_NONE, NVME_UUID_NONE, csi, list, - NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + return nvme_identify(&args); } int nvme_identify_allocated_ns_list_css(int fd, __u32 nsid, __u8 csi, struct nvme_ns_list *list) { - return nvme_identify(fd, NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST, nsid, - NVME_CNTLID_NONE, NVME_NVMSETID_NONE, - NVME_DOMID_NONE, NVME_UUID_NONE, csi, list, - NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + struct nvme_identify_args args = { + .args_size = sizeof(args), + .fd = fd, + .cns = NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST, + .nsid = nsid, + .cntid = NVME_CNTLID_NONE, + .nvmsetid = NVME_NVMSETID_NONE, + .domid = NVME_DOMID_NONE, + .uuidx = NVME_UUID_NONE, + .csi = csi, + .data = list, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + + return nvme_identify(&args); } int nvme_identify_domain_list(int fd, __u16 domid, struct nvme_id_domain_list *list) { + struct nvme_identify_args args = { + .args_size = sizeof(args), + .fd = fd, + .cns = NVME_IDENTIFY_CNS_DOMAIN_LIST, + .nsid = NVME_NSID_NONE, + .cntid = NVME_CNTLID_NONE, + .nvmsetid = NVME_NVMSETID_NONE, + .domid = domid, + .uuidx = NVME_UUID_NONE, + .csi = NVME_CSI_NVM, + .data = list, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + BUILD_ASSERT(sizeof(struct nvme_id_domain_list) == 4096); - return nvme_identify(fd, NVME_IDENTIFY_CNS_DOMAIN_LIST, NVME_NSID_NONE, - NVME_CNTLID_NONE, NVME_NVMSETID_NONE, - domid, NVME_UUID_NONE, NVME_CSI_NVM, list, - NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + return nvme_identify(&args); } int nvme_identify_endurance_group_list(int fd, __u16 endgrp_id, struct nvme_id_endurance_group_list *list) { + struct nvme_identify_args args = { + .args_size = sizeof(args), + .fd = fd, + .cns = NVME_IDENTIFY_CNS_ENDURANCE_GROUP_ID, + .nsid = NVME_NSID_NONE, + .cntid = NVME_CNTLID_NONE, + .nvmsetid = NVME_NVMSETID_NONE, + .domid = endgrp_id, + .uuidx = NVME_UUID_NONE, + .csi = NVME_CSI_NVM, + .data = list, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + BUILD_ASSERT(sizeof(struct nvme_id_endurance_group_list) == 4096); - return nvme_identify(fd, NVME_IDENTIFY_CNS_ENDURANCE_GROUP_ID, - NVME_NSID_NONE, NVME_CNTLID_NONE, - NVME_NVMSETID_NONE, endgrp_id, NVME_UUID_NONE, - NVME_CSI_NVM, list, NVME_DEFAULT_IOCTL_TIMEOUT, - NULL); + return nvme_identify(&args); } int nvme_identify_independent_identify_ns(int fd, __u32 nsid, struct nvme_id_independent_id_ns *ns) { + struct nvme_identify_args args = { + .args_size = sizeof(args), + .fd = fd, + .cns = NVME_IDENTIFY_CNS_CSI_INDEPENDENT_ID_NS, + .nsid = nsid, + .cntid = NVME_CNTLID_NONE, + .nvmsetid = NVME_NVMSETID_NONE, + .domid = NVME_DOMID_NONE, + .uuidx = NVME_UUID_NONE, + .csi = NVME_CSI_NVM, + .data = ns, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + BUILD_ASSERT(sizeof(struct nvme_id_independent_id_ns) == 4096); - return nvme_identify(fd, NVME_IDENTIFY_CNS_CSI_INDEPENDENT_ID_NS, - nsid, NVME_CNTLID_NONE, NVME_NVMSETID_NONE, - NVME_DOMID_NONE, NVME_UUID_NONE, NVME_CSI_NVM, - ns, NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + return nvme_identify(&args); } int nvme_identify_iocs(int fd, __u16 cntlid, struct nvme_id_iocs *iocs) { + struct nvme_identify_args args = { + .args_size = sizeof(args), + .fd = fd, + .cns = NVME_IDENTIFY_CNS_COMMAND_SET_STRUCTURE, + .nsid = NVME_NSID_NONE, + .cntid = cntlid, + .nvmsetid = NVME_NVMSETID_NONE, + .domid = NVME_DOMID_NONE, + .uuidx = NVME_UUID_NONE, + .csi = NVME_CSI_NVM, + .data = iocs, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + BUILD_ASSERT(sizeof(struct nvme_id_iocs) == 4096); - return nvme_identify(fd, NVME_IDENTIFY_CNS_COMMAND_SET_STRUCTURE, - NVME_NSID_NONE, cntlid, NVME_NVMSETID_NONE, - NVME_DOMID_NONE, NVME_UUID_NONE, NVME_CSI_NVM, - iocs, NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + return nvme_identify(&args); } int nvme_zns_identify_ns(int fd, __u32 nsid, struct nvme_zns_id_ns *data) { + struct nvme_identify_args args = { + .args_size = sizeof(args), + .fd = fd, + .cns = NVME_IDENTIFY_CNS_CSI_NS, + .nsid = nsid, + .cntid = NVME_CNTLID_NONE, + .nvmsetid = NVME_NVMSETID_NONE, + .domid = NVME_DOMID_NONE, + .uuidx = NVME_UUID_NONE, + .csi = NVME_CSI_ZNS, + .data = data, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + BUILD_ASSERT(sizeof(struct nvme_zns_id_ns) == 4096); - return nvme_identify(fd, NVME_IDENTIFY_CNS_CSI_NS, nsid, - NVME_CNTLID_NONE, NVME_NVMSETID_NONE, - NVME_DOMID_NONE, NVME_UUID_NONE, NVME_CSI_ZNS, - data, NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + return nvme_identify(&args); } int nvme_zns_identify_ctrl(int fd, struct nvme_zns_id_ctrl *id) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 13b5df9bab..446831e8ba 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -374,7 +374,7 @@ int nvme_ns_rescan(int fd); int nvme_get_nsid(int fd, __u32 *nsid); /** - * nvme_identify() - Send the NVMe Identify command + * nvme_identify_args - Arguments for the NVMe Identify command * @fd: File descriptor of nvme device * @cns: The Controller or Namespace structure, see @enum nvme_identify_cns * @nsid: Namespace identifier, if applicable @@ -386,6 +386,25 @@ int nvme_get_nsid(int fd, __u32 *nsid); * @data: User space destination address to transfer the data * @timeout: Timeout in ms (0 for default timeout) * @result: The command completion result from CQE dword0 + */ +struct nvme_identify_args { + int args_size; + int fd; + enum nvme_identify_cns cns; + __u32 nsid; + __u16 cntid; + __u16 nvmsetid; + __u16 domid; + __u8 uuidx; + enum nvme_csi csi; + void *data; + __u32 timeout; + __u32 *result; +}; + +/** + * nvme_identify() - Send the NVMe Identify command + * @args: &struct nvme_identify_args argument structure * * The Identify command returns a data buffer that describes information about * the NVM subsystem, the controller or the namespace(s). @@ -393,10 +412,7 @@ int nvme_get_nsid(int fd, __u32 *nsid); * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_identify(int fd, enum nvme_identify_cns cns, __u32 nsid, - __u16 cntid, __u16 nvmsetid, __u16 domid, - __u8 uuidx, __u8 csi, void *data, __u32 timeout, - __u32 *result); +int nvme_identify(struct nvme_identify_args *args); /** * nvme_identify_ctrl() - Retrieves nvme identify controller From 869fad3e5abfa421ea7cd0ff3abf052c00f9acdf Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 17 Dec 2021 13:43:19 +0100 Subject: [PATCH 0323/1564] Inline nvme_identify() wrapper functions No point in having wrapper functions as part of the libnvme library. Signed-off-by: Hannes Reinecke --- src/nvme/ioctl.c | 383 ---------------------------------------------- src/nvme/ioctl.h | 387 ++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 352 insertions(+), 418 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 9c87b9667b..29f9ba010b 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -390,389 +390,6 @@ int nvme_identify(struct nvme_identify_args *args) return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } -static int __nvme_identify(int fd, __u8 cns, __u32 nsid, void *data) -{ - struct nvme_identify_args args = { - .args_size = sizeof(args), - .fd = fd, - .cns = cns, - .nsid = nsid, - .cntid = NVME_CNTLID_NONE, - .nvmsetid = NVME_NVMSETID_NONE, - .domid = NVME_DOMID_NONE, - .uuidx = NVME_UUID_NONE, - .csi = NVME_CSI_NVM, - .data = data, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - }; - - return nvme_identify(&args); -} - -int nvme_identify_ctrl(int fd, struct nvme_id_ctrl *id) -{ - BUILD_ASSERT(sizeof(struct nvme_id_ctrl) == 4096); - return __nvme_identify(fd, NVME_IDENTIFY_CNS_CTRL, NVME_NSID_NONE, id); -} - -int nvme_identify_ns(int fd, __u32 nsid, struct nvme_id_ns *ns) -{ - BUILD_ASSERT(sizeof(struct nvme_id_ns) == 4096); - return __nvme_identify(fd, NVME_IDENTIFY_CNS_NS, nsid, ns); -} - -int nvme_identify_allocated_ns(int fd, __u32 nsid, struct nvme_id_ns *ns) -{ - return __nvme_identify(fd, NVME_IDENTIFY_CNS_ALLOCATED_NS, nsid, ns); -} - -int nvme_identify_active_ns_list(int fd, __u32 nsid, struct nvme_ns_list *list) -{ - BUILD_ASSERT(sizeof(struct nvme_ns_list) == 4096); - return __nvme_identify(fd, NVME_IDENTIFY_CNS_NS_ACTIVE_LIST, nsid, - list); -} - -int nvme_identify_allocated_ns_list(int fd, __u32 nsid, - struct nvme_ns_list *list) -{ - return __nvme_identify(fd, NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST, nsid, - list); -} - -int nvme_identify_ctrl_list(int fd, __u16 cntid, - struct nvme_ctrl_list *ctrlist) -{ - struct nvme_identify_args args = { - .args_size = sizeof(args), - .fd = fd, - .cns = NVME_IDENTIFY_CNS_CTRL_LIST, - .nsid = NVME_NSID_NONE, - .cntid = NVME_CNTLID_NONE, - .nvmsetid = NVME_NVMSETID_NONE, - .domid = NVME_DOMID_NONE, - .uuidx = NVME_UUID_NONE, - .csi = NVME_CSI_NVM, - .data = ctrlist, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - }; - - BUILD_ASSERT(sizeof(struct nvme_ctrl_list) == 4096); - return nvme_identify(&args); -} - -int nvme_identify_nsid_ctrl_list(int fd, __u32 nsid, __u16 cntid, - struct nvme_ctrl_list *ctrlist) -{ - struct nvme_identify_args args = { - .args_size = sizeof(args), - .fd = fd, - .cns = NVME_IDENTIFY_CNS_NS_CTRL_LIST, - .nsid = nsid, - .cntid = cntid, - .nvmsetid = NVME_NVMSETID_NONE, - .domid = NVME_DOMID_NONE, - .uuidx = NVME_UUID_NONE, - .csi = NVME_CSI_NVM, - .data = ctrlist, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - }; - - return nvme_identify(&args); -} - -int nvme_identify_ns_descs(int fd, __u32 nsid, struct nvme_ns_id_desc *descs) -{ - return __nvme_identify(fd, NVME_IDENTIFY_CNS_NS_DESC_LIST, nsid, descs); -} - -int nvme_identify_nvmset_list(int fd, __u16 nvmsetid, - struct nvme_id_nvmset_list *nvmset) -{ - struct nvme_identify_args args = { - .args_size = sizeof(args), - .fd = fd, - .cns = NVME_IDENTIFY_CNS_NVMSET_LIST, - .nsid = NVME_NSID_NONE, - .cntid = NVME_CNTLID_NONE, - .nvmsetid = nvmsetid, - .domid = NVME_DOMID_NONE, - .uuidx = NVME_UUID_NONE, - .csi = NVME_CSI_NVM, - .data = nvmset, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - }; - - BUILD_ASSERT(sizeof(struct nvme_id_nvmset_list) == 4096); - return nvme_identify(&args); -} - -int nvme_identify_primary_ctrl(int fd, __u16 cntid, - struct nvme_primary_ctrl_cap *cap) -{ - struct nvme_identify_args args = { - .args_size = sizeof(args), - .fd = fd, - .cns = NVME_IDENTIFY_CNS_PRIMARY_CTRL_CAP, - .nsid = NVME_NSID_NONE, - .cntid = cntid, - .nvmsetid = NVME_NVMSETID_NONE, - .domid = NVME_DOMID_NONE, - .uuidx = NVME_UUID_NONE, - .csi = NVME_CSI_NVM, - .data = cap, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - }; - - BUILD_ASSERT(sizeof(struct nvme_primary_ctrl_cap) == 4096); - return nvme_identify(&args); -} - -int nvme_identify_secondary_ctrl_list(int fd, __u32 nsid, __u16 cntid, - struct nvme_secondary_ctrl_list *list) -{ - struct nvme_identify_args args = { - .args_size = sizeof(args), - .fd = fd, - .cns = NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST, - .nsid = nsid, - .cntid = cntid, - .nvmsetid = NVME_NVMSETID_NONE, - .domid = NVME_DOMID_NONE, - .uuidx = NVME_UUID_NONE, - .csi = NVME_CSI_NVM, - .data = list, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - }; - - BUILD_ASSERT(sizeof(struct nvme_secondary_ctrl_list) == 4096); - return nvme_identify(&args); -} - -int nvme_identify_ns_granularity(int fd, - struct nvme_id_ns_granularity_list *list) -{ - BUILD_ASSERT(sizeof(struct nvme_id_ns_granularity_list) == 4096); - return __nvme_identify(fd, NVME_IDENTIFY_CNS_NS_GRANULARITY, - NVME_NSID_NONE, list); -} - -int nvme_identify_uuid(int fd, struct nvme_id_uuid_list *list) -{ - BUILD_ASSERT(sizeof(struct nvme_id_uuid_list) == 4096); - return __nvme_identify(fd, NVME_IDENTIFY_CNS_UUID_LIST, NVME_NSID_NONE, - list); -} - -int nvme_identify_ctrl_csi(int fd, __u8 csi, void *data) -{ - struct nvme_identify_args args = { - .args_size = sizeof(args), - .fd = fd, - .cns = NVME_IDENTIFY_CNS_CSI_CTRL, - .nsid = NVME_NSID_NONE, - .cntid = NVME_CNTLID_NONE, - .nvmsetid = NVME_NVMSETID_NONE, - .domid = NVME_DOMID_NONE, - .uuidx = NVME_UUID_NONE, - .csi = csi, - .data = data, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - }; - - return nvme_identify(&args); -} - -int nvme_identify_ns_csi(int fd, __u32 nsid, __u8 csi, void *data) -{ - struct nvme_identify_args args = { - .args_size = sizeof(args), - .fd = fd, - .cns = NVME_IDENTIFY_CNS_CSI_NS, - .nsid = nsid, - .cntid = NVME_CNTLID_NONE, - .nvmsetid = NVME_NVMSETID_NONE, - .domid = NVME_DOMID_NONE, - .uuidx = NVME_UUID_NONE, - .csi = csi, - .data = data, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - }; - - return nvme_identify(&args); -} - -int nvme_identify_active_ns_list_csi(int fd, __u32 nsid, __u8 csi, - struct nvme_ns_list *list) -{ - struct nvme_identify_args args = { - .args_size = sizeof(args), - .fd = fd, - .cns = NVME_IDENTIFY_CNS_NS_ACTIVE_LIST, - .nsid = nsid, - .cntid = NVME_CNTLID_NONE, - .nvmsetid = NVME_NVMSETID_NONE, - .domid = NVME_DOMID_NONE, - .uuidx = NVME_UUID_NONE, - .csi = csi, - .data = list, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - }; - - BUILD_ASSERT(sizeof(struct nvme_ns_list) == 4096); - return nvme_identify(&args); -} - -int nvme_identify_allocated_ns_list_css(int fd, __u32 nsid, __u8 csi, - struct nvme_ns_list *list) -{ - struct nvme_identify_args args = { - .args_size = sizeof(args), - .fd = fd, - .cns = NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST, - .nsid = nsid, - .cntid = NVME_CNTLID_NONE, - .nvmsetid = NVME_NVMSETID_NONE, - .domid = NVME_DOMID_NONE, - .uuidx = NVME_UUID_NONE, - .csi = csi, - .data = list, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - }; - - return nvme_identify(&args); -} - -int nvme_identify_domain_list(int fd, __u16 domid, - struct nvme_id_domain_list *list) -{ - struct nvme_identify_args args = { - .args_size = sizeof(args), - .fd = fd, - .cns = NVME_IDENTIFY_CNS_DOMAIN_LIST, - .nsid = NVME_NSID_NONE, - .cntid = NVME_CNTLID_NONE, - .nvmsetid = NVME_NVMSETID_NONE, - .domid = domid, - .uuidx = NVME_UUID_NONE, - .csi = NVME_CSI_NVM, - .data = list, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - }; - - BUILD_ASSERT(sizeof(struct nvme_id_domain_list) == 4096); - return nvme_identify(&args); -} - -int nvme_identify_endurance_group_list(int fd, __u16 endgrp_id, - struct nvme_id_endurance_group_list *list) -{ - struct nvme_identify_args args = { - .args_size = sizeof(args), - .fd = fd, - .cns = NVME_IDENTIFY_CNS_ENDURANCE_GROUP_ID, - .nsid = NVME_NSID_NONE, - .cntid = NVME_CNTLID_NONE, - .nvmsetid = NVME_NVMSETID_NONE, - .domid = endgrp_id, - .uuidx = NVME_UUID_NONE, - .csi = NVME_CSI_NVM, - .data = list, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - }; - - BUILD_ASSERT(sizeof(struct nvme_id_endurance_group_list) == 4096); - return nvme_identify(&args); -} - -int nvme_identify_independent_identify_ns(int fd, __u32 nsid, - struct nvme_id_independent_id_ns *ns) -{ - struct nvme_identify_args args = { - .args_size = sizeof(args), - .fd = fd, - .cns = NVME_IDENTIFY_CNS_CSI_INDEPENDENT_ID_NS, - .nsid = nsid, - .cntid = NVME_CNTLID_NONE, - .nvmsetid = NVME_NVMSETID_NONE, - .domid = NVME_DOMID_NONE, - .uuidx = NVME_UUID_NONE, - .csi = NVME_CSI_NVM, - .data = ns, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - }; - - BUILD_ASSERT(sizeof(struct nvme_id_independent_id_ns) == 4096); - return nvme_identify(&args); -} - -int nvme_identify_iocs(int fd, __u16 cntlid, struct nvme_id_iocs *iocs) -{ - struct nvme_identify_args args = { - .args_size = sizeof(args), - .fd = fd, - .cns = NVME_IDENTIFY_CNS_COMMAND_SET_STRUCTURE, - .nsid = NVME_NSID_NONE, - .cntid = cntlid, - .nvmsetid = NVME_NVMSETID_NONE, - .domid = NVME_DOMID_NONE, - .uuidx = NVME_UUID_NONE, - .csi = NVME_CSI_NVM, - .data = iocs, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - }; - - BUILD_ASSERT(sizeof(struct nvme_id_iocs) == 4096); - return nvme_identify(&args); -} - -int nvme_zns_identify_ns(int fd, __u32 nsid, struct nvme_zns_id_ns *data) -{ - struct nvme_identify_args args = { - .args_size = sizeof(args), - .fd = fd, - .cns = NVME_IDENTIFY_CNS_CSI_NS, - .nsid = nsid, - .cntid = NVME_CNTLID_NONE, - .nvmsetid = NVME_NVMSETID_NONE, - .domid = NVME_DOMID_NONE, - .uuidx = NVME_UUID_NONE, - .csi = NVME_CSI_ZNS, - .data = data, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - }; - - BUILD_ASSERT(sizeof(struct nvme_zns_id_ns) == 4096); - return nvme_identify(&args); -} - -int nvme_zns_identify_ctrl(int fd, struct nvme_zns_id_ctrl *id) -{ - BUILD_ASSERT(sizeof(struct nvme_zns_id_ctrl) == 4096); - return nvme_identify_ctrl_csi(fd, NVME_CSI_ZNS, id); -} - -int nvme_nvm_identify_ctrl(int fd, struct nvme_id_ctrl_nvm *id) -{ - BUILD_ASSERT(sizeof(struct nvme_id_ctrl_nvm ) == 4096); - return nvme_identify_ctrl_csi(fd, NVME_CSI_NVM, id); -} - int nvme_get_log(struct nvme_get_log_args *args) { __u32 numd = (args->len >> 2) - 1; diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 446831e8ba..6ce047b002 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -414,6 +414,27 @@ 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) +{ + struct nvme_identify_args args = { + .args_size = sizeof(args), + .fd = fd, + .cns = cns, + .nsid = nsid, + .cntid = NVME_CNTLID_NONE, + .nvmsetid = NVME_NVMSETID_NONE, + .domid = NVME_DOMID_NONE, + .uuidx = NVME_UUID_NONE, + .csi = NVME_CSI_NVM, + .data = data, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + + return nvme_identify(&args); +} + /** * nvme_identify_ctrl() - Retrieves nvme identify controller * @fd: File descriptor of nvme device @@ -426,7 +447,11 @@ int nvme_identify(struct nvme_identify_args *args); * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_identify_ctrl(int fd, struct nvme_id_ctrl *id); +static inline int nvme_identify_ctrl(int fd, struct nvme_id_ctrl *id) +{ + return nvme_identify_cns_nsid(fd, NVME_IDENTIFY_CNS_CTRL, + NVME_NSID_NONE, id); +} /** * nvme_identify_ns() - Retrieves nvme identify namespace @@ -448,7 +473,10 @@ int nvme_identify_ctrl(int fd, struct nvme_id_ctrl *id); * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_identify_ns(int fd, __u32 nsid, struct nvme_id_ns *ns); +static inline int nvme_identify_ns(int fd, __u32 nsid, struct nvme_id_ns *ns) +{ + return nvme_identify_cns_nsid(fd, NVME_IDENTIFY_CNS_NS, nsid, ns); +} /** * nvme_identify_allocated_ns() - Same as nvme_identify_ns, but only for @@ -460,7 +488,12 @@ int nvme_identify_ns(int fd, __u32 nsid, struct nvme_id_ns *ns); * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_identify_allocated_ns(int fd, __u32 nsid, struct nvme_id_ns *ns); +static inline int nvme_identify_allocated_ns(int fd, __u32 nsid, + struct nvme_id_ns *ns) +{ + return nvme_identify_cns_nsid(fd, NVME_IDENTIFY_CNS_ALLOCATED_NS, + nsid, ns); +} /** * nvme_identify_active_ns_list() - Retrieves active namespaces id list @@ -477,7 +510,12 @@ int nvme_identify_allocated_ns(int fd, __u32 nsid, struct nvme_id_ns *ns); * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_identify_active_ns_list(int fd, __u32 nsid, struct nvme_ns_list *list); +static inline int nvme_identify_active_ns_list(int fd, __u32 nsid, + struct nvme_ns_list *list) +{ + return nvme_identify_cns_nsid(fd, NVME_IDENTIFY_CNS_NS_ACTIVE_LIST, + nsid, list); +} /** * nvme_identify_allocated_ns_list() - Retrieves allocated namespace id list @@ -494,8 +532,12 @@ int nvme_identify_active_ns_list(int fd, __u32 nsid, struct nvme_ns_list *list); * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_identify_allocated_ns_list(int fd, __u32 nsid, - struct nvme_ns_list *list); +static inline int nvme_identify_allocated_ns_list(int fd, __u32 nsid, + struct nvme_ns_list *list) +{ + return nvme_identify_cns_nsid(fd, NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST, + nsid, list); +} /** * nvme_identify_ctrl_list() - Retrieves identify controller list @@ -512,8 +554,26 @@ int nvme_identify_allocated_ns_list(int fd, __u32 nsid, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_identify_ctrl_list(int fd, __u16 cntid, - struct nvme_ctrl_list *ctrlist); +static inline int nvme_identify_ctrl_list(int fd, __u16 cntid, + struct nvme_ctrl_list *ctrlist) +{ + struct nvme_identify_args args = { + .args_size = sizeof(args), + .fd = fd, + .cns = NVME_IDENTIFY_CNS_CTRL_LIST, + .nsid = NVME_NSID_NONE, + .cntid = cntid, + .nvmsetid = NVME_NVMSETID_NONE, + .domid = NVME_DOMID_NONE, + .uuidx = NVME_UUID_NONE, + .csi = NVME_CSI_NVM, + .data = ctrlist, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + + return nvme_identify(&args); +} /** * nvme_identify_nsid_ctrl_list() - @@ -531,8 +591,26 @@ int nvme_identify_ctrl_list(int fd, __u16 cntid, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 */ -int nvme_identify_nsid_ctrl_list(int fd, __u32 nsid, __u16 cntid, - struct nvme_ctrl_list *ctrlist); +static inline int nvme_identify_nsid_ctrl_list(int fd, __u32 nsid, __u16 cntid, + struct nvme_ctrl_list *ctrlist) +{ + struct nvme_identify_args args = { + .args_size = sizeof(args), + .fd = fd, + .cns = NVME_IDENTIFY_CNS_NS_CTRL_LIST, + .nsid = nsid, + .cntid = cntid, + .nvmsetid = NVME_NVMSETID_NONE, + .domid = NVME_DOMID_NONE, + .uuidx = NVME_UUID_NONE, + .csi = NVME_CSI_NVM, + .data = ctrlist, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + + return nvme_identify(&args); +} /** * nvme_identify_ns_descs() - Retrieves namespace descriptor list @@ -551,7 +629,12 @@ int nvme_identify_nsid_ctrl_list(int fd, __u32 nsid, __u16 cntid, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_identify_ns_descs(int fd, __u32 nsid, struct nvme_ns_id_desc *descs); +static inline int nvme_identify_ns_descs(int fd, __u32 nsid, + struct nvme_ns_id_desc *descs) +{ + return nvme_identify_cns_nsid(fd, NVME_IDENTIFY_CNS_NS_DESC_LIST, + nsid, descs); +} /** * nvme_identify_nvmset_list() - Retrieves NVM Set List @@ -569,8 +652,26 @@ int nvme_identify_ns_descs(int fd, __u32 nsid, struct nvme_ns_id_desc *descs); * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_identify_nvmset_list(int fd, __u16 nvmsetid, - struct nvme_id_nvmset_list *nvmset); +static inline int nvme_identify_nvmset_list(int fd, __u16 nvmsetid, + struct nvme_id_nvmset_list *nvmset) +{ + struct nvme_identify_args args = { + .args_size = sizeof(args), + .fd = fd, + .cns = NVME_IDENTIFY_CNS_NVMSET_LIST, + .nsid = NVME_NSID_NONE, + .cntid = NVME_CNTLID_NONE, + .nvmsetid = nvmsetid, + .domid = NVME_DOMID_NONE, + .uuidx = NVME_UUID_NONE, + .csi = NVME_CSI_NVM, + .data = nvmset, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + + return nvme_identify(&args); +} /** * nvme_identify_primary_ctrl() - Retrieve NVMe Primary Controller @@ -584,8 +685,26 @@ int nvme_identify_nvmset_list(int fd, __u16 nvmsetid, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_identify_primary_ctrl(int fd, __u16 cntid, - struct nvme_primary_ctrl_cap *cap); +static inline int nvme_identify_primary_ctrl(int fd, __u16 cntid, + struct nvme_primary_ctrl_cap *cap) +{ + struct nvme_identify_args args = { + .args_size = sizeof(args), + .fd = fd, + .cns = NVME_IDENTIFY_CNS_PRIMARY_CTRL_CAP, + .nsid = NVME_NSID_NONE, + .cntid = cntid, + .nvmsetid = NVME_NVMSETID_NONE, + .domid = NVME_DOMID_NONE, + .uuidx = NVME_UUID_NONE, + .csi = NVME_CSI_NVM, + .data = cap, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + + return nvme_identify(&args); +} /** * nvme_identify_secondary_ctrl_list() - Retrieves secondary controller list @@ -605,8 +724,26 @@ int nvme_identify_primary_ctrl(int fd, __u16 cntid, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_identify_secondary_ctrl_list(int fd, __u32 nsid, __u16 cntid, - struct nvme_secondary_ctrl_list *list); +static inline int nvme_identify_secondary_ctrl_list(int fd, __u32 nsid, + __u16 cntid, struct nvme_secondary_ctrl_list *list) +{ + struct nvme_identify_args args = { + .args_size = sizeof(args), + .fd = fd, + .cns = NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST, + .nsid = nsid, + .cntid = cntid, + .nvmsetid = NVME_NVMSETID_NONE, + .domid = NVME_DOMID_NONE, + .uuidx = NVME_UUID_NONE, + .csi = NVME_CSI_NVM, + .data = list, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + + return nvme_identify(&args); +} /** * nvme_identify_ns_granularity() - Retrieves namespace granularity @@ -624,7 +761,12 @@ int nvme_identify_secondary_ctrl_list(int fd, __u32 nsid, __u16 cntid, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_identify_ns_granularity(int fd, struct nvme_id_ns_granularity_list *list); +static inline int nvme_identify_ns_granularity(int fd, + struct nvme_id_ns_granularity_list *list) +{ + return nvme_identify_cns_nsid(fd, NVME_IDENTIFY_CNS_NS_GRANULARITY, + NVME_NSID_NONE, list); +} /** * nvme_identify_uuid() - Retrieves device's UUIDs @@ -639,7 +781,11 @@ int nvme_identify_ns_granularity(int fd, struct nvme_id_ns_granularity_list *lis * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_identify_uuid(int fd, struct nvme_id_uuid_list *list); +static inline int nvme_identify_uuid(int fd, struct nvme_id_uuid_list *list) +{ + return nvme_identify_cns_nsid(fd, NVME_IDENTIFY_CNS_UUID_LIST, + NVME_NSID_NONE, list); +} /** * nvme_identify_ns_csi() - @@ -651,7 +797,26 @@ int nvme_identify_uuid(int fd, struct nvme_id_uuid_list *list); * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_identify_ns_csi(int fd, __u32 nsid, __u8 csi, void *data); +static inline int nvme_identify_ns_csi(int fd, __u32 nsid, + enum nvme_csi csi, void *data) +{ + struct nvme_identify_args args = { + .args_size = sizeof(args), + .fd = fd, + .cns = NVME_IDENTIFY_CNS_CSI_NS, + .nsid = nsid, + .cntid = NVME_CNTLID_NONE, + .nvmsetid = NVME_NVMSETID_NONE, + .domid = NVME_DOMID_NONE, + .uuidx = NVME_UUID_NONE, + .csi = csi, + .data = data, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + + return nvme_identify(&args); +} /** * nvme_identify_ctrl_csi() - @@ -662,7 +827,25 @@ int nvme_identify_ns_csi(int fd, __u32 nsid, __u8 csi, void *data); * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_identify_ctrl_csi(int fd, __u8 csi, void *data); +static inline int nvme_identify_ctrl_csi(int fd, enum nvme_csi csi, void *data) +{ + struct nvme_identify_args args = { + .args_size = sizeof(args), + .fd = fd, + .cns = NVME_IDENTIFY_CNS_CSI_CTRL, + .nsid = NVME_NSID_NONE, + .cntid = NVME_CNTLID_NONE, + .nvmsetid = NVME_NVMSETID_NONE, + .domid = NVME_DOMID_NONE, + .uuidx = NVME_UUID_NONE, + .csi = csi, + .data = data, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + + return nvme_identify(&args); +} /** * nvme_identify_active_ns_list_csi() - @@ -681,8 +864,26 @@ int nvme_identify_ctrl_csi(int fd, __u8 csi, void *data); * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_identify_active_ns_list_csi(int fd, __u32 nsid, __u8 csi, - struct nvme_ns_list *list); +static inline int nvme_identify_active_ns_list_csi(int fd, __u32 nsid, + enum nvme_csi csi, struct nvme_ns_list *list) +{ + struct nvme_identify_args args = { + .args_size = sizeof(args), + .fd = fd, + .cns = NVME_IDENTIFY_CNS_NS_ACTIVE_LIST, + .nsid = nsid, + .cntid = NVME_CNTLID_NONE, + .nvmsetid = NVME_NVMSETID_NONE, + .domid = NVME_DOMID_NONE, + .uuidx = NVME_UUID_NONE, + .csi = csi, + .data = list, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + + return nvme_identify(&args); +} /** * nvme_identify_allocated_ns_list_csi() - @@ -701,8 +902,26 @@ int nvme_identify_active_ns_list_csi(int fd, __u32 nsid, __u8 csi, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_identify_allocated_ns_list_csi(int fd, __u32 nsid, __u8 csi, - struct nvme_ns_list *list); +static inline int nvme_identify_allocated_ns_list_csi(int fd, __u32 nsid, + enum nvme_csi csi, struct nvme_ns_list *list) +{ + struct nvme_identify_args args = { + .args_size = sizeof(args), + .fd = fd, + .cns = NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST, + .nsid = nsid, + .cntid = NVME_CNTLID_NONE, + .nvmsetid = NVME_NVMSETID_NONE, + .domid = NVME_DOMID_NONE, + .uuidx = NVME_UUID_NONE, + .csi = csi, + .data = list, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + + return nvme_identify(&args); +} /** * nvme_identify_independent_identify_ns() - @@ -714,8 +933,26 @@ int nvme_identify_allocated_ns_list_csi(int fd, __u32 nsid, __u8 csi, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_identify_independent_identify_ns(int fd, __u32 nsid, - struct nvme_id_independent_id_ns *ns); +static inline int nvme_identify_independent_identify_ns(int fd, __u32 nsid, + struct nvme_id_independent_id_ns *ns) +{ + struct nvme_identify_args args = { + .args_size = sizeof(args), + .fd = fd, + .cns = NVME_IDENTIFY_CNS_CSI_INDEPENDENT_ID_NS, + .nsid = nsid, + .cntid = NVME_CNTLID_NONE, + .nvmsetid = NVME_NVMSETID_NONE, + .domid = NVME_DOMID_NONE, + .uuidx = NVME_UUID_NONE, + .csi = NVME_CSI_NVM, + .data = ns, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + + return nvme_identify(&args); +} /** * nvme_identify_ctrl_nvm() - @@ -725,7 +962,10 @@ int nvme_identify_independent_identify_ns(int fd, __u32 nsid, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_nvm_identify_ctrl(int fd, struct nvme_id_ctrl_nvm *id); +static inline int nvme_nvm_identify_ctrl(int fd, struct nvme_id_ctrl_nvm *id) +{ + return nvme_identify_ctrl_csi(fd, NVME_CSI_NVM, id); +} /** * nvme_idnetifY_domain_list() - @@ -743,8 +983,26 @@ int nvme_nvm_identify_ctrl(int fd, struct nvme_id_ctrl_nvm *id); * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_identify_domain_list(int fd, __u16 domid, - struct nvme_id_domain_list *list); +static inline int nvme_identify_domain_list(int fd, __u16 domid, + struct nvme_id_domain_list *list) +{ + struct nvme_identify_args args = { + .args_size = sizeof(args), + .fd = fd, + .cns = NVME_IDENTIFY_CNS_DOMAIN_LIST, + .nsid = NVME_NSID_NONE, + .cntid = NVME_CNTLID_NONE, + .nvmsetid = NVME_NVMSETID_NONE, + .domid = domid, + .uuidx = NVME_UUID_NONE, + .csi = NVME_CSI_NVM, + .data = list, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + + return nvme_identify(&args); +} /** * nvme_identifiy_endurance_group_list() - @@ -755,8 +1013,26 @@ int nvme_identify_domain_list(int fd, __u16 domid, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_identify_endurance_group_list(int fd, __u16 endgrp_id, - struct nvme_id_endurance_group_list *list); +static inline int nvme_identify_endurance_group_list(int fd, __u16 endgrp_id, + struct nvme_id_endurance_group_list *list) +{ + struct nvme_identify_args args = { + .args_size = sizeof(args), + .fd = fd, + .cns = NVME_IDENTIFY_CNS_ENDURANCE_GROUP_ID, + .nsid = NVME_NSID_NONE, + .cntid = NVME_CNTLID_NONE, + .nvmsetid = NVME_NVMSETID_NONE, + .domid = endgrp_id, + .uuidx = NVME_UUID_NONE, + .csi = NVME_CSI_NVM, + .data = list, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + + return nvme_identify(&args); +} /** * nvme_identify_iocs() - @@ -770,7 +1046,26 @@ int nvme_identify_endurance_group_list(int fd, __u16 endgrp_id, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_identify_iocs(int fd, __u16 cntlid, struct nvme_id_iocs *iocs); +static inline int nvme_identify_iocs(int fd, __u16 cntlid, + struct nvme_id_iocs *iocs) +{ + struct nvme_identify_args args = { + .args_size = sizeof(args), + .fd = fd, + .cns = NVME_IDENTIFY_CNS_COMMAND_SET_STRUCTURE, + .nsid = NVME_NSID_NONE, + .cntid = cntlid, + .nvmsetid = NVME_NVMSETID_NONE, + .domid = NVME_DOMID_NONE, + .uuidx = NVME_UUID_NONE, + .csi = NVME_CSI_NVM, + .data = iocs, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + + return nvme_identify(&args); +} /** * nvme_zns_identify_ns() - @@ -781,7 +1076,26 @@ int nvme_identify_iocs(int fd, __u16 cntlid, struct nvme_id_iocs *iocs); * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_zns_identify_ns(int fd, __u32 nsid, struct nvme_zns_id_ns *data); +static inline int nvme_zns_identify_ns(int fd, __u32 nsid, + struct nvme_zns_id_ns *data) +{ + struct nvme_identify_args args = { + .args_size = sizeof(args), + .fd = fd, + .cns = NVME_IDENTIFY_CNS_CSI_NS, + .nsid = nsid, + .cntid = NVME_CNTLID_NONE, + .nvmsetid = NVME_NVMSETID_NONE, + .domid = NVME_DOMID_NONE, + .uuidx = NVME_UUID_NONE, + .csi = NVME_CSI_ZNS, + .data = data, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + + return nvme_identify(&args); +} /** * nvme_zns_identify_ctrl() - @@ -791,7 +1105,10 @@ int nvme_zns_identify_ns(int fd, __u32 nsid, struct nvme_zns_id_ns *data); * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_zns_identify_ctrl(int fd, struct nvme_zns_id_ctrl *id); +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); +} /** * nvme_get_log_args - Arguments for the NVMe Admin Get Log command From bbab30b1bf810c04d0d076a077826985d8d8ee02 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 17 Dec 2021 08:03:42 +0100 Subject: [PATCH 0324/1564] Use argument structure for nvme_format_nvm() and nvme_ns_mgmt() Use an argument structure instead of passing all arguments one by one. This allows for a future expansion of the argument list without having to change the library ABI. Signed-off-by: Hannes Reinecke --- src/nvme/ioctl.c | 84 +++++++++++------------------- src/nvme/ioctl.h | 132 ++++++++++++++++++++++++++++++++++++++++------- src/nvme/linux.c | 15 ++++-- 3 files changed, 153 insertions(+), 78 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 29f9ba010b..44e3d1baa6 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -1147,87 +1147,63 @@ int nvme_get_features_iocs_profile(int fd, enum nvme_get_features_sel sel, return __nvme_get_features(fd, NVME_FEAT_FID_IOCS_PROFILE, sel, result); } -int nvme_format_nvm(int fd, __u32 nsid, __u8 lbaf, - enum nvme_cmd_format_mset mset, enum nvme_cmd_format_pi pi, - enum nvme_cmd_format_pil pil, enum nvme_cmd_format_ses ses, - __u32 timeout, __u32 *result) +int nvme_format_nvm(struct nvme_format_nvm_args *args) { - __u32 cdw10 = NVME_SET(lbaf, FORMAT_CDW10_LBAF) | - NVME_SET(mset, FORMAT_CDW10_MSET) | - NVME_SET(pi, FORMAT_CDW10_PI) | - NVME_SET(pil, FORMAT_CDW10_PIL) | - NVME_SET(ses, FORMAT_CDW10_SES); + __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); struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_format_nvm, - .nsid = nsid, + .nsid = args->nsid, .cdw10 = cdw10, - .timeout_ms = timeout, + .timeout_ms = args->timeout, }; - return nvme_submit_admin_passthru(fd, &cmd, result); + if (args->args_size < sizeof(*args)) + return -EINVAL; + return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } -int nvme_ns_mgmt(int fd, __u32 nsid, enum nvme_ns_mgmt_sel sel, - struct nvme_id_ns *ns, __u32 *result, __u32 timeout, __u8 csi) +int nvme_ns_mgmt(struct nvme_ns_mgmt_args *args) { - __u32 cdw10 = NVME_SET(sel, NAMESPACE_MGMT_CDW10_SEL); - __u32 cdw11 = NVME_SET(csi, NAMESPACE_MGMT_CDW11_CSI); - __u32 data_len = ns ? sizeof(*ns) : 0; + __u32 cdw10 = NVME_SET(args->sel, NAMESPACE_MGMT_CDW10_SEL); + __u32 cdw11 = NVME_SET(args->csi, NAMESPACE_MGMT_CDW11_CSI); + __u32 data_len = args->ns ? sizeof(*args->ns) : 0; struct nvme_passthru_cmd cmd = { - .nsid = nsid, + .nsid = args->nsid, .opcode = nvme_admin_ns_mgmt, .cdw10 = cdw10, .cdw11 = cdw11, - .timeout_ms = timeout, + .timeout_ms = args->timeout, .data_len = data_len, - .addr = (__u64)(uintptr_t)ns, + .addr = (__u64)(uintptr_t)args->ns, }; - return nvme_submit_admin_passthru(fd, &cmd, result); -} - -int nvme_ns_mgmt_create(int fd, struct nvme_id_ns *ns, __u32 *nsid, - __u32 timeout, __u8 csi) -{ - return nvme_ns_mgmt(fd, NVME_NSID_NONE, NVME_NS_MGMT_SEL_CREATE, ns, - nsid, timeout, csi); -} - -int nvme_ns_mgmt_delete(int fd, __u32 nsid) -{ - return nvme_ns_mgmt(fd, nsid, NVME_NS_MGMT_SEL_DELETE, NULL, NULL, 0, - 0); + if (args->args_size < sizeof(*args)) + return -EINVAL; + return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } -int nvme_ns_attach(int fd, __u32 nsid, enum nvme_ns_attach_sel sel, - struct nvme_ctrl_list *ctrlist, __u32 timeout) +int nvme_ns_attach(struct nvme_ns_attach_args *args) { - __u32 cdw10 = NVME_SET(sel, NAMESPACE_ATTACH_CDW10_SEL); + __u32 cdw10 = NVME_SET(args->sel, NAMESPACE_ATTACH_CDW10_SEL); struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_ns_attach, - .nsid = nsid, + .nsid = args->nsid, .cdw10 = cdw10, - .data_len = sizeof(*ctrlist), - .addr = (__u64)(uintptr_t)ctrlist, - .timeout_ms = timeout, + .data_len = sizeof(*args->ctrlist), + .addr = (__u64)(uintptr_t)args->ctrlist, + .timeout_ms = args->timeout, }; - return nvme_submit_admin_passthru(fd, &cmd, NULL); -} - -int nvme_ns_attach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist) -{ - return nvme_ns_attach(fd, nsid, NVME_NS_ATTACH_SEL_CTRL_ATTACH, - ctrlist, NVME_DEFAULT_IOCTL_TIMEOUT); -} - -int nvme_ns_detach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist) -{ - return nvme_ns_attach(fd, nsid, NVME_NS_ATTACH_SEL_CTRL_DEATTACH, - ctrlist, NVME_DEFAULT_IOCTL_TIMEOUT); + if (args->args_size < sizeof(*args)) + return -EINVAL; + return nvme_submit_admin_passthru(args->fd, &cmd, NULL); } int nvme_fw_download(int fd, __u32 offset, __u32 data_len, void *data, diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 6ce047b002..4e307919a3 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -2666,7 +2666,7 @@ int nvme_get_features_iocs_profile(int fd, enum nvme_get_features_sel sel, __u32 *result); /** - * nvme_format_nvm() - Format nvme namespace(s) + * nvme_format_nvm_args - Arguments for the Format Nvme Namespace command * @fd: File descriptor of nvme device * @nsid: Namespace ID to format * @lbaf: Logical block address format @@ -2677,6 +2677,23 @@ int nvme_get_features_iocs_profile(int fd, enum nvme_get_features_sel sel, * @timeout: Set to override default timeout to this value in milliseconds; * useful for long running formats. 0 will use system default. * @result: The command completion result from CQE dword0 + */ +struct nvme_format_nvm_args { + int args_size; + int fd; + __u32 nsid; + __u8 lbaf; + enum nvme_cmd_format_mset mset; + enum nvme_cmd_format_pi pi; + enum nvme_cmd_format_pil pil; + enum nvme_cmd_format_ses ses; + __u32 timeout; + __u32 *result; +}; + +/** + * nvme_format_nvm() - Format nvme namespace(s) + * @args: &struct nvme_format_nvme_args argument structure * * The Format NVM command low level formats the NVM media. This command is used * by the host to change the LBA data size and/or metadata size. A low level @@ -2686,25 +2703,34 @@ int nvme_get_features_iocs_profile(int fd, enum nvme_get_features_sel sel, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_format_nvm(int fd, __u32 nsid, __u8 lbaf, - enum nvme_cmd_format_mset mset, - enum nvme_cmd_format_pi pi, - enum nvme_cmd_format_pil pil, - enum nvme_cmd_format_ses ses, - __u32 timeout, __u32 *result); +int nvme_format_nvm(struct nvme_format_nvm_args *args); /** - * nvme_ns_mgmt() - + * nvme_ns_mgmt_args - Arguments for NVMe Namespace Management command * @fd: File descriptor of nvme device * @nsid: Namespace identifier - * @sel: + * @sel: Type of management operation to perform * @ns: Namespace identication descriptors * @result: NVMe command result * @timeout: Timeout in ms * @csi: Command Set Identifier */ -int nvme_ns_mgmt(int fd, __u32 nsid, enum nvme_ns_mgmt_sel sel, - struct nvme_id_ns *ns, __u32 *result, __u32 timeout, __u8 csi); +struct nvme_ns_mgmt_args { + int args_size; + int fd; + __u32 nsid; + enum nvme_ns_mgmt_sel sel; + struct nvme_id_ns *ns; + __u32 *result; + __u32 timeout; + __u8 csi; +}; + +/** + * nvme_ns_mgmt() - + * @args: &struct nvme_ns_mgmt_args Argument structure + */ +int nvme_ns_mgmt(struct nvme_ns_mgmt_args *args); /** * nvme_ns_mgmt_create() - @@ -2722,8 +2748,22 @@ int nvme_ns_mgmt(int fd, __u32 nsid, enum nvme_ns_mgmt_sel sel, * 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_create(int fd, struct nvme_id_ns *ns, __u32 *nsid, - __u32 timeout, __u8 csi); +static inline int nvme_ns_mgmt_create(int fd, struct nvme_id_ns *ns, + __u32 *nsid, __u32 timeout, __u8 csi) +{ + struct nvme_ns_mgmt_args args = { + .args_size = sizeof(args), + .fd = fd, + .nsid = NVME_NSID_NONE, + .sel = NVME_NS_MGMT_SEL_CREATE, + .ns = ns, + .result = nsid, + .timeout = timeout, + .csi = csi, + }; + + return nvme_ns_mgmt(&args); +} /** * nvme_ns_mgmt_delete() - @@ -2737,18 +2777,44 @@ int nvme_ns_mgmt_create(int fd, struct nvme_id_ns *ns, __u32 *nsid, * 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_delete(int fd, __u32 nsid); +static inline int nvme_ns_mgmt_delete(int fd, __u32 nsid) +{ + struct nvme_ns_mgmt_args args = { + .args_size = sizeof(args), + .fd = fd, + .nsid = nsid, + .sel = NVME_NS_MGMT_SEL_DELETE, + .ns = NULL, + .result = NULL, + .timeout = 0, + .csi = 0, + }; + + return nvme_ns_mgmt(&args); +} /** - * nvme_ns_attach() - Attach or detach namespace to controller(s) + * nvme_ns_attach_args - Arguments for Nvme Namespace Management command * @fd: File descriptor of nvme device * @nsid: Namespace ID to execute attach selection * @sel: Attachment selection, see &enum nvme_ns_attach_sel * @ctrlist: Controller list to modify attachment state of nsid * @timeout: Timeout in ms */ -int nvme_ns_attach(int fd, __u32 nsid, enum nvme_ns_attach_sel sel, - struct nvme_ctrl_list *ctrlist, __u32 timeout); +struct nvme_ns_attach_args { + int args_size; + int fd; + __u32 nsid; + enum nvme_ns_attach_sel sel; + struct nvme_ctrl_list *ctrlist; + __u32 timeout; +}; + +/** + * nvme_ns_attach_args - Attach or detach namespace to controller(s) + * @args: &struct nvme_ns_attach_args Argument structure + */ +int nvme_ns_attach(struct nvme_ns_attach_args *args); /** * nvme_ns_attach_ctrls() - @@ -2756,7 +2822,20 @@ int nvme_ns_attach(int fd, __u32 nsid, enum nvme_ns_attach_sel sel, * @nsid: Namespace ID to attach * @ctrlist: Controller list to modify attachment state of nsid */ -int nvme_ns_attach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist); +static inline int nvme_ns_attach_ctrls(int fd, __u32 nsid, + struct nvme_ctrl_list *ctrlist) +{ + struct nvme_ns_attach_args args = { + .args_size = sizeof(args), + .fd = fd, + .nsid = nsid, + .sel = NVME_NS_ATTACH_SEL_CTRL_ATTACH, + .ctrlist = ctrlist, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + }; + + return nvme_ns_attach(&args); +} /** * nvme_ns_detach_ctrls() - @@ -2764,7 +2843,20 @@ int nvme_ns_attach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist); * @nsid: Namespace ID to detach * @ctrlist: Controller list to modify attachment state of nsid */ -int nvme_ns_detach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist); +static inline int nvme_ns_detach_ctrls(int fd, __u32 nsid, + struct nvme_ctrl_list *ctrlist) +{ + struct nvme_ns_attach_args args = { + .args_size = sizeof(args), + .fd = fd, + .nsid = nsid, + .sel = NVME_NS_ATTACH_SEL_CTRL_DEATTACH, + .ctrlist = ctrlist, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + }; + + return nvme_ns_attach(&args); +} /** * nvme_fw_download() - Download part or all of a firmware image to the @@ -3016,7 +3108,7 @@ int nvme_directive_recv_stream_allocate(int fd, __u32 nsid, __u16 nsr, __u32 *result); /** - * nvme_capacity_mgmt() - + * nvme_capacity_mgmt_args - Arguments for the NVMe Capacity Management command * @fd: File descriptor of nvme device * @op: Operation to be performed by the controller * @element_id: Value specific to the value of the Operation field diff --git a/src/nvme/linux.c b/src/nvme/linux.c index 84786110bf..48a12e4ac8 100644 --- a/src/nvme/linux.c +++ b/src/nvme/linux.c @@ -280,14 +280,21 @@ int nvme_get_lba_status_log(int fd, bool rae, struct nvme_lba_status_log **log) static int nvme_ns_attachment(int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist, bool attach, __u32 timeout) { - enum nvme_ns_attach_sel sel = NVME_NS_ATTACH_SEL_CTRL_DEATTACH; struct nvme_ctrl_list cntlist = { 0 }; + struct nvme_ns_attach_args args = { + .args_size = sizeof(args), + .fd = fd, + .nsid = nsid, + .sel = NVME_NS_ATTACH_SEL_CTRL_DEATTACH, + .ctrlist = &cntlist, + .timeout = timeout, + }; if (attach) - sel = NVME_NS_ATTACH_SEL_CTRL_ATTACH; + args.sel = NVME_NS_ATTACH_SEL_CTRL_ATTACH; - nvme_init_ctrl_list(&cntlist, num_ctrls, ctrlist); - return nvme_ns_attach(fd, nsid, sel, &cntlist, timeout); + nvme_init_ctrl_list(args.ctrlist, num_ctrls, ctrlist); + return nvme_ns_attach(&args); } int nvme_namespace_attach_ctrls(int fd, __u32 nsid, __u16 num_ctrls, From aef4b82fd14c0fb4be9abf25f45ab0c7074cb9ba Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 17 Dec 2021 08:03:42 +0100 Subject: [PATCH 0325/1564] Use argument structure for nvme_fw_download() Use an argument structure instead of passing all arguments one by one. This allows for a future expansion of the argument list without having to change the library ABI. Signed-off-by: Hannes Reinecke --- src/nvme/ioctl.c | 17 +++++++++-------- src/nvme/ioctl.h | 21 +++++++++++++++++---- src/nvme/linux.c | 18 +++++++++++++----- 3 files changed, 39 insertions(+), 17 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 44e3d1baa6..d4dfe335f5 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -1206,22 +1206,23 @@ int nvme_ns_attach(struct nvme_ns_attach_args *args) return nvme_submit_admin_passthru(args->fd, &cmd, NULL); } -int nvme_fw_download(int fd, __u32 offset, __u32 data_len, void *data, - __u32 timeout, __u32 *result) +int nvme_fw_download(struct nvme_fw_download_args *args) { - __u32 cdw10 = (data_len >> 2) - 1; - __u32 cdw11 = offset >> 2; + __u32 cdw10 = (args->data_len >> 2) - 1; + __u32 cdw11 = args->offset >> 2; struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_fw_download, .cdw10 = cdw10, .cdw11 = cdw11, - .data_len = data_len, - .addr = (__u64)(uintptr_t)data, - .timeout_ms = timeout, + .data_len = args->data_len, + .addr = (__u64)(uintptr_t)args->data, + .timeout_ms = args->timeout, }; - return nvme_submit_admin_passthru(fd, &cmd, result); + if (args->args_size < sizeof(*args)) + return -EINVAL; + return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } int nvme_fw_commit(int fd, __u8 slot, enum nvme_fw_commit_ca action, bool bpid, diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 4e307919a3..c07c7f6508 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -2859,14 +2859,28 @@ static inline int nvme_ns_detach_ctrls(int fd, __u32 nsid, } /** - * nvme_fw_download() - Download part or all of a firmware image to the - * controller + * nvme_fw_download_args - Arguments for the NVMe Firmware Download command * @fd: File descriptor of nvme device * @offset: Offset in the firmware data * @data_len: Length of data in this command in bytes * @data: Userspace address of the firmware data * @timeout: Timeout in ms * @result: The command completion result from CQE dword0 + */ +struct nvme_fw_download_args { + int args_size; + int fd; + __u32 offset; + __u32 data_len; + void *data; + __u32 timeout; + __u32 *result; +}; + +/** + * nvme_fw_download() - Download part or all of a firmware image to the + * controller + * @args: &struct nvme_fw_download_args argument structure * * The Firmware Image Download command downloads all or a portion of an image * for a future update to the controller. The Firmware Image Download command @@ -2884,8 +2898,7 @@ static inline int nvme_ns_detach_ctrls(int fd, __u32 nsid, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_fw_download(int fd, __u32 offset, __u32 data_len, void *data, - __u32 timeout, __u32 *result); +int nvme_fw_download(struct nvme_fw_download_args *args); /** * nvme_fw_commit() - Commit firmware using the specified action diff --git a/src/nvme/linux.c b/src/nvme/linux.c index 48a12e4ac8..747d69b2ae 100644 --- a/src/nvme/linux.c +++ b/src/nvme/linux.c @@ -92,17 +92,25 @@ int nvme_fw_download_seq(int fd, __u32 size, __u32 xfer, __u32 offset, void *buf) { int err = 0; + struct nvme_fw_download_args args = { + .args_size = sizeof(args), + .fd = fd, + .offset = offset, + .data_len = xfer, + .data = buf, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; while (size > 0) { - xfer = MIN(xfer, size); - err = nvme_fw_download(fd, offset, xfer, buf, - NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + args.data_len = MIN(xfer, size); + err = nvme_fw_download(&args); if (err) break; - buf += xfer; + args.data += xfer; size -= xfer; - offset += xfer; + args.offset += xfer; } return err; From e4653281bdb9ec0a4f2af1893cbbcc6b46b184eb Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 17 Dec 2021 08:03:42 +0100 Subject: [PATCH 0326/1564] Use argument structure for nvme_fw_commit() Use an argument structure instead of passing all arguments one by one. This allows for a future expansion of the argument list without having to change the library ABI. Signed-off-by: Hannes Reinecke --- src/nvme/ioctl.c | 14 ++++++++------ src/nvme/ioctl.h | 25 +++++++++++++++++++------ 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index d4dfe335f5..7927e57de8 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -1225,19 +1225,21 @@ int nvme_fw_download(struct nvme_fw_download_args *args) return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } -int nvme_fw_commit(int fd, __u8 slot, enum nvme_fw_commit_ca action, bool bpid, - __u32 *result) +int nvme_fw_commit(struct nvme_fw_commit_args *args) { - __u32 cdw10 = NVME_SET(slot, FW_COMMIT_CDW10_FS) | - NVME_SET(action, FW_COMMIT_CDW10_CA) | - NVME_SET(bpid, FW_COMMIT_CDW10_BPID); + __u32 cdw10 = NVME_SET(args->slot, FW_COMMIT_CDW10_FS) | + NVME_SET(args->action, FW_COMMIT_CDW10_CA) | + NVME_SET(args->bpid, FW_COMMIT_CDW10_BPID); struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_fw_commit, .cdw10 = cdw10, + .timeout_ms = args->timeout, }; - return nvme_submit_admin_passthru(fd, &cmd, result); + if (args->args_size < sizeof(*args)) + return -EINVAL; + return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } int nvme_security_send(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index c07c7f6508..7997f291d7 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -2901,23 +2901,36 @@ struct nvme_fw_download_args { int nvme_fw_download(struct nvme_fw_download_args *args); /** - * nvme_fw_commit() - Commit firmware using the specified action + * nvme_fw_commit_args - Arguments for the NVMe Firmware Commit command * @fd: File descriptor of nvme device * @slot: Firmware slot to commit the downloaded image * @action: Action to use for the firmware image, see &enum nvme_fw_commit_ca * @bpid: Set to true to select the boot partition id + * @timeout: Timeout in ms * @result: The command completion result from CQE dword0 + */ +struct nvme_fw_commit_args { + int args_size; + int fd; + __u8 slot; + enum nvme_fw_commit_ca action; + bool bpid; + __u32 timeout; + __u32 *result; +}; + +/** + * nvme_fw_commit() - Commit firmware using the specified action + * @args: &struct nvme_fw_commit_args argument structure * * The Firmware Commit command modifies the firmware image or Boot Partitions. * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. The command - * status - * response may specify additional - * reset actions required to complete the commit process. + * status response may specify additional reset actions required to complete + * the commit process. */ -int nvme_fw_commit(int fd, __u8 slot, enum nvme_fw_commit_ca action, bool bpid, - __u32 *result); +int nvme_fw_commit(struct nvme_fw_commit_args *args); /** * nvme_security_send() - From 0b5a6b8ca0b7e1869030ea7628a34dfb7f8c9e07 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 17 Dec 2021 08:03:42 +0100 Subject: [PATCH 0327/1564] Use argument structure for nvme_security_send() and nvme_security_receive() Use an argument structure instead of passing all arguments one by one. This allows for a future expansion of the argument list without having to change the library ABI. Signed-off-by: Hannes Reinecke --- src/nvme/ioctl.c | 52 ++++++++++++++++++++++++------------------------ src/nvme/ioctl.h | 50 ++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 68 insertions(+), 34 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 7927e57de8..097ddc0f35 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -1242,50 +1242,50 @@ int nvme_fw_commit(struct nvme_fw_commit_args *args) return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } -int nvme_security_send(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, - __u8 secp, __u32 tl, __u32 data_len, void *data, - __u32 timeout, __u32 *result) +int nvme_security_send(struct nvme_security_send_args *args) { - __u32 cdw10 = NVME_SET(secp, SECURITY_SECP) | - NVME_SET(spsp0, SECURITY_SPSP0) | - NVME_SET(spsp1, SECURITY_SPSP1) | - NVME_SET(nssf, SECURITY_NSSF); - __u32 cdw11 = tl; + __u32 cdw10 = NVME_SET(args->secp, SECURITY_SECP) | + NVME_SET(args->spsp0, SECURITY_SPSP0) | + NVME_SET(args->spsp1, SECURITY_SPSP1) | + NVME_SET(args->nssf, SECURITY_NSSF); + __u32 cdw11 = args->tl; struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_security_send, - .nsid = nsid, + .nsid = args->nsid, .cdw10 = cdw10, .cdw11 = cdw11, - .data_len = data_len, - .addr = (__u64)(uintptr_t)data, - .timeout_ms = timeout, + .data_len = args->data_len, + .addr = (__u64)(uintptr_t)args->data, + .timeout_ms = args->timeout, }; - return nvme_submit_admin_passthru(fd, &cmd, result); + if (args->args_size < sizeof(*args)) + return -EINVAL; + return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } -int nvme_security_receive(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, - __u8 spsp1, __u8 secp, __u32 al, __u32 data_len, - void *data, __u32 timeout, __u32 *result) +int nvme_security_receive(struct nvme_security_receive_args *args) { - __u32 cdw10 = NVME_SET(secp, SECURITY_SECP) | - NVME_SET(spsp0, SECURITY_SPSP0) | - NVME_SET(spsp1, SECURITY_SPSP1) | - NVME_SET(nssf, SECURITY_NSSF); - __u32 cdw11 = al; + __u32 cdw10 = NVME_SET(args->secp, SECURITY_SECP) | + NVME_SET(args->spsp0, SECURITY_SPSP0) | + NVME_SET(args->spsp1, SECURITY_SPSP1) | + NVME_SET(args->nssf, SECURITY_NSSF); + __u32 cdw11 = args->al; struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_security_recv, - .nsid = nsid, + .nsid = args->nsid, .cdw10 = cdw10, .cdw11 = cdw11, - .data_len = data_len, - .addr = (__u64)(uintptr_t)data, - .timeout_ms = timeout, + .data_len = args->data_len, + .addr = (__u64)(uintptr_t)args->data, + .timeout_ms = args->timeout, }; - return nvme_submit_admin_passthru(fd, &cmd, result); + if (args->args_size < sizeof(*args)) + return -EINVAL; + return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } int nvme_get_lba_status(int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl, diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 7997f291d7..9e6d20a884 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -2933,7 +2933,7 @@ struct nvme_fw_commit_args { int nvme_fw_commit(struct nvme_fw_commit_args *args); /** - * nvme_security_send() - + * nvme_security_send_args - Arguments for the NVMe Security Send command * @fd: File descriptor of nvme device * @nsid: Namespace ID to issue security command on * @nssf: NVMe Security Specific field @@ -2945,6 +2945,25 @@ int nvme_fw_commit(struct nvme_fw_commit_args *args); * @data: Security data payload to send * @timeout: Timeout in ms * @result: The command completion result from CQE dword0 + */ +struct nvme_security_send_args { + int args_size; + int fd; + __u32 nsid; + __u8 nssf; + __u8 spsp0; + __u8 spsp1; + __u8 secp; + __u32 tl; + __u32 data_len; + void *data; + __u32 timeout; + __u32 *result; +}; + +/** + * nvme_security_send() - + * @args: &struct nvme_security_send argument structure * * The Security Send command transfers security protocol data to the * controller. The data structure transferred to the controller as part of this @@ -2958,12 +2977,10 @@ int nvme_fw_commit(struct nvme_fw_commit_args *args); * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_security_send(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, - __u8 secp, __u32 tl, __u32 data_len, void *data, - __u32 timeout, __u32 *result); +int nvme_security_send(struct nvme_security_send_args *args); /** - * nvme_security_receive() - + * nvme_security_receive_args - Arguments for the NVMe Security Receive command * @fd: File descriptor of nvme device * @nsid: Namespace ID to issue security command on * @nssf: NVMe Security Specific field @@ -2975,13 +2992,30 @@ int nvme_security_send(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, * @data: Security data payload to send * @timeout: Timeout in ms * @result: The command completion result from CQE dword0 + */ +struct nvme_security_receive_args { + int args_size; + int fd; + __u32 nsid; + __u8 nssf; + __u8 spsp0; + __u8 spsp1; + __u8 secp; + __u32 al; + __u32 data_len; + void *data; + __u32 timeout; + __u32 *result; +}; + +/** + * nvme_security_receive() - + * @args: &struct nvme_security_recevice 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(int fd, __u32 nsid, __u8 nssf, __u8 spsp0, - __u8 spsp1, __u8 secp, __u32 al, __u32 data_len, - void *data, __u32 timeout, __u32 *result); +int nvme_security_receive(struct nvme_security_receive_args *args); /** * nvme_get_lba_status() - Retrieve information on possibly unrecoverable LBAs From d1eee6a6a42de8edff34f71ceacc0cf6f823c6ae Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 17 Dec 2021 08:03:42 +0100 Subject: [PATCH 0328/1564] Use argument structure for nvme_get_lba_status() Use an argument structure instead of passing all arguments one by one. This allows for a future expansion of the argument list without having to change the library ABI. Signed-off-by: Hannes Reinecke --- src/nvme/ioctl.c | 24 ++++++++++++------------ src/nvme/ioctl.h | 23 +++++++++++++++++++---- 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 097ddc0f35..db652c649f 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -1288,28 +1288,28 @@ int nvme_security_receive(struct nvme_security_receive_args *args) return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } -int nvme_get_lba_status(int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl, - enum nvme_lba_status_atype atype, __u32 timeout, - struct nvme_lba_status *lbas, __u32 *result) +int nvme_get_lba_status(struct nvme_get_lba_status_args *args) { - __u32 cdw10 = slba & 0xffffffff; - __u32 cdw11 = slba >> 32; - __u32 cdw12 = mndw; - __u32 cdw13 = NVME_SET(rl, GET_LBA_STATUS_CDW13_RL) | - NVME_SET(atype, GET_LBA_STATUS_CDW13_ATYPE); + __u32 cdw10 = args->slba & 0xffffffff; + __u32 cdw11 = args->slba >> 32; + __u32 cdw12 = args->mndw; + __u32 cdw13 = NVME_SET(args->rl, GET_LBA_STATUS_CDW13_RL) | + NVME_SET(args->atype, GET_LBA_STATUS_CDW13_ATYPE); struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_get_lba_status, - .nsid = nsid, - .addr = (__u64)(uintptr_t)lbas, + .nsid = args->nsid, + .addr = (__u64)(uintptr_t)args->lbas, .cdw10 = cdw10, .cdw11 = cdw11, .cdw12 = cdw12, .cdw13 = cdw13, - .timeout_ms = timeout, + .timeout_ms = args->timeout, }; - return nvme_submit_admin_passthru(fd, &cmd, result); + if (args->args_size < sizeof(*args)) + return -EINVAL; + return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } int nvme_directive_send(int fd, __u32 nsid, __u16 dspec, diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 9e6d20a884..0bb6a93611 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -3018,7 +3018,7 @@ struct nvme_security_receive_args { int nvme_security_receive(struct nvme_security_receive_args *args); /** - * nvme_get_lba_status() - Retrieve information on possibly unrecoverable LBAs + * nvme_get_lba_status_args - Arguments for the NVMe Get LBA Status command * @fd: File descriptor of nvme device * @nsid: Namespace ID to retrieve LBA status * @slba: Starting logical block address to check statuses @@ -3029,6 +3029,23 @@ int nvme_security_receive(struct nvme_security_receive_args *args); * @timeout: Timeout in ms * @lbas: Data payload to return status descriptors * @result: The command completion result from CQE dword0 + */ +struct nvme_get_lba_status_args { + int args_size; + int fd; + __u32 nsid; + __u64 slba; + __u32 mndw; + __u16 rl; + enum nvme_lba_status_atype atype; + __u32 timeout; + struct nvme_lba_status *lbas; + __u32 *result; +}; + +/** + * nvme_get_lba_status() - Retrieve information on possibly unrecoverable LBAs + * @args: &struct nvme_get_lba_status_args argument structure * * The Get LBA Status command requests information about Potentially * Unrecoverable LBAs. Refer to the specification for action type descriptions. @@ -3036,9 +3053,7 @@ int nvme_security_receive(struct nvme_security_receive_args *args); * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_get_lba_status(int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl, - enum nvme_lba_status_atype atype, __u32 timeout, - struct nvme_lba_status *lbas, __u32 *result); +int nvme_get_lba_status(struct nvme_get_lba_status_args *args); /** * nvme_directive_send() - Send directive command From 7459192786a0caf51db965c9757d2d08ae0c1aeb Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 17 Dec 2021 08:03:42 +0100 Subject: [PATCH 0329/1564] Use argument structure for nvme_directive_send() and nvme_directive_receive() Use an argument structure instead of passing all arguments one by one. This allows for a future expansion of the argument list without having to change the library ABI. Signed-off-by: Hannes Reinecke --- src/nvme/ioctl.c | 140 ++++++++++------------------------- src/nvme/ioctl.h | 186 ++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 200 insertions(+), 126 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index db652c649f..17675b0a9a 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -1312,29 +1312,27 @@ int nvme_get_lba_status(struct nvme_get_lba_status_args *args) return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } -int nvme_directive_send(int fd, __u32 nsid, __u16 dspec, - enum nvme_directive_send_doper doper, - enum nvme_directive_dtype dtype, __u32 cdw12, - __u32 data_len, void *data, __u32 timeout, - __u32 *result) +int nvme_directive_send(struct nvme_directive_send_args *args) { - __u32 cdw10 = data_len ? (data_len >> 2) - 1 : 0; - __u32 cdw11 = NVME_SET(doper, DIRECTIVE_CDW11_DOPER) | - NVME_SET(dtype, DIRECTIVE_CDW11_DTYPE) | - NVME_SET(dspec, DIRECTIVE_CDW11_DPSEC); + __u32 cdw10 = args->data_len ? (args->data_len >> 2) - 1 : 0; + __u32 cdw11 = NVME_SET(args->doper, DIRECTIVE_CDW11_DOPER) | + NVME_SET(args->dtype, DIRECTIVE_CDW11_DTYPE) | + NVME_SET(args->dspec, DIRECTIVE_CDW11_DPSEC); struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_directive_send, - .nsid = nsid, + .nsid = args->nsid, .cdw10 = cdw10, .cdw11 = cdw11, - .cdw12 = cdw12, - .data_len = data_len, - .addr = (__u64)(uintptr_t)data, - .timeout_ms = timeout, + .cdw12 = args->cdw12, + .data_len = args->data_len, + .addr = (__u64)(uintptr_t)args->data, + .timeout_ms = args->timeout, }; - return nvme_submit_admin_passthru(fd, &cmd, result); + if (args->args_size < sizeof(*args)) + return -EINVAL; + return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } int nvme_directive_send_id_endir(int fd, __u32 nsid, bool endir, @@ -1343,102 +1341,44 @@ int nvme_directive_send_id_endir(int fd, __u32 nsid, bool endir, { __u32 cdw12 = NVME_SET(dtype, DIRECTIVE_SEND_IDENTIFY_CDW12_DTYPE) | NVME_SET(endir, DIRECTIVE_SEND_IDENTIFY_CDW12_ENDIR); + struct nvme_directive_send_args args = { + .args_size = sizeof(args), + .fd = fd, + .nsid = nsid, + .dspec = 0, + .dtype = NVME_DIRECTIVE_DTYPE_IDENTIFY, + .doper = NVME_DIRECTIVE_SEND_IDENTIFY_DOPER_ENDIR, + .cdw12 = cdw12, + .data_len = sizeof(*id), + .data = id, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; - return nvme_directive_send(fd, nsid, 0, NVME_DIRECTIVE_DTYPE_IDENTIFY, - NVME_DIRECTIVE_SEND_IDENTIFY_DOPER_ENDIR, - cdw12, sizeof(*id), id, - NVME_DEFAULT_IOCTL_TIMEOUT, NULL); -} - -int nvme_directive_send_stream_release_identifier(int fd, __u32 nsid, - __u16 stream_id) -{ - enum nvme_directive_dtype dtype = - NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_IDENTIFIER; - - return nvme_directive_send(fd, nsid, stream_id, - NVME_DIRECTIVE_DTYPE_STREAMS, - dtype, 0, 0, NULL, - NVME_DEFAULT_IOCTL_TIMEOUT, NULL); -} - -int nvme_directive_send_stream_release_resource(int fd, __u32 nsid) -{ - enum nvme_directive_dtype dtype = - NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE; - - return nvme_directive_send(fd, nsid, 0, NVME_DIRECTIVE_DTYPE_STREAMS, - dtype, 0, 0, NULL, - NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + return nvme_directive_send(&args); } -int nvme_directive_recv(int fd, __u32 nsid, __u16 dspec, - enum nvme_directive_receive_doper doper, - enum nvme_directive_dtype dtype, __u32 cdw12, - __u32 data_len, void *data, __u32 timeout, - __u32 *result) +int nvme_directive_recv(struct nvme_directive_recv_args *args) { - __u32 cdw10 = data_len ? (data_len >> 2) - 1 : 0; - __u32 cdw11 = NVME_SET(doper, DIRECTIVE_CDW11_DOPER) | - NVME_SET(dtype, DIRECTIVE_CDW11_DTYPE) | - NVME_SET(dspec, DIRECTIVE_CDW11_DPSEC); + __u32 cdw10 = args->data_len ? (args->data_len >> 2) - 1 : 0; + __u32 cdw11 = NVME_SET(args->doper, DIRECTIVE_CDW11_DOPER) | + NVME_SET(args->dtype, DIRECTIVE_CDW11_DTYPE) | + NVME_SET(args->dspec, DIRECTIVE_CDW11_DPSEC); struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_directive_recv, - .nsid = nsid, + .nsid = args->nsid, .cdw10 = cdw10, .cdw11 = cdw11, - .cdw12 = cdw12, - .data_len = data_len, - .addr = (__u64)(uintptr_t)data, - .timeout_ms = timeout, + .cdw12 = args->cdw12, + .data_len = args->data_len, + .addr = (__u64)(uintptr_t)args->data, + .timeout_ms = args->timeout, }; - return nvme_submit_admin_passthru(fd, &cmd, result); -} - -int nvme_directive_recv_identify_parameters(int fd, __u32 nsid, - struct nvme_id_directives *id) -{ - enum nvme_directive_dtype dtype = - NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM; - - return nvme_directive_recv(fd, nsid, 0, NVME_DIRECTIVE_DTYPE_IDENTIFY, - dtype, 0, sizeof(*id), id, - NVME_DEFAULT_IOCTL_TIMEOUT, NULL); -} - -int nvme_directive_recv_stream_parameters(int fd, __u32 nsid, - struct nvme_streams_directive_params *parms) -{ - enum nvme_directive_dtype dtype = - NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM; - - return nvme_directive_recv(fd, nsid, 0, NVME_DIRECTIVE_DTYPE_STREAMS, - dtype, 0, sizeof(*parms), parms, - NVME_DEFAULT_IOCTL_TIMEOUT, NULL); -} - -int nvme_directive_recv_stream_status(int fd, __u32 nsid, unsigned nr_entries, - struct nvme_streams_directive_status *id) -{ - enum nvme_directive_dtype dtype = - NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS; - - return nvme_directive_recv(fd, nsid, 0, NVME_DIRECTIVE_DTYPE_STREAMS, - dtype, 0, sizeof(*id), id, - NVME_DEFAULT_IOCTL_TIMEOUT, NULL); -} - -int nvme_directive_recv_stream_allocate(int fd, __u32 nsid, __u16 nsr, - __u32 *result) -{ - enum nvme_directive_dtype dtype = - NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE; - - return nvme_directive_recv(fd, nsid, 0, NVME_DIRECTIVE_DTYPE_STREAMS, - dtype, nsr, 0, NULL, - NVME_DEFAULT_IOCTL_TIMEOUT, result); + if (args->args_size < sizeof(*args)) + return -EINVAL; + return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } int nvme_capacity_mgmt(int fd, __u8 op, __u16 element_id, diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 0bb6a93611..f273d2b07d 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -3056,7 +3056,7 @@ struct nvme_get_lba_status_args { int nvme_get_lba_status(struct nvme_get_lba_status_args *args); /** - * nvme_directive_send() - Send directive command + * nvme_directive_send_args - Arguments for the NVMe Directive Send command * @fd: File descriptor of nvme device * @nsid: Namespace ID, if applicable * @dspec: Directive specific field @@ -3067,6 +3067,24 @@ int nvme_get_lba_status(struct nvme_get_lba_status_args *args); * @data: Usespace address of data payload * @timeout: Timeout in ms * @result: If successful, the CQE dword0 value + */ +struct nvme_directive_send_args { + int args_size; + int fd; + __u32 nsid; + __u16 dspec; + enum nvme_directive_send_doper doper; + enum nvme_directive_dtype dtype; + __u32 cdw12; + __u32 data_len; + void *data; + __u32 timeout; + __u32 *result; +}; + +/** + * nvme_directive_send() - Send directive command + * @args: &struct nvme_directive_send_args argument structure * * Directives is a mechanism to enable host and NVM subsystem or controller * information exchange. The Directive Send command transfers data related to a @@ -3077,11 +3095,7 @@ int nvme_get_lba_status(struct nvme_get_lba_status_args *args); * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_directive_send(int fd, __u32 nsid, __u16 dspec, - enum nvme_directive_send_doper doper, - enum nvme_directive_dtype dtype, __u32 cdw12, - __u32 data_len, void *data, __u32 timeout, - __u32 *result); +int nvme_directive_send(struct nvme_directive_send_args *args); /** * nvme_directive_send_id_endir() - @@ -3103,8 +3117,25 @@ int nvme_directive_send_id_endir(int fd, __u32 nsid, bool endir, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_directive_send_stream_release_identifier(int fd, __u32 nsid, - __u16 stream_id); +static inline int nvme_directive_send_stream_release_identifier(int fd, + __u32 nsid, __u16 stream_id) +{ + struct nvme_directive_send_args args = { + .args_size = sizeof(args), + .fd = fd, + .nsid = nsid, + .dspec = stream_id, + .doper = NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_IDENTIFIER, + .dtype = NVME_DIRECTIVE_DTYPE_STREAMS, + .cdw12 = 0, + .data_len = 0, + .data = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + + return nvme_directive_send(&args); +} /** * nvme_directive_send_stream_release_resource() - @@ -3114,29 +3145,60 @@ int nvme_directive_send_stream_release_identifier(int fd, __u32 nsid, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_directive_send_stream_release_resource(int fd, __u32 nsid); +static inline int nvme_directive_send_stream_release_resource(int fd, __u32 nsid) +{ + struct nvme_directive_send_args args = { + .args_size = sizeof(args), + .fd = fd, + .nsid = nsid, + .dspec = 0, + .doper = NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE, + .dtype = NVME_DIRECTIVE_DTYPE_STREAMS, + .cdw12 = 0, + .data_len = 0, + .data = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + + return nvme_directive_send(&args); +} /** - * nvme_directive_recv() - Receive directive specific data + * nvme_directive_recv_args - Arguments for the NVMe Directive Receive command * @fd: File descriptor of nvme device * @nsid: Namespace ID, if applicable * @dspec: Directive specific field - * @doper: Directive receive operation, see &enum nvme_directive_receive_doper + * @doper: Directive send operation, see &enum nvme_directive_send_doper * @dtype: Directive type, see &enum nvme_directive_dtype * @dw12: Directive specific command dword12 - * @data_len: Length of data payload - * @data: Usespace address of data payload in bytes + * @data_len: Length of data payload in bytes + * @data: Usespace address of data payload * @timeout: Timeout in ms * @result: If successful, the CQE dword0 value + */ +struct nvme_directive_recv_args { + int args_size; + int fd; + __u32 nsid; + __u16 dspec; + enum nvme_directive_receive_doper doper; + enum nvme_directive_dtype dtype; + __u32 cdw12; + __u32 data_len; + void *data; + __u32 timeout; + __u32 *result; +}; + +/** + * nvme_directive_recv() - Receive directive specific data + * @args: &struct nvme_directive_recv_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_directive_recv(int fd, __u32 nsid, __u16 dspec, - enum nvme_directive_receive_doper doper, - enum nvme_directive_dtype dtype, __u32 cdw12, - __u32 data_len, void *data, __u32 timeout, - __u32 *result); +int nvme_directive_recv(struct nvme_directive_recv_args *args); /** * nvme_directive_recv_identify_parameters() - @@ -3146,8 +3208,25 @@ int nvme_directive_recv(int fd, __u32 nsid, __u16 dspec, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_directive_recv_identify_parameters(int fd, __u32 nsid, - struct nvme_id_directives *id); +static inline int nvme_directive_recv_identify_parameters(int fd, __u32 nsid, + struct nvme_id_directives *id) +{ + struct nvme_directive_recv_args args = { + .args_size = sizeof(args), + .fd = fd, + .nsid = nsid, + .dspec = 0, + .doper = NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM, + .dtype = NVME_DIRECTIVE_DTYPE_IDENTIFY, + .cdw12 = 0, + .data_len = sizeof(*id), + .data = id, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + + return nvme_directive_recv(&args); +} /** * nvme_directive_recv_stream_parameters() - @@ -3157,8 +3236,26 @@ int nvme_directive_recv_identify_parameters(int fd, __u32 nsid, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_directive_recv_stream_parameters(int fd, __u32 nsid, - struct nvme_streams_directive_params *parms); +static inline int nvme_directive_recv_stream_parameters(int fd, __u32 nsid, + struct nvme_streams_directive_params *parms) +{ + struct nvme_directive_recv_args args = { + .args_size = sizeof(args), + .fd = fd, + .nsid = nsid, + .dspec = 0, + .doper = NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM, + .dtype = NVME_DIRECTIVE_DTYPE_STREAMS, + .cdw12 = 0, + .data_len = sizeof(*parms), + .data = parms, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + + return nvme_directive_recv(&args); +} + /** * nvme_directive_recv_stream_status() - @@ -3168,8 +3265,27 @@ int nvme_directive_recv_stream_parameters(int fd, __u32 nsid, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_directive_recv_stream_status(int fd, __u32 nsid, unsigned nr_entries, - struct nvme_streams_directive_status *id); +static inline int nvme_directive_recv_stream_status(int fd, __u32 nsid, + unsigned nr_entries, + struct nvme_streams_directive_status *id) +{ + struct nvme_directive_recv_args args = { + .args_size = sizeof(args), + .fd = fd, + .nsid = nsid, + .dspec = 0, + .doper = NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS, + .dtype = NVME_DIRECTIVE_DTYPE_STREAMS, + .cdw12 = 0, + .data_len = sizeof(*id), + .data = id, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + + return nvme_directive_recv(&args); +} + /** * nvme_directive_recv_stream_allocate() - @@ -3179,8 +3295,26 @@ int nvme_directive_recv_stream_status(int fd, __u32 nsid, unsigned nr_entries, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_directive_recv_stream_allocate(int fd, __u32 nsid, __u16 nsr, - __u32 *result); +static inline int nvme_directive_recv_stream_allocate(int fd, __u32 nsid, + __u16 nsr, __u32 *result) +{ + struct nvme_directive_recv_args args = { + .args_size = sizeof(args), + .fd = fd, + .nsid = nsid, + .dspec = 0, + .doper = NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE, + .dtype = NVME_DIRECTIVE_DTYPE_STREAMS, + .cdw12 = nsr, + .data_len = 0, + .data = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = result, + }; + + return nvme_directive_recv(&args); +} + /** * nvme_capacity_mgmt_args - Arguments for the NVMe Capacity Management command From 353d689490f4b53b2656c829f7de3a1df41b3369 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 17 Dec 2021 08:03:42 +0100 Subject: [PATCH 0330/1564] Use argument structure for nvme_capacity_mgmt() Use an argument structure instead of passing all arguments one by one. This allows for a future expansion of the argument list without having to change the library ABI. Signed-off-by: Hannes Reinecke --- src/nvme/ioctl.c | 18 +++++++++--------- src/nvme/ioctl.h | 19 ++++++++++++++++--- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 17675b0a9a..debe10e70e 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -1381,21 +1381,21 @@ int nvme_directive_recv(struct nvme_directive_recv_args *args) return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } -int nvme_capacity_mgmt(int fd, __u8 op, __u16 element_id, - __u32 dw11, __u32 dw12, - __u32 timeout, __u32 *result) +int nvme_capacity_mgmt(struct nvme_capacity_mgmt_args *args) { - __u32 dw10 = op | element_id << 16; + __u32 cdw10 = args->op | args->element_id << 16; struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_capacity_mgmt, - .cdw10 = dw10, - .cdw11 = dw11, - .cdw12 = dw12, - .timeout_ms = timeout, + .cdw10 = cdw10, + .cdw11 = args->cdw11, + .cdw12 = args->cdw12, + .timeout_ms = args->timeout, }; - return nvme_submit_admin_passthru(fd, &cmd, result); + if (args->args_size < sizeof(*args)) + return -EINVAL; + return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } int nvme_lockdown(int fd, __u8 scp, __u8 prhbt, __u8 ifc, __u8 ofi, diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index f273d2b07d..42f34da300 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -3327,13 +3327,26 @@ static inline int nvme_directive_recv_stream_allocate(int fd, __u32 nsid, * Endurance Group or NVM Set to be created * @timeout: Timeout in ms * @result: If successful, the CQE dword0 value + */ +struct nvme_capacity_mgmt_args { + int args_size; + int fd; + __u8 op; + __u16 element_id; + __u32 cdw11; + __u32 cdw12; + __u32 timeout; + __u32 *result; +}; + +/** + * nvme_capacity_mgmt() - + * @args: &struct nvme_capacity_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_capacity_mgmt(int fd, __u8 op, __u16 element_id, - __u32 dw11, __u32 dw12, - __u32 timeout, __u32 *result); +int nvme_capacity_mgmt(struct nvme_capacity_mgmt_args *args); /** * nvme_lockdown() - Issue lockdown command From 8e376cb2d11a93477cb30c62255bc0e4ca6d14ef Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 17 Dec 2021 08:03:42 +0100 Subject: [PATCH 0331/1564] Use argument structure for nvme_lockdown() Use an argument structure instead of passing all arguments one by one. This allows for a future expansion of the argument list without having to change the library ABI. Signed-off-by: Hannes Reinecke --- src/nvme/ioctl.c | 15 ++++++++++----- src/nvme/ioctl.h | 33 +++++++++++++++++++++++++-------- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index debe10e70e..b457326bf6 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -1398,18 +1398,23 @@ int nvme_capacity_mgmt(struct nvme_capacity_mgmt_args *args) return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } -int nvme_lockdown(int fd, __u8 scp, __u8 prhbt, __u8 ifc, __u8 ofi, - __u8 uuid) +int nvme_lockdown(struct nvme_lockdown_args *args) { - __u32 cdw10 = ofi << 8 | (ifc & 0x3) << 5 | (prhbt & 0x1) << 4 | (scp & 0xF); + __u32 cdw10 = args->ofi << 8 | + (args->ifc & 0x3) << 5 | + (args->prhbt & 0x1) << 4 | + (args->scp & 0xF); struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_lockdown, .cdw10 = cdw10, - .cdw14 = uuid & 0x3F, + .cdw14 = args->uuidx & 0x3F, + .timeout_ms = args->timeout, }; - return nvme_submit_admin_passthru(fd, &cmd, NULL); + if (args->args_size < sizeof(*args)) + return -EINVAL; + return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } int nvme_set_property(int fd, int offset, __u64 value, diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 42f34da300..c708cd47a9 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -3349,19 +3349,36 @@ struct nvme_capacity_mgmt_args { int nvme_capacity_mgmt(struct nvme_capacity_mgmt_args *args); /** - * nvme_lockdown() - Issue lockdown command + * nvme_lockdown_args - Arguments for the NVME Lockdown command * @fd: File descriptor of nvme device - * @scp: - * @prhbt: - * @ifc: - * @ofi: - * @uuid: + * @scp: Scope of the command + * @prhbt: Prohibit or allow the command opcode or Set Features command + * @ifc: Affected interface + * @ofi: Opcode or Feature Identifier + * @uuid: UUID Index if controller supports this id selection method + * @timeout: Timeout in ms (0 for default timeout) + * @result: The command completion result from CQE dword0 + */ +struct nvme_lockdown_args { + int args_size; + int fd; + __u8 scp; + __u8 prhbt; + __u8 ifc; + __u8 ofi; + __u8 uuidx; + __u32 timeout; + __u32 *result; +}; + +/** + * nvme_lockdown() - Issue lockdown command + * @args: &struct nvme_lockdown_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_lockdown(int fd, __u8 scp, __u8 prhbt, __u8 ifc, __u8 ofi, - __u8 uuid); +int nvme_lockdown(struct nvme_lockdown_args *args); /** * nvme_set_property() - Set controller property From 38692fdb8c28210a8161fb2845a0302419528d0e Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 17 Dec 2021 08:03:42 +0100 Subject: [PATCH 0332/1564] Use argument structure for nvme_set_property() and nvme_get_property() Use an argument structure instead of passing all arguments one by one. This allows for a future expansion of the argument list without having to change the library ABI. Signed-off-by: Hannes Reinecke --- src/nvme/ioctl.c | 29 ++++++++++++++++------------- src/nvme/ioctl.h | 34 +++++++++++++++++++++++++++++----- 2 files changed, 45 insertions(+), 18 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index b457326bf6..15fe32550c 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -1417,37 +1417,40 @@ int nvme_lockdown(struct nvme_lockdown_args *args) return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } -int nvme_set_property(int fd, int offset, __u64 value, - __u32 timeout, __u32 *result) +int nvme_set_property(struct nvme_set_property_args *args) { - __u32 cdw10 = nvme_is_64bit_reg(offset); + __u32 cdw10 = nvme_is_64bit_reg(args->offset); struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_fabrics, .nsid = nvme_fabrics_type_property_set, .cdw10 = cdw10, - .cdw11 = offset, - .cdw12 = value & 0xffffffff, - .cdw13 = value >> 32, - .timeout_ms = timeout, + .cdw11 = args->offset, + .cdw12 = args->value & 0xffffffff, + .cdw13 = args->value >> 32, + .timeout_ms = args->timeout, }; - return nvme_submit_admin_passthru(fd, &cmd, result); + if (args->args_size < sizeof(*args)) + return -EINVAL; + return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } -int nvme_get_property(int fd, int offset, __u64 *value, __u32 timeout) +int nvme_get_property(struct nvme_get_property_args *args) { - __u32 cdw10 = nvme_is_64bit_reg(offset); + __u32 cdw10 = nvme_is_64bit_reg(args->offset); struct nvme_passthru_cmd64 cmd = { .opcode = nvme_admin_fabrics, .nsid = nvme_fabrics_type_property_get, .cdw10 = cdw10, - .cdw11 = offset, - .timeout_ms = timeout, + .cdw11 = args->offset, + .timeout_ms = args->timeout, }; - return nvme_submit_admin_passthru64(fd, &cmd, value); + if (args->args_size < sizeof(*args)) + return -EINVAL; + return nvme_submit_admin_passthru64(args->fd, &cmd, args->value); } int nvme_sanitize_nvm(int fd, enum nvme_sanitize_sanact sanact, bool ause, diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index c708cd47a9..167a0524cf 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -3381,12 +3381,25 @@ struct nvme_lockdown_args { int nvme_lockdown(struct nvme_lockdown_args *args); /** - * nvme_set_property() - Set controller property + * nvme_set_property_args - Arguments for NVMe Set Property command * @fd: File descriptor of nvme device * @offset: Property offset from the base to set * @value: The value to set the property * @timeout: Timeout in ms * @result: The command completion result from CQE dword0 + */ +struct nvme_set_property_args { + int args_size; + int fd; + int offset; + __u64 value; + __u32 timeout; + __u32 *result; +}; + +/** + * nvme_set_property() - Set controller property + * @args: &struct nvme_set_property_args argument structure * * This is an NVMe-over-Fabrics specific command, not applicable to PCIe. These * properties align to the PCI MMIO controller registers. @@ -3394,15 +3407,26 @@ int nvme_lockdown(struct nvme_lockdown_args *args); * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_set_property(int fd, int offset, __u64 value, - __u32 timeout, __u32 *result); +int nvme_set_property(struct nvme_set_property_args *args); /** - * nvme_get_property() - Get a controller property + * nvme_get_property_args - Arguments for NVMe Get Property command * @fd: File descriptor of nvme device * @offset: Property offset from the base to retrieve * @value: Where the property's value will be stored on success * @timeout: Timeout in ms + */ +struct nvme_get_property_args { + int args_size; + int fd; + int offset; + __u64 *value; + __u32 timeout; +}; + +/** + * nvme_get_property() - Get a controller property + * @args: &struct nvme_get_propert_args argument structure * * This is an NVMe-over-Fabrics specific command, not applicable to PCIe. These * properties align to the PCI MMIO controller registers. @@ -3410,7 +3434,7 @@ int nvme_set_property(int fd, int offset, __u64 value, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_get_property(int fd, int offset, __u64 *value, __u32 timeout); +int nvme_get_property(struct nvme_get_property_args *args); /** * nvme_sanitize_nvm() - Start a sanitize operation From 00b1ea933a81f45a430988db18bcc0f76a94a8f3 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 17 Dec 2021 08:03:42 +0100 Subject: [PATCH 0333/1564] Use argument structure for nvme_sanize_nvm() Use an argument structure instead of passing all arguments one by one. This allows for a future expansion of the argument list without having to change the library ABI. Signed-off-by: Hannes Reinecke --- src/nvme/ioctl.c | 22 +++++++++++----------- src/nvme/ioctl.h | 23 +++++++++++++++++++---- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 15fe32550c..7725da791d 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -1453,25 +1453,25 @@ int nvme_get_property(struct nvme_get_property_args *args) return nvme_submit_admin_passthru64(args->fd, &cmd, args->value); } -int nvme_sanitize_nvm(int fd, enum nvme_sanitize_sanact sanact, bool ause, - __u8 owpass, bool oipbp, bool nodas, __u32 ovrpat, - __u32 timeout, __u32 *result) +int nvme_sanitize_nvm(struct nvme_sanitize_nvm_args *args) { - __u32 cdw10 = NVME_SET(sanact, SANITIZE_CDW10_SANACT) | - NVME_SET(!!ause, SANITIZE_CDW10_AUSE) | - NVME_SET(owpass, SANITIZE_CDW10_OWPASS) | - NVME_SET(!!oipbp, SANITIZE_CDW10_OIPBP) | - NVME_SET(!!nodas, SANITIZE_CDW10_NODAS); - __u32 cdw11 = ovrpat; + __u32 cdw10 = NVME_SET(args->sanact, SANITIZE_CDW10_SANACT) | + NVME_SET(!!args->ause, SANITIZE_CDW10_AUSE) | + NVME_SET(args->owpass, SANITIZE_CDW10_OWPASS) | + NVME_SET(!!args->oipbp, SANITIZE_CDW10_OIPBP) | + NVME_SET(!!args->nodas, SANITIZE_CDW10_NODAS); + __u32 cdw11 = args->ovrpat; struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_sanitize_nvm, .cdw10 = cdw10, .cdw11 = cdw11, - .timeout_ms = timeout, + .timeout_ms = args->timeout, }; - return nvme_submit_admin_passthru(fd, &cmd, result); + if (args->args_size < sizeof(*args)) + return -EINVAL; + return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } int nvme_dev_self_test(int fd, __u32 nsid, enum nvme_dst_stc stc) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 167a0524cf..b20eb1d4ca 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -3437,7 +3437,7 @@ struct nvme_get_property_args { int nvme_get_property(struct nvme_get_property_args *args); /** - * nvme_sanitize_nvm() - Start a sanitize operation + * nvme_sanitize_nvm_args - Arguments for the NVMe Sanitize NVM command * @fd: File descriptor of nvme device * @sanact: Sanitize action, see &enum nvme_sanitize_sanact * @ause: Set to allow unrestriced sanitize exit @@ -3447,6 +3447,23 @@ int nvme_get_property(struct nvme_get_property_args *args); * @ovrpat: Overwrite pattern * @timeout: Timeout in ms * @result: The command completion result from CQE dword0 + */ +struct nvme_sanitize_nvm_args { + int args_size; + int fd; + enum nvme_sanitize_sanact sanact; + bool ause; + __u8 owpass; + bool oipbp; + bool nodas; + __u32 ovrpat; + __u32 timeout; + __u32 *result; +}; + +/** + * nvme_sanitize_nvm() - Start a sanitize operation + * @args: &struct nvme_sanitize_nvm_args argument structure * * A sanitize operation alters all user data in the NVM subsystem such that * recovery of any previous user data from any cache, the non-volatile media, @@ -3461,9 +3478,7 @@ int nvme_get_property(struct nvme_get_property_args *args); * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_sanitize_nvm(int fd, enum nvme_sanitize_sanact sanact, bool ause, - __u8 owpass, bool oipbp, bool nodas, __u32 ovrpat, - __u32 timeout, __u32 *result); +int nvme_sanitize_nvm(struct nvme_sanitize_nvm_args *args); /** * nvme_dev_self_test() - Start or abort a self test From 2bfe3d24f5273738574af5924a00173ebd263278 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 17 Dec 2021 08:03:42 +0100 Subject: [PATCH 0334/1564] Use argument structure for nvme_dev_self_test() Use an argument structure instead of passing all arguments one by one. This allows for a future expansion of the argument list without having to change the library ABI. Signed-off-by: Hannes Reinecke --- src/nvme/ioctl.c | 15 +++++++++------ src/nvme/ioctl.h | 19 +++++++++++++++++-- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 7725da791d..6a624b8bfd 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -1474,17 +1474,20 @@ int nvme_sanitize_nvm(struct nvme_sanitize_nvm_args *args) return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } -int nvme_dev_self_test(int fd, __u32 nsid, enum nvme_dst_stc stc) +int nvme_dev_self_test(struct nvme_dev_self_test_args *args) { - __u32 cdw10 = NVME_SET(stc, DEVICE_SELF_TEST_CDW10_STC); + __u32 cdw10 = NVME_SET(args->stc, DEVICE_SELF_TEST_CDW10_STC); struct nvme_passthru_cmd cmd = { - .opcode = nvme_admin_dev_self_test, - .nsid = nsid, - .cdw10 = cdw10, + .opcode = nvme_admin_dev_self_test, + .nsid = args->nsid, + .cdw10 = cdw10, + .timeout_ms = args->timeout, }; - return nvme_submit_admin_passthru(fd, &cmd, NULL); + if (args->args_size < sizeof(*args)) + return -EINVAL; + return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } int nvme_virtual_mgmt(int fd, enum nvme_virt_mgmt_act act, diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index b20eb1d4ca..55f097044a 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -3481,10 +3481,25 @@ struct nvme_sanitize_nvm_args { int nvme_sanitize_nvm(struct nvme_sanitize_nvm_args *args); /** - * nvme_dev_self_test() - Start or abort a self test + * nvme_dev_self_test_args - Arguments for the NVMe Device Self Test command * @fd: File descriptor of nvme device * @nsid: Namespace ID to test * @stc: Self test code, see &enum nvme_dst_stc + * @timeout: Timeout in ms + * @result: The command completion result from CQE dword0 + */ +struct nvme_dev_self_test_args { + int args_size; + int fd; + __u32 nsid; + enum nvme_dst_stc stc; + __u32 timeout; + __u32 *result; +}; + +/** + * nvme_dev_self_test() - Start or abort a self test + * @args: &struct nvme_dev_self_test argument structure * * The Device Self-test command starts a device self-test operation or abort a * device self-test operation. A device self-test operation is a diagnostic @@ -3500,7 +3515,7 @@ int nvme_sanitize_nvm(struct nvme_sanitize_nvm_args *args); * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_dev_self_test(int fd, __u32 nsid, enum nvme_dst_stc stc); +int nvme_dev_self_test(struct nvme_dev_self_test_args *args); /** * nvme_virtual_mgmt() - Virtualization resource management From db91866c6a3b6f86d567bb8b47b68c925920f8cb Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 17 Dec 2021 08:03:42 +0100 Subject: [PATCH 0335/1564] Use argument structure for nvme_virtual_mgmt() Use an argument structure instead of passing all arguments one by one. This allows for a future expansion of the argument list without having to change the library ABI. Signed-off-by: Hannes Reinecke --- src/nvme/ioctl.c | 23 ++++++++++++----------- src/nvme/ioctl.h | 23 +++++++++++++++++++---- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 6a624b8bfd..f1ef3efa88 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -1490,22 +1490,23 @@ int nvme_dev_self_test(struct nvme_dev_self_test_args *args) return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } -int nvme_virtual_mgmt(int fd, enum nvme_virt_mgmt_act act, - enum nvme_virt_mgmt_rt rt, __u16 cntlid, __u16 nr, - __u32 *result) +int nvme_virtual_mgmt(struct nvme_virtual_mgmt_args *args) { - __u32 cdw10 = NVME_SET(act, VIRT_MGMT_CDW10_ACT) | - NVME_SET(rt, VIRT_MGMT_CDW10_RT) | - NVME_SET(cntlid, VIRT_MGMT_CDW10_CNTLID); - __u32 cdw11 = NVME_SET(nr, VIRT_MGMT_CDW11_NR); + __u32 cdw10 = NVME_SET(args->act, VIRT_MGMT_CDW10_ACT) | + NVME_SET(args->rt, VIRT_MGMT_CDW10_RT) | + NVME_SET(args->cntlid, VIRT_MGMT_CDW10_CNTLID); + __u32 cdw11 = NVME_SET(args->nr, VIRT_MGMT_CDW11_NR); struct nvme_passthru_cmd cmd = { - .opcode = nvme_admin_virtual_mgmt, - .cdw10 = cdw10, - .cdw11 = cdw11, + .opcode = nvme_admin_virtual_mgmt, + .cdw10 = cdw10, + .cdw11 = cdw11, + .timeout_ms = args->timeout, }; - return nvme_submit_admin_passthru(fd, &cmd, result); + if (args->args_size < sizeof(*args)) + return -EINVAL; + return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } int nvme_submit_io_passthru64(int fd, struct nvme_passthru_cmd64 *cmd, diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 55f097044a..f35c7aa8c4 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -3518,13 +3518,30 @@ struct nvme_dev_self_test_args { int nvme_dev_self_test(struct nvme_dev_self_test_args *args); /** - * nvme_virtual_mgmt() - Virtualization resource management + * nvme_virtual_mgmt_args - Arguments for the NVMe Virtualization + * resource management command * @fd: File descriptor of nvme device * @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 + * @timeout: Timeout in ms * @result: If successful, the CQE dword0 + */ +struct nvme_virtual_mgmt_args { + int args_size; + int fd; + enum nvme_virt_mgmt_act act; + enum nvme_virt_mgmt_rt rt; + __u16 cntlid; + __u16 nr; + __u32 timeout; + __u32 *result; +}; + +/** + * nvme_virtual_mgmt() - Virtualization resource management + * @args: &struct nvme_virtual_mgmt_args argument structure * * The Virtualization Management command is supported by primary controllers * that support the Virtualization Enhancements capability. This command is @@ -3537,9 +3554,7 @@ int nvme_dev_self_test(struct nvme_dev_self_test_args *args); * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_virtual_mgmt(int fd, enum nvme_virt_mgmt_act act, - enum nvme_virt_mgmt_rt rt, __u16 cntlid, __u16 nr, - __u32 *result); +int nvme_virtual_mgmt(struct nvme_virtual_mgmt_args *args); /** * nvme_flush() - Send an nvme flush command From 03583610a8261f8bdb1d210667bfcc99fc9e3ac0 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 17 Dec 2021 08:03:42 +0100 Subject: [PATCH 0336/1564] Use argument structure for NVMe I/O commands Use an argument structure for NVMe I/O commands like nvme_read() or nvme_write() instead of passing all arguments one by one. This allows for a future expansion of the argument list without having to change the library ABI. Signed-off-by: Hannes Reinecke --- src/nvme/ioctl.c | 92 +++++--------------------- src/nvme/ioctl.h | 168 ++++++++++++++++++----------------------------- src/nvme/tree.c | 165 +++++++++++++++++++++++++++++++++++----------- 3 files changed, 208 insertions(+), 217 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index f1ef3efa88..4c2b92bfbe 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -1552,23 +1552,20 @@ int nvme_flush(int fd, __u32 nsid) return nvme_submit_io_passthru(fd, &cmd, NULL); } -static int nvme_io(int fd, __u8 opcode, __u32 nsid, __u64 slba, __u16 nlb, - __u16 control, __u32 flags, __u32 reftag, __u16 apptag, __u16 appmask, - __u64 storage_tag, __u32 data_len, void *data, __u32 metadata_len, - void *metadata, __u32 timeout) +int nvme_io(struct nvme_io_args *args, __u8 opcode) { - __u32 cdw2 = storage_tag & 0xffffffff; - __u32 cdw3 = (storage_tag >> 32) & 0xffff; - __u32 cdw10 = slba & 0xffffffff; - __u32 cdw11 = slba >> 32; - __u32 cdw12 = nlb | (control << 16); - __u32 cdw13 = flags; - __u32 cdw14 = reftag; - __u32 cdw15 = apptag | (appmask << 16); + __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); struct nvme_passthru_cmd cmd = { .opcode = opcode, - .nsid = nsid, + .nsid = args->nsid, .cdw2 = cdw2, .cdw3 = cdw3, .cdw10 = cdw10, @@ -1577,69 +1574,16 @@ static int nvme_io(int fd, __u8 opcode, __u32 nsid, __u64 slba, __u16 nlb, .cdw13 = cdw13, .cdw14 = cdw14, .cdw15 = cdw15, - .data_len = data_len, - .metadata_len = metadata_len, - .addr = (__u64)(uintptr_t)data, - .metadata = (__u64)(uintptr_t)metadata, - .timeout_ms = timeout, + .data_len = args->data_len, + .metadata_len = args->metadata_len, + .addr = (__u64)(uintptr_t)args->data, + .metadata = (__u64)(uintptr_t)args->metadata, + .timeout_ms = args->timeout, }; - return nvme_submit_io_passthru(fd, &cmd, NULL); -} - -int nvme_read(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, - __u8 dsm, __u32 reftag, __u16 apptag, __u16 appmask, - __u64 storage_tag, __u32 data_len, void *data, - __u32 metadata_len, void *metadata, __u32 timeout) -{ - return nvme_io(fd, nvme_cmd_read, nsid, slba, nlb, control, dsm, - reftag, apptag, appmask, storage_tag, data_len, data, - metadata_len, metadata, timeout); -} - -int nvme_write(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, - __u8 dsm, __u16 dspec, __u32 reftag, __u16 apptag, - __u16 appmask, __u64 storage_tag, __u32 data_len, void *data, - __u32 metadata_len, void *metadata, __u32 timeout) -{ - __u32 flags = dsm | dspec << 16; - - return nvme_io(fd, nvme_cmd_write, nsid, slba, nlb, control, flags, - reftag, apptag, appmask, storage_tag, data_len, data, - metadata_len, metadata, timeout); -} - -int nvme_compare(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, - __u32 reftag, __u16 apptag, __u16 appmask, __u32 data_len, - void *data, __u32 metadata_len, void *metadata, __u32 timeout) -{ - return nvme_io(fd, nvme_cmd_compare, nsid, slba, nlb, control, 0, - reftag, apptag, appmask, 0, data_len, data, metadata_len, - metadata, timeout); -} - -int nvme_write_zeros(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, - __u32 reftag, __u16 apptag, __u16 appmask, - __u64 storage_tag, __u32 timeout) -{ - return nvme_io(fd, nvme_cmd_write_zeroes, nsid, slba, nlb, control, 0, - reftag, apptag, appmask, storage_tag, 0, NULL, 0, NULL, - timeout); -} - -int nvme_verify(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, - __u32 reftag, __u16 apptag, __u16 appmask, __u64 storage_tag, - __u32 timeout) -{ - return nvme_io(fd, nvme_cmd_verify, nsid, slba, nlb, control, 0, - reftag, apptag, appmask, 0, 0, NULL, 0, NULL, timeout); -} - -int nvme_write_uncorrectable(int fd, __u32 nsid, __u64 slba, __u16 nlb, - __u32 timeout) -{ - return nvme_io(fd, nvme_cmd_write_uncor, nsid, slba, nlb, 0, 0, 0, 0, - 0, 0, 0, NULL, 0, NULL, timeout); + if (args->args_size < sizeof(*args)) + return -EINVAL; + return nvme_submit_io_passthru(args->fd, &cmd, args->result); } int nvme_dsm(int fd, __u32 nsid, __u32 attrs, __u16 nr_ranges, diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index f35c7aa8c4..1016bc6eae 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -3570,7 +3570,7 @@ int nvme_virtual_mgmt(struct nvme_virtual_mgmt_args *args); int nvme_flush(int fd, __u32 nsid); /** - * nvme_read() - Submit an nvme user read command + * nvme_io_args - Arguments for NVMe I/O commands * @fd: File descriptor of nvme device * @nsid: Namespace ID * @slba: Starting logical block @@ -3594,99 +3594,76 @@ int nvme_flush(int fd, __u32 nsid); * @metadata_len:Length of user buffer, @metadata, in bytes * @metadata: Pointer to user address of the metadata buffer * @timeout: Timeout in ms + */ +struct nvme_io_args { + int args_size; + int fd; + __u32 nsid; + __u64 slba; + __u16 nlb; + __u16 control; + __u8 dsm; + __u8 dspec; + __u32 reftag; + __u16 apptag; + __u16 appmask; + __u64 storage_tag; + __u32 data_len; + void *data; + __u32 metadata_len; + void *metadata; + __u32 timeout; + __u32 *result; +}; + +/** + * nvme_io() - Submit an nvme user I/O command + * @args: &struct nvme_io_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_io(struct nvme_io_args *args, __u8 opcode); + +/** + * nvme_read() - Submit an nvme user read command + * @args: &struct nvme_io_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_read(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, - __u8 dsm, __u32 reftag, __u16 apptag, __u16 appmask, - __u64 storage_tag, __u32 data_len, void *data, - __u32 metadata_len, void *metadata, __u32 timeout); +static inline int nvme_read(struct nvme_io_args *args) +{ + return nvme_io(args, nvme_cmd_read); +} /** * nvme_write() - Submit an nvme user write command - * @fd: File descriptor of nvme device - * @nsid: Namespace ID - * @slba: Starting logical block - * @nblocks: Number of logical blocks to send (0's based value) - * @control: Command control flags, see &enum nvme_io_control_flags. - * @dsm: Data set management attributes, see &enum nvme_io_dsm_flags - * @dspec: Directive specific command, eg: stream identifier - * @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. - * @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. - * @storage_tag: This filed specifies Variable Sized Expected Logical Block - * Storage Tag (ELBST) and Expected Logical Block Reference - * Tag (ELBRT) - * @data_len: Length of user buffer, @data, in bytes - * @data: Pointer to user address of the data buffer - * @metadata_len:Length of user buffer, @metadata, in bytes - * @metadata: Pointer to user address of the metadata buffer - * @timeout: Timeout in ms + * @args: &struct nvme_io_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_write(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, - __u8 dsm, __u16 dspec, __u32 reftag, __u16 apptag, - __u16 appmask, __u64 storage_tag, __u32 data_len, void *data, - __u32 metadata_len, void *metadata, __u32 timeout); +static inline int nvme_write(struct nvme_io_args *args) +{ + return nvme_io(args, nvme_cmd_write); +} /** * nvme_compare() - Submit an nvme user compare command - * @fd: File descriptor of nvme device - * @nsid: Namespace ID - * @slba: Starting logical block - * @nblocks: Number of logical blocks to send (0's based value) - * @control: Command control flags, see &enum nvme_io_control_flags. - * @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. - * @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. - * @data_len: Length of user buffer, @data, in bytes - * @data: Pointer to user address of the data buffer - * @metadata_len:Length of user buffer, @metadata, in bytes - * @metadata: Pointer to user address of the metadata buffer - * @timeout: Timeout in ms + * @args: &struct nvme_io_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_compare(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, - __u32 reftag, __u16 apptag, __u16 appmask, __u32 data_len, - void *data, __u32 metadata_len, void *metadata, __u32 timeout); +static inline int nvme_compare(struct nvme_io_args *args) +{ + return nvme_io(args, nvme_cmd_compare); +} /** * nvme_write_zeros() - Submit an nvme write zeroes command - * @fd: File descriptor of nvme device - * @nsid: Namespace identifier - * @slba: Starting logical block - * @nlb: Number of logical blocks to clear (0's based value) - * @control: Command control flags, see &enum nvme_io_control_flags. - * @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. - * @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. - * @storage_tag: This filed specifies Variable Sized Expected Logical Block - * Storage Tag (ELBST) and Expected Logical Block Reference - * Tag (ELBRT) - * @timeout: Timeout in ms + * @args: &struct nvme_io_args argument structure * * The Write Zeroes command sets a range of logical blocks to zero. After * successful completion of this command, the value returned by subsequent @@ -3696,17 +3673,14 @@ int nvme_compare(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_write_zeros(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, - __u32 reftag, __u16 apptag, __u16 appmask, - __u64 storage_tag, __u32 timeout); +static inline int nvme_write_zeros(struct nvme_io_args *args) +{ + return nvme_io(args, nvme_cmd_write_zeroes); +} /** * nvme_write_uncorrectable() - Submit an nvme write uncorrectable command - * @fd: File descriptor of nvme device - * @nsid: Namespace identifier - * @slba: Starting logical block - * @nlb: Number of logical blocks to invalidate (0's based value) - * @timeout: Timeout in ms + * @args: &struct nvme_io_args argument structure * * The Write Uncorrectable command marks a range of logical blocks as invalid. * When the specified logical block(s) are read after this operation, a failure @@ -3716,29 +3690,14 @@ int nvme_write_zeros(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_write_uncorrectable(int fd, __u32 nsid, __u64 slba, __u16 nlb, - __u32 timeout); +static inline int nvme_write_uncorrectable(struct nvme_io_args *args) +{ + return nvme_io(args, nvme_cmd_write_uncor); +} /** * nvme_verify() - Send an nvme verify command - * @fd: File descriptor of nvme device - * @nsid: Namespace identifier - * @slba: Starting logical block - * @nlb: Number of logical blocks to verify (0's based value) - * @control: Command control flags, see &enum nvme_io_control_flags. - * @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. - * @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. - * @storage_tag: This filed specifies Variable Sized Expected Logical Block - * Storage Tag (ELBST) and Expected Logical Block Reference - * Tag (ELBRT) - * @timeout: Timeout in ms + * @args: &struct nvme_io_args argument structure * * The Verify command verifies integrity of stored information by reading data * and metadata, if applicable, for the LBAs indicated without transferring any @@ -3747,9 +3706,10 @@ int nvme_write_uncorrectable(int fd, __u32 nsid, __u64 slba, __u16 nlb, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_verify(int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, - __u32 reftag, __u16 apptag, __u16 appmask, __u64 storage_tag, - __u32 timeout); +static inline int nvme_verify(struct nvme_io_args *args) +{ + return nvme_io(args, nvme_cmd_verify); +} /** * nvme_dsm() - Send an nvme data set management command diff --git a/src/nvme/tree.c b/src/nvme/tree.c index a782f04a2e..7bcecc9bdd 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -1493,77 +1493,164 @@ int nvme_ns_identify_descs(nvme_ns_t n, struct nvme_ns_id_desc *descs) int nvme_ns_verify(nvme_ns_t n, off_t offset, size_t count) { - __u64 slba; - __u16 nlb; - - if (nvme_bytes_to_lba(n, offset, count, &slba, &nlb)) + struct nvme_io_args args = { + .args_size = sizeof(args), + .fd = nvme_ns_get_fd(n), + .nsid = nvme_ns_get_nsid(n), + .control = 0, + .dsm = 0, + .dspec = 0, + .reftag = 0, + .apptag = 0, + .appmask = 0, + .storage_tag = 0, + .data_len = 0, + .data = NULL, + .metadata_len = 0, + .metadata = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + + if (nvme_bytes_to_lba(n, offset, count, &args.slba, &args.nlb)) return -1; - return nvme_verify(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), slba, nlb, - 0, 0, 0, 0, 0, NVME_DEFAULT_IOCTL_TIMEOUT); + return nvme_verify(&args); } int nvme_ns_write_uncorrectable(nvme_ns_t n, off_t offset, size_t count) { - __u64 slba; - __u16 nlb; - - if (nvme_bytes_to_lba(n, offset, count, &slba, &nlb)) + struct nvme_io_args args = { + .args_size = sizeof(args), + .fd = nvme_ns_get_fd(n), + .nsid = nvme_ns_get_nsid(n), + .control = 0, + .dsm = 0, + .dspec = 0, + .reftag = 0, + .apptag = 0, + .appmask = 0, + .storage_tag = 0, + .data_len = 0, + .data = NULL, + .metadata_len = 0, + .metadata = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + + if (nvme_bytes_to_lba(n, offset, count, &args.slba, &args.nlb)) return -1; - return nvme_write_uncorrectable(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), - slba, nlb, NVME_DEFAULT_IOCTL_TIMEOUT); + return nvme_write_uncorrectable(&args); } int nvme_ns_write_zeros(nvme_ns_t n, off_t offset, size_t count) { - __u64 slba; - __u16 nlb; - - if (nvme_bytes_to_lba(n, offset, count, &slba, &nlb)) + struct nvme_io_args args = { + .args_size = sizeof(args), + .fd = nvme_ns_get_fd(n), + .nsid = nvme_ns_get_nsid(n), + .control = 0, + .dsm = 0, + .dspec = 0, + .reftag = 0, + .apptag = 0, + .appmask = 0, + .storage_tag = 0, + .data_len = 0, + .data = NULL, + .metadata_len = 0, + .metadata = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + + if (nvme_bytes_to_lba(n, offset, count, &args.slba, &args.nlb)) return -1; - return nvme_write_zeros(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), slba, - nlb, 0, 0, 0, 0, 0, NVME_DEFAULT_IOCTL_TIMEOUT); + return nvme_write_zeros(&args); } int nvme_ns_write(nvme_ns_t n, void *buf, off_t offset, size_t count) { - __u64 slba; - __u16 nlb; - - if (nvme_bytes_to_lba(n, offset, count, &slba, &nlb)) + struct nvme_io_args args = { + .args_size = sizeof(args), + .fd = nvme_ns_get_fd(n), + .nsid = nvme_ns_get_nsid(n), + .control = 0, + .dsm = 0, + .dspec = 0, + .reftag = 0, + .apptag = 0, + .appmask = 0, + .storage_tag = 0, + .data_len = count, + .data = buf, + .metadata_len = 0, + .metadata = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + + if (nvme_bytes_to_lba(n, offset, count, &args.slba, &args.nlb)) return -1; - return nvme_write(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), slba, nlb, 0, - 0, 0, 0, 0, 0, 0, count, buf, 0, NULL, - NVME_DEFAULT_IOCTL_TIMEOUT); + return nvme_write(&args); } int nvme_ns_read(nvme_ns_t n, void *buf, off_t offset, size_t count) { - __u64 slba; - __u16 nlb; - - if (nvme_bytes_to_lba(n, offset, count, &slba, &nlb)) + struct nvme_io_args args = { + .args_size = sizeof(args), + .fd = nvme_ns_get_fd(n), + .nsid = nvme_ns_get_nsid(n), + .control = 0, + .dsm = 0, + .dspec = 0, + .reftag = 0, + .apptag = 0, + .appmask = 0, + .storage_tag = 0, + .data_len = count, + .data = buf, + .metadata_len = 0, + .metadata = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + + if (nvme_bytes_to_lba(n, offset, count, &args.slba, &args.nlb)) return -1; - return nvme_read(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), slba, nlb, 0, - 0, 0, 0, 0, 0, count, buf, 0, NULL, - NVME_DEFAULT_IOCTL_TIMEOUT); + return nvme_read(&args); } int nvme_ns_compare(nvme_ns_t n, void *buf, off_t offset, size_t count) { - __u64 slba; - __u16 nlb; - - if (nvme_bytes_to_lba(n, offset, count, &slba, &nlb)) + struct nvme_io_args args = { + .args_size = sizeof(args), + .fd = nvme_ns_get_fd(n), + .nsid = nvme_ns_get_nsid(n), + .control = 0, + .dsm = 0, + .dspec = 0, + .reftag = 0, + .apptag = 0, + .appmask = 0, + .storage_tag = 0, + .data_len = count, + .data = buf, + .metadata_len = 0, + .metadata = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = NULL, + }; + + if (nvme_bytes_to_lba(n, offset, count, &args.slba, &args.nlb)) return -1; - return nvme_compare(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), slba, nlb, - 0, 0, 0, 0, count, buf, 0, NULL, - NVME_DEFAULT_IOCTL_TIMEOUT); + return nvme_compare(&args); } int nvme_ns_flush(nvme_ns_t n) From b171dce243e6674e164081b5b1409fec96edd5ee Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 17 Dec 2021 08:03:42 +0100 Subject: [PATCH 0337/1564] Use argument structure for nvme_dsm() Use an argument structure instead of passing all arguments one by one. This allows for a future expansion of the argument list without having to change the library ABI. Signed-off-by: Hannes Reinecke --- src/nvme/ioctl.c | 21 ++++++++++----------- src/nvme/ioctl.h | 20 +++++++++++++++++--- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 4c2b92bfbe..005ba0f509 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -1586,22 +1586,21 @@ int nvme_io(struct nvme_io_args *args, __u8 opcode) return nvme_submit_io_passthru(args->fd, &cmd, args->result); } -int nvme_dsm(int fd, __u32 nsid, __u32 attrs, __u16 nr_ranges, - struct nvme_dsm_range *dsm, __u32 timeout, __u32 *result) +int nvme_dsm(struct nvme_dsm_args *args) { - __u32 cdw11 = attrs; - struct nvme_passthru_cmd cmd = { .opcode = nvme_cmd_dsm, - .nsid = nsid, - .addr = (__u64)(uintptr_t)dsm, - .data_len = nr_ranges * sizeof(*dsm), - .cdw10 = nr_ranges - 1, - .cdw11 = cdw11, - .timeout_ms = timeout, + .nsid = args->nsid, + .addr = (__u64)(uintptr_t)args->dsm, + .data_len = args->nr_ranges * sizeof(*args->dsm), + .cdw10 = args->nr_ranges - 1, + .cdw11 = args->attrs, + .timeout_ms = args->timeout, }; - return nvme_submit_io_passthru(fd, &cmd, result); + if (args->args_size < sizeof(*args)) + return -EINVAL; + return nvme_submit_io_passthru(args->fd, &cmd, args->result); } int nvme_copy(int fd, __u32 nsid, struct nvme_copy_range *copy, __u64 sdlba, diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 1016bc6eae..6c56b58a03 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -3712,7 +3712,7 @@ static inline int nvme_verify(struct nvme_io_args *args) } /** - * nvme_dsm() - Send an nvme data set management command + * nvme_dsm_args - Arguments for the NVMe Dataset Management command * @fd: File descriptor of nvme device * @nsid: Namespace identifier * @attrs: DSM attributes, see &enum nvme_dsm_attributes @@ -3720,6 +3720,21 @@ static inline int nvme_verify(struct nvme_io_args *args) * @dsm: The data set management attributes * @timeout: Timeout in ms * @result: The command completion result from CQE dword0 + */ +struct nvme_dsm_args { + int args_size; + int fd; + __u32 nsid; + __u32 attrs; + __u16 nr_ranges; + struct nvme_dsm_range *dsm; + __u32 timeout; + __u32 *result; +}; + +/** + * nvme_dsm() - Send an nvme data set management command + * @args: &struct nvme_dsm_args argument structure * * The Dataset Management command is used by the host to indicate attributes * for ranges of logical blocks. This includes attributes like frequency that @@ -3730,8 +3745,7 @@ static inline int nvme_verify(struct nvme_io_args *args) * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_dsm(int fd, __u32 nsid, __u32 attrs, __u16 nr_ranges, - struct nvme_dsm_range *dsm, __u32 timeout, __u32 *result); +int nvme_dsm(struct nvme_dsm_args *args); /** * nvme_copy() - From 4571032fb727346971a6f733cfc391141559531b Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 17 Dec 2021 08:03:42 +0100 Subject: [PATCH 0338/1564] Use argument structure for nvme_copy() Use an argument structure instead of passing all arguments one by one. This allows for a future expansion of the argument list without having to change the library ABI. Signed-off-by: Hannes Reinecke --- src/nvme/ioctl.c | 35 +++++++++++++++++------------------ src/nvme/ioctl.h | 34 ++++++++++++++++++++++++++++------ 2 files changed, 45 insertions(+), 24 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 005ba0f509..7e3ff18cdd 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -1603,31 +1603,30 @@ int nvme_dsm(struct nvme_dsm_args *args) return nvme_submit_io_passthru(args->fd, &cmd, args->result); } -int nvme_copy(int fd, __u32 nsid, struct nvme_copy_range *copy, __u64 sdlba, - __u16 nr, __u8 prinfor, __u8 prinfow, __u8 dtype, __u16 dspec, - __u8 format, int lr, int fua, __u32 ilbrt, __u16 lbatm, - __u16 lbat, __u32 timeout, __u32 *result) +int nvme_copy(struct nvme_copy_args *args) { - __u32 cdw12 = ((nr - 1) & 0xff) | ((format & 0xf) << 8) | - ((prinfor & 0xf) << 12) | ((dtype & 0xf) << 20) | - ((prinfow & 0xf) << 26) | ((fua & 0x1) << 30) | - ((lr & 0x1) << 31); + __u32 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); struct nvme_passthru_cmd cmd = { .opcode = nvme_cmd_copy, - .nsid = nsid, - .addr = (__u64)(uintptr_t)copy, - .data_len = nr * sizeof(*copy), - .cdw10 = sdlba & 0xffffffff, - .cdw11 = sdlba >> 32, + .nsid = args->nsid, + .addr = (__u64)(uintptr_t)args->copy, + .data_len = args->nr * sizeof(*args->copy), + .cdw10 = args->sdlba & 0xffffffff, + .cdw11 = args->sdlba >> 32, .cdw12 = cdw12, - .cdw13 = (dspec & 0xffff) << 16, - .cdw14 = ilbrt, - .cdw15 = (lbatm << 16) | lbat, - .timeout_ms = timeout, + .cdw13 = (args->dspec & 0xffff) << 16, + .cdw14 = args->ilbrt, + .cdw15 = (args->lbatm << 16) | args->lbat, + .timeout_ms = args->timeout, }; - return nvme_submit_io_passthru(fd, &cmd, result); + if (args->args_size < sizeof(*args)) + return -EINVAL; + return nvme_submit_io_passthru(args->fd, &cmd, args->result); } int nvme_resv_acquire(int fd, __u32 nsid, enum nvme_resv_rtype rtype, diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 6c56b58a03..f8de15169e 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -3748,8 +3748,7 @@ struct nvme_dsm_args { int nvme_dsm(struct nvme_dsm_args *args); /** - * nvme_copy() - - * + * nvme_copy_args - Arguments for the NVMe Copy command * @fd: File descriptor of the nvme device * @nsid: Namespace identifier * @copy: Range descriptior @@ -3767,14 +3766,37 @@ int nvme_dsm(struct nvme_dsm_args *args); * @lbat: Logical block application tag * @timeout: Timeout in ms * @result: The command completion result from CQE dword0 + */ +struct nvme_copy_args { + int args_size; + int fd; + __u32 nsid; + struct nvme_copy_range *copy; + __u64 sdlba; + __u16 nr; + __u8 prinfor; + __u8 prinfow; + __u8 dtype; + __u16 dspec; + __u8 format; + int lr; + int fua; + __u32 ilbrt; + __u16 lbatm; + __u16 lbat; + __u32 timeout; + __u32 *result; +}; + +/** + * nvme_copy() - + * + * @args: &struct nvme_copy_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_copy(int fd, __u32 nsid, struct nvme_copy_range *copy, __u64 sdlba, - __u16 nr, __u8 prinfor, __u8 prinfow, __u8 dtype, __u16 dspec, - __u8 format, int lr, int fua, __u32 ilbrt, __u16 lbatm, - __u16 lbat, __u32 timeout, __u32 *result); +int nvme_copy(struct nvme_copy_args *args); /** * nvme_resv_acquire() - Send an nvme reservation acquire From b57ff520c306c5384e8b98be99cc66a31a9bccc5 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 17 Dec 2021 08:03:42 +0100 Subject: [PATCH 0339/1564] Use argument structure for NVMe reservation commands Use an argument structure for NVMe reservation commands like nvme_resv_acquire() or nvme_resv_release() instead of passing all arguments one by one. This allows for a future expansion of the argument list without having to change the library ABI. Signed-off-by: Hannes Reinecke --- src/nvme/ioctl.c | 80 +++++++++++++++++++++++++------------------ src/nvme/ioctl.h | 89 +++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 119 insertions(+), 50 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 7e3ff18cdd..9973919de4 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -1629,78 +1629,90 @@ int nvme_copy(struct nvme_copy_args *args) return nvme_submit_io_passthru(args->fd, &cmd, args->result); } -int nvme_resv_acquire(int fd, __u32 nsid, enum nvme_resv_rtype rtype, - enum nvme_resv_racqa racqa, bool iekey, - __u64 crkey, __u64 nrkey, __u32 timeout, __u32 *result) +int nvme_resv_acquire(struct nvme_resv_acquire_args *args) { - __le64 payload[2] = { cpu_to_le64(crkey), cpu_to_le64(nrkey) }; - __u32 cdw10 = (racqa & 0x7) | (iekey ? 1 << 3 : 0) | rtype << 8; + __le64 payload[2] = { + cpu_to_le64(args->crkey), + cpu_to_le64(args->nrkey) + }; + __u32 cdw10 = (args->racqa & 0x7) | + (args->iekey ? 1 << 3 : 0) | + (args->rtype << 8); struct nvme_passthru_cmd cmd = { .opcode = nvme_cmd_resv_acquire, - .nsid = nsid, + .nsid = args->nsid, .cdw10 = cdw10, .data_len = sizeof(payload), .addr = (__u64)(uintptr_t)(payload), - .timeout_ms = timeout, + .timeout_ms = args->timeout, }; - return nvme_submit_io_passthru(fd, &cmd, result); + if (args->args_size < sizeof(*args)) + return -EINVAL; + return nvme_submit_io_passthru(args->fd, &cmd, args->result); } -int nvme_resv_register(int fd, __u32 nsid, enum nvme_resv_rrega rrega, - enum nvme_resv_cptpl cptpl, bool iekey, - __u64 crkey, __u64 nrkey, __u32 timeout, __u32 *result) +int nvme_resv_register(struct nvme_resv_register_args *args) { - __le64 payload[2] = { cpu_to_le64(crkey), cpu_to_le64(nrkey) }; - __u32 cdw10 = (rrega & 0x7) | (iekey ? 1 << 3 : 0) | cptpl << 30; + __le64 payload[2] = { + cpu_to_le64(args->crkey), + cpu_to_le64(args->nrkey) + }; + __u32 cdw10 = (args->rrega & 0x7) | + (args->iekey ? 1 << 3 : 0) | + (args->cptpl << 30); struct nvme_passthru_cmd cmd = { .opcode = nvme_cmd_resv_register, - .nsid = nsid, + .nsid = args->nsid, .cdw10 = cdw10, .data_len = sizeof(payload), .addr = (__u64)(uintptr_t)(payload), - .timeout_ms = timeout, + .timeout_ms = args->timeout, }; - return nvme_submit_io_passthru(fd, &cmd, result); + if (args->args_size < sizeof(*args)) + return -EINVAL; + return nvme_submit_io_passthru(args->fd, &cmd, args->result); } -int nvme_resv_release(int fd, __u32 nsid, enum nvme_resv_rtype rtype, - enum nvme_resv_rrela rrela, bool iekey, - __u64 crkey, __u32 timeout, __u32 *result) +int nvme_resv_release(struct nvme_resv_release_args *args) { - __le64 payload[1] = { cpu_to_le64(crkey) }; - __u32 cdw10 = (rrela & 0x7) | (iekey ? 1 << 3 : 0) | rtype << 8; + __le64 payload[1] = { cpu_to_le64(args->crkey) }; + __u32 cdw10 = (args->rrela & 0x7) | + (args->iekey ? 1 << 3 : 0) | + (args->rtype << 8); struct nvme_passthru_cmd cmd = { .opcode = nvme_cmd_resv_release, - .nsid = nsid, + .nsid = args->nsid, .cdw10 = cdw10, .addr = (__u64)(uintptr_t)(payload), .data_len = sizeof(payload), - .timeout_ms = timeout, + .timeout_ms = args->timeout, }; - return nvme_submit_io_passthru(fd, &cmd, result); + if (args->args_size < sizeof(*args)) + return -EINVAL; + return nvme_submit_io_passthru(args->fd, &cmd, args->result); } -int nvme_resv_report(int fd, __u32 nsid, bool eds, __u32 len, - struct nvme_resv_status *report, __u32 timeout, - __u32 *result) +int nvme_resv_report(struct nvme_resv_report_args *args) { struct nvme_passthru_cmd cmd = { .opcode = nvme_cmd_resv_report, - .nsid = nsid, - .cdw10 = (len >> 2) - 1, - .cdw11 = eds ? 1 : 0, - .addr = (__u64)(uintptr_t)report, - .data_len = len, - .timeout_ms = timeout, + .nsid = args->nsid, + .cdw10 = (args->len >> 2) - 1, + .cdw11 = args->eds ? 1 : 0, + .addr = (__u64)(uintptr_t)args->report, + .data_len = args->len, + .timeout_ms = args->timeout, }; - return nvme_submit_io_passthru(fd, &cmd, result); + if (args->args_size < sizeof(*args)) + return -EINVAL; + return nvme_submit_io_passthru(args->fd, &cmd, args->result); } int nvme_zns_mgmt_send(int fd, __u32 nsid, __u64 slba, diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index f8de15169e..3f52887288 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -3799,7 +3799,7 @@ struct nvme_copy_args { int nvme_copy(struct nvme_copy_args *args); /** - * nvme_resv_acquire() - Send an nvme reservation acquire + * nvme_resv_acquire_args - Arguments for the NVMe Reservation Acquire Comand * @fd: File descriptor of nvme device * @nsid: Namespace identifier * @rtype: The type of reservation to be create, see &enum nvme_resv_rtype @@ -3810,6 +3810,23 @@ int nvme_copy(struct nvme_copy_args *args); * the action is preempt * @timeout: Timeout in ms * @result: The command completion result from CQE dword0 + */ +struct nvme_resv_acquire_args { + int args_size; + int fd; + __u32 nsid; + enum nvme_resv_rtype rtype; + enum nvme_resv_racqa racqa; + bool iekey; + __u64 crkey; + __u64 nrkey; + __u32 timeout; + __u32 *result; +}; + +/** + * nvme_resv_acquire() - Send an nvme reservation acquire + * @args: &struct nvme_resv_acquire argument structure * * The Reservation Acquire command acquires a reservation on a namespace, * preempt a reservation held on a namespace, and abort a reservation held on a @@ -3818,12 +3835,10 @@ int nvme_copy(struct nvme_copy_args *args); * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_resv_acquire(int fd, __u32 nsid, enum nvme_resv_rtype rtype, - enum nvme_resv_racqa racqa, bool iekey, - __u64 crkey, __u64 nrkey, __u32 timeout, __u32 *result); +int nvme_resv_acquire(struct nvme_resv_acquire_args *args); /** - * nvme_resv_register() - Send an nvme reservation register + * nvme_resv_register_args - Arguments for the NVMe Reservation Register command * @fd: File descriptor of nvme device * @nsid: Namespace identifier * @rrega: The registration action, see &enum nvme_resv_rrega @@ -3833,6 +3848,23 @@ int nvme_resv_acquire(int fd, __u32 nsid, enum nvme_resv_rtype rtype, * @nrkey: The new reservation key to be register if action is register or * replace * @timeout: Timeout in ms + */ +struct nvme_resv_register_args { + int args_size; + int fd; + __u32 nsid; + enum nvme_resv_rrega rrega; + enum nvme_resv_cptpl cptpl; + bool iekey; + __u64 crkey; + __u64 nrkey; + __u32 timeout; + __u32 *result; +}; + +/** + * nvme_resv_register() - Send an nvme reservation register + * @args: &struct nvme_resv_register_args argument structure * * The Reservation Register command registers, unregisters, or replaces a * reservation key. @@ -3840,12 +3872,10 @@ int nvme_resv_acquire(int fd, __u32 nsid, enum nvme_resv_rtype rtype, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_resv_register(int fd, __u32 nsid, enum nvme_resv_rrega rrega, - enum nvme_resv_cptpl cptpl, bool iekey, - __u64 crkey, __u64 nrkey, __u32 timeout, __u32 *result); +int nvme_resv_register(struct nvme_resv_register_args *args); /** - * nvme_resv_release() - Send an nvme reservation release + * nvme_resv_release_args - Arguments for the NVMe Reservation Release Command * @fd: File descriptor of nvme device * @nsid: Namespace identifier * @rtype: The type of reservation to be create, see &enum nvme_resv_rtype @@ -3854,16 +3884,30 @@ int nvme_resv_register(int fd, __u32 nsid, enum nvme_resv_rrega rrega, * @crkey: The current reservation key to release * @timeout: Timeout in ms * @result: The command completion result from CQE dword0 + */ +struct nvme_resv_release_args { + int args_size; + int fd; + __u32 nsid; + enum nvme_resv_rtype rtype; + enum nvme_resv_rrela rrela; + bool iekey; + __u64 crkey; + __u32 timeout; + __u32 *result; +}; + +/** + * nvme_resv_release() - Send an nvme reservation release + * @args: &struct nvme_resv_release_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_resv_release(int fd, __u32 nsid, enum nvme_resv_rtype rtype, - enum nvme_resv_rrela rrela, bool iekey, - __u64 crkey, __u32 timeout, __u32 *result); +int nvme_resv_release(struct nvme_resv_release_args *args); /** - * nvme_resv_report() - Send an nvme reservation report + * nvme_resv_report_args - Arguments for the NVMe Reservation Report command * @fd: File descriptor of nvme device * @nsid: Namespace identifier * @eds: Request extended Data Structure @@ -3872,6 +3916,21 @@ int nvme_resv_release(int fd, __u32 nsid, enum nvme_resv_rtype rtype, * report * @timeout: Timeout in ms * @result: The command completion result from CQE dword0 + */ +struct nvme_resv_report_args { + int args_size; + int fd; + __u32 nsid; + bool eds; + __u32 len; + struct nvme_resv_status *report; + __u32 timeout; + __u32 *result; +}; + +/** + * 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 @@ -3880,9 +3939,7 @@ int nvme_resv_release(int fd, __u32 nsid, enum nvme_resv_rtype rtype, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_resv_report(int fd, __u32 nsid, bool eds, __u32 len, - struct nvme_resv_status *report, - __u32 timeout, __u32 *result); +int nvme_resv_report(struct nvme_resv_report_args *args); /** * nvme_zns_mgmt_send() - From f08139355010b7c64d49b8cd2e0ecf27d1d6632b Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 17 Dec 2021 08:03:42 +0100 Subject: [PATCH 0340/1564] Use argument structure for nvme_zns_mgmt_send() and nvme_zns_mgmt_recv() Use an argument structure instead of passing all arguments one by one. This allows for a future expansion of the argument list without having to change the library ABI. Also convert zns.c to use nvme_zns_report_zones() instead of calling nvme_zns_mgmt_recv() directly. Signed-off-by: Hannes Reinecke --- src/nvme/ioctl.c | 74 ++++++++++++++++++------------------------------ src/nvme/ioctl.h | 72 ++++++++++++++++++++++++++++++++++++++-------- test/zns.c | 9 +++--- 3 files changed, 91 insertions(+), 64 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 9973919de4..531763c206 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -1715,74 +1715,54 @@ int nvme_resv_report(struct nvme_resv_report_args *args) return nvme_submit_io_passthru(args->fd, &cmd, args->result); } -int nvme_zns_mgmt_send(int fd, __u32 nsid, __u64 slba, - enum nvme_zns_send_action zsa, bool select_all, - __u8 zsaso, __u32 data_len, - void *data, __u32 timeout, __u32 *result) +int nvme_zns_mgmt_send(struct nvme_zns_mgmt_send_args *args) { - __u32 cdw10 = slba & 0xffffffff; - __u32 cdw11 = slba >> 32; - __u32 cdw13 = NVME_SET(zsaso, ZNS_MGMT_SEND_ZSASO) | - NVME_SET(!!select_all, ZNS_MGMT_SEND_SEL) | - NVME_SET(zsa, ZNS_MGMT_SEND_ZSA); + __u32 cdw10 = args->slba & 0xffffffff; + __u32 cdw11 = args->slba >> 32; + __u32 cdw13 = NVME_SET(args->zsaso, ZNS_MGMT_SEND_ZSASO) | + NVME_SET(!!args->select_all, ZNS_MGMT_SEND_SEL) | + NVME_SET(args->zsa, ZNS_MGMT_SEND_ZSA); struct nvme_passthru_cmd cmd = { .opcode = nvme_zns_cmd_mgmt_send, - .nsid = nsid, + .nsid = args->nsid, .cdw10 = cdw10, .cdw11 = cdw11, .cdw13 = cdw13, - .addr = (__u64)(uintptr_t)data, - .data_len = data_len, - .timeout_ms = timeout, + .addr = (__u64)(uintptr_t)args->data, + .data_len = args->data_len, + .timeout_ms = args->timeout, }; - return nvme_submit_io_passthru(fd, &cmd, result); + if (args->args_size < sizeof(*args)) + return -EINVAL; + return nvme_submit_io_passthru(args->fd, &cmd, args->result); } -int nvme_zns_mgmt_recv(int fd, __u32 nsid, __u64 slba, - enum nvme_zns_recv_action zra, __u16 zrasf, - bool zras_feat, __u32 data_len, void *data, - __u32 timeout, __u32 *result) +int nvme_zns_mgmt_recv(struct nvme_zns_mgmt_recv_args *args) { - __u32 cdw10 = slba & 0xffffffff; - __u32 cdw11 = slba >> 32; - __u32 cdw12 = (data_len >> 2) - 1; - __u32 cdw13 = NVME_SET(zra, ZNS_MGMT_RECV_ZRA) | - NVME_SET(zrasf, ZNS_MGMT_RECV_ZRASF) | - NVME_SET(zras_feat, ZNS_MGMT_RECV_ZRAS_FEAT); + __u32 cdw10 = args->slba & 0xffffffff; + __u32 cdw11 = args->slba >> 32; + __u32 cdw12 = (args->data_len >> 2) - 1; + __u32 cdw13 = NVME_SET(args->zra, ZNS_MGMT_RECV_ZRA) | + NVME_SET(args->zrasf, ZNS_MGMT_RECV_ZRASF) | + NVME_SET(args->zras_feat, ZNS_MGMT_RECV_ZRAS_FEAT); struct nvme_passthru_cmd cmd = { .opcode = nvme_zns_cmd_mgmt_recv, - .nsid = nsid, + .nsid = args->nsid, .cdw10 = cdw10, .cdw11 = cdw11, .cdw12 = cdw12, .cdw13 = cdw13, - .addr = (__u64)(uintptr_t)data, - .data_len = data_len, - .timeout_ms = timeout, + .addr = (__u64)(uintptr_t)args->data, + .data_len = args->data_len, + .timeout_ms = args->timeout, }; - return nvme_submit_io_passthru(fd, &cmd, result); -} - -int nvme_zns_report_zones(int fd, __u32 nsid, __u64 slba, - enum nvme_zns_report_options opts, - bool extended, bool partial, - __u32 data_len, void *data, - __u32 timeout, __u32 *result) -{ - BUILD_ASSERT(sizeof(struct nvme_zns_desc) == 64); - enum nvme_zns_recv_action zra; - - if (extended) - zra = NVME_ZNS_ZRA_EXTENDED_REPORT_ZONES; - else - zra = NVME_ZNS_ZRA_REPORT_ZONES; - - return nvme_zns_mgmt_recv(fd, nsid, slba, zra, opts, partial, - data_len, data, timeout, result); + if (args->args_size < sizeof(*args)) + return -EINVAL; + return nvme_submit_io_passthru(args->fd, &cmd, args->result); } int nvme_zns_append(int fd, __u32 nsid, __u64 zslba, __u16 nlb, __u16 control, diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 3f52887288..42604ca92a 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -3942,7 +3942,7 @@ struct nvme_resv_report_args { int nvme_resv_report(struct nvme_resv_report_args *args); /** - * nvme_zns_mgmt_send() - + * nvme_zns_mgmt_send_args - Arguments for the NVMe ZNS Management Send command * @fd: File descriptor of nvme device * @nsid: Namespace ID * @slba: Starting logical block address @@ -3953,18 +3953,33 @@ int nvme_resv_report(struct nvme_resv_report_args *args); * @data: Userspace address of the data * @timeout: timeout in ms * @result: The command completion result from CQE dword0 + */ +struct nvme_zns_mgmt_send_args { + int args_size; + int fd; + __u32 nsid; + __u64 slba; + enum nvme_zns_send_action zsa; + bool select_all; + __u8 zsaso; + __u32 data_len; + void *data; + __u32 timeout; + __u32 *result; +}; + +/** + * nvme_zns_mgmt_send() - + * @args: &struct nvme_zns_mgmt_send_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_zns_mgmt_send(int fd, __u32 nsid, __u64 slba, - enum nvme_zns_send_action zsa, bool select_all, __u8 zsaso, - __u32 data_len, void *data, - __u32 timeout, __u32 *result); +int nvme_zns_mgmt_send(struct nvme_zns_mgmt_send_args *args); /** - * nvme_zns_mgmt_recv() - + * nvme_zns_mgmt_recv_args - Arguments for the NVMe ZNS Management Receive command * @fd: File descriptor of nvme device * @nsid: Namespace ID * @slba: Starting logical block address @@ -3975,14 +3990,29 @@ int nvme_zns_mgmt_send(int fd, __u32 nsid, __u64 slba, * @data: Userspace address of the data * @timeout: timeout in ms * @result: The command completion result from CQE dword0 + */ +struct nvme_zns_mgmt_recv_args { + int args_size; + int fd; + __u32 nsid; + __u64 slba; + enum nvme_zns_recv_action zra; + __u16 zrasf; + bool zras_feat; + __u32 data_len; + void *data; + __u32 timeout; + __u32 *result; +}; + +/** + * nvme_zns_mgmt_recv() - + * @args: &struct nvme_zns_mgmt_recv_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_zns_mgmt_recv(int fd, __u32 nsid, __u64 slba, - enum nvme_zns_recv_action zra, __u16 zrasf, - bool zras_feat, __u32 data_len, void *data, - __u32 timeout, __u32 *result); +int nvme_zns_mgmt_recv(struct nvme_zns_mgmt_recv_args *args); /** * nvme_zns_report_zones() - Return the list of zones @@ -4000,11 +4030,29 @@ int nvme_zns_mgmt_recv(int fd, __u32 nsid, __u64 slba, * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_zns_report_zones(int fd, __u32 nsid, __u64 slba, +static inline int nvme_zns_report_zones(int fd, __u32 nsid, __u64 slba, enum nvme_zns_report_options opts, bool extended, bool partial, __u32 data_len, void *data, - __u32 timeout, __u32 *result); + __u32 timeout, __u32 *result) +{ + struct nvme_zns_mgmt_recv_args args = { + .args_size = sizeof(args), + .fd = fd, + .nsid = nsid, + .slba = slba, + .zra = extended ? NVME_ZNS_ZRA_EXTENDED_REPORT_ZONES : + NVME_ZNS_ZRA_REPORT_ZONES, + .zrasf = opts, + .zras_feat = partial, + .data_len = data_len, + .data = data, + .timeout = timeout, + .result = result, + }; + + return nvme_zns_mgmt_recv(&args); +} /** * nvme_zns_append() - Append data to a zone diff --git a/test/zns.c b/test/zns.c index 997765b44b..b654986230 100644 --- a/test/zns.c +++ b/test/zns.c @@ -45,11 +45,10 @@ static void show_zns_properties(nvme_ns_t n) printf("zasl:%u\n", zns_ctrl.zasl); - if (nvme_zns_mgmt_recv(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), 0, - NVME_ZNS_ZRA_REPORT_ZONES, - NVME_ZNS_ZRAS_REPORT_ALL, - true, 0x1000, (void *)zr, - NVME_DEFAULT_IOCTL_TIMEOUT, &result)) { + if (nvme_zns_report_zones(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), 0, + NVME_ZNS_ZRAS_REPORT_ALL, false, + true, 0x1000, (void *)zr, + NVME_DEFAULT_IOCTL_TIMEOUT, &result)) { fprintf(stderr, "failed to report zones, result %x\n", le32_to_cpu(result)); return; From 7eb8331d0ffbc4263fa8b6a375f34edde4b442ae Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 17 Dec 2021 08:03:42 +0100 Subject: [PATCH 0341/1564] Use argument structure for nvme_zns_append() Use an argument structure instead of passing all arguments one by one. This allows for a future expansion of the argument list without having to change the library ABI. Signed-off-by: Hannes Reinecke --- src/nvme/ioctl.c | 31 +++++++++++++++---------------- src/nvme/ioctl.h | 29 ++++++++++++++++++++++++----- 2 files changed, 39 insertions(+), 21 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 531763c206..ad1fd0cad9 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -1765,31 +1765,30 @@ int nvme_zns_mgmt_recv(struct nvme_zns_mgmt_recv_args *args) return nvme_submit_io_passthru(args->fd, &cmd, args->result); } -int nvme_zns_append(int fd, __u32 nsid, __u64 zslba, __u16 nlb, __u16 control, - __u32 ilbrt, __u16 lbat, __u16 lbatm, __u32 data_len, - void *data, __u32 metadata_len, void *metadata, - __u32 timeout, __u64 *result) +int nvme_zns_append(struct nvme_zns_append_args *args) { - __u32 cdw10 = zslba & 0xffffffff; - __u32 cdw11 = zslba >> 32; - __u32 cdw12 = nlb | (control << 16); - __u32 cdw14 = ilbrt; - __u32 cdw15 = lbat | (lbatm << 16); + __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); struct nvme_passthru_cmd64 cmd = { .opcode = nvme_zns_cmd_append, - .nsid = nsid, + .nsid = args->nsid, .cdw10 = cdw10, .cdw11 = cdw11, .cdw12 = cdw12, .cdw14 = cdw14, .cdw15 = cdw15, - .metadata = (__u64)(uintptr_t)metadata, - .addr = (__u64)(uintptr_t)data, - .metadata_len = metadata_len, - .data_len = data_len, - .timeout_ms = timeout, + .data_len = args->data_len, + .addr = (__u64)(uintptr_t)args->data, + .metadata_len = args->metadata_len, + .metadata = (__u64)(uintptr_t)args->metadata, + .timeout_ms = args->timeout, }; - return nvme_submit_io_passthru64(fd, &cmd, result); + if (args->args_size < sizeof(*args)) + return -EINVAL; + return nvme_submit_io_passthru64(args->fd, &cmd, args->result); } diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 42604ca92a..b8b479dfdf 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -4055,7 +4055,7 @@ static inline int nvme_zns_report_zones(int fd, __u32 nsid, __u64 slba, } /** - * nvme_zns_append() - Append data to a zone + * nvme_zns_append_args - Arguments for the NVMe ZNS Append command * @fd: File descriptor of nvme device * @nsid: Namespace ID * @zslba: Zone start logical block address @@ -4070,13 +4070,32 @@ static inline int nvme_zns_report_zones(int fd, __u32 nsid, __u64 slba, * @metadata: Userspace address of the metadata * @timeout: Timeout in ms * @result: The command completion result from CQE dword0 + */ +struct nvme_zns_append_args { + int args_size; + int fd; + __u32 nsid; + __u64 zslba; + __u16 nlb; + __u16 control; + __u32 ilbrt; + __u16 lbat; + __u16 lbatm; + __u32 data_len; + void *data; + __u32 metadata_len; + void *metadata; + __u32 timeout; + __u64 *result; +}; + +/** + * nvme_zns_append() - Append data to a zone + * @args: &struct nvme_zns_append_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_zns_append(int fd, __u32 nsid, __u64 zslba, __u16 nlb, __u16 control, - __u32 ilbrt, __u16 lbat, __u16 lbatm, __u32 data_len, - void *data, __u32 metadata_len, void *metadata, - __u32 timeout, __u64 *result); +int nvme_zns_append(struct nvme_zns_append_args *args); #endif /* _LIBNVME_IOCTL_H */ From a02b9f19eaf2598c1086a42d2666083c72383830 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 17 Dec 2021 12:49:18 +0100 Subject: [PATCH 0342/1564] Inline nvme_flush() nvme_flush() is a trivial wrapper around nvme_submit_io_passthru(), so inline it instead of carrying a function in the library. Signed-off-by: Hannes Reinecke --- src/nvme/ioctl.c | 10 ---------- src/nvme/ioctl.h | 9 ++++++++- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index ad1fd0cad9..a633ebf9b7 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -1542,16 +1542,6 @@ int nvme_io_passthru(int fd, __u8 opcode, __u8 flags, __u16 rsvd, data, metadata_len, metadata, timeout_ms, result); } -int nvme_flush(int fd, __u32 nsid) -{ - struct nvme_passthru_cmd cmd = { - .opcode = nvme_cmd_flush, - .nsid = nsid, - }; - - return nvme_submit_io_passthru(fd, &cmd, NULL); -} - int nvme_io(struct nvme_io_args *args, __u8 opcode) { __u32 cdw2 = args->storage_tag & 0xffffffff; diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index b8b479dfdf..eb16fac423 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -3567,7 +3567,14 @@ 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. */ -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; + cmd.nsid = nsid; + + return nvme_submit_io_passthru(fd, &cmd, NULL); +} /** * nvme_io_args - Arguments for NVMe I/O commands From c921be9f1be46a2dea78bcd8d32c0a9df6f17b4e Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Tue, 11 Jan 2022 14:18:39 +0100 Subject: [PATCH 0343/1564] libnvme.map: Export nvme_io Add missing export. Signed-off-by: Daniel Wagner --- src/libnvme.map | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libnvme.map b/src/libnvme.map index f70bf2c6ff..c4df7c40a9 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -169,6 +169,7 @@ LIBNVME_1_0 { nvme_init_ctrl_list; nvme_init_dsm_range; nvme_init_id_ns; + nvme_io; nvme_io_passthru64; nvme_io_passthru; nvme_lockdown; From 88457055b4617d52dd2bd810a6c60ce9afcca9ee Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 28 Sep 2021 11:55:07 +0200 Subject: [PATCH 0344/1564] tree: use name as argument to nvme_ctrl_lookup_subsystem_name() When looking up the subsystem in ctrl_lookup_subsystem_name() we only need the controller name, not the entire controller structure. Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index a782f04a2e..396f521a87 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -1075,7 +1075,7 @@ static int nvme_ctrl_scan_namespaces(struct nvme_ctrl *c) return 0; } -static char *nvme_ctrl_lookup_subsystem_name(nvme_ctrl_t c) +static char *nvme_ctrl_lookup_subsystem_name(char *ctrl_name) { struct dirent **subsys; char *subsys_name = NULL; @@ -1089,7 +1089,7 @@ static char *nvme_ctrl_lookup_subsystem_name(nvme_ctrl_t c) struct stat st; sprintf(path, "%s/%s/%s", nvme_subsys_sysfs_dir, - subsys[i]->d_name, c->name); + subsys[i]->d_name, ctrl_name); nvme_msg(LOG_DEBUG, "lookup subsystem %s\n", path); if (stat(path, &st) < 0) continue; @@ -1162,7 +1162,7 @@ int nvme_init_ctrl(nvme_host_t h, nvme_ctrl_t c, int instance) } } - subsys_name = nvme_ctrl_lookup_subsystem_name(c); + subsys_name = nvme_ctrl_lookup_subsystem_name(name); if (!subsys_name) { nvme_msg(LOG_ERR, "Failed to lookup subsystem name for %s\n", c->name); From 3b786292c3298dc5a09352f3a319320f36986bc4 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 28 Sep 2021 12:01:21 +0200 Subject: [PATCH 0345/1564] tree: drop 'path' argument from nvme_init_subsystem() The 'path' argument for nvme_init_subsystem() can be derived from the name. Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 396f521a87..1c44478893 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -444,9 +444,13 @@ static int nvme_subsystem_scan_ctrls(struct nvme_subsystem *s) return 0; } -static int nvme_init_subsystem(nvme_subsystem_t s, const char *name, - const char *path) +static int nvme_init_subsystem(nvme_subsystem_t s, const char *name) { + char *path; + + if (asprintf(&path, "%s/%s", nvme_subsys_sysfs_dir, name) < 0) + return -1; + s->model = nvme_get_attr(path, "model"); if (!s->model) s->model = strdup("undefined"); @@ -509,7 +513,7 @@ static int nvme_scan_subsystem(struct nvme_root *r, char *name, goto free_path; } if (!s->name) { - ret = nvme_init_subsystem(s, name, path); + ret = nvme_init_subsystem(s, name); if (ret < 0) goto free_path; } @@ -1177,17 +1181,10 @@ int nvme_init_ctrl(nvme_host_t h, nvme_ctrl_t c, int instance) goto out_free_subsys; } if (!s->name) { - ret = asprintf(&path, "%s/%s", nvme_subsys_sysfs_dir, - subsys_name); - if (ret > 0) - ret = nvme_init_subsystem(s, subsys_name, path); - else - path = NULL; + ret = nvme_init_subsystem(s, subsys_name); if (ret < 0) { - nvme_msg(LOG_ERR, "Failed to init subsystem %s/%s\n", - nvme_subsys_sysfs_dir, subsys_name); - if (path) - free(path); + nvme_msg(LOG_ERR, "Failed to init subsystem %s\n", + subsys_name); goto out_free_subsys; } } From 6b4c2fb0748a263bd94cedcd809b15070172b93f Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 28 Sep 2021 14:14:49 +0200 Subject: [PATCH 0346/1564] tree: lookup correct subsystem in nvme_scan_ctrl() Looking subsystems by subsys NQN only might yield wrong results (eg for discovery controllers), as there might be several subsystem instances all having the same subsystem NQN. Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 1c44478893..bee373995a 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -39,7 +39,7 @@ static struct nvme_host *default_host; static void __nvme_free_host(nvme_host_t h); static void __nvme_free_ctrl(nvme_ctrl_t c); static int nvme_subsystem_scan_namespace(struct nvme_subsystem *s, char *name); -static int nvme_scan_subsystem(struct nvme_root *r, char *name, +static int nvme_scan_subsystem(struct nvme_root *r, const char *name, nvme_scan_filter_t f); static int nvme_subsystem_scan_ctrl(struct nvme_subsystem *s, char *name); static int nvme_ctrl_scan_namespace(struct nvme_ctrl *c, char *name); @@ -469,7 +469,7 @@ static int nvme_init_subsystem(nvme_subsystem_t s, const char *name) return 0; } -static int nvme_scan_subsystem(struct nvme_root *r, char *name, +static int nvme_scan_subsystem(struct nvme_root *r, const char *name, nvme_scan_filter_t f) { struct nvme_subsystem *s; @@ -1079,7 +1079,7 @@ static int nvme_ctrl_scan_namespaces(struct nvme_ctrl *c) return 0; } -static char *nvme_ctrl_lookup_subsystem_name(char *ctrl_name) +static char *nvme_ctrl_lookup_subsystem_name(const char *ctrl_name) { struct dirent **subsys; char *subsys_name = NULL; @@ -1286,7 +1286,7 @@ nvme_ctrl_t nvme_scan_ctrl(nvme_root_t r, const char *name) nvme_subsystem_t s; nvme_ctrl_t c; char *path; - char *hostnqn, *hostid, *subsysnqn; + char *hostnqn, *hostid, *subsysnqn, *subsysname; int ret; ret = asprintf(&path, "%s/%s", nvme_ctrl_sysfs_dir, name); @@ -1322,7 +1322,8 @@ nvme_ctrl_t nvme_scan_ctrl(nvme_root_t r, const char *name) errno = ENXIO; return NULL; } - s = nvme_lookup_subsystem(h, NULL, subsysnqn); + subsysname = nvme_ctrl_lookup_subsystem_name(name); + s = nvme_lookup_subsystem(h, subsysname, subsysnqn); free(subsysnqn); if (!s) { free(path); From c12bd2c59e751fffdc93879c2aa13401408dc02f Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 15 Nov 2021 11:32:20 +0100 Subject: [PATCH 0347/1564] tree: scan controllers before scanning subsystems in nvme_scan_topology() The linux sysfs hierarchy only knows about 'controllers' and 'subsystems', so when scanning the topology we should follow this structure and scan first for controllers and then for subsystems. Just scanning for subsystems and all controllers attached to them has the problem that the hostnqn can only be derived from the controller, but by the time the controller is scanned the subsystem has already been created and attached to the default host. Scanning for controllers first will setup the correct hosts (and subsystems), so the subsequent scan for subsystems is primarily there to find all namespaces attached to the subsystems. Signed-off-by: Hannes Reinecke --- doc/libnvme.rst | 11 ----- doc/man/nvme_scan_subsystem_ctrls.2 | 11 ----- src/libnvme.map | 1 - src/nvme/filters.c | 12 ++--- src/nvme/filters.h | 13 +++-- src/nvme/tree.c | 74 ++++++++++------------------- 6 files changed, 38 insertions(+), 84 deletions(-) delete mode 100644 doc/man/nvme_scan_subsystem_ctrls.2 diff --git a/doc/libnvme.rst b/doc/libnvme.rst index 09c69c5888..3f347dbb02 100644 --- a/doc/libnvme.rst +++ b/doc/libnvme.rst @@ -38,17 +38,6 @@ ``struct dirent *** subsys`` -.. c:function:: int nvme_scan_subsystem_ctrls (nvme_subsystem_t s, struct dirent *** ctrls) - - -**Parameters** - -``nvme_subsystem_t s`` - *undescribed* - -``struct dirent *** ctrls`` - - .. c:function:: int nvme_scan_subsystem_namespaces (nvme_subsystem_t s, struct dirent *** namespaces) diff --git a/doc/man/nvme_scan_subsystem_ctrls.2 b/doc/man/nvme_scan_subsystem_ctrls.2 deleted file mode 100644 index a596878804..0000000000 --- a/doc/man/nvme_scan_subsystem_ctrls.2 +++ /dev/null @@ -1,11 +0,0 @@ -.TH "nvme_scan_subsystem_ctrls" 2 "nvme_scan_subsystem_ctrls" "February 2020" "libnvme Manual" -.SH NAME -nvme_scan_subsystem_ctrls \- -.SH SYNOPSIS -.B "int" nvme_scan_subsystem_ctrls -.BI "(nvme_subsystem_t " s "," -.BI "struct dirent ***" ctrls ");" -.SH ARGUMENTS -.IP "s" 12 --- undescribed -- -.IP "ctrls" 12 diff --git a/src/libnvme.map b/src/libnvme.map index f70bf2c6ff..b0cf2933e2 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -241,7 +241,6 @@ LIBNVME_1_0 { nvme_scan_ctrl_namespaces; nvme_scan_filter; nvme_scan_namespace; - nvme_scan_subsystem_ctrls; nvme_scan_subsystem_namespaces; nvme_scan_subsystems; nvme_security_receive; diff --git a/src/nvme/filters.c b/src/nvme/filters.c index 06137f5f1a..b726db6961 100644 --- a/src/nvme/filters.c +++ b/src/nvme/filters.c @@ -93,18 +93,18 @@ int nvme_scan_subsystems(struct dirent ***subsys) alphasort); } -int nvme_scan_subsystem_ctrls(nvme_subsystem_t s, struct dirent ***ctrls) -{ - return scandir(nvme_subsystem_get_sysfs_dir(s), ctrls, - nvme_ctrls_filter, alphasort); -} - int nvme_scan_subsystem_namespaces(nvme_subsystem_t s, struct dirent ***namespaces) { return scandir(nvme_subsystem_get_sysfs_dir(s), namespaces, nvme_namespace_filter, alphasort); } +int nvme_scan_ctrls(struct dirent ***ctrls) +{ + return scandir(nvme_ctrl_sysfs_dir, ctrls, nvme_ctrls_filter, + alphasort); +} + int nvme_scan_ctrl_namespace_paths(nvme_ctrl_t c, struct dirent ***namespaces) { return scandir(nvme_ctrl_get_sysfs_dir(c), namespaces, diff --git a/src/nvme/filters.h b/src/nvme/filters.h index 52318311b0..cf10cdb86d 100644 --- a/src/nvme/filters.h +++ b/src/nvme/filters.h @@ -53,22 +53,21 @@ int nvme_subsys_filter(const struct dirent *d); int nvme_scan_subsystems(struct dirent ***subsys); /** - * nvme_scan_subsystem_ctrls() - + * nvme_scan_subsystem_namespaces() - * @s: - * @ctrls: + * @namespaces: * * Return: */ -int nvme_scan_subsystem_ctrls(nvme_subsystem_t s, struct dirent ***ctrls); +int nvme_scan_subsystem_namespaces(nvme_subsystem_t s, struct dirent ***namespaces); /** - * nvme_scan_subsystem_namespaces() - - * @s: - * @namespaces: + * nvme_scan_ctrls() - + * @ctrls: * * Return: */ -int nvme_scan_subsystem_namespaces(nvme_subsystem_t s, struct dirent ***namespaces); +int nvme_scan_ctrls(struct dirent ***ctrls); /** * nvme_scan_ctrl_namespace_paths() - diff --git a/src/nvme/tree.c b/src/nvme/tree.c index bee373995a..52c2b2253a 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -41,7 +41,6 @@ static void __nvme_free_ctrl(nvme_ctrl_t c); static int nvme_subsystem_scan_namespace(struct nvme_subsystem *s, char *name); static int nvme_scan_subsystem(struct nvme_root *r, const char *name, nvme_scan_filter_t f); -static int nvme_subsystem_scan_ctrl(struct nvme_subsystem *s, char *name); static int nvme_ctrl_scan_namespace(struct nvme_ctrl *c, char *name); static int nvme_ctrl_scan_path(struct nvme_ctrl *c, char *name); @@ -72,8 +71,28 @@ nvme_host_t nvme_default_host(nvme_root_t r) static int nvme_scan_topology(struct nvme_root *r, nvme_scan_filter_t f) { - struct dirent **subsys; - int i, num_subsys, ret; + struct dirent **subsys, **ctrls; + int i, num_subsys, num_ctrls, ret; + + num_ctrls = nvme_scan_ctrls(&ctrls); + if (num_ctrls < 0) { + nvme_msg(LOG_DEBUG, "failed to scan ctrls: %s\n", + strerror(errno)); + return num_ctrls; + } + + for (i = 0; i < num_ctrls; i++) { + nvme_ctrl_t c = nvme_scan_ctrl(r, ctrls[i]->d_name); + if (!c) { + nvme_msg(LOG_DEBUG, "failed to scan ctrl %s: %s\n", + ctrls[i]->d_name, strerror(errno)); + } + if ((f) && !f(c->s)) { + nvme_free_ctrl(c); + } + } + + nvme_free_dirents(ctrls, i); num_subsys = nvme_scan_subsystems(&subsys); if (num_subsys < 0) { @@ -91,6 +110,7 @@ static int nvme_scan_topology(struct nvme_root *r, nvme_scan_filter_t f) } nvme_free_dirents(subsys, i); + return 0; } @@ -419,31 +439,6 @@ static int nvme_subsystem_scan_namespaces(struct nvme_subsystem *s) return 0; } -static int nvme_subsystem_scan_ctrls(struct nvme_subsystem *s) -{ - struct dirent **ctrls; - int i, num_ctrls, ret; - - num_ctrls = nvme_scan_subsystem_ctrls(s, &ctrls); - if (num_ctrls < 0) { - nvme_msg(LOG_DEBUG, - "failed to scan ctrls for subsys %s: %s\n", - s->subsysnqn, strerror(errno)); - return num_ctrls; - } - - for (i = 0; i < num_ctrls; i++) { - ret = nvme_subsystem_scan_ctrl(s, ctrls[i]->d_name); - if (ret < 0) - nvme_msg(LOG_DEBUG, - "failed to scan ctrl %s: %s\n", - ctrls[i]->d_name, strerror(errno)); - } - - nvme_free_dirents(ctrls, i); - return 0; -} - static int nvme_init_subsystem(nvme_subsystem_t s, const char *name) { char *path; @@ -519,7 +514,6 @@ static int nvme_scan_subsystem(struct nvme_root *r, const char *name, } nvme_subsystem_scan_namespaces(s); - nvme_subsystem_scan_ctrls(s); if (f && !f(s)) { __nvme_free_subsystem(s); @@ -1330,31 +1324,15 @@ nvme_ctrl_t nvme_scan_ctrl(nvme_root_t r, const char *name) errno = ENOMEM; return NULL; } - c = nvme_ctrl_alloc(s, path, name); - if (!c) - free(path); - - return c; -} - -static int nvme_subsystem_scan_ctrl(struct nvme_subsystem *s, char *name) -{ - nvme_ctrl_t c; - char *path; - - if (asprintf(&path, "%s/%s", s->sysfs_dir, name) < 0) { - errno = ENOMEM; - return -1; - } - c = nvme_ctrl_alloc(s, path, name); if (!c) { free(path); - return -1; + return NULL; } + nvme_ctrl_scan_namespaces(c); nvme_ctrl_scan_paths(c); - return 0; + return c; } void nvme_rescan_ctrl(struct nvme_ctrl *c) From 9a4dd382809176d49fb679bf582386ecd6358c8d Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 13 Jan 2022 17:18:45 +0100 Subject: [PATCH 0348/1564] Move 'host_traddr' and 'host_iface' into fabrics configuration Having 'host_traddr' and 'host_iface' as part of the controller structure is technically correct, but won't work for 'connect-all'. There we evaluate the contents of the discovery log page, and create new controllers based on that information. But as 'host_traddr' and 'host_iface' are Linux-only constructs, the spec (and the discovery log page) doesn't know about them, and can't provide us with that information. Signed-off-by: Hannes Reinecke --- libnvme/nvme.i | 6 ++++-- src/nvme/fabrics.c | 9 ++++++--- src/nvme/fabrics.h | 4 ++++ src/nvme/private.h | 2 -- src/nvme/tree.c | 28 ++++++++++++++-------------- 5 files changed, 28 insertions(+), 21 deletions(-) diff --git a/libnvme/nvme.i b/libnvme/nvme.i index 5458d3cc49..ab4d743f18 100644 --- a/libnvme/nvme.i +++ b/libnvme/nvme.i @@ -123,6 +123,10 @@ static int discover_err = 0; temp.tos = -1; temp.ctrl_loss_tmo = NVMF_DEF_CTRL_LOSS_TMO; while (PyDict_Next($input, &pos, &key, &value)) { + if (!PyUnicode_CompareWithASCIIString(key, "host_traddr")) + temp.host_traddr = PyBytes_AsString(value); + if (!PyUnicode_CompareWithASCIIString(key, "host_iface")) + temp.host_iface = PyBytes_AsString(value); if (!PyUnicode_CompareWithASCIIString(key, "nr_io_queues")) temp.nr_io_queues = PyLong_AsLong(value); if (!PyUnicode_CompareWithASCIIString(key, "reconnect_delay")) @@ -293,7 +297,6 @@ struct nvme_ctrl { %immutable transport; %immutable subsysnqn; %immutable traddr; - %immutable host_traddr; %immutable trsvcid; %immutable address; %immutable firmware; @@ -307,7 +310,6 @@ struct nvme_ctrl { char *transport; char *subsysnqn; char *traddr; - char *host_traddr; char *trsvcid; char *dhchap_key; char *address; diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 82c4deb824..7645e40250 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -170,6 +170,8 @@ static struct nvme_fabrics_config *merge_config(nvme_ctrl_t c, { struct nvme_fabrics_config *ctrl_cfg = nvme_ctrl_get_config(c); + UPDATE_CFG_OPTION(ctrl_cfg, cfg, host_traddr, NULL); + UPDATE_CFG_OPTION(ctrl_cfg, cfg, host_iface, NULL); UPDATE_CFG_OPTION(ctrl_cfg, cfg, nr_io_queues, 0); UPDATE_CFG_OPTION(ctrl_cfg, cfg, nr_write_queues, 0); UPDATE_CFG_OPTION(ctrl_cfg, cfg, nr_poll_queues, 0); @@ -438,9 +440,9 @@ static int build_options(nvme_host_t h, nvme_ctrl_t c, char **argstr) add_argument(argstr, "traddr", nvme_ctrl_get_traddr(c)) || add_argument(argstr, "host_traddr", - nvme_ctrl_get_host_traddr(c)) || + cfg->host_traddr) || add_argument(argstr, "host_iface", - nvme_ctrl_get_host_iface(c)) || + cfg->host_iface) || add_argument(argstr, "trsvcid", nvme_ctrl_get_trsvcid(c)) || (hostnqn && add_argument(argstr, "hostnqn", hostnqn)) || @@ -648,7 +650,8 @@ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, nvme_msg(LOG_DEBUG, "lookup ctrl " "(transport: %s, traddr: %s, trsvcid %s)\n", transport, traddr, trsvcid); - c = nvme_create_ctrl(e->subnqn, transport, traddr, NULL, NULL, trsvcid); + c = nvme_create_ctrl(e->subnqn, transport, traddr, + cfg->host_traddr, cfg->host_iface, trsvcid); if (!c) { nvme_msg(LOG_DEBUG, "skipping discovery entry, " "failed to allocate %s controller with traddr %s\n", diff --git a/src/nvme/fabrics.h b/src/nvme/fabrics.h index 73932ff382..0309c978ef 100644 --- a/src/nvme/fabrics.h +++ b/src/nvme/fabrics.h @@ -18,6 +18,8 @@ /** * struct nvme_fabrics_config - Defines all linux nvme fabrics initiator options + * @host_traddr: Host transport address + * @host_iface: Host interface name * @queue_size: Number of IO queue entries * @nr_io_queues: Number of controller IO queues to establish * @reconnect_delay: Time between two consecutive reconnect attempts. @@ -33,6 +35,8 @@ * @data_digest: Generate/verify data digest (TCP) */ struct nvme_fabrics_config { + char *host_traddr; + char *host_iface; int queue_size; int nr_io_queues; int reconnect_delay; diff --git a/src/nvme/private.h b/src/nvme/private.h index d6abb3e9c9..5b5809aa75 100644 --- a/src/nvme/private.h +++ b/src/nvme/private.h @@ -85,8 +85,6 @@ struct nvme_ctrl { char *subsysnqn; char *traddr; char *trsvcid; - char *host_traddr; - char *host_iface; char *dhchap_key; bool discovery_ctrl; bool discovered; diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 7bcecc9bdd..91f6f51c5b 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -716,12 +716,12 @@ const char *nvme_ctrl_get_trsvcid(nvme_ctrl_t c) const char *nvme_ctrl_get_host_traddr(nvme_ctrl_t c) { - return c->host_traddr; + return c->cfg.host_traddr; } const char *nvme_ctrl_get_host_iface(nvme_ctrl_t c) { - return c->host_iface; + return c->cfg.host_iface; } struct nvme_fabrics_config *nvme_ctrl_get_config(nvme_ctrl_t c) @@ -866,8 +866,8 @@ static void __nvme_free_ctrl(nvme_ctrl_t c) FREE_CTRL_ATTR(c->transport); FREE_CTRL_ATTR(c->subsysnqn); FREE_CTRL_ATTR(c->traddr); - FREE_CTRL_ATTR(c->host_traddr); - FREE_CTRL_ATTR(c->host_iface); + FREE_CTRL_ATTR(c->cfg.host_traddr); + FREE_CTRL_ATTR(c->cfg.host_iface); FREE_CTRL_ATTR(c->trsvcid); free(c); } @@ -917,7 +917,7 @@ void hostname2traddr(nvme_ctrl_t c, const char *host_traddr) if (ret) { nvme_msg(LOG_DEBUG, "failed to resolve host %s info\n", host_traddr); - c->host_traddr = strdup(host_traddr); + c->cfg.host_traddr = strdup(host_traddr); return; } @@ -935,15 +935,15 @@ void hostname2traddr(nvme_ctrl_t c, const char *host_traddr) default: nvme_msg(LOG_DEBUG, "unrecognized address family (%d) %s\n", host_info->ai_family, c->traddr); - c->host_traddr = strdup(host_traddr); + c->cfg.host_traddr = strdup(host_traddr); goto free_addrinfo; } if (!p) { nvme_msg(LOG_DEBUG, "failed to get traddr for %s\n", c->traddr); - c->host_traddr = strdup(host_traddr); + c->cfg.host_traddr = strdup(host_traddr); } else - c->host_traddr = strdup(addrstr); + c->cfg.host_traddr = strdup(addrstr); free_addrinfo: freeaddrinfo(host_info); @@ -991,10 +991,10 @@ struct nvme_ctrl *nvme_create_ctrl(const char *subsysnqn, const char *transport, if (traddr_is_hostname(transport, host_traddr)) hostname2traddr(c, host_traddr); else - c->host_traddr = strdup(host_traddr); + c->cfg.host_traddr = strdup(host_traddr); } if (host_iface) - c->host_iface = strdup(host_iface); + c->cfg.host_iface = strdup(host_iface); if (trsvcid) c->trsvcid = strdup(trsvcid); else if (discovery) @@ -1025,11 +1025,11 @@ struct nvme_ctrl *nvme_lookup_ctrl(struct nvme_subsystem *s, const char *transpo if (traddr && c->traddr && strcmp(c->traddr, traddr)) continue; - if (host_traddr && c->host_traddr && - strcmp(c->host_traddr, host_traddr)) + if (host_traddr && c->cfg.host_traddr && + strcmp(c->cfg.host_traddr, host_traddr)) continue; - if (host_iface && c->host_iface && - strcmp(c->host_iface, host_iface)) + if (host_iface && c->cfg.host_iface && + strcmp(c->cfg.host_iface, host_iface)) continue; if (trsvcid && c->trsvcid && strcmp(c->trsvcid, trsvcid)) From 70c9a1a486b9743c00516778bdcc24301e43e299 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 13 Jan 2022 14:56:34 +0100 Subject: [PATCH 0349/1564] ioctl: Remove declration of nvme_set_features_iocs_profile() There is no implemenation for this function. Remove it. Signed-off-by: Daniel Wagner --- src/nvme/ioctl.h | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index eb16fac423..1cfedf1dba 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -2231,18 +2231,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); - -/** - * nvme_set_features_iocs_profile() - - * @fd: File descriptor of nvme device - * @iocsi: IO Command Set Combination Index - * @save: Save value across power states - * - * Return: The nvme command status if a response was received (see - * &enum nvme_status_field) or -1 with errno set otherwise. - */ -int nvme_set_features_iocs_profile(int fd, __u8 iocsi, bool save); - /** * nvme_get_features_args - Arguments for the NVMe Admin Get Feature command * @fd: File descriptor of nvme device From b5b991d4082654df97315b951622622932aa8082 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 13 Jan 2022 14:19:16 +0100 Subject: [PATCH 0350/1564] ioctl: Rearrange members in nvme_identify_args Avoid any holes in the struct by rearranging the members. Also add the attribute packed to struct definition to reduce ABI breakage. struct nvme_identify_args { int args_size; /* 0 4 */ int fd; /* 4 4 */ __u32 * result; /* 8 8 */ __u32 timeout; /* 16 4 */ enum nvme_identify_cns cns; /* 20 4 */ void * data; /* 24 8 */ enum nvme_csi csi; /* 32 4 */ __u32 nsid; /* 36 4 */ __u16 cntid; /* 40 2 */ __u16 nvmsetid; /* 42 2 */ __u16 domid; /* 44 2 */ __u8 uuidx; /* 46 1 */ /* size: 48, cachelines: 1, members: 12 */ /* padding: 1 */ /* last cacheline: 48 bytes */ } __attribute__((__aligned__(8))); Signed-off-by: Daniel Wagner --- src/nvme/ioctl.h | 139 +++++++++++++++++++++++------------------------ 1 file changed, 69 insertions(+), 70 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 1cfedf1dba..c3409ca3f2 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -376,31 +376,31 @@ int nvme_get_nsid(int fd, __u32 *nsid); /** * nvme_identify_args - Arguments for the NVMe Identify command * @fd: File descriptor of nvme device + * @result: The command completion result from CQE dword0 + * @timeout: Timeout in ms (0 for default timeout) * @cns: The Controller or Namespace structure, see @enum nvme_identify_cns + * @data: User space destination address to transfer the data + * @csi: Command Set Identifier * @nsid: Namespace identifier, if applicable * @domid: Domain identifier, if applicable * @cntid: The Controller Identifier, if applicable * @nvmsetid: The NVMe Set ID if CNS is 04h * @uuidx: UUID Index if controller supports this id selection method - * @csi: Command Set Identifier - * @data: User space destination address to transfer the data - * @timeout: Timeout in ms (0 for default timeout) - * @result: The command completion result from CQE dword0 */ struct nvme_identify_args { int args_size; int fd; + __u32 *result; + __u32 timeout; enum nvme_identify_cns cns; + void *data; + enum nvme_csi csi; __u32 nsid; __u16 cntid; __u16 nvmsetid; __u16 domid; __u8 uuidx; - enum nvme_csi csi; - void *data; - __u32 timeout; - __u32 *result; -}; +} __attribute__((packed, aligned(__alignof__(__u32*)))); /** * nvme_identify() - Send the NVMe Identify command @@ -420,16 +420,16 @@ static int nvme_identify_cns_nsid(int fd, enum nvme_identify_cns cns, struct nvme_identify_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .cns = cns, + .data = data, + .csi = NVME_CSI_NVM, .nsid = nsid, .cntid = NVME_CNTLID_NONE, .nvmsetid = NVME_NVMSETID_NONE, .domid = NVME_DOMID_NONE, .uuidx = NVME_UUID_NONE, - .csi = NVME_CSI_NVM, - .data = data, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, }; return nvme_identify(&args); @@ -560,16 +560,16 @@ static inline int nvme_identify_ctrl_list(int fd, __u16 cntid, struct nvme_identify_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .cns = NVME_IDENTIFY_CNS_CTRL_LIST, + .data = ctrlist, + .csi = NVME_CSI_NVM, .nsid = NVME_NSID_NONE, .cntid = cntid, .nvmsetid = NVME_NVMSETID_NONE, .domid = NVME_DOMID_NONE, .uuidx = NVME_UUID_NONE, - .csi = NVME_CSI_NVM, - .data = ctrlist, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, }; return nvme_identify(&args); @@ -597,16 +597,16 @@ static inline int nvme_identify_nsid_ctrl_list(int fd, __u32 nsid, __u16 cntid, struct nvme_identify_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .cns = NVME_IDENTIFY_CNS_NS_CTRL_LIST, + .data = ctrlist, + .csi = NVME_CSI_NVM, .nsid = nsid, .cntid = cntid, .nvmsetid = NVME_NVMSETID_NONE, .domid = NVME_DOMID_NONE, .uuidx = NVME_UUID_NONE, - .csi = NVME_CSI_NVM, - .data = ctrlist, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, }; return nvme_identify(&args); @@ -658,16 +658,16 @@ static inline int nvme_identify_nvmset_list(int fd, __u16 nvmsetid, struct nvme_identify_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .cns = NVME_IDENTIFY_CNS_NVMSET_LIST, + .data = nvmset, + .csi = NVME_CSI_NVM, .nsid = NVME_NSID_NONE, .cntid = NVME_CNTLID_NONE, .nvmsetid = nvmsetid, .domid = NVME_DOMID_NONE, .uuidx = NVME_UUID_NONE, - .csi = NVME_CSI_NVM, - .data = nvmset, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, }; return nvme_identify(&args); @@ -691,16 +691,16 @@ static inline int nvme_identify_primary_ctrl(int fd, __u16 cntid, struct nvme_identify_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .cns = NVME_IDENTIFY_CNS_PRIMARY_CTRL_CAP, + .data = cap, + .csi = NVME_CSI_NVM, .nsid = NVME_NSID_NONE, .cntid = cntid, .nvmsetid = NVME_NVMSETID_NONE, .domid = NVME_DOMID_NONE, .uuidx = NVME_UUID_NONE, - .csi = NVME_CSI_NVM, - .data = cap, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, }; return nvme_identify(&args); @@ -730,16 +730,16 @@ static inline int nvme_identify_secondary_ctrl_list(int fd, __u32 nsid, struct nvme_identify_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .cns = NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST, + .data = list, + .csi = NVME_CSI_NVM, .nsid = nsid, .cntid = cntid, .nvmsetid = NVME_NVMSETID_NONE, .domid = NVME_DOMID_NONE, .uuidx = NVME_UUID_NONE, - .csi = NVME_CSI_NVM, - .data = list, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, }; return nvme_identify(&args); @@ -803,16 +803,16 @@ static inline int nvme_identify_ns_csi(int fd, __u32 nsid, struct nvme_identify_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .cns = NVME_IDENTIFY_CNS_CSI_NS, + .data = data, + .csi = csi, .nsid = nsid, .cntid = NVME_CNTLID_NONE, .nvmsetid = NVME_NVMSETID_NONE, .domid = NVME_DOMID_NONE, .uuidx = NVME_UUID_NONE, - .csi = csi, - .data = data, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, }; return nvme_identify(&args); @@ -832,16 +832,16 @@ static inline int nvme_identify_ctrl_csi(int fd, enum nvme_csi csi, void *data) struct nvme_identify_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .cns = NVME_IDENTIFY_CNS_CSI_CTRL, + .data = data, + .csi = csi, .nsid = NVME_NSID_NONE, .cntid = NVME_CNTLID_NONE, .nvmsetid = NVME_NVMSETID_NONE, .domid = NVME_DOMID_NONE, .uuidx = NVME_UUID_NONE, - .csi = csi, - .data = data, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, }; return nvme_identify(&args); @@ -870,16 +870,16 @@ static inline int nvme_identify_active_ns_list_csi(int fd, __u32 nsid, struct nvme_identify_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .cns = NVME_IDENTIFY_CNS_NS_ACTIVE_LIST, + .data = list, + .csi = csi, .nsid = nsid, .cntid = NVME_CNTLID_NONE, .nvmsetid = NVME_NVMSETID_NONE, .domid = NVME_DOMID_NONE, .uuidx = NVME_UUID_NONE, - .csi = csi, - .data = list, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, }; return nvme_identify(&args); @@ -908,16 +908,16 @@ static inline int nvme_identify_allocated_ns_list_csi(int fd, __u32 nsid, struct nvme_identify_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .cns = NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST, + .data = list, + .csi = csi, .nsid = nsid, .cntid = NVME_CNTLID_NONE, .nvmsetid = NVME_NVMSETID_NONE, .domid = NVME_DOMID_NONE, .uuidx = NVME_UUID_NONE, - .csi = csi, - .data = list, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, }; return nvme_identify(&args); @@ -939,16 +939,16 @@ static inline int nvme_identify_independent_identify_ns(int fd, __u32 nsid, struct nvme_identify_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .cns = NVME_IDENTIFY_CNS_CSI_INDEPENDENT_ID_NS, + .data = ns, + .csi = NVME_CSI_NVM, .nsid = nsid, .cntid = NVME_CNTLID_NONE, .nvmsetid = NVME_NVMSETID_NONE, .domid = NVME_DOMID_NONE, .uuidx = NVME_UUID_NONE, - .csi = NVME_CSI_NVM, - .data = ns, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, }; return nvme_identify(&args); @@ -989,16 +989,16 @@ static inline int nvme_identify_domain_list(int fd, __u16 domid, struct nvme_identify_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .cns = NVME_IDENTIFY_CNS_DOMAIN_LIST, + .data = list, + .csi = NVME_CSI_NVM, .nsid = NVME_NSID_NONE, .cntid = NVME_CNTLID_NONE, .nvmsetid = NVME_NVMSETID_NONE, .domid = domid, .uuidx = NVME_UUID_NONE, - .csi = NVME_CSI_NVM, - .data = list, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, }; return nvme_identify(&args); @@ -1019,16 +1019,16 @@ static inline int nvme_identify_endurance_group_list(int fd, __u16 endgrp_id, struct nvme_identify_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .cns = NVME_IDENTIFY_CNS_ENDURANCE_GROUP_ID, + .data = list, + .csi = NVME_CSI_NVM, .nsid = NVME_NSID_NONE, .cntid = NVME_CNTLID_NONE, .nvmsetid = NVME_NVMSETID_NONE, .domid = endgrp_id, .uuidx = NVME_UUID_NONE, - .csi = NVME_CSI_NVM, - .data = list, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, }; return nvme_identify(&args); @@ -1052,16 +1052,16 @@ static inline int nvme_identify_iocs(int fd, __u16 cntlid, struct nvme_identify_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .cns = NVME_IDENTIFY_CNS_COMMAND_SET_STRUCTURE, + .data = iocs, + .csi = NVME_CSI_NVM, .nsid = NVME_NSID_NONE, .cntid = cntlid, .nvmsetid = NVME_NVMSETID_NONE, .domid = NVME_DOMID_NONE, .uuidx = NVME_UUID_NONE, - .csi = NVME_CSI_NVM, - .data = iocs, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, }; return nvme_identify(&args); @@ -1082,16 +1082,15 @@ static inline int nvme_zns_identify_ns(int fd, __u32 nsid, struct nvme_identify_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .cns = NVME_IDENTIFY_CNS_CSI_NS, + .data = data, + .csi = NVME_CSI_ZNS, .nsid = nsid, .cntid = NVME_CNTLID_NONE, .nvmsetid = NVME_NVMSETID_NONE, .domid = NVME_DOMID_NONE, - .uuidx = NVME_UUID_NONE, - .csi = NVME_CSI_ZNS, - .data = data, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, }; return nvme_identify(&args); From 659a37c1c380310e8ca3041277dbb85196744f60 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 13 Jan 2022 14:43:31 +0100 Subject: [PATCH 0351/1564] ioctl: Rearrange members in nvme_get_log_args Avoid any holes in the struct by rearranging the members. Also add the attribute packed to struct definition to reduce ABI breakage. struct nvme_get_log_args { int args_size; /* 0 4 */ int fd; /* 4 4 */ __u32 * result; /* 8 8 */ __u32 timeout; /* 16 4 */ enum nvme_cmd_get_log_lid lid; /* 20 4 */ __u64 lpo; /* 24 8 */ void * log; /* 32 8 */ __u32 len; /* 40 4 */ __u32 nsid; /* 44 4 */ enum nvme_csi csi; /* 48 4 */ __u16 lsi; /* 52 2 */ __u8 lsp; /* 54 1 */ __u8 uuidx; /* 55 1 */ _Bool rae; /* 56 1 */ _Bool ot; /* 57 1 */ /* size: 64, cachelines: 1, members: 15 */ /* padding: 6 */ } __attribute__((__aligned__(8))); Signed-off-by: Daniel Wagner --- src/nvme/ioctl.h | 273 +++++++++++++++++++++++------------------------ 1 file changed, 136 insertions(+), 137 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index c3409ca3f2..c5e7049830 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -1113,41 +1113,40 @@ static inline int nvme_zns_identify_ctrl(int fd, struct nvme_zns_id_ctrl *id) * nvme_get_log_args - Arguments for the NVMe Admin Get Log command * @args_size: Length of the structure * @fd: File descriptor of nvme device + * @result: The command completion result from CQE dword0 + * @timeout: Timeout in ms * @lid: Log page identifier, see &enum nvme_cmd_get_log_lid for known * values - * @nsid: Namespace identifier, if applicable * @lpo: Log page offset for partial log transfers + * @log: User space destination address to transfer the data + * @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 * @lsp: Log specific field * @lsi: Endurance group information - * @rae: Retain asynchronous events * @uuidx: UUID selection, if supported - * @len: Length of provided user buffer to hold the log data in bytes - * @log: User space destination address to transfer the data - * @timeout: Timeout in ms - * @result: The command completion result from CQE dword0 - * @csi: Command set identifier, see &enum nvme_csi for known values + * @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 { int args_size; int fd; + __u32 *result; + __u32 timeout; enum nvme_cmd_get_log_lid lid; - __u32 nsid; __u64 lpo; - __u8 lsp; - __u16 lsi; - bool rae; - __u8 uuidx; - __u32 len; void *log; - __u32 timeout; - __u32 *result; + __u32 len; + __u32 nsid; enum nvme_csi csi; + __u16 lsi; + __u8 lsp; + __u8 uuidx; + bool rae; bool ot; -}; +} __attribute__((packed, aligned(__alignof__(__u64)))); /** * nvme_get_log() - NVMe Admin Get Log command @@ -1165,18 +1164,18 @@ static inline int nvme_get_nsid_log(int fd, bool rae, struct nvme_get_log_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .lid = lid, - .nsid = nsid, .lpo = 0, - .lsp = NVME_LOG_LSP_NONE, - .lsi = NVME_LOG_LSI_NONE, - .rae = false, - .uuidx = NVME_UUID_NONE, - .len = len, .log = log, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, + .len = len, + .nsid = nsid, .csi = NVME_CSI_NVM, + .lsi = NVME_LOG_LSI_NONE, + .lsp = NVME_LOG_LSP_NONE, + .uuidx = NVME_UUID_NONE, + .rae = false, .ot = false, }; @@ -1310,18 +1309,18 @@ static inline int nvme_get_log_cmd_effects(int fd, enum nvme_csi csi, struct nvme_get_log_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .lid = NVME_LOG_LID_CMD_EFFECTS, - .nsid = NVME_NSID_ALL, .lpo = 0, - .lsp = NVME_LOG_LSP_NONE, - .lsi = NVME_LOG_LSI_NONE, - .rae = false, - .uuidx = NVME_UUID_NONE, - .len = sizeof(*log), .log = log, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, + .len = sizeof(*log), + .nsid = NVME_NSID_ALL, .csi = csi, + .lsi = NVME_LOG_LSI_NONE, + .lsp = NVME_LOG_LSP_NONE, + .uuidx = NVME_UUID_NONE, + .rae = false, .ot = false, }; return nvme_get_log(&args); @@ -1357,18 +1356,18 @@ static inline int nvme_get_log_create_telemetry_host(int fd, struct nvme_get_log_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .lid = NVME_LOG_LID_TELEMETRY_HOST, - .nsid = NVME_NSID_NONE, .lpo = 0, - .lsp = NVME_LOG_TELEM_HOST_LSP_CREATE, - .lsi = NVME_LOG_LSI_NONE, - .rae = false, - .uuidx = NVME_UUID_NONE, - .len = sizeof(*log), .log = log, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, + .len = sizeof(*log), + .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, + .lsi = NVME_LOG_LSI_NONE, + .lsp = NVME_LOG_TELEM_HOST_LSP_CREATE, + .uuidx = NVME_UUID_NONE, + .rae = false, .ot = false, }; return nvme_get_log(&args); @@ -1394,18 +1393,18 @@ static inline int nvme_get_log_telemetry_host(int fd, __u64 offset, struct nvme_get_log_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .lid = NVME_LOG_LID_TELEMETRY_HOST, - .nsid = NVME_NSID_NONE, .lpo = 0, - .lsp = NVME_LOG_TELEM_HOST_LSP_RETAIN, - .lsi = NVME_LOG_LSI_NONE, - .rae = false, - .uuidx = NVME_UUID_NONE, - .len = len, .log = log, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, + .len = len, + .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, + .lsi = NVME_LOG_LSI_NONE, + .lsp = NVME_LOG_TELEM_HOST_LSP_RETAIN, + .uuidx = NVME_UUID_NONE, + .rae = false, .ot = false, }; return nvme_get_log(&args); @@ -1425,18 +1424,18 @@ static inline int nvme_get_log_telemetry_ctrl(int fd, bool rae, struct nvme_get_log_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .lid = NVME_LOG_LID_TELEMETRY_CTRL, - .nsid = NVME_NSID_NONE, .lpo = offset, - .lsp = NVME_LOG_LSP_NONE, - .lsi = NVME_LOG_LSI_NONE, - .rae = rae, - .uuidx = NVME_UUID_NONE, - .len = len, .log = log, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, + .len = len, + .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, + .lsi = NVME_LOG_LSI_NONE, + .lsp = NVME_LOG_LSP_NONE, + .uuidx = NVME_UUID_NONE, + .rae = rae, .ot = false, }; return nvme_get_log(&args); @@ -1464,18 +1463,18 @@ static inline int nvme_get_log_endurance_group(int fd, __u16 endgid, struct nvme_get_log_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .lid = NVME_LOG_LID_ENDURANCE_GROUP, - .nsid = NVME_NSID_NONE, .lpo = 0, - .lsp = NVME_LOG_LSP_NONE, - .lsi = endgid, - .rae = false, - .uuidx = NVME_UUID_NONE, - .len = sizeof(*log), .log = log, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, + .len = sizeof(*log), + .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, + .lsi = endgid, + .lsp = NVME_LOG_LSP_NONE, + .uuidx = NVME_UUID_NONE, + .rae = false, .ot = false, }; return nvme_get_log(&args); @@ -1495,18 +1494,18 @@ static inline int nvme_get_log_predictable_lat_nvmset(int fd, __u16 nvmsetid, struct nvme_get_log_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .lid = NVME_LOG_LID_PREDICTABLE_LAT_NVMSET, - .nsid = NVME_NSID_NONE, .lpo = 0, - .lsp = NVME_LOG_LSP_NONE, - .lsi = nvmsetid, - .rae = false, - .uuidx = NVME_UUID_NONE, - .len = sizeof(*log), .log = log, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, + .len = sizeof(*log), + .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, + .lsi = nvmsetid, + .lsp = NVME_LOG_LSP_NONE, + .uuidx = NVME_UUID_NONE, + .rae = false, .ot = false, }; return nvme_get_log(&args); @@ -1523,18 +1522,18 @@ static inline int nvme_get_log_predictable_lat_event(int fd, bool rae, struct nvme_get_log_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .lid = NVME_LOG_LID_PREDICTABLE_LAT_AGG, - .nsid = NVME_NSID_NONE, .lpo = offset, - .lsp = NVME_LOG_LSP_NONE, - .lsi = NVME_LOG_LSI_NONE, - .rae = rae, - .uuidx = NVME_UUID_NONE, - .len = len, .log = log, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, + .len = len, + .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, + .lsi = NVME_LOG_LSI_NONE, + .lsp = NVME_LOG_LSP_NONE, + .uuidx = NVME_UUID_NONE, + .rae = rae, .ot = false, }; return nvme_get_log(&args); @@ -1563,18 +1562,18 @@ static int nvme_get_log_ana(int fd, enum nvme_log_ana_lsp lsp, bool rae, struct nvme_get_log_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .lid = NVME_LOG_LID_ANA, - .nsid = NVME_NSID_NONE, .lpo = offset, - .lsp = lsp, - .lsi = NVME_LOG_LSI_NONE, - .rae = false, - .uuidx = NVME_UUID_NONE, - .len = len, .log = log, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, + .len = len, + .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, + .lsi = NVME_LOG_LSI_NONE, + .lsp = lsp, + .uuidx = NVME_UUID_NONE, + .rae = false, .ot = false, }; return nvme_get_log(&args); @@ -1607,18 +1606,18 @@ static inline int nvme_get_log_lba_status(int fd, bool rae, struct nvme_get_log_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .lid = NVME_LOG_LID_LBA_STATUS, - .nsid = NVME_NSID_NONE, .lpo = offset, - .lsp = NVME_LOG_LSP_NONE, - .lsi = NVME_LOG_LSI_NONE, - .rae = rae, - .uuidx = NVME_UUID_NONE, - .len = len, .log = log, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, + .len = len, + .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, + .lsi = NVME_LOG_LSI_NONE, + .lsp = NVME_LOG_LSP_NONE, + .uuidx = NVME_UUID_NONE, + .rae = rae, .ot = false, }; return nvme_get_log(&args); @@ -1635,18 +1634,18 @@ static inline int nvme_get_log_endurance_grp_evt(int fd, bool rae, struct nvme_get_log_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .lid = NVME_LOG_LID_ENDURANCE_GRP_EVT, - .nsid = NVME_NSID_NONE, .lpo = offset, - .lsp = NVME_LOG_LSP_NONE, - .lsi = NVME_LOG_LSI_NONE, - .rae = rae, - .uuidx = NVME_UUID_NONE, - .len = len, .log = log, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, + .len = len, + .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, + .lsi = NVME_LOG_LSI_NONE, + .lsp = NVME_LOG_LSP_NONE, + .uuidx = NVME_UUID_NONE, + .rae = rae, .ot = false, }; return nvme_get_log(&args); @@ -1686,18 +1685,18 @@ static inline int nvme_get_log_boot_partition(int fd, bool rae, struct nvme_get_log_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .lid = NVME_LOG_LID_BOOT_PARTITION, - .nsid = NVME_NSID_NONE, .lpo = 0, - .lsp = NVME_LOG_LSP_NONE, - .lsi = NVME_LOG_LSI_NONE, - .rae = rae, - .uuidx = NVME_UUID_NONE, - .len = len, .log = part, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, + .len = len, + .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, + .lsi = NVME_LOG_LSI_NONE, + .lsp = NVME_LOG_LSP_NONE, + .uuidx = NVME_UUID_NONE, + .rae = rae, .ot = false, }; return nvme_get_log(&args); @@ -1724,18 +1723,18 @@ static inline int nvme_get_log_discovery(int fd, bool rae, struct nvme_get_log_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .lid = NVME_LOG_LID_DISCOVER, - .nsid = NVME_NSID_NONE, .lpo = offset, - .lsp = NVME_LOG_LSP_NONE, - .lsi = NVME_LOG_LSI_NONE, - .rae = rae, - .uuidx = NVME_UUID_NONE, - .len = len, .log = log, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, + .len = len, + .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, + .lsi = NVME_LOG_LSI_NONE, + .lsp = NVME_LOG_LSP_NONE, + .uuidx = NVME_UUID_NONE, + .rae = rae, .ot = false, }; return nvme_get_log(&args); @@ -1793,18 +1792,18 @@ static inline int nvme_get_log_zns_changed_zones(int fd, __u32 nsid, bool rae, struct nvme_get_log_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .lid = NVME_LOG_LID_ZNS_CHANGED_ZONES, - .nsid = nsid, .lpo = 0, - .lsp = NVME_LOG_LSP_NONE, - .lsi = NVME_LOG_LSI_NONE, - .rae = rae, - .uuidx = NVME_UUID_NONE, - .len = sizeof(*log), .log = log, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, + .len = sizeof(*log), + .nsid = nsid, .csi = NVME_CSI_ZNS, + .lsi = NVME_LOG_LSI_NONE, + .lsp = NVME_LOG_LSP_NONE, + .uuidx = NVME_UUID_NONE, + .rae = rae, .ot = false, }; return nvme_get_log(&args); @@ -1825,18 +1824,18 @@ static inline int nvme_get_log_persistent_event(int fd, struct nvme_get_log_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .lid = NVME_LOG_LID_PERSISTENT_EVENT, - .nsid = NVME_NSID_ALL, .lpo = 0, - .lsp = NVME_LOG_LSP_NONE, - .lsi = NVME_LOG_LSI_NONE, - .rae = false, - .uuidx = NVME_UUID_NONE, - .len = size, .log = pevent_log, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, + .len = size, + .nsid = NVME_NSID_ALL, .csi = NVME_CSI_NVM, + .lsi = NVME_LOG_LSI_NONE, + .lsp = NVME_LOG_LSP_NONE, + .uuidx = NVME_UUID_NONE, + .rae = false, .ot = false, }; return nvme_get_log(&args); From 4cc907dd5ffeef613c1aef7fe9daeaeb7c0f88e1 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 13 Jan 2022 14:48:26 +0100 Subject: [PATCH 0352/1564] ioctl: Rearrange members in nvme_set_features_args Avoid any holes in the struct by rearranging the members. Also add the attribute packed to struct definition to reduce ABI breakage. struct nvme_set_features_args { int args_size; /* 0 4 */ int fd; /* 4 4 */ __u32 * result; /* 8 8 */ __u32 timeout; /* 16 4 */ __u32 nsid; /* 20 4 */ __u32 cdw11; /* 24 4 */ __u32 cdw12; /* 28 4 */ __u32 cdw15; /* 32 4 */ __u32 data_len; /* 36 4 */ void * data; /* 40 8 */ _Bool save; /* 48 1 */ __u8 uuidx; /* 49 1 */ __u8 fid; /* 50 1 */ /* size: 56, cachelines: 1, members: 13 */ /* padding: 5 */ /* last cacheline: 56 bytes */ } __attribute__((__aligned__(8))); Signed-off-by: Daniel Wagner --- src/nvme/ioctl.h | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index c5e7049830..eca75bfa12 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -1845,34 +1845,33 @@ static inline int nvme_get_log_persistent_event(int fd, /** * nvme_set_features_args - Arguments for the NVMe Admin Set Feature command * @fd: File descriptor of nvme device - * @fid: Feature identifier + * @result: The command completion result from CQE dword0 + * @timeout: Timeout in ms * @nsid: Namespace ID, if applicable * @cdw11: Value to set the feature to * @cdw12: Feature specific command dword12 field - * @save: Save value across power states - * @uuidx: UUID Index for differentiating vendor specific encoding * @cdw14: Feature specific command dword15 field * @data_len: Length of feature data, if applicable, in bytes * @data: User address of feature data, if applicable - * @timeout: Timeout in ms - * @result: The command completion result from CQE dword0 + * @save: Save value across power states + * @uuidx: UUID Index for differentiating vendor specific encoding + * @fid: Feature identifier */ - struct nvme_set_features_args { int args_size; int fd; - __u8 fid; + __u32 *result; + __u32 timeout; __u32 nsid; __u32 cdw11; __u32 cdw12; - bool save; - __u8 uuidx; __u32 cdw15; __u32 data_len; void *data; - __u32 timeout; - __u32 *result; -}; + bool save; + __u8 uuidx; + __u8 fid; +} __attribute__((packed, aligned(__alignof__(__u32*)))); /** * nvme_set_features_args() - Set a feature attribute @@ -1885,22 +1884,22 @@ int nvme_set_features(struct nvme_set_features_args *args); static inline int nvme_set_features_data(int fd, __u8 fid, __u32 nsid, __u32 cdw11, bool save, __u32 data_len, void *data, - __u32 *result) + __u32 *result) { struct nvme_set_features_args args = { .args_size = sizeof(args), .fd = fd, - .fid = fid, + .result = result, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .nsid = nsid, .cdw11 = cdw11, .cdw12 = 0, - .save = save, - .uuidx = 0, .cdw15 = 0, .data_len = data_len, .data = data, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = result, + .save = save, + .uuidx = 0, + .fid = fid, }; return nvme_set_features(&args); } From 4a1fefa39c7aef6513e98465d342233ee921b33d Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 13 Jan 2022 15:01:08 +0100 Subject: [PATCH 0353/1564] ioctl: Rearrange members in nvme_get_features_args Avoid any holes in the struct by rearranging the members. Also add the attribute packed to struct definition to reduce ABI breakage. struct nvme_get_features_args { int args_size; /* 0 4 */ int fd; /* 4 4 */ __u32 * result; /* 8 8 */ __u32 timeout; /* 16 4 */ __u32 nsid; /* 20 4 */ enum nvme_get_features_sel sel; /* 24 4 */ __u32 cdw11; /* 28 4 */ __u32 data_len; /* 32 4 */ void * data; /* 36 8 */ __u8 fid; /* 44 1 */ __u8 uuidx; /* 45 1 */ /* size: 48, cachelines: 1, members: 11 */ /* padding: 2 */ /* last cacheline: 48 bytes */ } __attribute__((__aligned__(8))); Signed-off-by: Daniel Wagner --- src/nvme/ioctl.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index eca75bfa12..2a5c74089c 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -2231,30 +2231,30 @@ int nvme_set_features_write_protect(int fd, enum nvme_feat_nswpcfg_state state, /** * nvme_get_features_args - Arguments for the NVMe Admin Get Feature command * @fd: File descriptor of nvme device - * @fid: Feature identifier, see &enum nvme_features_id + * @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 - * @uuidx: UUID Index for differentiating vendor specific encoding * @data_len: Length of feature data, if applicable, in bytes * @data: User address of feature data, if applicable - * @timeout: Timeout in ms - * @result: The command completion result from CQE dword0 + * @fid: Feature identifier, see &enum nvme_features_id + * @uuidx: UUID Index for differentiating vendor specific encoding */ struct nvme_get_features_args { int args_size; int fd; - __u8 fid; + __u32 *result; + __u32 timeout; __u32 nsid; enum nvme_get_features_sel sel; __u32 cdw11; - __u8 uuidx; __u32 data_len; void *data; - __u32 timeout; - __u32 *result; -}; + __u8 fid; + __u8 uuidx; +} __attribute__((packed, aligned(__alignof__(__u32*)))); /** * nvme_get_features() - Retrieve a feature attribute @@ -2271,15 +2271,15 @@ static inline int nvme_get_features_data(int fd, enum nvme_features_id fid, struct nvme_get_features_args args = { .args_size = sizeof(args), .fd = fd, - .fid = fid, + .result = result, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .nsid = nsid, .sel = NVME_GET_FEATURES_SEL_CURRENT, .cdw11 = 0, - .uuidx = NVME_UUID_NONE, .data_len = data_len, .data = data, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = result, + .fid = fid, + .uuidx = NVME_UUID_NONE, }; return nvme_get_features(&args); From 91eb974ce4f64199596b5781879228cc4a16f521 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 13 Jan 2022 15:03:11 +0100 Subject: [PATCH 0354/1564] ioctl: Rearrange members in nvme_format_nvm_args Avoid any holes in the struct by rearranging the members. Also add the attribute packed to struct definition to reduce ABI breakage. struct nvme_format_nvm_args { int args_size; /* 0 4 */ int fd; /* 4 4 */ __u32 * result; /* 8 8 */ __u32 timeout; /* 16 4 */ __u32 nsid; /* 20 4 */ enum nvme_cmd_format_mset mset; /* 24 4 */ enum nvme_cmd_format_pi pi; /* 28 4 */ enum nvme_cmd_format_pil pil; /* 32 4 */ enum nvme_cmd_format_ses ses; /* 36 4 */ __u8 lbaf; /* 40 1 */ /* size: 48, cachelines: 1, members: 10 */ /* padding: 7 */ /* last cacheline: 48 bytes */ } __attribute__((__aligned__(8))); Signed-off-by: Daniel Wagner --- src/nvme/ioctl.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 2a5c74089c..a91655b465 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -2653,28 +2653,28 @@ int nvme_get_features_iocs_profile(int fd, enum nvme_get_features_sel sel, /** * nvme_format_nvm_args - Arguments for the Format Nvme Namespace command * @fd: File descriptor of nvme device + * @result: The command completion result from CQE dword0 + * @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 - * @lbaf: Logical block address 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 - * @timeout: Set to override default timeout to this value in milliseconds; - * useful for long running formats. 0 will use system default. - * @result: The command completion result from CQE dword0 + * @lbaf: Logical block address format */ struct nvme_format_nvm_args { int args_size; int fd; + __u32 *result; + __u32 timeout; __u32 nsid; - __u8 lbaf; enum nvme_cmd_format_mset mset; enum nvme_cmd_format_pi pi; enum nvme_cmd_format_pil pil; enum nvme_cmd_format_ses ses; - __u32 timeout; - __u32 *result; -}; + __u8 lbaf; +} __attribute__((packed, aligned(__alignof__(__u32*)))); /** * nvme_format_nvm() - Format nvme namespace(s) From fe068c6894d53cdb4e6b3e83bc69f27c55283880 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 13 Jan 2022 15:04:53 +0100 Subject: [PATCH 0355/1564] ioctl: Rearrange members in nvme_ns_mgmt_args Avoid any holes in the struct by rearranging the members. Also add the attribute packed to struct definition to reduce ABI breakage. struct nvme_ns_mgmt_args { int args_size; /* 0 4 */ int fd; /* 4 4 */ __u32 * result; /* 8 8 */ __u32 timeout; /* 16 4 */ __u32 nsid; /* 20 4 */ struct nvme_id_ns * ns; /* 24 8 */ enum nvme_ns_mgmt_sel sel; /* 32 4 */ __u8 csi; /* 36 1 */ /* size: 40, cachelines: 1, members: 8 */ /* padding: 3 */ /* last cacheline: 40 bytes */ } __attribute__((__aligned__(8))); Signed-off-by: Daniel Wagner --- src/nvme/ioctl.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index a91655b465..15cd76393e 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -2693,23 +2693,23 @@ int nvme_format_nvm(struct nvme_format_nvm_args *args); /** * nvme_ns_mgmt_args - Arguments for NVMe Namespace Management command * @fd: File descriptor of nvme device - * @nsid: Namespace identifier - * @sel: Type of management operation to perform - * @ns: Namespace identication descriptors * @result: NVMe command result * @timeout: Timeout in ms + * @nsid: Namespace identifier + * @ns: Namespace identication descriptors + * @sel: Type of management operation to perform * @csi: Command Set Identifier */ struct nvme_ns_mgmt_args { int args_size; int fd; - __u32 nsid; - enum nvme_ns_mgmt_sel sel; - struct nvme_id_ns *ns; __u32 *result; __u32 timeout; + __u32 nsid; + struct nvme_id_ns *ns; + enum nvme_ns_mgmt_sel sel; __u8 csi; -}; +} __attribute__((packed, aligned(__alignof__(__u32*)))); /** * nvme_ns_mgmt() - @@ -2739,11 +2739,11 @@ static inline int nvme_ns_mgmt_create(int fd, struct nvme_id_ns *ns, struct nvme_ns_mgmt_args args = { .args_size = sizeof(args), .fd = fd, - .nsid = NVME_NSID_NONE, - .sel = NVME_NS_MGMT_SEL_CREATE, - .ns = ns, .result = nsid, .timeout = timeout, + .nsid = NVME_NSID_NONE, + .ns = ns, + .sel = NVME_NS_MGMT_SEL_CREATE, .csi = csi, }; @@ -2767,11 +2767,11 @@ static inline int nvme_ns_mgmt_delete(int fd, __u32 nsid) struct nvme_ns_mgmt_args args = { .args_size = sizeof(args), .fd = fd, - .nsid = nsid, - .sel = NVME_NS_MGMT_SEL_DELETE, - .ns = NULL, .result = NULL, .timeout = 0, + .nsid = nsid, + .ns = NULL, + .sel = NVME_NS_MGMT_SEL_DELETE, .csi = 0, }; From 30df2e1e429bc1d8d73f2429019754378a84837a Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 13 Jan 2022 15:07:09 +0100 Subject: [PATCH 0356/1564] ioctl: Rearrange members in nvme_ns_attach_args Avoid any holes in the struct by rearranging the members. Also add the attribute packed to struct definition to reduce ABI breakage. struct nvme_ns_attach_args { int args_size; /* 0 4 */ int fd; /* 4 4 */ __u32 * result; /* 8 8 */ __u32 timeout; /* 16 4 */ __u32 nsid; /* 20 4 */ struct nvme_ctrl_list * ctrlist; /* 24 8 */ enum nvme_ns_attach_sel sel; /* 32 4 */ /* size: 40, cachelines: 1, members: 7 */ /* padding: 4 */ /* last cacheline: 40 bytes */ } __attribute__((__aligned__(8))); While at it also introduce the result member. Signed-off-by: Daniel Wagner --- src/nvme/ioctl.c | 2 +- src/nvme/ioctl.h | 22 +++++++++++++--------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index a633ebf9b7..e6f184a4de 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -1203,7 +1203,7 @@ int nvme_ns_attach(struct nvme_ns_attach_args *args) if (args->args_size < sizeof(*args)) return -EINVAL; - return nvme_submit_admin_passthru(args->fd, &cmd, NULL); + return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } int nvme_fw_download(struct nvme_fw_download_args *args) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 15cd76393e..b0b02ec452 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -2781,19 +2781,21 @@ static inline int nvme_ns_mgmt_delete(int fd, __u32 nsid) /** * nvme_ns_attach_args - Arguments for Nvme Namespace Management command * @fd: File descriptor of nvme device + * @result: NVMe command result + * @timeout: Timeout in ms * @nsid: Namespace ID to execute attach selection - * @sel: Attachment selection, see &enum nvme_ns_attach_sel * @ctrlist: Controller list to modify attachment state of nsid - * @timeout: Timeout in ms + * @sel: Attachment selection, see &enum nvme_ns_attach_sel */ struct nvme_ns_attach_args { int args_size; int fd; + __u32 *result; + __u32 timeout; __u32 nsid; - enum nvme_ns_attach_sel sel; struct nvme_ctrl_list *ctrlist; - __u32 timeout; -}; + enum nvme_ns_attach_sel sel; +} __attribute__((packed, aligned(__alignof__(__u32*)))); /** * nvme_ns_attach_args - Attach or detach namespace to controller(s) @@ -2813,10 +2815,11 @@ static inline int nvme_ns_attach_ctrls(int fd, __u32 nsid, struct nvme_ns_attach_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .nsid = nsid, - .sel = NVME_NS_ATTACH_SEL_CTRL_ATTACH, .ctrlist = ctrlist, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .sel = NVME_NS_ATTACH_SEL_CTRL_ATTACH, }; return nvme_ns_attach(&args); @@ -2834,10 +2837,11 @@ static inline int nvme_ns_detach_ctrls(int fd, __u32 nsid, struct nvme_ns_attach_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .nsid = nsid, - .sel = NVME_NS_ATTACH_SEL_CTRL_DEATTACH, .ctrlist = ctrlist, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .sel = NVME_NS_ATTACH_SEL_CTRL_DEATTACH, }; return nvme_ns_attach(&args); From 46a2473f635887a1d62abcab29906ae64827db43 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 13 Jan 2022 15:09:09 +0100 Subject: [PATCH 0357/1564] ioctl: Rearrange members in nvme_fw_download_args Avoid any holes in the struct by rearranging the members. Also add the attribute packed to struct definition to reduce ABI breakage. struct nvme_fw_download_args { int args_size; /* 0 4 */ int fd; /* 4 4 */ __u32 * result; /* 8 8 */ __u32 timeout; /* 16 4 */ __u32 offset; /* 20 4 */ void * data; /* 24 8 */ __u32 data_len; /* 32 4 */ /* size: 40, cachelines: 1, members: 7 */ /* padding: 4 */ /* last cacheline: 40 bytes */ } __attribute__((__aligned__(8))); Signed-off-by: Daniel Wagner --- src/nvme/ioctl.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index b0b02ec452..7f5db16041 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -2850,21 +2850,21 @@ static inline int nvme_ns_detach_ctrls(int fd, __u32 nsid, /** * nvme_fw_download_args - Arguments for the NVMe Firmware Download command * @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_len: Length of data in this command in bytes * @data: Userspace address of the firmware data - * @timeout: Timeout in ms - * @result: The command completion result from CQE dword0 + * @data_len: Length of data in this command in bytes */ struct nvme_fw_download_args { int args_size; int fd; + __u32 *result; + __u32 timeout; __u32 offset; - __u32 data_len; void *data; - __u32 timeout; - __u32 *result; -}; + __u32 data_len; +} __attribute__((packed, aligned(__alignof__(__u32*)))); /** * nvme_fw_download() - Download part or all of a firmware image to the From b289574e2e8a2ff4fb87f93ef06622edbf34a3f2 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 13 Jan 2022 15:15:54 +0100 Subject: [PATCH 0358/1564] ioctl: Rearrange members in nvme_fw_commit_args Avoid any holes in the struct by rearranging the members. Also add the attribute packed to struct definition to reduce ABI breakage. struct nvme_fw_commit_args { int args_size; /* 0 4 */ int fd; /* 4 4 */ __u32 * result; /* 8 8 */ __u32 timeout; /* 16 4 */ enum nvme_fw_commit_ca action; /* 20 4 */ __u8 slot; /* 24 1 */ _Bool bpid; /* 25 1 */ /* size: 32, cachelines: 1, members: 7 */ /* padding: 6 */ /* last cacheline: 32 bytes */ } __attribute__((__aligned__(8))); Signed-off-by: Daniel Wagner --- src/nvme/ioctl.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 7f5db16041..dd3185a7d5 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -2892,21 +2892,21 @@ int nvme_fw_download(struct nvme_fw_download_args *args); /** * nvme_fw_commit_args - Arguments for the NVMe Firmware Commit command * @fd: File descriptor of nvme device - * @slot: Firmware slot to commit the downloaded image * @action: Action to use for the firmware image, see &enum nvme_fw_commit_ca - * @bpid: Set to true to select the boot partition id * @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 { int args_size; int fd; - __u8 slot; + __u32 *result; + __u32 timeout; enum nvme_fw_commit_ca action; + __u8 slot; bool bpid; - __u32 timeout; - __u32 *result; -}; +} __attribute__((packed, aligned(__alignof__(__u32*)))); /** * nvme_fw_commit() - Commit firmware using the specified action From bd6f91937f29065ff7916c7109ba1e675a5498a4 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 13 Jan 2022 15:16:54 +0100 Subject: [PATCH 0359/1564] ioctl: Rearrange members in nvme_security_send_args Avoid any holes in the struct by rearranging the members. Also add the attribute packed to struct definition to reduce ABI breakage. struct nvme_security_send_args { int args_size; /* 0 4 */ int fd; /* 4 4 */ __u32 * result; /* 8 8 */ __u32 timeout; /* 16 4 */ __u32 nsid; /* 20 4 */ __u8 nssf; /* 24 1 */ __u8 spsp0; /* 25 1 */ __u8 spsp1; /* 26 1 */ __u8 secp; /* 27 1 */ __u32 tl; /* 28 4 */ void * data; /* 32 8 */ __u32 data_len; /* 40 4 */ /* size: 48, cachelines: 1, members: 12 */ /* padding: 4 */ /* last cacheline: 48 bytes */ } __attribute__((__aligned__(8))); Signed-off-by: Daniel Wagner --- src/nvme/ioctl.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index dd3185a7d5..c2ba281272 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -2924,31 +2924,31 @@ int nvme_fw_commit(struct nvme_fw_commit_args *args); /** * nvme_security_send_args - Arguments for the NVMe Security Send command * @fd: File descriptor of nvme device + * @result: The command completion result from CQE dword0 + * @timeout: Timeout in ms * @nsid: Namespace ID to issue security command on * @nssf: NVMe Security Specific field * @spsp0: Security Protocol Specific field * @spsp1: Security Protocol Specific field * @secp: Security Protocol * @tl: Protocol specific transfer length - * @data_len: Data length of the payload in bytes * @data: Security data payload to send - * @timeout: Timeout in ms - * @result: The command completion result from CQE dword0 + * @data_len: Data length of the payload in bytes */ struct nvme_security_send_args { int args_size; int fd; + __u32 *result; + __u32 timeout; __u32 nsid; __u8 nssf; __u8 spsp0; __u8 spsp1; __u8 secp; __u32 tl; - __u32 data_len; void *data; - __u32 timeout; - __u32 *result; -}; + __u32 data_len; +} __attribute__((packed, aligned(__alignof__(__u32*)))); /** * nvme_security_send() - From 355ca204650d2db60706597fa548592edcd68309 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 13 Jan 2022 15:20:34 +0100 Subject: [PATCH 0360/1564] ioctl: Rearrange members in nvme_security_receive_args Avoid any holes in the struct by rearranging the members. Also add the attribute packed to struct definition to reduce ABI breakage. struct nvme_security_receive_args { int args_size; /* 0 4 */ int fd; /* 4 4 */ __u32 * result; /* 8 8 */ __u32 timeout; /* 16 4 */ __u32 nsid; /* 20 4 */ __u8 nssf; /* 24 1 */ __u8 spsp0; /* 25 1 */ __u8 spsp1; /* 26 1 */ __u8 secp; /* 27 1 */ __u32 al; /* 28 4 */ void * data; /* 32 8 */ __u32 data_len; /* 40 4 */ /* size: 48, cachelines: 1, members: 12 */ /* padding: 4 */ /* last cacheline: 48 bytes */ } __attribute__((__aligned__(8))); Signed-off-by: Daniel Wagner --- src/nvme/ioctl.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index c2ba281272..7e062b6315 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -2971,31 +2971,31 @@ int nvme_security_send(struct nvme_security_send_args *args); /** * nvme_security_receive_args - Arguments for the NVMe Security Receive command * @fd: File descriptor of nvme device + * @result: The command completion result from CQE dword0 + * @timeout: Timeout in ms * @nsid: Namespace ID to issue security command on * @nssf: NVMe Security Specific field * @spsp0: Security Protocol Specific field * @spsp1: Security Protocol Specific field * @secp: Security Protocol * @al: Protocol specific allocation length - * @data_len: Data length of the payload in bytes * @data: Security data payload to send - * @timeout: Timeout in ms - * @result: The command completion result from CQE dword0 + * @data_len: Data length of the payload in bytes */ struct nvme_security_receive_args { int args_size; int fd; + __u32 *result; + __u32 timeout; __u32 nsid; __u8 nssf; __u8 spsp0; __u8 spsp1; __u8 secp; __u32 al; - __u32 data_len; void *data; - __u32 timeout; - __u32 *result; -}; + __u32 data_len; +} __attribute__((packed, aligned(__alignof__(__u32*)))); /** * nvme_security_receive() - From 15a2a84e96427eab33e5c33ee3af4fc969619a7e Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 13 Jan 2022 15:23:02 +0100 Subject: [PATCH 0361/1564] ioctl: Rearrange members in nvme_get_lba_status_args Avoid any holes in the struct by rearranging the members. Also add the attribute packed to struct definition to reduce ABI breakage. struct nvme_get_lba_status_args { int args_size; /* 0 4 */ int fd; /* 4 4 */ __u32 * result; /* 8 8 */ __u32 timeout; /* 16 4 */ __u32 nsid; /* 20 4 */ __u32 mndw; /* 24 4 */ enum nvme_lba_status_atype atype; /* 28 4 */ __u64 slba; /* 32 8 */ struct nvme_lba_status * lbas; /* 40 8 */ __u16 rl; /* 48 2 */ /* size: 50, cachelines: 1, members: 10 */ /* last cacheline: 50 bytes */ } __attribute__((__packed__)); Signed-off-by: Daniel Wagner --- src/nvme/ioctl.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 7e062b6315..b219e15f73 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -3009,28 +3009,28 @@ int nvme_security_receive(struct nvme_security_receive_args *args); /** * nvme_get_lba_status_args - Arguments for the NVMe Get LBA Status command * @fd: File descriptor of nvme device + * @result: The command completion result from CQE dword0 + * @timeout: Timeout in ms * @nsid: Namespace ID to retrieve LBA status - * @slba: Starting logical block address to check statuses * @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 - * @timeout: Timeout in ms + * return, see &enum nvme_lba_status_atype + * @slba: Starting logical block address to check statuses * @lbas: Data payload to return status descriptors - * @result: The command completion result from CQE dword0 + * @rl: Range length from slba to perform the action */ struct nvme_get_lba_status_args { int args_size; int fd; + __u32 *result; + __u32 timeout; __u32 nsid; - __u64 slba; __u32 mndw; - __u16 rl; enum nvme_lba_status_atype atype; - __u32 timeout; + __u64 slba; struct nvme_lba_status *lbas; - __u32 *result; -}; + __u16 rl; +} __attribute__((__packed__)); /** * nvme_get_lba_status() - Retrieve information on possibly unrecoverable LBAs From f824455baae24ea0dfa7dd8e057884ef9718b716 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 13 Jan 2022 15:26:01 +0100 Subject: [PATCH 0362/1564] ioctl: Rearrange members in nvme_directive_send_args Avoid any holes in the struct by rearranging the members. Also add the attribute packed to struct definition to reduce ABI breakage. struct nvme_directive_send_args { int args_size; /* 0 4 */ int fd; /* 4 4 */ __u32 * result; /* 8 8 */ __u32 timeout; /* 16 4 */ __u32 nsid; /* 20 4 */ enum nvme_directive_send_doper doper; /* 24 4 */ enum nvme_directive_dtype dtype; /* 28 4 */ __u32 cdw12; /* 32 4 */ __u32 data_len; /* 36 4 */ void * data; /* 40 8 */ __u16 dspec; /* 48 2 */ /* size: 56, cachelines: 1, members: 10 */ /* padding: 6 */ /* last cacheline: 56 bytes */ } __attribute__((__aligned__(8))); Signed-off-by: Daniel Wagner --- src/nvme/ioctl.h | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index b219e15f73..9ce64ee51e 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -3030,7 +3030,7 @@ struct nvme_get_lba_status_args { __u64 slba; struct nvme_lba_status *lbas; __u16 rl; -} __attribute__((__packed__)); +} __attribute__((packed, aligned(__alignof__(__u64)))); /** * nvme_get_lba_status() - Retrieve information on possibly unrecoverable LBAs @@ -3047,29 +3047,28 @@ int nvme_get_lba_status(struct nvme_get_lba_status_args *args); /** * nvme_directive_send_args - Arguments for the NVMe Directive Send command * @fd: File descriptor of nvme device + * @result: If successful, the CQE dword0 value + * @timeout: Timeout in ms * @nsid: Namespace ID, if applicable - * @dspec: Directive specific field * @doper: Directive send operation, see &enum nvme_directive_send_doper * @dtype: Directive type, see &enum nvme_directive_dtype * @dw12: Directive specific command dword12 * @data_len: Length of data payload in bytes - * @data: Usespace address of data payload - * @timeout: Timeout in ms - * @result: If successful, the CQE dword0 value + * @dspec: Directive specific field */ struct nvme_directive_send_args { int args_size; int fd; + __u32 *result; + __u32 timeout; __u32 nsid; - __u16 dspec; enum nvme_directive_send_doper doper; enum nvme_directive_dtype dtype; __u32 cdw12; __u32 data_len; void *data; - __u32 timeout; - __u32 *result; -}; + __u16 dspec; +} __attribute__((__packed__)); /** * nvme_directive_send() - Send directive command @@ -3112,15 +3111,15 @@ static inline int nvme_directive_send_stream_release_identifier(int fd, struct nvme_directive_send_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .nsid = nsid, - .dspec = stream_id, .doper = NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_IDENTIFIER, .dtype = NVME_DIRECTIVE_DTYPE_STREAMS, .cdw12 = 0, .data_len = 0, .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, + .dspec = stream_id, }; return nvme_directive_send(&args); @@ -3139,15 +3138,15 @@ static inline int nvme_directive_send_stream_release_resource(int fd, __u32 nsid struct nvme_directive_send_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .nsid = nsid, - .dspec = 0, .doper = NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE, .dtype = NVME_DIRECTIVE_DTYPE_STREAMS, .cdw12 = 0, .data_len = 0, .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, + .dspec = 0, }; return nvme_directive_send(&args); From f283430be9602ff5cde3eb6f5b4f0b94dfb09401 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 13 Jan 2022 15:42:22 +0100 Subject: [PATCH 0363/1564] ioctl: Rearrange members in nvme_directive_recv_args Avoid any holes in the struct by rearranging the members. Also add the attribute packed to struct definition to reduce ABI breakage. struct nvme_directive_recv_args { int args_size; /* 0 4 */ int fd; /* 4 4 */ __u32 * result; /* 8 8 */ __u32 timeout; /* 16 4 */ __u32 nsid; /* 20 4 */ enum nvme_directive_receive_doper doper; /* 24 4 */ enum nvme_directive_dtype dtype; /* 28 4 */ __u32 cdw12; /* 32 4 */ __u32 data_len; /* 36 4 */ void * data; /* 40 8 */ __u16 dspec; /* 48 2 */ /* size: 56, cachelines: 1, members: 11 */ /* padding: 6 */ /* last cacheline: 56 bytes */ } __attribute__((__aligned__(8))); Signed-off-by: Daniel Wagner --- src/nvme/ioctl.h | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 9ce64ee51e..e687db2c00 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -3068,7 +3068,7 @@ struct nvme_directive_send_args { __u32 data_len; void *data; __u16 dspec; -} __attribute__((__packed__)); +} __attribute__((packed, aligned(__alignof__(__u32*)))); /** * nvme_directive_send() - Send directive command @@ -3155,29 +3155,29 @@ static inline int nvme_directive_send_stream_release_resource(int fd, __u32 nsid /** * nvme_directive_recv_args - Arguments for the NVMe Directive Receive command * @fd: File descriptor of nvme device + * @result: If successful, the CQE dword0 value + * @timeout: Timeout in ms * @nsid: Namespace ID, if applicable - * @dspec: Directive specific field * @doper: Directive send operation, see &enum nvme_directive_send_doper * @dtype: Directive type, see &enum nvme_directive_dtype * @dw12: Directive specific command dword12 * @data_len: Length of data payload in bytes * @data: Usespace address of data payload - * @timeout: Timeout in ms - * @result: If successful, the CQE dword0 value + * @dspec: Directive specific field */ struct nvme_directive_recv_args { int args_size; int fd; + __u32 *result; + __u32 timeout; __u32 nsid; - __u16 dspec; enum nvme_directive_receive_doper doper; enum nvme_directive_dtype dtype; __u32 cdw12; __u32 data_len; void *data; - __u32 timeout; - __u32 *result; -}; + __u16 dspec; +} __attribute__((__packed__)); /** * nvme_directive_recv() - Receive directive specific data @@ -3202,15 +3202,15 @@ static inline int nvme_directive_recv_identify_parameters(int fd, __u32 nsid, struct nvme_directive_recv_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .nsid = nsid, - .dspec = 0, .doper = NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM, .dtype = NVME_DIRECTIVE_DTYPE_IDENTIFY, .cdw12 = 0, .data_len = sizeof(*id), .data = id, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, + .dspec = 0, }; return nvme_directive_recv(&args); @@ -3230,21 +3230,20 @@ static inline int nvme_directive_recv_stream_parameters(int fd, __u32 nsid, struct nvme_directive_recv_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .nsid = nsid, - .dspec = 0, .doper = NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM, .dtype = NVME_DIRECTIVE_DTYPE_STREAMS, .cdw12 = 0, .data_len = sizeof(*parms), .data = parms, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, + .dspec = 0, }; return nvme_directive_recv(&args); } - /** * nvme_directive_recv_stream_status() - * @fd: File descriptor of nvme device @@ -3260,21 +3259,20 @@ static inline int nvme_directive_recv_stream_status(int fd, __u32 nsid, struct nvme_directive_recv_args args = { .args_size = sizeof(args), .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .nsid = nsid, - .dspec = 0, .doper = NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS, .dtype = NVME_DIRECTIVE_DTYPE_STREAMS, .cdw12 = 0, .data_len = sizeof(*id), .data = id, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, + .dspec = 0, }; return nvme_directive_recv(&args); } - /** * nvme_directive_recv_stream_allocate() - * @fd: File descriptor of nvme device @@ -3289,15 +3287,15 @@ static inline int nvme_directive_recv_stream_allocate(int fd, __u32 nsid, struct nvme_directive_recv_args args = { .args_size = sizeof(args), .fd = fd, + .result = result, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .nsid = nsid, - .dspec = 0, .doper = NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE, .dtype = NVME_DIRECTIVE_DTYPE_STREAMS, .cdw12 = nsr, .data_len = 0, .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = result, + .dspec = 0, }; return nvme_directive_recv(&args); From 301c99ee6cbafe65a0b024d3f97cb6fef1fd842e Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 13 Jan 2022 15:47:05 +0100 Subject: [PATCH 0364/1564] ioctl: Rearrange members in nvme_capacity_mgmt_args Avoid any holes in the struct by rearranging the members. Also add the attribute packed to struct definition to reduce ABI breakage. struct nvme_capacity_mgmt_args { int args_size; /* 0 4 */ int fd; /* 4 4 */ __u32 * result; /* 8 8 */ __u32 timeout; /* 16 4 */ __u32 cdw11; /* 20 4 */ __u32 cdw12; /* 24 4 */ __u16 element_id; /* 28 2 */ __u8 op; /* 30 1 */ /* size: 56, cachelines: 1, members: 11 */ /* padding: 6 */ /* last cacheline: 56 bytes */ } __attribute__((__aligned__(8))); Signed-off-by: Daniel Wagner --- src/nvme/ioctl.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index e687db2c00..c44817022b 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -3177,7 +3177,7 @@ struct nvme_directive_recv_args { __u32 data_len; void *data; __u16 dspec; -} __attribute__((__packed__)); +} __attribute__((packed, aligned(__alignof__(__u32*)))); /** * nvme_directive_recv() - Receive directive specific data @@ -3305,25 +3305,25 @@ static inline int nvme_directive_recv_stream_allocate(int fd, __u32 nsid, /** * nvme_capacity_mgmt_args - Arguments for the NVMe Capacity Management command * @fd: File descriptor of nvme device - * @op: Operation to be performed by the controller - * @element_id: Value specific to the value of the Operation field * @dw11: Least significant 32 bits of the capacity in bytes of the * Endurance Group or NVM Set to be created * @dw12: Most significant 32 bits of the capacity in bytes of the * Endurance Group or NVM Set to be created - * @timeout: Timeout in ms * @result: If successful, the CQE dword0 value + * @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 { int args_size; int fd; - __u8 op; - __u16 element_id; + __u32 *result; + __u32 timeout; __u32 cdw11; __u32 cdw12; - __u32 timeout; - __u32 *result; -}; + __u16 element_id; + __u8 op; +} __attribute__((__packed__)); /** * nvme_capacity_mgmt() - From 65d2d83a7b4fdcfc30fd0c3bb92e84d433544627 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 13 Jan 2022 15:49:10 +0100 Subject: [PATCH 0365/1564] ioctl: Rearrange members in nvme_lockdown_args Avoid any holes in the struct by rearranging the members. Also add the attribute packed to struct definition to reduce ABI breakage. struct nvme_lockdown_args { int args_size; /* 0 4 */ int fd; /* 4 4 */ __u32 * result; /* 8 8 */ __u32 timeout; /* 16 4 */ __u8 scp; /* 20 1 */ __u8 prhbt; /* 21 1 */ __u8 ifc; /* 22 1 */ __u8 ofi; /* 23 1 */ __u8 uuidx; /* 24 1 */ /* size: 32, cachelines: 1, members: 8 */ /* padding: 1 */ /* last cacheline: 32 bytes */ } __attribute__((__aligned__(8))); Signed-off-by: Daniel Wagner --- src/nvme/ioctl.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index c44817022b..18142e79a9 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -3323,7 +3323,7 @@ struct nvme_capacity_mgmt_args { __u32 cdw12; __u16 element_id; __u8 op; -} __attribute__((__packed__)); +} __attribute__((packed, aligned(__alignof__(__u32*)))); /** * nvme_capacity_mgmt() - @@ -3337,25 +3337,25 @@ int nvme_capacity_mgmt(struct nvme_capacity_mgmt_args *args); /** * nvme_lockdown_args - Arguments for the NVME Lockdown command * @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 * @uuid: UUID Index if controller supports this id selection method - * @timeout: Timeout in ms (0 for default timeout) - * @result: The command completion result from CQE dword0 */ struct nvme_lockdown_args { int args_size; int fd; + __u32 *result; + __u32 timeout; __u8 scp; __u8 prhbt; __u8 ifc; __u8 ofi; __u8 uuidx; - __u32 timeout; - __u32 *result; -}; +} __attribute__((__packed__)); /** * nvme_lockdown() - Issue lockdown command From 3bca40d5402d7b41458328ef457058298d24cf4a Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 13 Jan 2022 15:51:13 +0100 Subject: [PATCH 0366/1564] ioctl: Rearrange members in nvme_set_property_args Avoid any holes in the struct by rearranging the members. Also add the attribute packed to struct definition to reduce ABI breakage. struct nvme_set_property_args { int args_size; /* 0 4 */ int fd; /* 4 4 */ __u32 * result; /* 8 8 */ __u32 timeout; /* 16 4 */ int offset; /* 20 4 */ __u64 value; /* 24 8 */ /* size: 32, cachelines: 1, members: 6 */ /* last cacheline: 32 bytes */ } __attribute__((__aligned__(8))); Signed-off-by: Daniel Wagner --- src/nvme/ioctl.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 18142e79a9..582e9ddd22 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -3369,19 +3369,19 @@ int nvme_lockdown(struct nvme_lockdown_args *args); /** * nvme_set_property_args - Arguments for NVMe Set Property command * @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 - * @timeout: Timeout in ms - * @result: The command completion result from CQE dword0 */ struct nvme_set_property_args { int args_size; int fd; + __u32 *result; + __u32 timeout; int offset; __u64 value; - __u32 timeout; - __u32 *result; -}; +} __attribute__((packed, aligned(__alignof__(__u64)))); /** * nvme_set_property() - Set controller property From 425b9ceeb2d15a3c9cf24b3275035e15047a8389 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 13 Jan 2022 17:47:10 +0100 Subject: [PATCH 0367/1564] ioctl: Rearrange members in nvme_get_property_args Avoid any holes in the struct by rearranging the members. Also add the attribute packed to struct definition to reduce ABI breakage. struct nvme_get_property_args { int args_size; /* 0 4 */ int fd; /* 4 4 */ __u64 * value; /* 8 8 */ __u32 timeout; /* 16 4 */ int offset; /* 20 4 */ /* size: 24, cachelines: 1, members: 5 */ /* last cacheline: 24 bytes */ } __attribute__((__aligned__(8))); Signed-off-by: Daniel Wagner --- src/nvme/ioctl.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 582e9ddd22..11edaf049d 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -3398,17 +3398,17 @@ int nvme_set_property(struct nvme_set_property_args *args); /** * nvme_get_property_args - Arguments for NVMe Get Property command * @fd: File descriptor of nvme device - * @offset: Property offset from the base to retrieve * @value: Where the property's value will be stored on success + * @offset: Property offset from the base to retrieve * @timeout: Timeout in ms */ struct nvme_get_property_args { int args_size; int fd; - int offset; __u64 *value; __u32 timeout; -}; + int offset; +} __attribute__((packed, aligned(__alignof__(__u64*)))); /** * nvme_get_property() - Get a controller property From f621fb54a555e5cf071de21751eabff360b02982 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 13 Jan 2022 17:49:00 +0100 Subject: [PATCH 0368/1564] ioctl: Rearrange members in nvme_sanitize_nvm_args Avoid any holes in the struct by rearranging the members. Also add the attribute packed to struct definition to reduce ABI breakage. struct nvme_sanitize_nvm_args { int args_size; /* 0 4 */ int fd; /* 4 4 */ __u32 * result; /* 8 8 */ __u32 timeout; /* 16 4 */ enum nvme_sanitize_sanact sanact; /* 20 4 */ _Bool ause; /* 24 1 */ __u8 owpass; /* 25 1 */ _Bool oipbp; /* 26 1 */ _Bool nodas; /* 27 1 */ __u32 ovrpat; /* 28 4 */ /* size: 32, cachelines: 1, members: 6 */ /* padding: 4 */ /* last cacheline: 32 bytes */ } __attribute__((__aligned__(8))); Signed-off-by: Daniel Wagner --- src/nvme/ioctl.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 11edaf049d..bee0f19327 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -3425,27 +3425,27 @@ int nvme_get_property(struct nvme_get_property_args *args); /** * nvme_sanitize_nvm_args - Arguments for the NVMe Sanitize NVM command * @fd: File descriptor of nvme device + * @result: The command completion result from CQE dword0 + * @timeout: Timeout in ms * @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 * @ovrpat: Overwrite pattern - * @timeout: Timeout in ms - * @result: The command completion result from CQE dword0 */ struct nvme_sanitize_nvm_args { int args_size; int fd; + __u32 *result; + __u32 timeout; enum nvme_sanitize_sanact sanact; bool ause; __u8 owpass; bool oipbp; bool nodas; __u32 ovrpat; - __u32 timeout; - __u32 *result; -}; +} __attribute__((packed, aligned(__alignof__(__u32*)))); /** * nvme_sanitize_nvm() - Start a sanitize operation @@ -3477,11 +3477,11 @@ int nvme_sanitize_nvm(struct nvme_sanitize_nvm_args *args); struct nvme_dev_self_test_args { int args_size; int fd; + __u32 *result; + __u32 timeout; __u32 nsid; enum nvme_dst_stc stc; - __u32 timeout; - __u32 *result; -}; +} __attribute__((packed, aligned(__alignof__(__u32*)))); /** * nvme_dev_self_test() - Start or abort a self test From 57af2be56e3158251460e5177a67b19c2d0e5875 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 13 Jan 2022 17:52:19 +0100 Subject: [PATCH 0369/1564] ioctl: Rearrange members in nvme_virtual_mgmt_args Avoid any holes in the struct by rearranging the members. Also add the attribute packed to struct definition to reduce ABI breakage. struct nvme_virtual_mgmt_args { int args_size; /* 0 4 */ int fd; /* 4 4 */ __u32 * result; /* 8 8 */ __u32 timeout; /* 16 4 */ enum nvme_virt_mgmt_act act; /* 20 4 */ enum nvme_virt_mgmt_rt rt; /* 24 4 */ __u16 cntlid; /* 28 2 */ __u16 nr; /* 30 2 */ /* size: 32, cachelines: 1, members: 8 */ /* last cacheline: 32 bytes */ } __attribute__((__aligned__(8))); Signed-off-by: Daniel Wagner --- src/nvme/ioctl.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index bee0f19327..7a28363d67 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -3507,23 +3507,23 @@ int nvme_dev_self_test(struct nvme_dev_self_test_args *args); * nvme_virtual_mgmt_args - Arguments for the NVMe Virtualization * resource management command * @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 - * @timeout: Timeout in ms - * @result: If successful, the CQE dword0 */ struct nvme_virtual_mgmt_args { int args_size; int fd; + __u32 *result; + __u32 timeout; enum nvme_virt_mgmt_act act; enum nvme_virt_mgmt_rt rt; __u16 cntlid; __u16 nr; - __u32 timeout; - __u32 *result; -}; +} __attribute__((packed, aligned(__alignof__(__u32*)))); /** * nvme_virtual_mgmt() - Virtualization resource management From fc93fb68725d6bff59e99e735220f8d7d646c88f Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 13 Jan 2022 17:59:20 +0100 Subject: [PATCH 0370/1564] ioctl: Rearrange members in nvme_io_args Avoid any holes in the struct by rearranging the members. Also add the attribute packed to struct definition to reduce ABI breakage. struct nvme_io_args { int args_size; /* 0 4 */ int fd; /* 4 4 */ __u32 * result; /* 8 8 */ __u32 timeout; /* 16 4 */ __u32 nsid; /* 20 4 */ void * data; /* 24 8 */ void * metadata; /* 32 8 */ __u64 slba; /* 40 8 */ __u16 nlb; /* 48 2 */ __u16 control; /* 50 2 */ __u16 apptag; /* 52 2 */ __u16 appmask; /* 54 2 */ __u32 reftag; /* 56 4 */ __u32 data_len; /* 60 4 */ /* --- cacheline 1 boundary (64 bytes) --- */ __u64 storage_tag; /* 64 8 */ __u32 metadata_len; /* 72 4 */ __u8 dsm; /* 76 1 */ __u8 dspec; /* 77 1 */ /* size: 80, cachelines: 2, members: 18 */ /* padding: 2 */ /* last cacheline: 16 bytes */ } __attribute__((__aligned__(8))); Signed-off-by: Daniel Wagner --- src/nvme/ioctl.h | 46 ++++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 7a28363d67..850cf8d6c8 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -3565,49 +3565,51 @@ static inline int nvme_flush(int fd, __u32 nsid) { /** * nvme_io_args - Arguments for NVMe I/O commands * @fd: File descriptor of nvme device + * @result: The command completion result from CQE dword0 + * @timeout: Timeout in ms * @nsid: Namespace ID + * @data: Pointer to user address of the data buffer + * @metadata: Pointer to user address of the metadata buffer * @slba: Starting logical block - * @nblocks: Number of logical blocks to send (0's based value) + * @nbl: Number of logical blocks to send (0's based value) * @control: Command control flags, see &enum nvme_io_control_flags. - * @dsm: Data set management attributes, see &enum nvme_io_dsm_flags - * @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. * @apptag: This field specifies the Application Tag Mask expected value. - * Used only if the namespace is formatted to use end-to-end - * protection information. + * 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. + * 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. + * @data_len: Length of user buffer, @data, in bytes * @storage_tag: This filed specifies Variable Sized Expected Logical Block * Storage Tag (ELBST) and Expected Logical Block Reference * Tag (ELBRT) - * @data_len: Length of user buffer, @data, in bytes - * @data: Pointer to user address of the data buffer * @metadata_len:Length of user buffer, @metadata, in bytes - * @metadata: Pointer to user address of the metadata buffer - * @timeout: Timeout in ms + * @dsm: Data set management attributes, see &enum nvme_io_dsm_flags + * @dspec: Directive specific value */ struct nvme_io_args { int args_size; int fd; + __u32 *result; + __u32 timeout; __u32 nsid; + void *data; + void *metadata; __u64 slba; __u16 nlb; __u16 control; - __u8 dsm; - __u8 dspec; - __u32 reftag; __u16 apptag; __u16 appmask; - __u64 storage_tag; + __u32 reftag; __u32 data_len; - void *data; + __u64 storage_tag; __u32 metadata_len; - void *metadata; - __u32 timeout; - __u32 *result; -}; + __u8 dsm; + __u8 dspec; +} __attribute__((__packed__, aligned(__alignof__(__u64)))); /** * nvme_io() - Submit an nvme user I/O command From e78db5adb93df72adbe6b118dd24e9facfa9c1bd Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 13 Jan 2022 18:46:48 +0100 Subject: [PATCH 0371/1564] ioctl: Rearrange members in nvme_dsm_args Avoid any holes in the struct by rearranging the members. Also add the attribute packed to struct definition to reduce ABI breakage. struct nvme_dsm_args { int args_size; /* 0 4 */ int fd; /* 4 4 */ __u32 * result; /* 8 8 */ __u32 timeout; /* 16 4 */ __u32 nsid; /* 20 4 */ struct nvme_dsm_range * dsm; /* 24 8 */ __u32 attrs; /* 32 4 */ __u16 nr_ranges; /* 36 2 */ /* size: 40, cachelines: 1, members: 8 */ /* padding: 2 */ /* last cacheline: 40 bytes */ } __attribute__((__aligned__(8))); Signed-off-by: Daniel Wagner --- src/nvme/ioctl.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 850cf8d6c8..2a99010516 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -3709,23 +3709,23 @@ static inline int nvme_verify(struct nvme_io_args *args) /** * nvme_dsm_args - Arguments for the NVMe Dataset Management command * @fd: File descriptor of nvme device + * @result: The command completion result from CQE dword0 + * @timeout: Timeout in ms * @nsid: Namespace identifier + * @dsm: The data set management attributes * @attrs: DSM attributes, see &enum nvme_dsm_attributes * @nr_ranges: Number of block ranges in the data set management attributes - * @dsm: The data set management attributes - * @timeout: Timeout in ms - * @result: The command completion result from CQE dword0 */ struct nvme_dsm_args { int args_size; int fd; + __u32 *result; + __u32 timeout; __u32 nsid; + struct nvme_dsm_range *dsm; __u32 attrs; __u16 nr_ranges; - struct nvme_dsm_range *dsm; - __u32 timeout; - __u32 *result; -}; +} __attribute__((packed, aligned(__alignof__(__u32*)))); /** * nvme_dsm() - Send an nvme data set management command From 3b3d57a25ae6ec9b9fda18bce731644abb7d39bb Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 13 Jan 2022 18:50:31 +0100 Subject: [PATCH 0372/1564] ioctl: Rearrange members in nvme_copy_args Avoid any holes in the struct by rearranging the members. Also add the attribute packed to struct definition to reduce ABI breakage. struct nvme_copy_args { int args_size; /* 0 4 */ int fd; /* 4 4 */ __u32 * result; /* 8 8 */ __u32 timeout; /* 16 4 */ __u32 nsid; /* 20 4 */ struct nvme_copy_range * copy; /* 24 8 */ __u64 sdlba; /* 32 8 */ __u16 nr; /* 40 2 */ __u16 dspec; /* 42 2 */ __u8 prinfor; /* 44 1 */ __u8 prinfow; /* 45 1 */ __u8 dtype; /* 46 1 */ __u8 format; /* 47 1 */ int lr; /* 48 4 */ int fua; /* 52 4 */ __u32 ilbrt; /* 56 4 */ __u16 lbatm; /* 60 2 */ __u16 lbat; /* 62 2 */ /* size: 64, cachelines: 1, members: 18 */ } __attribute__((__aligned__(8))); Signed-off-by: Daniel Wagner --- src/nvme/ioctl.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 2a99010516..81d1b1bb0a 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -3745,43 +3745,43 @@ int nvme_dsm(struct nvme_dsm_args *args); /** * nvme_copy_args - Arguments for the NVMe Copy command * @fd: File descriptor of the nvme device + * @result: The command completion result from CQE dword0 + * @timeout: Timeout in ms * @nsid: Namespace identifier * @copy: Range descriptior * @sdlba: Start destination LBA * @nr: Number of ranges + * @dspec: Directive specific value * @prinfor: Protection information field for read * @prinfow: Protection information field for write * @dtype: Directive type - * @dspec: Directive specific value * @format: Descriptor format * @lr: Limited retry * @fua: Force unit access * @ilbrt: Initial logical block reference tag * @lbatm: Logical block application tag mask * @lbat: Logical block application tag - * @timeout: Timeout in ms - * @result: The command completion result from CQE dword0 */ struct nvme_copy_args { int args_size; int fd; + __u32 *result; + __u32 timeout; __u32 nsid; struct nvme_copy_range *copy; __u64 sdlba; __u16 nr; + __u16 dspec; __u8 prinfor; __u8 prinfow; __u8 dtype; - __u16 dspec; __u8 format; int lr; int fua; __u32 ilbrt; __u16 lbatm; __u16 lbat; - __u32 timeout; - __u32 *result; -}; +} __attribute__((packed, aligned(__alignof__(__u64)))); /** * nvme_copy() - From 83479721e39f086bac6458c54cdfdba9ad035adf Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 13 Jan 2022 18:54:43 +0100 Subject: [PATCH 0373/1564] ioctl: Rearrange members in nvme_resv_acquire_args Avoid any holes in the struct by rearranging the members. Also add the attribute packed to struct definition to reduce ABI breakage. struct nvme_resv_acquire_args { int args_size; /* 0 4 */ int fd; /* 4 4 */ __u32 * result; /* 8 8 */ __u32 timeout; /* 16 4 */ __u32 nsid; /* 20 4 */ enum nvme_resv_rtype rtype; /* 24 4 */ enum nvme_resv_racqa racqa; /* 28 4 */ __u64 crkey; /* 32 8 */ __u64 nrkey; /* 40 8 */ _Bool iekey; /* 48 1 */ /* size: 56, cachelines: 1, members: 10 */ /* padding: 7 */ /* last cacheline: 56 bytes */ } __attribute__((__aligned__(8))); Signed-off-by: Daniel Wagner --- src/nvme/ioctl.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 81d1b1bb0a..24fd59decb 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -3796,28 +3796,28 @@ int nvme_copy(struct nvme_copy_args *args); /** * nvme_resv_acquire_args - Arguments for the NVMe Reservation Acquire Comand * @fd: File descriptor of nvme device + * @result: The command completion result from CQE dword0 + * @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 - * @iekey: Set to ignore the existing key * @crkey: The current reservation key associated with the host * @nrkey: The reservation key to be unregistered from the namespace if - * the action is preempt - * @timeout: Timeout in ms - * @result: The command completion result from CQE dword0 + * the action is preempt + * @iekey: Set to ignore the existing key */ struct nvme_resv_acquire_args { int args_size; int fd; + __u32 *result; + __u32 timeout; __u32 nsid; enum nvme_resv_rtype rtype; enum nvme_resv_racqa racqa; - bool iekey; __u64 crkey; __u64 nrkey; - __u32 timeout; - __u32 *result; -}; + bool iekey; +} __attribute__((packed, aligned(__alignof__(__u64)))); /** * nvme_resv_acquire() - Send an nvme reservation acquire From a4304bc7a9302ac6fb2e09cb3c01b6d55c8c97ba Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 13 Jan 2022 18:56:22 +0100 Subject: [PATCH 0374/1564] ioctl: Rearrange members in nvme_resv_register_args Avoid any holes in the struct by rearranging the members. Also add the attribute packed to struct definition to reduce ABI breakage. struct nvme_resv_register_args { int args_size; /* 0 4 */ int fd; /* 4 4 */ __u32 * result; /* 8 8 */ __u32 timeout; /* 16 4 */ __u32 nsid; /* 20 4 */ enum nvme_resv_rrega rrega; /* 24 4 */ enum nvme_resv_cptpl cptpl; /* 28 4 */ __u64 crkey; /* 32 8 */ __u64 nrkey; /* 40 8 */ _Bool iekey; /* 48 1 */ /* size: 56, cachelines: 1, members: 10 */ /* padding: 7 */ /* last cacheline: 56 bytes */ } __attribute__((__aligned__(8))); Signed-off-by: Daniel Wagner --- src/nvme/ioctl.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 24fd59decb..5978a39e89 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -3847,15 +3847,15 @@ int nvme_resv_acquire(struct nvme_resv_acquire_args *args); struct nvme_resv_register_args { int args_size; int fd; + __u32 *result; + __u32 timeout; __u32 nsid; enum nvme_resv_rrega rrega; enum nvme_resv_cptpl cptpl; - bool iekey; __u64 crkey; __u64 nrkey; - __u32 timeout; - __u32 *result; -}; + bool iekey; +} __attribute__((packed, aligned(__alignof__(__u64)))); /** * nvme_resv_register() - Send an nvme reservation register From 9f6b2bddb170ba9efaa26bb699ac21226a91a86e Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 13 Jan 2022 18:57:44 +0100 Subject: [PATCH 0375/1564] ioctl: Rearrange members in nvme_resv_release_args Avoid any holes in the struct by rearranging the members. Also add the attribute packed to struct definition to reduce ABI breakage. struct nvme_resv_release_args { int args_size; /* 0 4 */ int fd; /* 4 4 */ __u32 * result; /* 8 8 */ __u32 timeout; /* 16 4 */ __u32 nsid; /* 20 4 */ enum nvme_resv_rtype rtype; /* 24 4 */ enum nvme_resv_rrela rrela; /* 28 4 */ __u64 crkey; /* 32 8 */ _Bool iekey; /* 40 1 */ /* size: 48, cachelines: 1, members: 9 */ /* padding: 7 */ /* last cacheline: 48 bytes */ } __attribute__((__aligned__(8))); Signed-off-by: Daniel Wagner --- src/nvme/ioctl.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 5978a39e89..f22fd59285 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -3872,25 +3872,25 @@ int nvme_resv_register(struct nvme_resv_register_args *args); /** * nvme_resv_release_args - Arguments for the NVMe Reservation Release Command * @fd: File descriptor of nvme device + * @result: The command completion result from CQE dword0 + * @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 * @crkey: The current reservation key to release - * @timeout: Timeout in ms - * @result: The command completion result from CQE dword0 + * @iekey: Set to ignore the existing key */ struct nvme_resv_release_args { int args_size; int fd; + __u32 *result; + __u32 timeout; __u32 nsid; enum nvme_resv_rtype rtype; enum nvme_resv_rrela rrela; - bool iekey; __u64 crkey; - __u32 timeout; - __u32 *result; -}; + bool iekey; +} __attribute__((packed, aligned(__alignof__(__u64)))); /** * nvme_resv_release() - Send an nvme reservation release From f5fa119106f97b56816cd74b1b78a1fd4c33fb34 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 13 Jan 2022 19:01:48 +0100 Subject: [PATCH 0376/1564] ioctl: Rearrange members in nvme_resv_report_args Avoid any holes in the struct by rearranging the members. Also add the attribute packed to struct definition to reduce ABI breakage. struct nvme_resv_report_args { int args_size; /* 0 4 */ int fd; /* 4 4 */ __u32 * result; /* 8 8 */ __u32 timeout; /* 16 4 */ __u32 nsid; /* 20 4 */ struct nvme_resv_status * report; /* 24 8 */ __u32 len; /* 32 4 */ _Bool eds; /* 36 1 */ /* size: 40, cachelines: 1, members: 8 */ /* padding: 3 */ /* last cacheline: 40 bytes */ } __attribute__((__aligned__(8))); Signed-off-by: Daniel Wagner --- src/nvme/ioctl.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index f22fd59285..86ef600c33 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -3904,24 +3904,24 @@ int nvme_resv_release(struct nvme_resv_release_args *args); /** * nvme_resv_report_args - Arguments for the NVMe Reservation Report command * @fd: File descriptor of nvme device + * @result: The command completion result from CQE dword0 + * @timeout: Timeout in ms * @nsid: Namespace identifier - * @eds: Request extended Data Structure - * @len: Number of bytes to request transfered with this command * @report: The user space destination address to store the reservation * report - * @timeout: Timeout in ms - * @result: The command completion result from CQE dword0 + * @len: Number of bytes to request transfered with this command + * @eds: Request extended Data Structure */ struct nvme_resv_report_args { int args_size; int fd; + __u32 *result; + __u32 timeout; __u32 nsid; - bool eds; - __u32 len; struct nvme_resv_status *report; - __u32 timeout; - __u32 *result; -}; + __u32 len; + bool eds; +} __attribute__((packed, aligned(__alignof__(__u32*)))); /** * nvme_resv_report() - Send an nvme reservation report From a335603816389e64c60f00a62d55b8cc88bcda22 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 13 Jan 2022 19:04:09 +0100 Subject: [PATCH 0377/1564] ioctl: Rearrange members in nvme_zns_mgmt_send_args Avoid any holes in the struct by rearranging the members. Also add the attribute packed to struct definition to reduce ABI breakage. struct nvme_zns_mgmt_send_args { int args_size; /* 0 4 */ int fd; /* 4 4 */ __u32 * result; /* 8 8 */ __u32 timeout; /* 16 4 */ __u32 nsid; /* 20 4 */ __u64 slba; /* 24 8 */ enum nvme_zns_send_action zsa; /* 32 4 */ __u32 data_len; /* 36 4 */ void * data; /* 40 8 */ _Bool select_all; /* 48 1 */ __u8 zsaso; /* 49 1 */ /* size: 56, cachelines: 1, members: 11 */ /* padding: 6 */ /* last cacheline: 56 bytes */ } __attribute__((__aligned__(8))); Signed-off-by: Daniel Wagner --- src/nvme/ioctl.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 86ef600c33..91fc3c4f34 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -3939,29 +3939,29 @@ int nvme_resv_report(struct nvme_resv_report_args *args); /** * nvme_zns_mgmt_send_args - Arguments for the NVMe ZNS Management Send command * @fd: File descriptor of nvme device + * @result: The command completion result from CQE dword0 + * @timeout: timeout in ms * @nsid: Namespace ID * @slba: Starting logical block address * @zsa: Zone send action - * @select_all: Select all flag - * @zsaso: Zone Send Action Specific Option * @data_len: Length of @data * @data: Userspace address of the data - * @timeout: timeout in ms - * @result: The command completion result from CQE dword0 + * @select_all: Select all flag + * @zsaso: Zone Send Action Specific Option */ struct nvme_zns_mgmt_send_args { int args_size; int fd; + __u32 *result; + __u32 timeout; __u32 nsid; __u64 slba; enum nvme_zns_send_action zsa; - bool select_all; - __u8 zsaso; __u32 data_len; void *data; - __u32 timeout; - __u32 *result; -}; + bool select_all; + __u8 zsaso; +} __attribute__((packed, aligned(__alignof__(__u64)))); /** * nvme_zns_mgmt_send() - From 727b8b0e81e2428f44bd433c2a831761951ce364 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 13 Jan 2022 19:07:18 +0100 Subject: [PATCH 0378/1564] ioctl: Rearrange members in nvme_zns_mgmt_recv_args Avoid any holes in the struct by rearranging the members. Also add the attribute packed to struct definition to reduce ABI breakage. struct nvme_zns_mgmt_recv_args { int args_size; /* 0 4 */ int fd; /* 4 4 */ __u32 * result; /* 8 8 */ __u32 timeout; /* 16 4 */ __u32 nsid; /* 20 4 */ __u64 slba; /* 24 8 */ enum nvme_zns_recv_action zra; /* 32 4 */ __u32 data_len; /* 36 4 */ void * data; /* 40 8 */ __u16 zrasf; /* 48 2 */ _Bool zras_feat; /* 50 1 */ /* size: 56, cachelines: 1, members: 11 */ /* padding: 5 */ /* last cacheline: 56 bytes */ } __attribute__((__aligned__(8))); Signed-off-by: Daniel Wagner --- src/nvme/ioctl.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 91fc3c4f34..73628e17fb 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -3976,29 +3976,29 @@ int nvme_zns_mgmt_send(struct nvme_zns_mgmt_send_args *args); /** * nvme_zns_mgmt_recv_args - Arguments for the NVMe ZNS Management Receive command * @fd: File descriptor of nvme device + * @result: The command completion result from CQE dword0 + * @timeout: timeout in ms * @nsid: Namespace ID * @slba: Starting logical block address * @zra: zone receive action - * @zrasf: Zone receive action specific field - * @zras_feat: Zone receive action specific features * @data_len: Length of @data * @data: Userspace address of the data - * @timeout: timeout in ms - * @result: The command completion result from CQE dword0 + * @zrasf: Zone receive action specific field + * @zras_feat: Zone receive action specific features */ struct nvme_zns_mgmt_recv_args { int args_size; int fd; + __u32 *result; + __u32 timeout; __u32 nsid; __u64 slba; enum nvme_zns_recv_action zra; - __u16 zrasf; - bool zras_feat; __u32 data_len; void *data; - __u32 timeout; - __u32 *result; -}; + __u16 zrasf; + bool zras_feat; +} __attribute__((packed, aligned(__alignof__(__u32*)))); /** * nvme_zns_mgmt_recv() - @@ -4034,16 +4034,16 @@ static inline int nvme_zns_report_zones(int fd, __u32 nsid, __u64 slba, struct nvme_zns_mgmt_recv_args args = { .args_size = sizeof(args), .fd = fd, + .result = result, + .timeout = timeout, .nsid = nsid, .slba = slba, .zra = extended ? NVME_ZNS_ZRA_EXTENDED_REPORT_ZONES : NVME_ZNS_ZRA_REPORT_ZONES, - .zrasf = opts, - .zras_feat = partial, .data_len = data_len, .data = data, - .timeout = timeout, - .result = result, + .zrasf = opts, + .zras_feat = partial, }; return nvme_zns_mgmt_recv(&args); From 2fa9cf680d037ac181e10bac65fc6c69da6687f7 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 13 Jan 2022 19:09:35 +0100 Subject: [PATCH 0379/1564] ioctl: Rearrange members in nvme_zns_append_args Avoid any holes in the struct by rearranging the members. Also add the attribute packed to struct definition to reduce ABI breakage. struct nvme_zns_append_args { int args_size; /* 0 4 */ int fd; /* 4 4 */ __u64 * result; /* 8 8 */ __u32 timeout; /* 16 4 */ __u32 nsid; /* 20 4 */ __u64 zslba; /* 24 8 */ __u16 nlb; /* 32 2 */ __u16 control; /* 34 2 */ __u32 ilbrt; /* 36 4 */ __u16 lbat; /* 40 2 */ __u16 lbatm; /* 42 2 */ __u32 data_len; /* 44 4 */ void * data; /* 48 8 */ void * metadata; /* 56 8 */ /* --- cacheline 1 boundary (64 bytes) --- */ __u32 metadata_len; /* 64 4 */ /* size: 72, cachelines: 2, members: 15 */ /* padding: 4 */ /* last cacheline: 8 bytes */ } __attribute__((__aligned__(8))); Signed-off-by: Daniel Wagner --- src/nvme/ioctl.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 73628e17fb..84e7e3c42a 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -4052,6 +4052,8 @@ static inline int nvme_zns_report_zones(int fd, __u32 nsid, __u64 slba, /** * nvme_zns_append_args - Arguments for the NVMe ZNS Append command * @fd: File descriptor of nvme device + * @result: The command completion result from CQE dword0 + * @timeout: Timeout in ms * @nsid: Namespace ID * @zslba: Zone start logical block address * @nlb: Number of logical blocks @@ -4061,14 +4063,14 @@ static inline int nvme_zns_report_zones(int fd, __u32 nsid, __u64 slba, * @lbatm: Logical block application tag mask * @data_len: Length of @data * @data: Userspace address of the data - * @metadata_len: Length of @metadata * @metadata: Userspace address of the metadata - * @timeout: Timeout in ms - * @result: The command completion result from CQE dword0 + * @metadata_len: Length of @metadata */ struct nvme_zns_append_args { int args_size; int fd; + __u64 *result; + __u32 timeout; __u32 nsid; __u64 zslba; __u16 nlb; @@ -4078,11 +4080,9 @@ struct nvme_zns_append_args { __u16 lbatm; __u32 data_len; void *data; - __u32 metadata_len; void *metadata; - __u32 timeout; - __u64 *result; -}; + __u32 metadata_len; +} __attribute__((packed, aligned(__alignof__(__u64)))); /** * nvme_zns_append() - Append data to a zone From 31c533d50b0219c19512836f929ee38549853cbb Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Fri, 14 Jan 2022 11:10:08 +0100 Subject: [PATCH 0380/1564] log: Introduce libnvme error codes Add libnvme specific error codes which map to a specific error message. The system error codes in errno are too overloaded to figure out what is going wrong. With this we can remove the nvme_log_message buffer. This avoids having a global library buffer. Signed-off-by: Daniel Wagner --- libnvme/nvme.i | 45 ++++++++++++++++++++++++++++++++++---- src/libnvme.map | 2 -- src/nvme/fabrics.c | 54 ++++++++++++++++++++++++++-------------------- src/nvme/ioctl.h | 14 ++++++++++++ src/nvme/log.c | 5 ----- src/nvme/tree.c | 6 +++--- 6 files changed, 89 insertions(+), 37 deletions(-) diff --git a/libnvme/nvme.i b/libnvme/nvme.i index 5458d3cc49..a2d9b5d522 100644 --- a/libnvme/nvme.i +++ b/libnvme/nvme.i @@ -94,14 +94,51 @@ static int discover_err = 0; %exception nvme_ctrl::connect { connect_err = 0; + errno = 0; $action /* $action sets connect_err to non-zero value on failure */ if (connect_err == 1) { SWIG_exception(SWIG_AttributeError, "Existing controller connection"); } else if (connect_err) { - if (nvme_log_message) - SWIG_exception(SWIG_RuntimeError, nvme_log_message); - else - SWIG_exception(SWIG_RuntimeError, "Connect failed"); + switch (errno) { + case ENVME_CONNECT_RESOLVE: + SWIG_exception(SWIG_RuntimeError, "failed to resolve host"); + break; + case ENVME_CONNECT_ADDRFAM: + SWIG_exception(SWIG_RuntimeError, "unrecognized address family"); + break; + case ENVME_CONNECT_TRADDR: + SWIG_exception(SWIG_RuntimeError, "failed to get traddr"); + break; + case ENVME_CONNECT_TARG: + SWIG_exception(SWIG_RuntimeError, "need a transport (-t) argument"); + break; + case ENVME_CONNECT_AARG: + SWIG_exception(SWIG_RuntimeError, "need a address (-a) argument\n"); + break; + case ENVME_CONNECT_OPEN: + SWIG_exception(SWIG_RuntimeError, "failed to open nvme-fabrics device"); + break; + case ENVME_CONNECT_WRITE: + SWIG_exception(SWIG_RuntimeError, "failed to write to nvme-fabrics device"); + break; + case ENVME_CONNECT_READ: + SWIG_exception(SWIG_RuntimeError, "failed to read from nvme-fabrics device"); + break; + case ENVME_CONNECT_PARSE: + SWIG_exception(SWIG_RuntimeError, "failed to parse ctrl info"); + break; + case ENVME_CONNECT_INVAL_TR: + SWIG_exception(SWIG_RuntimeError, "invalid transport type"); + break; + case ENVME_CONNECT_LOOKUP_SUBSYS_NAME: + SWIG_exception(SWIG_RuntimeError, "failed to lookup subsystem name"); + break; + case ENVME_CONNECT_LOOKUP_SUBSYS: + SWIG_exception(SWIG_RuntimeError, "failed to lookup subsystem"); + break; + default: + SWIG_exception(SWIG_RuntimeError, "Connect failed"); + } } } diff --git a/src/libnvme.map b/src/libnvme.map index c4df7c40a9..b47003247e 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -1,7 +1,6 @@ LIBNVME_1_0 { global: __nvme_get_log_page; - __nvme_msg; nvme_admin_passthru64; nvme_admin_passthru; nvme_attach_ns; @@ -174,7 +173,6 @@ LIBNVME_1_0 { nvme_io_passthru; nvme_lockdown; nvme_log_level; - nvme_log_message; nvme_lookup_host; nvme_lookup_subsystem; nvme_namespace_attach_ctrls; diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 82c4deb824..7546fb1ad3 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -361,7 +361,7 @@ static int hostname2traddr(nvme_ctrl_t c) ret = getaddrinfo(c->traddr, NULL, &hints, &host_info); if (ret) { nvme_msg(LOG_ERR, "failed to resolve host %s info\n", c->traddr); - return ret; + return -ENVME_CONNECT_RESOLVE; } switch (host_info->ai_family) { @@ -378,13 +378,13 @@ static int hostname2traddr(nvme_ctrl_t c) default: nvme_msg(LOG_ERR, "unrecognized address family (%d) %s\n", host_info->ai_family, c->traddr); - ret = -EINVAL; + ret = -ENVME_CONNECT_ADDRFAM; goto free_addrinfo; } if (!p) { nvme_msg(LOG_ERR, "failed to get traddr for %s\n", c->traddr); - ret = -errno; + ret = -ENVME_CONNECT_TRADDR; goto free_addrinfo; } c->traddr = strdup(addrstr); @@ -403,15 +403,13 @@ static int build_options(nvme_host_t h, nvme_ctrl_t c, char **argstr) if (!transport) { nvme_msg(LOG_ERR, "need a transport (-t) argument\n"); - errno = EINVAL; - return -1; + return -ENVME_CONNECT_TARG; } if (strncmp(transport, "loop", 4)) { if (!nvme_ctrl_get_traddr(c)) { nvme_msg(LOG_ERR, "need a address (-a) argument\n"); - errno = EINVAL; - return -1; + return -ENVME_CONNECT_AARG; } /* Use the default ctrl loss timeout if unset */ if (cfg->ctrl_loss_tmo == -1) @@ -421,8 +419,7 @@ static int build_options(nvme_host_t h, nvme_ctrl_t c, char **argstr) /* always specify nqn as first arg - this will init the string */ if (asprintf(argstr, "nqn=%s", nvme_ctrl_get_subsysnqn(c)) < 0) { - errno = ENOMEM; - return -1; + return -ENOMEM; } if (!strcmp(nvme_ctrl_get_subsysnqn(c), NVME_DISC_SUBSYS_NAME)) { nvme_ctrl_set_discovery_ctrl(c, true); @@ -499,7 +496,7 @@ static int __nvmf_add_ctrl(const char *argstr) if (fd < 0) { nvme_msg(LOG_ERR, "Failed to open %s: %s\n", nvmf_dev, strerror(errno)); - return -1; + return -ENVME_CONNECT_OPEN; } nvme_msg(LOG_DEBUG, "connect ctrl, '%.*s'\n", @@ -508,7 +505,7 @@ static int __nvmf_add_ctrl(const char *argstr) if (ret != len) { nvme_msg(LOG_NOTICE, "Failed to write to %s: %s\n", nvmf_dev, strerror(errno)); - ret = -1; + ret = -ENVME_CONNECT_WRITE; goto out_close; } @@ -516,7 +513,7 @@ static int __nvmf_add_ctrl(const char *argstr) if (len < 0) { nvme_msg(LOG_ERR, "Failed to read from %s: %s\n", nvmf_dev, strerror(errno)); - ret = -1; + ret = -ENVME_CONNECT_READ; goto out_close; } nvme_msg(LOG_DEBUG, "connect ctrl, response '%.*s'\n", @@ -531,8 +528,7 @@ static int __nvmf_add_ctrl(const char *argstr) } nvme_msg(LOG_ERR, "Failed to parse ctrl info for \"%s\"\n", argstr); - errno = EINVAL; - ret = -1; + ret = -ENVME_CONNECT_PARSE; out_close: close(fd); return ret; @@ -548,18 +544,26 @@ int nvmf_add_ctrl_opts(nvme_ctrl_t c, struct nvme_fabrics_config *cfg) cfg = merge_config(c, cfg); if (traddr_is_hostname(c)) { ret = hostname2traddr(c); - if (ret) - return ret; + if (ret) { + errno = -ret; + return -1; + } } ret = build_options(h, c, &argstr); - if (ret) - return ret; + if (ret) { + errno = -ret; + return -1; + } ret = __nvmf_add_ctrl(argstr); free(argstr); - if (ret >= 0) + if (ret < 0) { + errno = -ret; + ret = -1; + } else { nvme_msg(LOG_INFO, "nvme%d: ctrl connected\n", ret); + } return ret; } @@ -575,8 +579,10 @@ int nvmf_add_ctrl(nvme_host_t h, nvme_ctrl_t c, nvme_ctrl_set_discovered(c, true); if (traddr_is_hostname(c)) { ret = hostname2traddr(c); - if (ret) - return ret; + if (ret) { + errno = -ret; + return -1; + } } ret = build_options(h, c, &argstr); @@ -585,8 +591,10 @@ int nvmf_add_ctrl(nvme_host_t h, nvme_ctrl_t c, ret = __nvmf_add_ctrl(argstr); free(argstr); - if (ret < 0) - return ret; + if (ret < 0) { + errno = -ret; + return -1; + } nvme_msg(LOG_INFO, "nvme%d: ctrl connected\n", ret); return nvme_init_ctrl(h, c, ret); diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index eb16fac423..b472d44d7c 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -24,6 +24,20 @@ #ifndef _LINUX_NVME_IOCTL_H #define _LINUX_NVME_IOCTL_H +/* libnvme errno error codes */ +#define ENVME_CONNECT_RESOLVE 1000 /* "failed to resolve host" */ +#define ENVME_CONNECT_ADDRFAM 1001 /* "unrecognized address family" */ +#define ENVME_CONNECT_TRADDR 1002 /* "failed to get traddr" */ +#define ENVME_CONNECT_TARG 1003 /* "need a transport (-t) argument" */ +#define ENVME_CONNECT_AARG 1004 /* "need a address (-a) argument\n" */ +#define ENVME_CONNECT_OPEN 1005 /* "failed to open nvme-fabrics device" */ +#define ENVME_CONNECT_WRITE 1006 /* "failed to write to nvme-fabrics device" */ +#define ENVME_CONNECT_READ 1007 /* "failed to read from nvme-fabrics device" */ +#define ENVME_CONNECT_PARSE 1008 /* "failed to parse ctrl info" */ +#define ENVME_CONNECT_INVAL_TR 1009 /* "invalid transport type" */ +#define ENVME_CONNECT_LOOKUP_SUBSYS_NAME 1010 /* "failed to lookup subsystem name" */ +#define ENVME_CONNECT_LOOKUP_SUBSYS 1011 /* "failed to lookup subsystem */ + /* '0' is interpreted by the kernel to mean 'apply the default timeout' */ #define NVME_DEFAULT_IOCTL_TIMEOUT 0 diff --git a/src/nvme/log.c b/src/nvme/log.c index 9a7bcafeeb..7d71d69dd4 100644 --- a/src/nvme/log.c +++ b/src/nvme/log.c @@ -35,7 +35,6 @@ int nvme_log_level = DEFAULT_LOGLEVEL; bool nvme_log_timestamp; bool nvme_log_pid; -char *nvme_log_message = NULL; void __attribute__((format(printf, 3, 4))) __nvme_msg(int lvl, const char *func, const char *format, ...) @@ -83,10 +82,6 @@ __nvme_msg(int lvl, const char *func, const char *format, ...) message = NULL; va_end(ap); - if (nvme_log_message) - free(nvme_log_message); - nvme_log_message = strdup(message); - if (lvl <= nvme_log_level) fprintf(stderr, "%s%s", header ? header : "", message ? message : ""); diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 7bcecc9bdd..6dd7a8e75f 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -1156,7 +1156,7 @@ int nvme_init_ctrl(nvme_host_t h, nvme_ctrl_t c, int instance) if (strcmp(c->transport, "loop")) { c->address = nvme_get_attr(path, "address"); if (!c->address) { - errno = ENXIO; + errno = ENVME_CONNECT_INVAL_TR; ret = -1; goto out_free_name; } @@ -1166,13 +1166,13 @@ int nvme_init_ctrl(nvme_host_t h, nvme_ctrl_t c, int instance) if (!subsys_name) { nvme_msg(LOG_ERR, "Failed to lookup subsystem name for %s\n", c->name); - errno = ENXIO; + errno = ENVME_CONNECT_LOOKUP_SUBSYS_NAME; ret = -1; goto out_free_name; } s = nvme_lookup_subsystem(h, subsys_name, c->subsysnqn); if (!s) { - errno = ENXIO; + errno = ENVME_CONNECT_LOOKUP_SUBSYS; ret = -1; goto out_free_subsys; } From 5d7b210a44174276522d389b961712c0563d5c36 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Fri, 14 Jan 2022 16:59:05 +0100 Subject: [PATCH 0381/1564] ioctl: Set provided timestamp nvme_set_features_timestamp The argument order for memcpy is clearly the wrong way around. The provided timestamp should be stored into the ts variable. The compiler was warning about ts not being initialized. Signed-off-by: Daniel Wagner --- src/nvme/ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index e6f184a4de..eec702f107 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -589,7 +589,7 @@ int nvme_set_features_timestamp(int fd, bool save, __u64 timestamp) .result = NULL, }; - memcpy(&t, ts.timestamp, sizeof(ts.timestamp)); + memcpy(ts.timestamp, &t, sizeof(ts.timestamp)); return nvme_set_features(&args); } From 7d14b6dc02c6049bf4062f73b4139c8490c2ee47 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Fri, 14 Jan 2022 17:13:16 +0100 Subject: [PATCH 0382/1564] tree: Skip invalid pointer when scanning topology Do not try to dereference a NULL pointer. Just ignore it. Signed-off-by: Daniel Wagner --- src/nvme/tree.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 8f8c68b60a..583632ead9 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -86,6 +86,7 @@ static int nvme_scan_topology(struct nvme_root *r, nvme_scan_filter_t f) if (!c) { nvme_msg(LOG_DEBUG, "failed to scan ctrl %s: %s\n", ctrls[i]->d_name, strerror(errno)); + continue; } if ((f) && !f(c->s)) { nvme_free_ctrl(c); From f6cc9487ef8e272ac1dbb61a1df87585df2d2eb3 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Fri, 14 Jan 2022 18:24:34 +0100 Subject: [PATCH 0383/1564] build: Add __nvme_msg back to exported symbols nvme_msg() is a macro which call __nvme_msg(). The naming scheme is not great but until we figured it out, add it back to the list of exported symbols. Signed-off-by: Daniel Wagner --- src/libnvme.map | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libnvme.map b/src/libnvme.map index 506f26853e..9b6a1d353d 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -1,6 +1,7 @@ LIBNVME_1_0 { global: __nvme_get_log_page; + __nvme_msg; nvme_admin_passthru64; nvme_admin_passthru; nvme_attach_ns; From 2686f28b210fb87261c294e6ccb317142395eae9 Mon Sep 17 00:00:00 2001 From: Tomas Bzatek Date: Sun, 16 Jan 2022 11:46:44 +0100 Subject: [PATCH 0384/1564] docs: Fix a typo in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 683c1328ba..0b1d2bbb30 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # libnvme This is the libnvme development C library. libnvme provides type -defintions for NVMe specification structures, enumerations, and bit +definitions for NVMe specification structures, enumerations, and bit fields, helper functions to construct, dispatch, and decode commands and payloads, and utilities to connect, scan, and manage nvme devices on a Linux system. From 4e678f83307802630d336fe09e62696e3fefe436 Mon Sep 17 00:00:00 2001 From: Tomas Bzatek Date: Sun, 16 Jan 2022 12:34:29 +0100 Subject: [PATCH 0385/1564] types: TP8013 and TP8014 doc strings updates Also changed NVMF_DISC_EFLAGS defines into an enum for consistency with other definitions. --- src/nvme/types.h | 58 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 11 deletions(-) diff --git a/src/nvme/types.h b/src/nvme/types.h index 35fc37ff94..d0536c75fa 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -3944,9 +3944,22 @@ enum nvme_ae_info_notice { /** * enum nvme_subsys_type - Type of the NVM subsystem. - * @NVME_NQN_DISC: Discovery type target subsystem - * @NVME_NQN_NVME: NVME type target subsystem - * @NVME_NQN_CURR: Current Discovery type target 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). + * @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. + * @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. */ enum nvme_subsys_type { NVME_NQN_DISC = 1, @@ -3962,10 +3975,28 @@ enum nvme_subsys_type { #define NVMF_NQN_SIZE 223 #define NVMF_TRSVCID_SIZE 32 -#define NVMF_DISC_EFLAGS_NONE 0 -#define NVMF_DISC_EFLAGS_DUPRETINFO 1 -#define NVMF_DISC_EFLAGS_EPCSD 2 -#define NVMF_DISC_EFLAGS_BOTH 3 +/** + * enum nvmf_disc_eflags - Discovery Log Page entry flags. + * @NVMF_DISC_EFLAGS_NONE: Indicates that none of the DUPRETINFO or EPCSD + * 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. + * @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. + */ +enum nvmf_disc_eflags { + NVMF_DISC_EFLAGS_NONE = 0, + NVMF_DISC_EFLAGS_DUPRETINFO = 1, + NVMF_DISC_EFLAGS_EPCSD = 2, + NVMF_DISC_EFLAGS_BOTH = 3, +}; /** * struct nvmf_disc_log_entry - Discovery Log Page entry @@ -3992,15 +4023,20 @@ enum nvme_subsys_type { * @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. - * @eflags: + * @eflags: Entry Flags (EFLAGS): Indicates additional information related to + * the current entry. See &enum nvmf_disc_eflags. * @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. * @subnqn: NVM Subsystem Qualified Name (SUBNQN): NVMe Qualified Name (NQN) - * that uniquely identifies the NVM subsystem. For a Discovery Service, - * 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. From cde70c4425b62dbe69372935553ac44734004fe1 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Sun, 16 Jan 2022 10:38:01 +0100 Subject: [PATCH 0386/1564] Implement nvme_errno_to_string() Add a function nvme_errno_to_string() to provide a string describing the error from nvme_add_ctrl(). Signed-off-by: Hannes Reinecke --- libnvme/nvme.i | 44 +++++--------------------------------------- src/libnvme.map | 1 + src/nvme/ioctl.h | 14 -------------- src/nvme/util.c | 22 ++++++++++++++++++++++ src/nvme/util.h | 22 ++++++++++++++++++++++ 5 files changed, 50 insertions(+), 53 deletions(-) diff --git a/libnvme/nvme.i b/libnvme/nvme.i index 7589f7ef00..25d7ac2575 100644 --- a/libnvme/nvme.i +++ b/libnvme/nvme.i @@ -99,45 +99,11 @@ static int discover_err = 0; if (connect_err == 1) { SWIG_exception(SWIG_AttributeError, "Existing controller connection"); } else if (connect_err) { - switch (errno) { - case ENVME_CONNECT_RESOLVE: - SWIG_exception(SWIG_RuntimeError, "failed to resolve host"); - break; - case ENVME_CONNECT_ADDRFAM: - SWIG_exception(SWIG_RuntimeError, "unrecognized address family"); - break; - case ENVME_CONNECT_TRADDR: - SWIG_exception(SWIG_RuntimeError, "failed to get traddr"); - break; - case ENVME_CONNECT_TARG: - SWIG_exception(SWIG_RuntimeError, "need a transport (-t) argument"); - break; - case ENVME_CONNECT_AARG: - SWIG_exception(SWIG_RuntimeError, "need a address (-a) argument\n"); - break; - case ENVME_CONNECT_OPEN: - SWIG_exception(SWIG_RuntimeError, "failed to open nvme-fabrics device"); - break; - case ENVME_CONNECT_WRITE: - SWIG_exception(SWIG_RuntimeError, "failed to write to nvme-fabrics device"); - break; - case ENVME_CONNECT_READ: - SWIG_exception(SWIG_RuntimeError, "failed to read from nvme-fabrics device"); - break; - case ENVME_CONNECT_PARSE: - SWIG_exception(SWIG_RuntimeError, "failed to parse ctrl info"); - break; - case ENVME_CONNECT_INVAL_TR: - SWIG_exception(SWIG_RuntimeError, "invalid transport type"); - break; - case ENVME_CONNECT_LOOKUP_SUBSYS_NAME: - SWIG_exception(SWIG_RuntimeError, "failed to lookup subsystem name"); - break; - case ENVME_CONNECT_LOOKUP_SUBSYS: - SWIG_exception(SWIG_RuntimeError, "failed to lookup subsystem"); - break; - default: - SWIG_exception(SWIG_RuntimeError, "Connect failed"); + const char *errstr = nvme_errno_to_string(errno); + if (errstr) { + SWIG_exception(SWIG_RuntimeError, errstr); + } else { + SWIG_exception(SWIG_RuntimeError, "Connect failed"); } } } diff --git a/src/libnvme.map b/src/libnvme.map index 9b6a1d353d..81b8d52ed8 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -56,6 +56,7 @@ LIBNVME_1_0 { nvme_dsm; nvme_dsm_range; nvme_dump_config; + nvme_errno_to_string; nvme_first_host; nvme_first_subsystem; nvme_flush; diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 0297dfb8af..84e7e3c42a 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -24,20 +24,6 @@ #ifndef _LINUX_NVME_IOCTL_H #define _LINUX_NVME_IOCTL_H -/* libnvme errno error codes */ -#define ENVME_CONNECT_RESOLVE 1000 /* "failed to resolve host" */ -#define ENVME_CONNECT_ADDRFAM 1001 /* "unrecognized address family" */ -#define ENVME_CONNECT_TRADDR 1002 /* "failed to get traddr" */ -#define ENVME_CONNECT_TARG 1003 /* "need a transport (-t) argument" */ -#define ENVME_CONNECT_AARG 1004 /* "need a address (-a) argument\n" */ -#define ENVME_CONNECT_OPEN 1005 /* "failed to open nvme-fabrics device" */ -#define ENVME_CONNECT_WRITE 1006 /* "failed to write to nvme-fabrics device" */ -#define ENVME_CONNECT_READ 1007 /* "failed to read from nvme-fabrics device" */ -#define ENVME_CONNECT_PARSE 1008 /* "failed to parse ctrl info" */ -#define ENVME_CONNECT_INVAL_TR 1009 /* "invalid transport type" */ -#define ENVME_CONNECT_LOOKUP_SUBSYS_NAME 1010 /* "failed to lookup subsystem name" */ -#define ENVME_CONNECT_LOOKUP_SUBSYS 1011 /* "failed to lookup subsystem */ - /* '0' is interpreted by the kernel to mean 'apply the default timeout' */ #define NVME_DEFAULT_IOCTL_TIMEOUT 0 diff --git a/src/nvme/util.c b/src/nvme/util.c index f8da8f3cfd..b3c762051a 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -476,3 +476,25 @@ int nvme_get_directive_receive_length(enum nvme_directive_dtype dtype, return -EINVAL; } } + +static const char * const libnvme_status[] = { + [ENVME_CONNECT_RESOLVE] = "failed to resolve host", + [ENVME_CONNECT_ADDRFAM] = "unrecognized address family", + [ENVME_CONNECT_TRADDR] = "failed to get transport address", + [ENVME_CONNECT_TARG] = "no transport specified", + [ENVME_CONNECT_AARG] = "no transport address specified", + [ENVME_CONNECT_OPEN] = "failed to open nvme-fabrics device", + [ENVME_CONNECT_WRITE] = "failed to write to nvme-fabrics device", + [ENVME_CONNECT_READ] = "failed to read from nvme-fabrics device", + [ENVME_CONNECT_PARSE] = "failed to parse ctrl info", + [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", +}; + +const char *nvme_errno_to_string(int status) +{ + const char *s = ARGSTR(libnvme_status, status); + + return s; +} diff --git a/src/nvme/util.h b/src/nvme/util.h index d55307fa81..f46dc5043d 100644 --- a/src/nvme/util.h +++ b/src/nvme/util.h @@ -11,6 +11,20 @@ #include "types.h" +/* nvme connect error codes */ +#define ENVME_CONNECT_RESOLVE 1000 /* "failed to resolve host" */ +#define ENVME_CONNECT_ADDRFAM 1001 /* "unrecognized address family" */ +#define ENVME_CONNECT_TRADDR 1002 /* "failed to get traddr" */ +#define ENVME_CONNECT_TARG 1003 /* "need a transport (-t) argument" */ +#define ENVME_CONNECT_AARG 1004 /* "need a address (-a) argument\n" */ +#define ENVME_CONNECT_OPEN 1005 /* "failed to open nvme-fabrics device" */ +#define ENVME_CONNECT_WRITE 1006 /* "failed to write to nvme-fabrics device" */ +#define ENVME_CONNECT_READ 1007 /* "failed to read from nvme-fabrics device" */ +#define ENVME_CONNECT_PARSE 1008 /* "failed to parse ctrl info" */ +#define ENVME_CONNECT_INVAL_TR 1009 /* "invalid transport type" */ +#define ENVME_CONNECT_LOOKUP_SUBSYS_NAME 1010 /* "failed to lookup subsystem name" */ +#define ENVME_CONNECT_LOOKUP_SUBSYS 1011 /* "failed to lookup subsystem */ + /** * nvme_status_to_errno() - Converts nvme return status to errno * @status: Return status from an nvme passthrough commmand @@ -31,6 +45,14 @@ __u8 nvme_status_to_errno(int status, bool fabrics); */ const char *nvme_status_to_string(int status, bool fabrics); +/** + * nvme_errno_to_string() - Returns string describing nvme connect failures + * @err: Returned error code from nvme_add_ctrl() + * + * Return: String representation of the nvme connect error codes + */ +const char *nvme_errno_to_string(int err); + /** * nvme_init_id_ns() - Initialize an Identify Namepsace structure for creation. * @ns: Address of the Identify Namespace structure to initialize From d06c94d80e244c5c2a50ad6f76d2ae278700903b Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 17 Jan 2022 10:03:34 +0100 Subject: [PATCH 0387/1564] fabrics: do not treat ctrl_loss_tmo values of '-1' as invalid '-1' is perfectly valid for ctrl_loss_tmo as it indicates an infinite timeout. Signed-off-by: Hannes Reinecke --- src/nvme/fabrics.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 97bb0b37d3..bc249b3630 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -222,6 +222,22 @@ static int add_int_argument(char **argstr, char *tok, int arg, bool allow_zero) return 0; } +static int add_int_or_minus_one_argument(char **argstr, char *tok, int arg) +{ + char *nstr; + + if (arg < -1) + return 0; + if (asprintf(&nstr, "%s,%s=%d", *argstr, tok, arg) < 0) { + errno = ENOMEM; + return -1; + } + free(*argstr); + *argstr = nstr; + + return 0; +} + static int add_argument(char **argstr, const char *tok, const char *arg) { char *nstr; @@ -413,9 +429,6 @@ static int build_options(nvme_host_t h, nvme_ctrl_t c, char **argstr) nvme_msg(LOG_ERR, "need a address (-a) argument\n"); return -ENVME_CONNECT_AARG; } - /* Use the default ctrl loss timeout if unset */ - if (cfg->ctrl_loss_tmo == -1) - cfg->ctrl_loss_tmo = NVMF_DEF_CTRL_LOSS_TMO; } /* always specify nqn as first arg - this will init the string */ @@ -467,8 +480,8 @@ static int build_options(nvme_host_t h, nvme_ctrl_t c, char **argstr) add_int_argument(argstr, "reconnect_delay", cfg->reconnect_delay, false) || (strcmp(transport, "loop") && - add_int_argument(argstr, "ctrl_loss_tmo", - cfg->ctrl_loss_tmo, false)) || + add_int_or_minus_one_argument(argstr, "ctrl_loss_tmo", + cfg->ctrl_loss_tmo)) || (strcmp(transport, "loop") && add_int_argument(argstr, "fast_io_fail_tmo", cfg->fast_io_fail_tmo, false)) || From a90705bea783e0089b12b9426f383beadaa7df94 Mon Sep 17 00:00:00 2001 From: Steven Seungcheol Lee Date: Mon, 17 Jan 2022 15:27:34 +0900 Subject: [PATCH 0388/1564] meson: ssl version checking allowed version only >=1.1.0 & <2.0.0 or >=3.0.0 For lower version of ssl or 2.x, config will be below define CONFIG_OPENSSL undef CONFIG_OPENSSL_1 undef CONFIG_OPENSSL_3 so function nvme_gen_dhchap_key is not defined in c file Signed-off-by: Steven Seungcheol Lee --- meson.build | 1 + 1 file changed, 1 insertion(+) diff --git a/meson.build b/meson.build index 6e25e47346..6b7fa49329 100644 --- a/meson.build +++ b/meson.build @@ -45,6 +45,7 @@ conf.set('CONFIG_JSONC', json_c_dep.found(), description: 'Is json-c required?') # Check for OpenSSL availability openssl_dep = dependency('openssl', + version: '>=1.1.0', required: get_option('openssl'), fallback : ['openssl', 'openssl_dep']) if openssl_dep.found() From 9948c634da8afab91013683f1fa4e14425ca50a2 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Tue, 18 Jan 2022 09:10:11 +0100 Subject: [PATCH 0389/1564] linux: Include missing stddef.h The header is not self contained because nvme_get_ana_log_len() is using the size_t type. Signed-off-by: Daniel Wagner --- src/nvme/linux.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/nvme/linux.h b/src/nvme/linux.h index 82b1a1e80f..d609a140ad 100644 --- a/src/nvme/linux.h +++ b/src/nvme/linux.h @@ -9,6 +9,8 @@ #ifndef _LIBNVME_LINUX_H #define _LIBNVME_LINUX_H +#include + #include "types.h" /** From 563cc590d57b311627d3a526b6414b0b80662579 Mon Sep 17 00:00:00 2001 From: Steven Seungcheol Lee Date: Wed, 19 Jan 2022 11:47:18 +0900 Subject: [PATCH 0390/1564] util: modify flbas rsvd bits to be used flbas Bits 6:5 indicate the most significant 2 bits of the Format Index of the supported LBA Format indicated in this data structure that was used to format the namespace Signed-off-by: Steven Seungcheol Lee --- doc/libnvme.rst | 10 ++++++---- doc/man/enum nvme_id_ns_flbas.2 | 18 +++++++++++++----- src/nvme/linux.c | 4 ++-- src/nvme/tree.c | 4 ++-- src/nvme/types.h | 25 ++++++++++++++++--------- src/nvme/util.h | 6 ++++++ test/test.c | 4 +++- 7 files changed, 48 insertions(+), 23 deletions(-) diff --git a/doc/libnvme.rst b/doc/libnvme.rst index 3f347dbb02..7d44e9eacf 100644 --- a/doc/libnvme.rst +++ b/doc/libnvme.rst @@ -7745,9 +7745,9 @@ Returns true if given offset is 64bit register, otherwise it returns false. **Constants** -``NVME_NS_FLBAS_LBA_MASK`` - Mask to get the index of one of the 16 supported - LBA Formats indicated in :c:type:`struct nvme_id_ns `.lbaf. +``NVME_NS_FLBAS_LOWER_MASK`` + Mask to get the index of one of the supported LBA Formats's least significant + 4bits indicated in :c:type:`struct nvme_id_ns `.lbaf. ``NVME_NS_FLBAS_META_EXT`` Applicable only if format contains metadata. If @@ -7757,7 +7757,9 @@ Returns true if given offset is 64bit register, otherwise it returns false. 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 the supported LBA Formats's most significant + 2bits indicated in :c:type:`struct nvme_id_ns `.lbaf. .. c:type:: enum nvme_id_ns_mc diff --git a/doc/man/enum nvme_id_ns_flbas.2 b/doc/man/enum nvme_id_ns_flbas.2 index 080d2ee274..37444a858e 100644 --- a/doc/man/enum nvme_id_ns_flbas.2 +++ b/doc/man/enum nvme_id_ns_flbas.2 @@ -4,17 +4,21 @@ enum nvme_id_ns_flbas \- This field indicates the LBA data size & metadata size .SH SYNOPSIS enum nvme_id_ns_flbas { .br -.BI " NVME_NS_FLBAS_LBA_MASK" +.BI " NVME_NS_FLBAS_LOWER_MASK" , .br .br .BI " NVME_NS_FLBAS_META_EXT" - +, +.br +.br +.BI " NVME_NS_FLBAS_HIGHER_MASK" }; .SH Constants -.IP "NVME_NS_FLBAS_LBA_MASK" 12 -Mask to get the index of one of the 16 supported -LBA Formats indicated in \fIstruct nvme_id_ns\fP.lbaf. +.IP "NVME_NS_FLBAS_LOWER_MASK" 12 +Mask to get the index of one of the supported LBA Formats's +least significant 4bits indicated in \fIstruct nvme_id_ns\fP.lbaf. + .IP "NVME_NS_FLBAS_META_EXT" 12 Applicable only if format contains metadata. If this bit is set, indicates that the metadata is @@ -22,3 +26,7 @@ transferred at the end of the data LBA, creating an extended data LBA. If cleared, indicates that all of the metadata for a command is transferred as a separate contiguous buffer of data. + +.IP "NVME_NS_FLBAS_HIGHER_MASK" 12 +Mask to get the index of one of the supported LBA Formats's +most significant 2bits indicated in \fIstruct nvme_id_ns\fP.lbaf. \ No newline at end of file diff --git a/src/nvme/linux.c b/src/nvme/linux.c index 747d69b2ae..b6f86b7d3f 100644 --- a/src/nvme/linux.c +++ b/src/nvme/linux.c @@ -337,14 +337,14 @@ int nvme_get_ana_log_len(int fd, size_t *analen) int nvme_get_logical_block_size(int fd, __u32 nsid, int *blksize) { struct nvme_id_ns ns; - int flbas; + __u8 flbas; int ret; ret = nvme_identify_ns(fd, nsid, &ns); if (ret) return ret; - flbas = ns.flbas & NVME_NS_FLBAS_LBA_MASK; + nvme_id_ns_flbas_to_lbaf_inuse(ns.flbas, &flbas); *blksize = 1 << ns.lbaf[flbas].ds; return 0; diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 583632ead9..15520f05c5 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -1670,14 +1670,14 @@ static int nvme_ns_init(struct nvme_ns *n) struct nvme_id_ns ns = { }; uint8_t buffer[NVME_IDENTIFY_DATA_SIZE] = { }; struct nvme_ns_id_desc *descs = (void *)buffer; - int flbas; + uint8_t flbas; int ret; ret = nvme_ns_identify(n, &ns); if (ret) return ret; - flbas = ns.flbas & NVME_NS_FLBAS_LBA_MASK; + nvme_id_ns_flbas_to_lbaf_inuse(ns.flbas, &flbas); n->lba_shift = ns.lbaf[flbas].ds; n->lba_size = 1 << n->lba_shift; n->lba_count = le64_to_cpu(ns.nsze); diff --git a/src/nvme/types.h b/src/nvme/types.h index 35fc37ff94..d7bb8eb596 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -1700,18 +1700,25 @@ 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 - * @NVME_NS_FLBAS_LBA_MASK: Mask to get the index of one of the 16 supported - * LBA Formats indicated in &struct nvme_id_ns.lbaf. - * @NVME_NS_FLBAS_META_EXT: Applicable only if format contains metadata. If - * this bit is set, indicates that the metadata is - * transferred at the end of the data LBA, creating an - * 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_LOWER_MASK: Mask to get the index of one of the supported + * LBA Formats's least significant + * 4bits indicated in + * :c:type:`struct nvme_id_ns `.lbaf. + * @NVME_NS_FLBAS_META_EXT: Applicable only if format contains metadata. If + * this bit is set, indicates that the metadata is + * transferred at the end of the data LBA, creating an + * 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 + * the supported LBA Formats's most significant + * 2bits indicated in + * :c:type:`struct nvme_id_ns `.lbaf. */ enum nvme_id_ns_flbas { - NVME_NS_FLBAS_LBA_MASK = 15 << 0, + NVME_NS_FLBAS_LOWER_MASK = 15 << 0, NVME_NS_FLBAS_META_EXT = 1 << 4, + NVME_NS_FLBAS_HIGHER_MASK = 3 << 5, }; /** diff --git a/src/nvme/util.h b/src/nvme/util.h index d55307fa81..98af82c927 100644 --- a/src/nvme/util.h +++ b/src/nvme/util.h @@ -363,4 +363,10 @@ static inline void nvme_feature_decode_namespace_write_protect(__u32 value, { *wps = NVME_FEAT_WP_WPS(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)); +} #endif /* _LIBNVME_UTIL_H */ diff --git a/test/test.c b/test/test.c index 34d7c7da59..4419746d6d 100644 --- a/test/test.c +++ b/test/test.c @@ -267,13 +267,15 @@ static int test_namespace(nvme_ns_t n) struct nvme_id_ns ns = { 0 }, allocated = { 0 }; struct nvme_ns_id_desc descs = { 0 }; __u32 result = 0; + __u8 flbas; ret = nvme_ns_identify(n, &ns); if (ret) return ret; + nvme_id_ns_flbas_to_lbaf_inuse(ns.flbas, &flbas); printf("%s: nsze:%lx lba size:%d\n", nvme_ns_get_name(n), le64_to_cpu(ns.nsze), - 1 << ns.lbaf[ns.flbas & NVME_NS_FLBAS_LBA_MASK].ds); + 1 << ns.lbaf[flbas].ds); ret = nvme_identify_allocated_ns(fd, nsid, &allocated); if (!ret) From 781b9105cc43b0f144cf05141e79852306f4b655 Mon Sep 17 00:00:00 2001 From: Arunpandian J Date: Wed, 19 Jan 2022 18:14:34 +0530 Subject: [PATCH 0391/1564] nvme: Add Media Unit Status log page(LID: 0x10) Reviewed-by: Steven Seungcheol Lee Signed-off-by: Arunpandian J --- doc/libnvme.rst | 3 +++ doc/man/enum nvme_cmd_get_log_lid.2 | 6 +++++ src/nvme/ioctl.h | 36 ++++++++++++++++++++++++++ src/nvme/types.h | 40 +++++++++++++++++++++++++++++ 4 files changed, 85 insertions(+) diff --git a/doc/libnvme.rst b/doc/libnvme.rst index 7d44e9eacf..7f10748cfd 100644 --- a/doc/libnvme.rst +++ b/doc/libnvme.rst @@ -921,6 +921,9 @@ otherwise. ``NVME_LOG_LID_ENDURANCE_GRP_EVT`` *undescribed* +``NVME_LOG_LID_MEDIA_UNIT_STATUS`` + *undescribed* + ``NVME_LOG_LID_DISCOVER`` *undescribed* diff --git a/doc/man/enum nvme_cmd_get_log_lid.2 b/doc/man/enum nvme_cmd_get_log_lid.2 index e292734115..f799074ccc 100644 --- a/doc/man/enum nvme_cmd_get_log_lid.2 +++ b/doc/man/enum nvme_cmd_get_log_lid.2 @@ -64,6 +64,10 @@ enum nvme_cmd_get_log_lid { , .br .br +.BI " NVME_LOG_LID_MEDIA_UNIT_STATUS" +, +.br +.br .BI " NVME_LOG_LID_DISCOVER" , .br @@ -106,6 +110,8 @@ enum nvme_cmd_get_log_lid { -- undescribed -- .IP "NVME_LOG_LID_ENDURANCE_GRP_EVT" 12 -- undescribed -- +.IP "NVME_LOG_LID_MEDIA_UNIT_STATUS" 12 +-- undescribed -- .IP "NVME_LOG_LID_DISCOVER" 12 -- undescribed -- .IP "NVME_LOG_LID_RESERVATION" 12 diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 84e7e3c42a..16b5501ed3 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -1124,6 +1124,7 @@ static inline int nvme_zns_identify_ctrl(int fd, struct nvme_zns_id_ctrl *id) * @csi: Command set identifier, see &enum nvme_csi for known values * @lsp: Log specific field * @lsi: Endurance group information + * @domid: Domain Identifier selection, if supported * @uuidx: UUID selection, if supported * @rae: Retain asynchronous events * @ot: Offset Type; if set @lpo specifies the index into the list @@ -1143,6 +1144,7 @@ struct nvme_get_log_args { enum nvme_csi csi; __u16 lsi; __u8 lsp; + __u16 domid; __u8 uuidx; bool rae; bool ot; @@ -1174,6 +1176,7 @@ static inline int nvme_get_nsid_log(int fd, bool rae, .csi = NVME_CSI_NVM, .lsi = NVME_LOG_LSI_NONE, .lsp = NVME_LOG_LSP_NONE, + .domid = NVME_DOMID_NONE, .uuidx = NVME_UUID_NONE, .rae = false, .ot = false, @@ -1741,6 +1744,39 @@ static inline int nvme_get_log_discovery(int fd, bool rae, } +/** + * nvme_get_log_media_unit_stat() - + * @fd: File descriptor of nvme device + * @domid: Domain Identifier selection, if supported + * + * 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_media_unit_stat(int fd, __u16 domid, + struct nvme_media_unit_stat_log *mus) +{ + struct nvme_get_log_args args = { + .args_size = sizeof(args), + .fd = fd, + .result = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .lid = NVME_LOG_LID_MEDIA_UNIT_STATUS, + .lpo = 0, + .log = mus, + .len = sizeof(*mus), + .nsid = NVME_NSID_NONE, + .csi = NVME_CSI_NVM, + .lsi = NVME_LOG_LSI_NONE, + .lsp = NVME_LOG_LSP_NONE, + .domid = domid, + .uuidx = NVME_UUID_NONE, + .rae = false, + .ot = false, + }; + return nvme_get_log(&args); +} + + /** * nvme_get_log_reservation() - * @fd: File descriptor of nvme device diff --git a/src/nvme/types.h b/src/nvme/types.h index b2bd99b54f..95bf818e94 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -3281,6 +3281,44 @@ struct nvme_boot_partition { __u8 boot_partition_data[]; }; +/** + * struct nvme_media_unit_stat_desc - + * @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 + * @percent_used: Percentage Used + * @mucs: Number of Channels attached to media units + * @cio: Channel Identifiers Offset + */ +struct nvme_media_unit_stat_desc { + __le16 muid; + __le16 domainid; + __le16 endgid; + __le16 nvmsetid; + __le16 cap_adj_fctr; + __u8 avl_spare; + __u8 percent_used; + __u8 mucs; + __u8 cio; +}; + +/** + * struct nvme_media_unit_stat_log - + * @nmu: Number unit status descriptor + * @cchans: Number of Channels + * @sel_config: Selected Configuration + */ +struct nvme_media_unit_stat_log { + __le16 nmu; + __le16 cchans; + __le16 sel_config; + __u8 rsvd6[10]; + struct nvme_media_unit_stat_desc mus_desc[]; +}; + /** * struct nvme_resv_notification_log - * @lpc: @@ -5346,6 +5384,7 @@ enum nvme_identify_cns { * @NVME_LOG_LID_PERSISTENT_EVENT: * @NVME_LOG_LID_LBA_STATUS: * @NVME_LOG_LID_ENDURANCE_GRP_EVT: + * @NVME_LOG_LID_MEDIA_UNIT_STATUS: * @NVME_LOG_LID_FID_SUPPORTED_EFFECTS: * @NVME_LOG_LID_BOOT_PARTITION: * @NVME_LOG_LID_DISCOVER: @@ -5370,6 +5409,7 @@ enum nvme_cmd_get_log_lid { NVME_LOG_LID_PERSISTENT_EVENT = 0x0d, NVME_LOG_LID_LBA_STATUS = 0x0e, NVME_LOG_LID_ENDURANCE_GRP_EVT = 0x0f, + NVME_LOG_LID_MEDIA_UNIT_STATUS = 0x10, NVME_LOG_LID_FID_SUPPORTED_EFFECTS = 0x12, NVME_LOG_LID_BOOT_PARTITION = 0x15, NVME_LOG_LID_DISCOVER = 0x70, From 0827e06298aea2c6d969419066359e33e6815a48 Mon Sep 17 00:00:00 2001 From: Martin Belanger Date: Tue, 18 Jan 2022 11:14:14 -0500 Subject: [PATCH 0392/1564] Define ccan as a static library ccan gets built as a static library, which gets linked to libnvme.so. Signed-off-by: Martin Belanger --- ccan/meson.build | 12 ++++++++++-- examples/meson.build | 1 - internal/meson.build | 21 +++++++++++++++++++++ libnvme/meson.build | 9 ++------- meson.build | 13 +++++++++---- src/meson.build | 3 ++- 6 files changed, 44 insertions(+), 15 deletions(-) create mode 100644 internal/meson.build diff --git a/ccan/meson.build b/ccan/meson.build index 05d10c9d03..a77240acb7 100644 --- a/ccan/meson.build +++ b/ccan/meson.build @@ -6,13 +6,21 @@ # Authors: Martin Belanger # -sources += files([ +sources = [ 'ccan/list/list.c', 'ccan/str/debug.c', 'ccan/str/str.c', -]) +] if get_option('buildtype') == 'debug' add_project_arguments('-DCCAN_LIST_DEBUG=1', language : ['c', 'cpp']) add_project_arguments('-DCCAN_STR_DEBUG=1', language : ['c', 'cpp']) endif + +libccan = static_library( + 'ccan', + sources, + install: false, + include_directories: [incdir, internal_incdir], + dependencies: config_dep, +) diff --git a/examples/meson.build b/examples/meson.build index 92e05a9a55..6b6286eaac 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -25,4 +25,3 @@ executable( link_with: libnvme, include_directories: [incdir, internal_incdir] ) - diff --git a/internal/meson.build b/internal/meson.build new file mode 100644 index 0000000000..fde4ccac35 --- /dev/null +++ b/internal/meson.build @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# This file is part of libnvme. +# Copyright (c) 2022 Dell Inc. +# +# Authors: Martin Belanger +# +# Because libnvme is used as a subproject of nvme-cli, +# the config.h file must be generated as a private file +# hidden from nvme-cli. + +config_h = configure_file( + output: 'config.h', + configuration: conf +) + +internal_incdir = include_directories('.') + +config_dep = declare_dependency( + include_directories : internal_incdir, + sources: config_h) diff --git a/libnvme/meson.build b/libnvme/meson.build index 284c408fe5..e077fe68d2 100644 --- a/libnvme/meson.build +++ b/libnvme/meson.build @@ -5,11 +5,6 @@ # # Authors: Martin Belanger # -configure_file( - output: 'config.h', - configuration: conf -) - want_python = get_option('python') if want_python != 'false' python3 = import('python').find_installation('python3') @@ -35,8 +30,8 @@ if have_python_support '_nvme', pymod_swig[1], dependencies : py3_dep, - include_directories: incdir, - link_with: libnvme, + include_directories: [incdir, internal_incdir], + link_with: [libnvme, libccan], install: true, subdir: 'libnvme', ) diff --git a/meson.build b/meson.build index 6b7fa49329..02cc4fb8e4 100644 --- a/meson.build +++ b/meson.build @@ -150,13 +150,18 @@ configure_file( ) ################################################################################ -add_project_arguments(['-fomit-frame-pointer', '-D_GNU_SOURCE', - '-include', 'libnvme/config.h'], language : 'c') +add_project_arguments( + [ + '-fomit-frame-pointer', + '-D_GNU_SOURCE', + '-include', 'internal/config.h', + ], + language : 'c', +) incdir = include_directories(['.', 'ccan', 'src']) -internal_incdir = include_directories('libnvme') ################################################################################ -sources = [] +subdir('internal') subdir('ccan') subdir('src') subdir('libnvme') diff --git a/src/meson.build b/src/meson.build index 4f78f63e7d..caab9174bc 100644 --- a/src/meson.build +++ b/src/meson.build @@ -5,7 +5,7 @@ # # Authors: Martin Belanger # -sources += [ +sources = [ 'nvme/cleanup.c', 'nvme/fabrics.c', 'nvme/filters.c', @@ -39,6 +39,7 @@ libnvme = library( link_depends: mapfile, include_directories: [incdir, internal_incdir], install: true, + link_with: libccan, ) pkg = import('pkgconfig') From 3acfca080de3877d95615448f0ea809c3c8e83bd Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Wed, 19 Jan 2022 15:54:50 +0100 Subject: [PATCH 0393/1564] src: Use PRIu64 format specifier for uint64 types When compiling for 32bit architectures the compiler is complaining about the wrong format specifier for uint64. Use the the PRIu64 format specifier in this case which is supported from 32bit and 64bit. Signed-off-by: Daniel Wagner --- examples/display-columnar.c | 5 +++-- src/nvme/fabrics.c | 5 +++-- test/test.c | 8 +++++--- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/examples/display-columnar.c b/examples/display-columnar.c index a2a2938e11..db98bdfec8 100644 --- a/examples/display-columnar.c +++ b/examples/display-columnar.c @@ -11,6 +11,7 @@ * column format for easy visual scanning. */ #include +#include #include static const char dash[101] = {[0 ... 99] = '-'}; @@ -90,7 +91,7 @@ int main() nvme_for_each_subsystem(h, s) { nvme_subsystem_for_each_ctrl(s, c) { nvme_ctrl_for_each_ns(c, n) - printf("%-12s %-8d %-16lu %-8d %s\n", + printf("%-12s %-8d %-16" PRIu64 " %-8d %s\n", nvme_ns_get_name(n), nvme_ns_get_nsid(n), nvme_ns_get_lba_count(n), @@ -101,7 +102,7 @@ int main() nvme_subsystem_for_each_ns(s, n) { bool first = true; - printf("%-12s %-8d %-16lu %-8d ", + printf("%-12s %-8d %-16" PRIu64 " %-8d ", nvme_ns_get_name(n), nvme_ns_get_nsid(n), nvme_ns_get_lba_count(n), diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 97bb0b37d3..171c70fabf 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -778,7 +779,7 @@ int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, } genctr = le64_to_cpu(log->genctr); - nvme_msg(LOG_DEBUG, "%s: discover genctr %lu, retry\n", + nvme_msg(LOG_DEBUG, "%s: discover genctr %" PRIu64 ", retry\n", name, genctr); ret = nvme_discovery_log(nvme_ctrl_get_fd(c), hdr, log, true); if (ret) { @@ -795,7 +796,7 @@ int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, errno = EAGAIN; ret = -1; } else if (numrec != le64_to_cpu(log->numrec)) { - nvme_msg(LOG_INFO, "%s: could only fetch %lu of %lu records\n", + nvme_msg(LOG_INFO, "%s: could only fetch %" PRIu64 " of %" PRIu64 " records\n", name, numrec, le64_to_cpu(log->numrec)); errno = EBADSLT; ret = -1; diff --git a/test/test.c b/test/test.c index 4419746d6d..c50e96d4e6 100644 --- a/test/test.c +++ b/test/test.c @@ -18,6 +18,7 @@ #include #include #include +#include #ifdef CONFIG_LIBUUID #include #endif @@ -274,7 +275,8 @@ static int test_namespace(nvme_ns_t n) return ret; nvme_id_ns_flbas_to_lbaf_inuse(ns.flbas, &flbas); - printf("%s: nsze:%lx lba size:%d\n", nvme_ns_get_name(n), le64_to_cpu(ns.nsze), + printf("%s: nsze:%" PRIu64 " lba size:%d\n", + nvme_ns_get_name(n), le64_to_cpu(ns.nsze), 1 << ns.lbaf[flbas].ds); ret = nvme_identify_allocated_ns(fd, nsid, &allocated); @@ -367,7 +369,7 @@ int main(int argc, char **argv) char uuid_str[40]; uuid_t uuid; #endif - printf(" `- %s lba size:%d lba max:%lu\n", + printf(" `- %s lba size:%d lba max:%" PRIu64 "\n", nvme_ns_get_name(n), nvme_ns_get_lba_size(n), nvme_ns_get_lba_count(n)); @@ -390,7 +392,7 @@ int main(int argc, char **argv) } nvme_subsystem_for_each_ns(s, n) { - printf(" `- %s lba size:%d lba max:%lu\n", + printf(" `- %s lba size:%d lba max:%" PRIu64 "\n", nvme_ns_get_name(n), nvme_ns_get_lba_size(n), nvme_ns_get_lba_count(n)); From 3962a453a8bef1b59c1842824955d3c885a5dea8 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 20 Jan 2022 15:39:48 +0100 Subject: [PATCH 0394/1564] fabrics: add fabrics config option 'tls' Add an option 'tls' to the fabrics config to start TLS encryption on the connection. Signed-off-by: Hannes Reinecke --- doc/config-schema.json | 5 +++++ src/nvme/fabrics.c | 10 +++++++++- src/nvme/fabrics.h | 2 ++ src/nvme/json.c | 3 +++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/doc/config-schema.json b/doc/config-schema.json index 2eda3af7ab..3240d9b8a2 100644 --- a/doc/config-schema.json +++ b/doc/config-schema.json @@ -140,6 +140,11 @@ "type": "boolean", "default": false }, + "tls": { + "description": "Enable TLS encryption", + "type": "boolean", + "default": false + }, "persistent": { "description": "Create persistent discovery connection", "type": "boolean" diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index e966e31770..1e7d1a1f28 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -187,6 +187,7 @@ static struct nvme_fabrics_config *merge_config(nvme_ctrl_t c, UPDATE_CFG_OPTION(ctrl_cfg, cfg, disable_sqflow, false); UPDATE_CFG_OPTION(ctrl_cfg, cfg, hdr_digest, false); UPDATE_CFG_OPTION(ctrl_cfg, cfg, data_digest, false); + UPDATE_CFG_OPTION(ctrl_cfg, cfg, tls, false); return ctrl_cfg; } @@ -495,7 +496,9 @@ static int build_options(nvme_host_t h, nvme_ctrl_t c, char **argstr) (!strcmp(transport, "tcp") && add_bool_argument(argstr, "hdr_digest", cfg->hdr_digest)) || (!strcmp(transport, "tcp") && - add_bool_argument(argstr, "data_digest", cfg->data_digest))) { + add_bool_argument(argstr, "data_digest", cfg->data_digest)) || + (!strcmp(transport, "tcp") && + add_bool_argument(argstr, "tls", cfg->tls))) { free(*argstr); return -1; } @@ -708,6 +711,11 @@ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, if (e->treq & NVMF_TREQ_DISABLE_SQFLOW) disable_sqflow = true; + if (e->trtype == NVMF_TRTYPE_TCP && + (e->treq & NVMF_TREQ_REQUIRED || + e->treq & NVMF_TREQ_NOT_REQUIRED)) + c->cfg.tls = true; + ret = nvmf_add_ctrl(h, c, cfg, disable_sqflow); if (!ret) return c; diff --git a/src/nvme/fabrics.h b/src/nvme/fabrics.h index 0309c978ef..eb7ede73e1 100644 --- a/src/nvme/fabrics.h +++ b/src/nvme/fabrics.h @@ -33,6 +33,7 @@ * @disable_sqflow: Disable controller sq flow control * @hdr_digest: Generate/verify header digest (TCP) * @data_digest: Generate/verify data digest (TCP) + * @tls: Start TLS on the connection (TCP) */ struct nvme_fabrics_config { char *host_traddr; @@ -51,6 +52,7 @@ struct nvme_fabrics_config { bool disable_sqflow; bool hdr_digest; bool data_digest; + bool tls; }; /** diff --git a/src/nvme/json.c b/src/nvme/json.c index e93b7a30ae..3f5fe881a4 100644 --- a/src/nvme/json.c +++ b/src/nvme/json.c @@ -62,6 +62,8 @@ static void json_update_attributes(nvme_ctrl_t c, hdr_digest, val_obj); JSON_UPDATE_BOOL_OPTION(cfg, key_str, data_digest, val_obj); + JSON_UPDATE_BOOL_OPTION(cfg, key_str, + tls, val_obj); if (!strcmp("persistent", key_str) && !nvme_ctrl_is_persistent(c)) nvme_ctrl_set_persistent(c, true); @@ -220,6 +222,7 @@ static void json_update_port(struct json_object *ctrl_array, nvme_ctrl_t c) JSON_BOOL_OPTION(cfg, port_obj, disable_sqflow); JSON_BOOL_OPTION(cfg, port_obj, hdr_digest); JSON_BOOL_OPTION(cfg, port_obj, data_digest); + JSON_BOOL_OPTION(cfg, port_obj, tls); if (nvme_ctrl_is_persistent(c)) json_object_add_value_bool(port_obj, "persistent", true); if (nvme_ctrl_is_discovery_ctrl(c)) From cb32a9020ca18a39ca4f756776f32a5b1a95acf9 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Fri, 21 Jan 2022 10:39:53 +0100 Subject: [PATCH 0395/1564] ioctl: Initialize all members in nvme_get_log_args MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 781b9105cc43 ("nvme: Add Media Unit Status log page(LID: 0x10)") introduces a new member in nvme_get_log_args. Older compilers are not happy when we don't initialize all members in the inline functions. In file included from ../subprojects/libnvme/src/libnvme.h:19:0, from ../subprojects/libnvme/test/cpp.cc:10: ../subprojects/libnvme/src/nvme/ioctl.h: In function ‘int nvme_get_log_cmd_effects(int, nvme_csi, nvme_cmd_effects_log*)’: ../subprojects/libnvme/src/nvme/ioctl.h:1328:2: sorry, unimplemented: non-trivial designated initializers not supported }; Signed-off-by: Daniel Wagner --- src/nvme/ioctl.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 16b5501ed3..23738aa8f2 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -1322,6 +1322,7 @@ static inline int nvme_get_log_cmd_effects(int fd, enum nvme_csi csi, .csi = csi, .lsi = NVME_LOG_LSI_NONE, .lsp = NVME_LOG_LSP_NONE, + .domid = NVME_DOMID_NONE, .uuidx = NVME_UUID_NONE, .rae = false, .ot = false, @@ -1369,6 +1370,7 @@ static inline int nvme_get_log_create_telemetry_host(int fd, .csi = NVME_CSI_NVM, .lsi = NVME_LOG_LSI_NONE, .lsp = NVME_LOG_TELEM_HOST_LSP_CREATE, + .domid = NVME_DOMID_NONE, .uuidx = NVME_UUID_NONE, .rae = false, .ot = false, @@ -1406,6 +1408,7 @@ static inline int nvme_get_log_telemetry_host(int fd, __u64 offset, .csi = NVME_CSI_NVM, .lsi = NVME_LOG_LSI_NONE, .lsp = NVME_LOG_TELEM_HOST_LSP_RETAIN, + .domid = NVME_DOMID_NONE, .uuidx = NVME_UUID_NONE, .rae = false, .ot = false, @@ -1437,6 +1440,7 @@ static inline int nvme_get_log_telemetry_ctrl(int fd, bool rae, .csi = NVME_CSI_NVM, .lsi = NVME_LOG_LSI_NONE, .lsp = NVME_LOG_LSP_NONE, + .domid = NVME_DOMID_NONE, .uuidx = NVME_UUID_NONE, .rae = rae, .ot = false, @@ -1476,6 +1480,7 @@ static inline int nvme_get_log_endurance_group(int fd, __u16 endgid, .csi = NVME_CSI_NVM, .lsi = endgid, .lsp = NVME_LOG_LSP_NONE, + .domid = NVME_DOMID_NONE, .uuidx = NVME_UUID_NONE, .rae = false, .ot = false, @@ -1507,6 +1512,7 @@ static inline int nvme_get_log_predictable_lat_nvmset(int fd, __u16 nvmsetid, .csi = NVME_CSI_NVM, .lsi = nvmsetid, .lsp = NVME_LOG_LSP_NONE, + .domid = NVME_DOMID_NONE, .uuidx = NVME_UUID_NONE, .rae = false, .ot = false, @@ -1535,6 +1541,7 @@ static inline int nvme_get_log_predictable_lat_event(int fd, bool rae, .csi = NVME_CSI_NVM, .lsi = NVME_LOG_LSI_NONE, .lsp = NVME_LOG_LSP_NONE, + .domid = NVME_DOMID_NONE, .uuidx = NVME_UUID_NONE, .rae = rae, .ot = false, @@ -1575,6 +1582,7 @@ static int nvme_get_log_ana(int fd, enum nvme_log_ana_lsp lsp, bool rae, .csi = NVME_CSI_NVM, .lsi = NVME_LOG_LSI_NONE, .lsp = lsp, + .domid = NVME_DOMID_NONE, .uuidx = NVME_UUID_NONE, .rae = false, .ot = false, @@ -1619,6 +1627,7 @@ static inline int nvme_get_log_lba_status(int fd, bool rae, .csi = NVME_CSI_NVM, .lsi = NVME_LOG_LSI_NONE, .lsp = NVME_LOG_LSP_NONE, + .domid = NVME_DOMID_NONE, .uuidx = NVME_UUID_NONE, .rae = rae, .ot = false, @@ -1647,6 +1656,7 @@ static inline int nvme_get_log_endurance_grp_evt(int fd, bool rae, .csi = NVME_CSI_NVM, .lsi = NVME_LOG_LSI_NONE, .lsp = NVME_LOG_LSP_NONE, + .domid = NVME_DOMID_NONE, .uuidx = NVME_UUID_NONE, .rae = rae, .ot = false, @@ -1698,6 +1708,7 @@ static inline int nvme_get_log_boot_partition(int fd, bool rae, .csi = NVME_CSI_NVM, .lsi = NVME_LOG_LSI_NONE, .lsp = NVME_LOG_LSP_NONE, + .domid = NVME_DOMID_NONE, .uuidx = NVME_UUID_NONE, .rae = rae, .ot = false, @@ -1736,6 +1747,7 @@ static inline int nvme_get_log_discovery(int fd, bool rae, .csi = NVME_CSI_NVM, .lsi = NVME_LOG_LSI_NONE, .lsp = NVME_LOG_LSP_NONE, + .domid = NVME_DOMID_NONE, .uuidx = NVME_UUID_NONE, .rae = rae, .ot = false, @@ -1838,6 +1850,7 @@ static inline int nvme_get_log_zns_changed_zones(int fd, __u32 nsid, bool rae, .csi = NVME_CSI_ZNS, .lsi = NVME_LOG_LSI_NONE, .lsp = NVME_LOG_LSP_NONE, + .domid = NVME_DOMID_NONE, .uuidx = NVME_UUID_NONE, .rae = rae, .ot = false, @@ -1870,6 +1883,7 @@ static inline int nvme_get_log_persistent_event(int fd, .csi = NVME_CSI_NVM, .lsi = NVME_LOG_LSI_NONE, .lsp = NVME_LOG_LSP_NONE, + .domid = NVME_DOMID_NONE, .uuidx = NVME_UUID_NONE, .rae = false, .ot = false, From 3c9fa45f3d7838fcbe5db8f8847995ac6fa7613f Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 21 Jan 2022 12:53:51 +0100 Subject: [PATCH 0396/1564] tree: only open controller device node if required Opening the controller device will fail if the controller is resetting, so trying to open it during controller initialisation will fail, and the controller will not displayed correctly. So only try to open the controller device if required, allowing the initialisation to continue. Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 15520f05c5..c22d99e689 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -630,6 +630,12 @@ static int nvme_ctrl_scan_path(struct nvme_ctrl *c, char *name) int nvme_ctrl_get_fd(nvme_ctrl_t c) { + if (c->fd < 0) { + c->fd = nvme_open(c->name); + if (c->fd < 0) + nvme_msg(LOG_ERR, "Failed to open ctrl %s, errno %d\n", + c->name, errno); + } return c->fd; } @@ -1106,15 +1112,14 @@ static int nvme_configure_ctrl(nvme_ctrl_t c, const char *path, d = opendir(path); if (!d) { + nvme_msg(LOG_ERR, "Failed to open ctrl dir %s, error %d\n", + path, errno); errno = ENODEV; return -1; } closedir(d); - c->fd = nvme_open(name); - if (c->fd < 0) - return c->fd; - + c->fd = -1; c->name = strdup(name); c->sysfs_dir = (char *)path; c->firmware = nvme_get_ctrl_attr(c, "firmware_rev"); From 0f318817024c5de79ecb68871a1df3191a387c1f Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 21 Jan 2022 13:47:20 +0100 Subject: [PATCH 0397/1564] fabrics: kill 'disable_sqflow' argument to nvmf_add_ctrl() The 'disable_sqflow' argument to nvmf_add_ctrl() is pointless, as 'struct fabrics_config' is exported and the caller can set it directly there, without having to involve library functions at all. And consequently we can also remove nvme_ctrl_disable_sqflow(). Signed-off-by: Hannes Reinecke --- examples/discover-loop.c | 2 +- libnvme/nvme.i | 2 +- src/nvme/fabrics.c | 15 ++++++--------- src/nvme/fabrics.h | 18 ++++++++++-------- src/nvme/tree.c | 7 ------- src/nvme/tree.h | 9 --------- 6 files changed, 18 insertions(+), 35 deletions(-) diff --git a/examples/discover-loop.c b/examples/discover-loop.c index b28edfa0df..3f8176278e 100644 --- a/examples/discover-loop.c +++ b/examples/discover-loop.c @@ -69,7 +69,7 @@ int main() fprintf(stderr, "Failed to allocate memory\n"); return ENOMEM; } - ret = nvmf_add_ctrl(h, c, &cfg, false); + ret = nvmf_add_ctrl(h, c, &cfg); if (ret < 0) { fprintf(stderr, "no controller found\n"); return errno; diff --git a/libnvme/nvme.i b/libnvme/nvme.i index 25d7ac2575..2c856476fd 100644 --- a/libnvme/nvme.i +++ b/libnvme/nvme.i @@ -535,7 +535,7 @@ struct nvme_ns { connect_err = 1; return; } - ret = nvmf_add_ctrl(h, $self, cfg, cfg->disable_sqflow); + ret = nvmf_add_ctrl(h, $self, cfg); if (ret < 0) { connect_err = 2; return; diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 1e7d1a1f28..4d1b48e786 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -587,14 +587,12 @@ int nvmf_add_ctrl_opts(nvme_ctrl_t c, struct nvme_fabrics_config *cfg) } int nvmf_add_ctrl(nvme_host_t h, nvme_ctrl_t c, - const struct nvme_fabrics_config *cfg, - bool disable_sqflow) + const struct nvme_fabrics_config *cfg) { char *argstr; int ret; cfg = merge_config(c, cfg); - nvme_ctrl_disable_sqflow(c, disable_sqflow); nvme_ctrl_set_discovered(c, true); if (traddr_is_hostname(c)) { ret = hostname2traddr(c); @@ -627,7 +625,6 @@ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, const char *transport; char *traddr = NULL, *trsvcid = NULL; nvme_ctrl_t c; - bool disable_sqflow = false; int ret; switch (e->trtype) { @@ -709,24 +706,24 @@ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, } if (e->treq & NVMF_TREQ_DISABLE_SQFLOW) - disable_sqflow = true; + c->cfg.disable_sqflow = true; if (e->trtype == NVMF_TRTYPE_TCP && (e->treq & NVMF_TREQ_REQUIRED || e->treq & NVMF_TREQ_NOT_REQUIRED)) c->cfg.tls = true; - ret = nvmf_add_ctrl(h, c, cfg, disable_sqflow); + ret = nvmf_add_ctrl(h, c, cfg); if (!ret) return c; - if (errno == EINVAL && disable_sqflow) { + if (errno == EINVAL && c->cfg.disable_sqflow) { errno = 0; /* disable_sqflow is unrecognized option on older kernels */ nvme_msg(LOG_INFO, "failed to connect controller, " "retry with disabling SQ flow control\n"); - disable_sqflow = false; - ret = nvmf_add_ctrl(h, c, cfg, disable_sqflow); + c->cfg.disable_sqflow = false; + ret = nvmf_add_ctrl(h, c, cfg); if (!ret) return c; } diff --git a/src/nvme/fabrics.h b/src/nvme/fabrics.h index eb7ede73e1..0475ee7a1e 100644 --- a/src/nvme/fabrics.h +++ b/src/nvme/fabrics.h @@ -160,17 +160,19 @@ void nvmf_default_config(struct nvme_fabrics_config *cfg); int nvmf_add_ctrl_opts(nvme_ctrl_t c, struct nvme_fabrics_config *cfg); /** - * nvmf_add_ctrl() - - * @h: - * @c: - * @cfg: - * @disable_sqflow: + * nvmf_add_ctrl() - Connect a controller and update topology + * @h: Host to which the controller should be attached + * @c: Controller to be connected + * @cfg: Default configuration for the controller * - * Return: + * Issues a 'connect' command to the NVMe-oF controller and inserts @c + * into the topology using @h as parent. + * @c must be initialized and not connected to the topology. + * + * Return: 0 on success; on failure errno is set and -1 is returned. */ int nvmf_add_ctrl(nvme_host_t h, nvme_ctrl_t c, - const struct nvme_fabrics_config *cfg, - bool disable_sqflow); + const struct nvme_fabrics_config *cfg); /** * nvmf_get_discovery_log() - diff --git a/src/nvme/tree.c b/src/nvme/tree.c index c22d99e689..6fc3810c64 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -749,13 +749,6 @@ void nvme_ctrl_set_dhchap_key(nvme_ctrl_t c, const char *key) c->dhchap_key = strdup(key); } -void nvme_ctrl_disable_sqflow(nvme_ctrl_t c, bool disable_sqflow) -{ - c->cfg.disable_sqflow = disable_sqflow; - if (c->s && c->s->h && c->s->h->r) - c->s->h->r->modified = true; -} - void nvme_ctrl_set_discovered(nvme_ctrl_t c, bool discovered) { c->discovered = discovered; diff --git a/src/nvme/tree.h b/src/nvme/tree.h index 06500ea45a..f886ecbb19 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -873,15 +873,6 @@ void nvme_ctrl_set_discovery_ctrl(nvme_ctrl_t c, bool discovery); */ bool nvme_ctrl_is_discovery_ctrl(nvme_ctrl_t c); -/** - * nvme_ctrl_disable_sqflow() - - * @c: - * @disable_sqflow: - * - * Return: - */ -void nvme_ctrl_disable_sqflow(nvme_ctrl_t c, bool disable_sqflow); - /** * nvme_ctrl_identify() - * @c: From b97d8b36266aa7ab94d87270be928055b8abaffb Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 21 Jan 2022 17:13:20 +0100 Subject: [PATCH 0398/1564] fabrics: Remove nvmf_add_ctrl_opts() Unused, and nvmf_add_ctrl() is doing exactly the same. Signed-off-by: Hannes Reinecke --- src/nvme/fabrics.c | 33 --------------------------------- src/nvme/fabrics.h | 9 --------- 2 files changed, 42 deletions(-) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 4d1b48e786..e0e992ce94 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -553,39 +553,6 @@ static int __nvmf_add_ctrl(const char *argstr) return ret; } -int nvmf_add_ctrl_opts(nvme_ctrl_t c, struct nvme_fabrics_config *cfg) -{ - nvme_subsystem_t s = nvme_ctrl_get_subsystem(c); - nvme_host_t h = nvme_subsystem_get_host(s); - char *argstr; - int ret; - - cfg = merge_config(c, cfg); - if (traddr_is_hostname(c)) { - ret = hostname2traddr(c); - if (ret) { - errno = -ret; - return -1; - } - } - - ret = build_options(h, c, &argstr); - if (ret) { - errno = -ret; - return -1; - } - - ret = __nvmf_add_ctrl(argstr); - free(argstr); - if (ret < 0) { - errno = -ret; - ret = -1; - } else { - nvme_msg(LOG_INFO, "nvme%d: ctrl connected\n", ret); - } - return ret; -} - int nvmf_add_ctrl(nvme_host_t h, nvme_ctrl_t c, const struct nvme_fabrics_config *cfg) { diff --git a/src/nvme/fabrics.h b/src/nvme/fabrics.h index 0475ee7a1e..785191d1b3 100644 --- a/src/nvme/fabrics.h +++ b/src/nvme/fabrics.h @@ -150,15 +150,6 @@ const char *nvmf_cms_str(__u8 cms); */ void nvmf_default_config(struct nvme_fabrics_config *cfg); -/** - * nvmf_add_ctrl_opts() - - * @c: - * @cfg: - * - * Return: - */ -int nvmf_add_ctrl_opts(nvme_ctrl_t c, struct nvme_fabrics_config *cfg); - /** * nvmf_add_ctrl() - Connect a controller and update topology * @h: Host to which the controller should be attached From c95ae8a0e9d4251dc2b140f2a95626b32121da5e Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 21 Jan 2022 17:28:00 +0100 Subject: [PATCH 0399/1564] fabrics: Update prototype documentation Fill out missing bits in the function prototyp documentation. Signed-off-by: Hannes Reinecke --- src/nvme/fabrics.h | 60 +++++++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 24 deletions(-) diff --git a/src/nvme/fabrics.h b/src/nvme/fabrics.h index 785191d1b3..d47277dc0c 100644 --- a/src/nvme/fabrics.h +++ b/src/nvme/fabrics.h @@ -111,34 +111,46 @@ const char *nvmf_treq_str(__u8 treq); const char *nvmf_eflags_str(__u16 eflags); /** - * nvmf_sectype_str() - - * @sectype: + * nvmf_sectype_str() - Decode SECTYPE field + * @sectype: value to be decoded * - * Return: + * Decode the SECTYPE field in the discovery log page + * entry. + * + * Return: decoded string */ const char *nvmf_sectype_str(__u8 sectype); /** - * nvmf_prtype_str() - - * @prtype: + * nvmf_prtype_str() - Decode RDMA Provider type field + * @prtype: value to be decoded * - * Return: + * Decode the RDMA Provider type field in the discovery + * log page entry. + * + * Return: decoded string */ const char *nvmf_prtype_str(__u8 prtype); /** - * nvmf_qptype_str() - - * @qptype: + * nvmf_qptype_str() - Decode RDMA QP Service type field + * @qptype: value to be decoded * - * Return: + * Decode the RDMA QP Service type field in the discovery log page + * entry. + * + * Return: decoded string */ const char *nvmf_qptype_str(__u8 qptype); /** - * nvmf_cms_str() - - * @cms: + * nvmf_cms_str() - Decode RDMA connection management service field + * @cms: value to be decoded * - * Return: + * Decode the RDMA connection management service field in the discovery + * log page entry. + * + * Return: decoded string */ const char *nvmf_cms_str(__u8 cms); @@ -166,12 +178,12 @@ int nvmf_add_ctrl(nvme_host_t h, nvme_ctrl_t c, const struct nvme_fabrics_config *cfg); /** - * nvmf_get_discovery_log() - - * @c: - * @logp: - * @max_retries: + * nvmf_get_discovery_log() - Return the discovery log page + * @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 * - * Return: + * Return: 0 on success; on failure -1 is returned and errno is set */ int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, int max_retries); @@ -200,13 +212,13 @@ char *nvmf_hostnqn_from_file(); char *nvmf_hostid_from_file(); /** - * nvmf_connect_disc_entry() - - * @h: - * @e: - * @defcfg: - * @discover: + * 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 + * @discover: Set to 'true' if the new controller is a discovery controller * - * Return: An + * Return: Pointer to the new controller */ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, struct nvmf_disc_log_entry *e, @@ -214,7 +226,7 @@ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, /** * nvme_chomp() - Strip trailing white space - * &s: String to strip + * @s: String to strip * @l: Maximum length of string */ static inline void nvme_chomp(char *s, int l) From 0c3978a2e5cbeff6d64ee2763b8f2ae2e19b341b Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 21 Jan 2022 17:42:21 +0100 Subject: [PATCH 0400/1564] fabrics: remove documentation for nvmf_add_ctrl_opts() function is gone, no need for the documentation. Signed-off-by: Hannes Reinecke --- doc/man/nvmf_add_ctrl_opts.2 | 9 --------- src/libnvme.map | 1 - 2 files changed, 10 deletions(-) delete mode 100644 doc/man/nvmf_add_ctrl_opts.2 diff --git a/doc/man/nvmf_add_ctrl_opts.2 b/doc/man/nvmf_add_ctrl_opts.2 deleted file mode 100644 index 00094fc0e4..0000000000 --- a/doc/man/nvmf_add_ctrl_opts.2 +++ /dev/null @@ -1,9 +0,0 @@ -.TH "nvmf_add_ctrl_opts" 2 "nvmf_add_ctrl_opts" "February 2020" "libnvme Manual" -.SH NAME -nvmf_add_ctrl_opts \- -.SH SYNOPSIS -.B "int" nvmf_add_ctrl_opts -.BI "(struct nvme_fabrics_config *" cfg ");" -.SH ARGUMENTS -.IP "cfg" 12 --- undescribed -- diff --git a/src/libnvme.map b/src/libnvme.map index 81b8d52ed8..c71274b3cf 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -312,7 +312,6 @@ LIBNVME_1_0 { nvme_zns_mgmt_send; nvme_zns_report_zones; nvmf_add_ctrl; - nvmf_add_ctrl_opts; nvmf_adrfam_str; nvmf_cms_str; nvmf_connect_disc_entry; From 20cc76c7fe24c2e01518f01e4272b5d6d5184f7e Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 28 Jan 2022 11:44:59 +0100 Subject: [PATCH 0401/1564] Update README.md Add documentation on how to build a static library. --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 0b1d2bbb30..56657a4338 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,12 @@ To `configure` the project: meson .build ``` +Which will default to build a shared library. To configure for static libraries call + +``` +meson .build --default-library=static +``` + One nice feature of meson is that it doesn't mix build artifacts (e.g. `*.o`, `*.so`, etc.) with source code. In the above example, "`.build`" is the name of the directory where the build configuration From 909a13f899ef462ed30f2d02485b8fe2669494e2 Mon Sep 17 00:00:00 2001 From: Arunpandian J Date: Fri, 28 Jan 2022 17:19:32 +0530 Subject: [PATCH 0402/1564] Clean up Patch for types.h, ioctl.h Signed-off-by: Arunpandian J --- src/nvme/ioctl.h | 18 +----------------- src/nvme/types.h | 1 + 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 23738aa8f2..0dca0e3b21 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -1227,7 +1227,6 @@ static inline int nvme_get_log_error(int fd, unsigned nr_entries, bool rae, NVME_NSID_ALL, sizeof(*log) * nr_entries, log); } - /** * nvme_get_log_smart() - Retrieve nvme smart log * @fd: File descriptor of nvme device @@ -1272,7 +1271,6 @@ static inline int nvme_get_log_fw_slot(int fd, bool rae, NVME_NSID_ALL, sizeof(*log), log); } - /** * nvme_get_log_changed_ns_list() - Retrieve namespace changed list * @fd: File descriptor of nvme device @@ -1293,7 +1291,6 @@ static inline int nvme_get_log_changed_ns_list(int fd, bool rae, NVME_NSID_ALL, sizeof(*log), log); } - /** * nvme_get_log_cmd_effects() - Retrieve nvme command effects log * @fd: File descriptor of nvme device @@ -1350,7 +1347,6 @@ static inline int nvme_get_log_device_self_test(int fd, NVME_NSID_ALL, sizeof(*log), log); } - /** * nvme_get_log_create_telemetry_host() - */ @@ -1378,7 +1374,6 @@ static inline int nvme_get_log_create_telemetry_host(int fd, return nvme_get_log(&args); } - /** * nvme_get_log_telemetry_host() - * @fd: File descriptor of nvme device @@ -1590,7 +1585,6 @@ static int nvme_get_log_ana(int fd, enum nvme_log_ana_lsp lsp, bool rae, return nvme_get_log(&args); } - /** * nvme_get_log_ana_groups() - * @fd: File descriptor of nvme device @@ -1605,7 +1599,6 @@ static inline int nvme_get_log_ana_groups(int fd, bool rae, __u32 len, len, log); } - /** * nvme_get_log_lba_status() - * @fd: File descriptor of nvme device @@ -1680,7 +1673,6 @@ static inline int nvme_get_log_fid_supported_effects(int fd, bool rae, NVME_NSID_NONE, sizeof(*log), log); } - /** * nvme_get_log_boot_partition() - * @fd: File descriptor of nvme device @@ -1716,7 +1708,6 @@ static inline int nvme_get_log_boot_partition(int fd, bool rae, return nvme_get_log(&args); } - /** * nvme_get_log_discovery() - * @fd: File descriptor of nvme device @@ -1755,7 +1746,6 @@ static inline int nvme_get_log_discovery(int fd, bool rae, return nvme_get_log(&args); } - /** * nvme_get_log_media_unit_stat() - * @fd: File descriptor of nvme device @@ -1788,7 +1778,6 @@ static inline int nvme_get_log_media_unit_stat(int fd, __u16 domid, return nvme_get_log(&args); } - /** * nvme_get_log_reservation() - * @fd: File descriptor of nvme device @@ -1801,7 +1790,6 @@ static inline int nvme_get_log_reservation(int fd, bool rae, NVME_NSID_ALL, sizeof(*log), log); } - /** * nvme_get_log_sanitize() - * @fd: File descriptor of nvme device @@ -1821,7 +1809,6 @@ static inline int nvme_get_log_sanitize(int fd, bool rae, NVME_NSID_ALL, sizeof(*log), log); } - /** * nvme_get_log_zns_changed_zones() - * @fd: File descriptor of nvme device @@ -1858,7 +1845,6 @@ static inline int nvme_get_log_zns_changed_zones(int fd, __u32 nsid, bool rae, return nvme_get_log(&args); } - /** * nvme_get_log_persistent_event() - * @fd: File descriptor of nvme device @@ -1891,7 +1877,6 @@ static inline int nvme_get_log_persistent_event(int fd, return nvme_get_log(&args); } - /** * nvme_set_features_args - Arguments for the NVMe Admin Set Feature command * @fd: File descriptor of nvme device @@ -2229,7 +2214,6 @@ int nvme_set_features_endurance_evt_cfg(int fd, __u16 endgid, __u8 egwarn, int nvme_set_features_sw_progress(int fd, __u8 pbslc, bool save, __u32 *result); - /** * nvme_set_features_host_id() - * @fd: File descriptor of nvme device @@ -2376,6 +2360,7 @@ int nvme_get_features_power_mgmt(int fd, enum nvme_get_features_sel sel, int nvme_get_features_lba_range(int fd, enum nvme_get_features_sel sel, struct nvme_lba_range_type *data, __u32 *result); + /** * nvme_get_features_temp_thresh() - * @fd: File descriptor of nvme device @@ -3351,7 +3336,6 @@ static inline int nvme_directive_recv_stream_allocate(int fd, __u32 nsid, return nvme_directive_recv(&args); } - /** * nvme_capacity_mgmt_args - Arguments for the NVMe Capacity Management command * @fd: File descriptor of nvme device diff --git a/src/nvme/types.h b/src/nvme/types.h index 95bf818e94..e926180fd1 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -3923,6 +3923,7 @@ enum nvme_ae_type { NVME_AER_CSS = 6, NVME_AER_VS = 7, }; + /** * enum nvme_ae_info_error - * @NVME_AER_ERROR_INVALID_DB_REG: From 12a90e5075e66ba3c644622f8c0a65744480d2b1 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Fri, 28 Jan 2022 17:52:14 +0100 Subject: [PATCH 0403/1564] ioctl: Set errno when command args check fails In error the function is supposed to return -1 and set the errno accordingly. Signed-off-by: Daniel Wagner --- src/nvme/ioctl.c | 186 +++++++++++++++++++++++++++++++---------------- 1 file changed, 124 insertions(+), 62 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index eec702f107..88b0a1389e 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -385,8 +385,10 @@ int nvme_identify(struct nvme_identify_args *args) .timeout_ms = args->timeout, }; - if (args->args_size < sizeof(*args)) - return -EINVAL; + if (args->args_size < sizeof(*args)) { + errno = EINVAL; + return -1; + } return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } @@ -420,8 +422,10 @@ int nvme_get_log(struct nvme_get_log_args *args) .timeout_ms = args->timeout, }; - if (args->args_size < sizeof(struct nvme_get_log_args)) - return -EINVAL; + if (args->args_size < sizeof(struct nvme_get_log_args)) { + errno = EINVAL; + return -1; + } return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } @@ -443,8 +447,10 @@ int nvme_set_features(struct nvme_set_features_args *args) .cdw15 = args->cdw15, .timeout_ms = args->timeout, }; - if (args->args_size < sizeof(*args)) - return -EINVAL; + if (args->args_size < sizeof(*args)) { + errno = EINVAL; + return -1; + } return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } @@ -799,8 +805,10 @@ int nvme_get_features(struct nvme_get_features_args *args) .timeout_ms = args->timeout, }; - if (args->args_size < sizeof(*args)) - return -EINVAL; + if (args->args_size < sizeof(*args)) { + errno = EINVAL; + return -1; + } return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } @@ -1162,8 +1170,10 @@ int nvme_format_nvm(struct nvme_format_nvm_args *args) .timeout_ms = args->timeout, }; - if (args->args_size < sizeof(*args)) - return -EINVAL; + if (args->args_size < sizeof(*args)) { + errno = EINVAL; + return -1; + } return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } @@ -1183,8 +1193,10 @@ int nvme_ns_mgmt(struct nvme_ns_mgmt_args *args) .addr = (__u64)(uintptr_t)args->ns, }; - if (args->args_size < sizeof(*args)) - return -EINVAL; + if (args->args_size < sizeof(*args)) { + errno = EINVAL; + return -1; + } return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } @@ -1201,8 +1213,10 @@ int nvme_ns_attach(struct nvme_ns_attach_args *args) .timeout_ms = args->timeout, }; - if (args->args_size < sizeof(*args)) - return -EINVAL; + if (args->args_size < sizeof(*args)) { + errno = EINVAL; + return -1; + } return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } @@ -1220,8 +1234,10 @@ int nvme_fw_download(struct nvme_fw_download_args *args) .timeout_ms = args->timeout, }; - if (args->args_size < sizeof(*args)) - return -EINVAL; + if (args->args_size < sizeof(*args)) { + errno = EINVAL; + return -1; + } return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } @@ -1237,8 +1253,10 @@ int nvme_fw_commit(struct nvme_fw_commit_args *args) .timeout_ms = args->timeout, }; - if (args->args_size < sizeof(*args)) - return -EINVAL; + if (args->args_size < sizeof(*args)) { + errno = EINVAL; + return -1; + } return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } @@ -1260,8 +1278,10 @@ int nvme_security_send(struct nvme_security_send_args *args) .timeout_ms = args->timeout, }; - if (args->args_size < sizeof(*args)) - return -EINVAL; + if (args->args_size < sizeof(*args)) { + errno = EINVAL; + return -1; + } return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } @@ -1283,8 +1303,10 @@ int nvme_security_receive(struct nvme_security_receive_args *args) .timeout_ms = args->timeout, }; - if (args->args_size < sizeof(*args)) - return -EINVAL; + if (args->args_size < sizeof(*args)) { + errno = EINVAL; + return -1; + } return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } @@ -1307,8 +1329,10 @@ int nvme_get_lba_status(struct nvme_get_lba_status_args *args) .timeout_ms = args->timeout, }; - if (args->args_size < sizeof(*args)) - return -EINVAL; + if (args->args_size < sizeof(*args)) { + errno = EINVAL; + return -1; + } return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } @@ -1330,8 +1354,10 @@ int nvme_directive_send(struct nvme_directive_send_args *args) .timeout_ms = args->timeout, }; - if (args->args_size < sizeof(*args)) - return -EINVAL; + if (args->args_size < sizeof(*args)) { + errno = EINVAL; + return -1; + } return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } @@ -1376,8 +1402,10 @@ int nvme_directive_recv(struct nvme_directive_recv_args *args) .timeout_ms = args->timeout, }; - if (args->args_size < sizeof(*args)) - return -EINVAL; + if (args->args_size < sizeof(*args)) { + errno = EINVAL; + return -1; + } return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } @@ -1393,8 +1421,10 @@ int nvme_capacity_mgmt(struct nvme_capacity_mgmt_args *args) .timeout_ms = args->timeout, }; - if (args->args_size < sizeof(*args)) - return -EINVAL; + if (args->args_size < sizeof(*args)) { + errno = EINVAL; + return -1; + } return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } @@ -1412,8 +1442,10 @@ int nvme_lockdown(struct nvme_lockdown_args *args) .timeout_ms = args->timeout, }; - if (args->args_size < sizeof(*args)) - return -EINVAL; + if (args->args_size < sizeof(*args)) { + errno = EINVAL; + return -1; + } return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } @@ -1431,8 +1463,10 @@ int nvme_set_property(struct nvme_set_property_args *args) .timeout_ms = args->timeout, }; - if (args->args_size < sizeof(*args)) - return -EINVAL; + if (args->args_size < sizeof(*args)) { + errno = EINVAL; + return -1; + } return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } @@ -1448,8 +1482,10 @@ int nvme_get_property(struct nvme_get_property_args *args) .timeout_ms = args->timeout, }; - if (args->args_size < sizeof(*args)) - return -EINVAL; + if (args->args_size < sizeof(*args)) { + errno = EINVAL; + return -1; + } return nvme_submit_admin_passthru64(args->fd, &cmd, args->value); } @@ -1469,8 +1505,10 @@ int nvme_sanitize_nvm(struct nvme_sanitize_nvm_args *args) .timeout_ms = args->timeout, }; - if (args->args_size < sizeof(*args)) - return -EINVAL; + if (args->args_size < sizeof(*args)) { + errno = EINVAL; + return -1; + } return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } @@ -1485,8 +1523,10 @@ int nvme_dev_self_test(struct nvme_dev_self_test_args *args) .timeout_ms = args->timeout, }; - if (args->args_size < sizeof(*args)) - return -EINVAL; + if (args->args_size < sizeof(*args)) { + errno = EINVAL; + return -1; + } return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } @@ -1504,8 +1544,10 @@ int nvme_virtual_mgmt(struct nvme_virtual_mgmt_args *args) .timeout_ms = args->timeout, }; - if (args->args_size < sizeof(*args)) - return -EINVAL; + if (args->args_size < sizeof(*args)) { + errno = EINVAL; + return -1; + } return nvme_submit_admin_passthru(args->fd, &cmd, args->result); } @@ -1571,8 +1613,10 @@ int nvme_io(struct nvme_io_args *args, __u8 opcode) .timeout_ms = args->timeout, }; - if (args->args_size < sizeof(*args)) - return -EINVAL; + if (args->args_size < sizeof(*args)) { + errno = EINVAL; + return -1; + } return nvme_submit_io_passthru(args->fd, &cmd, args->result); } @@ -1588,8 +1632,10 @@ int nvme_dsm(struct nvme_dsm_args *args) .timeout_ms = args->timeout, }; - if (args->args_size < sizeof(*args)) - return -EINVAL; + if (args->args_size < sizeof(*args)) { + errno = EINVAL; + return -1; + } return nvme_submit_io_passthru(args->fd, &cmd, args->result); } @@ -1614,8 +1660,10 @@ int nvme_copy(struct nvme_copy_args *args) .timeout_ms = args->timeout, }; - if (args->args_size < sizeof(*args)) - return -EINVAL; + if (args->args_size < sizeof(*args)) { + errno = EINVAL; + return -1; + } return nvme_submit_io_passthru(args->fd, &cmd, args->result); } @@ -1638,8 +1686,10 @@ int nvme_resv_acquire(struct nvme_resv_acquire_args *args) .timeout_ms = args->timeout, }; - if (args->args_size < sizeof(*args)) - return -EINVAL; + if (args->args_size < sizeof(*args)) { + errno = EINVAL; + return -1; + } return nvme_submit_io_passthru(args->fd, &cmd, args->result); } @@ -1662,8 +1712,10 @@ int nvme_resv_register(struct nvme_resv_register_args *args) .timeout_ms = args->timeout, }; - if (args->args_size < sizeof(*args)) - return -EINVAL; + if (args->args_size < sizeof(*args)) { + errno = EINVAL; + return -1; + } return nvme_submit_io_passthru(args->fd, &cmd, args->result); } @@ -1683,8 +1735,10 @@ int nvme_resv_release(struct nvme_resv_release_args *args) .timeout_ms = args->timeout, }; - if (args->args_size < sizeof(*args)) - return -EINVAL; + if (args->args_size < sizeof(*args)) { + errno = EINVAL; + return -1; + } return nvme_submit_io_passthru(args->fd, &cmd, args->result); } @@ -1700,8 +1754,10 @@ int nvme_resv_report(struct nvme_resv_report_args *args) .timeout_ms = args->timeout, }; - if (args->args_size < sizeof(*args)) - return -EINVAL; + if (args->args_size < sizeof(*args)) { + errno = EINVAL; + return -1; + } return nvme_submit_io_passthru(args->fd, &cmd, args->result); } @@ -1724,8 +1780,10 @@ int nvme_zns_mgmt_send(struct nvme_zns_mgmt_send_args *args) .timeout_ms = args->timeout, }; - if (args->args_size < sizeof(*args)) - return -EINVAL; + if (args->args_size < sizeof(*args)) { + errno = EINVAL; + return -1; + } return nvme_submit_io_passthru(args->fd, &cmd, args->result); } @@ -1750,8 +1808,10 @@ int nvme_zns_mgmt_recv(struct nvme_zns_mgmt_recv_args *args) .timeout_ms = args->timeout, }; - if (args->args_size < sizeof(*args)) - return -EINVAL; + if (args->args_size < sizeof(*args)) { + errno = EINVAL; + return -1; + } return nvme_submit_io_passthru(args->fd, &cmd, args->result); } @@ -1778,7 +1838,9 @@ int nvme_zns_append(struct nvme_zns_append_args *args) .timeout_ms = args->timeout, }; - if (args->args_size < sizeof(*args)) - return -EINVAL; + if (args->args_size < sizeof(*args)) { + errno = EINVAL; + return -1; + } return nvme_submit_io_passthru64(args->fd, &cmd, args->result); } From efcb5ec7edba4fc3906d8c9c8f82b6dade7e431b Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Fri, 28 Jan 2022 17:58:40 +0100 Subject: [PATCH 0404/1564] util: Set errno in error case nvme_get_directive_receive_length The API says we return -1 in the error case and set the errno accordingly. Update nvme_get_directive_receive_length to fulfill the promise. Signed-off-by: Daniel Wagner --- src/nvme/util.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/nvme/util.c b/src/nvme/util.c index b3c762051a..50c2021a50 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -470,10 +470,12 @@ int nvme_get_directive_receive_length(enum nvme_directive_dtype dtype, *len = 0; return 0; default: - return -EINVAL; + errno = EINVAL; + return -1; } default: - return -EINVAL; + errno = EINVAL; + return -1; } } From 519e0f52a1df33d17d3c7cdc437788cd78154abb Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 28 Jan 2022 13:42:58 +0100 Subject: [PATCH 0405/1564] Merge hostname2traddr() For some reason we have two versions of hostname2traddr(). Signed-off-by: Hannes Reinecke --- src/nvme/fabrics.c | 53 ++++++---------------------------------------- src/nvme/tree.c | 47 ++-------------------------------------- src/nvme/util.c | 48 ++++++++++++++++++++++++++++++++++++++++- src/nvme/util.h | 2 ++ 4 files changed, 58 insertions(+), 92 deletions(-) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index e0e992ce94..bb900020f3 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -371,49 +371,6 @@ static bool traddr_is_hostname(nvme_ctrl_t c) return true; } -static int hostname2traddr(nvme_ctrl_t c) -{ - struct addrinfo *host_info, hints = {.ai_family = AF_UNSPEC}; - char addrstr[NVMF_TRADDR_SIZE]; - const char *p; - int ret; - - ret = getaddrinfo(c->traddr, NULL, &hints, &host_info); - if (ret) { - nvme_msg(LOG_ERR, "failed to resolve host %s info\n", c->traddr); - return -ENVME_CONNECT_RESOLVE; - } - - switch (host_info->ai_family) { - case AF_INET: - p = inet_ntop(host_info->ai_family, - &(((struct sockaddr_in *)host_info->ai_addr)->sin_addr), - addrstr, NVMF_TRADDR_SIZE); - break; - case AF_INET6: - p = inet_ntop(host_info->ai_family, - &(((struct sockaddr_in6 *)host_info->ai_addr)->sin6_addr), - addrstr, NVMF_TRADDR_SIZE); - break; - default: - nvme_msg(LOG_ERR, "unrecognized address family (%d) %s\n", - host_info->ai_family, c->traddr); - ret = -ENVME_CONNECT_ADDRFAM; - goto free_addrinfo; - } - - if (!p) { - nvme_msg(LOG_ERR, "failed to get traddr for %s\n", c->traddr); - ret = -ENVME_CONNECT_TRADDR; - goto free_addrinfo; - } - c->traddr = strdup(addrstr); - -free_addrinfo: - freeaddrinfo(host_info); - return ret; -} - static int build_options(nvme_host_t h, nvme_ctrl_t c, char **argstr) { struct nvme_fabrics_config *cfg = nvme_ctrl_get_config(c); @@ -562,11 +519,15 @@ int nvmf_add_ctrl(nvme_host_t h, nvme_ctrl_t c, cfg = merge_config(c, cfg); nvme_ctrl_set_discovered(c, true); if (traddr_is_hostname(c)) { - ret = hostname2traddr(c); - if (ret) { - errno = -ret; + const char *traddr = c->traddr; + + c->traddr = hostname2traddr(traddr); + if (!c->traddr) { + c->traddr = (char *)traddr; + errno = ENVME_CONNECT_TRADDR; return -1; } + free(c->traddr); } ret = build_options(h, c, &argstr); diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 6fc3810c64..de7af7ac91 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -904,49 +904,6 @@ static bool traddr_is_hostname(const char *transport, const char *traddr) return true; } -void hostname2traddr(nvme_ctrl_t c, const char *host_traddr) -{ - struct addrinfo *host_info, hints = {.ai_family = AF_UNSPEC}; - char addrstr[NVMF_TRADDR_SIZE]; - const char *p; - int ret; - - ret = getaddrinfo(host_traddr, NULL, &hints, &host_info); - if (ret) { - nvme_msg(LOG_DEBUG, "failed to resolve host %s info\n", - host_traddr); - c->cfg.host_traddr = strdup(host_traddr); - return; - } - - switch (host_info->ai_family) { - case AF_INET: - p = inet_ntop(host_info->ai_family, - &(((struct sockaddr_in *)host_info->ai_addr)->sin_addr), - addrstr, NVMF_TRADDR_SIZE); - break; - case AF_INET6: - p = inet_ntop(host_info->ai_family, - &(((struct sockaddr_in6 *)host_info->ai_addr)->sin6_addr), - addrstr, NVMF_TRADDR_SIZE); - break; - default: - nvme_msg(LOG_DEBUG, "unrecognized address family (%d) %s\n", - host_info->ai_family, c->traddr); - c->cfg.host_traddr = strdup(host_traddr); - goto free_addrinfo; - } - if (!p) { - nvme_msg(LOG_DEBUG, "failed to get traddr for %s\n", - c->traddr); - c->cfg.host_traddr = strdup(host_traddr); - } else - c->cfg.host_traddr = strdup(addrstr); - -free_addrinfo: - freeaddrinfo(host_info); -} - struct nvme_ctrl *nvme_create_ctrl(const char *subsysnqn, const char *transport, const char *traddr, const char *host_traddr, const char *host_iface, const char *trsvcid) @@ -987,8 +944,8 @@ struct nvme_ctrl *nvme_create_ctrl(const char *subsysnqn, const char *transport, c->traddr = strdup(traddr); if (host_traddr) { if (traddr_is_hostname(transport, host_traddr)) - hostname2traddr(c, host_traddr); - else + c->cfg.host_traddr = hostname2traddr(host_traddr); + if (!c->cfg.host_traddr) c->cfg.host_traddr = strdup(host_traddr); } if (host_iface) diff --git a/src/nvme/util.c b/src/nvme/util.c index 50c2021a50..14b543ae66 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -11,11 +11,13 @@ #include #include +#include +#include #include #include "util.h" - +#include "log.h" static inline __u8 nvme_generic_status_to_errno(__u16 status) { switch (status) { @@ -500,3 +502,47 @@ const char *nvme_errno_to_string(int status) return s; } + +char *hostname2traddr(const char *traddr) +{ + struct addrinfo *host_info, hints = {.ai_family = AF_UNSPEC}; + char addrstr[NVMF_TRADDR_SIZE]; + const char *p; + char *ret_traddr = NULL; + int ret; + + ret = getaddrinfo(traddr, NULL, &hints, &host_info); + if (ret) { + nvme_msg(LOG_ERR, "failed to resolve host %s info\n", + traddr); + return NULL; + } + + switch (host_info->ai_family) { + case AF_INET: + p = inet_ntop(host_info->ai_family, + &(((struct sockaddr_in *)host_info->ai_addr)->sin_addr), + addrstr, NVMF_TRADDR_SIZE); + break; + case AF_INET6: + p = inet_ntop(host_info->ai_family, + &(((struct sockaddr_in6 *)host_info->ai_addr)->sin6_addr), + addrstr, NVMF_TRADDR_SIZE); + break; + default: + nvme_msg(LOG_ERR, "unrecognized address family (%d) %s\n", + host_info->ai_family, traddr); + goto free_addrinfo; + } + + if (!p) { + nvme_msg(LOG_ERR, "failed to get traddr for %s\n", + traddr); + goto free_addrinfo; + } + ret_traddr = strdup(addrstr); + +free_addrinfo: + freeaddrinfo(host_info); + return ret_traddr; +} diff --git a/src/nvme/util.h b/src/nvme/util.h index 783024251e..bec933964f 100644 --- a/src/nvme/util.h +++ b/src/nvme/util.h @@ -391,4 +391,6 @@ 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)); } + +char *hostname2traddr(const char *traddr); #endif /* _LIBNVME_UTIL_H */ From 24ac082f481d8a168a8ac6f5498bd6d246c61ea3 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 28 Jan 2022 14:18:25 +0100 Subject: [PATCH 0406/1564] Add 'nvme_root_t' argument to nvme_msg() Add a 'nvme_root_t' argument to nvme_msg() to allow for error messages to be redirected to a different filedescriptor than 'stderr'. Signed-off-by: Hannes Reinecke --- examples/discover-loop.c | 2 +- libnvme/nvme.i | 4 +- src/nvme/fabrics.c | 92 +++++++++++++++-------------- src/nvme/json.c | 4 +- src/nvme/linux.c | 44 +++++--------- src/nvme/log.c | 9 ++- src/nvme/log.h | 8 +-- src/nvme/private.h | 1 + src/nvme/tree.c | 122 ++++++++++++++++++++++----------------- src/nvme/tree.h | 42 +++++++++----- src/nvme/util.c | 11 ++-- src/nvme/util.h | 4 +- test/test.c | 2 +- 13 files changed, 188 insertions(+), 157 deletions(-) diff --git a/examples/discover-loop.c b/examples/discover-loop.c index 3f8176278e..a577cd403a 100644 --- a/examples/discover-loop.c +++ b/examples/discover-loop.c @@ -63,7 +63,7 @@ int main() fprintf(stderr, "Failed to allocated memory\n"); return ENOMEM; } - c = nvme_create_ctrl(NVME_DISC_SUBSYS_NAME, "loop", + c = nvme_create_ctrl(r, NVME_DISC_SUBSYS_NAME, "loop", NULL, NULL, NULL, NULL); if (!c) { fprintf(stderr, "Failed to allocate memory\n"); diff --git a/libnvme/nvme.i b/libnvme/nvme.i index 2c856476fd..ec78ffb8b6 100644 --- a/libnvme/nvme.i +++ b/libnvme/nvme.i @@ -508,10 +508,10 @@ struct nvme_ns { } %extend nvme_ctrl { - nvme_ctrl(const char *subsysnqn, const char *transport, + nvme_ctrl(nvme_root_t r, const char *subsysnqn, const char *transport, const char *traddr = NULL, const char *host_traddr = NULL, const char *host_iface = NULL, const char *trsvcid = NULL) { - return nvme_create_ctrl(subsysnqn, transport, traddr, + return nvme_create_ctrl(r, subsysnqn, transport, traddr, host_traddr, host_iface, trsvcid); } ~nvme_ctrl() { diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index bb900020f3..945bac6049 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -273,7 +273,7 @@ static int inet4_pton(const char *src, uint16_t port, return 0; } -static int inet6_pton(const char *src, uint16_t port, +static int inet6_pton(nvme_root_t r, const char *src, uint16_t port, struct sockaddr_storage *addr) { int ret = -EINVAL; @@ -284,7 +284,7 @@ static int inet6_pton(const char *src, uint16_t port, char *tmp = strdup(src); if (!tmp) - nvme_msg(LOG_ERR, "cannot copy: %s\n", src); + nvme_msg(r, LOG_ERR, "cannot copy: %s\n", src); const char *scope = NULL; char *p = strchr(tmp, SCOPE_DELIMITER); @@ -299,7 +299,7 @@ static int inet6_pton(const char *src, uint16_t port, if (IN6_IS_ADDR_LINKLOCAL(&addr6->sin6_addr) && scope) { addr6->sin6_scope_id = if_nametoindex(scope); if (addr6->sin6_scope_id == 0) { - nvme_msg(LOG_ERR, + nvme_msg(r, LOG_ERR, "can't find iface index for: %s (%m)\n", scope); goto free_tmp; } @@ -322,7 +322,8 @@ static int inet6_pton(const char *src, uint16_t port, * * Return 0 on success, errno otherwise. */ -static int inet_pton_with_scope(int af, const char *src, const char * trsvcid, +static int inet_pton_with_scope(nvme_root_t r, int af, + const char *src, const char * trsvcid, struct sockaddr_storage *addr) { int ret = -EINVAL; @@ -332,7 +333,8 @@ static int inet_pton_with_scope(int af, const char *src, const char * trsvcid, unsigned long long tmp = strtoull(trsvcid, NULL, 0); port = (uint16_t)tmp; if (tmp != port) { - nvme_msg(LOG_ERR, "trsvcid out of range: %s\n", trsvcid); + nvme_msg(r, LOG_ERR, "trsvcid out of range: %s\n", + trsvcid); return -ERANGE; } } else { @@ -344,21 +346,21 @@ static int inet_pton_with_scope(int af, const char *src, const char * trsvcid, ret = inet4_pton(src, port, addr); break; case AF_INET6: - ret = inet6_pton(src, port, addr); + ret = inet6_pton(r, src, port, addr); break; case AF_UNSPEC: ret = inet4_pton(src, port, addr); if (ret) - ret = inet6_pton(src, port, addr); + ret = inet6_pton(r, src, port, addr); break; default: - nvme_msg(LOG_ERR, "unexpected address family %d\n", af); + nvme_msg(r, LOG_ERR, "unexpected address family %d\n", af); } return ret; } -static bool traddr_is_hostname(nvme_ctrl_t c) +static bool traddr_is_hostname(nvme_root_t r, nvme_ctrl_t c) { struct sockaddr_storage addr; @@ -366,7 +368,7 @@ static bool traddr_is_hostname(nvme_ctrl_t c) return false; if (strcmp(c->transport, "tcp") && strcmp(c->transport, "rdma")) return false; - if (inet_pton_with_scope(AF_UNSPEC, c->traddr, c->trsvcid, &addr) == 0) + if (inet_pton_with_scope(r, AF_UNSPEC, c->traddr, c->trsvcid, &addr) == 0) return false; return true; } @@ -379,13 +381,13 @@ static int build_options(nvme_host_t h, nvme_ctrl_t c, char **argstr) bool discover = false, discovery_nqn = false; if (!transport) { - nvme_msg(LOG_ERR, "need a transport (-t) argument\n"); + nvme_msg(h->r, LOG_ERR, "need a transport (-t) argument\n"); return -ENVME_CONNECT_TARG; } if (strncmp(transport, "loop", 4)) { if (!nvme_ctrl_get_traddr(c)) { - nvme_msg(LOG_ERR, "need a address (-a) argument\n"); + nvme_msg(h->r, LOG_ERR, "need a address (-a) argument\n"); return -ENVME_CONNECT_AARG; } } @@ -463,23 +465,23 @@ static int build_options(nvme_host_t h, nvme_ctrl_t c, char **argstr) return 0; } -static int __nvmf_add_ctrl(const char *argstr) +static int __nvmf_add_ctrl(nvme_root_t r, const char *argstr) { int ret, fd, len = strlen(argstr); char buf[0x1000], *options, *p; fd = open(nvmf_dev, O_RDWR); if (fd < 0) { - nvme_msg(LOG_ERR, "Failed to open %s: %s\n", + nvme_msg(r, LOG_ERR, "Failed to open %s: %s\n", nvmf_dev, strerror(errno)); return -ENVME_CONNECT_OPEN; } - nvme_msg(LOG_DEBUG, "connect ctrl, '%.*s'\n", + nvme_msg(r, LOG_DEBUG, "connect ctrl, '%.*s'\n", (int)strcspn(argstr,"\n"), argstr); ret = write(fd, argstr, len); if (ret != len) { - nvme_msg(LOG_NOTICE, "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; goto out_close; @@ -487,12 +489,12 @@ static int __nvmf_add_ctrl(const char *argstr) len = read(fd, buf, sizeof(buf)); if (len < 0) { - nvme_msg(LOG_ERR, "Failed to read from %s: %s\n", + nvme_msg(r, LOG_ERR, "Failed to read from %s: %s\n", nvmf_dev, strerror(errno)); ret = -ENVME_CONNECT_READ; goto out_close; } - nvme_msg(LOG_DEBUG, "connect ctrl, response '%.*s'\n", + nvme_msg(r, LOG_DEBUG, "connect ctrl, response '%.*s'\n", (int)strcspn(buf, "\n"), buf); buf[len] = '\0'; options = buf; @@ -503,7 +505,7 @@ static int __nvmf_add_ctrl(const char *argstr) goto out_close; } - nvme_msg(LOG_ERR, "Failed to parse ctrl info for \"%s\"\n", argstr); + nvme_msg(r, LOG_ERR, "Failed to parse ctrl info for \"%s\"\n", argstr); ret = -ENVME_CONNECT_PARSE; out_close: close(fd); @@ -518,10 +520,10 @@ int nvmf_add_ctrl(nvme_host_t h, nvme_ctrl_t c, cfg = merge_config(c, cfg); nvme_ctrl_set_discovered(c, true); - if (traddr_is_hostname(c)) { + if (traddr_is_hostname(h->r, c)) { const char *traddr = c->traddr; - c->traddr = hostname2traddr(traddr); + c->traddr = hostname2traddr(h->r, traddr); if (!c->traddr) { c->traddr = (char *)traddr; errno = ENVME_CONNECT_TRADDR; @@ -534,14 +536,14 @@ int nvmf_add_ctrl(nvme_host_t h, nvme_ctrl_t c, if (ret) return ret; - ret = __nvmf_add_ctrl(argstr); + ret = __nvmf_add_ctrl(h->r, argstr); free(argstr); if (ret < 0) { errno = -ret; return -1; } - nvme_msg(LOG_INFO, "nvme%d: ctrl connected\n", ret); + nvme_msg(h->r, LOG_INFO, "nvme%d: ctrl connected\n", ret); return nvme_init_ctrl(h, c, ret); } @@ -567,7 +569,8 @@ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, trsvcid = e->trsvcid; break; default: - nvme_msg(LOG_ERR, "skipping unsupported adrfam %d\n", + nvme_msg(h->r, LOG_ERR, + "skipping unsupported adrfam %d\n", e->adrfam); errno = EINVAL; return NULL; @@ -581,7 +584,8 @@ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, trsvcid = NULL; break; default: - nvme_msg(LOG_ERR, "skipping unsupported adrfam %d\n", + nvme_msg(h->r, LOG_ERR, + "skipping unsupported adrfam %d\n", e->adrfam); errno = EINVAL; return NULL; @@ -589,7 +593,7 @@ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, case NVMF_TRTYPE_LOOP: break; default: - nvme_msg(LOG_ERR, "skipping unsupported transport %d\n", + nvme_msg(h->r, LOG_ERR, "skipping unsupported transport %d\n", e->trtype); errno = EINVAL; return NULL; @@ -597,13 +601,13 @@ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, transport = nvmf_trtype_str(e->trtype); - nvme_msg(LOG_DEBUG, "lookup ctrl " + nvme_msg(h->r, LOG_DEBUG, "lookup ctrl " "(transport: %s, traddr: %s, trsvcid %s)\n", transport, traddr, trsvcid); - c = nvme_create_ctrl(e->subnqn, transport, traddr, + c = nvme_create_ctrl(h->r, e->subnqn, transport, traddr, cfg->host_traddr, cfg->host_iface, trsvcid); if (!c) { - nvme_msg(LOG_DEBUG, "skipping discovery entry, " + nvme_msg(h->r, LOG_DEBUG, "skipping discovery entry, " "failed to allocate %s controller with traddr %s\n", transport, traddr); errno = ENOMEM; @@ -620,7 +624,7 @@ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, nvme_ctrl_set_discovery_ctrl(c, true); break; default: - nvme_msg(LOG_ERR, "unsupported subtype %d\n", + nvme_msg(h->r, LOG_ERR, "unsupported subtype %d\n", e->subtype); /* fallthrough */ case NVME_NQN_NVME: @@ -648,14 +652,15 @@ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, if (errno == EINVAL && c->cfg.disable_sqflow) { errno = 0; /* disable_sqflow is unrecognized option on older kernels */ - nvme_msg(LOG_INFO, "failed to connect controller, " + nvme_msg(h->r, LOG_INFO, "failed to connect controller, " "retry with disabling SQ flow control\n"); c->cfg.disable_sqflow = false; ret = nvmf_add_ctrl(h, c, cfg); if (!ret) return c; } - nvme_msg(LOG_ERR, "failed to connect controller, error %d\n", errno); + nvme_msg(h->r, LOG_ERR, "failed to connect controller, error %d\n", + errno); nvme_free_ctrl(c); return NULL; } @@ -669,6 +674,7 @@ static int nvme_discovery_log(int fd, __u32 len, struct nvmf_discovery_log *log, 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; const char *name = nvme_ctrl_get_name(c); @@ -678,17 +684,17 @@ int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, hdr = sizeof(struct nvmf_discovery_log); log = malloc(hdr); if (!log) { - nvme_msg(LOG_ERR, + nvme_msg(r, LOG_ERR, "could not allocate memory for discovery log header\n"); errno = ENOMEM; return -1; } memset(log, 0, hdr); - nvme_msg(LOG_DEBUG, "%s: discover length %d\n", name, 0x100); + 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(LOG_INFO, "%s: discover failed, error %d\n", + nvme_msg(r, LOG_INFO, "%s: discover failed, error %d\n", name, errno); goto out_free_log; } @@ -708,28 +714,29 @@ int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, free(log); log = malloc(size); if (!log) { - nvme_msg(LOG_ERR, + nvme_msg(r, LOG_ERR, "could not alloc memory for discovery log page\n"); errno = ENOMEM; return -1; } memset(log, 0, size); - nvme_msg(LOG_DEBUG, "%s: discover length %d\n", name, 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); if (ret) { - nvme_msg(LOG_INFO, + nvme_msg(r, LOG_INFO, "%s: discover try %d/%d failed, error %d\n", name, retries, max_retries, errno); goto out_free_log; } genctr = le64_to_cpu(log->genctr); - nvme_msg(LOG_DEBUG, "%s: discover genctr %" PRIu64 ", retry\n", + 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); if (ret) { - nvme_msg(LOG_INFO, + nvme_msg(r, LOG_INFO, "%s: discover try %d/%d failed, error %d\n", name, retries, max_retries, errno); goto out_free_log; @@ -738,11 +745,12 @@ int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, ++retries < max_retries); if (genctr != le64_to_cpu(log->genctr)) { - nvme_msg(LOG_INFO, "%s: discover genctr mismatch\n", name); + nvme_msg(r, LOG_INFO, "%s: discover genctr mismatch\n", name); errno = EAGAIN; ret = -1; } else if (numrec != le64_to_cpu(log->numrec)) { - nvme_msg(LOG_INFO, "%s: could only fetch %" PRIu64 " of %" PRIu64 " records\n", + nvme_msg(r, LOG_INFO, + "%s: could only fetch %" PRIu64 " of %" PRIu64 " records\n", name, numrec, le64_to_cpu(log->numrec)); errno = EBADSLT; ret = -1; diff --git a/src/nvme/json.c b/src/nvme/json.c index 3f5fe881a4..49468c8acc 100644 --- a/src/nvme/json.c +++ b/src/nvme/json.c @@ -163,7 +163,7 @@ void json_read_config(nvme_root_t r, const char *config_file) json_root = json_object_from_file(config_file); if (!json_root) { - nvme_msg(LOG_DEBUG, "Failed to read %s, %s\n", + nvme_msg(r, LOG_DEBUG, "Failed to read %s, %s\n", config_file, json_util_get_last_err()); return; } @@ -295,7 +295,7 @@ int json_update_config(nvme_root_t r, const char *config_file) ret = json_object_to_file_ext(config_file, json_root, JSON_C_TO_STRING_PRETTY); if (ret < 0) { - nvme_msg(LOG_ERR, "Failed to write to %s, %s\n", + nvme_msg(r, LOG_ERR, "Failed to write to %s, %s\n", config_file ? "stdout" : config_file, json_util_get_last_err()); ret = -1; diff --git a/src/nvme/linux.c b/src/nvme/linux.c index b6f86b7d3f..cc7a3589dd 100644 --- a/src/nvme/linux.c +++ b/src/nvme/linux.c @@ -449,7 +449,7 @@ int nvme_gen_dhchap_key(char *hostnqn, enum nvme_hmac_alg hmac, unsigned char *key) { if (hmac != NVME_HMAC_ALG_NONE) { - nvme_msg(LOG_ERR, "HMAC transformation not supported; " \ + nvme_msg(NULL, LOG_ERR, "HMAC transformation not supported; " \ "recompile with OpenSSL support.\n"); errno = -EINVAL; return -1; @@ -475,8 +475,7 @@ int nvme_gen_dhchap_key(char *hostnqn, enum nvme_hmac_alg hmac, hmac_ctx = HMAC_CTX_new(); if (!hmac_ctx) { - nvme_msg(LOG_ERR, "OpenSSL: could not create HMAC context\n"); - errno = ENOENT; + errno = ENOMEM; return err; } @@ -500,34 +499,29 @@ int nvme_gen_dhchap_key(char *hostnqn, enum nvme_hmac_alg hmac, } if (!md) { - nvme_msg(LOG_ERR, "OpenSSL: could not fetch hash function\n"); - errno = ENOENT; + errno = EINVAL; goto out; } if (!HMAC_Init_ex(hmac_ctx, secret, key_len, md, NULL)) { - nvme_msg(LOG_ERR, "OpenSSL: initializing HMAC context failed\n"); - errno = ENOENT; + errno = ENOMEM; goto out; } if (!HMAC_Update(hmac_ctx, (unsigned char *)hostnqn, strlen(hostnqn))) { - nvme_msg(LOG_ERR, "OpenSSL: HMAC for hostnqn failed\n"); - errno = ENOENT; + errno = ENOKEY; goto out; } if (!HMAC_Update(hmac_ctx, (unsigned char *)hmac_seed, strlen(hmac_seed))) { - nvme_msg(LOG_ERR, "OpenSSL: HMAC for seed failed\n"); - errno = ENOENT; + errno = ENOKEY; goto out; } if (!HMAC_Final(hmac_ctx, key, &key_len)) { - nvme_msg(LOG_ERR, "OpenSSL: finializing MAC failed\n"); - errno = ENOENT; + errno = ENOKEY; goto out; } @@ -556,22 +550,19 @@ int nvme_gen_dhchap_key(char *hostnqn, enum nvme_hmac_alg hmac, lib_ctx = OSSL_LIB_CTX_new(); if (!lib_ctx) { - nvme_msg(LOG_ERR, "OpenSSL: Library initializing failed\n"); - errno = ENOENT; + errno = ENOMEM; return err; } mac = EVP_MAC_fetch(lib_ctx, OSSL_MAC_NAME_HMAC, progq); if (!mac) { - nvme_msg(LOG_ERR, "OpenSSL: could not fetch HMAC algorithm\n"); - errno = EINVAL; + errno = ENOMEM; goto out; } mac_ctx = EVP_MAC_CTX_new(mac); if (!mac_ctx) { - nvme_msg(LOG_ERR, "OpenSSL: could not create HMAC context\n"); - errno = ENOENT; + errno = ENOMEM; goto out; } @@ -599,34 +590,29 @@ int nvme_gen_dhchap_key(char *hostnqn, enum nvme_hmac_alg hmac, *p = OSSL_PARAM_construct_end(); if (!EVP_MAC_init(mac_ctx, secret, key_len, params)) { - nvme_msg(LOG_ERR, "OpenSSL: could not initialize HMAC context\n"); - errno = EINVAL; + errno = ENOKEY; goto out; } if (!EVP_MAC_update(mac_ctx, (unsigned char *)hostnqn, strlen(hostnqn))) { - nvme_msg(LOG_ERR, "OpenSSL: HMAC for hostnqn failed\n"); - errno = ENOENT; + errno = ENOKEY; goto out; } if (!EVP_MAC_update(mac_ctx, (unsigned char *)hmac_seed, strlen(hmac_seed))) { - nvme_msg(LOG_ERR, "OpenSSL: HMAC for seed failed\n"); - errno = ENOENT; + errno = ENOKEY; goto out; } if (!EVP_MAC_final(mac_ctx, key, &len, key_len)) { - nvme_msg(LOG_ERR, "OpenSSL: finializing MAC failed\n"); - errno = ENOENT; + errno = ENOKEY; goto out; } if (len != key_len) { - nvme_msg(LOG_ERR, "OpenSSL: generated HMAC has an unexpected lenght\n"); - errno = EINVAL; + errno = EMSGSIZE; goto out; } diff --git a/src/nvme/log.c b/src/nvme/log.c index 7d71d69dd4..0cdc4c37fa 100644 --- a/src/nvme/log.c +++ b/src/nvme/log.c @@ -25,6 +25,7 @@ #include #include #define LOG_FUNCNAME 1 +#include "private.h" #include "log.h" #include "cleanup.h" @@ -36,9 +37,11 @@ int nvme_log_level = DEFAULT_LOGLEVEL; bool nvme_log_timestamp; bool nvme_log_pid; -void __attribute__((format(printf, 3, 4))) -__nvme_msg(int lvl, const char *func, const char *format, ...) +void __attribute__((format(printf, 4, 5))) +__nvme_msg(nvme_root_t r, int lvl, + const char *func, const char *format, ...) { + FILE *fp = r ? r->fp : stderr; va_list ap; char pidbuf[16]; char timebuf[32]; @@ -83,7 +86,7 @@ __nvme_msg(int lvl, const char *func, const char *format, ...) va_end(ap); if (lvl <= nvme_log_level) - fprintf(stderr, "%s%s", header ? header : "", + fprintf(fp, "%s%s", header ? header : "", message ? message : ""); } diff --git a/src/nvme/log.h b/src/nvme/log.h index 5848764e47..0bb467cfbe 100644 --- a/src/nvme/log.h +++ b/src/nvme/log.h @@ -26,13 +26,13 @@ extern bool nvme_log_timestamp; extern bool nvme_log_pid; extern char *nvme_log_message; -void __attribute__((format(printf, 3, 4))) -__nvme_msg(int lvl, const char *func, const char *format, ...); +void __attribute__((format(printf, 4, 5))) +__nvme_msg(nvme_root_t r, int lvl, const char *func, const char *format, ...); -#define nvme_msg(lvl, format, ...) \ +#define nvme_msg(r, lvl, format, ...) \ do { \ if ((lvl) <= MAX_LOGLEVEL) \ - __nvme_msg(lvl, __nvme_log_func, \ + __nvme_msg(r, lvl, __nvme_log_func, \ format, ##__VA_ARGS__); \ } while (0) diff --git a/src/nvme/private.h b/src/nvme/private.h index 5b5809aa75..8badc1c122 100644 --- a/src/nvme/private.h +++ b/src/nvme/private.h @@ -120,6 +120,7 @@ struct nvme_host { struct nvme_root { char *config_file; struct list_head hosts; + FILE *fp; bool modified; }; diff --git a/src/nvme/tree.c b/src/nvme/tree.c index de7af7ac91..b99ffa780e 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -38,10 +38,12 @@ static struct nvme_host *default_host; static void __nvme_free_host(nvme_host_t h); static void __nvme_free_ctrl(nvme_ctrl_t c); -static int nvme_subsystem_scan_namespace(struct nvme_subsystem *s, char *name); -static int nvme_scan_subsystem(struct nvme_root *r, const char *name, +static int nvme_subsystem_scan_namespace(nvme_root_t r, + struct nvme_subsystem *s, char *name); +static int nvme_scan_subsystem(nvme_root_t r, const char *name, nvme_scan_filter_t f); -static int nvme_ctrl_scan_namespace(struct nvme_ctrl *c, char *name); +static int nvme_ctrl_scan_namespace(nvme_root_t r, struct nvme_ctrl *c, + char *name); static int nvme_ctrl_scan_path(struct nvme_ctrl *c, char *name); static inline void nvme_free_dirents(struct dirent **d, int i) @@ -76,7 +78,7 @@ static int nvme_scan_topology(struct nvme_root *r, nvme_scan_filter_t f) num_ctrls = nvme_scan_ctrls(&ctrls); if (num_ctrls < 0) { - nvme_msg(LOG_DEBUG, "failed to scan ctrls: %s\n", + nvme_msg(r, LOG_DEBUG, "failed to scan ctrls: %s\n", strerror(errno)); return num_ctrls; } @@ -84,7 +86,7 @@ static int nvme_scan_topology(struct nvme_root *r, nvme_scan_filter_t f) for (i = 0; i < num_ctrls; i++) { nvme_ctrl_t c = nvme_scan_ctrl(r, ctrls[i]->d_name); if (!c) { - nvme_msg(LOG_DEBUG, "failed to scan ctrl %s: %s\n", + nvme_msg(r, LOG_DEBUG, "failed to scan ctrl %s: %s\n", ctrls[i]->d_name, strerror(errno)); continue; } @@ -97,7 +99,7 @@ static int nvme_scan_topology(struct nvme_root *r, nvme_scan_filter_t f) num_subsys = nvme_scan_subsystems(&subsys); if (num_subsys < 0) { - nvme_msg(LOG_DEBUG, "failed to scan subsystems: %s\n", + nvme_msg(r, LOG_DEBUG, "failed to scan subsystems: %s\n", strerror(errno)); return num_subsys; } @@ -105,7 +107,8 @@ static int nvme_scan_topology(struct nvme_root *r, nvme_scan_filter_t f) for (i = 0; i < num_subsys; i++) { ret = nvme_scan_subsystem(r, subsys[i]->d_name, f); if (ret < 0) { - nvme_msg(LOG_DEBUG, "failed to scan subsystem %s: %s\n", + nvme_msg(r, LOG_DEBUG, + "failed to scan subsystem %s: %s\n", subsys[i]->d_name, strerror(errno)); } } @@ -115,7 +118,7 @@ static int nvme_scan_topology(struct nvme_root *r, nvme_scan_filter_t f) return 0; } -nvme_root_t nvme_scan_filter(nvme_scan_filter_t f) +nvme_root_t nvme_scan_filter(nvme_scan_filter_t f, FILE *fp) { struct nvme_root *r = calloc(1, sizeof(*r)); @@ -123,7 +126,9 @@ nvme_root_t nvme_scan_filter(nvme_scan_filter_t f) errno = ENOMEM; return NULL; } - + r->fp = stderr; + if (fp) + r->fp = fp; list_head_init(&r->hosts); nvme_scan_topology(r, f); return r; @@ -131,7 +136,7 @@ nvme_root_t nvme_scan_filter(nvme_scan_filter_t f) nvme_root_t nvme_scan(const char *config_file) { - nvme_root_t r = nvme_scan_filter(NULL); + nvme_root_t r = nvme_scan_filter(NULL, NULL); #ifdef CONFIG_JSONC if (r && config_file) { @@ -415,23 +420,23 @@ struct nvme_host *nvme_lookup_host(nvme_root_t r, const char *hostnqn, return h; } -static int nvme_subsystem_scan_namespaces(struct nvme_subsystem *s) +static int nvme_subsystem_scan_namespaces(nvme_root_t r, nvme_subsystem_t s) { struct dirent **namespaces; int i, num_ns, ret; num_ns = nvme_scan_subsystem_namespaces(s, &namespaces); if (num_ns < 0) { - nvme_msg(LOG_DEBUG, + nvme_msg(r, LOG_DEBUG, "failed to scan namespaces for subsys %s: %s\n", s->subsysnqn, strerror(errno)); return num_ns; } for (i = 0; i < num_ns; i++) { - ret = nvme_subsystem_scan_namespace(s, namespaces[i]->d_name); + ret = nvme_subsystem_scan_namespace(r, s, namespaces[i]->d_name); if (ret < 0) - nvme_msg(LOG_DEBUG, + nvme_msg(r, LOG_DEBUG, "failed to scan namespace %s: %s\n", namespaces[i]->d_name, strerror(errno)); } @@ -514,7 +519,7 @@ static int nvme_scan_subsystem(struct nvme_root *r, const char *name, goto free_path; } - nvme_subsystem_scan_namespaces(s); + nvme_subsystem_scan_namespaces(r, s); if (f && !f(s)) { __nvme_free_subsystem(s); @@ -630,10 +635,13 @@ static int nvme_ctrl_scan_path(struct nvme_ctrl *c, char *name) int nvme_ctrl_get_fd(nvme_ctrl_t c) { + nvme_root_t r = c->s && c->s->h ? c->s->h->r : NULL; + if (c->fd < 0) { c->fd = nvme_open(c->name); if (c->fd < 0) - nvme_msg(LOG_ERR, "Failed to open ctrl %s, errno %d\n", + nvme_msg(r, LOG_ERR, + "Failed to open ctrl %s, errno %d\n", c->name, errno); } return c->fd; @@ -826,16 +834,17 @@ void nvme_deconfigure_ctrl(nvme_ctrl_t c) int nvme_disconnect_ctrl(nvme_ctrl_t c) { + nvme_root_t r = c->s && c->s->h ? c->s->h->r : NULL; int ret; ret = nvme_set_attr(nvme_ctrl_get_sysfs_dir(c), "delete_controller", "1"); if (ret < 0) { - nvme_msg(LOG_ERR, "%s: failed to disconnect, error %d\n", + nvme_msg(r, LOG_ERR, "%s: failed to disconnect, error %d\n", c->name, errno); return ret; } - nvme_msg(LOG_INFO, "%s: disconnected\n", c->name); + nvme_msg(r, LOG_INFO, "%s: disconnected\n", c->name); nvme_deconfigure_ctrl(c); return 0; } @@ -904,7 +913,8 @@ static bool traddr_is_hostname(const char *transport, const char *traddr) return true; } -struct nvme_ctrl *nvme_create_ctrl(const char *subsysnqn, const char *transport, +struct nvme_ctrl *nvme_create_ctrl(nvme_root_t r, + const char *subsysnqn, const char *transport, const char *traddr, const char *host_traddr, const char *host_iface, const char *trsvcid) { @@ -912,18 +922,19 @@ struct nvme_ctrl *nvme_create_ctrl(const char *subsysnqn, const char *transport, bool discovery = false; if (!transport) { - nvme_msg(LOG_ERR, "No transport specified\n"); + nvme_msg(r, LOG_ERR, "No transport specified\n"); errno = EINVAL; return NULL; } if (strncmp(transport, "loop", 4) && strncmp(transport, "pcie", 4) && !traddr) { - nvme_msg(LOG_ERR, "No transport address for '%s'\n", transport); + nvme_msg(r, LOG_ERR, "No transport address for '%s'\n", + transport); errno = EINVAL; return NULL; } if (!subsysnqn) { - nvme_msg(LOG_ERR, "No subsystem NQN specified\n"); + nvme_msg(r, LOG_ERR, "No subsystem NQN specified\n"); errno = EINVAL; return NULL; } else if (!strcmp(subsysnqn, NVME_DISC_SUBSYS_NAME)) @@ -944,7 +955,7 @@ struct nvme_ctrl *nvme_create_ctrl(const char *subsysnqn, const char *transport, c->traddr = strdup(traddr); if (host_traddr) { if (traddr_is_hostname(transport, host_traddr)) - c->cfg.host_traddr = hostname2traddr(host_traddr); + c->cfg.host_traddr = hostname2traddr(r, host_traddr); if (!c->cfg.host_traddr) c->cfg.host_traddr = strdup(host_traddr); } @@ -956,7 +967,7 @@ struct nvme_ctrl *nvme_create_ctrl(const char *subsysnqn, const char *transport, discovery_trsvcid(c); else if (!strncmp(transport, "rdma", 4) || !strncmp(transport, "tcp", 3)) { - nvme_msg(LOG_ERR, "No trsvcid specified for '%s'\n", + nvme_msg(r, LOG_ERR, "No trsvcid specified for '%s'\n", transport); errno = EINVAL; __nvme_free_ctrl(c); @@ -970,6 +981,7 @@ struct nvme_ctrl *nvme_lookup_ctrl(struct nvme_subsystem *s, const char *transpo const char *traddr, const char *host_traddr, const char *host_iface, const char *trsvcid) { + nvme_root_t r = s->h ? s->h->r : NULL; struct nvme_ctrl *c; if (!s || !transport) @@ -991,7 +1003,7 @@ struct nvme_ctrl *nvme_lookup_ctrl(struct nvme_subsystem *s, const char *transpo continue; return c; } - c = nvme_create_ctrl(s->subsysnqn, transport, traddr, + c = nvme_create_ctrl(r, s->subsysnqn, transport, traddr, host_traddr, host_iface, trsvcid); if (c) { c->s = s; @@ -1001,7 +1013,7 @@ struct nvme_ctrl *nvme_lookup_ctrl(struct nvme_subsystem *s, const char *transpo return c; } -static int nvme_ctrl_scan_paths(struct nvme_ctrl *c) +static int nvme_ctrl_scan_paths(nvme_root_t r, struct nvme_ctrl *c) { struct dirent **paths; int i, ret; @@ -1017,20 +1029,21 @@ static int nvme_ctrl_scan_paths(struct nvme_ctrl *c) return 0; } -static int nvme_ctrl_scan_namespaces(struct nvme_ctrl *c) +static int nvme_ctrl_scan_namespaces(nvme_root_t r, struct nvme_ctrl *c) { struct dirent **namespaces; int i, ret; ret = nvme_scan_ctrl_namespaces(c, &namespaces); for (i = 0; i < ret; i++) - nvme_ctrl_scan_namespace(c, namespaces[i]->d_name); + nvme_ctrl_scan_namespace(r, c, namespaces[i]->d_name); nvme_free_dirents(namespaces, i); return 0; } -static char *nvme_ctrl_lookup_subsystem_name(const char *ctrl_name) +static char *nvme_ctrl_lookup_subsystem_name(nvme_root_t r, + const char *ctrl_name) { struct dirent **subsys; char *subsys_name = NULL; @@ -1045,7 +1058,7 @@ static char *nvme_ctrl_lookup_subsystem_name(const char *ctrl_name) sprintf(path, "%s/%s/%s", nvme_subsys_sysfs_dir, subsys[i]->d_name, ctrl_name); - nvme_msg(LOG_DEBUG, "lookup subsystem %s\n", path); + nvme_msg(r, LOG_DEBUG, "lookup subsystem %s\n", path); if (stat(path, &st) < 0) continue; subsys_name = strdup(subsys[i]->d_name); @@ -1055,14 +1068,14 @@ static char *nvme_ctrl_lookup_subsystem_name(const char *ctrl_name) return subsys_name; } -static int nvme_configure_ctrl(nvme_ctrl_t c, const char *path, +static int nvme_configure_ctrl(nvme_root_t r, nvme_ctrl_t c, const char *path, const char *name) { DIR *d; d = opendir(path); if (!d) { - nvme_msg(LOG_ERR, "Failed to open ctrl dir %s, error %d\n", + nvme_msg(r, LOG_ERR, "Failed to open ctrl dir %s, error %d\n", path, errno); errno = ENODEV; return -1; @@ -1101,7 +1114,7 @@ int nvme_init_ctrl(nvme_host_t h, nvme_ctrl_t c, int instance) goto out_free_name; } - ret = nvme_configure_ctrl(c, path, name); + ret = nvme_configure_ctrl(h->r, c, path, name); if (ret < 0) { free(path); goto out_free_name; @@ -1116,9 +1129,10 @@ int nvme_init_ctrl(nvme_host_t h, nvme_ctrl_t c, int instance) } } - subsys_name = nvme_ctrl_lookup_subsystem_name(name); + subsys_name = nvme_ctrl_lookup_subsystem_name(h->r, name); if (!subsys_name) { - nvme_msg(LOG_ERR, "Failed to lookup subsystem name for %s\n", + nvme_msg(h->r, LOG_ERR, + "Failed to lookup subsystem name for %s\n", c->name); errno = ENVME_CONNECT_LOOKUP_SUBSYS_NAME; ret = -1; @@ -1133,7 +1147,7 @@ int nvme_init_ctrl(nvme_host_t h, nvme_ctrl_t c, int instance) if (!s->name) { ret = nvme_init_subsystem(s, subsys_name); if (ret < 0) { - nvme_msg(LOG_ERR, "Failed to init subsystem %s\n", + nvme_msg(h->r, LOG_ERR, "Failed to init subsystem %s\n", subsys_name); goto out_free_subsys; } @@ -1149,8 +1163,8 @@ int nvme_init_ctrl(nvme_host_t h, nvme_ctrl_t c, int instance) return ret; } -static nvme_ctrl_t nvme_ctrl_alloc(nvme_subsystem_t s, const char *path, - const char *name) +static nvme_ctrl_t nvme_ctrl_alloc(nvme_root_t r, nvme_subsystem_t s, + const char *path, const char *name) { nvme_ctrl_t c; char *addr = NULL, *address = NULL, *a, *e; @@ -1226,7 +1240,7 @@ static nvme_ctrl_t nvme_ctrl_alloc(nvme_subsystem_t s, const char *path, c->address = addr; if (s->subsystype && !strcmp(s->subsystype, "discovery")) c->discovery_ctrl = true; - ret = nvme_configure_ctrl(c, path, name); + ret = nvme_configure_ctrl(r, c, path, name); return (ret < 0) ? NULL : c; } @@ -1272,7 +1286,7 @@ nvme_ctrl_t nvme_scan_ctrl(nvme_root_t r, const char *name) errno = ENXIO; return NULL; } - subsysname = nvme_ctrl_lookup_subsystem_name(name); + subsysname = nvme_ctrl_lookup_subsystem_name(r, name); s = nvme_lookup_subsystem(h, subsysname, subsysnqn); free(subsysnqn); if (!s) { @@ -1280,24 +1294,25 @@ nvme_ctrl_t nvme_scan_ctrl(nvme_root_t r, const char *name) errno = ENOMEM; return NULL; } - c = nvme_ctrl_alloc(s, path, name); + c = nvme_ctrl_alloc(r, s, path, name); if (!c) { free(path); return NULL; } - nvme_ctrl_scan_namespaces(c); - nvme_ctrl_scan_paths(c); + nvme_ctrl_scan_namespaces(r, c); + nvme_ctrl_scan_paths(r, c); return c; } void nvme_rescan_ctrl(struct nvme_ctrl *c) { + nvme_root_t r = c->s && c->s->h ? c->s->h->r : NULL; if (!c->s) return; - nvme_subsystem_scan_namespaces(c->s); - nvme_ctrl_scan_namespaces(c); - nvme_ctrl_scan_paths(c); + nvme_subsystem_scan_namespaces(r, c->s); + nvme_ctrl_scan_namespaces(r, c); + nvme_ctrl_scan_paths(r, c); } static int nvme_bytes_to_lba(nvme_ns_t n, off_t offset, size_t count, @@ -1724,19 +1739,20 @@ nvme_ns_t nvme_scan_namespace(const char *name) return __nvme_scan_namespace(nvme_ns_sysfs_dir, name); } -static int nvme_ctrl_scan_namespace(struct nvme_ctrl *c, char *name) +static int nvme_ctrl_scan_namespace(nvme_root_t r, struct nvme_ctrl *c, + char *name) { struct nvme_ns *n; if (!c->s) { - nvme_msg(LOG_DEBUG, "%s: no subsystem for %s\n", + nvme_msg(r, LOG_DEBUG, "%s: no subsystem for %s\n", __func__, name); errno = EINVAL; return -1; } n = __nvme_scan_namespace(c->sysfs_dir, name); if (!n) { - nvme_msg(LOG_DEBUG, "%s: failed to scan namespace %s\n", + nvme_msg(r, LOG_DEBUG, "%s: failed to scan namespace %s\n", __func__, name); return -1; } @@ -1747,13 +1763,14 @@ static int nvme_ctrl_scan_namespace(struct nvme_ctrl *c, char *name) return 0; } -static int nvme_subsystem_scan_namespace(struct nvme_subsystem *s, char *name) +static int nvme_subsystem_scan_namespace(nvme_root_t r, nvme_subsystem_t s, + char *name) { struct nvme_ns *n; n = __nvme_scan_namespace(s->sysfs_dir, name); if (!n) { - nvme_msg(LOG_DEBUG, "%s: failed to scan namespace %s\n", + nvme_msg(r, LOG_DEBUG, "%s: failed to scan namespace %s\n", __func__, name); return -1; } @@ -1766,6 +1783,7 @@ static int nvme_subsystem_scan_namespace(struct nvme_subsystem *s, char *name) 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; @@ -1775,7 +1793,7 @@ struct nvme_ns *nvme_subsystem_lookup_namespace(struct nvme_subsystem *s, return NULL; n = __nvme_scan_namespace(s->sysfs_dir, name); if (!n) { - nvme_msg(LOG_DEBUG, "%s: failed to scan namespace %d\n", + nvme_msg(r, LOG_DEBUG, "%s: failed to scan namespace %d\n", __func__, nsid); free(name); return NULL; diff --git a/src/nvme/tree.h b/src/nvme/tree.h index f886ecbb19..4c0233e60b 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -10,6 +10,7 @@ #ifndef _LIBNVME_TREE_H #define _LIBNVME_TREE_H +#include #include #include @@ -239,17 +240,22 @@ nvme_ctrl_t nvme_lookup_ctrl(nvme_subsystem_t s, const char *transport, /** - * nvme_create_ctrl() - - * @subsysnqn: - * @transport: - * @traddr: - * @host_traddr: - * @host_iface: - * @trsvcid: + * nvme_create_ctrl() - Allocate an unconnected NVMe controller + * @r: NVMe root element + * @subsysnqn: Subsystem NQN + * @transport: Transport type + * @traddr: Transport address + * @host_traddr: Host transport address + * @host_iface: Host interface name + * @trsvcid: Transport service ID * - * Return: + * Creates an unconnected nvme_ctrl_t structure to be used for + * nvme_add_ctrl(). + * + * Return: nvme_ctrl_t structure */ -nvme_ctrl_t nvme_create_ctrl(const char *subsysnqn, const char *transport, +nvme_ctrl_t nvme_create_ctrl(nvme_root_t r, + const char *subsysnqn, const char *transport, const char *traddr, const char *host_traddr, const char *host_iface, const char *trsvcid); @@ -961,12 +967,16 @@ const char *nvme_subsystem_get_name(nvme_subsystem_t s); const char *nvme_subsystem_get_type(nvme_subsystem_t s); /** - * nvme_scan_filter() - - * @f: + * nvme_scan_filter() - Scan NVMe topology and apply filter + * @f: filter to apply + * @fp: filepointer for error messages * - * Return: + * Scans the NVMe topology and filters out the resulting elements + * by applying @f. + * + * Return: nvme_root_t structure holding the resulting elements. */ -nvme_root_t nvme_scan_filter(nvme_scan_filter_t f); +nvme_root_t nvme_scan_filter(nvme_scan_filter_t f, FILE *fp); /** * nvme_host_get_hostnqn() - @@ -999,10 +1009,10 @@ nvme_host_t nvme_default_host(nvme_root_t r); void nvme_free_host(nvme_host_t h); /** - * nvme_scan() - - * @config_file: + * nvme_scan() - Scan NVMe topology + * @config_file: configuration file * - * Return: + * Return: nvme_root_t structure of found elements */ nvme_root_t nvme_scan(const char *config_file); diff --git a/src/nvme/util.c b/src/nvme/util.c index 14b543ae66..34bd548773 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -7,6 +7,7 @@ * Chaitanya Kulkarni */ +#include #include #include @@ -16,8 +17,10 @@ #include +#include "private.h" #include "util.h" #include "log.h" + static inline __u8 nvme_generic_status_to_errno(__u16 status) { switch (status) { @@ -503,7 +506,7 @@ const char *nvme_errno_to_string(int status) return s; } -char *hostname2traddr(const char *traddr) +char *hostname2traddr(struct nvme_root *r, const char *traddr) { struct addrinfo *host_info, hints = {.ai_family = AF_UNSPEC}; char addrstr[NVMF_TRADDR_SIZE]; @@ -513,7 +516,7 @@ char *hostname2traddr(const char *traddr) ret = getaddrinfo(traddr, NULL, &hints, &host_info); if (ret) { - nvme_msg(LOG_ERR, "failed to resolve host %s info\n", + nvme_msg(r, LOG_ERR, "failed to resolve host %s info\n", traddr); return NULL; } @@ -530,13 +533,13 @@ char *hostname2traddr(const char *traddr) addrstr, NVMF_TRADDR_SIZE); break; default: - nvme_msg(LOG_ERR, "unrecognized address family (%d) %s\n", + nvme_msg(r, LOG_ERR, "unrecognized address family (%d) %s\n", host_info->ai_family, traddr); goto free_addrinfo; } if (!p) { - nvme_msg(LOG_ERR, "failed to get traddr for %s\n", + nvme_msg(r, LOG_ERR, "failed to get traddr for %s\n", traddr); goto free_addrinfo; } diff --git a/src/nvme/util.h b/src/nvme/util.h index bec933964f..745aba8fcf 100644 --- a/src/nvme/util.h +++ b/src/nvme/util.h @@ -392,5 +392,7 @@ static inline void nvme_id_ns_flbas_to_lbaf_inuse(__u8 flbas, __u8 *lbaf_inuse) | (flbas & NVME_NS_FLBAS_LOWER_MASK)); } -char *hostname2traddr(const char *traddr); +struct nvme_root; + +char *hostname2traddr(struct nvme_root *r, const char *traddr); #endif /* _LIBNVME_UTIL_H */ diff --git a/test/test.c b/test/test.c index c50e96d4e6..d24bdf2deb 100644 --- a/test/test.c +++ b/test/test.c @@ -318,7 +318,7 @@ int main(int argc, char **argv) printf("Test filter for common loop back target\n"); nqn_match = "testnqn"; - r = nvme_scan_filter(nvme_match_subsysnqn_filter); + r = nvme_scan_filter(nvme_match_subsysnqn_filter, NULL); nvme_for_each_host(r, h) { nvme_for_each_subsystem(h, s) { printf("%s - NQN=%s\n", nvme_subsystem_get_name(s), From 19b12831a9ec6f8d47afabf1d6b7078f87d37992 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 31 Jan 2022 09:04:46 +0100 Subject: [PATCH 0407/1564] Move global logging variables into nvme_root_t Move the global logging variables into nvme_root_t to make them settable by the application. Signed-off-by: Hannes Reinecke --- libnvme/nvme.i | 19 ++++++++++--------- src/libnvme.map | 3 ++- src/nvme/log.c | 21 ++++++++++++--------- src/nvme/log.h | 14 +++++++++++--- src/nvme/private.h | 3 +++ src/nvme/tree.c | 15 +++++++++++---- src/nvme/tree.h | 13 ++++++++++++- test/test.c | 3 ++- 8 files changed, 63 insertions(+), 28 deletions(-) diff --git a/libnvme/nvme.i b/libnvme/nvme.i index ec78ffb8b6..16250ab6da 100644 --- a/libnvme/nvme.i +++ b/libnvme/nvme.i @@ -339,29 +339,30 @@ struct nvme_ns { %extend nvme_root { nvme_root(const char *config_file = NULL) { - nvme_log_level = LOG_ERR; return nvme_scan(config_file); } ~nvme_root() { nvme_free_tree($self); } void log_level(const char *level) { + int log_level = DEFAULT_LOGLEVEL; if (!strcmp(level,"debug")) - nvme_log_level = LOG_DEBUG; + log_level = LOG_DEBUG; else if (!strcmp(level, "info")) - nvme_log_level = LOG_INFO; + log_level = LOG_INFO; else if (!strcmp(level, "notice")) - nvme_log_level = LOG_NOTICE; + log_level = LOG_NOTICE; else if (!strcmp(level, "warning")) - nvme_log_level = LOG_WARNING; + log_level = LOG_WARNING; else if (!strcmp(level, "err")) - nvme_log_level = LOG_ERR; + log_level = LOG_ERR; else if (!strcmp(level, "crit")) - nvme_log_level = LOG_CRIT; + log_level = LOG_CRIT; else if (!strcmp(level, "alert")) - nvme_log_level = LOG_ALERT; + log_level = LOG_ALERT; else if (!strcmp(level, "emerg")) - nvme_log_level = LOG_EMERG; + log_level = LOG_EMERG; + nvme_init_logging($self, log_level, false, false); } struct nvme_host *hosts() { return nvme_first_host($self); diff --git a/src/libnvme.map b/src/libnvme.map index c71274b3cf..457fc086cb 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -169,12 +169,12 @@ LIBNVME_1_0 { nvme_init_ctrl; nvme_init_ctrl_list; nvme_init_dsm_range; + nvme_init_logging; nvme_init_id_ns; nvme_io; nvme_io_passthru64; nvme_io_passthru; nvme_lockdown; - nvme_log_level; nvme_lookup_host; nvme_lookup_subsystem; nvme_namespace_attach_ctrls; @@ -227,6 +227,7 @@ LIBNVME_1_0 { nvme_path_get_sysfs_dir; nvme_paths_filter; nvme_read; + nvme_read_config; nvme_refresh_topology; nvme_rescan_ctrl; nvme_reset_topology; diff --git a/src/nvme/log.c b/src/nvme/log.c index 0cdc4c37fa..e32e83fab6 100644 --- a/src/nvme/log.c +++ b/src/nvme/log.c @@ -33,10 +33,6 @@ #define LOG_CLOCK CLOCK_MONOTONIC #endif -int nvme_log_level = DEFAULT_LOGLEVEL; -bool nvme_log_timestamp; -bool nvme_log_pid; - void __attribute__((format(printf, 4, 5))) __nvme_msg(nvme_root_t r, int lvl, const char *func, const char *format, ...) @@ -59,7 +55,7 @@ __nvme_msg(nvme_root_t r, int lvl, char *message __cleanup__(cleanup_charp) = NULL; int idx; - if (nvme_log_timestamp) { + if (r->log_timestamp) { struct timespec now; clock_gettime(LOG_CLOCK, &now); @@ -68,13 +64,13 @@ __nvme_msg(nvme_root_t r, int lvl, } else *timebuf = '\0'; - if (nvme_log_pid) + if (r->log_pid) snprintf(pidbuf, sizeof(pidbuf), "%ld", (long)getpid()); else *pidbuf = '\0'; - idx = ((nvme_log_timestamp ? 1 : 0) << 2) | - ((nvme_log_pid ? 1 : 0) << 1) | (func ? 1 : 0); + idx = ((r->log_timestamp ? 1 : 0) << 2) | + ((r->log_pid ? 1 : 0) << 1) | (func ? 1 : 0); if (asprintf(&header, formats[idx], timebuf, pidbuf, func ? func : "") == -1) @@ -85,8 +81,15 @@ __nvme_msg(nvme_root_t r, int lvl, message = NULL; va_end(ap); - if (lvl <= nvme_log_level) + if (lvl <= r->log_level) fprintf(fp, "%s%s", header ? header : "", message ? message : ""); } + +void nvme_init_logging(nvme_root_t r, int lvl, bool log_pid, bool log_tstamp) +{ + r->log_level = lvl; + r->log_pid = log_pid; + r->log_timestamp = log_tstamp; +} diff --git a/src/nvme/log.h b/src/nvme/log.h index 0bb467cfbe..eef8f01b99 100644 --- a/src/nvme/log.h +++ b/src/nvme/log.h @@ -21,9 +21,6 @@ #define __nvme_log_func NULL #endif -extern int nvme_log_level; -extern bool nvme_log_timestamp; -extern bool nvme_log_pid; extern char *nvme_log_message; void __attribute__((format(printf, 4, 5))) @@ -36,4 +33,15 @@ __nvme_msg(nvme_root_t r, int lvl, const char *func, const char *format, ...); format, ##__VA_ARGS__); \ } while (0) +/** + * nvme_init_logging() - initialize logging + * @r: nvme_root_t context + * @lvl: logging level to set + * @log_pid: boolean to enable logging of the PID + * @log_tstamp: boolean to enable logging of the timestamp + * + * Sets the default logging variables for the library. + */ +void nvme_init_logging(nvme_root_t r, int lvl, bool log_pid, bool log_tstamp); + #endif /* _LOG_H */ diff --git a/src/nvme/private.h b/src/nvme/private.h index 8badc1c122..f33784bfb7 100644 --- a/src/nvme/private.h +++ b/src/nvme/private.h @@ -121,6 +121,9 @@ struct nvme_root { char *config_file; struct list_head hosts; FILE *fp; + int log_level; + bool log_pid; + bool log_timestamp; bool modified; }; diff --git a/src/nvme/tree.c b/src/nvme/tree.c index b99ffa780e..cbdcff5220 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -118,7 +118,7 @@ static int nvme_scan_topology(struct nvme_root *r, nvme_scan_filter_t f) return 0; } -nvme_root_t nvme_scan_filter(nvme_scan_filter_t f, FILE *fp) +nvme_root_t nvme_scan_filter(nvme_scan_filter_t f, FILE *fp, int log_level) { struct nvme_root *r = calloc(1, sizeof(*r)); @@ -126,6 +126,7 @@ nvme_root_t nvme_scan_filter(nvme_scan_filter_t f, FILE *fp) errno = ENOMEM; return NULL; } + r->log_level = log_level; r->fp = stderr; if (fp) r->fp = fp; @@ -134,16 +135,22 @@ nvme_root_t nvme_scan_filter(nvme_scan_filter_t f, FILE *fp) return r; } -nvme_root_t nvme_scan(const char *config_file) +void nvme_read_config(nvme_root_t r, const char *config_file) { - nvme_root_t r = nvme_scan_filter(NULL, NULL); - #ifdef CONFIG_JSONC if (r && config_file) { json_read_config(r, config_file); r->config_file = strdup(config_file); } #endif +} + +nvme_root_t nvme_scan(const char *config_file) +{ + nvme_root_t r = nvme_scan_filter(NULL, NULL, DEFAULT_LOGLEVEL); + + nvme_read_config(r, config_file); + return r; } diff --git a/src/nvme/tree.h b/src/nvme/tree.h index 4c0233e60b..0225d091b4 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -970,13 +970,14 @@ const char *nvme_subsystem_get_type(nvme_subsystem_t s); * nvme_scan_filter() - Scan NVMe topology and apply filter * @f: filter to apply * @fp: filepointer for error messages + * @log_level: logging level for this structure * * Scans the NVMe topology and filters out the resulting elements * by applying @f. * * Return: nvme_root_t structure holding the resulting elements. */ -nvme_root_t nvme_scan_filter(nvme_scan_filter_t f, FILE *fp); +nvme_root_t nvme_scan_filter(nvme_scan_filter_t f, FILE *fp, int log_level); /** * nvme_host_get_hostnqn() - @@ -1016,6 +1017,16 @@ void nvme_free_host(nvme_host_t h); */ nvme_root_t nvme_scan(const char *config_file); +/** + * nvme_read_config() - Read NVMe json configuration file + * @r: nvme_root_t object + * @config_file: json configuration file + * + * Read in the contents of @config_file and merge them with + * the elements in @r. + */ +void nvme_read_config(nvme_root_t r, const char *config_file); + /** * nvme_refresh_topology() - * @r: diff --git a/test/test.c b/test/test.c index d24bdf2deb..3dcbd2d0bb 100644 --- a/test/test.c +++ b/test/test.c @@ -318,7 +318,8 @@ int main(int argc, char **argv) printf("Test filter for common loop back target\n"); nqn_match = "testnqn"; - r = nvme_scan_filter(nvme_match_subsysnqn_filter, NULL); + r = nvme_scan_filter(nvme_match_subsysnqn_filter, NULL, + DEFAULT_LOGLEVEL); nvme_for_each_host(r, h) { nvme_for_each_subsystem(h, s) { printf("%s - NQN=%s\n", nvme_subsystem_get_name(s), From a6a09c1eb24bd76816392a8fb970026c16ad3dc2 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 31 Jan 2022 09:07:02 +0100 Subject: [PATCH 0408/1564] Remove stale definition for nvme_log_message No functionality anymore. Signed-off-by: Hannes Reinecke --- src/nvme/log.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/nvme/log.h b/src/nvme/log.h index eef8f01b99..8a0d2e3a3c 100644 --- a/src/nvme/log.h +++ b/src/nvme/log.h @@ -21,8 +21,6 @@ #define __nvme_log_func NULL #endif -extern char *nvme_log_message; - void __attribute__((format(printf, 4, 5))) __nvme_msg(nvme_root_t r, int lvl, const char *func, const char *format, ...); From f1af770aa33e2dcce122d2b5903b5fce35b2f6d4 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Mon, 31 Jan 2022 09:17:50 +0100 Subject: [PATCH 0409/1564] ioctl: Fix struct nvme_get_log_args memberm alignment Commit 781b9105cc43 ("nvme: Add Media Unit Status log page(LID: 0x10)") placed the domid member between two u8 members. The access domid member would not be 16 bit aligned which is caused problems on certain architectures. Let's fix the aligemnt by moving domid before lsp. This give us following layout struct nvme_get_log_args { int args_size; /* 0 4 */ int fd; /* 4 4 */ __u32 * result; /* 8 8 */ __u32 timeout; /* 16 4 */ enum nvme_cmd_get_log_lid lid; /* 20 4 */ __u64 lpo; /* 24 8 */ void * log; /* 32 8 */ __u32 len; /* 40 4 */ __u32 nsid; /* 44 4 */ enum nvme_csi csi; /* 48 4 */ __u16 lsi; /* 52 2 */ __u16 domid; /* 54 2 */ __u8 lsp; /* 56 1 */ __u8 uuidx; /* 57 1 */ _Bool rae; /* 58 1 */ _Bool ot; /* 59 1 */ /* size: 64, cachelines: 1, members: 16 */ /* padding: 4 */ } __attribute__((__aligned__(8))); Signed-off-by: Daniel Wagner --- src/nvme/ioctl.h | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 0dca0e3b21..f0ad3db6ad 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -1122,9 +1122,9 @@ static inline int nvme_zns_identify_ctrl(int fd, struct nvme_zns_id_ctrl *id) * @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 - * @lsp: Log specific field * @lsi: Endurance group information * @domid: Domain Identifier selection, if supported + * @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 @@ -1143,8 +1143,8 @@ struct nvme_get_log_args { __u32 nsid; enum nvme_csi csi; __u16 lsi; - __u8 lsp; __u16 domid; + __u8 lsp; __u8 uuidx; bool rae; bool ot; @@ -1175,8 +1175,8 @@ static inline int nvme_get_nsid_log(int fd, bool rae, .nsid = nsid, .csi = NVME_CSI_NVM, .lsi = NVME_LOG_LSI_NONE, - .lsp = NVME_LOG_LSP_NONE, .domid = NVME_DOMID_NONE, + .lsp = NVME_LOG_LSP_NONE, .uuidx = NVME_UUID_NONE, .rae = false, .ot = false, @@ -1318,8 +1318,8 @@ static inline int nvme_get_log_cmd_effects(int fd, enum nvme_csi csi, .nsid = NVME_NSID_ALL, .csi = csi, .lsi = NVME_LOG_LSI_NONE, - .lsp = NVME_LOG_LSP_NONE, .domid = NVME_DOMID_NONE, + .lsp = NVME_LOG_LSP_NONE, .uuidx = NVME_UUID_NONE, .rae = false, .ot = false, @@ -1365,8 +1365,8 @@ static inline int nvme_get_log_create_telemetry_host(int fd, .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, .lsi = NVME_LOG_LSI_NONE, - .lsp = NVME_LOG_TELEM_HOST_LSP_CREATE, .domid = NVME_DOMID_NONE, + .lsp = NVME_LOG_TELEM_HOST_LSP_CREATE, .uuidx = NVME_UUID_NONE, .rae = false, .ot = false, @@ -1402,8 +1402,8 @@ static inline int nvme_get_log_telemetry_host(int fd, __u64 offset, .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, .lsi = NVME_LOG_LSI_NONE, - .lsp = NVME_LOG_TELEM_HOST_LSP_RETAIN, .domid = NVME_DOMID_NONE, + .lsp = NVME_LOG_TELEM_HOST_LSP_RETAIN, .uuidx = NVME_UUID_NONE, .rae = false, .ot = false, @@ -1434,8 +1434,8 @@ static inline int nvme_get_log_telemetry_ctrl(int fd, bool rae, .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, .lsi = NVME_LOG_LSI_NONE, - .lsp = NVME_LOG_LSP_NONE, .domid = NVME_DOMID_NONE, + .lsp = NVME_LOG_LSP_NONE, .uuidx = NVME_UUID_NONE, .rae = rae, .ot = false, @@ -1474,8 +1474,8 @@ static inline int nvme_get_log_endurance_group(int fd, __u16 endgid, .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, .lsi = endgid, - .lsp = NVME_LOG_LSP_NONE, .domid = NVME_DOMID_NONE, + .lsp = NVME_LOG_LSP_NONE, .uuidx = NVME_UUID_NONE, .rae = false, .ot = false, @@ -1506,8 +1506,8 @@ static inline int nvme_get_log_predictable_lat_nvmset(int fd, __u16 nvmsetid, .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, .lsi = nvmsetid, - .lsp = NVME_LOG_LSP_NONE, .domid = NVME_DOMID_NONE, + .lsp = NVME_LOG_LSP_NONE, .uuidx = NVME_UUID_NONE, .rae = false, .ot = false, @@ -1535,8 +1535,8 @@ static inline int nvme_get_log_predictable_lat_event(int fd, bool rae, .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, .lsi = NVME_LOG_LSI_NONE, - .lsp = NVME_LOG_LSP_NONE, .domid = NVME_DOMID_NONE, + .lsp = NVME_LOG_LSP_NONE, .uuidx = NVME_UUID_NONE, .rae = rae, .ot = false, @@ -1576,8 +1576,8 @@ 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, .domid = NVME_DOMID_NONE, + .lsp = lsp, .uuidx = NVME_UUID_NONE, .rae = false, .ot = false, @@ -1619,8 +1619,8 @@ static inline int nvme_get_log_lba_status(int fd, bool rae, .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, .lsi = NVME_LOG_LSI_NONE, - .lsp = NVME_LOG_LSP_NONE, .domid = NVME_DOMID_NONE, + .lsp = NVME_LOG_LSP_NONE, .uuidx = NVME_UUID_NONE, .rae = rae, .ot = false, @@ -1648,8 +1648,8 @@ static inline int nvme_get_log_endurance_grp_evt(int fd, bool rae, .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, .lsi = NVME_LOG_LSI_NONE, - .lsp = NVME_LOG_LSP_NONE, .domid = NVME_DOMID_NONE, + .lsp = NVME_LOG_LSP_NONE, .uuidx = NVME_UUID_NONE, .rae = rae, .ot = false, @@ -1699,8 +1699,8 @@ static inline int nvme_get_log_boot_partition(int fd, bool rae, .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, .lsi = NVME_LOG_LSI_NONE, - .lsp = NVME_LOG_LSP_NONE, .domid = NVME_DOMID_NONE, + .lsp = NVME_LOG_LSP_NONE, .uuidx = NVME_UUID_NONE, .rae = rae, .ot = false, @@ -1737,8 +1737,8 @@ static inline int nvme_get_log_discovery(int fd, bool rae, .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, .lsi = NVME_LOG_LSI_NONE, - .lsp = NVME_LOG_LSP_NONE, .domid = NVME_DOMID_NONE, + .lsp = NVME_LOG_LSP_NONE, .uuidx = NVME_UUID_NONE, .rae = rae, .ot = false, @@ -1769,8 +1769,8 @@ static inline int nvme_get_log_media_unit_stat(int fd, __u16 domid, .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, .lsi = NVME_LOG_LSI_NONE, - .lsp = NVME_LOG_LSP_NONE, .domid = domid, + .lsp = NVME_LOG_LSP_NONE, .uuidx = NVME_UUID_NONE, .rae = false, .ot = false, @@ -1836,8 +1836,8 @@ static inline int nvme_get_log_zns_changed_zones(int fd, __u32 nsid, bool rae, .nsid = nsid, .csi = NVME_CSI_ZNS, .lsi = NVME_LOG_LSI_NONE, - .lsp = NVME_LOG_LSP_NONE, .domid = NVME_DOMID_NONE, + .lsp = NVME_LOG_LSP_NONE, .uuidx = NVME_UUID_NONE, .rae = rae, .ot = false, @@ -1868,8 +1868,8 @@ static inline int nvme_get_log_persistent_event(int fd, .nsid = NVME_NSID_ALL, .csi = NVME_CSI_NVM, .lsi = NVME_LOG_LSI_NONE, - .lsp = NVME_LOG_LSP_NONE, .domid = NVME_DOMID_NONE, + .lsp = NVME_LOG_LSP_NONE, .uuidx = NVME_UUID_NONE, .rae = false, .ot = false, From 2ed84924c5c3af21b8816f53de68df89c8574376 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 31 Jan 2022 09:12:13 +0100 Subject: [PATCH 0410/1564] libnvme/tests: fixup create-ctrl-obj.py Add the new 'root' argument to nvme.ctrl() Signed-off-by: Hannes Reinecke --- libnvme/nvme.i | 2 +- libnvme/tests/create-ctrl-obj.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libnvme/nvme.i b/libnvme/nvme.i index 16250ab6da..f2e48d8e83 100644 --- a/libnvme/nvme.i +++ b/libnvme/nvme.i @@ -509,7 +509,7 @@ struct nvme_ns { } %extend nvme_ctrl { - nvme_ctrl(nvme_root_t r, const char *subsysnqn, const char *transport, + nvme_ctrl(struct nvme_root *r, const char *subsysnqn, const char *transport, const char *traddr = NULL, const char *host_traddr = NULL, const char *host_iface = NULL, const char *trsvcid = NULL) { return nvme_create_ctrl(r, subsysnqn, transport, traddr, diff --git a/libnvme/tests/create-ctrl-obj.py b/libnvme/tests/create-ctrl-obj.py index 186c6013fc..51915cc0b9 100755 --- a/libnvme/tests/create-ctrl-obj.py +++ b/libnvme/tests/create-ctrl-obj.py @@ -11,4 +11,4 @@ transport = 'loop' traddr = '127.0.0.1' trsvcid = '8009' -ctrl = nvme.ctrl(subsysnqn=subsysnqn, transport=transport, traddr=traddr, trsvcid=trsvcid) +ctrl = nvme.ctrl(root, subsysnqn=subsysnqn, transport=transport, traddr=traddr, trsvcid=trsvcid) From 4be00c8876e1697b7cb57b3b9e28cabb63aa7f56 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Mon, 31 Jan 2022 10:43:58 +0100 Subject: [PATCH 0411/1564] ioctl: Sort members their natural size Previous attempt to align the members of all *_args structure didn't take into account that pointer types vary between 32bit and 64bit depending the arch. The only reliable alignemnt is to sort the members according their natural size: 64bit, pointers, 32bit, 16bit, 8bit. Signed-off-by: Daniel Wagner --- src/nvme/ioctl.h | 530 ++++++++++++++++++++++++----------------------- 1 file changed, 266 insertions(+), 264 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index f0ad3db6ad..b30393f1e3 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -375,11 +375,11 @@ int nvme_get_nsid(int fd, __u32 *nsid); /** * nvme_identify_args - Arguments for the NVMe Identify command + * @data: User space destination address to transfer the data + * @timeout: Timeout in ms (0 for default timeout) * @fd: File descriptor of nvme device * @result: The command completion result from CQE dword0 - * @timeout: Timeout in ms (0 for default timeout) * @cns: The Controller or Namespace structure, see @enum nvme_identify_cns - * @data: User space destination address to transfer the data * @csi: Command Set Identifier * @nsid: Namespace identifier, if applicable * @domid: Domain identifier, if applicable @@ -388,12 +388,12 @@ int nvme_get_nsid(int fd, __u32 *nsid); * @uuidx: UUID Index if controller supports this id selection method */ struct nvme_identify_args { + __u32 *result; + void *data; int args_size; int fd; - __u32 *result; __u32 timeout; enum nvme_identify_cns cns; - void *data; enum nvme_csi csi; __u32 nsid; __u16 cntid; @@ -418,12 +418,12 @@ static int nvme_identify_cns_nsid(int fd, enum nvme_identify_cns cns, __u32 nsid, void *data) { struct nvme_identify_args args = { + .result = NULL, + .data = data, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .cns = cns, - .data = data, .csi = NVME_CSI_NVM, .nsid = nsid, .cntid = NVME_CNTLID_NONE, @@ -558,12 +558,12 @@ static inline int nvme_identify_ctrl_list(int fd, __u16 cntid, struct nvme_ctrl_list *ctrlist) { struct nvme_identify_args args = { + .result = NULL, + .data = ctrlist, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .cns = NVME_IDENTIFY_CNS_CTRL_LIST, - .data = ctrlist, .csi = NVME_CSI_NVM, .nsid = NVME_NSID_NONE, .cntid = cntid, @@ -595,12 +595,12 @@ static inline int nvme_identify_nsid_ctrl_list(int fd, __u32 nsid, __u16 cntid, struct nvme_ctrl_list *ctrlist) { struct nvme_identify_args args = { + .result = NULL, + .data = ctrlist, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .cns = NVME_IDENTIFY_CNS_NS_CTRL_LIST, - .data = ctrlist, .csi = NVME_CSI_NVM, .nsid = nsid, .cntid = cntid, @@ -656,12 +656,12 @@ static inline int nvme_identify_nvmset_list(int fd, __u16 nvmsetid, struct nvme_id_nvmset_list *nvmset) { struct nvme_identify_args args = { + .result = NULL, + .data = nvmset, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .cns = NVME_IDENTIFY_CNS_NVMSET_LIST, - .data = nvmset, .csi = NVME_CSI_NVM, .nsid = NVME_NSID_NONE, .cntid = NVME_CNTLID_NONE, @@ -689,12 +689,12 @@ static inline int nvme_identify_primary_ctrl(int fd, __u16 cntid, struct nvme_primary_ctrl_cap *cap) { struct nvme_identify_args args = { + .result = NULL, + .data = cap, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .cns = NVME_IDENTIFY_CNS_PRIMARY_CTRL_CAP, - .data = cap, .csi = NVME_CSI_NVM, .nsid = NVME_NSID_NONE, .cntid = cntid, @@ -728,12 +728,12 @@ static inline int nvme_identify_secondary_ctrl_list(int fd, __u32 nsid, __u16 cntid, struct nvme_secondary_ctrl_list *list) { struct nvme_identify_args args = { + .result = NULL, + .data = list, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .cns = NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST, - .data = list, .csi = NVME_CSI_NVM, .nsid = nsid, .cntid = cntid, @@ -801,12 +801,12 @@ static inline int nvme_identify_ns_csi(int fd, __u32 nsid, enum nvme_csi csi, void *data) { struct nvme_identify_args args = { + .result = NULL, + .data = data, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .cns = NVME_IDENTIFY_CNS_CSI_NS, - .data = data, .csi = csi, .nsid = nsid, .cntid = NVME_CNTLID_NONE, @@ -830,12 +830,12 @@ static inline int nvme_identify_ns_csi(int fd, __u32 nsid, static inline int nvme_identify_ctrl_csi(int fd, enum nvme_csi csi, void *data) { struct nvme_identify_args args = { + .result = NULL, + .data = data, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .cns = NVME_IDENTIFY_CNS_CSI_CTRL, - .data = data, .csi = csi, .nsid = NVME_NSID_NONE, .cntid = NVME_CNTLID_NONE, @@ -868,12 +868,12 @@ static inline int nvme_identify_active_ns_list_csi(int fd, __u32 nsid, enum nvme_csi csi, struct nvme_ns_list *list) { struct nvme_identify_args args = { + .result = NULL, + .data = list, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .cns = NVME_IDENTIFY_CNS_NS_ACTIVE_LIST, - .data = list, .csi = csi, .nsid = nsid, .cntid = NVME_CNTLID_NONE, @@ -906,12 +906,12 @@ static inline int nvme_identify_allocated_ns_list_csi(int fd, __u32 nsid, enum nvme_csi csi, struct nvme_ns_list *list) { struct nvme_identify_args args = { + .result = NULL, + .data = list, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .cns = NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST, - .data = list, .csi = csi, .nsid = nsid, .cntid = NVME_CNTLID_NONE, @@ -937,12 +937,12 @@ static inline int nvme_identify_independent_identify_ns(int fd, __u32 nsid, struct nvme_id_independent_id_ns *ns) { struct nvme_identify_args args = { + .result = NULL, + .data = ns, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .cns = NVME_IDENTIFY_CNS_CSI_INDEPENDENT_ID_NS, - .data = ns, .csi = NVME_CSI_NVM, .nsid = nsid, .cntid = NVME_CNTLID_NONE, @@ -987,12 +987,12 @@ static inline int nvme_identify_domain_list(int fd, __u16 domid, struct nvme_id_domain_list *list) { struct nvme_identify_args args = { + .result = NULL, + .data = list, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .cns = NVME_IDENTIFY_CNS_DOMAIN_LIST, - .data = list, .csi = NVME_CSI_NVM, .nsid = NVME_NSID_NONE, .cntid = NVME_CNTLID_NONE, @@ -1017,12 +1017,12 @@ static inline int nvme_identify_endurance_group_list(int fd, __u16 endgrp_id, struct nvme_id_endurance_group_list *list) { struct nvme_identify_args args = { + .result = NULL, + .data = list, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .cns = NVME_IDENTIFY_CNS_ENDURANCE_GROUP_ID, - .data = list, .csi = NVME_CSI_NVM, .nsid = NVME_NSID_NONE, .cntid = NVME_CNTLID_NONE, @@ -1050,12 +1050,12 @@ static inline int nvme_identify_iocs(int fd, __u16 cntlid, struct nvme_id_iocs *iocs) { struct nvme_identify_args args = { + .result = NULL, + .data = iocs, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .cns = NVME_IDENTIFY_CNS_COMMAND_SET_STRUCTURE, - .data = iocs, .csi = NVME_CSI_NVM, .nsid = NVME_NSID_NONE, .cntid = cntlid, @@ -1080,12 +1080,12 @@ static inline int nvme_zns_identify_ns(int fd, __u32 nsid, struct nvme_zns_id_ns *data) { struct nvme_identify_args args = { + .result = NULL, + .data = data, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .cns = NVME_IDENTIFY_CNS_CSI_NS, - .data = data, .csi = NVME_CSI_ZNS, .nsid = nsid, .cntid = NVME_CNTLID_NONE, @@ -1111,14 +1111,14 @@ static inline int nvme_zns_identify_ctrl(int fd, struct nvme_zns_id_ctrl *id) /** * 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 - * @result: The command completion result from CQE dword0 * @timeout: Timeout in ms * @lid: Log page identifier, see &enum nvme_cmd_get_log_lid for known - * values - * @lpo: Log page offset for partial log transfers - * @log: User space destination address to transfer the data + * 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 @@ -1132,13 +1132,13 @@ static inline int nvme_zns_identify_ctrl(int fd, struct nvme_zns_id_ctrl *id) * into the log page. */ struct nvme_get_log_args { + __u64 lpo; + __u32 *result; + void *log; int args_size; int fd; - __u32 *result; __u32 timeout; enum nvme_cmd_get_log_lid lid; - __u64 lpo; - void *log; __u32 len; __u32 nsid; enum nvme_csi csi; @@ -1164,13 +1164,13 @@ static inline int nvme_get_nsid_log(int fd, bool rae, __u32 nsid, __u32 len, void *log) { struct nvme_get_log_args args = { + .lpo = 0, + .result = NULL, + .log = log, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .lid = lid, - .lpo = 0, - .log = log, .len = len, .nsid = nsid, .csi = NVME_CSI_NVM, @@ -1307,13 +1307,13 @@ static inline int nvme_get_log_cmd_effects(int fd, enum nvme_csi csi, struct nvme_cmd_effects_log *log) { struct nvme_get_log_args args = { + .lpo = 0, + .result = NULL, + .log = log, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .lid = NVME_LOG_LID_CMD_EFFECTS, - .lpo = 0, - .log = log, .len = sizeof(*log), .nsid = NVME_NSID_ALL, .csi = csi, @@ -1354,13 +1354,13 @@ static inline int nvme_get_log_create_telemetry_host(int fd, struct nvme_telemetry_log *log) { struct nvme_get_log_args args = { + .lpo = 0, + .result = NULL, + .log = log, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .lid = NVME_LOG_LID_TELEMETRY_HOST, - .lpo = 0, - .log = log, .len = sizeof(*log), .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, @@ -1391,13 +1391,13 @@ static inline int nvme_get_log_telemetry_host(int fd, __u64 offset, __u32 len, void *log) { struct nvme_get_log_args args = { + .lpo = 0, + .result = NULL, + .log = log, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .lid = NVME_LOG_LID_TELEMETRY_HOST, - .lpo = 0, - .log = log, .len = len, .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, @@ -1423,13 +1423,13 @@ static inline int nvme_get_log_telemetry_ctrl(int fd, bool rae, __u64 offset, __u32 len, void *log) { struct nvme_get_log_args args = { + .lpo = offset, + .result = NULL, + .log = log, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .lid = NVME_LOG_LID_TELEMETRY_CTRL, - .lpo = offset, - .log = log, .len = len, .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, @@ -1463,13 +1463,13 @@ static inline int nvme_get_log_endurance_group(int fd, __u16 endgid, struct nvme_endurance_group_log *log) { struct nvme_get_log_args args = { + .lpo = 0, + .result = NULL, + .log = log, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .lid = NVME_LOG_LID_ENDURANCE_GROUP, - .lpo = 0, - .log = log, .len = sizeof(*log), .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, @@ -1495,13 +1495,13 @@ static inline int nvme_get_log_predictable_lat_nvmset(int fd, __u16 nvmsetid, struct nvme_nvmset_predictable_lat_log *log) { struct nvme_get_log_args args = { + .lpo = 0, + .result = NULL, + .log = log, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .lid = NVME_LOG_LID_PREDICTABLE_LAT_NVMSET, - .lpo = 0, - .log = log, .len = sizeof(*log), .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, @@ -1524,13 +1524,13 @@ static inline int nvme_get_log_predictable_lat_event(int fd, bool rae, __u32 offset, __u32 len, void *log) { struct nvme_get_log_args args = { + .lpo = offset, + .result = NULL, + .log = log, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .lid = NVME_LOG_LID_PREDICTABLE_LAT_AGG, - .lpo = offset, - .log = log, .len = len, .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, @@ -1565,13 +1565,13 @@ static 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, + .result = NULL, + .log = log, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .lid = NVME_LOG_LID_ANA, - .lpo = offset, - .log = log, .len = len, .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, @@ -1608,13 +1608,13 @@ static inline int nvme_get_log_lba_status(int fd, bool rae, __u64 offset, __u32 len, void *log) { struct nvme_get_log_args args = { + .lpo = offset, + .result = NULL, + .log = log, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .lid = NVME_LOG_LID_LBA_STATUS, - .lpo = offset, - .log = log, .len = len, .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, @@ -1637,13 +1637,13 @@ static inline int nvme_get_log_endurance_grp_evt(int fd, bool rae, __u32 offset, __u32 len, void *log) { struct nvme_get_log_args args = { + .lpo = offset, + .result = NULL, + .log = log, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .lid = NVME_LOG_LID_ENDURANCE_GRP_EVT, - .lpo = offset, - .log = log, .len = len, .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, @@ -1688,13 +1688,13 @@ static inline int nvme_get_log_boot_partition(int fd, bool rae, __u8 lsp, __u32 len, struct nvme_boot_partition *part) { struct nvme_get_log_args args = { + .lpo = 0, + .result = NULL, + .log = part, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .lid = NVME_LOG_LID_BOOT_PARTITION, - .lpo = 0, - .log = part, .len = len, .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, @@ -1726,13 +1726,13 @@ static inline int nvme_get_log_discovery(int fd, bool rae, __u32 offset, __u32 len, void *log) { struct nvme_get_log_args args = { + .lpo = offset, + .result = NULL, + .log = log, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .lid = NVME_LOG_LID_DISCOVER, - .lpo = offset, - .log = log, .len = len, .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, @@ -1758,13 +1758,13 @@ static inline int nvme_get_log_media_unit_stat(int fd, __u16 domid, struct nvme_media_unit_stat_log *mus) { struct nvme_get_log_args args = { + .lpo = 0, + .result = NULL, + .log = mus, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .lid = NVME_LOG_LID_MEDIA_UNIT_STATUS, - .lpo = 0, - .log = mus, .len = sizeof(*mus), .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, @@ -1825,13 +1825,13 @@ static inline int nvme_get_log_zns_changed_zones(int fd, __u32 nsid, bool rae, struct nvme_zns_changed_zone_log *log) { struct nvme_get_log_args args = { + .lpo = 0, + .result = NULL, + .log = log, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .lid = NVME_LOG_LID_ZNS_CHANGED_ZONES, - .lpo = 0, - .log = log, .len = sizeof(*log), .nsid = nsid, .csi = NVME_CSI_ZNS, @@ -1857,13 +1857,13 @@ static inline int nvme_get_log_persistent_event(int fd, __u32 size, void *pevent_log) { struct nvme_get_log_args args = { + .lpo = 0, + .result = NULL, + .log = pevent_log, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .lid = NVME_LOG_LID_PERSISTENT_EVENT, - .lpo = 0, - .log = pevent_log, .len = size, .nsid = NVME_NSID_ALL, .csi = NVME_CSI_NVM, @@ -1879,30 +1879,30 @@ static inline int nvme_get_log_persistent_event(int fd, /** * nvme_set_features_args - Arguments for the NVMe Admin Set Feature command - * @fd: File descriptor of nvme device * @result: The command completion result from CQE dword0 + * @data: User address of feature data, if applicable + * @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 * @cdw14: Feature specific command dword15 field * @data_len: Length of feature data, if applicable, in bytes - * @data: User address of feature data, if applicable * @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 *result; __u32 timeout; __u32 nsid; __u32 cdw11; __u32 cdw12; __u32 cdw15; __u32 data_len; - void *data; bool save; __u8 uuidx; __u8 fid; @@ -1922,16 +1922,16 @@ static inline int nvme_set_features_data(int fd, __u8 fid, __u32 nsid, __u32 *result) { struct nvme_set_features_args args = { + .result = result, + .data = data, .args_size = sizeof(args), .fd = fd, - .result = result, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .nsid = nsid, .cdw11 = cdw11, .cdw12 = 0, .cdw15 = 0, .data_len = data_len, - .data = data, .save = save, .uuidx = 0, .fid = fid, @@ -2277,15 +2277,15 @@ int nvme_set_features_write_protect(int fd, enum nvme_feat_nswpcfg_state state, * @uuidx: UUID Index for differentiating vendor specific encoding */ struct nvme_get_features_args { + __u32 *result; + void *data; int args_size; int fd; - __u32 *result; __u32 timeout; __u32 nsid; enum nvme_get_features_sel sel; __u32 cdw11; __u32 data_len; - void *data; __u8 fid; __u8 uuidx; } __attribute__((packed, aligned(__alignof__(__u32*)))); @@ -2303,15 +2303,15 @@ static inline int nvme_get_features_data(int fd, enum nvme_features_id fid, __u32 nsid, __u32 data_len, void *data, __u32 *result) { struct nvme_get_features_args args = { + .result = result, + .data = data, .args_size = sizeof(args), .fd = fd, - .result = result, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .nsid = nsid, .sel = NVME_GET_FEATURES_SEL_CURRENT, .cdw11 = 0, .data_len = data_len, - .data = data, .fid = fid, .uuidx = NVME_UUID_NONE, }; @@ -2687,8 +2687,8 @@ int nvme_get_features_iocs_profile(int fd, enum nvme_get_features_sel sel, /** * nvme_format_nvm_args - Arguments for the Format Nvme Namespace command - * @fd: File descriptor of nvme device * @result: The command completion result from CQE dword0 + * @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 @@ -2699,9 +2699,9 @@ int nvme_get_features_iocs_profile(int fd, enum nvme_get_features_sel sel, * @lbaf: Logical block address format */ struct nvme_format_nvm_args { + __u32 *result; int args_size; int fd; - __u32 *result; __u32 timeout; __u32 nsid; enum nvme_cmd_format_mset mset; @@ -2727,21 +2727,21 @@ int nvme_format_nvm(struct nvme_format_nvm_args *args); /** * nvme_ns_mgmt_args - Arguments for NVMe Namespace Management command - * @fd: File descriptor of nvme device * @result: NVMe command result + * @ns: Namespace identication descriptors + * @fd: File descriptor of nvme device * @timeout: Timeout in ms * @nsid: Namespace identifier - * @ns: Namespace identication descriptors * @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 *result; __u32 timeout; __u32 nsid; - struct nvme_id_ns *ns; enum nvme_ns_mgmt_sel sel; __u8 csi; } __attribute__((packed, aligned(__alignof__(__u32*)))); @@ -2772,12 +2772,12 @@ static inline int nvme_ns_mgmt_create(int fd, struct nvme_id_ns *ns, __u32 *nsid, __u32 timeout, __u8 csi) { struct nvme_ns_mgmt_args args = { + .result = nsid, + .ns = ns, .args_size = sizeof(args), .fd = fd, - .result = nsid, .timeout = timeout, .nsid = NVME_NSID_NONE, - .ns = ns, .sel = NVME_NS_MGMT_SEL_CREATE, .csi = csi, }; @@ -2800,12 +2800,12 @@ static inline int nvme_ns_mgmt_create(int fd, struct nvme_id_ns *ns, static inline int nvme_ns_mgmt_delete(int fd, __u32 nsid) { struct nvme_ns_mgmt_args args = { + .result = NULL, + .ns = NULL, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = 0, .nsid = nsid, - .ns = NULL, .sel = NVME_NS_MGMT_SEL_DELETE, .csi = 0, }; @@ -2815,20 +2815,20 @@ static inline int nvme_ns_mgmt_delete(int fd, __u32 nsid) /** * nvme_ns_attach_args - Arguments for Nvme Namespace Management command - * @fd: File descriptor of nvme device * @result: NVMe command result + * @ctrlist: Controller list to modify attachment state of nsid + * @fd: File descriptor of nvme device * @timeout: Timeout in ms * @nsid: Namespace ID to execute attach selection - * @ctrlist: Controller list to modify attachment state of nsid * @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 *result; __u32 timeout; __u32 nsid; - struct nvme_ctrl_list *ctrlist; enum nvme_ns_attach_sel sel; } __attribute__((packed, aligned(__alignof__(__u32*)))); @@ -2848,12 +2848,12 @@ static inline int nvme_ns_attach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist) { struct nvme_ns_attach_args args = { + .result = NULL, + .ctrlist = ctrlist, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .nsid = nsid, - .ctrlist = ctrlist, .sel = NVME_NS_ATTACH_SEL_CTRL_ATTACH, }; @@ -2870,12 +2870,12 @@ static inline int nvme_ns_detach_ctrls(int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist) { struct nvme_ns_attach_args args = { + .result = NULL, + .ctrlist = ctrlist, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .nsid = nsid, - .ctrlist = ctrlist, .sel = NVME_NS_ATTACH_SEL_CTRL_DEATTACH, }; @@ -2892,12 +2892,12 @@ static inline int nvme_ns_detach_ctrls(int fd, __u32 nsid, * @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 *result; __u32 timeout; __u32 offset; - void *data; __u32 data_len; } __attribute__((packed, aligned(__alignof__(__u32*)))); @@ -2934,9 +2934,9 @@ int nvme_fw_download(struct nvme_fw_download_args *args); * @bpid: Set to true to select the boot partition id */ struct nvme_fw_commit_args { + __u32 *result; int args_size; int fd; - __u32 *result; __u32 timeout; enum nvme_fw_commit_ca action; __u8 slot; @@ -2958,31 +2958,31 @@ int nvme_fw_commit(struct nvme_fw_commit_args *args); /** * nvme_security_send_args - Arguments for the NVMe Security Send command - * @fd: File descriptor of nvme device * @result: The command completion result from CQE dword0 + * @data: Security data payload to send + * @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 - * @tl: Protocol specific transfer length - * @data: Security data payload to send - * @data_len: Data length of the payload in bytes */ struct nvme_security_send_args { + __u32 *result; + void *data; int args_size; int fd; - __u32 *result; __u32 timeout; __u32 nsid; + __u32 tl; + __u32 data_len; __u8 nssf; __u8 spsp0; __u8 spsp1; __u8 secp; - __u32 tl; - void *data; - __u32 data_len; } __attribute__((packed, aligned(__alignof__(__u32*)))); /** @@ -3005,31 +3005,31 @@ int nvme_security_send(struct nvme_security_send_args *args); /** * nvme_security_receive_args - Arguments for the NVMe Security Receive command - * @fd: File descriptor of nvme device * @result: The command completion result from CQE dword0 - * @timeout: Timeout in ms + * @data: Security data payload to send + * @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 - * @al: Protocol specific allocation length - * @data: Security data payload to send - * @data_len: Data length of the payload in bytes */ struct nvme_security_receive_args { + __u32 *result; + void *data; int args_size; int fd; - __u32 *result; __u32 timeout; __u32 nsid; + __u32 al; + __u32 data_len; __u8 nssf; __u8 spsp0; __u8 spsp1; __u8 secp; - __u32 al; - void *data; - __u32 data_len; } __attribute__((packed, aligned(__alignof__(__u32*)))); /** @@ -3043,27 +3043,27 @@ int nvme_security_receive(struct nvme_security_receive_args *args); /** * nvme_get_lba_status_args - Arguments for the NVMe Get LBA Status command - * @fd: File descriptor of nvme device + * @lbas: Data payload to return status descriptors * @result: The command completion result from CQE dword0 + * @slba: Starting logical block address to check statuses + * @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 - * @slba: Starting logical block address to check statuses - * @lbas: Data payload to return status descriptors * @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 *result; __u32 timeout; __u32 nsid; __u32 mndw; enum nvme_lba_status_atype atype; - __u64 slba; - struct nvme_lba_status *lbas; __u16 rl; } __attribute__((packed, aligned(__alignof__(__u64)))); @@ -3081,8 +3081,9 @@ int nvme_get_lba_status(struct nvme_get_lba_status_args *args); /** * nvme_directive_send_args - Arguments for the NVMe Directive Send command - * @fd: File descriptor of nvme device * @result: If successful, the CQE dword0 value + * @data: Data payload to to be send + * @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 @@ -3092,16 +3093,16 @@ int nvme_get_lba_status(struct nvme_get_lba_status_args *args); * @dspec: Directive specific field */ struct nvme_directive_send_args { + __u32 *result; + void *data; int args_size; int fd; - __u32 *result; __u32 timeout; __u32 nsid; enum nvme_directive_send_doper doper; enum nvme_directive_dtype dtype; __u32 cdw12; __u32 data_len; - void *data; __u16 dspec; } __attribute__((packed, aligned(__alignof__(__u32*)))); @@ -3144,16 +3145,16 @@ static inline int nvme_directive_send_stream_release_identifier(int fd, __u32 nsid, __u16 stream_id) { struct nvme_directive_send_args args = { + .result = NULL, + .data = NULL, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .nsid = nsid, .doper = NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_IDENTIFIER, .dtype = NVME_DIRECTIVE_DTYPE_STREAMS, .cdw12 = 0, .data_len = 0, - .data = NULL, .dspec = stream_id, }; @@ -3171,16 +3172,16 @@ static inline int nvme_directive_send_stream_release_identifier(int fd, static inline int nvme_directive_send_stream_release_resource(int fd, __u32 nsid) { struct nvme_directive_send_args args = { + .result = NULL, + .data = NULL, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .nsid = nsid, .doper = NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE, .dtype = NVME_DIRECTIVE_DTYPE_STREAMS, .cdw12 = 0, .data_len = 0, - .data = NULL, .dspec = 0, }; @@ -3189,28 +3190,28 @@ static inline int nvme_directive_send_stream_release_resource(int fd, __u32 nsid /** * nvme_directive_recv_args - Arguments for the NVMe Directive Receive command - * @fd: File descriptor of nvme device * @result: If successful, the CQE dword0 value + * @data: Usespace address of data payload + * @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 * @dw12: Directive specific command dword12 * @data_len: Length of data payload in bytes - * @data: Usespace address of data payload * @dspec: Directive specific field */ struct nvme_directive_recv_args { + __u32 *result; + void *data; int args_size; int fd; - __u32 *result; __u32 timeout; __u32 nsid; enum nvme_directive_receive_doper doper; enum nvme_directive_dtype dtype; __u32 cdw12; __u32 data_len; - void *data; __u16 dspec; } __attribute__((packed, aligned(__alignof__(__u32*)))); @@ -3235,16 +3236,16 @@ static inline int nvme_directive_recv_identify_parameters(int fd, __u32 nsid, struct nvme_id_directives *id) { struct nvme_directive_recv_args args = { + .result = NULL, + .data = id, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .nsid = nsid, .doper = NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM, .dtype = NVME_DIRECTIVE_DTYPE_IDENTIFY, .cdw12 = 0, .data_len = sizeof(*id), - .data = id, .dspec = 0, }; @@ -3263,16 +3264,16 @@ static inline int nvme_directive_recv_stream_parameters(int fd, __u32 nsid, struct nvme_streams_directive_params *parms) { struct nvme_directive_recv_args args = { + .result = NULL, + .data = parms, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .nsid = nsid, .doper = NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM, .dtype = NVME_DIRECTIVE_DTYPE_STREAMS, .cdw12 = 0, .data_len = sizeof(*parms), - .data = parms, .dspec = 0, }; @@ -3292,16 +3293,16 @@ static inline int nvme_directive_recv_stream_status(int fd, __u32 nsid, struct nvme_streams_directive_status *id) { struct nvme_directive_recv_args args = { + .result = NULL, + .data = id, .args_size = sizeof(args), .fd = fd, - .result = NULL, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .nsid = nsid, .doper = NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS, .dtype = NVME_DIRECTIVE_DTYPE_STREAMS, .cdw12 = 0, .data_len = sizeof(*id), - .data = id, .dspec = 0, }; @@ -3320,16 +3321,16 @@ static inline int nvme_directive_recv_stream_allocate(int fd, __u32 nsid, __u16 nsr, __u32 *result) { struct nvme_directive_recv_args args = { + .result = result, + .data = NULL, .args_size = sizeof(args), .fd = fd, - .result = result, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .nsid = nsid, .doper = NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE, .dtype = NVME_DIRECTIVE_DTYPE_STREAMS, .cdw12 = nsr, .data_len = 0, - .data = NULL, .dspec = 0, }; @@ -3338,20 +3339,20 @@ static inline int nvme_directive_recv_stream_allocate(int fd, __u32 nsid, /** * nvme_capacity_mgmt_args - Arguments for the NVMe Capacity Management command + * @result: If successful, the CQE dword0 value * @fd: File descriptor of nvme device * @dw11: Least significant 32 bits of the capacity in bytes of the * Endurance Group or NVM Set to be created * @dw12: Most significant 32 bits of the capacity in bytes of the * Endurance Group or NVM Set to be created - * @result: If successful, the CQE dword0 value * @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 *result; __u32 timeout; __u32 cdw11; __u32 cdw12; @@ -3380,9 +3381,9 @@ int nvme_capacity_mgmt(struct nvme_capacity_mgmt_args *args); * @uuid: UUID Index if controller supports this id selection method */ struct nvme_lockdown_args { + __u32 *result; int args_size; int fd; - __u32 *result; __u32 timeout; __u8 scp; __u8 prhbt; @@ -3409,12 +3410,12 @@ int nvme_lockdown(struct nvme_lockdown_args *args); * @value: The value to set the property */ struct nvme_set_property_args { + __u64 value; + __u32 *result; int args_size; int fd; - __u32 *result; __u32 timeout; int offset; - __u64 value; } __attribute__((packed, aligned(__alignof__(__u64)))); /** @@ -3431,15 +3432,15 @@ int nvme_set_property(struct nvme_set_property_args *args); /** * nvme_get_property_args - Arguments for NVMe Get Property command - * @fd: File descriptor of nvme device * @value: Where the property's value will be stored on success + * @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; - __u64 *value; __u32 timeout; int offset; } __attribute__((packed, aligned(__alignof__(__u64*)))); @@ -3458,27 +3459,27 @@ int nvme_get_property(struct nvme_get_property_args *args); /** * nvme_sanitize_nvm_args - Arguments for the NVMe Sanitize NVM command - * @fd: File descriptor of nvme device * @result: The command completion result from CQE dword0 + * @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 - * @ovrpat: Overwrite pattern */ struct nvme_sanitize_nvm_args { + __u32 *result; int args_size; int fd; - __u32 *result; __u32 timeout; enum nvme_sanitize_sanact sanact; + __u32 ovrpat; bool ause; __u8 owpass; bool oipbp; bool nodas; - __u32 ovrpat; } __attribute__((packed, aligned(__alignof__(__u32*)))); /** @@ -3502,16 +3503,16 @@ int nvme_sanitize_nvm(struct nvme_sanitize_nvm_args *args); /** * nvme_dev_self_test_args - Arguments for the NVMe Device Self Test command + * @result: The command completion result from CQE dword0 * @fd: File descriptor of nvme device * @nsid: Namespace ID to test * @stc: Self test code, see &enum nvme_dst_stc * @timeout: Timeout in ms - * @result: The command completion result from CQE dword0 */ struct nvme_dev_self_test_args { + __u32 *result; int args_size; int fd; - __u32 *result; __u32 timeout; __u32 nsid; enum nvme_dst_stc stc; @@ -3549,9 +3550,9 @@ int nvme_dev_self_test(struct nvme_dev_self_test_args *args); * @nr: Number of resources being allocated or assigned */ struct nvme_virtual_mgmt_args { + __u32 *result; int args_size; int fd; - __u32 *result; __u32 timeout; enum nvme_virt_mgmt_act act; enum nvme_virt_mgmt_rt rt; @@ -3598,13 +3599,18 @@ static inline int nvme_flush(int fd, __u32 nsid) { /** * nvme_io_args - Arguments for NVMe I/O commands - * @fd: File descriptor of nvme device + * @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 - * @timeout: Timeout in ms - * @nsid: Namespace ID * @data: Pointer to user address of the data buffer * @metadata: Pointer to user address of the metadata buffer - * @slba: Starting logical block + * @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 * @nbl: 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. @@ -3616,31 +3622,26 @@ static inline int nvme_flush(int fd, __u32 nsid) { * @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. - * @data_len: Length of user buffer, @data, in bytes - * @storage_tag: This filed specifies Variable Sized Expected Logical Block - * Storage Tag (ELBST) and Expected Logical Block Reference - * Tag (ELBRT) - * @metadata_len:Length of user buffer, @metadata, in bytes * @dsm: Data set management attributes, see &enum nvme_io_dsm_flags * @dspec: Directive specific value */ struct nvme_io_args { + __u64 slba; + __u64 storage_tag; + __u32 *result; + void *data; + void *metadata; int args_size; int fd; - __u32 *result; __u32 timeout; __u32 nsid; - void *data; - void *metadata; - __u64 slba; + __u32 reftag; + __u32 data_len; + __u32 metadata_len; __u16 nlb; __u16 control; __u16 apptag; __u16 appmask; - __u32 reftag; - __u32 data_len; - __u64 storage_tag; - __u32 metadata_len; __u8 dsm; __u8 dspec; } __attribute__((__packed__, aligned(__alignof__(__u64)))); @@ -3742,21 +3743,21 @@ static inline int nvme_verify(struct nvme_io_args *args) /** * nvme_dsm_args - Arguments for the NVMe Dataset Management command - * @fd: File descriptor of nvme device * @result: The command completion result from CQE dword0 + * @dsm: The data set management attributes + * @fd: File descriptor of nvme device * @timeout: Timeout in ms * @nsid: Namespace identifier - * @dsm: The data set management attributes * @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 *result; __u32 timeout; __u32 nsid; - struct nvme_dsm_range *dsm; __u32 attrs; __u16 nr_ranges; } __attribute__((packed, aligned(__alignof__(__u32*)))); @@ -3778,43 +3779,43 @@ int nvme_dsm(struct nvme_dsm_args *args); /** * nvme_copy_args - Arguments for the NVMe Copy command - * @fd: File descriptor of the nvme device + * @sdlba: Start destination LBA * @result: The command completion result from CQE dword0 + * @copy: Range descriptior + * @fd: File descriptor of the nvme device * @timeout: Timeout in ms * @nsid: Namespace identifier - * @copy: Range descriptior - * @sdlba: Start destination LBA + * @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 - * @lr: Limited retry - * @fua: Force unit access - * @ilbrt: Initial logical block reference tag - * @lbatm: Logical block application tag mask - * @lbat: Logical block application tag */ struct nvme_copy_args { + __u64 sdlba; + __u32 *result; + struct nvme_copy_range *copy; int args_size; int fd; - __u32 *result; __u32 timeout; __u32 nsid; - struct nvme_copy_range *copy; - __u64 sdlba; + __u32 ilbrt; + int lr; + int fua; __u16 nr; __u16 dspec; + __u16 lbatm; + __u16 lbat; __u8 prinfor; __u8 prinfow; __u8 dtype; __u8 format; - int lr; - int fua; - __u32 ilbrt; - __u16 lbatm; - __u16 lbat; } __attribute__((packed, aligned(__alignof__(__u64)))); /** @@ -3829,27 +3830,27 @@ int nvme_copy(struct nvme_copy_args *args); /** * nvme_resv_acquire_args - Arguments for the NVMe Reservation Acquire Comand - * @fd: File descriptor of nvme device + * @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 + * @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 - * @nrkey: The reservation key to be unregistered from the namespace if - * the action is preempt - * @iekey: Set to ignore the existing key */ struct nvme_resv_acquire_args { + __u64 crkey; + __u64 nrkey; + __u32 *result; int args_size; int fd; - __u32 *result; __u32 timeout; __u32 nsid; enum nvme_resv_rtype rtype; enum nvme_resv_racqa racqa; - __u64 crkey; - __u64 nrkey; bool iekey; } __attribute__((packed, aligned(__alignof__(__u64)))); @@ -3868,26 +3869,27 @@ int nvme_resv_acquire(struct nvme_resv_acquire_args *args); /** * 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 * @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 - * @crkey: The current reservation key associated with the host - * @nrkey: The new reservation key to be register if action is register or - * replace * @timeout: Timeout in ms */ struct nvme_resv_register_args { + __u64 crkey; + __u64 nrkey; + __u32 *result; int args_size; int fd; - __u32 *result; __u32 timeout; __u32 nsid; enum nvme_resv_rrega rrega; enum nvme_resv_cptpl cptpl; - __u64 crkey; - __u64 nrkey; bool iekey; } __attribute__((packed, aligned(__alignof__(__u64)))); @@ -3905,24 +3907,24 @@ int nvme_resv_register(struct nvme_resv_register_args *args); /** * nvme_resv_release_args - Arguments for the NVMe Reservation Release Command - * @fd: File descriptor of nvme device + * @crkey: The current reservation key to release * @result: The command completion result from CQE dword0 + * @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 - * @crkey: The current reservation key to release * @iekey: Set to ignore the existing key */ struct nvme_resv_release_args { + __u64 crkey; + __u32 *result; int args_size; int fd; - __u32 *result; __u32 timeout; __u32 nsid; enum nvme_resv_rtype rtype; enum nvme_resv_rrela rrela; - __u64 crkey; bool iekey; } __attribute__((packed, aligned(__alignof__(__u64)))); @@ -3937,22 +3939,22 @@ int nvme_resv_release(struct nvme_resv_release_args *args); /** * nvme_resv_report_args - Arguments for the NVMe Reservation Report command - * @fd: File descriptor of nvme device * @result: The command completion result from CQE dword0 - * @timeout: Timeout in ms - * @nsid: Namespace identifier * @report: The user space destination address to store the reservation * report + * @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 *result; __u32 timeout; __u32 nsid; - struct nvme_resv_status *report; __u32 len; bool eds; } __attribute__((packed, aligned(__alignof__(__u32*)))); @@ -3972,27 +3974,27 @@ int nvme_resv_report(struct nvme_resv_report_args *args); /** * nvme_zns_mgmt_send_args - Arguments for the NVMe ZNS Management Send command - * @fd: File descriptor of nvme device + * @slba: Starting logical block address * @result: The command completion result from CQE dword0 + * @data: Userspace address of the data + * @fd: File descriptor of nvme device * @timeout: timeout in ms * @nsid: Namespace ID - * @slba: Starting logical block address * @zsa: Zone send action * @data_len: Length of @data - * @data: Userspace address of the 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 *result; __u32 timeout; __u32 nsid; - __u64 slba; enum nvme_zns_send_action zsa; __u32 data_len; - void *data; bool select_all; __u8 zsaso; } __attribute__((packed, aligned(__alignof__(__u64)))); @@ -4009,30 +4011,30 @@ int nvme_zns_mgmt_send(struct nvme_zns_mgmt_send_args *args); /** * nvme_zns_mgmt_recv_args - Arguments for the NVMe ZNS Management Receive command - * @fd: File descriptor of nvme device + * @slba: Starting logical block address * @result: The command completion result from CQE dword0 + * @data: Userspace address of the data + * @fd: File descriptor of nvme device * @timeout: timeout in ms * @nsid: Namespace ID - * @slba: Starting logical block address * @zra: zone receive action * @data_len: Length of @data - * @data: Userspace address of the 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 *result; __u32 timeout; __u32 nsid; - __u64 slba; enum nvme_zns_recv_action zra; __u32 data_len; - void *data; __u16 zrasf; bool zras_feat; -} __attribute__((packed, aligned(__alignof__(__u32*)))); +} __attribute__((packed, aligned(__alignof__(__u64)))); /** * nvme_zns_mgmt_recv() - @@ -4066,16 +4068,16 @@ static inline int nvme_zns_report_zones(int fd, __u32 nsid, __u64 slba, __u32 timeout, __u32 *result) { struct nvme_zns_mgmt_recv_args args = { + .slba = slba, + .result = result, + .data = data, .args_size = sizeof(args), .fd = fd, - .result = result, .timeout = timeout, .nsid = nsid, - .slba = slba, .zra = extended ? NVME_ZNS_ZRA_EXTENDED_REPORT_ZONES : NVME_ZNS_ZRA_REPORT_ZONES, .data_len = data_len, - .data = data, .zrasf = opts, .zras_feat = partial, }; @@ -4085,37 +4087,37 @@ static inline int nvme_zns_report_zones(int fd, __u32 nsid, __u64 slba, /** * nvme_zns_append_args - Arguments for the NVMe ZNS Append command + * @zslba: Zone start logical block address * @fd: File descriptor of nvme device * @result: The command completion result from CQE dword0 + * @data: Userspace address of the data + * @metadata: Userspace address of the metadata * @timeout: Timeout in ms * @nsid: Namespace ID - * @zslba: Zone start logical block address + * @ilbrt: Initial logical block reference tag + * @data_len: Length of @data + * @metadata_len: Length of @metadata * @nlb: Number of logical blocks * @control: - * @ilbrt: Initial logical block reference tag * @lbat: Logical block application tag * @lbatm: Logical block application tag mask - * @data_len: Length of @data - * @data: Userspace address of the data - * @metadata: Userspace address of the metadata - * @metadata_len: Length of @metadata */ struct nvme_zns_append_args { + __u64 zslba; + __u64 *result; + void *data; + void *metadata; int args_size; int fd; - __u64 *result; __u32 timeout; __u32 nsid; - __u64 zslba; + __u32 ilbrt; + __u32 data_len; + __u32 metadata_len; __u16 nlb; __u16 control; - __u32 ilbrt; __u16 lbat; __u16 lbatm; - __u32 data_len; - void *data; - void *metadata; - __u32 metadata_len; } __attribute__((packed, aligned(__alignof__(__u64)))); /** From 3af35b9ef9a1b7823c91c0db71012fa757cdc916 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Feb 2022 07:50:40 +0100 Subject: [PATCH 0412/1564] Rework nvme_scan_filter() Split off nvme_scan_filter() into nvme_create_root() and export the remaining functionality as nvme_scan_topology(). With that nvme_scan_filter() becomes pointless as the component functions can be called directly. Signed-off-by: Hannes Reinecke --- doc/libnvme.rst | 8 -------- doc/man/nvme_scan_filter.2 | 8 -------- src/libnvme.map | 3 ++- src/nvme/tree.c | 12 +++++++----- src/nvme/tree.h | 32 +++++++++++++++++++++----------- test/test.c | 6 ++++-- 6 files changed, 34 insertions(+), 35 deletions(-) delete mode 100644 doc/man/nvme_scan_filter.2 diff --git a/doc/libnvme.rst b/doc/libnvme.rst index 7f10748cfd..4b4f8a247a 100644 --- a/doc/libnvme.rst +++ b/doc/libnvme.rst @@ -5840,14 +5840,6 @@ The nvme command status if a response was received (see ``nvme_subsystem_t s`` -.. c:function:: nvme_root_t nvme_scan_filter (nvme_scan_filter_t f) - - -**Parameters** - -``nvme_scan_filter_t f`` - - .. c:function:: nvme_root_t nvme_scan () diff --git a/doc/man/nvme_scan_filter.2 b/doc/man/nvme_scan_filter.2 deleted file mode 100644 index 8e9e62e35c..0000000000 --- a/doc/man/nvme_scan_filter.2 +++ /dev/null @@ -1,8 +0,0 @@ -.TH "nvme_scan_filter" 2 "nvme_scan_filter" "February 2020" "libnvme Manual" -.SH NAME -nvme_scan_filter \- -.SH SYNOPSIS -.B "nvme_root_t" nvme_scan_filter -.BI "(nvme_scan_filter_t " f ");" -.SH ARGUMENTS -.IP "f" 12 diff --git a/src/libnvme.map b/src/libnvme.map index 457fc086cb..009d44cd18 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -8,6 +8,7 @@ LIBNVME_1_0 { nvme_capacity_mgmt; nvme_compare; nvme_copy; + nvme_create_root; nvme_create_ctrl; nvme_ctrl_disconnect; nvme_ctrl_first_ns; @@ -241,7 +242,7 @@ LIBNVME_1_0 { nvme_scan_ctrl; nvme_scan_ctrl_namespace_paths; nvme_scan_ctrl_namespaces; - nvme_scan_filter; + nvme_scan_topology; nvme_scan_namespace; nvme_scan_subsystem_namespaces; nvme_scan_subsystems; diff --git a/src/nvme/tree.c b/src/nvme/tree.c index cbdcff5220..a2fe5335d1 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -71,11 +71,14 @@ nvme_host_t nvme_default_host(nvme_root_t r) return h; } -static int nvme_scan_topology(struct nvme_root *r, nvme_scan_filter_t f) +int nvme_scan_topology(struct nvme_root *r, nvme_scan_filter_t f) { struct dirent **subsys, **ctrls; int i, num_subsys, num_ctrls, ret; + if (!r) + return 0; + num_ctrls = nvme_scan_ctrls(&ctrls); if (num_ctrls < 0) { nvme_msg(r, LOG_DEBUG, "failed to scan ctrls: %s\n", @@ -118,7 +121,7 @@ static int nvme_scan_topology(struct nvme_root *r, nvme_scan_filter_t f) return 0; } -nvme_root_t nvme_scan_filter(nvme_scan_filter_t f, FILE *fp, int log_level) +nvme_root_t nvme_create_root(FILE *fp, int log_level) { struct nvme_root *r = calloc(1, sizeof(*r)); @@ -131,7 +134,6 @@ nvme_root_t nvme_scan_filter(nvme_scan_filter_t f, FILE *fp, int log_level) if (fp) r->fp = fp; list_head_init(&r->hosts); - nvme_scan_topology(r, f); return r; } @@ -147,10 +149,10 @@ void nvme_read_config(nvme_root_t r, const char *config_file) nvme_root_t nvme_scan(const char *config_file) { - nvme_root_t r = nvme_scan_filter(NULL, NULL, DEFAULT_LOGLEVEL); + nvme_root_t r = nvme_create_root(NULL, DEFAULT_LOGLEVEL); + nvme_scan_topology(r, NULL); nvme_read_config(r, config_file); - return r; } diff --git a/src/nvme/tree.h b/src/nvme/tree.h index 0225d091b4..00b75b00a6 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -56,6 +56,23 @@ typedef struct nvme_root *nvme_root_t; */ typedef bool (*nvme_scan_filter_t)(nvme_subsystem_t); +/** + * nvme_create_root() - Initialize root object + * @fp: filedescriptor for logging messages + * @log_level: logging level to use + * + * Return: initialized nvme_root_t structure + */ +nvme_root_t nvme_create_root(FILE *fp, int log_level); + +/** + * nvme_free_tree() - Free root object + * @r: nvme_root_t object + * + * Free an nvme_root_t object and all attached objects + */ +void nvme_free_tree(nvme_root_t r); + /** * nvme_first_host() - * @r: @@ -967,17 +984,16 @@ const char *nvme_subsystem_get_name(nvme_subsystem_t s); const char *nvme_subsystem_get_type(nvme_subsystem_t s); /** - * nvme_scan_filter() - Scan NVMe topology and apply filter + * nvme_scan_topology() - Scan NVMe topology and apply filter + * @r: nvme_root_t object * @f: filter to apply - * @fp: filepointer for error messages - * @log_level: logging level for this structure * * Scans the NVMe topology and filters out the resulting elements * by applying @f. * - * Return: nvme_root_t structure holding the resulting elements. + * Return: Number of elements scanned */ -nvme_root_t nvme_scan_filter(nvme_scan_filter_t f, FILE *fp, int log_level); +int nvme_scan_topology(nvme_root_t r, nvme_scan_filter_t f); /** * nvme_host_get_hostnqn() - @@ -1055,12 +1071,6 @@ int nvme_update_config(nvme_root_t r); */ int nvme_dump_config(nvme_root_t r); -/** - * nvme_free_tree() - - * @r: - */ -void nvme_free_tree(nvme_root_t r); - /** * nvme_get_attr() - * @dir: diff --git a/test/test.c b/test/test.c index 3dcbd2d0bb..2f2e957656 100644 --- a/test/test.c +++ b/test/test.c @@ -318,8 +318,10 @@ int main(int argc, char **argv) printf("Test filter for common loop back target\n"); nqn_match = "testnqn"; - r = nvme_scan_filter(nvme_match_subsysnqn_filter, NULL, - DEFAULT_LOGLEVEL); + r = nvme_create_root(NULL, DEFAULT_LOGLEVEL); + if (!r) + return 1; + nvme_scan_topology(r, nvme_match_subsysnqn_filter); nvme_for_each_host(r, h) { nvme_for_each_subsystem(h, s) { printf("%s - NQN=%s\n", nvme_subsystem_get_name(s), From 36c1a8eeafc21e2d2fb9df249e4773bddd55fe5b Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Mon, 31 Jan 2022 13:22:15 +0100 Subject: [PATCH 0413/1564] linux: Rename __nvme_get_log_page() The prefix of __nvme_get_log_page() is confusing as it usually indicates this is a private function. Rename this function to nvme_get_log_page(). The already existing one nvme_get_log_page() is renamed to nvme_get_log_page_padded() which is asking for 4k transfers. Signed-off-by: Daniel Wagner --- src/libnvme.map | 2 +- src/nvme/fabrics.c | 4 ++-- src/nvme/linux.c | 17 +++++++++-------- src/nvme/linux.h | 14 +++++++------- 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/libnvme.map b/src/libnvme.map index 009d44cd18..eac4610861 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -1,6 +1,5 @@ LIBNVME_1_0 { global: - __nvme_get_log_page; __nvme_msg; nvme_admin_passthru64; nvme_admin_passthru; @@ -125,6 +124,7 @@ LIBNVME_1_0 { nvme_get_log_fw_slot; nvme_get_log_lba_status; nvme_get_log_page; + nvme_get_log_page_padded; nvme_get_log_persistent_event; nvme_get_log_predictable_lat_event; nvme_get_log_predictable_lat_nvmset; diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 945bac6049..c9f987a0b0 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -667,8 +667,8 @@ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, static int nvme_discovery_log(int fd, __u32 len, struct nvmf_discovery_log *log, bool rae) { - return __nvme_get_log_page(fd, 0, NVME_LOG_LID_DISCOVER, rae, 512, - len, log); + return nvme_get_log_page(fd, 0, NVME_LOG_LID_DISCOVER, rae, 512, + len, log); } int nvmf_get_discovery_log(nvme_ctrl_t c, struct nvmf_discovery_log **logp, diff --git a/src/nvme/linux.c b/src/nvme/linux.c index cc7a3589dd..499ff85ab2 100644 --- a/src/nvme/linux.c +++ b/src/nvme/linux.c @@ -116,8 +116,8 @@ int nvme_fw_download_seq(int fd, __u32 size, __u32 xfer, __u32 offset, return err; } -int __nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, - __u32 xfer_len, __u32 data_len, void *data) +int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, + __u32 xfer_len, __u32 data_len, void *data) { __u64 offset = 0, xfer; bool retain = true; @@ -169,10 +169,10 @@ int __nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, return 0; } -int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, - __u32 data_len, void *data) +int nvme_get_log_page_padded(int fd, __u32 nsid, __u8 log_id, bool rae, + __u32 data_len, void *data) { - return __nvme_get_log_page(fd, nsid, log_id, rae, 4096, data_len, data); + return nvme_get_log_page(fd, nsid, log_id, rae, 4096, data_len, data); } static int nvme_get_telemetry_log(int fd, bool create, bool ctrl, bool rae, @@ -222,7 +222,8 @@ static int nvme_get_telemetry_log(int fd, bool create, bool ctrl, bool rae, } log = tmp; - err = nvme_get_log_page(fd, NVME_NSID_NONE, lid, rae, size, (void *)log); + err = nvme_get_log_page_padded(fd, NVME_NSID_NONE, lid, rae, size, + (void *)log); if (!err) { *buf = log; return 0; @@ -274,8 +275,8 @@ int nvme_get_lba_status_log(int fd, bool rae, struct nvme_lba_status_log **log) buf = tmp; *log = buf; - err = nvme_get_log_page(fd, NVME_NSID_NONE, NVME_LOG_LID_LBA_STATUS, - rae, size, buf); + err = nvme_get_log_page_padded(fd, NVME_NSID_NONE, NVME_LOG_LID_LBA_STATUS, + rae, size, buf); if (!err) return 0; diff --git a/src/nvme/linux.h b/src/nvme/linux.h index d609a140ad..73b542d3e3 100644 --- a/src/nvme/linux.h +++ b/src/nvme/linux.h @@ -68,7 +68,7 @@ int nvme_get_host_telemetry(int fd, struct nvme_telemetry_log **log); int nvme_get_new_host_telemetry(int fd, struct nvme_telemetry_log **log); /** - * __nvme_get_log_page() - + * nvme_get_log_page() - * @fd: File descriptor of nvme device * @nsid: Namespace Identifier, if applicable. * @log_id: Log Identifier, see &enum nvme_cmd_get_log_lid. @@ -80,11 +80,11 @@ int nvme_get_new_host_telemetry(int fd, struct nvme_telemetry_log **log); * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int __nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, - __u32 xfer_len, __u32 data_len, void *data); +int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, + __u32 xfer_len, __u32 data_len, void *data); /** - * nvme_get_log_page() - + * nvme_get_log_page_padded() - * @fd: File descriptor of nvme device * @nsid: Namespace Identifier, if applicable. * @log_id: Log Identifier, see &enum nvme_cmd_get_log_lid. @@ -92,14 +92,14 @@ int __nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, * @data_len: Total length of the log to transfer. * @data: User address of at least &data_len to store the log. * - * Calls __nvme_get_log_page() with a default 4k transfer length, as that is + * Calls nvme_get_log_page() with a default 4k transfer length, as that is * guarnateed by the protocol to be a safe transfer size. * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, - __u32 data_len, void *data); +int nvme_get_log_page_padded(int fd, __u32 nsid, __u8 log_id, bool rae, + __u32 data_len, void *data); /** * nvme_get_ana_log_len() - Retreive size of the current ANA log From 6e268f524b32b27f3606287d86e662d9bb0c2222 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Mon, 31 Jan 2022 13:24:56 +0100 Subject: [PATCH 0414/1564] libvnme: Remove __nvme_msg from export map nvme-cli was using the library infrastructure for logging. In the meantime this has been removed, hence we can remove this function from the export map. Furthermore, move nvme_msg() and __nvme_msg() to private header. Signed-off-by: Daniel Wagner --- src/libnvme.map | 1 - src/nvme/json.c | 1 + src/nvme/log.h | 16 ---------------- src/nvme/private.h | 16 ++++++++++++++++ 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/libnvme.map b/src/libnvme.map index eac4610861..9bcc84534e 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -1,6 +1,5 @@ LIBNVME_1_0 { global: - __nvme_msg; nvme_admin_passthru64; nvme_admin_passthru; nvme_attach_ns; diff --git a/src/nvme/json.c b/src/nvme/json.c index 49468c8acc..ebc1ae4f99 100644 --- a/src/nvme/json.c +++ b/src/nvme/json.c @@ -14,6 +14,7 @@ #include "fabrics.h" #include "log.h" +#include "private.h" #define json_object_add_value_string(o, k, v) \ json_object_object_add(o, k, json_object_new_string(v)) diff --git a/src/nvme/log.h b/src/nvme/log.h index 8a0d2e3a3c..eea652d687 100644 --- a/src/nvme/log.h +++ b/src/nvme/log.h @@ -15,22 +15,6 @@ # define DEFAULT_LOGLEVEL LOG_NOTICE #endif -#if (LOG_FUNCNAME == 1) -#define __nvme_log_func __func__ -#else -#define __nvme_log_func NULL -#endif - -void __attribute__((format(printf, 4, 5))) -__nvme_msg(nvme_root_t r, int lvl, const char *func, const char *format, ...); - -#define nvme_msg(r, lvl, format, ...) \ - do { \ - if ((lvl) <= MAX_LOGLEVEL) \ - __nvme_msg(r, lvl, __nvme_log_func, \ - format, ##__VA_ARGS__); \ - } while (0) - /** * nvme_init_logging() - initialize logging * @r: nvme_root_t context diff --git a/src/nvme/private.h b/src/nvme/private.h index f33784bfb7..945b453a36 100644 --- a/src/nvme/private.h +++ b/src/nvme/private.h @@ -133,4 +133,20 @@ void json_read_config(nvme_root_t r, const char *config_file); int json_update_config(nvme_root_t r, const char *config_file); +#if (LOG_FUNCNAME == 1) +#define __nvme_log_func __func__ +#else +#define __nvme_log_func NULL +#endif + +void __attribute__((format(printf, 4, 5))) +__nvme_msg(nvme_root_t r, int lvl, const char *func, const char *format, ...); + +#define nvme_msg(r, lvl, format, ...) \ + do { \ + if ((lvl) <= MAX_LOGLEVEL) \ + __nvme_msg(r, lvl, __nvme_log_func, \ + format, ##__VA_ARGS__); \ + } while (0) + #endif /* _LIBNVME_PRIVATE_H */ From 6ea2081aa7580d2aa3ed9fba8e7ffbebd611529d Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Feb 2022 11:28:23 +0100 Subject: [PATCH 0415/1564] Remove nvme_reset_topology() Identical to nvme_refresh_topology(). Signed-off-by: Hannes Reinecke --- doc/libnvme.rst | 9 --------- doc/man/nvme_reset_topology.2 | 9 --------- src/libnvme.map | 1 - src/nvme/tree.c | 9 --------- src/nvme/tree.h | 6 ------ 5 files changed, 34 deletions(-) delete mode 100644 doc/man/nvme_reset_topology.2 diff --git a/doc/libnvme.rst b/doc/libnvme.rst index 4b4f8a247a..d9247e30d6 100644 --- a/doc/libnvme.rst +++ b/doc/libnvme.rst @@ -5849,15 +5849,6 @@ The nvme command status if a response was received (see .. c:function:: void nvme_refresh_topology (nvme_root_t r) -**Parameters** - -``nvme_root_t r`` - *undescribed* - - -.. c:function:: void nvme_reset_topology (nvme_root_t r) - - **Parameters** ``nvme_root_t r`` diff --git a/doc/man/nvme_reset_topology.2 b/doc/man/nvme_reset_topology.2 deleted file mode 100644 index 3a25e7e3d7..0000000000 --- a/doc/man/nvme_reset_topology.2 +++ /dev/null @@ -1,9 +0,0 @@ -.TH "nvme_reset_topology" 2 "nvme_reset_topology" "February 2020" "libnvme Manual" -.SH NAME -nvme_reset_topology \- -.SH SYNOPSIS -.B "void" nvme_reset_topology -.BI "(nvme_root_t " r ");" -.SH ARGUMENTS -.IP "r" 12 --- undescribed -- diff --git a/src/libnvme.map b/src/libnvme.map index 009d44cd18..a0d73caca9 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -231,7 +231,6 @@ LIBNVME_1_0 { nvme_read_config; nvme_refresh_topology; nvme_rescan_ctrl; - nvme_reset_topology; nvme_resv_acquire; nvme_resv_register; nvme_resv_release; diff --git a/src/nvme/tree.c b/src/nvme/tree.c index a2fe5335d1..21d7294e90 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -237,15 +237,6 @@ void nvme_refresh_topology(nvme_root_t r) nvme_scan_topology(r, NULL); } -void nvme_reset_topology(nvme_root_t r) -{ - struct nvme_host *h, *_h; - - nvme_for_each_host_safe(r, h, _h) - __nvme_free_host(h); - nvme_scan_topology(r, NULL); -} - void nvme_free_tree(nvme_root_t r) { struct nvme_host *h, *_h; diff --git a/src/nvme/tree.h b/src/nvme/tree.h index 00b75b00a6..be80ce844d 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -1049,12 +1049,6 @@ void nvme_read_config(nvme_root_t r, const char *config_file); */ void nvme_refresh_topology(nvme_root_t r); -/** - * nvme_reset_topology() - - * @r: - */ -void nvme_reset_topology(nvme_root_t r); - /** * nvme_update_config() - * @r: From 9fda26c59382e06bbc31682b5b1dbb9fc92c2bff Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Feb 2022 11:31:05 +0100 Subject: [PATCH 0416/1564] Rename nvme_path_get_subsystem() Misnamed, should be nvme_path_get_ctrl() to be consistent with the other library functions. Signed-off-by: Hannes Reinecke --- doc/libnvme.rst | 2 +- doc/man/nvme_path_get_subsystem.2 | 8 -------- src/libnvme.map | 2 +- src/nvme/tree.c | 2 +- src/nvme/tree.h | 4 ++-- 5 files changed, 5 insertions(+), 13 deletions(-) delete mode 100644 doc/man/nvme_path_get_subsystem.2 diff --git a/doc/libnvme.rst b/doc/libnvme.rst index d9247e30d6..1196b1c032 100644 --- a/doc/libnvme.rst +++ b/doc/libnvme.rst @@ -5643,7 +5643,7 @@ The nvme command status if a response was received (see ``nvme_path_t p`` -.. c:function:: nvme_ctrl_t nvme_path_get_subsystem (nvme_path_t p) +.. c:function:: nvme_ctrl_t nvme_path_get_ctrl (nvme_path_t p) **Parameters** diff --git a/doc/man/nvme_path_get_subsystem.2 b/doc/man/nvme_path_get_subsystem.2 deleted file mode 100644 index 17222ecdaa..0000000000 --- a/doc/man/nvme_path_get_subsystem.2 +++ /dev/null @@ -1,8 +0,0 @@ -.TH "nvme_path_get_subsystem" 2 "nvme_path_get_subsystem" "February 2020" "libnvme Manual" -.SH NAME -nvme_path_get_subsystem \- -.SH SYNOPSIS -.B "nvme_ctrl_t" nvme_path_get_subsystem -.BI "(nvme_path_t " p ");" -.SH ARGUMENTS -.IP "p" 12 diff --git a/src/libnvme.map b/src/libnvme.map index a0d73caca9..b9fa985c69 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -222,9 +222,9 @@ LIBNVME_1_0 { nvme_nvm_identify_ctrl; nvme_open; nvme_path_get_ana_state; + nvme_path_get_ctrl; nvme_path_get_name; nvme_path_get_ns; - nvme_path_get_subsystem; nvme_path_get_sysfs_dir; nvme_paths_filter; nvme_read; diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 21d7294e90..8d67ec014f 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -533,7 +533,7 @@ static int nvme_scan_subsystem(struct nvme_root *r, const char *name, return -1; } -nvme_ctrl_t nvme_path_get_subsystem(nvme_path_t p) +nvme_ctrl_t nvme_path_get_ctrl(nvme_path_t p) { return p->c; } diff --git a/src/nvme/tree.h b/src/nvme/tree.h index be80ce844d..b7e6aad616 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -658,12 +658,12 @@ const char *nvme_path_get_sysfs_dir(nvme_path_t p); const char *nvme_path_get_ana_state(nvme_path_t p); /** - * nvme_path_get_subsystem() - + * nvme_path_get_ctrl() - * @p: * * Return: */ -nvme_ctrl_t nvme_path_get_subsystem(nvme_path_t p); +nvme_ctrl_t nvme_path_get_ctrl(nvme_path_t p); /** * nvme_path_get_ns() - From 89cad74ae02a6fba9c8a798f7ca59fd86abaaf48 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Feb 2022 13:27:28 +0100 Subject: [PATCH 0417/1564] tree: document function prototypes Document all function prototypes in tree.h. Signed-off-by: Hannes Reinecke --- src/nvme/tree.h | 696 ++++++++++++++++++++++++++---------------------- 1 file changed, 372 insertions(+), 324 deletions(-) diff --git a/src/nvme/tree.h b/src/nvme/tree.h index b7e6aad616..f6ed54485a 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -61,7 +61,7 @@ typedef bool (*nvme_scan_filter_t)(nvme_subsystem_t); * @fp: filedescriptor for logging messages * @log_level: logging level to use * - * Return: initialized nvme_root_t structure + * Return: initialized nvme_root_t object */ nvme_root_t nvme_create_root(FILE *fp, int log_level); @@ -74,52 +74,57 @@ nvme_root_t nvme_create_root(FILE *fp, int log_level); void nvme_free_tree(nvme_root_t r); /** - * nvme_first_host() - - * @r: + * nvme_first_host() - Start host iterator + * @r: nvme_root_t object * - * Return: + * Return: first nvme_host_t object in an iterator */ nvme_host_t nvme_first_host(nvme_root_t r); /** - * nvme_next_host() - - * @r: - * @h: + * nvme_next_host() - Next host iterator + * @r: nvme_root_t object + * @h: previous nvme_host_t iterator * - * Return: + * Return: next nvme_host_t object in an iterator */ nvme_host_t nvme_next_host(nvme_root_t r, nvme_host_t h); /** - * nvme_host_get_root() - - * @h: + * nvme_host_get_root() - Returns nvme_root_t object + * @h: host * - * Return: + * Return: nvme_root_t object from @h */ nvme_root_t nvme_host_get_root(nvme_host_t h); /** - * nvme_lookup_host() - - * @r: + * nvme_lookup_host() - Lookup nvme_host_t object + * @r: nvme_root_t object + * @hostnqn: Host NQN + * @hostid: Host ID * - * Return: + * Lookup a nvme_host_t object based on @hostnqn and @hostid + * or create one if not found. + * + * Return: nvme_host_t object */ nvme_host_t nvme_lookup_host(nvme_root_t r, const char *hostnqn, const char *hostid); /** - * nvme_host_get_hostnqn() - - * @h: + * nvme_host_get_hostnqn() - Returns the host NQN + * @h: host * - * Return: + * Return: NVMe host NQN */ const char *nvme_host_get_hostnqn(nvme_host_t h); /** - * nvme_host_get_hostid() - - * @h: + * nvme_host_get_hostid() - Returns the host ID + * @h: host * - * Return: + * Return: NVMe Host ID */ const char *nvme_host_get_hostid(nvme_host_t h); @@ -139,117 +144,130 @@ const char *nvme_host_get_dhchap_key(nvme_host_t h); void nvme_host_set_dhchap_key(nvme_host_t h, const char *key); /** - * nvme_default_host() - - * @r: + * nvme_default_host() - Initializes the default host + * @root: nvme_root_t object + * + * Initializes the default host object based on the values in + * /etc/nvme/hostnqn and /etc/nvme/hostid and attaches it to @r. * - * Return: + * Return: nvme_host_t object */ nvme_host_t nvme_default_host(nvme_root_t r); /** - * nvme_first_subsystem() - - * @h: + * nvme_first_subsystem() - Start subsystem iterator + * @h: nvme_host_t object * - * Return: + * Return: first nvme_subsystem_t object in an iterator */ nvme_subsystem_t nvme_first_subsystem(nvme_host_t h); /** - * nvme_next_subsystem() - - * @h: - * @s: + * nvme_next_subsystem() - Next subsystem iterator + * @h: nvme_host_t object + * @s: previous nvme_subsystem_t iterator * - * Return: + * Return: next nvme_subsystem_t object in an iterator */ nvme_subsystem_t nvme_next_subsystem(nvme_host_t h, nvme_subsystem_t s); /** - * nvme_lookup_subsystem() - - * @h: - * @name: - * @subsysnqn: + * nvme_lookup_subsystem() - Lookup nvme_subsystem_t object + * @h: nvme_host_t object + * @name: Name of the subsystem (may be NULL) + * @subsysnqn: Subsystem NQN * - * Return: + * Lookup a nvme_subsystem_t object in @h base on @name (if present) + * and @subsystemnqn or create one if not found. + * + * Return: nvme_subsystme_t object */ nvme_subsystem_t nvme_lookup_subsystem(struct nvme_host *h, const char *name, const char *subsysnqn); /** - * nvme_free_subsystem() - - * @s: + * nvme_free_subsystem() - Free a subsystem + * @s: subsystem + * + * Frees @s and all related objects. */ void nvme_free_subsystem(struct nvme_subsystem *s); /** - * nvme_subsystem_get_host() - - * @s: + * nvme_subsystem_get_host() - Returns nvme_host_t object + * @s: subsystem * - * Return: + * Return: nvme_host_t object from @s */ nvme_host_t nvme_subsystem_get_host(nvme_subsystem_t s); /** - * nvme_ctrl_first_ns() - - * @c: + * nvme_ctrl_first_ns() - Start namespace iterator + * @c: nvme_ctrl_t object * - * Return: + * Return: first nvme_ns_t object of an @c iterator */ nvme_ns_t nvme_ctrl_first_ns(nvme_ctrl_t c); /** - * nvme_ctrl_next_ns() - - * @c: - * @n: + * nvme_ctrl_next_ns() - Next namespace iterator + * @c: nvme_ctrl_t object + * @n: previous nvme_ns_t iterator * - * Return: + * Return: next nvme_ns_t object of an @c iterator */ nvme_ns_t nvme_ctrl_next_ns(nvme_ctrl_t c, nvme_ns_t n); /** - * nvme_ctrl_first_path() - - * @c: + * nvme_ctrl_first_path() - Start path iterator + * @c: nvme_ctrl_t object * - * Return: + * Return: First nvme_path_t object of an @c iterator */ nvme_path_t nvme_ctrl_first_path(nvme_ctrl_t c); /** - * nvme_ctrl_next_path() - - * @c: - * @p: + * nvme_ctrl_next_path() - Next path iterator + * @c: nvme_ctrl_t object + * @p: previous nvme_path_t object of an @c iterator * * Return: */ nvme_path_t nvme_ctrl_next_path(nvme_ctrl_t c, nvme_path_t p); /** - * nvme_subsystem_first_ctrl() - - * @s: + * nvme_subsystem_first_ctrl() - First ctrl iterator + * @s: nvme_subsystem_t object * - * Return: + * Return: First nvme_ctrl_t object of an @s iterator */ nvme_ctrl_t nvme_subsystem_first_ctrl(nvme_subsystem_t s); /** - * nvme_subsystem_next_ctrl() - - * @s: - * @c: + * nvme_subsystem_next_ctrl() - Next ctrl iterator + * @s: nvme_subsystem_t object + * @c: previous nvme_ctrl_t object of an @s iterator * - * Return: + * Return: next nvme_ctrl_t object of an @s iterator */ nvme_ctrl_t nvme_subsystem_next_ctrl(nvme_subsystem_t s, nvme_ctrl_t c); /** - * nvme_lookup_ctrl() - - * @s: - * @transport: - * @traddr: - * @host_traddr: - * @host_iface: - * @trsvcid: + * nvme_lookup_ctrl() - Lookup nvme_ctrl_t object + * @s: nvme_subsystem_t object + * @transport: transport name + * @traddr: transport address + * @host_traddr: host transport address + * @host_iface: host interface name + * @trsvcid: transport service identifier * - * Return: + * Lookup a nvme_ctrl_t object in @s based on @transport, @traddr, + * @host_traddr, @host_iface, and @trsvcid. @transport must be specified, + * other fields may be required depending on the transport. A new + * object is created if none is found. + * + * Return: nvme_ctrl_t object */ nvme_ctrl_t nvme_lookup_ctrl(nvme_subsystem_t s, const char *transport, const char *traddr, const char *host_traddr, @@ -266,10 +284,10 @@ nvme_ctrl_t nvme_lookup_ctrl(nvme_subsystem_t s, const char *transport, * @host_iface: Host interface name * @trsvcid: Transport service ID * - * Creates an unconnected nvme_ctrl_t structure to be used for + * Creates an unconnected nvme_ctrl_t object to be used for * nvme_add_ctrl(). * - * Return: nvme_ctrl_t structure + * Return: nvme_ctrl_t object */ nvme_ctrl_t nvme_create_ctrl(nvme_root_t r, const char *subsysnqn, const char *transport, @@ -278,19 +296,19 @@ nvme_ctrl_t nvme_create_ctrl(nvme_root_t r, /** - * nvme_subsystem_first_ns() - - * @s: + * nvme_subsystem_first_ns() - Start namespace iterator + * @s: nvme_subsystem_t object * - * Return: + * Return: First nvme_ns_t object of an @s iterator */ nvme_ns_t nvme_subsystem_first_ns(nvme_subsystem_t s); /** - * nvme_subsystem_next_ns() - - * @s: - * @n: + * nvme_subsystem_next_ns() - Next namespace iterator + * @s: nvme_subsystem_t object + * @n: previous nvme_ns_t iterator * - * Return: + * Return: Next nvme_ns_t object of an @s iterator */ nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n); @@ -391,102 +409,103 @@ nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n); n = nvme_subsystem_next_ns(s, n)) /** - * nvme_ns_get_fd() - - * @n: + * nvme_ns_get_fd() - Get associated filedescriptor + * @n: nvme_ns_t object * - * Return: + * Return: Filedescriptor associated with @n or -1 */ int nvme_ns_get_fd(nvme_ns_t n); /** - * nvme_ns_get_nsid() - - * @n: + * nvme_ns_get_nsid() - NSID of an nvme_ns_t object + * @n: nvme_ns_t object * - * Return: + * Return: NSID of @n */ int nvme_ns_get_nsid(nvme_ns_t n); /** - * nvme_ns_get_lba_size() - - * @n: + * nvme_ns_get_lba_size() - LBA size of an nvme_ns_t object + * @n: nvme_ns_t object * - * Return: + * Return: LBA size of @n */ int nvme_ns_get_lba_size(nvme_ns_t n); /** - * nvme_ns_get_meta_size() - - * @n: + * nvme_ns_get_meta_size() - Metadata size of an nvme_ns_t object + * @n: nvme_ns_t object * - * Return: + * Return: Metadata size of @n */ int nvme_ns_get_meta_size(nvme_ns_t n); /** - * nvme_ns_get_lba_count() - - * @n: + * nvme_ns_get_lba_count() - LBA count of an nvme_ns_t object + * @n: nvme_ns_t object * - * Return: + * Return: LBA count of @n */ uint64_t nvme_ns_get_lba_count(nvme_ns_t n); /** - * nvme_ns_get_lba_util() - - * @n: + * nvme_ns_get_lba_util() - LBA utilisation of an nvme_ns_t object + * @n: nvme_ns_t object * - * Return: + * Return: LBA utilisation of @n */ uint64_t nvme_ns_get_lba_util(nvme_ns_t n); /** - * nvme_ns_get_csi() - - * @n: + * nvme_ns_get_csi() - Command set identifier of an nvme_ns_t object + * @n: nvme_ns_t object * * Return: The namespace's command set identifier in use */ enum nvme_csi nvme_ns_get_csi(nvme_ns_t n); /** - * nvme_ns_get_eui64() - - * @n: + * nvme_ns_get_eui64() - 64-bit eui of an nvme_ns_t object + * @n: nvme_ns_t object * * Returns a pointer to the 64-bit eui */ const uint8_t *nvme_ns_get_eui64(nvme_ns_t n); /** - * nvme_ns_get_nguid() - - * @n: + * nvme_ns_get_nguid() - 128-bit nguid of an nvme_ns_t object + * @n: nvme_ns_t object * * Returns a pointer to the 128-bit nguid */ const uint8_t *nvme_ns_get_nguid(nvme_ns_t n); /** - * nvme_ns_get_uuid() - - * @n: - * @out: + * nvme_ns_get_uuid() - UUID of an nvme_ns_t object + * @n: nvme_ns_t object + * @out: buffer for the UUID * - * Copies the namespace's uuid to the destination buffer + * Copies the namespace's uuid into @out */ #ifdef CONFIG_LIBUUID void nvme_ns_get_uuid(nvme_ns_t n, uuid_t out); #else void nvme_ns_get_uuid(nvme_ns_t n, uint8_t *out); #endif + /** - * nvme_ns_get_sysfs_dir() - - * @n: + * nvme_ns_get_sysfs_dir() - sysfs directory of an nvme_ns_t object + * @n: nvme_ns_t object * - * Return: + * Return: sysfs directory name of @n */ const char *nvme_ns_get_sysfs_dir(nvme_ns_t n); /** - * nvme_ns_get_name() - - * @n: + * nvme_ns_get_name() - sysfs name of an nvme_ns_t object + * @n: nvme_ns_t object * - * Return: + * Return: sysfs name of @n */ const char *nvme_ns_get_name(nvme_ns_t n); @@ -499,321 +518,329 @@ const char *nvme_ns_get_name(nvme_ns_t n); const char *nvme_ns_get_generic_name(nvme_ns_t n); /** - * nvme_ns_get_firmware() - - * @n: + * nvme_ns_get_firmware() - Firmware string of an nvme_ns_t object + * @n: nvme_ns_t object * - * Return: + * Return: Firmware string of @n */ const char *nvme_ns_get_firmware(nvme_ns_t n); /** - * nvme_ns_get_serial() - - * @n: + * nvme_ns_get_serial() - Serial number of an nvme_ns_t object + * @n: nvme_ns_t object * - * Return: + * Return: Serial number string of @n */ const char *nvme_ns_get_serial(nvme_ns_t n); /** - * nvme_ns_get_model() - - * @n: + * nvme_ns_get_model() - Model of an nvme_ns_t object + * @n: nvme_ns_t object * - * Return: + * Return: Model string of @n */ const char *nvme_ns_get_model(nvme_ns_t n); /** - * nvme_ns_get_subsystem() - - * @n: + * nvme_ns_get_subsystem() - nvme_subsystem_t of an nvme_ns_t object + * @n: nvme_ns_t object * - * Return: + * Return: nvme_subsystem_t object of @n */ nvme_subsystem_t nvme_ns_get_subsystem(nvme_ns_t n); /** - * nvme_ns_get_ctrl() - - * @n: + * nvme_ns_get_ctrl() - nvme_ctrl_t of an nvme_ns_t object + * @n: nvme_ns_t object * - * Return: + * nvme_ctrl_t object may be NULL for a multipathed namespace + * + * Return: nvme_ctrl_t object of @n if present */ nvme_ctrl_t nvme_ns_get_ctrl(nvme_ns_t n); /** - * nvme_free_ns() - - * @ns: + * nvme_free_ns() - free an nvme_ns_t object + * @ns: nvme_ns_t object */ void nvme_free_ns(struct nvme_ns *n); /** - * nvme_ns_read() - - * @n: - * @buf: - * @offset: - * @count: + * nvme_ns_read() - Read from a namespace + * @n: nvme_ns_t object + * @buf: buffer into which the data will be transferred + * @offset: LBA offset of @n + * @count: Number of sectors in @buf * - * Return: + * Return: Number of sectors read or -1 on error. */ int nvme_ns_read(nvme_ns_t n, void *buf, off_t offset, size_t count); /** - * nvme_ns_write() - - * @n: - * @buf: - * @offset: - * @count: + * nvme_ns_write() - Write to a namespace + * @n: nvme_ns_t object + * @buf: buffer with data to be written + * @offset: LBA offset of @n + * @count: Number of sectors in @buf * - * Return: + * Return: Number of sectors written or -1 on error */ int nvme_ns_write(nvme_ns_t n, void *buf, off_t offset, size_t count); /** - * nvme_ns_verify() - - * @n: - * @offset: - * @count: + * nvme_ns_verify() - Verify data on a namespace + * @n: nvme_ns_t object + * @offset: LBA offset of @n + * @count: Number of sectors to be verified * - * Return: + * Return: Number of sectors verified */ int nvme_ns_verify(nvme_ns_t n, off_t offset, size_t count); /** - * nvme_ns_compare() - - * @n: - * @buf: - * @offset: - * @count: + * nvme_ns_compare() - Compare data on a namespace + * @n: nvme_ns_t object + * @buf: buffer with data to be compared + * @offset: LBA offset of @n + * @count: Number of sectors in @buf * - * Return: + * Return: Number of sectors compared */ int nvme_ns_compare(nvme_ns_t n, void *buf, off_t offset, size_t count); /** - * nvme_ns_write_zeros() - - * @n: - * @offset: - * @count: + * nvme_ns_write_zeros() - Write zeros to a namespace + * @n: nvme_ns_t object + * @offset: LBA offset in @n + * @count: Number of sectors to be written * - * Return: + * Return: Number of sectors written */ int nvme_ns_write_zeros(nvme_ns_t n, off_t offset, size_t count); /** - * nvme_ns_write_uncorrectable() - - * @n: - * @offset: - * @count: + * nvme_ns_write_uncorrectable() - Issus a 'write uncorrectable' command + * @n: nvme_ns_t object + * @offset: LBA offset in @n + * @count: Number of sectors to be written * - * Return: + * Return: Number of sectors written */ int nvme_ns_write_uncorrectable(nvme_ns_t n, off_t offset, size_t count); /** - * nvme_ns_flush() - - * @n: + * nvme_ns_flush() - Flush data to a namespace + * @n: nvme_ns_t object * - * Return: + * Return: 0 on success, -1 on error. */ int nvme_ns_flush(nvme_ns_t n); /** - * nvme_ns_identify() - - * @n: - * @ns: + * nvme_ns_identify() - Issue an 'identify namespace' command + * @n: nvme_ns_t object + * @ns: nvme_id_ns buffer * - * Return: + * Writes the data returned by the 'identify namespace' command + * into @ns. + * + * Return: 0 on success, -1 on error. */ int nvme_ns_identify(nvme_ns_t n, struct nvme_id_ns *ns); /** - * nvme_ns_identify_descs() - - * @n: - * @descs: + * nvme_ns_identify_descs() - Issue an 'identify descriptors' command + * @n: nvme_ns_t object + * @descs: list of identify descriptors * - * Return: + * Writes the data returned by the 'identify descriptors' command + * into @descs. + * + * Return: 0 on success, -1 on error. */ int nvme_ns_identify_descs(nvme_ns_t n, struct nvme_ns_id_desc *descs); /** - * nvme_path_get_name() - - * @p: + * nvme_path_get_name() - sysfs name of an nvme_path_t object + * @p: nvme_path_t object * - * Return: + * Return: sysfs name of @p */ const char *nvme_path_get_name(nvme_path_t p); /** - * nvme_path_get_sysfs_dir() - - * @p: + * nvme_path_get_sysfs_dir() - sysfs directory of an nvme_path_t object + * @p: nvme_path_t object * - * Return: + * Return: sysfs directory of @p */ const char *nvme_path_get_sysfs_dir(nvme_path_t p); /** - * nvme_path_get_ana_state() - - * @p: + * nvme_path_get_ana_state() - ANA state of an nvme_path_t object + * @p: nvme_path_t object * - * Return: + * Return: ANA (Asynchronous Namespace Access) state of @p */ const char *nvme_path_get_ana_state(nvme_path_t p); /** - * nvme_path_get_ctrl() - - * @p: + * nvme_path_get_ctrl() - parent controller of an nvme_path_t object + * @p: nvme_path_t object * - * Return: + * Return: parent controller if present */ nvme_ctrl_t nvme_path_get_ctrl(nvme_path_t p); /** - * nvme_path_get_ns() - - * @p: + * nvme_path_get_ns() - parent namespace of an nvme_path_t object + * @p: nvme_path_t object * - * Return: + * Return: parent namespace if present */ nvme_ns_t nvme_path_get_ns(nvme_path_t p); /** - * nvme_ctrl_get_fd() - - * @c: + * nvme_ctrl_get_fd() - Get associated filedescriptor + * @c: nvme_ctrl_t object * - * Return: + * Return: Filedescriptor associated with @c or -1 */ int nvme_ctrl_get_fd(nvme_ctrl_t c); /** - * nvme_ctrl_get_name() - - * @c: + * nvme_ctrl_get_name() - sysfs name of an nvme_ctrl_t object + * @c: nvme_ctrl_t object * - * Return: + * Return: sysfs name of @c */ const char *nvme_ctrl_get_name(nvme_ctrl_t c); /** - * nvme_ctrl_get_sysfs_dir() - - * @c: + * nvme_ctrl_get_sysfs_dir() - sysfs directory of an nvme_ctrl_t object + * @c: nvme_ctrl_t object * - * Return: + * Return: sysfs directory name of @c */ const char *nvme_ctrl_get_sysfs_dir(nvme_ctrl_t c); /** - * nvme_ctrl_get_address() - - * @c: + * nvme_ctrl_get_address() - Address string of an nvme_ctrl_t + * @c: nvme_ctrl_t object * - * Return: + * Return: NVMe-over-Fabrics address string of @c */ const char *nvme_ctrl_get_address(nvme_ctrl_t c); /** - * nvme_ctrl_get_firmware() - - * @c: + * nvme_ctrl_get_firmware() - Firmware string of an nvme_ctrl_t object + * @c: nvme_ctrl_t object * - * Return: + * Return: Firmware string of @c */ const char *nvme_ctrl_get_firmware(nvme_ctrl_t c); /** - * nvme_ctrl_get_model() - - * @c: + * nvme_ctrl_get_model() - Model of an nvme_ctrl_t object + * @c: nvme_ctrl_t object * - * Return: + * Return: Model string of @c */ const char *nvme_ctrl_get_model(nvme_ctrl_t c); /** - * nvme_ctrl_get_state() - - * @c: + * nvme_ctrl_get_state() - Running state of an nvme_ctrl_t object + * @c: nvme_ctrl_t object * - * Return: + * Return: string indicating the running state of @c */ const char *nvme_ctrl_get_state(nvme_ctrl_t c); /** - * nvme_ctrl_get_numa_node() - - * @c: + * nvme_ctrl_get_numa_node() - NUMA node of an nvme_ctrl_t object + * @c: nvme_ctrl_t object * - * Return: + * Return: string indicating the NUMA node */ const char *nvme_ctrl_get_numa_node(nvme_ctrl_t c); /** - * nvme_ctrl_get_queue_count() - - * @c: + * nvme_ctrl_get_queue_count() - Queue count of an nvme_ctrl_t object + * @c: nvme_ctrl_t object * - * Return: + * Return: Queue count of @c */ const char *nvme_ctrl_get_queue_count(nvme_ctrl_t c); /** - * nvme_ctrl_get_serial() - - * @c: + * nvme_ctrl_get_serial() - Serial number of an nvme_ctrl_t object + * @c: nvme_ctrl_t object * - * Return: + * Return: Serial number string of @c */ const char *nvme_ctrl_get_serial(nvme_ctrl_t c); /** - * nvme_ctrl_get_sqsize() - - * @c: + * nvme_ctrl_get_sqsize() - SQ size of an nvme_ctrl_t object + * @c: nvme_ctrl_t object * - * Return: + * Return: SQ size (as string) of @c */ const char *nvme_ctrl_get_sqsize(nvme_ctrl_t c); /** - * nvme_ctrl_get_transport() - - * @c: + * nvme_ctrl_get_transport() - Transport type of an nvme_ctrl_t object + * @c: nvme_ctrl_t object * - * Return: + * Return: Transport type of @c */ const char *nvme_ctrl_get_transport(nvme_ctrl_t c); /** - * nvme_ctrl_get_subsysnqn() - - * @c: + * nvme_ctrl_get_subsysnqn() - Subsystem NQN of an nvme_ctrl_t object + * @c: nvme_ctrl_t object * - * Return: + * Return: Subsystem NQN of @c */ const char *nvme_ctrl_get_subsysnqn(nvme_ctrl_t c); /** - * nvme_ctrl_get_subsystem() - - * @c: + * nvme_ctrl_get_subsystem() - Parent subsystem of an nvme_ctrl_t object + * @c: nvme_ctrl_t object * - * Return: + * Return: Parent nvme_subsystem_t object */ nvme_subsystem_t nvme_ctrl_get_subsystem(nvme_ctrl_t c); /** - * nvme_ctrl_get_traddr() - - * @c: + * nvme_ctrl_get_traddr() - Transport address of an nvme_ctrl_t object + * @c: nvme_ctrl_t object * - * Return: + * Return: Transport address of @c */ const char *nvme_ctrl_get_traddr(nvme_ctrl_t c); /** - * nvme_ctrl_get_trsvcid() - - * @c: + * nvme_ctrl_get_trsvcid() - Transport service identifier of an nvme_ctrl_t object + * @c: nvme_ctrl_t object * - * Return: + * Return: Transport service identifier of @c (if present) */ const char *nvme_ctrl_get_trsvcid(nvme_ctrl_t c); /** - * nvme_ctrl_get_host_traddr() - - * @c: + * nvme_ctrl_get_host_traddr() - Host transport address of an nvme_ctrl_t object + * @c: nvme_ctrl_t object * - * Return: + * Return: Host transport address of @c (if present) */ const char *nvme_ctrl_get_host_traddr(nvme_ctrl_t c); /** - * nvme_ctrl_get_host_iface() - - * @c: + * nvme_ctrl_get_host_iface() - Host interface name of an nvme_ctrl_t object + * @c: nvme_ctrl_t object * - * Return: + * Return: Host interface name of @c (if present) */ const char *nvme_ctrl_get_host_iface(nvme_ctrl_t c); @@ -833,44 +860,44 @@ const char *nvme_ctrl_get_dhchap_key(nvme_ctrl_t c); void nvme_ctrl_set_dhchap_key(nvme_ctrl_t c, const char *key); /** - * nvme_ctrl_get_config() - - * @c: + * nvme_ctrl_get_config() - Fabrics configuration of an nvme_ctrl_t object + * @c: nvme_ctrl_t object * - * Return: + * Return: Fabrics configuration of @c */ struct nvme_fabrics_config *nvme_ctrl_get_config(nvme_ctrl_t c); /** - * nvme_ctrl_set_discovered() - - * @c: - * @discovered: + * nvme_ctrl_set_discovered() - Set the 'discovered' flag + * @c: nvme_ctrl_t object + * @discovered: value of the 'discovered' flag * - * Return: + * Set the 'discovered' flag of @c to @discovered */ void nvme_ctrl_set_discovered(nvme_ctrl_t c, bool discovered); /** - * nvme_ctrl_is_discovered() - - * @c: + * nvme_ctrl_is_discovered() - Returns the value of the 'discovered' flag + * @c: nvme_ctrl_t object * - * Return: + * Return: Value of the 'discovered' flag of @c */ bool nvme_ctrl_is_discovered(nvme_ctrl_t c); /** - * nvme_ctrl_set_persistent() - - * @c: - * @persistent: + * nvme_ctrl_set_persistent() - Set the 'persistent' flag + * @c: nvme_ctrl_t object + * @persistent: value of the 'persistent' flag * - * Return: + * Set the 'persistent' flag of @c to @persistent */ void nvme_ctrl_set_persistent(nvme_ctrl_t c, bool persistent); /** - * nvme_ctrl_is_persistent() - - * @c: + * nvme_ctrl_is_persistent() - Returns the value of the 'persistent' flag + * @c: nvme_ctrl_t object * - * Return: + * Return: Value of the 'persistent' flag of @c */ bool nvme_ctrl_is_persistent(nvme_ctrl_t c); @@ -897,40 +924,48 @@ void nvme_ctrl_set_discovery_ctrl(nvme_ctrl_t c, bool discovery); bool nvme_ctrl_is_discovery_ctrl(nvme_ctrl_t c); /** - * nvme_ctrl_identify() - - * @c: - * @id: + * nvme_ctrl_identify() - Issues an 'identify controller' command + * @c: nvme_ctrl_t object + * @id: identify controller data structure * - * Return: + * Issues an 'identify controller' command to @c and copies the + * data into @id. + * + * Return: 0 on success or -1 on failure. */ int nvme_ctrl_identify(nvme_ctrl_t c, struct nvme_id_ctrl *id); /** - * nvme_disconnect_ctrl() - - * @c: + * nvme_disconnect_ctrl() - Disconnect a controller + * @c: nvme_ctrl_t object * - * Return: + * Issues a 'disconnect' fabrics command to @c + * + * Return: 0 on success, -1 on failure. */ int nvme_disconnect_ctrl(nvme_ctrl_t c); /** - * nvme_scan_ctrl() - - * @name: + * nvme_scan_ctrl() - Scan on a controller + * @r: nvme_root_t object + * @name: name of the controller * - * Return: + * Scans a controller with sysfs name @name and add it to @r. + * + * Return: nvme_ctrl_t object */ nvme_ctrl_t nvme_scan_ctrl(nvme_root_t r, const char *name); /** - * @c: - * + * nvme_rescan_ctrl() - Rescan an existing nvme_ctrl_t object + * @c: nvme_ctrl_t object */ void nvme_rescan_ctrl(nvme_ctrl_t c); /** - * nvme_init_ctrl() - Initialize control for an existing nvme device. - * @h: host - * @c: ctrl + * nvme_init_ctrl() - Initialize nvme_ctrl_t object for an existing nvme controller. + * @h: nvme_host_t object + * @c: nvme_ctrl_t object * @instance: Instance number (e.g. 1 for nvme1) * * Return: The ioctl() return code. Typically 0 on success. @@ -958,18 +993,18 @@ void nvme_unlink_ctrl(struct nvme_ctrl *c); const char *nvme_subsystem_get_nqn(nvme_subsystem_t s); /** - * nvme_subsystem_get_sysfs_dir() - - * @s: + * nvme_subsystem_get_sysfs_dir() - sysfs directory of an nvme_subsystem_t object + * @s: nvme_subsystem_t object * - * Return: + * Return: sysfs directory name of @s */ const char *nvme_subsystem_get_sysfs_dir(nvme_subsystem_t s); /** - * nvme_subsystem_get_name() - - * @s: + * nvme_subsystem_get_name() - sysfs name of an nvme_subsystem_t object + * @s: nvme_subsystem_t object * - * Return: + * Return: sysfs name of @s */ const char *nvme_subsystem_get_name(nvme_subsystem_t s); @@ -996,32 +1031,24 @@ const char *nvme_subsystem_get_type(nvme_subsystem_t s); int nvme_scan_topology(nvme_root_t r, nvme_scan_filter_t f); /** - * nvme_host_get_hostnqn() - - * @h: + * nvme_host_get_hostnqn() - Host NQN of an nvme_host_t object + * @h: nvme_host_t object * - * Return: + * Return: Host NQN of @h */ const char *nvme_host_get_hostnqn(nvme_host_t h); /** - * nvme_host_get_hostid() - - * @h: + * nvme_host_get_hostid() - Host ID of an nvme_host_t object + * @h: nvme_host_t object * - * Return: + * Return: Host ID of @h */ const char *nvme_host_get_hostid(nvme_host_t h); /** - * nvme_default_host() - - * @root: - * - * Return: - */ -nvme_host_t nvme_default_host(nvme_root_t r); - -/** - * nvme_free_host() - - * @r: + * nvme_free_host() - Free nvme_host_t object + * @h: nvme_host_t object */ void nvme_free_host(nvme_host_t h); @@ -1029,7 +1056,7 @@ void nvme_free_host(nvme_host_t h); * nvme_scan() - Scan NVMe topology * @config_file: configuration file * - * Return: nvme_root_t structure of found elements + * Return: nvme_root_t object of found elements */ nvme_root_t nvme_scan(const char *config_file); @@ -1044,74 +1071,95 @@ nvme_root_t nvme_scan(const char *config_file); void nvme_read_config(nvme_root_t r, const char *config_file); /** - * nvme_refresh_topology() - - * @r: + * nvme_refresh_topology() - refresh nvme_root_t object contents + * @r: nvme_root_t object + * + * Removes all elements in @r and rescans the existing topology. */ void nvme_refresh_topology(nvme_root_t r); /** - * nvme_update_config() - - * @r: + * nvme_update_config() - Update JSON configuration + * @r: nvme_root_t object + * + * Updates the JSON configuration file with the contents of @r. * - * Return: + * Return: 0 on success, -1 on failure. */ int nvme_update_config(nvme_root_t r); /** - * nvme_dump_config() - - * @r: + * nvme_dump_config() - Print the JSON configuration + * @r: nvme_root_t object + * + * Prints the current contents of the JSON configuration + * file to stdout. * - * Return: + * Return: 0 on success, -1 on failure. */ int nvme_dump_config(nvme_root_t r); /** - * nvme_get_attr() - - * @dir: - * @attr: + * nvme_get_attr() - Read sysfs attribute + * @dir: sysfs directory + * @attr: sysfs attribute name * - * Return: + * Return: string with the contents of @attr */ char *nvme_get_attr(const char *dir, const char *attr); /** - * nvme_get_subsys_attr() - - * @s: - * @attr: + * nvme_get_subsys_attr() - Read subsystem sysfs attribute + * @s: nvme_subsystem_t object + * @attr: sysfs attribute name * - * Return: + * Return: string with the contents of @attr */ char *nvme_get_subsys_attr(nvme_subsystem_t s, const char *attr); /** - * nvme_get_ctrl_attr() - - * @c: - * @attr: + * nvme_get_ctrl_attr() - Read controller sysfs attribute + * @c: nvme_ctrl_t object + * @attr: sysfs attribute name * - * Return: + * Return: string with the contents of @attr */ char *nvme_get_ctrl_attr(nvme_ctrl_t c, const char *attr); /** - * nvme_get_ns_attr() - - * @n: - * @attr: + * nvme_get_ns_attr() - Read namespace sysfs attribute + * @n: nvme_ns_t object + * @attr: sysfs attribute name * - * Return: + * Return: string with the contents of @attr */ char *nvme_get_ns_attr(nvme_ns_t n, const char *attr); +/** + * nvme_subsystem_lookup_namespace - lookup namespace by NSID + * @s: nvme_subsystem_t object + * @nsid: namespace id + * + * Return: nvme_ns_t of the namespace with id @nsid in subsystem @s + */ nvme_ns_t nvme_subsystem_lookup_namespace(struct nvme_subsystem *s, __u32 nsid); + /** - * nvme_get_path_attr() - - * @p: - * @attr: + * nvme_get_path_attr() - Read path sysfs attribute + * @p: nvme_path_t object + * @attr: sysfs attribute name * - * Return: + * Return: string with the contents of @attr */ char *nvme_get_path_attr(nvme_path_t p, const char *attr); +/** + * nvme_scan_namespace() - scan namespace based on sysfs name + * @name: sysfs name of the namespace to scan + * + * Return: nvme_ns_t object or NULL if not found. + */ nvme_ns_t nvme_scan_namespace(const char *name); #endif /* _LIBNVME_TREE_H */ From b4080fb52b70406b1ebb3c0ffa09c836fbf2bd7f Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Feb 2022 13:49:04 +0100 Subject: [PATCH 0418/1564] Return error from nvme_read_config() nvme_read_config() can fail, so we should be returning an error code to inform the caller about it. Signed-off-by: Hannes Reinecke --- src/nvme/json.c | 15 ++++++++++----- src/nvme/private.h | 2 +- src/nvme/tree.c | 11 ++++++++--- src/nvme/tree.h | 4 +++- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/nvme/json.c b/src/nvme/json.c index ebc1ae4f99..c4375d9f4d 100644 --- a/src/nvme/json.c +++ b/src/nvme/json.c @@ -126,7 +126,8 @@ static void json_parse_subsys(nvme_host_t h, struct json_object *subsys_obj) struct json_object *port_obj; port_obj = json_object_array_get_idx(port_array, p); - json_parse_port(s, port_obj); + if (port_obj) + json_parse_port(s, port_obj); } } @@ -153,11 +154,12 @@ static void json_parse_host(nvme_root_t r, struct json_object *host_obj) return; for (s = 0; s < json_object_array_length(subsys_array); s++) { subsys_obj = json_object_array_get_idx(subsys_array, s); - json_parse_subsys(h, subsys_obj); + if (subsys_obj) + json_parse_subsys(h, subsys_obj); } } -void json_read_config(nvme_root_t r, const char *config_file) +int json_read_config(nvme_root_t r, const char *config_file) { struct json_object *json_root, *host_obj; int h; @@ -166,13 +168,16 @@ void json_read_config(nvme_root_t r, const char *config_file) if (!json_root) { nvme_msg(r, LOG_DEBUG, "Failed to read %s, %s\n", config_file, json_util_get_last_err()); - return; + errno = EAGAIN; + return -1; } for (h = 0; h < json_object_array_length(json_root); h++) { host_obj = json_object_array_get_idx(json_root, h); - json_parse_host(r, host_obj); + if (host_obj) + json_parse_host(r, host_obj); } json_object_put(json_root); + return 0; } #define JSON_STRING_OPTION(c, p, o) \ diff --git a/src/nvme/private.h b/src/nvme/private.h index 945b453a36..356cae3001 100644 --- a/src/nvme/private.h +++ b/src/nvme/private.h @@ -129,7 +129,7 @@ struct nvme_root { int nvme_set_attr(const char *dir, const char *attr, const char *value); -void json_read_config(nvme_root_t r, const char *config_file); +int json_read_config(nvme_root_t r, const char *config_file); int json_update_config(nvme_root_t r, const char *config_file); diff --git a/src/nvme/tree.c b/src/nvme/tree.c index a2fe5335d1..0acc045e3a 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -137,14 +137,19 @@ nvme_root_t nvme_create_root(FILE *fp, int log_level) return r; } -void nvme_read_config(nvme_root_t r, const char *config_file) +int nvme_read_config(nvme_root_t r, const char *config_file) { + int err = -1; #ifdef CONFIG_JSONC if (r && config_file) { - json_read_config(r, config_file); - r->config_file = strdup(config_file); + err = json_read_config(r, config_file); + if (!err) + r->config_file = strdup(config_file); } +#else + errno = ENOTSUP; #endif + return err; } nvme_root_t nvme_scan(const char *config_file) diff --git a/src/nvme/tree.h b/src/nvme/tree.h index 00b75b00a6..1f9703fbc0 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -1040,8 +1040,10 @@ nvme_root_t nvme_scan(const char *config_file); * * Read in the contents of @config_file and merge them with * the elements in @r. + * + * Returns: 0 on success, -1 on failure with errno set. */ -void nvme_read_config(nvme_root_t r, const char *config_file); +int nvme_read_config(nvme_root_t r, const char *config_file); /** * nvme_refresh_topology() - From bee678d9c3baeb63c93e8bfbac3cac0c959d94f1 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Feb 2022 14:00:24 +0100 Subject: [PATCH 0419/1564] Ignore errors when opening JSON configuration file The JSON configuration file is optional, so any errors during opening can be ignored. Signed-off-by: Hannes Reinecke --- src/nvme/json.c | 16 +++++++++++++--- src/nvme/tree.c | 6 ++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/nvme/json.c b/src/nvme/json.c index c4375d9f4d..c6e3ac59a6 100644 --- a/src/nvme/json.c +++ b/src/nvme/json.c @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include @@ -162,13 +164,20 @@ static void json_parse_host(nvme_root_t r, struct json_object *host_obj) int json_read_config(nvme_root_t r, const char *config_file) { struct json_object *json_root, *host_obj; - int h; + int fd, h; - json_root = json_object_from_file(config_file); + fd = open(config_file, O_RDONLY); + if (fd < 0) { + nvme_msg(r, LOG_DEBUG, "Error opening %s, %s\n", + config_file, strerror(errno)); + return fd; + } + json_root = json_object_from_fd(fd); if (!json_root) { nvme_msg(r, LOG_DEBUG, "Failed to read %s, %s\n", config_file, json_util_get_last_err()); - errno = EAGAIN; + errno = EPROTO; + close(fd); return -1; } for (h = 0; h < json_object_array_length(json_root); h++) { @@ -177,6 +186,7 @@ int json_read_config(nvme_root_t r, const char *config_file) json_parse_host(r, host_obj); } json_object_put(json_root); + close(fd); return 0; } diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 0acc045e3a..a2b98396ac 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -145,6 +145,12 @@ int nvme_read_config(nvme_root_t r, const char *config_file) err = json_read_config(r, config_file); if (!err) r->config_file = strdup(config_file); + /* + * The json configuration file is optional, + * so ignore errors when opening the file. + */ + if (err < 0 && errno != EPROTO) + err = 0; } #else errno = ENOTSUP; From b804423a4e15fc534f2d405970b2a9cfbe4d5234 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 2 Feb 2022 08:23:49 +0100 Subject: [PATCH 0420/1564] ioctl.h: fixup kernel-doc comments To keep sphinx happy. Signed-off-by: Hannes Reinecke --- src/nvme/ioctl.h | 343 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 243 insertions(+), 100 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index b30393f1e3..e3c6b7b227 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -374,17 +374,18 @@ int nvme_ns_rescan(int fd); int nvme_get_nsid(int fd, __u32 *nsid); /** - * nvme_identify_args - Arguments for the NVMe Identify command + * 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 - * @timeout: Timeout in ms (0 for default timeout) + * @args_size: Size of &struct nvme_identify_args * @fd: File descriptor of nvme device - * @result: The command completion result from CQE dword0 + * @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 - * @domid: Domain identifier, if applicable * @cntid: The Controller Identifier, if applicable * @nvmsetid: The NVMe Set ID if CNS is 04h + * @domid: Domain identifier, if applicable * @uuidx: UUID Index if controller supports this id selection method */ struct nvme_identify_args { @@ -438,7 +439,7 @@ static int nvme_identify_cns_nsid(int fd, enum nvme_identify_cns cns, /** * nvme_identify_ctrl() - Retrieves nvme identify controller * @fd: File descriptor of nvme device - * id: User space destination address to transfer the data, + * @id: User space destination address to transfer the data, * * Sends nvme identify with CNS value %NVME_IDENTIFY_CNS_CTRL. * @@ -499,7 +500,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 - * @ns_list: User space destination address to transfer the data + * @list: User space destination address to transfer the data * * A list of 1024 namespace IDs is returned to the host containing NSIDs in * increasing order that are greater than the value specified in the Namespace @@ -521,7 +522,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 - * @ns_list: User space destination address to transfer the data + * @list: User space destination address to transfer the data * * A list of 1024 namespace IDs is returned to the host containing NSIDs in * increasing order that are greater than the value specified in the Namespace @@ -542,7 +543,7 @@ static inline int nvme_identify_allocated_ns_list(int fd, __u32 nsid, /** * nvme_identify_ctrl_list() - Retrieves identify controller list * @fd: File descriptor of nvme device - * @cntlid: Starting CNTLID to return in the list + * @cntid: Starting CNTLID to return in the list * @cntlist: User space destination address to transfer the data * * Up to 2047 controller identifiers is returned containing a controller @@ -555,11 +556,11 @@ static inline int nvme_identify_allocated_ns_list(int fd, __u32 nsid, * &enum nvme_status_field) or -1 with errno set otherwise. */ static inline int nvme_identify_ctrl_list(int fd, __u16 cntid, - struct nvme_ctrl_list *ctrlist) + struct nvme_ctrl_list *cntlist) { struct nvme_identify_args args = { .result = NULL, - .data = ctrlist, + .data = cntlist, .args_size = sizeof(args), .fd = fd, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, @@ -579,7 +580,7 @@ static inline int nvme_identify_ctrl_list(int fd, __u16 cntid, * nvme_identify_nsid_ctrl_list() - * @fd: File descriptor of nvme device * @nsid: Return controllers that are attached to this nsid - * @cntlid: Starting CNTLID to return in the list + * @cntid: Starting CNTLID to return in the list * @cntlist: User space destination address to transfer the data * * Up to 2047 controller identifiers is returned containing a controller @@ -592,11 +593,11 @@ static inline int nvme_identify_ctrl_list(int fd, __u16 cntid, * &enum nvme_status_field) or -1 */ static inline int nvme_identify_nsid_ctrl_list(int fd, __u32 nsid, __u16 cntid, - struct nvme_ctrl_list *ctrlist) + struct nvme_ctrl_list *cntlist) { struct nvme_identify_args args = { .result = NULL, - .data = ctrlist, + .data = cntlist, .args_size = sizeof(args), .fd = fd, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, @@ -639,11 +640,11 @@ static inline int nvme_identify_ns_descs(int fd, __u32 nsid, /** * nvme_identify_nvmset_list() - Retrieves NVM Set List * @fd: File descriptor of nvme device - * @nvmeset_id: NVM Set Identifier + * @nvmsetid: NVM Set Identifier * @nvmset: User space destination address to transfer the data * - * Retrieves an NVM Set List, @struct nvme_id_nvmset_list. The data structure is an - * ordered list by NVM Set Identifier, starting with the first NVM Set + * Retrieves an NVM Set List, &struct nvme_id_nvmset_list. The data structure + * is an ordered list by NVM Set Identifier, starting with the first NVM Set * Identifier supported by the NVM subsystem that is equal to or greater than * the NVM Set Identifier. * @@ -725,11 +726,11 @@ static inline int nvme_identify_primary_ctrl(int fd, __u16 cntid, * &enum nvme_status_field) or -1 with errno set otherwise. */ static inline int nvme_identify_secondary_ctrl_list(int fd, __u32 nsid, - __u16 cntid, struct nvme_secondary_ctrl_list *list) + __u16 cntid, struct nvme_secondary_ctrl_list *sc_list) { struct nvme_identify_args args = { .result = NULL, - .data = list, + .data = sc_list, .args_size = sizeof(args), .fd = fd, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, @@ -762,10 +763,10 @@ static inline int nvme_identify_secondary_ctrl_list(int fd, __u32 nsid, * &enum nvme_status_field) or -1 with errno set otherwise. */ static inline int nvme_identify_ns_granularity(int fd, - struct nvme_id_ns_granularity_list *list) + struct nvme_id_ns_granularity_list *gr_list) { return nvme_identify_cns_nsid(fd, NVME_IDENTIFY_CNS_NS_GRANULARITY, - NVME_NSID_NONE, list); + NVME_NSID_NONE, gr_list); } /** @@ -781,10 +782,10 @@ static inline int nvme_identify_ns_granularity(int fd, * 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_identify_uuid(int fd, struct nvme_id_uuid_list *list) +static inline int nvme_identify_uuid(int fd, struct nvme_id_uuid_list *uuid_list) { return nvme_identify_cns_nsid(fd, NVME_IDENTIFY_CNS_UUID_LIST, - NVME_NSID_NONE, list); + NVME_NSID_NONE, uuid_list); } /** @@ -865,11 +866,11 @@ static inline int nvme_identify_ctrl_csi(int fd, enum nvme_csi csi, void *data) * &enum nvme_status_field) or -1 with errno set otherwise. */ static inline int nvme_identify_active_ns_list_csi(int fd, __u32 nsid, - enum nvme_csi csi, struct nvme_ns_list *list) + enum nvme_csi csi, struct nvme_ns_list *ns_list) { struct nvme_identify_args args = { .result = NULL, - .data = list, + .data = ns_list, .args_size = sizeof(args), .fd = fd, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, @@ -903,11 +904,11 @@ static inline int nvme_identify_active_ns_list_csi(int fd, __u32 nsid, * &enum nvme_status_field) or -1 with errno set otherwise. */ static inline int nvme_identify_allocated_ns_list_csi(int fd, __u32 nsid, - enum nvme_csi csi, struct nvme_ns_list *list) + enum nvme_csi csi, struct nvme_ns_list *ns_list) { struct nvme_identify_args args = { .result = NULL, - .data = list, + .data = ns_list, .args_size = sizeof(args), .fd = fd, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, @@ -955,7 +956,7 @@ static inline int nvme_identify_independent_identify_ns(int fd, __u32 nsid, } /** - * nvme_identify_ctrl_nvm() - + * nvme_nvm_identify_ctrl() - * @fd: File descriptor of nvme device * @id: User space destination address to transfer the data * @@ -968,7 +969,7 @@ static inline int nvme_nvm_identify_ctrl(int fd, struct nvme_id_ctrl_nvm *id) } /** - * nvme_idnetifY_domain_list() - + * nvme_identify_domain_list() - * @fd: File descriptor of nvme device * @domid: Domain ID * @list: User space destiantion address to transfer data @@ -977,7 +978,7 @@ static inline int nvme_nvm_identify_ctrl(int fd, struct nvme_id_ctrl_nvm *id) * attributes in increasing order that are greater than the value * specified in the @domid field. * - * See @struct nvme_identify_domain_attr for the definition of the + * See &struct nvme_identify_domain_attr for the definition of the * returned structure. * * Return: The nvme command status if a response was received (see @@ -1005,7 +1006,7 @@ static inline int nvme_identify_domain_list(int fd, __u16 domid, } /** - * nvme_identifiy_endurance_group_list() - + * nvme_identify_endurance_group_list() - * @fd: File descriptor of nvme device * @endgrp_id: Endurance group identifier * @list: Array of endurance group identifiers @@ -1041,7 +1042,7 @@ static inline int nvme_identify_endurance_group_list(int fd, __u16 endgrp_id, * @iocs: User space destination address to transfer the data * * Retrieves list of the controller's supported io command set vectors. See - * @struct nvme_id_iocs. + * &struct nvme_id_iocs. * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. @@ -1110,7 +1111,7 @@ static inline int nvme_zns_identify_ctrl(int fd, struct nvme_zns_id_ctrl *id) } /** - * nvme_get_log_args - Arguments for the NVMe Admin Get Log command + * 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 @@ -1191,7 +1192,8 @@ static inline int nvme_get_log_simple(int fd, enum nvme_cmd_get_log_lid lid, return nvme_get_nsid_log(fd, false, lid, NVME_NSID_ALL, len, log); } -/** nvme_get_log_supported_log_pages() - Retrieve nmve supported log pages +/** + * nvme_get_log_supported_log_pages() - Retrieve nmve supported log pages * @fd: File descriptor of nvme device * @rae: Retain asynchronous events * @log: Array of LID supported and Effects data structures @@ -1209,7 +1211,7 @@ static inline int nvme_get_log_supported_log_pages(int fd, bool rae, /** * nvme_get_log_error() - Retrieve nvme error log * @fd: File descriptor of nvme device - * @entries: Number of error log entries allocated + * @nr_entries: Number of error log entries allocated * @rae: Retain asynchronous events * @err_log: Array of error logs of size 'entries' * @@ -1221,10 +1223,11 @@ static inline int nvme_get_log_supported_log_pages(int fd, bool rae, * &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 *log) + struct nvme_error_log_page *err_log) { return nvme_get_nsid_log(fd, rae, NVME_LOG_LID_ERROR, - NVME_NSID_ALL, sizeof(*log) * nr_entries, log); + NVME_NSID_ALL, sizeof(*err_log) * nr_entries, + err_log); } /** @@ -1245,10 +1248,10 @@ static inline int nvme_get_log_error(int fd, unsigned nr_entries, bool rae, * &enum nvme_status_field) or -1 with errno set otherwise. */ static inline int nvme_get_log_smart(int fd, __u32 nsid, bool rae, - struct nvme_smart_log *log) + struct nvme_smart_log *smart_log) { return nvme_get_nsid_log(fd, rae, NVME_LOG_LID_SMART, - nsid, sizeof(*log), log); + nsid, sizeof(*smart_log), smart_log); } /** @@ -1265,17 +1268,17 @@ static inline int nvme_get_log_smart(int fd, __u32 nsid, bool rae, * &enum nvme_status_field) or -1 with errno set otherwise. */ static inline int nvme_get_log_fw_slot(int fd, bool rae, - struct nvme_firmware_slot *log) + struct nvme_firmware_slot *fw_log) { return nvme_get_nsid_log(fd, rae, NVME_LOG_LID_SMART, - NVME_NSID_ALL, sizeof(*log), log); + NVME_NSID_ALL, sizeof(*fw_log), fw_log); } /** * nvme_get_log_changed_ns_list() - Retrieve namespace changed list * @fd: File descriptor of nvme device * @rae: Retain asynchronous events - * @ns_list: User address to store the log page + * @ns_log: User address to store the log page * * This log page describes namespaces attached to this controller that have * changed since the last time the namespace was identified, been added, or @@ -1285,10 +1288,10 @@ static inline int nvme_get_log_fw_slot(int fd, bool rae, * &enum nvme_status_field) or -1 with errno set otherwise. */ static inline int nvme_get_log_changed_ns_list(int fd, bool rae, - struct nvme_ns_list *log) + struct nvme_ns_list *ns_log) { return nvme_get_nsid_log(fd, rae, NVME_LOG_LID_CHANGED_NS, - NVME_NSID_ALL, sizeof(*log), log); + NVME_NSID_ALL, sizeof(*ns_log), ns_log); } /** @@ -1304,17 +1307,17 @@ static inline int nvme_get_log_changed_ns_list(int fd, bool rae, * &enum nvme_status_field) or -1 with errno set otherwise. */ static inline int nvme_get_log_cmd_effects(int fd, enum nvme_csi csi, - struct nvme_cmd_effects_log *log) + struct nvme_cmd_effects_log *effects_log) { struct nvme_get_log_args args = { .lpo = 0, .result = NULL, - .log = log, + .log = effects_log, .args_size = sizeof(args), .fd = fd, .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, .lid = NVME_LOG_LID_CMD_EFFECTS, - .len = sizeof(*log), + .len = sizeof(*effects_log), .nsid = NVME_NSID_ALL, .csi = csi, .lsi = NVME_LOG_LSI_NONE, @@ -1330,7 +1333,6 @@ static inline int nvme_get_log_cmd_effects(int fd, enum nvme_csi csi, /** * nvme_get_log_device_self_test() - Retrieve the device self test log * @fd: File descriptor of nvme device - * @nsid: Namespace ID being tested * @log: Userspace address of the log payload * * The log page indicates the status of an in progress self test and the @@ -1348,7 +1350,9 @@ static inline int nvme_get_log_device_self_test(int fd, } /** - * nvme_get_log_create_telemetry_host() - + * nvme_get_log_create_telemetry_host() - Create host telemetry log + * @fd: File descriptor of nvme device + * @log: Userspace address of the log payload */ static inline int nvme_get_log_create_telemetry_host(int fd, struct nvme_telemetry_log *log) @@ -1485,8 +1489,9 @@ static inline int nvme_get_log_endurance_group(int fd, __u16 endgid, /** * nvme_get_log_predictable_lat_nvmset() - - * @fd: - * @nvmsetid: + * @fd: File descriptor of nvme device + * @nvmsetid: NVM set id + * @log: User address to store the predictable latency log * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. @@ -1519,6 +1524,9 @@ static inline int nvme_get_log_predictable_lat_nvmset(int fd, __u16 nvmsetid, * nvme_get_log_predictable_lat_event() - * @fd: File descriptor of nvme device * @rae: Retain asynchronous events + * @offset: + * @len: + * @log: */ static inline int nvme_get_log_predictable_lat_event(int fd, bool rae, __u32 offset, __u32 len, void *log) @@ -1549,6 +1557,7 @@ static inline int nvme_get_log_predictable_lat_event(int fd, bool rae, * @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 * @@ -1589,6 +1598,8 @@ static int nvme_get_log_ana(int fd, enum nvme_log_ana_lsp lsp, bool rae, * nvme_get_log_ana_groups() - * @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 * * See &struct nvme_ana_group_desc for the defintion of the returned structure. */ @@ -1603,6 +1614,9 @@ static inline int nvme_get_log_ana_groups(int fd, bool rae, __u32 len, * nvme_get_log_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 */ static inline int nvme_get_log_lba_status(int fd, bool rae, __u64 offset, __u32 len, void *log) @@ -1632,6 +1646,9 @@ static inline int nvme_get_log_lba_status(int fd, bool rae, * nvme_get_log_endurance_grp_evt() - * @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 */ static inline int nvme_get_log_endurance_grp_evt(int fd, bool rae, __u32 offset, __u32 len, void *log) @@ -1680,6 +1697,7 @@ static inline int nvme_get_log_fid_supported_effects(int fd, bool rae, * @lsp: The log specified field of LID * @len: The allocated size, minimum * struct nvme_boot_partition + * @part: User address to store the log page * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise @@ -1750,6 +1768,7 @@ static inline int nvme_get_log_discovery(int fd, bool rae, * nvme_get_log_media_unit_stat() - * @fd: File descriptor of nvme device * @domid: Domain Identifier selection, if supported + * @mus: User address to store the Media Unit statistics log * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise @@ -1782,6 +1801,7 @@ static inline int nvme_get_log_media_unit_stat(int fd, __u16 domid, * nvme_get_log_reservation() - * @fd: File descriptor of nvme device * @rae: Retain asynchronous events + * @log: User address to store the reservation log */ static inline int nvme_get_log_reservation(int fd, bool rae, struct nvme_resv_notification_log *log) @@ -1878,15 +1898,16 @@ static inline int nvme_get_log_persistent_event(int fd, } /** - * nvme_set_features_args - Arguments for the NVMe Admin Set Feature command + * 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 - * @cdw14: Feature specific command dword15 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 @@ -1909,7 +1930,7 @@ struct nvme_set_features_args { } __attribute__((packed, aligned(__alignof__(__u32*)))); /** - * nvme_set_features_args() - Set a feature attribute + * nvme_set_features() - Set a feature attribute * @args: &struct nvme_set_features_args argument structure * * Return: The nvme command status if a response was received (see @@ -1917,6 +1938,17 @@ struct nvme_set_features_args { */ int nvme_set_features(struct nvme_set_features_args *args); +/** + * nvme_set_features_data() - 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 + * @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 + */ static inline int nvme_set_features_data(int fd, __u8 fid, __u32 nsid, __u32 cdw11, bool save, __u32 data_len, void *data, __u32 *result) @@ -1939,6 +1971,15 @@ static inline int nvme_set_features_data(int fd, __u8 fid, __u32 nsid, return nvme_set_features(&args); } +/** + * nvme_set_features_simple() - Helper functionn 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 + */ static inline int nvme_set_features_simple(int fd, __u8 fid, __u32 nsid, __u32 cdw11, bool save, __u32 *result) { @@ -1949,6 +1990,10 @@ static inline int nvme_set_features_simple(int fd, __u8 fid, __u32 nsid, /** * nvme_set_features_arbitration() - * @fd: File descriptor of nvme device + * @ab: + * @lpw: + * @mpw: + * @hpw: * @save: Save value across power states * @result: The command completion result from CQE dword0 * @@ -1961,6 +2006,8 @@ int nvme_set_features_arbitration(int fd, __u8 ab, __u8 lpw, __u8 mpw, /** * nvme_set_features_power_mgmt() - * @fd: File descriptor of nvme device + * @ps: + * @wh: * @save: Save value across power states * @result: The command completion result from CQE dword0 * @@ -1973,7 +2020,10 @@ int nvme_set_features_power_mgmt(int fd, __u8 ps, __u8 wh, bool save, /** * nvme_set_features_lba_range() - * @fd: File descriptor of nvme device + * @nsid: Namespace ID + * @nr_ranges: Number of ranges in @data * @save: Save value across power states + * @data: User address of feature data * @result: The command completion result from CQE dword0 * * Return: The nvme command status if a response was received (see @@ -1985,6 +2035,9 @@ int nvme_set_features_lba_range(int fd, __u32 nsid, __u32 nr_ranges, bool save, /** * nvme_set_features_temp_thresh() - * @fd: File descriptor of nvme device + * @tmpth: + * @tmpsel: + * @thsel: * @save: Save value across power states * @result: The command completion result from CQE dword0 * @@ -1998,6 +2051,9 @@ int nvme_set_features_temp_thresh(int fd, __u16 tmpth, __u8 tmpsel, /** * nvme_set_features_err_recovery() - * @fd: File descriptor of nvme device + * @nsid: Namespace ID + * @tler: Time-limited error recovery value + * @dulbe: * @save: Save value across power states * @result: The command completion result from CQE dword0 * @@ -2010,6 +2066,7 @@ int nvme_set_features_err_recovery(int fd, __u32 nsid, __u16 tler, /** * nvme_set_features_volatile_wc() - * @fd: File descriptor of nvme device + * @wce: Write cache enable * @save: Save value across power states * @result: The command completion result from CQE dword0 * @@ -2022,6 +2079,8 @@ int nvme_set_features_volatile_wc(int fd, bool wce, bool save, /** * nvme_set_features_irq_coalesce() - * @fd: File descriptor of nvme device + * @thr: + * @time: * @save: Save value across power states * @result: The command completion result from CQE dword0 * @@ -2034,6 +2093,8 @@ int nvme_set_features_irq_coalesce(int fd, __u8 thr, __u8 time, /** * nvme_set_features_irq_config() - * @fd: File descriptor of nvme device + * @iv: + * @cd: * @save: Save value across power states * @result: The command completion result from CQE dword0 * @@ -2046,6 +2107,7 @@ int nvme_set_features_irq_config(int fd, __u16 iv, bool cd, bool save, /** * nvme_set_features_write_atomic() - * @fd: File descriptor of nvme device + * @dn: * @save: Save value across power states * @result: The command completion result from CQE dword0 * @@ -2058,6 +2120,7 @@ int nvme_set_features_write_atomic(int fd, bool dn, bool save, /** * nvme_set_features_async_event() - * @fd: File descriptor of nvme device + * @events: Events to enable * @save: Save value across power states * @result: The command completion result from CQE dword0 * @@ -2070,6 +2133,8 @@ int nvme_set_features_async_event(int fd, __u32 events, bool save, /** * nvme_set_features_auto_pst() - * @fd: File descriptor of nvme device + * @apste: + * @apst: * @save: Save value across power states * @result: The command completion result from CQE dword0 * @@ -2094,6 +2159,8 @@ int nvme_set_features_timestamp(int fd, bool save, __u64 timestamp); /** * nvme_set_features_hctm() - * @fd: File descriptor of nvme device + * @tmt2: + * @tmt1: * @save: Save value across power states * @result: The command completion result from CQE dword0 * @@ -2106,6 +2173,7 @@ int nvme_set_features_hctm(int fd, __u16 tmt2, __u16 tmt1, bool save, /** * nvme_set_features_nopsc() - * @fd: File descriptor of nvme device + * @noppme: * @save: Save value across power states * @result: The command completion result from CQE dword0 * @@ -2117,6 +2185,8 @@ int nvme_set_features_nopsc(int fd, bool noppme, bool save, __u32 *result); /** * nvme_set_features_rrl() - * @fd: File descriptor of nvme device + * @rrl: Read recovery level setting + * @nvmsetid: NVM set id * @save: Save value across power states * @result: The command completion result from CQE dword0 * @@ -2129,7 +2199,10 @@ int nvme_set_features_rrl(int fd, __u8 rrl, __u16 nvmsetid, bool save, /** * nvme_set_features_plm_config() - * @fd: File descriptor of nvme device + * @enable: + * @nvmsetid: * @save: Save value across power states + * @data: * @result: The command completion result from CQE dword0 * * Return: The nvme command status if a response was received (see @@ -2142,6 +2215,8 @@ int nvme_set_features_plm_config(int fd, bool enable, __u16 nvmsetid, /** * nvme_set_features_plm_window() - * @fd: File descriptor of nvme device + * @sel: + * @nvmsetid: * @save: Save value across power states * @result: The command completion result from CQE dword0 * @@ -2155,6 +2230,8 @@ int nvme_set_features_plm_window(int fd, enum nvme_feat_plm_window_select sel, * nvme_set_features_lba_sts_interval() - * @fd: File descriptor of nvme device * @save: Save value across power states + * @lsiri: + * @lsipi: * @result: The command completion result from CQE dword0 * * Return: The nvme command status if a response was received (see @@ -2178,7 +2255,7 @@ int nvme_set_features_host_behavior(int fd, bool save, /** * nvme_set_features_sanitize() - * @fd: File descriptor of nvme device - * @nodrm: + * @nodrm: * @save: Save value across power states * @result: The command completion result from CQE dword0 * @@ -2204,7 +2281,7 @@ int nvme_set_features_endurance_evt_cfg(int fd, __u16 endgid, __u8 egwarn, /** * nvme_set_features_sw_progress() - * @fd: File descriptor of nvme device - * @pbslc: + * @pbslc: * @save: Save value across power states * @result: The command completion result from CQE dword0 * @@ -2217,9 +2294,9 @@ int nvme_set_features_sw_progress(int fd, __u8 pbslc, bool save, /** * nvme_set_features_host_id() - * @fd: File descriptor of nvme device - * @exhid: + * @exhid: * @save: Save value across power states - * @result: The command completion result from CQE dword0 + * @hostid: Host ID to set * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. @@ -2229,7 +2306,7 @@ int nvme_set_features_host_id(int fd, bool exhid, bool save, __u8 *hostid); /** * nvme_set_features_resv_mask() - * @fd: File descriptor of nvme device - * @mask: + * @mask: * @save: Save value across power states * @result: The command completion result from CQE dword0 * @@ -2241,7 +2318,7 @@ int nvme_set_features_resv_mask(int fd, __u32 mask, bool save, __u32 *result); /** * nvme_set_features_resv_persist() - * @fd: File descriptor of nvme device - * @ptpl: + * @ptpl: * @save: Save value across power states * @result: The command completion result from CQE dword0 * @@ -2253,7 +2330,7 @@ int nvme_set_features_resv_persist(int fd, bool ptpl, bool save, __u32 *result); /** * nvme_set_features_write_protect() - * @fd: File descriptor of nvme device - * @stat: + * @state: * @save: Save value across power states * @result: The command completion result from CQE dword0 * @@ -2263,7 +2340,8 @@ 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); /** - * nvme_get_features_args - Arguments for the NVMe Admin Get Feature command + * 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 @@ -2299,6 +2377,15 @@ struct nvme_get_features_args { */ int nvme_get_features(struct nvme_get_features_args *args); +/** + * nvme_get_features_data() - Helper function for @nvme_get_features() + * @fd: File descriptor of nvme device + * @fid: Feature identifier + * @nsid: Namespace ID, if applicable + * @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 + */ static inline int nvme_get_features_data(int fd, enum nvme_features_id fid, __u32 nsid, __u32 data_len, void *data, __u32 *result) { @@ -2318,6 +2405,14 @@ static inline int nvme_get_features_data(int fd, enum nvme_features_id fid, return nvme_get_features(&args); } + +/** + * nvme_get_features_simple() - Helper function for @nvme_get_features() + * @fd: File descriptor of nvme device + * @fid: Feature identifier + * @nsid: Namespace ID, if applicable + * @result: The command completion result from CQE dword0 + */ static inline int nvme_get_features_simple(int fd, enum nvme_features_id fid, __u32 nsid, __u32 *result) { @@ -2352,6 +2447,7 @@ int nvme_get_features_power_mgmt(int fd, enum nvme_get_features_sel sel, * nvme_get_features_lba_range() - * @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 * @result: The command completion result from CQE dword0 * * Return: The nvme command status if a response was received (see @@ -2425,6 +2521,7 @@ int nvme_get_features_irq_coalesce(int fd, enum nvme_get_features_sel sel, * nvme_get_features_irq_config() - * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @iv: * @result: The command completion result from CQE dword0 * * Return: The nvme command status if a response was received (see @@ -2461,6 +2558,7 @@ int nvme_get_features_async_event(int fd, enum nvme_get_features_sel sel, * nvme_get_features_auto_pst() - * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @apst: * @result: The command completion result from CQE dword0 * * Return: The nvme command status if a response was received (see @@ -2485,7 +2583,7 @@ int nvme_get_features_host_mem_buf(int fd, enum nvme_get_features_sel sel, * nvme_get_features_timestamp() - * @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 + * @ts: Current timestamp * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. @@ -2541,6 +2639,8 @@ int nvme_get_features_rrl(int fd, enum nvme_get_features_sel sel, __u32 *result) * nvme_get_features_plm_config() - * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @nvmsetid: NVM set id + * @data: * @result: The command completion result from CQE dword0 * * Return: The nvme command status if a response was received (see @@ -2554,6 +2654,7 @@ int nvme_get_features_plm_config(int fd, enum nvme_get_features_sel sel, * nvme_get_features_plm_window() - * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @nvmsetid: NVM set id * @result: The command completion result from CQE dword0 * * Return: The nvme command status if a response was received (see @@ -2578,6 +2679,7 @@ int nvme_get_features_lba_sts_interval(int fd, enum nvme_get_features_sel sel, * nvme_get_features_host_behavior() - * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @data: * @result: The command completion result from CQE dword0 * * Return: The nvme command status if a response was received (see @@ -2603,6 +2705,7 @@ int nvme_get_features_sanitize(int fd, enum nvme_get_features_sel sel, * nvme_get_features_endurance_event_cfg() - * @fd: File descriptor of nvme device * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @endgid: * @result: The command completion result from CQE dword0 * * Return: The nvme command status if a response was received (see @@ -2627,7 +2730,9 @@ int nvme_get_features_sw_progress(int fd, enum nvme_get_features_sel sel, * nvme_get_features_host_id() - * @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 + * @exhid: + * @len: Length of @hostid + * @hostid: Buffer for returned host ID * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. @@ -2686,8 +2791,9 @@ int nvme_get_features_iocs_profile(int fd, enum nvme_get_features_sel sel, __u32 *result); /** - * nvme_format_nvm_args - Arguments for the Format Nvme Namespace command + * 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. @@ -2726,9 +2832,10 @@ struct nvme_format_nvm_args { int nvme_format_nvm(struct nvme_format_nvm_args *args); /** - * nvme_ns_mgmt_args - Arguments for NVMe Namespace Management command + * 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 @@ -2747,7 +2854,7 @@ struct nvme_ns_mgmt_args { } __attribute__((packed, aligned(__alignof__(__u32*)))); /** - * nvme_ns_mgmt() - + * nvme_ns_mgmt() - Issue a Namespace management command * @args: &struct nvme_ns_mgmt_args Argument structure */ int nvme_ns_mgmt(struct nvme_ns_mgmt_args *args); @@ -2814,9 +2921,10 @@ static inline int nvme_ns_mgmt_delete(int fd, __u32 nsid) } /** - * nvme_ns_attach_args - Arguments for Nvme Namespace Management command + * 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 @@ -2833,7 +2941,7 @@ struct nvme_ns_attach_args { } __attribute__((packed, aligned(__alignof__(__u32*)))); /** - * nvme_ns_attach_args - Attach or detach namespace to controller(s) + * nvme_ns_attach() - Attach or detach namespace to controller(s) * @args: &struct nvme_ns_attach_args Argument structure */ int nvme_ns_attach(struct nvme_ns_attach_args *args); @@ -2883,7 +2991,8 @@ static inline int nvme_ns_detach_ctrls(int fd, __u32 nsid, } /** - * nvme_fw_download_args - Arguments for the NVMe Firmware Download command + * 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 @@ -2925,7 +3034,8 @@ struct nvme_fw_download_args { int nvme_fw_download(struct nvme_fw_download_args *args); /** - * nvme_fw_commit_args - Arguments for the NVMe Firmware Commit command + * 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 @@ -2957,9 +3067,10 @@ struct nvme_fw_commit_args { int nvme_fw_commit(struct nvme_fw_commit_args *args); /** - * nvme_security_send_args - Arguments for the NVMe Security Send command + * 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 @@ -3004,9 +3115,10 @@ struct nvme_security_send_args { int nvme_security_send(struct nvme_security_send_args *args); /** - * nvme_security_receive_args - Arguments for the NVMe Security Receive command + * 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 @@ -3042,10 +3154,11 @@ struct nvme_security_receive_args { int nvme_security_receive(struct nvme_security_receive_args *args); /** - * nvme_get_lba_status_args - Arguments for the NVMe Get LBA Status command + * 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 @@ -3080,15 +3193,16 @@ struct nvme_get_lba_status_args { int nvme_get_lba_status(struct nvme_get_lba_status_args *args); /** - * nvme_directive_send_args - Arguments for the NVMe Directive Send command + * 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 - * @dw12: Directive specific command dword12 + * @cdw12: Directive specific command dword12 * @data_len: Length of data payload in bytes * @dspec: Directive specific field */ @@ -3124,7 +3238,10 @@ int nvme_directive_send(struct nvme_directive_send_args *args); /** * nvme_directive_send_id_endir() - * @fd: File descriptor of nvme device - * @nsid: Namespace ID + * @nsid: + * @endir: + * @dtype: + * @id: * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. @@ -3137,6 +3254,7 @@ int nvme_directive_send_id_endir(int fd, __u32 nsid, bool endir, * nvme_directive_send_stream_release_identifier() - * @fd: File descriptor of nvme device * @nsid: Namespace ID + * @stream_id: Stream identifier * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. @@ -3189,15 +3307,16 @@ static inline int nvme_directive_send_stream_release_resource(int fd, __u32 nsid } /** - * nvme_directive_recv_args - Arguments for the NVMe Directive Receive command + * 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 - * @dw12: Directive specific command dword12 + * @cdw12: Directive specific command dword12 * @data_len: Length of data payload in bytes * @dspec: Directive specific field */ @@ -3228,6 +3347,7 @@ int nvme_directive_recv(struct nvme_directive_recv_args *args); * nvme_directive_recv_identify_parameters() - * @fd: File descriptor of nvme device * @nsid: Namespace ID + * @id: Identify parameters buffer * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. @@ -3256,6 +3376,7 @@ static inline int nvme_directive_recv_identify_parameters(int fd, __u32 nsid, * nvme_directive_recv_stream_parameters() - * @fd: File descriptor of nvme device * @nsid: Namespace ID + * @parms: Streams directive parameters buffer * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. @@ -3284,6 +3405,8 @@ static inline int nvme_directive_recv_stream_parameters(int fd, __u32 nsid, * nvme_directive_recv_stream_status() - * @fd: File descriptor of nvme device * @nsid: Namespace ID + * @nr_entries: Number of streams to receive + * @id: Stream status buffer * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. @@ -3313,6 +3436,8 @@ static inline int nvme_directive_recv_stream_status(int fd, __u32 nsid, * nvme_directive_recv_stream_allocate() - * @fd: File descriptor of nvme device * @nsid: Namespace ID + * @nsr: + * @result: * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. @@ -3338,12 +3463,13 @@ static inline int nvme_directive_recv_stream_allocate(int fd, __u32 nsid, } /** - * nvme_capacity_mgmt_args - Arguments for the NVMe Capacity Management command + * 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 - * @dw11: Least significant 32 bits of the capacity in bytes of the + * @cdw11: Least significant 32 bits of the capacity in bytes of the * Endurance Group or NVM Set to be created - * @dw12: Most significant 32 bits of the capacity in bytes of the + * @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 @@ -3370,7 +3496,8 @@ struct nvme_capacity_mgmt_args { int nvme_capacity_mgmt(struct nvme_capacity_mgmt_args *args); /** - * nvme_lockdown_args - Arguments for the NVME Lockdown command + * 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) @@ -3378,7 +3505,7 @@ int nvme_capacity_mgmt(struct nvme_capacity_mgmt_args *args); * @prhbt: Prohibit or allow the command opcode or Set Features command * @ifc: Affected interface * @ofi: Opcode or Feature Identifier - * @uuid: UUID Index if controller supports this id selection method + * @uuidx: UUID Index if controller supports this id selection method */ struct nvme_lockdown_args { __u32 *result; @@ -3402,7 +3529,8 @@ struct nvme_lockdown_args { int nvme_lockdown(struct nvme_lockdown_args *args); /** - * nvme_set_property_args - Arguments for NVMe Set Property command + * 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 @@ -3431,8 +3559,9 @@ struct nvme_set_property_args { int nvme_set_property(struct nvme_set_property_args *args); /** - * nvme_get_property_args - Arguments for NVMe Get Property command + * 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 @@ -3458,8 +3587,9 @@ struct nvme_get_property_args { int nvme_get_property(struct nvme_get_property_args *args); /** - * nvme_sanitize_nvm_args - Arguments for the NVMe Sanitize NVM command + * 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 @@ -3502,8 +3632,9 @@ struct nvme_sanitize_nvm_args { int nvme_sanitize_nvm(struct nvme_sanitize_nvm_args *args); /** - * nvme_dev_self_test_args - Arguments for the NVMe Device Self Test command + * 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 @@ -3539,8 +3670,9 @@ struct nvme_dev_self_test_args { int nvme_dev_self_test(struct nvme_dev_self_test_args *args); /** - * nvme_virtual_mgmt_args - Arguments for the NVMe Virtualization + * 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 @@ -3598,7 +3730,7 @@ static inline int nvme_flush(int fd, __u32 nsid) { } /** - * nvme_io_args - Arguments for NVMe I/O commands + * 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 @@ -3606,12 +3738,13 @@ static inline int nvme_flush(int fd, __u32 nsid) { * @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 - * @nbl: Number of logical blocks to send (0's based value) + * @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 @@ -3649,6 +3782,7 @@ struct nvme_io_args { /** * nvme_io() - Submit an nvme user I/O command * @args: &struct nvme_io_args argument structure + * @opcode: Opcode to execute * * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. @@ -3742,9 +3876,10 @@ static inline int nvme_verify(struct nvme_io_args *args) } /** - * nvme_dsm_args - Arguments for the NVMe Dataset Management command + * 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 @@ -3778,10 +3913,11 @@ struct nvme_dsm_args { int nvme_dsm(struct nvme_dsm_args *args); /** - * nvme_copy_args - Arguments for the NVMe Copy command + * 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 @@ -3829,11 +3965,12 @@ struct nvme_copy_args { int nvme_copy(struct nvme_copy_args *args); /** - * nvme_resv_acquire_args - Arguments for the NVMe Reservation Acquire Comand + * 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 @@ -3868,11 +4005,12 @@ struct nvme_resv_acquire_args { int nvme_resv_acquire(struct nvme_resv_acquire_args *args); /** - * nvme_resv_register_args - Arguments for the NVMe Reservation Register command + * 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 @@ -3906,9 +4044,10 @@ struct nvme_resv_register_args { int nvme_resv_register(struct nvme_resv_register_args *args); /** - * nvme_resv_release_args - Arguments for the NVMe Reservation Release Command + * 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 @@ -3938,10 +4077,11 @@ struct nvme_resv_release_args { int nvme_resv_release(struct nvme_resv_release_args *args); /** - * nvme_resv_report_args - Arguments for the NVMe Reservation Report command + * 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 @@ -3973,10 +4113,11 @@ struct nvme_resv_report_args { int nvme_resv_report(struct nvme_resv_report_args *args); /** - * nvme_zns_mgmt_send_args - Arguments for the NVMe ZNS Management Send command + * 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 @@ -4010,10 +4151,11 @@ int nvme_zns_mgmt_send(struct nvme_zns_mgmt_send_args *args); /** - * nvme_zns_mgmt_recv_args - Arguments for the NVMe ZNS Management Receive command + * 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 @@ -4086,12 +4228,13 @@ static inline int nvme_zns_report_zones(int fd, __u32 nsid, __u64 slba, } /** - * nvme_zns_append_args - Arguments for the NVMe ZNS Append command + * struct nvme_zns_append_args - Arguments for the NVMe ZNS Append command * @zslba: Zone start logical block address - * @fd: File descriptor of nvme device * @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 From 7247b35a870e67f589b51cb03b6d7146e4e9f9b3 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 2 Feb 2022 08:23:49 +0100 Subject: [PATCH 0421/1564] linux.h: fixup kernel-doc comments To keep sphinx happy. Signed-off-by: Hannes Reinecke --- src/nvme/linux.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/nvme/linux.h b/src/nvme/linux.h index 73b542d3e3..83820c410b 100644 --- a/src/nvme/linux.h +++ b/src/nvme/linux.h @@ -114,6 +114,7 @@ int nvme_get_ana_log_len(int fd, size_t *analen); /** * nvme_get_logical_block_size() - Retrieve block size * @fd: File descriptor of nvme device + * @nsid: Namespace id * @blksize: Pointer to where the block size will be set on success * * Return: The nvme command status if a response was received (see @@ -167,10 +168,10 @@ int nvme_open(const char *name); /** * enum nvme_hmac_alg - HMAC algorithm - * NVME_HMAC_ALG_NONE: No HMAC algorithm - * NVME_HMAC_ALG_SHA2_256: SHA2-256 - * NVME_HMAC_ALG_SHA2_384: SHA2-384 - * NVME_HMAC_ALG_SHA2_512: SHA2-512 + * @NVME_HMAC_ALG_NONE: No HMAC algorithm + * @NVME_HMAC_ALG_SHA2_256: SHA2-256 + * @NVME_HMAC_ALG_SHA2_384: SHA2-384 + * @NVME_HMAC_ALG_SHA2_512: SHA2-512 */ enum nvme_hmac_alg { NVME_HMAC_ALG_NONE = 0, From fa0dd2fbd2875e2737ebcced2761ce1416791292 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 2 Feb 2022 08:23:49 +0100 Subject: [PATCH 0422/1564] tree.h: fixup kernel-doc comments To keep sphinx happy. Signed-off-by: Hannes Reinecke --- src/nvme/tree.h | 88 ++++++++++++++++++++++++++----------------------- 1 file changed, 46 insertions(+), 42 deletions(-) diff --git a/src/nvme/tree.h b/src/nvme/tree.h index f6ed54485a..70643c4bfb 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -21,39 +21,13 @@ #include "ioctl.h" #include "util.h" -/** - * - */ typedef struct nvme_ns *nvme_ns_t; - -/** - * - */ typedef struct nvme_path *nvme_path_t; - -/** - * - */ typedef struct nvme_ctrl *nvme_ctrl_t; - -/** - * - */ typedef struct nvme_subsystem *nvme_subsystem_t; - -/** - * - */ typedef struct nvme_host *nvme_host_t; - -/** - * - */ typedef struct nvme_root *nvme_root_t; -/** - * - */ typedef bool (*nvme_scan_filter_t)(nvme_subsystem_t); /** @@ -145,7 +119,7 @@ void nvme_host_set_dhchap_key(nvme_host_t h, const char *key); /** * nvme_default_host() - Initializes the default host - * @root: nvme_root_t object + * @r: nvme_root_t object * * Initializes the default host object based on the values in * /etc/nvme/hostnqn and /etc/nvme/hostid and attaches it to @r. @@ -313,7 +287,10 @@ nvme_ns_t nvme_subsystem_first_ns(nvme_subsystem_t s); nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n); /** - * nvme_for_each_host_safe() + * nvme_for_each_host_safe() - Traverse host list + * @r: nvme_root_t object + * @h: nvme_host_t object + * @_h: temporary nvme_host_t object */ #define nvme_for_each_host_safe(r, h, _h) \ for (h = nvme_first_host(r), \ @@ -322,14 +299,19 @@ nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n); h = _h, _h = nvme_next_host(r, h)) /** - * nvme_for_each_host() + * nvme_for_each_host() - Traverse host list + * @r: nvme_root_t object + * @h: nvme_host_t object */ #define nvme_for_each_host(r, h) \ for (h = nvme_first_host(r); h != NULL; \ h = nvme_next_host(r, h)) /** - * nvme_for_each_subsystem_safe() + * nvme_for_each_subsystem_safe() - Traverse subsystems + * @h: nvme_host_t object + * @s: nvme_subsystem_t object + * @_s: temporary nvme_subsystem_t object */ #define nvme_for_each_subsystem_safe(h, s, _s) \ for (s = nvme_first_subsystem(h), \ @@ -338,14 +320,19 @@ nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n); s = _s, _s = nvme_next_subsystem(h, s)) /** - * nvme_for_each_subsystem() + * nvme_for_each_subsystem() - Traverse subsystems + * @h: nvme_host_t object + * @s: nvme_subsystem_t object */ #define nvme_for_each_subsystem(h, s) \ for (s = nvme_first_subsystem(h); s != NULL; \ s = nvme_next_subsystem(h, s)) /** - * nvme_subsystem_for_each_ctrl_safe() + * nvme_subsystem_for_each_ctrl_safe() - Traverse controllers + * @s: nvme_subsystem_t object + * @c: nvme_ctrl_t object + * @_c: temporary nvme_ctrl_t object */ #define nvme_subsystem_for_each_ctrl_safe(s, c, _c) \ for (c = nvme_subsystem_first_ctrl(s), \ @@ -354,14 +341,19 @@ nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n); c = _c, _c = nvme_subsystem_next_ctrl(s, c)) /** - * nvme_subsystem_for_each_ctrl() + * nvme_subsystem_for_each_ctrl() - traverse controllers + * @s: nvme_subsystem_t object + * @c: nvme_ctrl_t object */ #define nvme_subsystem_for_each_ctrl(s, c) \ for (c = nvme_subsystem_first_ctrl(s); c != NULL; \ c = nvme_subsystem_next_ctrl(s, c)) /** - * nvme_ctrl_for_each_ns_safe() + * nvme_ctrl_for_each_ns_safe() - traverse namespaces + * @c: nvme_ctrl_t object + * @n: nvme_ns_t object + * @_n: temporary nvme_ns_t object */ #define nvme_ctrl_for_each_ns_safe(c, n, _n) \ for (n = nvme_ctrl_first_ns(c), \ @@ -370,14 +362,19 @@ nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n); n = _n, _n = nvme_ctrl_next_ns(c, n)) /** - * nvme_ctrl_for_each_ns() + * nvme_ctrl_for_each_ns() - traverse namespaces + * @c: nvme_ctrl_t object + * @n: nvme_ns_t object */ #define nvme_ctrl_for_each_ns(c, n) \ for (n = nvme_ctrl_first_ns(c); n != NULL; \ n = nvme_ctrl_next_ns(c, n)) /** - * nvme_ctrl_for_each_path_safe() + * nvme_ctrl_for_each_path_safe() - Traverse paths + * @c: nvme_ctrl_t object + * @p: nvme_path_t object + * @_p: temporary nvme_path_t object */ #define nvme_ctrl_for_each_path_safe(c, p, _p) \ for (p = nvme_ctrl_first_path(c), \ @@ -386,14 +383,19 @@ nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n); p = _p, _p = nvme_ctrl_next_path(c, p)) /** - * nvme_ctrl_for_each_path() + * nvme_ctrl_for_each_path() - Traverse paths + * @c: nvme_ctrl_t object + * @p: nvme_path_t object */ #define nvme_ctrl_for_each_path(c, p) \ for (p = nvme_ctrl_first_path(c); p != NULL; \ p = nvme_ctrl_next_path(c, p)) /** - * nvme_subsystem_for_each_ns_safe() + * nvme_subsystem_for_each_ns_safe() - Traverse namespaces + * @s: nvme_subsystem_t object + * @n: nvme_ns_t object + * @_n: temporary nvme_ns_t object */ #define nvme_subsystem_for_each_ns_safe(s, n, _n) \ for (n = nvme_subsystem_first_ns(s), \ @@ -402,7 +404,9 @@ nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n); n = _n, _n = nvme_subsystem_next_ns(s, n)) /** - * nvme_subsystem_for_each_ns() + * nvme_subsystem_for_each_ns() - Traverse namespaces + * @s: nvme_subsystem_t object + * @n: nvme_ns_t object */ #define nvme_subsystem_for_each_ns(s, n) \ for (n = nvme_subsystem_first_ns(s); n != NULL; \ @@ -561,7 +565,7 @@ nvme_ctrl_t nvme_ns_get_ctrl(nvme_ns_t n); /** * nvme_free_ns() - free an nvme_ns_t object - * @ns: nvme_ns_t object + * @n: nvme_ns_t object */ void nvme_free_ns(struct nvme_ns *n); @@ -1101,12 +1105,12 @@ int nvme_dump_config(nvme_root_t r); /** * nvme_get_attr() - Read sysfs attribute - * @dir: sysfs directory + * @d: sysfs directory * @attr: sysfs attribute name * * Return: string with the contents of @attr */ -char *nvme_get_attr(const char *dir, const char *attr); +char *nvme_get_attr(const char *d, const char *attr); /** * nvme_get_subsys_attr() - Read subsystem sysfs attribute From 29198cd83edaaee182ad216b2f216f2bd47bbba7 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 2 Feb 2022 08:23:49 +0100 Subject: [PATCH 0423/1564] types.h: fixup kernel-doc comments To keep sphinx happy. Signed-off-by: Hannes Reinecke --- src/nvme/types.h | 749 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 615 insertions(+), 134 deletions(-) diff --git a/src/nvme/types.h b/src/nvme/types.h index e926180fd1..8afccbdecc 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -65,8 +65,13 @@ * identify namespace list * @NVME_ID_SECONDARY_CTRL_MAX: The largest possible secondary controller index * in identify secondary controller - * @NMVE_ID_DOMAIN_LIST_MAX: The largest possible domain index in the + * @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 + * index in the endurance group list + * @NVME_ID_ND_DESCRIPTOR_MAX: The largest possible namespace granularity + * index in the namespace granularity descriptor + * list * @NVME_FEAT_LBA_RANGE_MAX: The largest possible LBA range index in feature * lba range type * @NVME_LOG_ST_MAX_RESULTS: The largest possible self test result index in the @@ -79,6 +84,8 @@ * @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 + * @NVME_ZNS_CHANGED_ZONES_MAX: Max number of zones in the changed zones log + * page */ enum nvme_constants { NVME_NSID_ALL = 0xffffffff, @@ -550,7 +557,7 @@ enum nvme_pmrswtp { /** * nvme_pmr_throughput() - Calculate throughput of persistent memory buffer - * @mprswtp: Value from controller register %NVME_REG_PMRSWTP + * @pmrswtp: Value from controller register %NVME_REG_PMRSWTP * * Returns throughput of controller persistent memory buffer in bytes/second */ @@ -592,8 +599,8 @@ 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_IPS_100_MICRO_WATT: 0.0001 watt scale - * NVME_PSD_IPS_10_MILLI_WATT: 0.01 watt scale + * @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_100_MICRO_WATT = 1, @@ -602,8 +609,9 @@ enum nvme_psd_ps { /** * nvme_psd_power_scale() - power scale occupies the upper 3 bits + * @ps: power scale value */ -static inline unsigned nvme_psd_power_scale(__u8 ps) +static inline unsigned int nvme_psd_power_scale(__u8 ps) { return ps >> 6; } @@ -639,6 +647,7 @@ enum nvme_psd_workload { * 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 @@ -662,6 +671,7 @@ enum nvme_psd_workload { * 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. + * @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. @@ -670,6 +680,7 @@ enum nvme_psd_workload { * 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 { __le16 mp; @@ -720,6 +731,7 @@ struct nvme_id_psd { * @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 * @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 @@ -729,6 +741,7 @@ struct nvme_id_psd { * field is 2 * @crdt3: Controller Retry Delay time in 100 millisecod 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 @@ -777,9 +790,9 @@ struct nvme_id_psd { * 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 + * @rpmbs: Replay Protected Memory Block Support, see * &enum nvme_id_ctrl_rpmbs. - * @edstt Extended Device Self-test Time, if Device Self-test command is + * @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 @@ -792,7 +805,8 @@ struct nvme_id_psd { * provided. A value of FFh indicates no restriction * @kas: Keep Alive Support indicates the granularity of the Keep Alive * Timer in 100 millisecond units. - * @hctma: Host Controlled Thermal Management Attributes, see &enum nvme_id_ctrl_hctm. + * @hctma: Host Controlled Thermal Management Attributes, see + * &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 @@ -829,8 +843,10 @@ struct nvme_id_psd { * for the Persistent Event Log. * @domainid: Domain Identifier indicates the identifier of the domain * that contains this controller. + * @rsvd358: Reserved * @megcap: Max Endurance Group Capacity indicates the maximum capacity * 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 @@ -874,7 +890,9 @@ struct nvme_id_psd { * @maxcna: Maximum I/O Controller Namespace Attachments indicates the * 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. * @iorcsz: I/O Queue Response Capsule Supported Size, defines the maximum @@ -887,6 +905,7 @@ struct nvme_id_psd { * 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. + * @rsvd1806: Reserved * @psd: Power State Descriptors, see &struct nvme_id_psd. * @vs: Vendor Specific */ @@ -1019,13 +1038,18 @@ enum nvme_id_ctrl_cmic { }; /** - * enum nvme_id_ctrl_oaes - The typical latency in microseconds to enter Runtime D3 - * @NVME_CTRL_OAES_NA: - * @NVME_CTRL_OAES_FA: - * @NVME_CTRL_OAES_ANA: - * @NVME_CTRL_OAES_PLEA: - * @NVME_CTRL_OAES_LBAS:: - * @NVME_CTRL_OAES_EGE: + * enum nvme_id_ctrl_oaes - Optional Asynchronous Events Supported + * @NVME_CTRL_OAES_NA: Namespace Attribute Notices event supported + * @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 + * @NVME_CTRL_OAES_LBAS: LBA Status Information Notices event supported + * @NVME_CTRL_OAES_EGE: Endurance Group Events Aggregate Log Change + * 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 */ enum nvme_id_ctrl_oaes { NVME_CTRL_OAES_NA = 1 << 8, @@ -1034,20 +1058,31 @@ enum nvme_id_ctrl_oaes { NVME_CTRL_OAES_PLEA = 1 << 12, NVME_CTRL_OAES_LBAS = 1 << 13, NVME_CTRL_OAES_EGE = 1 << 14, -}; - -/** - * enum nvme_id_ctrl_ctratt - - * @NVME_CTRL_CTRATT_128_ID: - * @NVME_CTRL_CTRATT_NON_OP_PSP: - * @NVME_CTRL_CTRATT_NVM_SETS: - * @NVME_CTRL_CTRATT_READ_RECV_LVLS: - * @NVME_CTRL_CTRATT_ENDURANCE_GROUPS: - * @NVME_CTRL_CTRATT_PREDICTABLE_LAT: - * @NVME_CTRL_CTRATT_TBKAS: - * @NVME_CTRL_CTRATT_NAMESPACE_GRANULARITY: - * @NVME_CTRL_CTRATT_SQ_ASSOCIATIONS: - * @NVME_CTRL_CTRATT_UUID_LIST: + NVME_CTRL_OAES_NS = 1 << 15, + NVME_CTRL_OAES_ZD = 1 << 27, + NVME_CTRL_OAES_DL = 1 << 31, +}; + +/** + * 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 + * @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 + * @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_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 */ enum nvme_id_ctrl_ctratt { NVME_CTRL_CTRATT_128_ID = 1 << 0, @@ -1060,13 +1095,19 @@ enum nvme_id_ctrl_ctratt { NVME_CTRL_CTRATT_NAMESPACE_GRANULARITY = 1 << 7, NVME_CTRL_CTRATT_SQ_ASSOCIATIONS = 1 << 8, NVME_CTRL_CTRATT_UUID_LIST = 1 << 9, + NVME_CTRL_CTRATT_MDS = 1 << 10, + NVME_CTRL_CTRATT_FIXED_CAP = 1 << 11, + NVME_CTRL_CTRATT_VARIABLE_CAP = 1 << 12, + NVME_CTRL_CTRATT_DEL_ENDURANCE_GROUPS = 1 << 13, + NVME_CTRL_CTRATT_DEL_NVM_SETS = 1 << 14, + NVME_CTRL_CTRATT_ELBAS = 1 << 15, }; /** - * enum nvme_id_ctrl_cntrltype - - * @NVME_CTRL_CNTRLTYPE_IO: - * @NVME_CTRL_CNTRLTYPE_DISCOVERY: - * @NVME_CTRL_CNTRLTYPE_ADMIN: + * enum nvme_id_ctrl_cntrltype - Controller types + * @NVME_CTRL_CNTRLTYPE_IO: NVM I/O controller + * @NVME_CTRL_CNTRLTYPE_DISCOVERY: Discovery controller + * @NVME_CTRL_CNTRLTYPE_ADMIN: Admin controller */ enum nvme_id_ctrl_cntrltype { NVME_CTRL_CNTRLTYPE_IO = 1, @@ -1333,7 +1374,7 @@ enum nvme_id_ctrl_sqes { * @NVME_CTRL_CQES_MAX: Mask to get the value of the maximum Completion Queue * entry size when using the NVM Command Set. */ -enum { +enum nvme_id_ctrl_cqes { NVME_CTRL_CQES_MIN = 0xf << 0, NVME_CTRL_CQES_MAX = 0xf << 4, }; @@ -1604,8 +1645,13 @@ enum nvme_lbaf_rp { * @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. + * @mssrl: + * @mcl: + * @msrc: + * @rsvd81: Reserved * @anagrpid: ANA Group Identifier indicates the ANA Group Identifier of the * 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. @@ -1876,6 +1922,7 @@ enum nvme_id_ns_attr { * @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. + * @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. @@ -1883,7 +1930,7 @@ enum nvme_id_ns_attr { struct nvme_ns_id_desc { __u8 nidt; __u8 nidl; - __le16 reserved; + __le16 rsvd; __u8 nid[]; }; @@ -1895,6 +1942,7 @@ struct nvme_ns_id_desc { * 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. */ enum nvme_ns_id_desc_nidt { NVME_NIDT_EUI64 = 1, @@ -1914,6 +1962,7 @@ enum nvme_ns_id_desc_nidt_lens { * struct nvme_nvmset_attr - NVM Set Attributes Entry * @nvmsetid: NVM Set Identifier * @endgid: Endurance Group Identifier + * @rsvd4: Reserved * @rr4kt: Random 4 KiB Read Typical indicates the typical * time to complete a 4 KiB random read in 100 nanosecond units * when the NVM Set is in a Predictable Latency Mode Deterministic @@ -1921,6 +1970,7 @@ enum nvme_ns_id_desc_nidt_lens { * @ows: Optimal Write Size * @tnvmsetcap: Total NVM Set Capacity * @unvmsetcap: Unallocated NVM Set Capacity + * @rsvd48: Reserved */ struct nvme_nvmset_attr { __le16 nvmsetid; @@ -1935,8 +1985,9 @@ struct nvme_nvmset_attr { /** * struct nvme_id_nvmset_list - - * @nid; - * @ent:; + * @nid: Nvmset id + * @rsvd1: Reserved + * @ent: nvmset id list */ struct nvme_id_nvmset_list { __u8 nid; @@ -1952,9 +2003,11 @@ struct nvme_id_nvmset_list { * @fpi: * @anagrpid: * @nsattr: + * @rsvd9: * @nvmsetid: * @endgid: * @nstat: + * @rsvd15: */ struct nvme_id_independent_id_ns { __u8 nsfeat; @@ -1984,12 +2037,14 @@ struct nvme_id_ns_granularity_desc { * struct nvme_id_ns_granularity_list - * @attributes: * @num_descriptors: + * @rsvd5: * @entry: + * @rsvd288: */ struct nvme_id_ns_granularity_list { __le32 attributes; __u8 num_descriptors; - __u8 rsvd[27]; + __u8 rsvd5[27]; struct nvme_id_ns_granularity_desc entry[NVME_ID_ND_DESCRIPTOR_MAX]; __u8 rsvd288[3808]; }; @@ -1997,6 +2052,7 @@ struct nvme_id_ns_granularity_list { /** * struct nvme_id_uuid_list_entry - * @header: + * @rsvd1: * @uuid: */ struct nvme_id_uuid_list_entry { @@ -2006,7 +2062,7 @@ struct nvme_id_uuid_list_entry { }; /** - * enum - nvme_id_uuid + * enum nvme_id_uuid - * @NVME_ID_UUID_HDR_ASSOCIATION_MASK: * @NVME_ID_UUID_ASSOCIATION_NONE: * @NVME_ID_UUID_ASSOCIATION_VENDOR: @@ -2021,6 +2077,7 @@ enum nvme_id_uuid { /** * struct nvme_id_uuid_list - + * @rsvd0: * @entry: */ struct nvme_id_uuid_list { @@ -2048,12 +2105,13 @@ struct nvme_ns_list { /** * struct nvme_id_ctrl_nvm - - * vsl: - * wzsl: - * wusl: - * dmrl: - * dmrsl: - * dmsl: + * @vsl: + * @wzsl: + * @wusl: + * @dmrl: + * @dmrsl: + * @dmsl: + * @rsvd16: */ struct nvme_id_ctrl_nvm { __u8 vsl; @@ -2067,8 +2125,9 @@ struct nvme_id_ctrl_nvm { /** * struct nvme_zns_lbafe - - * zsze: - * zdes: + * @zsze: + * @zdes: + * @rsvd9: */ struct nvme_zns_lbafe { __le64 zsze; @@ -2085,10 +2144,17 @@ struct nvme_zns_lbafe { * @mor: Maximum Open Resources * @rrl: Reset Recommended Limit * @frl: Finish Recommended Limit + * @rrl1: Reset Recommended Limit 1 + * @rrl2: Reset Recommended Limit 2 + * @rrl3: Reset Recommended Limit 3 + * @frl1: Finish Recommended Limit 1 + * @frl2: Finish Recommended Limit 2 + * @frl3: Finish Recommended Limit 3 * @numzrwa: Number of ZRWA Resources * @zrwafg: ZRWA Flush Granularity * @zrwasz: ZRWA Size * @zrwacap: ZRWA Capability + * @rsvd53: Reserved * @lbafe: LBA Format Extension * @vs: Vendor Specific */ @@ -2117,6 +2183,7 @@ struct nvme_zns_id_ns { /** * struct nvme_zns_id_ctrl - * @zasl: + * @rsvd1: Reserved */ struct nvme_zns_id_ctrl { __u8 zasl; @@ -2128,18 +2195,21 @@ struct nvme_zns_id_ctrl { * @cntlid: * @portid: * @crt: + * @rsvd5: * @vqfrt: * @vqrfa: * @vqrfap: * @vqprt: * @vqfrsm: * @vqgran: + * @rsvd48: * @vifrt: * @virfa: * @virfap: * @viprt: * @vifrsm: * @vigran: + * @rsvd80: */ struct nvme_primary_ctrl_cap { __le16 cntlid; @@ -2167,9 +2237,11 @@ struct nvme_primary_ctrl_cap { * @scid: * @pcid: * @scs: + * @rsvd5: * @vfn: * @nvq: * @nvi: + * @rsvd14: */ struct nvme_secondary_ctrl { __le16 scid; @@ -2184,7 +2256,8 @@ struct nvme_secondary_ctrl { /** * struct nvme_secondary_ctrl_list - - * @num; + * @num: + * @rsvd: * @sc_entry: */ struct nvme_secondary_ctrl_list { @@ -2204,9 +2277,11 @@ struct nvme_id_iocs { /** * struct nvme_id_domain_attr - Domain Attributes Entry * @dom_id: + * @rsvd2: * @dom_cap: * @unalloc_dom_cap: * @max_egrp_dom_cap: + * @rsvd64: */ struct nvme_id_domain_attr { __le16 dom_id; @@ -2219,7 +2294,8 @@ struct nvme_id_domain_attr { /** * struct nvme_id_domain_list - - * @num: + * @num: Number of domain attributes + * @rsvd: Reserved * @domain_attr: List of domain attributes */ struct nvme_id_domain_list { @@ -2303,10 +2379,12 @@ struct nvme_supported_log_pages { * 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. * @trtype_spec_info: + * @rsvd2: */ struct nvme_error_log_page { __le64 error_count; @@ -2325,7 +2403,7 @@ struct nvme_error_log_page { }; /** - * enum - nvme_err_pel + * enum nvme_err_pel - * @NVME_ERR_PEL_BYTE_MASK: * @NVME_ERR_PEL_BIT_MASK: */ @@ -2372,6 +2450,7 @@ enum nvme_err_pel { * 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 @@ -2483,6 +2562,7 @@ enum nvme_err_pel { * 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 */ struct nvme_smart_log { __u8 critical_warning; @@ -2513,7 +2593,7 @@ struct nvme_smart_log { }; /** - * enum - nvme_smart_crit: Critical Warning + * enum nvme_smart_crit - Critical Warning * @NVME_SMART_CRIT_SPARE: If set, then the available spare capacity has fallen * below the threshold. * @NVME_SMART_CRIT_TEMPERATURE: If set, then a temperature is either greater @@ -2543,7 +2623,7 @@ enum nvme_smart_crit { }; /** - * enum - nvme_smart_egcw: Endurance Group Critical Warning Summary + * 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. * @NVME_SMART_EGCW_DEGRADED: If set, then the reliability of one or more @@ -2564,19 +2644,22 @@ enum nvme_smart_egcw { /** * struct nvme_firmware_slot - * @afi: + * @rsvd1: * @frs: + * @rsvd2: */ struct nvme_firmware_slot { __u8 afi; - __u8 resv[7]; + __u8 rsvd1[7]; char frs[7][8]; - __u8 resv2[448]; + __u8 rsvd2[448]; }; /** * struct nvme_cmd_effects_log - * @acs: * @iocs: + * @rsvd: */ struct nvme_cmd_effects_log { __le32 acs[256]; @@ -2585,7 +2668,7 @@ struct nvme_cmd_effects_log { }; /** - * enum - nvme_cmd_effects + * enum nvme_cmd_effects - * @NVME_CMD_EFFECTS_CSUPP: * @NVME_CMD_EFFECTS_LBCC: * @NVME_CMD_EFFECTS_NCC: @@ -2613,6 +2696,7 @@ enum nvme_cmd_effects { * #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. + * @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 @@ -2771,6 +2855,7 @@ enum nvme_st_valid_diag_info { * 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. */ struct nvme_self_test_log { @@ -2780,6 +2865,11 @@ struct nvme_self_test_log { struct nvme_st_result result[NVME_LOG_ST_MAX_RESULTS]; } __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 { NVME_LOG_TELEM_HOST_LSP_RETAIN = 0, NVME_LOG_TELEM_HOST_LSP_CREATE = 1, @@ -2790,16 +2880,19 @@ enum nvme_cmd_get_log_telemetry_host_lsp { * manufacturer. * @lpi: Log Identifier, either %NVME_LOG_LID_TELEMETRY_HOST or * %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. * @dalb1: Telemetry Controller-Initiated Data Area 1 Last Block is * the value of the last block in this area. - * @dalb3: Telemetry Controller-Initiated Data Area 1 Last Block is + * @dalb2: Telemetry Controller-Initiated Data Area 1 Last Block is * 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. + * @rsvd14: Reserved * @dalb4: Telemetry Controller-Initiated Data Area 4 Last Block is * the value of the last block in this area. + * @rsvd20: Reserved * @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 @@ -2837,9 +2930,11 @@ struct nvme_telemetry_log { /** * struct nvme_endurance_group_log - * @critical_warning: + * @rsvd1: * @avl_spare: * @avl_spare_threshold: * @percent_used: + * @rsvd6: * @endurance_estimate: * @data_units_read: * @data_units_written: @@ -2848,6 +2943,7 @@ struct nvme_telemetry_log { * @host_write_cmds: * @media_data_integrity_err: * @num_err_info_log_entries: + * @rsvd160: */ struct nvme_endurance_group_log { __u8 critical_warning; @@ -2868,7 +2964,7 @@ struct nvme_endurance_group_log { }; /** - * enum - + * enum nvme_eg_critical_warning_flags - * @NVME_EG_CRITICAL_WARNING_SPARE: * @NVME_EG_CRITICAL_WARNING_DEGRADED: * @NVME_EG_CRITICAL_WARNING_READ_ONLY: @@ -2880,9 +2976,9 @@ enum nvme_eg_critical_warning_flags { }; /** - * struct nvme_aggregate_endurance_group_event - - * @num_entries: - * @entries: + * struct nvme_aggregate_endurance_group_event - + * @num_entries: Number or entries + * @entries: List of entries */ struct nvme_aggregate_endurance_group_event { __le64 num_entries; @@ -2892,15 +2988,19 @@ struct nvme_aggregate_endurance_group_event { /** * struct nvme_nvmset_predictable_lat_log - * @status: + * @rsvd1: * @event_type: + * @rsvd4: * @dtwin_rt: * @dtwin_wt: * @dtwin_tmax: - * @dtwin_tmin_hi: - * @dtwin_tmin_lo: + * @ndwin_tmin_hi: + * @ndwin_tmin_lo: + * @rsvd72: * @dtwin_re: * @dtwin_we: * @dtwin_te: + * @rsvd152: */ struct nvme_nvmset_predictable_lat_log { __u8 status; @@ -2920,7 +3020,7 @@ struct nvme_nvmset_predictable_lat_log { }; /** - * enum - nvme_nvmeset_pl_status + * enum nvme_nvmeset_pl_status - * @NVME_NVMSET_PL_STATUS_DISABLED: * @NVME_NVMSET_PL_STATUS_DTWIN: * @NVME_NVMSET_PL_STATUS_NDWIN: @@ -2932,7 +3032,7 @@ enum nvme_nvmeset_pl_status { }; /** - * enum - nvme_nvmset_pl_events + * 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: @@ -2949,8 +3049,8 @@ enum nvme_nvmset_pl_events { /** * struct nvme_aggregate_predictable_lat_event - - * @num_entries: - * @entries: + * @num_entries: Number of entries + * @entries: Entry list */ struct nvme_aggregate_predictable_lat_event { __le64 num_entries; @@ -2959,11 +3059,12 @@ struct nvme_aggregate_predictable_lat_event { /** * struct nvme_ana_group_desc - - * @grpid: - * @nnsids: - * @chgcnt: - * @state: - * @nsids: + * @grpid: ANA group id + * @nnsids: Number of namespaces in @nsids + * @chgcnt: Change counter + * @state: ANA state + * @rsvd17: Reserved + * @nsids: List of namespaces */ struct nvme_ana_group_desc { __le32 grpid; @@ -2994,6 +3095,7 @@ enum nvme_ana_state { * struct nvme_ana_log - * @chgcnt: * @ngrps: + * @rsvd10: * @descs: */ struct nvme_ana_log { @@ -3006,9 +3108,11 @@ struct nvme_ana_log { /** * struct nvme_persistent_event_log - * @lid: + * @rsvd1: * @tnev: * @tll: * @rv: + * @rsvd17: * @lhl: * @ts: * @poh: @@ -3020,6 +3124,7 @@ struct nvme_ana_log { * @subnqn: * @gen_number: * @rci: + * @rsvd378: * @seb: */ struct nvme_persistent_event_log { @@ -3044,6 +3149,18 @@ struct nvme_persistent_event_log { __u8 seb[32]; } __attribute__((packed)); +/** + * struct nvme_persistent_event_entry - + * @etype: + * @etype_rev: + * @ehl: + * @rsvd3: + * @cntlid: + * @ets: + * @rsvd14: + * @vsil: + * @el: + */ struct nvme_persistent_event_entry { __u8 etype; __u8 etype_rev; @@ -3056,6 +3173,22 @@ struct nvme_persistent_event_entry { __le16 el; } __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 { NVME_PEL_SMART_HEALTH_EVENT = 0x01, NVME_PEL_FW_COMMIT_EVENT = 0x02, @@ -3072,6 +3205,16 @@ enum nvme_persistent_event_types { NVME_PEL_THERMAL_EXCURSION_EVENT = 0x0d, }; +/** + * struct nvme_fw_commit_event - + * @old_fw_rev: + * @new_fw_rev: + * @fw_commit_action: + * @fw_slot: + * @sct_fw: + * @sc_fw: + * @vndr_assign_fw_commit_rc: + */ struct nvme_fw_commit_event { __le64 old_fw_rev; __le64 new_fw_rev; @@ -3082,11 +3225,26 @@ struct nvme_fw_commit_event { __le16 vndr_assign_fw_commit_rc; } __attribute__((packed)); +/** + * struct nvme_time_stamp_change_event - + * @previous_timestamp: + * @ml_secs_since_reset: + */ struct nvme_time_stamp_change_event { __le64 previous_timestamp; __le64 ml_secs_since_reset; }; +/** + * struct nvme_power_on_reset_info_list - + * @cid: + * @fw_act: + * @op_in_prog: + * @rsvd4: + * @ctrl_power_cycle: + * @power_on_ml_seconds: + * @ctrl_time_stamp: + */ struct nvme_power_on_reset_info_list { __le16 cid; __u8 fw_act; @@ -3097,12 +3255,34 @@ struct nvme_power_on_reset_info_list { __le64 ctrl_time_stamp; } __attribute__((packed)); +/** + * struct nvme_nss_hw_err_event - + * @nss_hw_err_event_code: + * @rsvd2: + * @add_hw_err_info: + */ struct nvme_nss_hw_err_event { __le16 nss_hw_err_event_code; __u8 rsvd2[2]; __u8 *add_hw_err_info; }; +/** + * struct nvme_change_ns_event - + * @nsmgt_cdw10: + * @rsvd4: + * @nsze: + * @rsvd16: + * @nscap: + * @flbas: + * @dps: + * @nmic: + * @rsvd35: + * @ana_grp_id: + * @nvmset_id: + * @rsvd42: + * @nsid: + */ struct nvme_change_ns_event { __le32 nsmgt_cdw10; __u8 rsvd4[4]; @@ -3119,6 +3299,13 @@ struct nvme_change_ns_event { __le32 nsid; }; +/** + * struct nvme_format_nvm_start_event - + * @nsid: + * @fna: + * @rsvd5: + * @format_nvm_cdw10: + */ struct nvme_format_nvm_start_event { __le32 nsid; __u8 fna; @@ -3126,6 +3313,14 @@ struct nvme_format_nvm_start_event { __le32 format_nvm_cdw10; }; +/** + * struct nvme_format_nvm_compln_event - + * @nsid: + * @smallest_fpi: + * @format_nvm_status: + * @compln_info: + * @status_field: + */ struct nvme_format_nvm_compln_event { __le32 nsid; __u8 smallest_fpi; @@ -3134,12 +3329,25 @@ struct nvme_format_nvm_compln_event { __le32 status_field; }; +/** + * struct nvme_sanitize_start_event - + * @sani_cap: + * @sani_cdw10: + * @sani_cdw11: + */ struct nvme_sanitize_start_event { __le32 sani_cap; __le32 sani_cdw10; __le32 sani_cdw11; }; +/** + * struct nvme_sanitize_compln_event - + * @sani_prog: + * @sani_status: + * @cmpln_info: + * @rsvd6: + */ struct nvme_sanitize_compln_event { __le16 sani_prog; __le16 sani_status; @@ -3147,12 +3355,21 @@ struct nvme_sanitize_compln_event { __u8 rsvd6[2]; }; -/* persistent event type 0Bh */ +/** + * struct nvme_set_feature_event - + * @layout: + * @cdw_mem: + */ struct nvme_set_feature_event { __le32 layout; __le32 cdw_mem[0]; }; +/** + * struct nvme_thermal_exc_event - + * @over_temp: + * @threshold: + */ struct nvme_thermal_exc_event { __u8 over_temp; __u8 threshold; @@ -3162,6 +3379,7 @@ struct nvme_thermal_exc_event { * struct nvme_lba_rd - * @rslba: * @rnlb: + * @rsvd12: */ struct nvme_lba_rd { __le64 rslba; @@ -3174,6 +3392,7 @@ struct nvme_lba_rd { * @neid: * @nlrd: * @ratype: + * @rsvd8: * @lba_rd: */ struct nvme_lbas_ns_element { @@ -3199,6 +3418,7 @@ enum nvme_lba_status_atype { * @lslplen: * @nlslne: * @estulb: + * @rsvd12: * @lsgc: * @elements: */ @@ -3268,10 +3488,12 @@ struct nvme_fid_supported_effects_log { }; /** - * struct nvme_boot_paritition - + * struct nvme_boot_partition - * @lid: + * @rsvd1: * @bpinfo: - * @boot_partitiion_data: + * @rsvd8: + * @boot_partition_data: */ struct nvme_boot_partition { __u8 lid; @@ -3310,6 +3532,8 @@ struct nvme_media_unit_stat_desc { * @nmu: Number unit status descriptor * @cchans: Number of Channels * @sel_config: Selected Configuration + * @rsvd6: Reserved + * @mus_desc: Media unit statistic descriptors */ struct nvme_media_unit_stat_log { __le16 nmu; @@ -3324,7 +3548,9 @@ struct nvme_media_unit_stat_log { * @lpc: * @rnlpt: See &enum nvme_resv_notify_rnlpt. * @nalp: + * @rsvd9: * @nsid: + * @rsvd16: */ struct nvme_resv_notification_log { __le64 lpc; @@ -3415,6 +3641,7 @@ enum nvme_resv_notify_rnlpt { * 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; @@ -3489,6 +3716,7 @@ enum nvme_sanitize_sstat { /** * struct nvme_zns_changed_zone_log - ZNS Changed Zone List log * @nrzid: + * @rsvd2: * @zid: */ struct nvme_zns_changed_zone_log { @@ -3499,6 +3727,7 @@ struct nvme_zns_changed_zone_log { /** * enum nvme_zns_zt - + * @NVME_ZONE_TYPE_SEQWRITE_REQ: */ enum nvme_zns_zt { NVME_ZONE_TYPE_SEQWRITE_REQ = 0x2, @@ -3506,6 +3735,11 @@ enum nvme_zns_zt { /** * enum nvme_zns_za - + * @NVME_ZNS_ZA_ZFC: + * @NVME_ZNS_ZA_FZR: + * @NVME_ZNS_ZA_RZR: + * @NVME_ZNS_ZA_ZRWAV: + * @NVME_ZNS_ZA_ZDEV: */ enum nvme_zns_za { NVME_ZNS_ZA_ZFC = 1 << 0, @@ -3517,6 +3751,13 @@ enum nvme_zns_za { /** * enum nvme_zns_zs - + * @NVME_ZNS_ZS_EMPTY: + * @NVME_ZNS_ZS_IMPL_OPEN: + * @NVME_ZNS_ZS_EXPL_OPEN: + * @NVME_ZNS_ZS_CLOSED: + * @NVME_ZNS_ZS_READ_ONLY: + * @NVME_ZNS_ZS_FULL: + * @NVME_ZNS_ZS_OFFLINE: */ enum nvme_zns_zs { NVME_ZNS_ZS_EMPTY = 0x1, @@ -3530,6 +3771,15 @@ enum nvme_zns_zs { /** * struct nvme_zns_desc - + * @zt: + * @zs: + * @za: + * @zai: + * @rsvd4: + * @zcap: + * @zslba: + * @wp: + * @rsvd32: */ struct nvme_zns_desc { __u8 zt; @@ -3545,10 +3795,13 @@ struct nvme_zns_desc { /** * struct nvme_zone_report - + * @nr_zones: Number of descriptors in @entries + * @rsvd8: Reserved + * @entries: Zoned namespace descriptors */ struct nvme_zone_report { __le64 nr_zones; - __u8 resv8[56]; + __u8 rsvd8[56]; struct nvme_zns_desc entries[]; }; @@ -3556,7 +3809,9 @@ struct nvme_zone_report { * struct nvme_lba_status_desc - * @dslba: * @nlb: + * @rsvd12: * @status: + * @rsvd14: */ struct nvme_lba_status_desc { __le64 dslba; @@ -3570,6 +3825,7 @@ struct nvme_lba_status_desc { * struct nvme_lba_status - * @nlsd: * @cmpc: + * @rsvd5: * @descs: */ struct nvme_lba_status { @@ -3589,6 +3845,10 @@ 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 { NVME_APST_ENTRY_ITPS_SHIFT = 3, @@ -3614,7 +3874,9 @@ struct nvme_metadata_element_desc { /** * struct nvme_host_metadata - Host Metadata Data Structure * @ndesc: Number of metadata element descriptors + * @rsvd1: Reserved * @descs: Metadata element descriptors + * @descs_buf: Metadata element descriptor buffer */ struct nvme_host_metadata { __u8 ndesc; @@ -3689,8 +3951,9 @@ enum nvme_ns_metadata_type { /** * struct nvme_timestamp - - * timestamp: + * @timestamp: * @attr: + * @rsvd: */ struct nvme_timestamp { __u8 timestamp[6]; @@ -3702,9 +3965,11 @@ struct nvme_timestamp { * struct nvme_lba_range_type_entry - * @type: * @attributes: + * @rsvd2: * @slba: * @nlb: * @guid: + * @rsvd48: */ struct nvme_lba_range_type_entry { __u8 type; @@ -3717,7 +3982,7 @@ struct nvme_lba_range_type_entry { }; /** - * enum - nvme_lbart + * enum nvme_lbart - * @NVME_LBART_TYPE_GP: * @NVME_LBART_TYPE_FS: * @NVME_LBART_TYPE_RAID: @@ -3746,10 +4011,12 @@ struct nvme_lba_range_type { /** * struct nvme_plm_config - - * @ee; - * @dtwinrt; - * @dtwinwt; - * @dtwintt; + * @ee: + * @rsvd2: + * @dtwinrt: + * @dtwinwt: + * @dtwintt: + * @rsvd56: */ struct nvme_plm_config { __le16 ee; @@ -3763,6 +4030,7 @@ struct nvme_plm_config { /** * struct nvme_feat_host_behavior - * @acre: + * @rsvd1: */ struct nvme_feat_host_behavior { __u8 acre; @@ -3789,6 +4057,16 @@ struct nvme_dsm_range { __le64 slba; }; +/** + * struct nvme_copy_range - + * @rsvd0: + * @slba: + * @nlb: + * @rsvd18: + * @eilbrt: + * @elbatm: + * @elbat: + */ struct nvme_copy_range { __u8 rsvd0[8]; __le64 slba; @@ -3803,6 +4081,7 @@ struct nvme_copy_range { * struct nvme_registered_ctrl - * @cntlid: * @rcsts: + * @rsvd3: * @hostid: * @rkey: */ @@ -3818,8 +4097,10 @@ struct nvme_registered_ctrl { * struct nvme_registered_ctrl_ext - * @cntlid: * @rcsts: + * @rsvd3: * @rkey: * @hostid: + * @rsvd32: */ struct nvme_registered_ctrl_ext { __le16 cntlid; @@ -3835,7 +4116,10 @@ struct nvme_registered_ctrl_ext { * @gen: * @rtype: * @regctl: + * @rsvd7: * @ptpls: + * @rsvd10: + * @rsvd24: * @regctl_eds: * @regctl_ds: */ @@ -3857,6 +4141,16 @@ struct nvme_resv_status { /** * struct nvme_streams_directive_params - + * @msl: + * @nssa: + * @nsso: + * @nssc: + * @rsvd: + * @sws: + * @sgs: + * @nsa: + * @nso: + * @rsvd2: */ struct nvme_streams_directive_params { __le16 msl; @@ -3873,6 +4167,8 @@ struct nvme_streams_directive_params { /** * struct nvme_streams_directive_status - + * @osc: + * @sid: */ struct nvme_streams_directive_status { __le16 osc; @@ -3881,6 +4177,9 @@ struct nvme_streams_directive_status { /** * struct nvme_id_directives - + * @supported: + * @enabled: + * @rsvd64: */ struct nvme_id_directives { __u8 supported[32]; @@ -3890,6 +4189,8 @@ struct nvme_id_directives { /** * enum - + * @NVME_ID_DIR_ID_BIT: Identify directive is supported + * @NVME_ID_DIR_SD_BIT: Streams directive is supported */ enum { NVME_ID_DIR_ID_BIT = 0, @@ -3898,6 +4199,11 @@ enum { /** * struct nvme_host_mem_buf_attrs - + * @hsize: + * @hmdlal: + * @hmdlau: + * @hmdlec: + * @rsvd16: */ struct nvme_host_mem_buf_attrs { __le32 hsize; @@ -4071,10 +4377,12 @@ enum nvmf_disc_eflags { * 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. + * @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. + * @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 @@ -4086,7 +4394,9 @@ enum nvmf_disc_eflags { * @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. - * @common: + * @tsas: Transport specific attribute settings + * @common: Common transport specific attributes + * @rdma: RDMA transport specific attribute settings * @qptype: RDMA QP Service Type (RDMA_QPTYPE): Specifies the type of RDMA * Queue Pair. See &enum nvmf_rdma_qptype. * @prtype: RDMA Provider Type (RDMA_PRTYPE): Specifies the type of RDMA @@ -4095,6 +4405,7 @@ enum nvmf_disc_eflags { * of RDMA IP Connection Management Service. See &enum nvmf_rdma_cms. * @pkey: RDMA_PKEY: Specifies the Partition Key when AF_IB (InfiniBand) * address family type is used. + * @tcp: TCP transport specific attribute settings * @sectype: Security Type (SECTYPE): Specifies the type of security used by the * NVMe/TCP port. If SECTYPE is a value of 0h (No Security), then the * host shall set up a normal TCP connection. See &enum nvmf_tcp_sectype. @@ -4137,6 +4448,7 @@ struct nvmf_disc_log_entry { * @NVMF_TRTYPE_TCP: TCP * @NVMF_TRTYPE_LOOP: Intra-host Transport (i.e., loopback), reserved * for host usage. + * @NVMF_TRTYPE_MAX: Maximum value for &enum nvmf_trtype */ enum nvmf_trtype { NVMF_TRTYPE_UNSPECIFIED = 0, @@ -4245,6 +4557,7 @@ enum nvmf_tcp_sectype { * @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. + * @rsvd14: Reserved * @entries: Discovery Log Page Entries - see &struct nvmf_disc_log_entry. */ struct nvmf_discovery_log { @@ -4256,11 +4569,13 @@ struct nvmf_discovery_log { }; /** - * struct nvmf_connect_data - - * @hostid: - * @cntlid: - * @subsysnqn - * @hostnqn + * struct nvmf_connect_data - Data payload for the 'connect' command + * @hostid: Host ID of the connecting host + * @cntlid: Requested controller ID + * @rsvd4: Reserved + * @subsysnqn: Subsystem NQN to connect to + * @hostnqn: Host NQN of the connecting host + * @rsvd5: Reserved */ struct nvmf_connect_data { __u8 hostid[16]; @@ -4276,6 +4591,7 @@ struct nvmf_connect_data { * @nump: * @mjr: * @mnr: + * @rsvd3: */ struct nvme_mi_read_nvm_ss_info { __u8 nump; @@ -4292,6 +4608,7 @@ struct nvme_mi_read_nvm_ss_info { * @mlw: * @nlw: * @pn: + * @rsvd14: */ struct nvme_mi_port_pcie { __u8 mps; @@ -4310,6 +4627,7 @@ struct nvme_mi_port_pcie { * @mme_addr: * @mme_freq: * @nvmebm: + * @rsvd13: */ struct nvme_mi_port_smb { __u8 vpd_addr; @@ -4323,7 +4641,8 @@ struct nvme_mi_port_smb { /** * struct nvme_mi_read_port_info - * @portt: - * @mmctptus; + * @rsvd1: + * @mmctptus: * @meb: * @pcie: * @smb: @@ -4341,13 +4660,15 @@ struct nvme_mi_read_port_info { /** * struct nvme_mi_read_ctrl_info - - * @portid; - * @prii; - * @pri; - * @vid; - * @did; - * @ssvid; - * @ssid; + * @portid: + * @rsvd1: + * @prii: + * @pri: + * @vid: + * @did: + * @ssvid: + * @ssid: + * @rsvd16: */ struct nvme_mi_read_ctrl_info { __u8 portid; @@ -4363,8 +4684,8 @@ struct nvme_mi_read_ctrl_info { /** * struct nvme_mi_osc - - * @type; - * @opc; + * @type: + * @opc: */ struct nvme_mi_osc { __u8 type; @@ -4388,6 +4709,7 @@ struct nvme_mi_read_sc_list { * @ctemp: * @pdlu: * @ccs: + * @rsvd8: */ struct nvme_mi_nvm_ss_health_status { __u8 nss; @@ -4399,7 +4721,7 @@ struct nvme_mi_nvm_ss_health_status { }; /** - * enum - nvme_mi_css + * enum nvme_mi_css - * @NVME_MI_CCS_RDY: * @NVME_MI_CSS_CFS: * @NVME_MI_CSS_SHST: @@ -4436,6 +4758,7 @@ enum nvme_mi_css { * @pdlu: * @spare: * @cwarn: + * @rsvd9: */ struct nvme_mi_ctrl_health_status { __le16 ctlid; @@ -4448,7 +4771,7 @@ struct nvme_mi_ctrl_health_status { }; /** - * enum - + * enum nvme_mi_csts - * @NVME_MI_CSTS_RDY: * @NVME_MI_CSTS_CFS: * @NVME_MI_CSTS_SHST: @@ -4456,11 +4779,6 @@ struct nvme_mi_ctrl_health_status { * @NVME_MI_CSTS_CECO: * @NVME_MI_CSTS_NAC: * @NVME_MI_CSTS_FA: - * @NVME_MI_CWARN_ST: - * @NVME_MI_CWARN_TAUT: - * @NVME_MI_CWARN_RD: - * @NVME_MI_CWARN_RO: - * @NVME_MI_CWARN_VMBF: */ enum nvme_mi_csts { NVME_MI_CSTS_RDY = 1 << 0, @@ -4472,8 +4790,15 @@ enum nvme_mi_csts { NVME_MI_CSTS_FA = 1 << 7, }; +/** + * enum nvme_mi_cwarn - + * @NVME_MI_CWARN_ST: + * @NVME_MI_CWARN_TAUT: + * @NVME_MI_CWARN_RD: + * @NVME_MI_CWARN_RO: + * @NVME_MI_CWARN_VMBF: + */ enum nvme_mi_cwarn { - NVME_MI_CWARN_ST = 1 << 0, NVME_MI_CWARN_TAUT = 1 << 1, NVME_MI_CWARN_RD = 1 << 2, @@ -4483,19 +4808,22 @@ enum nvme_mi_cwarn { /** * struct nvme_mi_vpd_mra - - * @nmravn; - * @ff; - * @i18vpwr; - * @m18vpwr; - * @i33vpwr; - * @m33vpwr; - * @m33vapsr; - * @i5vapsr; - * @m5vapsr; - * @i12vapsr; - * @m12vapsr; - * @mtl; - * @tnvmcap[16]; + * @nmravn: + * @ff: + * @rsvd7: + * @i18vpwr: + * @m18vpwr: + * @i33vpwr: + * @m33vpwr: + * @rsvd17: + * @m33vapsr: + * @i5vapsr: + * @m5vapsr: + * @i12vapsr: + * @m12vapsr: + * @mtl: + * @tnvmcap: + * @rsvd37: */ struct nvme_mi_vpd_mra { __u8 nmravn; @@ -4526,6 +4854,7 @@ struct nvme_mi_vpd_mra { * @mctp: * @refccap: * @pi: + * @rsvd13: */ struct nvme_mi_vpd_ppmra { __u8 nppmravn; @@ -4554,7 +4883,7 @@ struct nvme_mi_vpd_telem { }; /** - * enum - + * enum nvme_mi_elem - * @NVME_MI_ELEM_EED: * @NVME_MI_ELEM_USCE: * @NVME_MI_ELEM_ECED: @@ -4576,6 +4905,7 @@ enum nvme_mi_elem { /** * struct nvme_mi_vpd_tra - * @vn: + * @rsvd6: * @ec: * @elems: */ @@ -4619,6 +4949,7 @@ struct nvme_mi_vpd_mr_common { * @biaoff: * @piaoff: * @mrioff: + * @rsvd6: * @chchk: * @vpd: */ @@ -5265,6 +5596,7 @@ static inline __u16 nvme_status_code(__u16 status_field) * @nvme_admin_get_features: * @nvme_admin_async_event: * @nvme_admin_ns_mgmt: + * @nvme_admin_fw_activate: * @nvme_admin_fw_commit: * @nvme_admin_fw_download: * @nvme_admin_dev_self_test: @@ -5328,7 +5660,7 @@ enum nvme_admin_opcode { * @NVME_IDENTIFY_CNS_NVMSET_LIST: * @NVME_IDENTIFY_CNS_CSI_NS: * @NVME_IDENTIFY_CNS_CSI_CTRL: - * @NVME_IDENTIFY_CNS_CSI_CSI_NS_ACTIVE_LIST: + * @NVME_IDENTIFY_CNS_CSI_NS_ACTIVE_LIST: * @NVME_IDENTIFY_CNS_CSI_INDEPENDENT_ID_NS: * @NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST: * @NVME_IDENTIFY_CNS_ALLOCATED_NS: @@ -5340,7 +5672,7 @@ enum nvme_admin_opcode { * @NVME_IDENTIFY_CNS_UUID_LIST: * @NVME_IDENTIFY_CNS_DOMAIN_LIST: * @NVME_IDENTIFY_CNS_ENDURANCE_GROUP_ID: - * @NVME_IDENTIFY_CNS_CSI_ALLOCATED_NS_LIST: + * @NVME_IDENTIFY_CNS_CSS_ALLOCATED_NS_LIST: * @NVME_IDENTIFY_CNS_COMMAND_SET_STRUCTURE: Base Specification 2.0a section 5.17.2.21 */ enum nvme_identify_cns { @@ -5493,6 +5825,104 @@ enum nvme_features_id { /** * enum nvme_feat - + * @NVME_FEAT_ARBITRATION_BURST_SHIFT: + * @NVME_FEAT_ARBITRATION_BURST_MASK: + * @NVME_FEAT_ARBITRATION_LPW_SHIFT: + * @NVME_FEAT_ARBITRATION_LPW_MASK: + * @NVME_FEAT_ARBITRATION_MPW_SHIFT: + * @NVME_FEAT_ARBITRATION_MPW_MASK: + * @NVME_FEAT_ARBITRATION_HPW_SHIFT: + * @NVME_FEAT_ARBITRATION_HPW_MASK: + * @NVME_FEAT_PWRMGMT_PS_SHIFT: + * @NVME_FEAT_PWRMGMT_PS_MASK: + * @NVME_FEAT_PWRMGMT_WH_SHIFT: + * @NVME_FEAT_PWRMGMT_WH_MASK: + * @NVME_FEAT_LBAR_NR_SHIFT: + * @NVME_FEAT_LBAR_NR_MASK: + * @NVME_FEAT_TT_TMPTH_SHIFT: + * @NVME_FEAT_TT_TMPTH_MASK: + * @NVME_FEAT_TT_TMPSEL_SHIFT: + * @NVME_FEAT_TT_TMPSEL_MASK: + * @NVME_FEAT_TT_THSEL_SHIFT: + * @NVME_FEAT_TT_THSEL_MASK: + * @NVME_FEAT_ERROR_RECOVERY_TLER_SHIFT: + * @NVME_FEAT_ERROR_RECOVERY_TLER_MASK: + * @NVME_FEAT_ERROR_RECOVERY_DULBE_SHIFT: + * @NVME_FEAT_ERROR_RECOVERY_DULBE_MASK: + * @NVME_FEAT_VWC_WCE_SHIFT: + * @NVME_FEAT_VWC_WCE_MASK: + * @NVME_FEAT_NRQS_NSQR_SHIFT: + * @NVME_FEAT_NRQS_NSQR_MASK: + * @NVME_FEAT_NRQS_NCQR_SHIFT: + * @NVME_FEAT_NRQS_NCQR_MASK: + * @NVME_FEAT_IRQC_THR_SHIFT: + * @NVME_FEAT_IRQC_THR_MASK: + * @NVME_FEAT_IRQC_TIME_SHIFT: + * @NVME_FEAT_IRQC_TIME_MASK: + * @NVME_FEAT_ICFG_IV_SHIFT: + * @NVME_FEAT_ICFG_IV_MASK: + * @NVME_FEAT_ICFG_CD_SHIFT: + * @NVME_FEAT_ICFG_CD_MASK: + * @NVME_FEAT_WA_DN_SHIFT: + * @NVME_FEAT_WA_DN_MASK: + * @NVME_FEAT_AE_SMART_SHIFT: + * @NVME_FEAT_AE_SMART_MASK: + * @NVME_FEAT_AE_NAN_SHIFT: + * @NVME_FEAT_AE_NAN_MASK: + * @NVME_FEAT_AE_FW_SHIFT: + * @NVME_FEAT_AE_FW_MASK: + * @NVME_FEAT_AE_TELEM_SHIFT: + * @NVME_FEAT_AE_TELEM_MASK: + * @NVME_FEAT_AE_ANA_SHIFT: + * @NVME_FEAT_AE_ANA_MASK: + * @NVME_FEAT_AE_PLA_SHIFT: + * @NVME_FEAT_AE_PLA_MASK: + * @NVME_FEAT_AE_LBAS_SHIFT: + * @NVME_FEAT_AE_LBAS_MASK: + * @NVME_FEAT_AE_EGA_SHIFT: + * @NVME_FEAT_AE_EGA_MASK: + * @NVME_FEAT_APST_APSTE_SHIFT: + * @NVME_FEAT_APST_APSTE_MASK: + * @NVME_FEAT_HMEM_EHM_SHIFT: + * @NVME_FEAT_HMEM_EHM_MASK: + * @NVME_FEAT_HCTM_TMT2_SHIFT: + * @NVME_FEAT_HCTM_TMT2_MASK: + * @NVME_FEAT_HCTM_TMT1_SHIFT: + * @NVME_FEAT_HCTM_TMT1_MASK: + * @NVME_FEAT_NOPS_NOPPME_SHIFT: + * @NVME_FEAT_NOPS_NOPPME_MASK: + * @NVME_FEAT_RRL_RRL_SHIFT: + * @NVME_FEAT_RRL_RRL_MASK: + * @NVME_FEAT_PLM_PLME_SHIFT: + * @NVME_FEAT_PLM_PLME_MASK: + * @NVME_FEAT_PLMW_WS_SHIFT: + * @NVME_FEAT_PLMW_WS_MASK: + * @NVME_FEAT_LBAS_LSIRI_SHIFT: + * @NVME_FEAT_LBAS_LSIRI_MASK: + * @NVME_FEAT_LBAS_LSIPI_SHIFT: + * @NVME_FEAT_LBAS_LSIPI_MASK: + * @NVME_FEAT_SC_NODRM_SHIFT: + * @NVME_FEAT_SC_NODRM_MASK: + * @NVME_FEAT_EG_ENDGID_SHIFT: + * @NVME_FEAT_EG_ENDGID_MASK: + * @NVME_FEAT_EG_EGCW_SHIFT: + * @NVME_FEAT_EG_EGCW_MASK: + * @NVME_FEAT_SPM_PBSLC_SHIFT: + * @NVME_FEAT_SPM_PBSLC_MASK: + * @NVME_FEAT_HOSTID_EXHID_SHIFT: + * @NVME_FEAT_HOSTID_EXHID_MASK: + * @NVME_FEAT_RM_REGPRE_SHIFT: + * @NVME_FEAT_RM_REGPRE_MASK: + * @NVME_FEAT_RM_RESREL_SHIFT: + * @NVME_FEAT_RM_RESREL_MASK: + * @NVME_FEAT_RM_RESPRE_SHIFT: + * @NVME_FEAT_RM_RESPRE_MASK: + * @NVME_FEAT_RP_PTPL_SHIFT: + * @NVME_FEAT_RP_PTPL_MASK: + * @NVME_FEAT_WP_WPS_SHIFT: + * @NVME_FEAT_WP_WPS_MASK: + * @NVME_FEAT_IOCSP_IOCSCI_SHIFT: + * @NVME_FEAT_IOCSP_IOCSCI_MASK: */ enum nvme_feat { NVME_FEAT_ARBITRATION_BURST_SHIFT = 0, @@ -5600,6 +6030,7 @@ enum nvme_feat { * @NVME_GET_FEATURES_SEL_CURRENT: * @NVME_GET_FEATURES_SEL_DEFAULT: * @NVME_GET_FEATURES_SEL_SAVED: + * @NVME_GET_FEATURES_SEL_SUPPORTED: */ enum nvme_get_features_sel { NVME_GET_FEATURES_SEL_CURRENT = 0, @@ -5635,7 +6066,7 @@ enum nvme_cmd_format_pi { }; /** - * @enum nvme_cmd_format_pil - Format NVM - Protection Information Location + * enum nvme_cmd_format_pil - Format NVM - Protection Information Location * @NVME_FORMAT_PIL_LAST: Protection information is transferred as the last * bytes of metadata. * @NVME_FORMAT_PIL_FIRST: Protection information is transferred as the first @@ -5669,8 +6100,8 @@ enum nvme_cmd_format_ses { /** * enum nvme_ns_mgmt_sel - - * @NVME_NAMESPACE_MGMT_SEL_CREATE: - * @NVME_NAMESPACE_MGMT_SEL_DELETE: + * @NVME_NS_MGMT_SEL_CREATE: + * @NVME_NS_MGMT_SEL_DELETE: */ enum nvme_ns_mgmt_sel { NVME_NS_MGMT_SEL_CREATE = 0, @@ -5679,8 +6110,8 @@ enum nvme_ns_mgmt_sel { /** * enum nvme_ns_attach_sel - - * NVME_NS_ATTACH_SEL_CTRL_ATTACH: - * NVME_NP_ATTACH_SEL_CTRL_DEATTACH: + * @NVME_NS_ATTACH_SEL_CTRL_ATTACH: + * @NVME_NS_ATTACH_SEL_CTRL_DEATTACH: */ enum nvme_ns_attach_sel { NVME_NS_ATTACH_SEL_CTRL_ATTACH = 0, @@ -5743,6 +6174,8 @@ enum nvme_directive_send_doper { /** * enum nvme_directive_send_identify_endir - + * @NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_DISABLE: + * @NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_ENABLE: */ enum nvme_directive_send_identify_endir { NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_DISABLE = 0, @@ -5802,11 +6235,11 @@ enum nvme_virt_mgmt_rt { }; /** - * enum nvme_ns_write_protect - - * @NVME_NS_WP_CFG_NONE - * @NVME_NS_WP_CFG_PROTECT - * @NVME_NS_WP_CFG_PROTECT_POWER_CYCLE - * @NVME_NS_WP_CFG_PROTECT_PERMANENT + * enum nvme_ns_write_protect_cfg - + * @NVME_NS_WP_CFG_NONE: + * @NVME_NS_WP_CFG_PROTECT: + * @NVME_NS_WP_CFG_PROTECT_POWER_CYCLE: + * @NVME_NS_WP_CFG_PROTECT_PERMANENT: */ enum nvme_ns_write_protect_cfg { NVME_NS_WP_CFG_NONE = 0, @@ -5827,6 +6260,9 @@ enum nvme_log_ana_lsp { /** * enum nvme_pevent_log_action - + * @NVME_PEVENT_LOG_READ: + * @NVME_PEVENT_LOG_EST_CTX_AND_READ: + * @NVME_PEVENT_LOG_RELEASE_CTX: */ enum nvme_pevent_log_action { NVME_PEVENT_LOG_READ = 0x0, @@ -5836,6 +6272,8 @@ enum nvme_pevent_log_action { /** * enum nvme_feat_tmpthresh_thsel - + * @NVME_FEATURE_TEMPTHRESH_THSEL_OVER: + * @NVME_FEATURE_TEMPTHRESH_THSEL_UNDER: */ enum nvme_feat_tmpthresh_thsel { NVME_FEATURE_TEMPTHRESH_THSEL_OVER = 0, @@ -5844,6 +6282,20 @@ enum nvme_feat_tmpthresh_thsel { /** * enum nvme_features_async_event_config_flags - + * @NVME_FEATURE_AENCFG_SMART_CRIT_SPARE: + * @NVME_FEATURE_AENCFG_SMART_CRIT_TEMPERATURE: + * @NVME_FEATURE_AENCFG_SMART_CRIT_DEGRADED: + * @NVME_FEATURE_AENCFG_SMART_CRIT_READ_ONLY: + * @NVME_FEATURE_AENCFG_SMART_CRIT_VOLATILE_BACKUP: + * @NVME_FEATURE_AENCFG_SMART_CRIT_READ_ONLY_PMR: + * @NVME_FEATURE_AENCFG_NOTICE_NAMESPACE_ATTRIBUTES: + * @NVME_FEATURE_AENCFG_NOTICE_FIRMWARE_ACTIVATION: + * @NVME_FEATURE_AENCFG_NOTICE_TELEMETRY_LOG: + * @NVME_FEATURE_AENCFG_NOTICE_ANA_CHANGE: + * @NVME_FEATURE_AENCFG_NOTICE_PL_EVENT: + * @NVME_FEATURE_AENCFG_NOTICE_LBA_STATUS: + * @NVME_FEATURE_AENCFG_NOTICE_EG_EVENT: + * @NVME_FEATURE_AENCFG_NOTICE_DISCOVERY_CHANGE: */ enum nvme_features_async_event_config_flags { NVME_FEATURE_AENCFG_SMART_CRIT_SPARE = 1 << 0, @@ -5864,6 +6316,8 @@ enum nvme_features_async_event_config_flags { /** * enum nvme_feat_plm_window_select - + * @NVME_FEATURE_PLM_DTWIN: + * @NVME_FEATURE_PLM_NDWIN: */ enum nvme_feat_plm_window_select { NVME_FEATURE_PLM_DTWIN = 1, @@ -5871,7 +6325,10 @@ enum nvme_feat_plm_window_select { }; /** - * + * enum nvme_feat_resv_notify_flags - + * @NVME_FEAT_RESV_NOTIFY_REGPRE: + * @NVME_FEAT_RESV_NOTIFY_RESREL: + * @NVME_FEAT_RESV_NOTIFY_RESPRE: */ enum nvme_feat_resv_notify_flags { NVME_FEAT_RESV_NOTIFY_REGPRE = 1 << 1, @@ -5880,7 +6337,7 @@ enum nvme_feat_resv_notify_flags { }; /** - * enum nvme_feat_ns_wp_cfg_state - + * enum nvme_feat_nswpcfg_state - * @NVME_FEAT_NS_NO_WRITE_PROTECT: * @NVME_FEAT_NS_WRITE_PROTECT: * @NVME_FEAT_NS_WRITE_PROTECT_PWR_CYCLE: @@ -5925,6 +6382,10 @@ enum nvme_fctype { * @nvme_cmd_resv_report: * @nvme_cmd_resv_acquire: * @nvme_cmd_resv_release: + * @nvme_cmd_copy: + * @nvme_zns_cmd_mgmt_send: + * @nvme_zns_cmd_mgmt_recv: + * @nvme_zns_cmd_append: */ enum nvme_io_opcode { nvme_cmd_flush = 0x00, @@ -5970,7 +6431,7 @@ enum nvme_io_control_flags { }; /** - * enum nvme_io_dsm_flag - + * enum nvme_io_dsm_flags - * @NVME_IO_DSM_FREQ_UNSPEC: * @NVME_IO_DSM_FREQ_TYPICAL: * @NVME_IO_DSM_FREQ_RARE: @@ -6081,6 +6542,16 @@ enum nvme_resv_rrela { NVME_RESERVATION_RRELA_CLEAR = 1 }; +/** + * enum nvme_zns_send_action - + * @NVME_ZNS_ZSA_CLOSE: + * @NVME_ZNS_ZSA_FINISH: + * @NVME_ZNS_ZSA_OPEN: + * @NVME_ZNS_ZSA_RESET: + * @NVME_ZNS_ZSA_OFFLINE: + * @NVME_ZNS_ZSA_SET_DESC_EXT: + * @NVME_ZNS_ZSA_ZRWA_FLUSH: + */ enum nvme_zns_send_action { NVME_ZNS_ZSA_CLOSE = 0x1, NVME_ZNS_ZSA_FINISH = 0x2, @@ -6093,6 +6564,8 @@ enum nvme_zns_send_action { /** * enum nvme_zns_recv_action - + * @NVME_ZNS_ZRA_REPORT_ZONES: + * @NVME_ZNS_ZRA_EXTENDED_REPORT_ZONES: */ enum nvme_zns_recv_action { NVME_ZNS_ZRA_REPORT_ZONES = 0x0, @@ -6101,6 +6574,14 @@ enum nvme_zns_recv_action { /** * enum nvme_zns_report_options - + * @NVME_ZNS_ZRAS_REPORT_ALL: + * @NVME_ZNS_ZRAS_REPORT_EMPTY: + * @NVME_ZNS_ZRAS_REPORT_IMPL_OPENED: + * @NVME_ZNS_ZRAS_REPORT_EXPL_OPENED: + * @NVME_ZNS_ZRAS_REPORT_CLOSED: + * @NVME_ZNS_ZRAS_REPORT_FULL: + * @NVME_ZNS_ZRAS_REPORT_READ_ONLY: + * @NVME_ZNS_ZRAS_REPORT_OFFLINE: */ enum nvme_zns_report_options { NVME_ZNS_ZRAS_REPORT_ALL = 0x0, From 3068bd77168850c47a9e8ce6f14bfaf8ae6a53fa Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 2 Feb 2022 08:23:49 +0100 Subject: [PATCH 0424/1564] fabrics.c: fixup kernel-doc comments To keep sphinx happy. Signed-off-by: Hannes Reinecke --- src/nvme/fabrics.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index c9f987a0b0..d8f4be25fc 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -316,8 +316,10 @@ static int inet6_pton(nvme_root_t r, const char *src, uint16_t port, /** * inet_pton_with_scope - convert an IPv4/IPv6 to socket address + * @r: nvme_root_t object * @af: address family, AF_INET, AF_INET6 or AF_UNSPEC for either * @src: the start of the address string + * @trsvcid: transport service identifier * @addr: output socket address * * Return 0 on success, errno otherwise. @@ -842,15 +844,17 @@ static int uuid_from_dmi_entries(char *system_uuid) return strlen(system_uuid) ? 0 : -ENXIO; } +#define PATH_DMI_PROD_UUID "/sys/class/dmi/id/product_uuid" + /** - * @brief Get system UUID from /sys/class/dmi/id/product_uuid and fix - * endianess. + * uuid_from_product_uuid() - Get system UUID from product_uuid + * @system_uuid: Where to save the system UUID. * - * @param system_uuid - Where to save the system UUID. + * Get system UUID from /sys/class/dmi/id/product_uuid and fix + * endianess. * - * @return 0 on success, -ENXIO otherwise. + * Return: 0 on success, -ENXIO otherwise. */ -#define PATH_DMI_PROD_UUID "/sys/class/dmi/id/product_uuid" static int uuid_from_product_uuid(char *system_uuid) { FILE *stream = NULL; @@ -890,12 +894,17 @@ static int uuid_from_product_uuid(char *system_uuid) } /** - * @brief The system UUID can be read from two different locations: + * uuid_from_dmi() - read system UUID + * @system_uuid: buffer for the UUID + * + * The system UUID can be read from two different locations: * * 1) /sys/class/dmi/id/product_uuid * 2) /sys/firmware/dmi/entries * * Note that the second location is not present on Debian-based systems. + * + * Return: 0 on success, negative errno otherwise. */ static int uuid_from_dmi(char *system_uuid) { From 8d84dab7d6620eddd7a124ebedf7a492e3c5dad2 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 2 Feb 2022 08:23:49 +0100 Subject: [PATCH 0425/1564] util.h: fixup kernel-doc comments To keep sphinx happy. Signed-off-by: Hannes Reinecke --- src/nvme/util.h | 51 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/src/nvme/util.h b/src/nvme/util.h index 745aba8fcf..1a9567b4a4 100644 --- a/src/nvme/util.h +++ b/src/nvme/util.h @@ -11,19 +11,35 @@ #include "types.h" -/* nvme connect error codes */ -#define ENVME_CONNECT_RESOLVE 1000 /* "failed to resolve host" */ -#define ENVME_CONNECT_ADDRFAM 1001 /* "unrecognized address family" */ -#define ENVME_CONNECT_TRADDR 1002 /* "failed to get traddr" */ -#define ENVME_CONNECT_TARG 1003 /* "need a transport (-t) argument" */ -#define ENVME_CONNECT_AARG 1004 /* "need a address (-a) argument\n" */ -#define ENVME_CONNECT_OPEN 1005 /* "failed to open nvme-fabrics device" */ -#define ENVME_CONNECT_WRITE 1006 /* "failed to write to nvme-fabrics device" */ -#define ENVME_CONNECT_READ 1007 /* "failed to read from nvme-fabrics device" */ -#define ENVME_CONNECT_PARSE 1008 /* "failed to parse ctrl info" */ -#define ENVME_CONNECT_INVAL_TR 1009 /* "invalid transport type" */ -#define ENVME_CONNECT_LOOKUP_SUBSYS_NAME 1010 /* "failed to lookup subsystem name" */ -#define ENVME_CONNECT_LOOKUP_SUBSYS 1011 /* "failed to lookup subsystem */ +/** + * enum nvme_connect_err - nvme connect error codes + * @ENVME_CONNECT_RESOLVE: failed to resolve host + * @ENVME_CONNECT_ADDRFAM: unrecognized address family + * @ENVME_CONNECT_TRADDR: failed to get traddr + * @ENVME_CONNECT_TARG: need a transport (-t) argument + * @ENVME_CONNECT_AARG: need a address (-a) argument + * @ENVME_CONNECT_OPEN: failed to open nvme-fabrics device + * @ENVME_CONNECT_WRITE: failed to write to nvme-fabrics device + * @ENVME_CONNECT_READ: failed to read from nvme-fabrics device + * @ENVME_CONNECT_PARSE: failed to parse ctrl info + * @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 + */ +enum nvme_connect_err { + ENVME_CONNECT_RESOLVE = 1000, + ENVME_CONNECT_ADDRFAM, + ENVME_CONNECT_TRADDR, + ENVME_CONNECT_TARG, + ENVME_CONNECT_AARG, + ENVME_CONNECT_OPEN, + ENVME_CONNECT_WRITE, + ENVME_CONNECT_READ, + ENVME_CONNECT_PARSE, + ENVME_CONNECT_INVAL_TR, + ENVME_CONNECT_LOOKUP_SUBSYS_NAME, + ENVME_CONNECT_LOOKUP_SUBSYS, +}; /** * nvme_status_to_errno() - Converts nvme return status to errno @@ -100,7 +116,14 @@ void nvme_init_dsm_range(struct nvme_dsm_range *dsm, __u32 *ctx_attrs, __u32 *llbas, __u64 *slbas, __u16 nr_ranges); /** - * nvme_init_copy_range() - + * nvme_init_copy_range() - Constructs a copy range 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(struct nvme_copy_range *copy, __u16 *nlbs, __u64 *slbas, __u32 *eilbrts, __u32 *elbatms, From 50bfc12a8a5624c748cbe7952c1d65f1522c141a Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 2 Feb 2022 11:04:13 +0100 Subject: [PATCH 0426/1564] Fixup sphinx warnings When configuring with 'meson -Dman=true' sphinx is printing out errors on the generated libnvme.rst file. This patch fixes up the function documentations to fixup these warnings. Signed-off-by: Hannes Reinecke --- src/nvme/ioctl.h | 4 ++-- src/nvme/types.h | 6 +++--- src/nvme/util.h | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index e3c6b7b227..02768097fc 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -2869,7 +2869,7 @@ int nvme_ns_mgmt(struct nvme_ns_mgmt_args *args); * @csi: Command Set Identifier * * On successful creation, the namespace exists in the subsystem, but is not - * attached to any controller. Use the &nvme_ns_attach_ctrls() to assign the + * attached to any controller. Use the nvme_ns_attach_ctrls() to assign the * namespace to one or more controllers. * * Return: The nvme command status if a response was received (see @@ -2898,7 +2898,7 @@ static inline int nvme_ns_mgmt_create(int fd, struct nvme_id_ns *ns, * @nsid: Namespace identifier to delete * * It is recommended that a namespace being deleted is not attached to any - * controller. Use the &nvme_ns_detach_ctrls() first if the namespace is still + * controller. Use the nvme_ns_detach_ctrls() first if the namespace is still * attached. * * Return: The nvme command status if a response was received (see diff --git a/src/nvme/types.h b/src/nvme/types.h index 8afccbdecc..4542a09a58 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -677,9 +677,9 @@ enum nvme_psd_workload { * 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 + * 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. + * See &enum nvme_psd_workload for decoding this field. * @rsvd23: Reserved */ struct nvme_id_psd { @@ -773,7 +773,7 @@ struct nvme_id_psd { * 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 + * 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 diff --git a/src/nvme/util.h b/src/nvme/util.h index 1a9567b4a4..1308031716 100644 --- a/src/nvme/util.h +++ b/src/nvme/util.h @@ -81,7 +81,7 @@ const char *nvme_errno_to_string(int err); * @nvmsetid: NVM Set identifer * * This is intended to be used with a namespace management "create", see - * &nvme_ns_mgmt_create(). + * nvme_ns_mgmt_create(). */ void nvme_init_id_ns(struct nvme_id_ns *ns, __u64 nsze, __u64 ncap, __u8 flbas, __u8 dps, __u8 nmic, __u32 anagrpid, __u16 nvmsetid); @@ -93,7 +93,7 @@ void nvme_init_id_ns(struct nvme_id_ns *ns, __u64 nsze, __u64 ncap, __u8 flbas, * @ctrlist: An array of controller identifiers in CPU native endian. * * This is intended to be used with any command that takes a controller list - * argument. See &nvme_ns_attach_ctrls() and &nvme_ns_detach(). + * argument. See nvme_ns_attach_ctrls() and nvme_ns_detach(). */ void nvme_init_ctrl_list(struct nvme_ctrl_list *cntlist, __u16 num_ctrls, __u16 *ctrlist); @@ -107,7 +107,7 @@ void nvme_init_ctrl_list(struct nvme_ctrl_list *cntlist, __u16 num_ctrls, * @nr_ranges: The size of the dsm arrays * * Each array must be the same size of size 'nr_ranges'. This is intended to be - * used with constructing a payload for &nvme_dsm(). + * used with constructing a payload for nvme_dsm(). * * Return: The nvme command status if a response was received or -errno * otherwise. From 4da2674428615943699aae6531d477e44c5a2468 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 2 Feb 2022 11:24:47 +0100 Subject: [PATCH 0427/1564] Regenerate libnvme.rst Regenerate libnvme.rst with 'kernel-doc src/nvme/{filters,ioctl,linux,tree,types,fabrics,util}.h > doc/libnvme.rst' Signed-off-by: Hannes Reinecke --- doc/libnvme.rst | 17460 +++++++++++++++++++++++++++++++--------------- 1 file changed, 12026 insertions(+), 5434 deletions(-) diff --git a/doc/libnvme.rst b/doc/libnvme.rst index 1196b1c032..975f0d8e26 100644 --- a/doc/libnvme.rst +++ b/doc/libnvme.rst @@ -1,74 +1,79 @@ -.. c:function:: int nvme_namespace_filter (const struct dirent * d) +.. c:function:: int nvme_namespace_filter (const struct dirent *d) **Parameters** -``const struct dirent * d`` +``const struct dirent *d`` -.. c:function:: int nvme_paths_filter (const struct dirent * d) +.. c:function:: int nvme_paths_filter (const struct dirent *d) **Parameters** -``const struct dirent * d`` +``const struct dirent *d`` -.. c:function:: int nvme_ctrls_filter (const struct dirent * d) +.. c:function:: int nvme_ctrls_filter (const struct dirent *d) **Parameters** -``const struct dirent * d`` +``const struct dirent *d`` -.. c:function:: int nvme_subsys_filter (const struct dirent * d) +.. c:function:: int nvme_subsys_filter (const struct dirent *d) **Parameters** -``const struct dirent * d`` +``const struct dirent *d`` -.. c:function:: int nvme_scan_subsystems (struct dirent *** subsys) +.. c:function:: int nvme_scan_subsystems (struct dirent ***subsys) **Parameters** -``struct dirent *** subsys`` +``struct dirent ***subsys`` -.. c:function:: int nvme_scan_subsystem_namespaces (nvme_subsystem_t s, struct dirent *** namespaces) +.. c:function:: int nvme_scan_subsystem_namespaces (nvme_subsystem_t s, struct dirent ***namespaces) **Parameters** ``nvme_subsystem_t s`` - *undescribed* -``struct dirent *** namespaces`` +``struct dirent ***namespaces`` -.. c:function:: int nvme_scan_ctrl_namespace_paths (nvme_ctrl_t c, struct dirent *** namespaces) +.. c:function:: int nvme_scan_ctrls (struct dirent ***ctrls) + + +**Parameters** + +``struct dirent ***ctrls`` + + +.. c:function:: int nvme_scan_ctrl_namespace_paths (nvme_ctrl_t c, struct dirent ***namespaces) **Parameters** ``nvme_ctrl_t c`` - *undescribed* -``struct dirent *** namespaces`` +``struct dirent ***namespaces`` -.. c:function:: int nvme_scan_ctrl_namespaces (nvme_ctrl_t c, struct dirent *** namespaces) +.. c:function:: int nvme_scan_ctrl_namespaces (nvme_ctrl_t c, struct dirent ***namespaces) **Parameters** ``nvme_ctrl_t c`` - *undescribed* -``struct dirent *** namespaces`` +``struct dirent ***namespaces`` @@ -251,7 +256,7 @@ -.. c:function:: int nvme_submit_admin_passthru64 (int fd, struct nvme_passthru_cmd64 * cmd, __u64 * result) +.. c:function:: int nvme_submit_admin_passthru64 (int fd, struct nvme_passthru_cmd64 *cmd, __u64 *result) Submit a 64-bit nvme passthrough admin command @@ -260,10 +265,10 @@ ``int fd`` File descriptor of nvme device -``struct nvme_passthru_cmd64 * cmd`` +``struct nvme_passthru_cmd64 *cmd`` The nvme admin command to send -``__u64 * result`` +``__u64 *result`` Optional field to return the result from the CQE DW0-1 **Description** @@ -276,7 +281,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_admin_passthru64 (int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, __u32 data_len, void * data, __u32 metadata_len, void * metadata, __u32 timeout_ms, __u64 * result) +.. c:function:: int nvme_admin_passthru64 (int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, __u32 data_len, void *data, __u32 metadata_len, void *metadata, __u32 timeout_ms, __u64 *result) Submit an nvme passthrough command @@ -324,19 +329,19 @@ The nvme command status if a response was received (see ``__u32 data_len`` Length of the data transfered in this command in bytes -``void * data`` +``void *data`` Pointer to user address of the data buffer ``__u32 metadata_len`` Length of metadata transfered in this command -``void * metadata`` +``void *metadata`` Pointer to user address of the metadata buffer ``__u32 timeout_ms`` How long the kernel waits for the command to complete -``__u64 * result`` +``__u64 *result`` Optional field to return the result from the CQE dword 0 **Description** @@ -352,7 +357,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_submit_admin_passthru (int fd, struct nvme_passthru_cmd * cmd, __u32 * result) +.. c:function:: int nvme_submit_admin_passthru (int fd, struct nvme_passthru_cmd *cmd, __u32 *result) Submit an nvme passthrough admin command @@ -361,10 +366,10 @@ The nvme command status if a response was received (see ``int fd`` File descriptor of nvme device -``struct nvme_passthru_cmd * cmd`` +``struct nvme_passthru_cmd *cmd`` The nvme admin command to send -``__u32 * result`` +``__u32 *result`` Optional field to return the result from the CQE DW0 **Description** @@ -377,7 +382,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_admin_passthru (int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, __u32 data_len, void * data, __u32 metadata_len, void * metadata, __u32 timeout_ms, __u32 * result) +.. c:function:: int nvme_admin_passthru (int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, __u32 data_len, void *data, __u32 metadata_len, void *metadata, __u32 timeout_ms, __u32 *result) Submit an nvme passthrough command @@ -425,19 +430,19 @@ The nvme command status if a response was received (see ``__u32 data_len`` Length of the data transfered in this command in bytes -``void * data`` +``void *data`` Pointer to user address of the data buffer ``__u32 metadata_len`` Length of metadata transfered in this command -``void * metadata`` +``void *metadata`` Pointer to user address of the metadata buffer ``__u32 timeout_ms`` How long the kernel waits for the command to complete -``__u32 * result`` +``__u32 *result`` Optional field to return the result from the CQE dword 0 **Description** @@ -453,7 +458,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_submit_io_passthru64 (int fd, struct nvme_passthru_cmd64 * cmd, __u64 * result) +.. c:function:: int nvme_submit_io_passthru64 (int fd, struct nvme_passthru_cmd64 *cmd, __u64 *result) Submit a 64-bit nvme passthrough command @@ -462,10 +467,10 @@ The nvme command status if a response was received (see ``int fd`` File descriptor of nvme device -``struct nvme_passthru_cmd64 * cmd`` +``struct nvme_passthru_cmd64 *cmd`` The nvme io command to send -``__u64 * result`` +``__u64 *result`` Optional field to return the result from the CQE DW0-1 **Description** @@ -478,7 +483,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_io_passthru64 (int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, __u32 data_len, void * data, __u32 metadata_len, void * metadata, __u32 timeout_ms, __u64 * result) +.. c:function:: int nvme_io_passthru64 (int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, __u32 data_len, void *data, __u32 metadata_len, void *metadata, __u32 timeout_ms, __u64 *result) Submit an nvme io passthrough command @@ -526,19 +531,19 @@ The nvme command status if a response was received (see ``__u32 data_len`` Length of the data transfered in this command in bytes -``void * data`` +``void *data`` Pointer to user address of the data buffer ``__u32 metadata_len`` Length of metadata transfered in this command -``void * metadata`` +``void *metadata`` Pointer to user address of the metadata buffer ``__u32 timeout_ms`` How long the kernel waits for the command to complete -``__u64 * result`` +``__u64 *result`` Optional field to return the result from the CQE dword 0 **Description** @@ -554,7 +559,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_submit_io_passthru (int fd, struct nvme_passthru_cmd * cmd, __u32 * result) +.. c:function:: int nvme_submit_io_passthru (int fd, struct nvme_passthru_cmd *cmd, __u32 *result) Submit an nvme passthrough command @@ -563,10 +568,10 @@ The nvme command status if a response was received (see ``int fd`` File descriptor of nvme device -``struct nvme_passthru_cmd * cmd`` +``struct nvme_passthru_cmd *cmd`` The nvme io command to send -``__u32 * result`` +``__u32 *result`` Optional field to return the result from the CQE DW0 **Description** @@ -579,7 +584,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_io_passthru (int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, __u32 data_len, void * data, __u32 metadata_len, void * metadata, __u32 timeout_ms, __u32 * result) +.. c:function:: int nvme_io_passthru (int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, __u32 data_len, void *data, __u32 metadata_len, void *metadata, __u32 timeout_ms, __u32 *result) Submit an nvme io passthrough command @@ -627,19 +632,19 @@ The nvme command status if a response was received (see ``__u32 data_len`` Length of the data transfered in this command in bytes -``void * data`` +``void *data`` Pointer to user address of the data buffer ``__u32 metadata_len`` Length of metadata transfered in this command -``void * metadata`` +``void *metadata`` Pointer to user address of the metadata buffer ``__u32 timeout_ms`` How long the kernel waits for the command to complete -``__u32 * result`` +``__u32 *result`` Optional field to return the result from the CQE dword 0 **Description** @@ -710,7 +715,7 @@ This should only be sent to controller handles, not to namespaces. 0 if a rescan was initiated or -1 with errno set otherwise. -.. c:function:: int nvme_get_nsid (int fd) +.. c:function:: int nvme_get_nsid (int fd, __u32 *nsid) Retrieve the NSID from a namespace file descriptor @@ -719,609 +724,642 @@ This should only be sent to controller handles, not to namespaces. ``int fd`` File descriptor of nvme namespace +``__u32 *nsid`` + User pointer to namespace id + **Description** -This should only be sent to namespace handles, not to controllers. +This should only be sent to namespace handles, not to controllers. The +kernel's interface returns the nsid as the return value. This is unfortunate +for many architectures that are incapable of allowing distinguishing a +namespace id > 0x80000000 from a negative error number. **Return** -The namespace identifier if a succecssful or -1 with errno set -otherwise. +0 if **nsid** was set successfully or -1 with errno set otherwise. -.. c:type:: enum nvme_admin_opcode +.. c:type:: struct nvme_identify_args - Known NVMe admin opcodes + Arguments for the NVMe Identify command -**Constants** +**Definition** -``nvme_admin_delete_sq`` - *undescribed* +:: -``nvme_admin_create_sq`` - *undescribed* + 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 nvmsetid; + __u16 domid; + __u8 uuidx; + }; -``nvme_admin_get_log_page`` - *undescribed* +**Members** -``nvme_admin_delete_cq`` - *undescribed* +``result`` + The command completion result from CQE dword0 -``nvme_admin_create_cq`` - *undescribed* +``data`` + User space destination address to transfer the data -``nvme_admin_identify`` - *undescribed* +``args_size`` + Size of :c:type:`struct nvme_identify_args ` -``nvme_admin_abort_cmd`` - *undescribed* +``fd`` + File descriptor of nvme device -``nvme_admin_set_features`` - *undescribed* +``timeout`` + Timeout in ms (0 for default timeout) -``nvme_admin_get_features`` - *undescribed* +``cns`` + The Controller or Namespace structure, see **enum** nvme_identify_cns -``nvme_admin_async_event`` - *undescribed* +``csi`` + Command Set Identifier -``nvme_admin_ns_mgmt`` - *undescribed* +``nsid`` + Namespace identifier, if applicable -``nvme_admin_fw_commit`` - *undescribed* +``cntid`` + The Controller Identifier, if applicable -``nvme_admin_fw_download`` - *undescribed* +``nvmsetid`` + The NVMe Set ID if CNS is 04h -``nvme_admin_dev_self_test`` - *undescribed* +``domid`` + Domain identifier, if applicable -``nvme_admin_ns_attach`` - *undescribed* +``uuidx`` + UUID Index if controller supports this id selection method -``nvme_admin_keep_alive`` - *undescribed* -``nvme_admin_directive_send`` - *undescribed* -``nvme_admin_directive_recv`` - *undescribed* +.. c:function:: int nvme_identify (struct nvme_identify_args *args) -``nvme_admin_virtual_mgmt`` - *undescribed* + Send the NVMe Identify command -``nvme_admin_nvme_mi_send`` - *undescribed* +**Parameters** -``nvme_admin_nvme_mi_recv`` - *undescribed* +``struct nvme_identify_args *args`` + :c:type:`struct nvme_identify_args ` argument structure -``nvme_admin_dbbuf`` - *undescribed* +**Description** -``nvme_admin_fabrics`` - *undescribed* +The Identify command returns a data buffer that describes information about +the NVM subsystem, the controller or the namespace(s). -``nvme_admin_format_nvm`` - *undescribed* +**Return** -``nvme_admin_security_send`` - *undescribed* +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -``nvme_admin_security_recv`` - *undescribed* -``nvme_admin_sanitize_nvm`` - *undescribed* +.. c:function:: int nvme_identify_ctrl (int fd, struct nvme_id_ctrl *id) -``nvme_admin_get_lba_status`` - *undescribed* + Retrieves nvme identify controller +**Parameters** +``int fd`` + File descriptor of nvme device +``struct nvme_id_ctrl *id`` + User space destination address to transfer the data, -.. c:type:: enum nvme_identify_cns +**Description** +Sends nvme identify with CNS value ``NVME_IDENTIFY_CNS_CTRL``. -**Constants** +See :c:type:`struct nvme_id_ctrl ` for details on the data returned. -``NVME_IDENTIFY_CNS_NS`` - *undescribed* +**Return** -``NVME_IDENTIFY_CNS_CTRL`` - *undescribed* +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -``NVME_IDENTIFY_CNS_NS_ACTIVE_LIST`` - *undescribed* -``NVME_IDENTIFY_CNS_NS_DESC_LIST`` - *undescribed* +.. c:function:: int nvme_identify_ns (int fd, __u32 nsid, struct nvme_id_ns *ns) -``NVME_IDENTIFY_CNS_NVMSET_LIST`` - *undescribed* + Retrieves nvme identify namespace -``NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST`` - *undescribed* +**Parameters** -``NVME_IDENTIFY_CNS_ALLOCATED_NS`` - *undescribed* +``int fd`` + File descriptor of nvme device -``NVME_IDENTIFY_CNS_NS_CTRL_LIST`` - *undescribed* +``__u32 nsid`` + Namespace to identify -``NVME_IDENTIFY_CNS_CTRL_LIST`` - *undescribed* +``struct nvme_id_ns *ns`` + User space destination address to transfer the data -``NVME_IDENTIFY_CNS_PRIMARY_CTRL_CAP`` - *undescribed* +**Description** -``NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST`` - *undescribed* +If the Namespace Identifier (NSID) field specifies an active NSID, then the +Identify Namespace data structure is returned to the host for that specified +namespace. -``NVME_IDENTIFY_CNS_NS_GRANULARITY`` - *undescribed* +If the controller supports the Namespace Management capability and the NSID +field is set to ``NVME_NSID_ALL``, then the controller returns an Identify Namespace +data structure that specifies capabilities that are common across namespaces +for this controller. -``NVME_IDENTIFY_CNS_UUID_LIST`` - *undescribed* +See :c:type:`struct nvme_id_ns ` for details on the structure returned. +**Return** +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:type:: enum nvme_cmd_get_log_lid +.. c:function:: int nvme_identify_allocated_ns (int fd, __u32 nsid, struct nvme_id_ns *ns) + Same as nvme_identify_ns, but only for allocated namespaces -**Constants** +**Parameters** -``NVME_LOG_LID_ERROR`` - *undescribed* +``int fd`` + File descriptor of nvme device -``NVME_LOG_LID_SMART`` - *undescribed* +``__u32 nsid`` + Namespace to identify -``NVME_LOG_LID_FW_SLOT`` - *undescribed* +``struct nvme_id_ns *ns`` + User space destination address to transfer the data -``NVME_LOG_LID_CHANGED_NS`` - *undescribed* +**Return** -``NVME_LOG_LID_CMD_EFFECTS`` - *undescribed* +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -``NVME_LOG_LID_DEVICE_SELF_TEST`` - *undescribed* -``NVME_LOG_LID_TELEMETRY_HOST`` - *undescribed* +.. c:function:: int nvme_identify_active_ns_list (int fd, __u32 nsid, struct nvme_ns_list *list) -``NVME_LOG_LID_TELEMETRY_CTRL`` - *undescribed* + Retrieves active namespaces id list -``NVME_LOG_LID_ENDURANCE_GROUP`` - *undescribed* +**Parameters** -``NVME_LOG_LID_PREDICTABLE_LAT_NVMSET`` - *undescribed* +``int fd`` + File descriptor of nvme device -``NVME_LOG_LID_PREDICTABLE_LAT_AGG`` - *undescribed* +``__u32 nsid`` + Return namespaces greater than this identifer -``NVME_LOG_LID_ANA`` - *undescribed* +``struct nvme_ns_list *list`` + User space destination address to transfer the data -``NVME_LOG_LID_PERSISTENT_EVENT`` - *undescribed* +**Description** -``NVME_LOG_LID_LBA_STATUS`` - *undescribed* +A list of 1024 namespace IDs is returned to the host containing NSIDs in +increasing order that are greater than the value specified in the Namespace +Identifier (nsid) field of the command. -``NVME_LOG_LID_ENDURANCE_GRP_EVT`` - *undescribed* +See :c:type:`struct nvme_ns_list ` for the definition of the returned structure. -``NVME_LOG_LID_MEDIA_UNIT_STATUS`` - *undescribed* +**Return** -``NVME_LOG_LID_DISCOVER`` - *undescribed* +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -``NVME_LOG_LID_RESERVATION`` - *undescribed* -``NVME_LOG_LID_SANITIZE`` - *undescribed* +.. c:function:: int nvme_identify_allocated_ns_list (int fd, __u32 nsid, struct nvme_ns_list *list) + Retrieves allocated namespace id list +**Parameters** +``int fd`` + File descriptor of nvme device -.. c:type:: enum nvme_features_id +``__u32 nsid`` + Return namespaces greater than this identifer +``struct nvme_ns_list *list`` + User space destination address to transfer the data -**Constants** +**Description** -``NVME_FEAT_FID_ARBITRATION`` - *undescribed* +A list of 1024 namespace IDs is returned to the host containing NSIDs in +increasing order that are greater than the value specified in the Namespace +Identifier (nsid) field of the command. -``NVME_FEAT_FID_POWER_MGMT`` - *undescribed* +See :c:type:`struct nvme_ns_list ` for the definition of the returned structure. -``NVME_FEAT_FID_LBA_RANGE`` - *undescribed* +**Return** -``NVME_FEAT_FID_TEMP_THRESH`` - *undescribed* +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -``NVME_FEAT_FID_ERR_RECOVERY`` - *undescribed* -``NVME_FEAT_FID_VOLATILE_WC`` - *undescribed* +.. c:function:: int nvme_identify_ctrl_list (int fd, __u16 cntid, struct nvme_ctrl_list *cntlist) -``NVME_FEAT_FID_NUM_QUEUES`` - *undescribed* + Retrieves identify controller list -``NVME_FEAT_FID_IRQ_COALESCE`` - *undescribed* +**Parameters** -``NVME_FEAT_FID_IRQ_CONFIG`` - *undescribed* +``int fd`` + File descriptor of nvme device -``NVME_FEAT_FID_WRITE_ATOMIC`` - *undescribed* +``__u16 cntid`` + Starting CNTLID to return in the list -``NVME_FEAT_FID_ASYNC_EVENT`` - *undescribed* +``struct nvme_ctrl_list *cntlist`` + User space destination address to transfer the data -``NVME_FEAT_FID_AUTO_PST`` - *undescribed* +**Description** -``NVME_FEAT_FID_HOST_MEM_BUF`` - *undescribed* +Up to 2047 controller identifiers is returned containing a controller +identifier greater than or equal to the controller identifier specified in +**cntid**. -``NVME_FEAT_FID_TIMESTAMP`` - *undescribed* +See :c:type:`struct nvme_ctrl_list ` for a definition of the structure returned. -``NVME_FEAT_FID_KATO`` - *undescribed* +**Return** -``NVME_FEAT_FID_HCTM`` - *undescribed* +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -``NVME_FEAT_FID_NOPSC`` - *undescribed* -``NVME_FEAT_FID_RRL`` - *undescribed* +.. c:function:: int nvme_identify_nsid_ctrl_list (int fd, __u32 nsid, __u16 cntid, struct nvme_ctrl_list *cntlist) -``NVME_FEAT_FID_PLM_CONFIG`` - *undescribed* -``NVME_FEAT_FID_PLM_WINDOW`` - *undescribed* +**Parameters** -``NVME_FEAT_FID_LBA_STS_INTERVAL`` - *undescribed* +``int fd`` + File descriptor of nvme device -``NVME_FEAT_FID_HOST_BEHAVIOR`` - *undescribed* +``__u32 nsid`` + Return controllers that are attached to this nsid -``NVME_FEAT_FID_SANITIZE`` - *undescribed* +``__u16 cntid`` + Starting CNTLID to return in the list -``NVME_FEAT_FID_ENDURANCE_EVT_CFG`` - *undescribed* +``struct nvme_ctrl_list *cntlist`` + User space destination address to transfer the data -``NVME_FEAT_FID_SW_PROGRESS`` - *undescribed* +**Description** -``NVME_FEAT_FID_HOST_ID`` - *undescribed* +Up to 2047 controller identifiers is returned containing a controller +identifier greater than or equal to the controller identifier specified in +**cntid**. -``NVME_FEAT_FID_RESV_MASK`` - *undescribed* +See :c:type:`struct nvme_ctrl_list ` for a definition of the structure returned. -``NVME_FEAT_FID_RESV_PERSIST`` - *undescribed* +**Return** -``NVME_FEAT_FID_WRITE_PROTECT`` - *undescribed* +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 +.. c:function:: int nvme_identify_ns_descs (int fd, __u32 nsid, struct nvme_ns_id_desc *descs) + Retrieves namespace descriptor list -.. c:type:: enum nvme_get_features_sel +**Parameters** +``int fd`` + File descriptor of nvme device -**Constants** +``__u32 nsid`` + The namespace id to retrieve destriptors -``NVME_GET_FEATURES_SEL_CURRENT`` - *undescribed* +``struct nvme_ns_id_desc *descs`` + User space destination address to transfer the data -``NVME_GET_FEATURES_SEL_DEFAULT`` - *undescribed* +**Description** -``NVME_GET_FEATURES_SEL_SAVED`` - *undescribed* +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'. +See :c:type:`struct nvme_ns_id_desc ` for the definition of the returned structure. +**Return** -.. c:type:: enum nvme_cmd_format_mset +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -**Constants** +.. c:function:: int nvme_identify_nvmset_list (int fd, __u16 nvmsetid, struct nvme_id_nvmset_list *nvmset) -``NVME_FORMAT_MSET_SEPARATE`` - *undescribed* + Retrieves NVM Set List -``NVME_FORMAT_MSET_EXTENEDED`` - *undescribed* +**Parameters** +``int fd`` + File descriptor of nvme device +``__u16 nvmsetid`` + NVM Set Identifier +``struct nvme_id_nvmset_list *nvmset`` + User space destination address to transfer the data -.. c:type:: enum nvme_cmd_format_pi - - -**Constants** - -``NVME_FORMAT_PI_DISABLE`` - *undescribed* - -``NVME_FORMAT_PI_TYPE1`` - *undescribed* +**Description** -``NVME_FORMAT_PI_TYPE2`` - *undescribed* +Retrieves an NVM Set List, :c:type:`struct nvme_id_nvmset_list `. The data structure +is an ordered list by NVM Set Identifier, starting with the first NVM Set +Identifier supported by the NVM subsystem that is equal to or greater than +the NVM Set Identifier. -``NVME_FORMAT_PI_TYPE3`` - *undescribed* +See :c:type:`struct nvme_id_nvmset_list ` for the defintion of the returned structure. +**Return** +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:type:: enum nvme_cmd_format_ses +.. c:function:: int nvme_identify_primary_ctrl (int fd, __u16 cntid, struct nvme_primary_ctrl_cap *cap) + Retrieve NVMe Primary Controller identification -**Constants** +**Parameters** -``NVME_FORMAT_SES_NONE`` - *undescribed* +``int fd`` + File descriptor of nvme device -``NVME_FORMAT_SES_USER_DATA_ERASE`` - *undescribed* +``__u16 cntid`` + Return controllers starting at this identifier -``NVME_FORMAT_SES_CRYPTO_ERASE`` - *undescribed* +``struct nvme_primary_ctrl_cap *cap`` + User space destination buffer address to transfer the data +**Description** +See :c:type:`struct nvme_primary_ctrl_cap ` for the defintion of the returned structure, **cap**. +**Return** -.. c:type:: enum nvme_ns_mgmt_sel +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -**Constants** +.. c:function:: int nvme_identify_secondary_ctrl_list (int fd, __u32 nsid, __u16 cntid, struct nvme_secondary_ctrl_list *sc_list) -``NVME_NS_MGMT_SEL_CREATE`` - *undescribed* + Retrieves secondary controller list -``NVME_NS_MGMT_SEL_DELETE`` - *undescribed* +**Parameters** +``int fd`` + File descriptor of nvme device +``__u32 nsid`` + Namespace identifier +``__u16 cntid`` + Return controllers starting at this identifier -.. c:type:: enum nvme_ns_attach_sel +``struct nvme_secondary_ctrl_list *sc_list`` + User space destination address to transfer the data - NVME_NS_ATTACH_SEL_CTRL_ATTACH: NVME_NP_ATTACH_SEL_CTRL_DEATTACH: +**Description** -**Constants** +A Secondary Controller List is returned to the host for up to 127 secondary +controllers associated with the primary controller processing this command. +The list contains entries for controller identifiers greater than or equal +to the value specified in the Controller Identifier (cntid). -``NVME_NS_ATTACH_SEL_CTRL_ATTACH`` - *undescribed* +See :c:type:`struct nvme_secondary_ctrls_list ` for a defintion of the returned +structure. -``NVME_NS_ATTACH_SEL_CTRL_DEATTACH`` - *undescribed* +**Return** +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. +.. c:function:: int nvme_identify_ns_granularity (int fd, struct nvme_id_ns_granularity_list *gr_list) -.. c:type:: enum nvme_fw_commit_ca + Retrieves namespace granularity identification +**Parameters** -**Constants** +``int fd`` + File descriptor of nvme device -``NVME_FW_COMMIT_CA_REPLACE`` - *undescribed* +``struct nvme_id_ns_granularity_list *gr_list`` + User space destination address to transfer the data -``NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE`` - *undescribed* +**Description** -``NVME_FW_COMMIT_CA_SET_ACTIVE`` - *undescribed* +If the controller supports reporting of Namespace Granularity, then a +Namespace Granularity List is returned to the host for up to sixteen +namespace granularity descriptors -``NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE_IMMEDIATE`` - *undescribed* +See :c:type:`struct nvme_id_ns_granularity_list ` for the definition of the returned +structure. -``NVME_FW_COMMIT_CA_REPLACE_BOOT_PARTITION`` - *undescribed* +**Return** -``NVME_FW_COMMIT_CA_ACTIVATE_BOOT_PARTITION`` - *undescribed* +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. +.. c:function:: int nvme_identify_uuid (int fd, struct nvme_id_uuid_list *uuid_list) + Retrieves device's UUIDs -.. c:type:: enum nvme_directive_dtype +**Parameters** +``int fd`` + File descriptor of nvme device -**Constants** +``struct nvme_id_uuid_list *uuid_list`` + User space destination address to transfer the data -``NVME_DIRECTIVE_DTYPE_IDENTIFY`` - *undescribed* +**Description** -``NVME_DIRECTIVE_DTYPE_STREAMS`` - *undescribed* +Each UUID List entry is either 0h, the NVMe Invalid UUID, or a valid UUID. +Valid UUIDs are those which are non-zero and are not the NVMe Invalid UUID. +See :c:type:`struct nvme_id_uuid_list ` for the definition of the returned structure. +**Return** +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:type:: enum nvme_directive_receive_doper +.. c:function:: int nvme_identify_ns_csi (int fd, __u32 nsid, enum nvme_csi csi, void *data) -**Constants** -``NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM`` - *undescribed* +**Parameters** -``NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM`` - *undescribed* +``int fd`` + File descriptor of nvme device -``NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS`` - *undescribed* +``__u32 nsid`` + Namespace to identify -``NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE`` - *undescribed* +``enum nvme_csi csi`` + Command Set Identifier +``void *data`` + User space destination address to transfer the data +**Return** +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:type:: enum nvme_directive_send_doper +.. c:function:: int nvme_identify_ctrl_csi (int fd, enum nvme_csi csi, void *data) -**Constants** -``NVME_DIRECTIVE_SEND_IDENTIFY_DOPER_ENDIR`` - *undescribed* +**Parameters** -``NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_IDENTIFIER`` - *undescribed* +``int fd`` + File descriptor of nvme device -``NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE`` - *undescribed* +``enum nvme_csi csi`` + Command Set Identifier +``void *data`` + User space destination address to transfer the data +**Return** +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:type:: enum nvme_directive_send_identify_endir +.. c:function:: int nvme_identify_active_ns_list_csi (int fd, __u32 nsid, enum nvme_csi csi, struct nvme_ns_list *ns_list) -**Constants** -``NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_DISABLE`` - *undescribed* +**Parameters** -``NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_ENABLE`` - *undescribed* +``int fd`` + File descriptor of nvme device +``__u32 nsid`` + Return namespaces greater than this identifier +``enum nvme_csi csi`` + Command Set Identifier +``struct nvme_ns_list *ns_list`` + User space destination address to transfer the data -.. c:type:: enum nvme_sanitize_sanact +**Description** +A list of 1024 namespace IDs is returned to the host containing active +NSIDs in increasing order that are greater than the value specified in +the Namespace Identifier (nsid) field of the command and matching the +I/O Command Set specified in the **csi** argument. -**Constants** +See :c:type:`struct nvme_ns_list ` for the definition of the returned structure. -``NVME_SANITIZE_SANACT_EXIT_FAILURE`` - *undescribed* +**Return** -``NVME_SANITIZE_SANACT_START_BLOCK_ERASE`` - *undescribed* +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -``NVME_SANITIZE_SANACT_START_OVERWRITE`` - *undescribed* -``NVME_SANITIZE_SANACT_START_CRYPTO_ERASE`` - *undescribed* +.. c:function:: int nvme_identify_allocated_ns_list_csi (int fd, __u32 nsid, enum nvme_csi csi, struct nvme_ns_list *ns_list) +**Parameters** +``int fd`` + File descriptor of nvme device -.. c:type:: enum nvme_dst_stc +``__u32 nsid`` + Return namespaces greater than this identifier +``enum nvme_csi csi`` + Command Set Identifier -**Constants** +``struct nvme_ns_list *ns_list`` + User space destination address to transfer the data -``NVME_DST_STC_SHORT`` - *undescribed* +**Description** -``NVME_DST_STC_LONG`` - *undescribed* +A list of 1024 namespace IDs is returned to the host containing allocated +NSIDs in increasing order that are greater than the value specified in +the **nsid** field of the command and matching the I/O Command Set +specified in the **csi** argument. -``NVME_DST_STC_VS`` - *undescribed* +See :c:type:`struct nvme_ns_list ` for the definition of the returned structure. -``NVME_DST_STC_ABORT`` - *undescribed* +**Return** +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. +.. c:function:: int nvme_identify_independent_identify_ns (int fd, __u32 nsid, struct nvme_id_independent_id_ns *ns) -.. c:type:: enum nvme_virt_mgmt_act +**Parameters** -**Constants** +``int fd`` + File descriptor of nvme device -``NVME_VIRT_MGMT_ACT_PRIM_CTRL_FLEX_ALLOC`` - *undescribed* +``__u32 nsid`` + Return namespaces greater than this identifier -``NVME_VIRT_MGMT_ACT_OFFLINE_SEC_CTRL`` - *undescribed* +``struct nvme_id_independent_id_ns *ns`` + I/O Command Set Independent Identify Namespace data + structure -``NVME_VIRT_MGMT_ACT_ASSIGN_SEC_CTRL`` - *undescribed* +**Return** -``NVME_VIRT_MGMT_ACT_ONLINE_SEC_CTRL`` - *undescribed* +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. +.. c:function:: int nvme_nvm_identify_ctrl (int fd, struct nvme_id_ctrl_nvm *id) -.. c:type:: enum nvme_virt_mgmt_rt +**Parameters** +``int fd`` + File descriptor of nvme device -**Constants** +``struct nvme_id_ctrl_nvm *id`` + User space destination address to transfer the data -``NVME_VIRT_MGMT_RT_VQ_RESOURCE`` - *undescribed* +**Return** -``NVME_VIRT_MGMT_RT_VI_RESOURCE`` - *undescribed* +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_identify (int fd, enum nvme_identify_cns cns, __u32 nsid, __u16 cntid, __u16 nvmsetid, __u8 uuidx, void * data) +.. c:function:: int nvme_identify_domain_list (int fd, __u16 domid, struct nvme_id_domain_list *list) - Send the NVMe Identify command **Parameters** ``int fd`` File descriptor of nvme device -``enum nvme_identify_cns cns`` - The Controller or Namespace structure, see **enum** nvme_identify_cns - -``__u32 nsid`` - Namespace identifier, if applicable - -``__u16 cntid`` - The Controller Identifier, if applicable - -``__u16 nvmsetid`` - The NVMe Set ID if CNS is 04h - -``__u8 uuidx`` - UUID Index if controller supports this id selection method +``__u16 domid`` + Domain ID -``void * data`` - User space destination address to transfer the data +``struct nvme_id_domain_list *list`` + User space destiantion address to transfer data **Description** -The Identify command returns a data buffer that describes information about -the NVM subsystem, the controller or the namespace(s). +A list of 31 domain IDs is returned to the host containing domain +attributes in increasing order that are greater than the value +specified in the **domid** field. + +See :c:type:`struct nvme_identify_domain_attr ` for the definition of the +returned structure. **Return** @@ -1329,24 +1367,19 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_identify_ctrl (int fd, struct nvme_id_ctrl * id) +.. c:function:: int nvme_identify_endurance_group_list (int fd, __u16 endgrp_id, struct nvme_id_endurance_group_list *list) - Retrieves nvme identify controller **Parameters** ``int fd`` File descriptor of nvme device - id: User space destination address to transfer the data, - -``struct nvme_id_ctrl * id`` - *undescribed* - -**Description** -Sends nvme identify with CNS value ``NVME_IDENTIFY_CNS_CTRL``. +``__u16 endgrp_id`` + Endurance group identifier -See :c:type:`struct nvme_id_ctrl ` for details on the data returned. +``struct nvme_id_endurance_group_list *list`` + Array of endurance group identifiers **Return** @@ -1354,33 +1387,24 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_identify_ns (int fd, __u32 nsid, struct nvme_id_ns * ns) +.. c:function:: int nvme_identify_iocs (int fd, __u16 cntlid, struct nvme_id_iocs *iocs) - Retrieves nvme identify namespace **Parameters** ``int fd`` File descriptor of nvme device -``__u32 nsid`` - Namespace to identify +``__u16 cntlid`` + Controller ID -``struct nvme_id_ns * ns`` +``struct nvme_id_iocs *iocs`` User space destination address to transfer the data **Description** -If the Namespace Identifier (NSID) field specifies an active NSID, then the -Identify Namespace data structure is returned to the host for that specified -namespace. - -If the controller supports the Namespace Management capability and the NSID -field is set to ``NVME_NSID_ALL``, then the controller returns an Identify Namespace -data structure that specifies capabilities that are common across namespaces -for this controller. - -See :c:type:`struct nvme_id_ns ` for details on the structure returned. +Retrieves list of the controller's supported io command set vectors. See +:c:type:`struct nvme_id_iocs `. **Return** @@ -1388,9 +1412,8 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_identify_allocated_ns (int fd, __u32 nsid, struct nvme_id_ns * ns) +.. c:function:: int nvme_zns_identify_ns (int fd, __u32 nsid, struct nvme_zns_id_ns *data) - Same as nvme_identify_ns, but only for allocated namespaces **Parameters** @@ -1400,7 +1423,7 @@ The nvme command status if a response was received (see ``__u32 nsid`` Namespace to identify -``struct nvme_id_ns * ns`` +``struct nvme_zns_id_ns *data`` User space destination address to transfer the data **Return** @@ -1409,28 +1432,16 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_identify_active_ns_list (int fd, __u32 nsid, struct nvme_ns_list * list) +.. c:function:: int nvme_zns_identify_ctrl (int fd, struct nvme_zns_id_ctrl *id) - Retrieves active namespaces id list **Parameters** ``int fd`` File descriptor of nvme device -``__u32 nsid`` - Return namespaces greater than this identifer - -``struct nvme_ns_list * list`` - *undescribed* - -**Description** - -A list of 1024 namespace IDs is returned to the host containing NSIDs in -increasing order that are greater than the value specified in the Namespace -Identifier (nsid) field of the command. - -See :c:type:`struct nvme_ns_list ` for the definition of the returned structure. +``struct nvme_zns_id_ctrl *id`` + User space destination address to transfer the data **Return** @@ -1438,256 +1449,98 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_identify_allocated_ns_list (int fd, __u32 nsid, struct nvme_ns_list * list) - Retrieves allocated namespace id list -**Parameters** +.. c:type:: struct nvme_get_log_args -``int fd`` - File descriptor of nvme device + Arguments for the NVMe Admin Get Log command -``__u32 nsid`` - Return namespaces greater than this identifer +**Definition** -``struct nvme_ns_list * list`` - *undescribed* +:: -**Description** + 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; + __u16 domid; + __u8 lsp; + __u8 uuidx; + bool rae; + bool ot; + }; -A list of 1024 namespace IDs is returned to the host containing NSIDs in -increasing order that are greater than the value specified in the Namespace -Identifier (nsid) field of the command. +**Members** -See :c:type:`struct nvme_ns_list ` for the definition of the returned structure. +``lpo`` + Log page offset for partial log transfers -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_identify_ctrl_list (int fd, __u16 cntid, struct nvme_ctrl_list * ctrlist) - - Retrieves identify controller list - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u16 cntid`` - *undescribed* - -``struct nvme_ctrl_list * ctrlist`` - *undescribed* - -**Description** - -Up to 2047 controller identifiers is returned containing a controller -identifier greater than or equal to the controller identifier specified in -**cntid**. - -See :c:type:`struct nvme_ctrl_list ` for a definition of the structure returned. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_identify_nsid_ctrl_list (int fd, __u32 nsid, __u16 cntid, struct nvme_ctrl_list * ctrlist) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Return controllers that are attached to this nsid - -``__u16 cntid`` - *undescribed* - -``struct nvme_ctrl_list * ctrlist`` - *undescribed* - -**Description** - -Up to 2047 controller identifiers is returned containing a controller -identifier greater than or equal to the controller identifier specified in -**cntid**. - -See :c:type:`struct nvme_ctrl_list ` for a definition of the structure returned. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 - - -.. c:function:: int nvme_identify_ns_descs (int fd, __u32 nsid, struct nvme_ns_id_desc * descs) - - Retrieves namespace descriptor list - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - The namespace id to retrieve destriptors - -``struct nvme_ns_id_desc * descs`` - User space destination address to transfer the data - -**Description** - -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'. - -See :c:type:`struct nvme_ns_id_desc ` for the definition of the returned structure. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_identify_nvmset_list (int fd, __u16 nvmsetid, struct nvme_id_nvmset_list * nvmset) - - Retrieves NVM Set List - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u16 nvmsetid`` - *undescribed* +``result`` + The command completion result from CQE dword0 -``struct nvme_id_nvmset_list * nvmset`` +``log`` User space destination address to transfer the data -**Description** - -Retrieves an NVM Set List, struct nvme_id_nvmset. The data structure is an -ordered list by NVM Set Identifier, starting with the first NVM Set -Identifier supported by the NVM subsystem that is equal to or greater than -the NVM Set Identifier. - -See :c:type:`struct nvme_id_nvmset_list ` for the defintion of the returned structure. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_identify_primary_ctrl (int fd, __u16 cntid, struct nvme_primary_ctrl_cap * cap) - - Retrieve NVMe Primary Controller identification :c:type:`fd`: - -**Parameters** - -``int fd`` - *undescribed* - -``__u16 cntid`` - *undescribed* - -``struct nvme_primary_ctrl_cap * cap`` - -**Description** - -See :c:type:`struct nvme_primary_ctrl_cap ` for the defintion of the returned structure, **cap**. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - +``args_size`` + Length of the structure -.. c:function:: int nvme_identify_secondary_ctrl_list (int fd, __u16 cntid, struct nvme_secondary_ctrl_list * list) - - Retrieves secondary controller list - -**Parameters** - -``int fd`` +``fd`` File descriptor of nvme device -``__u16 cntid`` - Return controllers starting at this identifier - -``struct nvme_secondary_ctrl_list * list`` - *undescribed* - -**Description** - -A Secondary Controller List is returned to the host for up to 127 secondary -controllers associated with the primary controller processing this command. -The list contains entries for controller identifiers greater than or equal -to the value specified in the Controller Identifier (cntid). - -See :c:type:`struct nvme_secondary_ctrls_list ` for a defintion of the returned -structure. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. +``timeout`` + Timeout in ms +``lid`` + Log page identifier, see :c:type:`enum nvme_cmd_get_log_lid ` for known + values -.. c:function:: int nvme_identify_ns_granularity (int fd, struct nvme_id_ns_granularity_list * list) +``len`` + Length of provided user buffer to hold the log data in bytes - Retrieves namespace granularity identification +``nsid`` + Namespace identifier, if applicable -**Parameters** +``csi`` + Command set identifier, see :c:type:`enum nvme_csi ` for known values -``int fd`` - File descriptor of nvme device +``lsi`` + Endurance group information -``struct nvme_id_ns_granularity_list * list`` - *undescribed* +``domid`` + Domain Identifier selection, if supported -**Description** +``lsp`` + Log specific field -If the controller supports reporting of Namespace Granularity, then a -Namespace Granularity List is returned to the host for up to sixteen -namespace granularity descriptors +``uuidx`` + UUID selection, if supported -See :c:type:`struct nvme_id_ns_granularity_list ` for the definition of the returned -structure. +``rae`` + Retain asynchronous events -**Return** +``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. -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_identify_uuid (int fd, struct nvme_id_uuid_list * list) +.. c:function:: int nvme_get_log (struct nvme_get_log_args *args) - Retrieves device's UUIDs + NVMe Admin Get Log command **Parameters** -``int fd`` - File descriptor of nvme device - -``struct nvme_id_uuid_list * list`` - *undescribed* - -**Description** - -Each UUID List entry is either 0h, the NVMe Invalid UUID, or a valid UUID. -Valid UUIDs are those which are non-zero and are not the NVMe Invalid UUID. - -See :c:type:`struct nvme_id_uuid_list ` for the definition of the returned structure. +``struct nvme_get_log_args *args`` + :c:type:`struct nvme_get_log_args ` argument structure **Return** @@ -1695,41 +1548,20 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_log (int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, __u8 lsp, __u16 lsi, bool rae, __u8 uuidx, __u32 len, void * log) +.. c:function:: int nvme_get_log_supported_log_pages (int fd, bool rae, struct nvme_supported_log_pages *log) - NVMe Admin Get Log command + Retrieve nmve supported log pages **Parameters** ``int fd`` File descriptor of nvme device -``enum nvme_cmd_get_log_lid lid`` - Log page identifier, see :c:type:`enum nvme_cmd_get_log_lid ` for known values - -``__u32 nsid`` - Namespace identifier, if applicable - -``__u64 lpo`` - Log page offset for partial log transfers - -``__u8 lsp`` - Log specific field - -``__u16 lsi`` - Endurance group information - ``bool rae`` Retain asynchronous events -``__u8 uuidx`` - UUID selection, if supported - -``__u32 len`` - Length of provided user buffer to hold the log data in bytes - -``void * log`` - User space destination address to transfer the data +``struct nvme_supported_log_pages *log`` + Array of LID supported and Effects data structures **Return** @@ -1737,7 +1569,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_log_error (int fd, unsigned nr_entries, bool rae, struct nvme_error_log_page * log) +.. c:function:: int nvme_get_log_error (int fd, unsigned nr_entries, bool rae, struct nvme_error_log_page *err_log) Retrieve nvme error log @@ -1747,18 +1579,18 @@ The nvme command status if a response was received (see File descriptor of nvme device ``unsigned nr_entries`` - *undescribed* + Number of error log entries allocated ``bool rae`` Retain asynchronous events -``struct nvme_error_log_page * log`` - *undescribed* +``struct nvme_error_log_page *err_log`` + Array of error logs of size 'entries' **Description** -This log page is used to describe extended error information for a command -that completed with error, or may report an error that is not specific to a +This log page describes extended error information for a command that +completed with error, or may report an error that is not specific to a particular command. **Return** @@ -1767,7 +1599,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_log_smart (int fd, __u32 nsid, bool rae, struct nvme_smart_log * log) +.. c:function:: int nvme_get_log_smart (int fd, __u32 nsid, bool rae, struct nvme_smart_log *smart_log) Retrieve nvme smart log @@ -1782,17 +1614,17 @@ The nvme command status if a response was received (see ``bool rae`` Retain asynchronous events -``struct nvme_smart_log * log`` - *undescribed* +``struct nvme_smart_log *smart_log`` + User address to store the smart log **Description** -This log page is used to provide SMART and general health information. The -information provided is over the life of the controller and is retained -across power cycles. To request the controller log page, the namespace -identifier specified is FFFFFFFFh. The controller may also support -requesting the log page on a per namespace basis, as indicated by bit 0 of -the LPA field in the Identify Controller data structure. +This log page provides SMART and general health information. The information +provided is over the life of the controller and is retained across power +cycles. To request the controller log page, the namespace identifier +specified is FFFFFFFFh. The controller may also support requesting the log +page on a per namespace basis, as indicated by bit 0 of the LPA field in the +Identify Controller data structure. **Return** @@ -1800,7 +1632,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_log_fw_slot (int fd, bool rae, struct nvme_firmware_slot * log) +.. c:function:: int nvme_get_log_fw_slot (int fd, bool rae, struct nvme_firmware_slot *fw_log) Retrieves the controller firmware log @@ -1812,14 +1644,14 @@ The nvme command status if a response was received (see ``bool rae`` Retain asynchronous events -``struct nvme_firmware_slot * log`` - *undescribed* +``struct nvme_firmware_slot *fw_log`` + User address to store the log page **Description** -This log page is used to describe the firmware revision stored in each -firmware slot supported. The firmware revision is indicated as an ASCII -string. The log page also indicates the active slot number. +This log page describes the firmware revision stored in each firmware slot +supported. The firmware revision is indicated as an ASCII string. The log +page also indicates the active slot number. **Return** @@ -1827,7 +1659,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_log_changed_ns_list (int fd, bool rae, struct nvme_ns_list * log) +.. c:function:: int nvme_get_log_changed_ns_list (int fd, bool rae, struct nvme_ns_list *ns_log) Retrieve namespace changed list @@ -1839,14 +1671,14 @@ The nvme command status if a response was received (see ``bool rae`` Retain asynchronous events -``struct nvme_ns_list * log`` - *undescribed* +``struct nvme_ns_list *ns_log`` + User address to store the log page **Description** -This log page is used to describe namespaces attached to this controller -that have changed since the last time the namespace was identified, been -added, or deleted. +This log page describes namespaces attached to this controller that have +changed since the last time the namespace was identified, been added, or +deleted. **Return** @@ -1854,7 +1686,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_log_cmd_effects (int fd, struct nvme_cmd_effects_log * log) +.. c:function:: int nvme_get_log_cmd_effects (int fd, enum nvme_csi csi, struct nvme_cmd_effects_log *effects_log) Retrieve nvme command effects log @@ -1863,13 +1695,16 @@ The nvme command status if a response was received (see ``int fd`` File descriptor of nvme device -``struct nvme_cmd_effects_log * log`` - *undescribed* +``enum nvme_csi csi`` + Command Set Identifier + +``struct nvme_cmd_effects_log *effects_log`` + User address to store the effects log **Description** -This log page is used to describe the commands that the controller supports -and the effects of those commands on the state of the NVM subsystem. +This log page describes the commands that the controller supports and the +effects of those commands on the state of the NVM subsystem. **Return** @@ -1877,7 +1712,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_log_device_self_test (int fd, struct nvme_self_test_log * log) +.. c:function:: int nvme_get_log_device_self_test (int fd, struct nvme_self_test_log *log) Retrieve the device self test log @@ -1886,13 +1721,13 @@ The nvme command status if a response was received (see ``int fd`` File descriptor of nvme device -``struct nvme_self_test_log * log`` +``struct nvme_self_test_log *log`` Userspace address of the log payload **Description** -The log page is used to indicate the status of an in progress self test and -the percent complete of that operation, and the results of the previous 20 +The log page indicates the status of an in progress self test and the +percent complete of that operation, and the results of the previous 20 self-test operations. **Return** @@ -1901,19 +1736,20 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_log_create_telemetry_host (int fd, struct nvme_telemetry_log * log) +.. c:function:: int nvme_get_log_create_telemetry_host (int fd, struct nvme_telemetry_log *log) + Create host telemetry log **Parameters** ``int fd`` - *undescribed* + File descriptor of nvme device -``struct nvme_telemetry_log * log`` - *undescribed* +``struct nvme_telemetry_log *log`` + Userspace address of the log payload -.. c:function:: int nvme_get_log_telemetry_host (int fd, __u64 offset, __u32 len, void * log) +.. c:function:: int nvme_get_log_telemetry_host (int fd, __u64 offset, __u32 len, void *log) **Parameters** @@ -1927,7 +1763,7 @@ The nvme command status if a response was received (see ``__u32 len`` Length of provided user buffer to hold the log data in bytes -``void * log`` +``void *log`` User address for log page data **Description** @@ -1941,7 +1777,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_log_telemetry_ctrl (int fd, bool rae, __u64 offset, __u32 len, void * log) +.. c:function:: int nvme_get_log_telemetry_ctrl (int fd, bool rae, __u64 offset, __u32 len, void *log) **Parameters** @@ -1958,11 +1794,11 @@ The nvme command status if a response was received (see ``__u32 len`` Length of provided user buffer to hold the log data in bytes -``void * log`` +``void *log`` User address for log page data -.. c:function:: int nvme_get_log_endurance_group (int fd, __u16 endgid, struct nvme_endurance_group_log * log) +.. c:function:: int nvme_get_log_endurance_group (int fd, __u16 endgid, struct nvme_endurance_group_log *log) **Parameters** @@ -1973,7 +1809,7 @@ The nvme command status if a response was received (see ``__u16 endgid`` Starting group identifier to return in the list -``struct nvme_endurance_group_log * log`` +``struct nvme_endurance_group_log *log`` User address to store the endurance log **Description** @@ -1991,18 +1827,19 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_log_predictable_lat_nvmset (int fd, __u16 nvmsetid, struct nvme_nvmset_predictable_lat_log * log) +.. c:function:: int nvme_get_log_predictable_lat_nvmset (int fd, __u16 nvmsetid, struct nvme_nvmset_predictable_lat_log *log) **Parameters** ``int fd`` - *undescribed* + File descriptor of nvme device ``__u16 nvmsetid`` + NVM set id -``struct nvme_nvmset_predictable_lat_log * log`` - *undescribed* +``struct nvme_nvmset_predictable_lat_log *log`` + User address to store the predictable latency log **Return** @@ -2010,7 +1847,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_log_predictable_lat_event (int fd, bool rae, __u32 offset, __u32 len, void * log) +.. c:function:: int nvme_get_log_predictable_lat_event (int fd, bool rae, __u32 offset, __u32 len, void *log) **Parameters** @@ -2022,30 +1859,13 @@ The nvme command status if a response was received (see Retain asynchronous events ``__u32 offset`` - *undescribed* ``__u32 len`` - *undescribed* - -``void * log`` - *undescribed* - +``void *log`` -.. c:type:: enum nvme_log_ana_lsp - - -**Constants** - -``NVME_LOG_ANA_LSP_RGO_NAMESPACES`` - *undescribed* - -``NVME_LOG_ANA_LSP_RGO_GROUPS_ONLY`` - *undescribed* - - -.. c:function:: int nvme_get_log_ana (int fd, enum nvme_log_ana_lsp lsp, bool rae, __u64 offset, __u32 len, void * log) +.. c:function:: int nvme_get_log_ana (int fd, enum nvme_log_ana_lsp lsp, bool rae, __u64 offset, __u32 len, void *log) **Parameters** @@ -2060,12 +1880,12 @@ The nvme command status if a response was received (see Retain asynchronous events ``__u64 offset`` - *undescribed* + Offset to the start of the log page ``__u32 len`` The allocated length of the log page -``void * log`` +``void *log`` User address to store the ana log **Description** @@ -2082,7 +1902,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_log_ana_groups (int fd, bool rae, __u32 len, struct nvme_ana_group_desc * log) +.. c:function:: int nvme_get_log_ana_groups (int fd, bool rae, __u32 len, struct nvme_ana_group_desc *log) **Parameters** @@ -2094,17 +1914,17 @@ The nvme command status if a response was received (see Retain asynchronous events ``__u32 len`` - *undescribed* + The allocated length of the log page -``struct nvme_ana_group_desc * log`` - *undescribed* +``struct nvme_ana_group_desc *log`` + User address to store the ana group log **Description** See :c:type:`struct nvme_ana_group_desc ` for the defintion of the returned structure. -.. c:function:: int nvme_get_log_lba_status (int fd, bool rae, __u64 offset, __u32 len, void * log) +.. c:function:: int nvme_get_log_lba_status (int fd, bool rae, __u64 offset, __u32 len, void *log) **Parameters** @@ -2116,16 +1936,16 @@ See :c:type:`struct nvme_ana_group_desc ` for the defintion Retain asynchronous events ``__u64 offset`` - *undescribed* + Offset to the start of the log page ``__u32 len`` - *undescribed* + The allocated length of the log page -``void * log`` - *undescribed* +``void *log`` + User address to store the log page -.. c:function:: int nvme_get_log_endurance_grp_evt (int fd, bool rae, __u32 offset, __u32 len, void * log) +.. c:function:: int nvme_get_log_endurance_grp_evt (int fd, bool rae, __u32 offset, __u32 len, void *log) **Parameters** @@ -2137,16 +1957,16 @@ See :c:type:`struct nvme_ana_group_desc ` for the defintion Retain asynchronous events ``__u32 offset`` - *undescribed* + Offset to the start of the log page ``__u32 len`` - *undescribed* + The allocated length of the log page -``void * log`` - *undescribed* +``void *log`` + User address to store the log page -.. c:function:: int nvme_get_log_discovery (int fd, bool rae, __u32 offset, __u32 len, void * log) +.. c:function:: int nvme_get_log_fid_supported_effects (int fd, bool rae, struct nvme_fid_supported_effects_log *log) **Parameters** @@ -2157,27 +1977,16 @@ See :c:type:`struct nvme_ana_group_desc ` for the defintion ``bool rae`` Retain asynchronous events -``__u32 offset`` - Offset of this log to retrieve - -``__u32 len`` - The allocated size for this portion of the log - -``void * log`` - User address to store the discovery log - -**Description** - -Supported only by fabrics discovery controllers, returning discovery -records. +``struct nvme_fid_supported_effects_log *log`` + FID Supported and Effects data structure **Return** The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise -.. c:function:: int nvme_get_log_reservation (int fd, bool rae, struct nvme_resv_notification_log * log) +.. c:function:: int nvme_get_log_boot_partition (int fd, bool rae, __u8 lsp, __u32 len, struct nvme_boot_partition *part) **Parameters** @@ -2188,11 +1997,23 @@ The nvme command status if a response was received (see ``bool rae`` Retain asynchronous events -``struct nvme_resv_notification_log * log`` - *undescribed* +``__u8 lsp`` + The log specified field of LID + +``__u32 len`` + The allocated size, minimum + struct nvme_boot_partition + +``struct nvme_boot_partition *part`` + User address to store the log page + +**Return** + +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise -.. c:function:: int nvme_get_log_sanitize (int fd, bool rae, struct nvme_sanitize_log_page * log) +.. c:function:: int nvme_get_log_discovery (int fd, bool rae, __u32 offset, __u32 len, void *log) **Parameters** @@ -2203,13 +2024,19 @@ The nvme command status if a response was received (see ``bool rae`` Retain asynchronous events -``struct nvme_sanitize_log_page * log`` - User address to store the sanitize log +``__u32 offset`` + Offset of this log to retrieve + +``__u32 len`` + The allocated size for this portion of the log + +``void *log`` + User address to store the discovery log **Description** -The Sanitize Status log page is used to report sanitize operation time -estimates and information about the most recent sanitize operation. +Supported only by fabrics discovery controllers, returning discovery +records. **Return** @@ -2217,52 +2044,252 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_set_features (int fd, __u8 fid, __u32 nsid, __u32 cdw11, __u32 cdw12, bool save, __u8 uuidx, __u32 cdw15, __u32 data_len, void * data, __u32 * result) +.. c:function:: int nvme_get_log_media_unit_stat (int fd, __u16 domid, struct nvme_media_unit_stat_log *mus) - Set a feature attribute **Parameters** ``int fd`` File descriptor of nvme device -``__u8 fid`` - Feature identifier +``__u16 domid`` + Domain Identifier selection, if supported -``__u32 nsid`` +``struct nvme_media_unit_stat_log *mus`` + User address to store the Media Unit statistics log + +**Return** + +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise + + +.. c:function:: int nvme_get_log_reservation (int fd, bool rae, struct nvme_resv_notification_log *log) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``bool rae`` + Retain asynchronous events + +``struct nvme_resv_notification_log *log`` + User address to store the reservation log + + +.. c:function:: int nvme_get_log_sanitize (int fd, bool rae, struct nvme_sanitize_log_page *log) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``bool rae`` + Retain asynchronous events + +``struct nvme_sanitize_log_page *log`` + User address to store the sanitize log + +**Description** + +The Sanitize Status log page reports sanitize operation time estimates and +information about the most recent sanitize operation. + +**Return** + +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. + + +.. c:function:: int nvme_get_log_zns_changed_zones (int fd, __u32 nsid, bool rae, struct nvme_zns_changed_zone_log *log) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u32 nsid`` + Namespace ID + +``bool rae`` + Retain asynchronous events + +``struct nvme_zns_changed_zone_log *log`` + User address to store the changed zone log + +**Description** + +The list of zones that have changed state due to an exceptional event. + +**Return** + +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. + + +.. c:function:: int nvme_get_log_persistent_event (int fd, enum nvme_pevent_log_action action, __u32 size, void *pevent_log) + + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_pevent_log_action action`` + Action the controller should take during processing this command + +``__u32 size`` + Size of **pevent_log** + +``void *pevent_log`` + User address to store the persistent event log + + + + +.. c:type:: struct nvme_set_features_args + + Arguments for the NVMe Admin Set Feature command + +**Definition** + +:: + + struct nvme_set_features_args { + __u32 *result; + void *data; + int args_size; + int fd; + __u32 timeout; + __u32 nsid; + __u32 cdw11; + __u32 cdw12; + __u32 cdw15; + __u32 data_len; + bool save; + __u8 uuidx; + __u8 fid; + }; + +**Members** + +``result`` + The command completion result from CQE dword0 + +``data`` + User address of feature data, if applicable + +``args_size`` + Size of :c:type:`struct nvme_set_features_args ` + +``fd`` + File descriptor of nvme device + +``timeout`` + Timeout in ms + +``nsid`` Namespace ID, if applicable -``__u32 cdw11`` +``cdw11`` Value to set the feature to -``__u32 cdw12`` +``cdw12`` Feature specific command dword12 field -``bool save`` +``cdw15`` + Feature specific command dword15 field + +``data_len`` + Length of feature data, if applicable, in bytes + +``save`` Save value across power states -``__u8 uuidx`` +``uuidx`` UUID Index for differentiating vendor specific encoding -``__u32 cdw15`` - *undescribed* +``fid`` + Feature identifier + + + +.. c:function:: int nvme_set_features (struct nvme_set_features_args *args) + + Set a feature attribute + +**Parameters** + +``struct nvme_set_features_args *args`` + :c:type:`struct nvme_set_features_args ` argument structure + +**Return** + +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. + + +.. c:function:: int nvme_set_features_data (int fd, __u8 fid, __u32 nsid, __u32 cdw11, bool save, __u32 data_len, void *data, __u32 *result) + + Helper function for **nvme_set_features\(\)** + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u8 fid`` + Feature identifier + +``__u32 nsid`` + Namespace ID, if applicable + +``__u32 cdw11`` + Value to set the feature to + +``bool save`` + Save value across power states ``__u32 data_len`` Length of feature data, if applicable, in bytes -``void * data`` +``void *data`` User address of feature data, if applicable -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 -**Return** -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. +.. c:function:: int nvme_set_features_simple (int fd, __u8 fid, __u32 nsid, __u32 cdw11, bool save, __u32 *result) + + Helper functionn for **nvme_set_features\(\)** + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``__u8 fid`` + Feature identifier + +``__u32 nsid`` + Namespace ID, if applicable + +``__u32 cdw11`` + Value to set the feature to + +``bool save`` + Save value across power states + +``__u32 *result`` + The command completion result from CQE dword0 -.. c:function:: int nvme_set_features_arbitration (int fd, __u8 ab, __u8 lpw, __u8 mpw, __u8 hpw, bool save, __u32 * result) +.. c:function:: int nvme_set_features_arbitration (int fd, __u8 ab, __u8 lpw, __u8 mpw, __u8 hpw, bool save, __u32 *result) **Parameters** @@ -2271,21 +2298,17 @@ The nvme command status if a response was received (see File descriptor of nvme device ``__u8 ab`` - *undescribed* ``__u8 lpw`` - *undescribed* ``__u8 mpw`` - *undescribed* ``__u8 hpw`` - *undescribed* ``bool save`` Save value across power states -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -2294,7 +2317,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_power_mgmt (int fd, __u8 ps, __u8 wh, bool save, __u32 * result) +.. c:function:: int nvme_set_features_power_mgmt (int fd, __u8 ps, __u8 wh, bool save, __u32 *result) **Parameters** @@ -2303,15 +2326,13 @@ The nvme command status if a response was received (see File descriptor of nvme device ``__u8 ps`` - *undescribed* ``__u8 wh`` - *undescribed* ``bool save`` Save value across power states -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -2320,7 +2341,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_lba_range (int fd, __u32 nsid, __u32 nr_ranges, bool save, struct nvme_lba_range_type * data, __u32 * result) +.. c:function:: int nvme_set_features_lba_range (int fd, __u32 nsid, __u32 nr_ranges, bool save, struct nvme_lba_range_type *data, __u32 *result) **Parameters** @@ -2329,18 +2350,18 @@ The nvme command status if a response was received (see File descriptor of nvme device ``__u32 nsid`` - *undescribed* + Namespace ID ``__u32 nr_ranges`` - *undescribed* + Number of ranges in **data** ``bool save`` Save value across power states -``struct nvme_lba_range_type * data`` - *undescribed* +``struct nvme_lba_range_type *data`` + User address of feature data -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -2349,21 +2370,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:type:: enum nvme_feat_tmpthresh_thsel - - -**Constants** - -``NVME_FEATURE_TEMPTHRESH_THSEL_OVER`` - *undescribed* - -``NVME_FEATURETEMPTHRESH__THSEL_UNDER`` - *undescribed* - - -.. c:function:: int nvme_set_features_temp_thresh (int fd, __u16 tmpth, __u8 tmpsel, enum nvme_feat_tmpthresh_thsel thsel, bool save, __u32 * result) +.. c:function:: int nvme_set_features_temp_thresh (int fd, __u16 tmpth, __u8 tmpsel, enum nvme_feat_tmpthresh_thsel thsel, bool save, __u32 *result) **Parameters** @@ -2372,18 +2379,15 @@ The nvme command status if a response was received (see File descriptor of nvme device ``__u16 tmpth`` - *undescribed* ``__u8 tmpsel`` - *undescribed* ``enum nvme_feat_tmpthresh_thsel thsel`` - *undescribed* ``bool save`` Save value across power states -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -2392,7 +2396,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_err_recovery (int fd, __u32 nsid, __u16 tler, bool dulbe, bool save, __u32 * result) +.. c:function:: int nvme_set_features_err_recovery (int fd, __u32 nsid, __u16 tler, bool dulbe, bool save, __u32 *result) **Parameters** @@ -2401,18 +2405,17 @@ The nvme command status if a response was received (see File descriptor of nvme device ``__u32 nsid`` - *undescribed* + Namespace ID ``__u16 tler`` - *undescribed* + Time-limited error recovery value ``bool dulbe`` - *undescribed* ``bool save`` Save value across power states -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -2421,7 +2424,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_volatile_wc (int fd, bool wce, bool save, __u32 * result) +.. c:function:: int nvme_set_features_volatile_wc (int fd, bool wce, bool save, __u32 *result) **Parameters** @@ -2430,12 +2433,12 @@ The nvme command status if a response was received (see File descriptor of nvme device ``bool wce`` - *undescribed* + Write cache enable ``bool save`` Save value across power states -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -2444,7 +2447,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_irq_coalesce (int fd, __u8 thr, __u8 time, bool save, __u32 * result) +.. c:function:: int nvme_set_features_irq_coalesce (int fd, __u8 thr, __u8 time, bool save, __u32 *result) **Parameters** @@ -2453,15 +2456,13 @@ The nvme command status if a response was received (see File descriptor of nvme device ``__u8 thr`` - *undescribed* ``__u8 time`` - *undescribed* ``bool save`` Save value across power states -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -2470,7 +2471,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_irq_config (int fd, __u16 iv, bool cd, bool save, __u32 * result) +.. c:function:: int nvme_set_features_irq_config (int fd, __u16 iv, bool cd, bool save, __u32 *result) **Parameters** @@ -2479,15 +2480,13 @@ The nvme command status if a response was received (see File descriptor of nvme device ``__u16 iv`` - *undescribed* ``bool cd`` - *undescribed* ``bool save`` Save value across power states -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -2496,7 +2495,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_write_atomic (int fd, bool dn, bool save, __u32 * result) +.. c:function:: int nvme_set_features_write_atomic (int fd, bool dn, bool save, __u32 *result) **Parameters** @@ -2505,12 +2504,11 @@ The nvme command status if a response was received (see File descriptor of nvme device ``bool dn`` - *undescribed* ``bool save`` Save value across power states -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -2519,57 +2517,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:type:: enum nvme_features_async_event_config_flags - - -**Constants** - -``NVME_FEATURE_AENCFG_SMART_CRIT_SPARE`` - *undescribed* - -``NVME_FEATURE_AENCFG_SMART_CRIT_TEMPERATURE`` - *undescribed* - -``NVME_FEATURE_AENCFG_SMART_CRIT_DEGRADED`` - *undescribed* - -``NVME_FEATURE_AENCFG_SMART_CRIT_READ_ONLY`` - *undescribed* - -``NVME_FEATURE_AENCFG_SMART_CRIT_VOLATILE_BACKUP`` - *undescribed* - -``NVME_FEATURE_AENCFG_SMART_CRIT_READ_ONLY_PMR`` - *undescribed* - -``NVME_FEATURE_AENCFG_NOTICE_NAMESPACE_ATTRIBUTES`` - *undescribed* - -``NVME_FEATURE_AENCFG_NOTICE_FIRMWARE_ACTIVATION`` - *undescribed* - -``NVME_FEATURE_AENCFG_NOTICE_TELEMETRY_LOG`` - *undescribed* - -``NVME_FEATURE_AENCFG_NOTICE_ANA_CHANGE`` - *undescribed* - -``NVME_FEATURE_AENCFG_NOTICE_PL_EVENT`` - *undescribed* - -``NVME_FEATURE_AENCFG_NOTICE_LBA_STATUS`` - *undescribed* - -``NVME_FEATURE_AENCFG_NOTICE_EG_EVENT`` - *undescribed* - -``NVME_FEATURE_AENCFG_NOTICE_DISCOVERY_CHANGE`` - *undescribed* - - -.. c:function:: int nvme_set_features_async_event (int fd, __u32 events, bool save, __u32 * result) +.. c:function:: int nvme_set_features_async_event (int fd, __u32 events, bool save, __u32 *result) **Parameters** @@ -2578,12 +2526,12 @@ The nvme command status if a response was received (see File descriptor of nvme device ``__u32 events`` - *undescribed* + Events to enable ``bool save`` Save value across power states -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -2592,7 +2540,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_auto_pst (int fd, bool apste, bool save, struct nvme_feat_auto_pst * apst, __u32 * result) +.. c:function:: int nvme_set_features_auto_pst (int fd, bool apste, bool save, struct nvme_feat_auto_pst *apst, __u32 *result) **Parameters** @@ -2601,15 +2549,13 @@ The nvme command status if a response was received (see File descriptor of nvme device ``bool apste`` - *undescribed* ``bool save`` Save value across power states -``struct nvme_feat_auto_pst * apst`` - *undescribed* +``struct nvme_feat_auto_pst *apst`` -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -2638,7 +2584,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_hctm (int fd, __u16 tmt2, __u16 tmt1, bool save, __u32 * result) +.. c:function:: int nvme_set_features_hctm (int fd, __u16 tmt2, __u16 tmt1, bool save, __u32 *result) **Parameters** @@ -2647,15 +2593,13 @@ The nvme command status if a response was received (see File descriptor of nvme device ``__u16 tmt2`` - *undescribed* ``__u16 tmt1`` - *undescribed* ``bool save`` Save value across power states -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -2664,25 +2608,29 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_nopsc (int fd, bool noppme, bool save, __u32 * result) +.. c:function:: int nvme_set_features_nopsc (int fd, bool noppme, bool save, __u32 *result) **Parameters** ``int fd`` - *undescribed* + File descriptor of nvme device ``bool noppme`` - *undescribed* ``bool save`` - *undescribed* + Save value across power states + +``__u32 *result`` + The command completion result from CQE dword0 + +**Return** -``__u32 * result`` - *undescribed* +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_rrl (int fd, __u8 rrl, __u16 nvmsetid, bool save, __u32 * result) +.. c:function:: int nvme_set_features_rrl (int fd, __u8 rrl, __u16 nvmsetid, bool save, __u32 *result) **Parameters** @@ -2691,15 +2639,15 @@ The nvme command status if a response was received (see File descriptor of nvme device ``__u8 rrl`` - *undescribed* + Read recovery level setting ``__u16 nvmsetid`` - *undescribed* + NVM set id ``bool save`` Save value across power states -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -2708,7 +2656,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_plm_config (int fd, bool enable, __u16 nvmsetid, bool save, struct nvme_plm_config * data, __u32 * result) +.. c:function:: int nvme_set_features_plm_config (int fd, bool enable, __u16 nvmsetid, bool save, struct nvme_plm_config *data, __u32*result) **Parameters** @@ -2717,18 +2665,15 @@ The nvme command status if a response was received (see File descriptor of nvme device ``bool enable`` - *undescribed* ``__u16 nvmsetid`` - *undescribed* ``bool save`` Save value across power states -``struct nvme_plm_config * data`` - *undescribed* +``struct nvme_plm_config *data`` -``__u32 * result`` +``__u32*result`` The command completion result from CQE dword0 **Return** @@ -2737,21 +2682,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:type:: enum nvme_feat_plm_window_select - - -**Constants** - -``NVME_FEATURE_PLM_DTWIN`` - *undescribed* - -``NVME_FEATURE_PLM_NDWIN`` - *undescribed* - - -.. c:function:: int nvme_set_features_plm_window (int fd, enum nvme_feat_plm_window_select sel, __u16 nvmsetid, bool save, __u32 * result) +.. c:function:: int nvme_set_features_plm_window (int fd, enum nvme_feat_plm_window_select sel, __u16 nvmsetid, bool save, __u32 *result) **Parameters** @@ -2760,15 +2691,13 @@ The nvme command status if a response was received (see File descriptor of nvme device ``enum nvme_feat_plm_window_select sel`` - *undescribed* ``__u16 nvmsetid`` - *undescribed* ``bool save`` Save value across power states -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -2777,7 +2706,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_lba_sts_interval (int fd, __u16 lsiri, __u16 lsipi, bool save, __u32 * result) +.. c:function:: int nvme_set_features_lba_sts_interval (int fd, __u16 lsiri, __u16 lsipi, bool save, __u32 *result) **Parameters** @@ -2786,15 +2715,13 @@ The nvme command status if a response was received (see File descriptor of nvme device ``__u16 lsiri`` - *undescribed* ``__u16 lsipi`` - *undescribed* ``bool save`` Save value across power states -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -2803,7 +2730,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_host_behavior (int fd, bool save, struct nvme_feat_host_behavior * data) +.. c:function:: int nvme_set_features_host_behavior (int fd, bool save, struct nvme_feat_host_behavior *data) **Parameters** @@ -2814,8 +2741,7 @@ The nvme command status if a response was received (see ``bool save`` Save value across power states -``struct nvme_feat_host_behavior * data`` - *undescribed* +``struct nvme_feat_host_behavior *data`` **Return** @@ -2823,7 +2749,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_sanitize (int fd, bool nodrm, bool save, __u32 * result) +.. c:function:: int nvme_set_features_sanitize (int fd, bool nodrm, bool save, __u32 *result) **Parameters** @@ -2832,12 +2758,11 @@ The nvme command status if a response was received (see File descriptor of nvme device ``bool nodrm`` - *undescribed* ``bool save`` Save value across power states -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -2846,7 +2771,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_endurance_evt_cfg (int fd, __u16 endgid, __u8 egwarn, bool save, __u32 * result) +.. c:function:: int nvme_set_features_endurance_evt_cfg (int fd, __u16 endgid, __u8 egwarn, bool save, __u32 *result) **Parameters** @@ -2855,7 +2780,6 @@ The nvme command status if a response was received (see File descriptor of nvme device ``__u16 endgid`` - *undescribed* ``__u8 egwarn`` Flags to enable warning, see :c:type:`enum nvme_eg_critical_warning_flags ` @@ -2863,7 +2787,7 @@ The nvme command status if a response was received (see ``bool save`` Save value across power states -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -2872,7 +2796,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_sw_progress (int fd, __u8 pbslc, bool save, __u32 * result) +.. c:function:: int nvme_set_features_sw_progress (int fd, __u8 pbslc, bool save, __u32 *result) **Parameters** @@ -2881,12 +2805,11 @@ The nvme command status if a response was received (see File descriptor of nvme device ``__u8 pbslc`` - *undescribed* ``bool save`` Save value across power states -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -2895,7 +2818,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_host_id (int fd, bool exhid, bool save, __u8 * hostid) +.. c:function:: int nvme_set_features_host_id (int fd, bool exhid, bool save, __u8 *hostid) **Parameters** @@ -2904,13 +2827,12 @@ The nvme command status if a response was received (see File descriptor of nvme device ``bool exhid`` - *undescribed* ``bool save`` Save value across power states -``__u8 * hostid`` - *undescribed* +``__u8 *hostid`` + Host ID to set **Return** @@ -2918,7 +2840,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_resv_mask (int fd, __u32 mask, bool save, __u32 * result) +.. c:function:: int nvme_set_features_resv_mask (int fd, __u32 mask, bool save, __u32 *result) **Parameters** @@ -2927,12 +2849,11 @@ The nvme command status if a response was received (see File descriptor of nvme device ``__u32 mask`` - *undescribed* ``bool save`` Save value across power states -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -2941,7 +2862,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_set_features_resv_persist (int fd, bool ptpl, bool save, __u32 * result) +.. c:function:: int nvme_set_features_resv_persist (int fd, bool ptpl, bool save, __u32 *result) **Parameters** @@ -2950,12 +2871,11 @@ The nvme command status if a response was received (see File descriptor of nvme device ``bool ptpl`` - *undescribed* ``bool save`` Save value across power states -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -2964,27 +2884,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:type:: enum nvme_feat_nswpcfg_state - - -**Constants** - -``NVME_FEAT_NS_NO_WRITE_PROTECT`` - *undescribed* - -``NVME_FEAT_NS_WRITE_PROTECT`` - *undescribed* - -``NVME_FEAT_NS_WRITE_PROTECT_PWR_CYCLE`` - *undescribed* - -``NVME_FEAT_NS_WRITE_PROTECT_PERMANENT`` - *undescribed* - - -.. c:function:: int nvme_set_features_write_protect (int fd, enum nvme_feat_nswpcfg_state state, bool save, __u32 * result) +.. c:function:: int nvme_set_features_write_protect (int fd, enum nvme_feat_nswpcfg_state state, bool save, __u32 *result) **Parameters** @@ -2993,12 +2893,11 @@ The nvme command status if a response was received (see File descriptor of nvme device ``enum nvme_feat_nswpcfg_state state`` - *undescribed* ``bool save`` Save value across power states -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -3007,46 +2906,128 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_features (int fd, enum nvme_features_id fid, __u32 nsid, enum nvme_get_features_sel sel, __u32 cdw11, __u8 uuidx, __u32 data_len, void * data, __u32 * result) - Retrieve a feature attribute -**Parameters** +.. c:type:: struct nvme_get_features_args -``int fd`` + Arguments for the NVMe Admin Get Feature command + +**Definition** + +:: + + 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; + }; + +**Members** + +``result`` + The command completion result from CQE dword0 + +``data`` + User address of feature data, if applicable + +``args_size`` + Size of :c:type:`struct nvme_get_features_args ` + +``fd`` File descriptor of nvme device -``enum nvme_features_id fid`` - Feature identifier, see :c:type:`enum nvme_features_id ` +``timeout`` + Timeout in ms -``__u32 nsid`` +``nsid`` Namespace ID, if applicable -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` +``sel`` + Select which type of attribute to return, + see :c:type:`enum nvme_get_features_sel ` -``__u32 cdw11`` +``cdw11`` Feature specific command dword11 field -``__u8 uuidx`` +``data_len`` + Length of feature data, if applicable, in bytes + +``fid`` + Feature identifier, see :c:type:`enum nvme_features_id ` + +``uuidx`` UUID Index for differentiating vendor specific encoding + + +.. c:function:: int nvme_get_features (struct nvme_get_features_args *args) + + Retrieve a feature attribute + +**Parameters** + +``struct nvme_get_features_args *args`` + :c:type:`struct nvme_get_features_args ` argument structure + +**Return** + +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. + + +.. c:function:: int nvme_get_features_data (int fd, enum nvme_features_id fid, __u32 nsid, __u32 data_len, void *data, __u32 *result) + + Helper function for **nvme_get_features\(\)** + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_features_id fid`` + Feature identifier + +``__u32 nsid`` + Namespace ID, if applicable + ``__u32 data_len`` Length of feature data, if applicable, in bytes -``void * data`` +``void *data`` User address of feature data, if applicable -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 -**Return** -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. +.. c:function:: int nvme_get_features_simple (int fd, enum nvme_features_id fid, __u32 nsid, __u32 *result) + + Helper function for **nvme_get_features\(\)** + +**Parameters** + +``int fd`` + File descriptor of nvme device + +``enum nvme_features_id fid`` + Feature identifier + +``__u32 nsid`` + Namespace ID, if applicable + +``__u32 *result`` + The command completion result from CQE dword0 -.. c:function:: int nvme_get_features_arbitration (int fd, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_get_features_arbitration (int fd, enum nvme_get_features_sel sel, __u32 *result) **Parameters** @@ -3057,7 +3038,7 @@ The nvme command status if a response was received (see ``enum nvme_get_features_sel sel`` Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -3066,7 +3047,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_power_mgmt (int fd, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_get_features_power_mgmt (int fd, enum nvme_get_features_sel sel, __u32 *result) **Parameters** @@ -3077,7 +3058,7 @@ The nvme command status if a response was received (see ``enum nvme_get_features_sel sel`` Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -3086,7 +3067,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_lba_range (int fd, enum nvme_get_features_sel sel, struct nvme_lba_range_type * data, __u32 * result) +.. c:function:: int nvme_get_features_lba_range (int fd, enum nvme_get_features_sel sel, struct nvme_lba_range_type *data, __u32 *result) **Parameters** @@ -3097,10 +3078,10 @@ The nvme command status if a response was received (see ``enum nvme_get_features_sel sel`` Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``struct nvme_lba_range_type * data`` - *undescribed* +``struct nvme_lba_range_type *data`` + User address of feature data, if applicable -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -3109,7 +3090,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_temp_thresh (int fd, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_get_features_temp_thresh (int fd, enum nvme_get_features_sel sel, __u32 *result) **Parameters** @@ -3120,7 +3101,7 @@ The nvme command status if a response was received (see ``enum nvme_get_features_sel sel`` Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -3129,7 +3110,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_err_recovery (int fd, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_get_features_err_recovery (int fd, enum nvme_get_features_sel sel, __u32 *result) **Parameters** @@ -3140,7 +3121,7 @@ The nvme command status if a response was received (see ``enum nvme_get_features_sel sel`` Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -3149,7 +3130,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_volatile_wc (int fd, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_get_features_volatile_wc (int fd, enum nvme_get_features_sel sel, __u32 *result) **Parameters** @@ -3160,7 +3141,7 @@ The nvme command status if a response was received (see ``enum nvme_get_features_sel sel`` Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -3169,7 +3150,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_num_queues (int fd, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_get_features_num_queues (int fd, enum nvme_get_features_sel sel, __u32 *result) **Parameters** @@ -3180,7 +3161,7 @@ The nvme command status if a response was received (see ``enum nvme_get_features_sel sel`` Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -3189,7 +3170,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_irq_coalesce (int fd, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_get_features_irq_coalesce (int fd, enum nvme_get_features_sel sel, __u32 *result) **Parameters** @@ -3200,7 +3181,7 @@ The nvme command status if a response was received (see ``enum nvme_get_features_sel sel`` Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -3209,7 +3190,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_irq_config (int fd, enum nvme_get_features_sel sel, __u16 iv, __u32 * result) +.. c:function:: int nvme_get_features_irq_config (int fd, enum nvme_get_features_sel sel, __u16 iv, __u32 *result) **Parameters** @@ -3221,9 +3202,8 @@ The nvme command status if a response was received (see Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` ``__u16 iv`` - *undescribed* -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -3232,7 +3212,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_write_atomic (int fd, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_get_features_write_atomic (int fd, enum nvme_get_features_sel sel, __u32 *result) **Parameters** @@ -3243,7 +3223,7 @@ The nvme command status if a response was received (see ``enum nvme_get_features_sel sel`` Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -3252,7 +3232,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_async_event (int fd, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_get_features_async_event (int fd, enum nvme_get_features_sel sel, __u32 *result) **Parameters** @@ -3263,7 +3243,7 @@ The nvme command status if a response was received (see ``enum nvme_get_features_sel sel`` Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -3272,7 +3252,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_auto_pst (int fd, enum nvme_get_features_sel sel, struct nvme_feat_auto_pst * apst, __u32 * result) +.. c:function:: int nvme_get_features_auto_pst (int fd, enum nvme_get_features_sel sel, struct nvme_feat_auto_pst *apst, __u32 *result) **Parameters** @@ -3283,10 +3263,9 @@ The nvme command status if a response was received (see ``enum nvme_get_features_sel sel`` Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``struct nvme_feat_auto_pst * apst`` - *undescribed* +``struct nvme_feat_auto_pst *apst`` -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -3295,7 +3274,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_host_mem_buf (int fd, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_get_features_host_mem_buf (int fd, enum nvme_get_features_sel sel, __u32 *result) **Parameters** @@ -3306,7 +3285,7 @@ The nvme command status if a response was received (see ``enum nvme_get_features_sel sel`` Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -3315,7 +3294,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_timestamp (int fd, enum nvme_get_features_sel sel, struct nvme_timestamp * ts) +.. c:function:: int nvme_get_features_timestamp (int fd, enum nvme_get_features_sel sel, struct nvme_timestamp *ts) **Parameters** @@ -3326,8 +3305,8 @@ The nvme command status if a response was received (see ``enum nvme_get_features_sel sel`` Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``struct nvme_timestamp * ts`` - *undescribed* +``struct nvme_timestamp *ts`` + Current timestamp **Return** @@ -3335,7 +3314,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_kato (int fd, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_get_features_kato (int fd, enum nvme_get_features_sel sel, __u32 *result) **Parameters** @@ -3346,7 +3325,7 @@ The nvme command status if a response was received (see ``enum nvme_get_features_sel sel`` Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -3355,7 +3334,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_hctm (int fd, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_get_features_hctm (int fd, enum nvme_get_features_sel sel, __u32 *result) **Parameters** @@ -3366,7 +3345,7 @@ The nvme command status if a response was received (see ``enum nvme_get_features_sel sel`` Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -3375,7 +3354,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_nopsc (int fd, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_get_features_nopsc (int fd, enum nvme_get_features_sel sel, __u32 *result) **Parameters** @@ -3386,7 +3365,7 @@ The nvme command status if a response was received (see ``enum nvme_get_features_sel sel`` Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -3395,7 +3374,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_rrl (int fd, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_get_features_rrl (int fd, enum nvme_get_features_sel sel, __u32 *result) **Parameters** @@ -3406,7 +3385,7 @@ The nvme command status if a response was received (see ``enum nvme_get_features_sel sel`` Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -3415,7 +3394,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_plm_config (int fd, enum nvme_get_features_sel sel, __u16 nvmsetid, struct nvme_plm_config * data, __u32 * result) +.. c:function:: int nvme_get_features_plm_config (int fd, enum nvme_get_features_sel sel, __u16 nvmsetid, struct nvme_plm_config *data, __u32 *result) **Parameters** @@ -3427,12 +3406,11 @@ The nvme command status if a response was received (see Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` ``__u16 nvmsetid`` - *undescribed* + NVM set id -``struct nvme_plm_config * data`` - *undescribed* +``struct nvme_plm_config *data`` -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -3441,7 +3419,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_plm_window (int fd, enum nvme_get_features_sel sel, __u16 nvmsetid, __u32 * result) +.. c:function:: int nvme_get_features_plm_window (int fd, enum nvme_get_features_sel sel, __u16 nvmsetid, __u32 *result) **Parameters** @@ -3453,9 +3431,9 @@ The nvme command status if a response was received (see Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` ``__u16 nvmsetid`` - *undescribed* + NVM set id -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -3464,7 +3442,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_lba_sts_interval (int fd, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_get_features_lba_sts_interval (int fd, enum nvme_get_features_sel sel, __u32 *result) **Parameters** @@ -3475,7 +3453,7 @@ The nvme command status if a response was received (see ``enum nvme_get_features_sel sel`` Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -3484,7 +3462,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_host_behavior (int fd, enum nvme_get_features_sel sel, struct nvme_feat_host_behavior * data, __u32 * result) +.. c:function:: int nvme_get_features_host_behavior (int fd, enum nvme_get_features_sel sel, struct nvme_feat_host_behavior *data, __u32 *result) **Parameters** @@ -3495,10 +3473,9 @@ The nvme command status if a response was received (see ``enum nvme_get_features_sel sel`` Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``struct nvme_feat_host_behavior * data`` - *undescribed* +``struct nvme_feat_host_behavior *data`` -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -3507,7 +3484,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_sanitize (int fd, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_get_features_sanitize (int fd, enum nvme_get_features_sel sel, __u32 *result) **Parameters** @@ -3518,7 +3495,7 @@ The nvme command status if a response was received (see ``enum nvme_get_features_sel sel`` Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -3527,7 +3504,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_endurance_event_cfg (int fd, enum nvme_get_features_sel sel, __u16 endgid, __u32 * result) +.. c:function:: int nvme_get_features_endurance_event_cfg (int fd, enum nvme_get_features_sel sel, __u16 endgid, __u32 *result) **Parameters** @@ -3539,9 +3516,8 @@ The nvme command status if a response was received (see Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` ``__u16 endgid`` - *undescribed* -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -3550,7 +3526,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_sw_progress (int fd, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_get_features_sw_progress (int fd, enum nvme_get_features_sel sel, __u32 *result) **Parameters** @@ -3561,7 +3537,7 @@ The nvme command status if a response was received (see ``enum nvme_get_features_sel sel`` Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -3570,7 +3546,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_host_id (int fd, enum nvme_get_features_sel sel, bool exhid, __u32 len, __u8 * hostid) +.. c:function:: int nvme_get_features_host_id (int fd, enum nvme_get_features_sel sel, bool exhid, __u32 len, __u8 *hostid) **Parameters** @@ -3582,13 +3558,12 @@ The nvme command status if a response was received (see Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` ``bool exhid`` - *undescribed* ``__u32 len`` - *undescribed* + Length of **hostid** -``__u8 * hostid`` - *undescribed* +``__u8 *hostid`` + Buffer for returned host ID **Return** @@ -3596,7 +3571,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_resv_mask (int fd, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_get_features_resv_mask (int fd, enum nvme_get_features_sel sel, __u32 *result) **Parameters** @@ -3607,7 +3582,7 @@ The nvme command status if a response was received (see ``enum nvme_get_features_sel sel`` Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -3616,7 +3591,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_resv_persist (int fd, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_get_features_resv_persist (int fd, enum nvme_get_features_sel sel, __u32 *result) **Parameters** @@ -3627,7 +3602,7 @@ The nvme command status if a response was received (see ``enum nvme_get_features_sel sel`` Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -3636,7 +3611,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_features_write_protect (int fd, __u32 nsid, enum nvme_get_features_sel sel, __u32 * result) +.. c:function:: int nvme_get_features_write_protect (int fd, __u32 nsid, enum nvme_get_features_sel sel, __u32 *result) **Parameters** @@ -3650,7 +3625,7 @@ The nvme command status if a response was received (see ``enum nvme_get_features_sel sel`` Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``__u32 * result`` +``__u32 *result`` The command completion result from CQE dword0 **Return** @@ -3659,43 +3634,99 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_format_nvm (int fd, __u32 nsid, __u8 lbaf, enum nvme_cmd_format_mset mset, enum nvme_cmd_format_pi pi, enum nvme_cmd_format_pil pil, enum nvme_cmd_format_ses ses, __u32 timeout) +.. c:function:: int nvme_get_features_iocs_profile (int fd, enum nvme_get_features_sel sel, __u32 *result) - Format nvme namespace(s) **Parameters** ``int fd`` File descriptor of nvme device -``__u32 nsid`` - Namespace ID to format +``enum nvme_get_features_sel sel`` + Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` -``__u8 lbaf`` - Logical block address format +``__u32 *result`` + The command completion result from CQE dword0 + +**Return** + +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. + + + + +.. c:type:: struct nvme_format_nvm_args + + Arguments for the Format Nvme Namespace command + +**Definition** -``enum nvme_cmd_format_mset mset`` +:: + + 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; + }; + +**Members** + +``result`` + The command completion result from CQE dword0 + +``args_size`` + Size of :c:type:`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 -``enum nvme_cmd_format_pi pi`` +``pi`` Protection information type -``enum nvme_cmd_format_pil pil`` +``pil`` Protection information location (beginning or end), true if end -``enum nvme_cmd_format_ses ses`` +``ses`` Secure erase settings -``__u32 timeout`` - Set to override default timeout to this value in milliseconds; - useful for long running formats. 0 will use system default. +``lbaf`` + Logical block address format + + + +.. c:function:: int nvme_format_nvm (struct nvme_format_nvm_args *args) + + Format nvme namespace(s) + +**Parameters** + +``struct nvme_format_nvm_args *args`` + :c:type:`struct nvme_format_nvme_args ` argument structure **Description** -The Format NVM command is used to low level format the NVM media. This -command is used by the host to change the LBA data size and/or metadata -size. A low level format may destroy all data and metadata associated with -all namespaces or only the specific namespace associated with the command +The Format NVM command low level formats the NVM media. This command is used +by the host to change the LBA data size and/or metadata size. A low level +format may destroy all data and metadata associated with all namespaces or +only the specific namespace associated with the command **Return** @@ -3703,31 +3734,66 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_ns_mgmt (int fd, __u32 nsid, enum nvme_ns_mgmt_sel sel, struct nvme_id_ns * ns, __u32 * result, __u32 timeout) -**Parameters** +.. c:type:: struct nvme_ns_mgmt_args -``int fd`` + Arguments for NVMe Namespace Management command + +**Definition** + +:: + + 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; + }; + +**Members** + +``result`` + NVMe command result + +``ns`` + Namespace identication descriptors + +``args_size`` + Size of :c:type:`struct nvme_ns_mgmt_args ` + +``fd`` File descriptor of nvme device -``__u32 nsid`` - *undescribed* +``timeout`` + Timeout in ms -``enum nvme_ns_mgmt_sel sel`` - *undescribed* +``nsid`` + Namespace identifier -``struct nvme_id_ns * ns`` - *undescribed* +``sel`` + Type of management operation to perform -``__u32 * result`` - *undescribed* +``csi`` + Command Set Identifier -``__u32 timeout`` - *undescribed* -.. c:function:: int nvme_ns_mgmt_create (int fd, struct nvme_id_ns * ns, __u32 * nsid, __u32 timeout) +.. c:function:: int nvme_ns_mgmt (struct nvme_ns_mgmt_args *args) + + Issue a Namespace management command + +**Parameters** + +``struct nvme_ns_mgmt_args *args`` + :c:type:`struct nvme_ns_mgmt_args ` Argument structure + + +.. c:function:: int nvme_ns_mgmt_create (int fd, struct nvme_id_ns *ns, __u32 *nsid, __u32 timeout, __u8 csi) **Parameters** @@ -3735,16 +3801,19 @@ The nvme command status if a response was received (see ``int fd`` File descriptor of nvme device -``struct nvme_id_ns * ns`` - Namespace identifiaction that defines creation parameters +``struct nvme_id_ns *ns`` + Namespace identification that defines ns creation parameters -``__u32 * nsid`` +``__u32 *nsid`` On success, set to the namespace id that was created ``__u32 timeout`` Overide the default timeout to this value in milliseconds; set to 0 to use the system default. +``__u8 csi`` + Command Set Identifier + **Description** On successful creation, the namespace exists in the subsystem, but is not @@ -3780,26 +3849,62 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_ns_attach (int fd, __u32 nsid, enum nvme_ns_attach_sel sel, struct nvme_ctrl_list * ctrlist) - Attach or detach namespace to controller(s) -**Parameters** +.. c:type:: struct nvme_ns_attach_args -``int fd`` + Arguments for Nvme Namespace Management command + +**Definition** + +:: + + 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; + }; + +**Members** + +``result`` + NVMe command result + +``ctrlist`` + Controller list to modify attachment state of nsid + +``args_size`` + Size of :c:type:`struct nvme_ns_attach_args ` + +``fd`` File descriptor of nvme device -``__u32 nsid`` +``timeout`` + Timeout in ms + +``nsid`` Namespace ID to execute attach selection -``enum nvme_ns_attach_sel sel`` +``sel`` Attachment selection, see :c:type:`enum nvme_ns_attach_sel ` -``struct nvme_ctrl_list * ctrlist`` - Controller list to modify attachment state of nsid -.. c:function:: int nvme_ns_attach_ctrls (int fd, __u32 nsid, struct nvme_ctrl_list * ctrlist) +.. c:function:: int nvme_ns_attach (struct nvme_ns_attach_args *args) + + Attach or detach namespace to controller(s) + +**Parameters** + +``struct nvme_ns_attach_args *args`` + :c:type:`struct nvme_ns_attach_args ` Argument structure + + +.. c:function:: int nvme_ns_attach_ctrls (int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist) **Parameters** @@ -3810,11 +3915,11 @@ The nvme command status if a response was received (see ``__u32 nsid`` Namespace ID to attach -``struct nvme_ctrl_list * ctrlist`` +``struct nvme_ctrl_list *ctrlist`` Controller list to modify attachment state of nsid -.. c:function:: int nvme_ns_detach_ctrls (int fd, __u32 nsid, struct nvme_ctrl_list * ctrlist) +.. c:function:: int nvme_ns_detach_ctrls (int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist) **Parameters** @@ -3825,33 +3930,69 @@ The nvme command status if a response was received (see ``__u32 nsid`` Namespace ID to detach -``struct nvme_ctrl_list * ctrlist`` +``struct nvme_ctrl_list *ctrlist`` Controller list to modify attachment state of nsid -.. c:function:: int nvme_fw_download (int fd, __u32 offset, __u32 data_len, void * data) - Download part or all of a firmware image to the controller -**Parameters** +.. c:type:: struct nvme_fw_download_args -``int fd`` + Arguments for the NVMe Firmware Download command + +**Definition** + +:: + + struct nvme_fw_download_args { + __u32 *result; + void *data; + int args_size; + int fd; + __u32 timeout; + __u32 offset; + __u32 data_len; + }; + +**Members** + +``result`` + The command completion result from CQE dword0 + +``data`` + Userspace address of the firmware data + +``args_size`` + Size of :c:type:`struct nvme_fw_download_args ` + +``fd`` File descriptor of nvme device -``__u32 offset`` +``timeout`` + Timeout in ms + +``offset`` Offset in the firmware data -``__u32 data_len`` +``data_len`` Length of data in this command in bytes -``void * data`` - Userspace address of the firmware data + + +.. c:function:: int nvme_fw_download (struct nvme_fw_download_args *args) + + Download part or all of a firmware image to the controller + +**Parameters** + +``struct nvme_fw_download_args *args`` + :c:type:`struct nvme_fw_download_args ` argument structure **Description** -The Firmware Image Download command is used to download all or a portion of -an image for a future update to the controller. The Firmware Image Download -command downloads a new image (in whole or in part) to the controller. +The Firmware Image Download command downloads all or a portion of an image +for a future update to the controller. The Firmware Image Download command +downloads a new image (in whole or in part) to the controller. The image may be constructed of multiple pieces that are individually downloaded with separate Firmware Image Download commands. Each Firmware @@ -3868,76 +4009,148 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_fw_commit (int fd, __u8 slot, enum nvme_fw_commit_ca action, bool bpid) - Commit firmware using the specified action -**Parameters** +.. c:type:: struct nvme_fw_commit_args -``int fd`` + Arguments for the NVMe Firmware Commit command + +**Definition** + +:: + + struct nvme_fw_commit_args { + __u32 *result; + int args_size; + int fd; + __u32 timeout; + enum nvme_fw_commit_ca action; + __u8 slot; + bool bpid; + }; + +**Members** + +``result`` + The command completion result from CQE dword0 + +``args_size`` + Size of :c:type:`struct nvme_fw_commit_args ` + +``fd`` File descriptor of nvme device -``__u8 slot`` - Firmware slot to commit the downloaded image +``timeout`` + Timeout in ms -``enum nvme_fw_commit_ca action`` +``action`` Action to use for the firmware image, see :c:type:`enum nvme_fw_commit_ca ` -``bool bpid`` +``slot`` + Firmware slot to commit the downloaded image + +``bpid`` Set to true to select the boot partition id + + +.. c:function:: int nvme_fw_commit (struct nvme_fw_commit_args *args) + + Commit firmware using the specified action + +**Parameters** + +``struct nvme_fw_commit_args *args`` + :c:type:`struct nvme_fw_commit_args ` argument structure + **Description** -The Firmware Commit command is used to modify the firmware image or Boot -Partitions. +The Firmware Commit command modifies the firmware image or Boot Partitions. **Return** The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. The command - status - response may specify additional - reset actions required to complete the commit process. +status response may specify additional reset actions required to complete +the commit process. -.. c:function:: int nvme_security_send (int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, __u8 secp, __u32 tl, __u32 data_len, void * data, __u32 * result) -**Parameters** +.. c:type:: struct nvme_security_send_args -``int fd`` - File descriptor of nvme device + Arguments for the NVMe Security Send command -``__u32 nsid`` - Namespace ID to issue security command on +**Definition** -``__u8 nssf`` - NVMe Security Specific field +:: -``__u8 spsp0`` - Security Protocol Specific field + 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; + }; -``__u8 spsp1`` - Security Protocol Specific field +**Members** -``__u8 secp`` - Security Protocol +``result`` + The command completion result from CQE dword0 + +``data`` + Security data payload to send + +``args_size`` + Size of :c:type:`struct nvme_security_send_args ` + +``fd`` + File descriptor of nvme device -``__u32 tl`` +``timeout`` + Timeout in ms + +``nsid`` + Namespace ID to issue security command on + +``tl`` Protocol specific transfer length -``__u32 data_len`` +``data_len`` Data length of the payload in bytes -``void * data`` - Security data payload to send +``nssf`` + NVMe Security Specific field + +``spsp0`` + Security Protocol Specific field + +``spsp1`` + Security Protocol Specific field + +``secp`` + Security Protocol + -``__u32 * result`` - The command completion result from CQE dword0 + +.. c:function:: int nvme_security_send (struct nvme_security_send_args *args) + + +**Parameters** + +``struct nvme_security_send_args *args`` + :c:type:`struct nvme_security_send ` argument structure **Description** -The Security Send command is used to transfer security protocol data to the +The Security Send command transfers security protocol data to the controller. The data structure transferred to the controller as part of this command contains security protocol specific commands to be performed by the controller. The data structure transferred may also contain data or @@ -3952,40 +4165,78 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_security_receive (int fd, __u32 nsid, __u8 nssf, __u8 spsp0, __u8 spsp1, __u8 secp, __u32 al, __u32 data_len, void * data, __u32 * result) -**Parameters** +.. c:type:: struct nvme_security_receive_args -``int fd`` + Arguments for the NVMe Security Receive command + +**Definition** + +:: + + 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; + }; + +**Members** + +``result`` + The command completion result from CQE dword0 + +``data`` + Security data payload to send + +``args_size`` + Size of :c:type:`struct nvme_security_receive_args ` + +``fd`` File descriptor of nvme device -``__u32 nsid`` +``timeout`` + Timeout in ms + +``nsid`` Namespace ID to issue security command on -``__u8 nssf`` +``al`` + Protocol specific allocation length + +``data_len`` + Data length of the payload in bytes + +``nssf`` NVMe Security Specific field -``__u8 spsp0`` +``spsp0`` Security Protocol Specific field -``__u8 spsp1`` +``spsp1`` Security Protocol Specific field -``__u8 secp`` +``secp`` Security Protocol -``__u32 al`` - Protocol specific allocation length -``__u32 data_len`` - Data length of the payload in bytes -``void * data`` - Security data payload to send +.. c:function:: int nvme_security_receive (struct nvme_security_receive_args *args) -``__u32 * result`` - The command completion result from CQE dword0 + +**Parameters** + +``struct nvme_security_receive_args *args`` + :c:type:`struct nvme_security_recevice ` argument structure **Return** @@ -3993,33 +4244,72 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_lba_status (int fd, __u32 nsid, __u64 slba, __u32 mndw, __u16 rl, enum nvme_lba_status_atype atype, struct nvme_lba_status * lbas) - Retrieve information on possibly unrecoverable LBAs -**Parameters** +.. c:type:: struct nvme_get_lba_status_args -``int fd`` - File descriptor of nvme device + Arguments for the NVMe Get LBA Status command -``__u32 nsid`` - Namespace ID to retrieve LBA status +**Definition** -``__u64 slba`` +:: + + 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; + }; + +**Members** + +``slba`` Starting logical block address to check statuses -``__u32 mndw`` - Maximum number of dwords to return +``result`` + The command completion result from CQE dword0 -``__u16 rl`` - Range length from slba to perform the action +``lbas`` + Data payload to return status descriptors + +``args_size`` + Size of :c:type:`struct nvme_get_lba_status_args ` + +``fd`` + File descriptor of nvme device -``enum nvme_lba_status_atype atype`` +``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 :c:type:`enum nvme_lba_status_atype ` -``struct nvme_lba_status * lbas`` - Data payload to return status descriptors +``rl`` + Range length from slba to perform the action + + + +.. c:function:: int nvme_get_lba_status (struct nvme_get_lba_status_args *args) + + Retrieve information on possibly unrecoverable LBAs + +**Parameters** + +``struct nvme_get_lba_status_args *args`` + :c:type:`struct nvme_get_lba_status_args ` argument structure **Description** @@ -4032,44 +4322,81 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_directive_send (int fd, __u32 nsid, __u16 dspec, enum nvme_directive_send_doper doper, enum nvme_directive_dtype dtype, __u32 cdw12, __u32 data_len, void * data, __u32 * result) - Send directive command -**Parameters** +.. c:type:: struct nvme_directive_send_args -``int fd`` + Arguments for the NVMe Directive Send command + +**Definition** + +:: + + 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; + }; + +**Members** + +``result`` + If successful, the CQE dword0 value + +``data`` + Data payload to to be send + +``args_size`` + Size of :c:type:`struct nvme_directive_send_args ` + +``fd`` File descriptor of nvme device -``__u32 nsid`` - Namespace ID, if applicable +``timeout`` + Timeout in ms -``__u16 dspec`` - Directive specific field +``nsid`` + Namespace ID, if applicable -``enum nvme_directive_send_doper doper`` +``doper`` Directive send operation, see :c:type:`enum nvme_directive_send_doper ` -``enum nvme_directive_dtype dtype`` +``dtype`` Directive type, see :c:type:`enum nvme_directive_dtype ` -``__u32 cdw12`` - *undescribed* +``cdw12`` + Directive specific command dword12 -``__u32 data_len`` +``data_len`` Length of data payload in bytes -``void * data`` - Usespace address of data payload +``dspec`` + Directive specific field -``__u32 * result`` - If successful, the CQE dword0 value + + +.. c:function:: int nvme_directive_send (struct nvme_directive_send_args *args) + + Send directive command + +**Parameters** + +``struct nvme_directive_send_args *args`` + :c:type:`struct nvme_directive_send_args ` argument structure **Description** Directives is a mechanism to enable host and NVM subsystem or controller -information exchange. The Directive Send command is used to transfer data -related to a specific Directive Type from the host to the controller. +information exchange. The Directive Send command transfers data related to a +specific Directive Type from the host to the controller. See the NVMe specification for more information. @@ -4079,7 +4406,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_directive_send_id_endir (int fd, __u32 nsid, bool endir, enum nvme_directive_dtype dtype, struct nvme_id_directives * id) +.. c:function:: int nvme_directive_send_id_endir (int fd, __u32 nsid, bool endir, enum nvme_directive_dtype dtype, struct nvme_id_directives *id) **Parameters** @@ -4088,16 +4415,12 @@ The nvme command status if a response was received (see File descriptor of nvme device ``__u32 nsid`` - Namespace ID ``bool endir`` - *undescribed* ``enum nvme_directive_dtype dtype`` - *undescribed* -``struct nvme_id_directives * id`` - *undescribed* +``struct nvme_id_directives *id`` **Return** @@ -4117,7 +4440,7 @@ The nvme command status if a response was received (see Namespace ID ``__u16 stream_id`` - *undescribed* + Stream identifier **Return** @@ -4142,38 +4465,75 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_directive_recv (int fd, __u32 nsid, __u16 dspec, enum nvme_directive_receive_doper doper, enum nvme_directive_dtype dtype, __u32 cdw12, __u32 data_len, void * data, __u32 * result) - Receive directive specific data -**Parameters** +.. c:type:: struct nvme_directive_recv_args -``int fd`` + Arguments for the NVMe Directive Receive command + +**Definition** + +:: + + 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; + }; + +**Members** + +``result`` + If successful, the CQE dword0 value + +``data`` + Usespace address of data payload + +``args_size`` + Size of :c:type:`struct nvme_directive_recv_args ` + +``fd`` File descriptor of nvme device -``__u32 nsid`` +``timeout`` + Timeout in ms + +``nsid`` Namespace ID, if applicable -``__u16 dspec`` +``doper`` + Directive send operation, see :c:type:`enum nvme_directive_send_doper ` + +``dtype`` + Directive type, see :c:type:`enum nvme_directive_dtype ` + +``cdw12`` + Directive specific command dword12 + +``data_len`` + Length of data payload in bytes + +``dspec`` Directive specific field -``enum nvme_directive_receive_doper doper`` - Directive receive operation, see :c:type:`enum nvme_directive_receive_doper ` -``enum nvme_directive_dtype dtype`` - Directive type, see :c:type:`enum nvme_directive_dtype ` -``__u32 cdw12`` - *undescribed* +.. c:function:: int nvme_directive_recv (struct nvme_directive_recv_args *args) -``__u32 data_len`` - Length of data payload + Receive directive specific data -``void * data`` - Usespace address of data payload in bytes +**Parameters** -``__u32 * result`` - If successful, the CQE dword0 value +``struct nvme_directive_recv_args *args`` + :c:type:`struct nvme_directive_recv_args ` argument structure **Return** @@ -4181,7 +4541,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_directive_recv_identify_parameters (int fd, __u32 nsid, struct nvme_id_directives * id) +.. c:function:: int nvme_directive_recv_identify_parameters (int fd, __u32 nsid, struct nvme_id_directives *id) **Parameters** @@ -4192,8 +4552,8 @@ The nvme command status if a response was received (see ``__u32 nsid`` Namespace ID -``struct nvme_id_directives * id`` - *undescribed* +``struct nvme_id_directives *id`` + Identify parameters buffer **Return** @@ -4201,7 +4561,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_directive_recv_stream_parameters (int fd, __u32 nsid, struct nvme_streams_directive_params * parms) +.. c:function:: int nvme_directive_recv_stream_parameters (int fd, __u32 nsid, struct nvme_streams_directive_params *parms) **Parameters** @@ -4212,8 +4572,8 @@ The nvme command status if a response was received (see ``__u32 nsid`` Namespace ID -``struct nvme_streams_directive_params * parms`` - *undescribed* +``struct nvme_streams_directive_params *parms`` + Streams directive parameters buffer **Return** @@ -4221,7 +4581,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_directive_recv_stream_status (int fd, __u32 nsid, unsigned nr_entries, struct nvme_streams_directive_status * id) +.. c:function:: int nvme_directive_recv_stream_status (int fd, __u32 nsid, unsigned nr_entries, struct nvme_streams_directive_status *id) **Parameters** @@ -4233,10 +4593,10 @@ The nvme command status if a response was received (see Namespace ID ``unsigned nr_entries`` - *undescribed* + Number of streams to receive -``struct nvme_streams_directive_status * id`` - *undescribed* +``struct nvme_streams_directive_status *id`` + Stream status buffer **Return** @@ -4244,7 +4604,7 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_directive_recv_stream_allocate (int fd, __u32 nsid, __u16 nsr, __u32 * result) +.. c:function:: int nvme_directive_recv_stream_allocate (int fd, __u32 nsid, __u16 nsr, __u32 *result) **Parameters** @@ -4256,10 +4616,8 @@ The nvme command status if a response was received (see Namespace ID ``__u16 nsr`` - *undescribed* -``__u32 * result`` - *undescribed* +``__u32 *result`` **Return** @@ -4269,49 +4627,62 @@ The nvme command status if a response was received (see -.. c:type:: enum nvme_fctype +.. c:type:: struct nvme_capacity_mgmt_args + Arguments for the NVMe Capacity Management command -**Constants** +**Definition** -``nvme_fabrics_type_property_set`` - *undescribed* +:: -``nvme_fabrics_type_connect`` - *undescribed* + struct nvme_capacity_mgmt_args { + __u32 *result; + int args_size; + int fd; + __u32 timeout; + __u32 cdw11; + __u32 cdw12; + __u16 element_id; + __u8 op; + }; -``nvme_fabrics_type_property_get`` - *undescribed* +**Members** -``nvme_fabrics_type_auth_send`` - *undescribed* +``result`` + If successful, the CQE dword0 value -``nvme_fabrics_type_auth_receive`` - *undescribed* +``args_size`` + Size of :c:type:`struct nvme_capacity_mgmt_args ` -``nvme_fabrics_type_disconnect`` - *undescribed* +``fd`` + File descriptor of nvme device +``timeout`` + Timeout in ms -.. c:function:: int nvme_set_property (int fd, int offset, __u64 value) +``cdw11`` + Least significant 32 bits of the capacity in bytes of the + Endurance Group or NVM Set to be created - Set controller property +``cdw12`` + Most significant 32 bits of the capacity in bytes of the + Endurance Group or NVM Set to be created -**Parameters** +``element_id`` + Value specific to the value of the Operation field -``int fd`` - File descriptor of nvme device +``op`` + Operation to be performed by the controller -``int offset`` - Property offset from the base to set -``__u64 value`` - The value to set the property -**Description** +.. c:function:: int nvme_capacity_mgmt (struct nvme_capacity_mgmt_args *args) -This is an NVMe-over-Fabrics specific command, not applicable to PCIe. These -properties align to the PCI MMIO controller registers. + +**Parameters** + +``struct nvme_capacity_mgmt_args *args`` + :c:type:`struct nvme_capacity_mgmt_args ` argument structure **Return** @@ -4319,70 +4690,67 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_get_property (int fd, int offset, __u64 * value) - - Get a controller property -**Parameters** -``int fd`` - File descriptor of nvme device +.. c:type:: struct nvme_lockdown_args -``int offset`` - Property offset from the base to retrieve + Arguments for the NVME Lockdown command -``__u64 * value`` - Where the property's value will be stored on success +**Definition** -**Description** +:: -This is an NVMe-over-Fabrics specific command, not applicable to PCIe. These -properties align to the PCI MMIO controller registers. + struct nvme_lockdown_args { + __u32 *result; + int args_size; + int fd; + __u32 timeout; + __u8 scp; + __u8 prhbt; + __u8 ifc; + __u8 ofi; + __u8 uuidx; + }; -**Return** +**Members** -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. +``result`` + The command completion result from CQE dword0 +``args_size`` + Size of :c:type:`struct nvme_lockdown_args ` -.. c:function:: int nvme_sanitize_nvm (int fd, enum nvme_sanitize_sanact sanact, bool ause, __u8 owpass, bool oipbp, bool nodas, __u32 ovrpat) +``fd`` + File descriptor of nvme device - Start a sanitize operation +``timeout`` + Timeout in ms (0 for default timeout) -**Parameters** +``scp`` + Scope of the command -``int fd`` - File descriptor of nvme device +``prhbt`` + Prohibit or allow the command opcode or Set Features command -``enum nvme_sanitize_sanact sanact`` - Sanitize action, see :c:type:`enum nvme_sanitize_sanact ` +``ifc`` + Affected interface -``bool ause`` - Set to allow unrestriced sanitize exit +``ofi`` + Opcode or Feature Identifier -``__u8 owpass`` - Overwrite pass count +``uuidx`` + UUID Index if controller supports this id selection method -``bool oipbp`` - Set to overwrite invert pattern between passes -``bool nodas`` - Set to not deallocate blocks after sanitizing -``__u32 ovrpat`` - Overwrite pattern +.. c:function:: int nvme_lockdown (struct nvme_lockdown_args *args) -**Description** + Issue lockdown command -A sanitize operation alters all user data in the NVM subsystem such that -recovery of any previous user data from any cache, the non-volatile media, -or any Controller Memory Buffer is not possible. +**Parameters** -The Sanitize command is used to start a sanitize operation or to recover -from a previously failed sanitize operation. The sanitize operation types -that may be supported are Block Erase, Crypto Erase, and Overwrite. All -sanitize operations are processed in the background, i.e., completion of the -sanitize command does not indicate completion of the sanitize operation. +``struct nvme_lockdown_args *args`` + :c:type:`struct nvme_lockdown_args ` argument structure **Return** @@ -4390,73 +4758,60 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_dev_self_test (int fd, __u32 nsid, enum nvme_dst_stc stc) - Start or abort a self test -**Parameters** +.. c:type:: struct nvme_set_property_args -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Namespace ID to test + Arguments for NVMe Set Property command -``enum nvme_dst_stc stc`` - Self test code, see :c:type:`enum nvme_dst_stc ` +**Definition** -**Description** +:: -The Device Self-test command is used to start a device self-test operation -or abort a device self-test operation. A device self-test operation is a -diagnostic testing sequence that tests the integrity and functionality of -the controller and may include testing of the media associated with -namespaces. The controller may return a response to this command immediately -while running the self-test in the background. + struct nvme_set_property_args { + __u64 value; + __u32 *result; + int args_size; + int fd; + __u32 timeout; + int offset; + }; -Set the 'nsid' field to 0 to not include namepsaces in the test. Set to -0xffffffff to test all namespaces. All other values tests a specific -namespace, if present. +**Members** -**Return** +``value`` + The value to set the property -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. +``result`` + The command completion result from CQE dword0 +``args_size`` + Size of :c:type:`struct nvme_set_property_args ` -.. c:function:: int nvme_virtual_mgmt (int fd, enum nvme_virt_mgmt_act act, enum nvme_virt_mgmt_rt rt, __u16 cntlid, __u16 nr, __u32 * result) +``fd`` + File descriptor of nvme device - Virtualization resource management +``timeout`` + Timeout in ms -**Parameters** +``offset`` + Property offset from the base to set -``int fd`` - File descriptor of nvme device -``enum nvme_virt_mgmt_act act`` - Virtual resource action, see :c:type:`enum nvme_virt_mgmt_act ` -``enum nvme_virt_mgmt_rt rt`` - Resource type to modify, see :c:type:`enum nvme_virt_mgmt_rt ` +.. c:function:: int nvme_set_property (struct nvme_set_property_args *args) -``__u16 cntlid`` - Controller id for which resources are bing modified + Set controller property -``__u16 nr`` - Number of resources being allocated or assigned +**Parameters** -``__u32 * result`` - If successful, the CQE dword0 +``struct nvme_set_property_args *args`` + :c:type:`struct nvme_set_property_args ` argument structure **Description** -The Virtualization Management command is supported by primary controllers -that support the Virtualization Enhancements capability. This command is -used for several functions: - - - Modifying Flexible Resource allocation for the primary controller - - Assigning Flexible Resources for secondary controllers - - Setting the Online and Offline state for secondary controllers +This is an NVMe-over-Fabrics specific command, not applicable to PCIe. These +properties align to the PCI MMIO controller registers. **Return** @@ -4466,64 +4821,54 @@ The nvme command status if a response was received (see -.. c:type:: enum nvme_io_opcode - - -**Constants** - -``nvme_cmd_flush`` - *undescribed* +.. c:type:: struct nvme_get_property_args -``nvme_cmd_write`` - *undescribed* + Arguments for NVMe Get Property command -``nvme_cmd_read`` - *undescribed* +**Definition** -``nvme_cmd_write_uncor`` - *undescribed* +:: -``nvme_cmd_compare`` - *undescribed* + struct nvme_get_property_args { + __u64 *value; + int args_size; + int fd; + __u32 timeout; + int offset; + }; -``nvme_cmd_write_zeroes`` - *undescribed* +**Members** -``nvme_cmd_dsm`` - *undescribed* +``value`` + Where the property's value will be stored on success -``nvme_cmd_verify`` - *undescribed* +``args_size`` + Size of :c:type:`struct nvme_get_property_args ` -``nvme_cmd_resv_register`` - *undescribed* +``fd`` + File descriptor of nvme device -``nvme_cmd_resv_report`` - *undescribed* +``timeout`` + Timeout in ms -``nvme_cmd_resv_acquire`` - *undescribed* +``offset`` + Property offset from the base to retrieve -``nvme_cmd_resv_release`` - *undescribed* -.. c:function:: int nvme_flush (int fd, __u32 nsid) +.. c:function:: int nvme_get_property (struct nvme_get_property_args *args) - Send an nvme flush command + Get a controller property **Parameters** -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Namespace identifier +``struct nvme_get_property_args *args`` + :c:type:`struct nvme_get_propert_args ` argument structure **Description** -The Flush command is used to request that the contents of volatile write -cache be made non-volatile. +This is an NVMe-over-Fabrics specific command, not applicable to PCIe. These +properties align to the PCI MMIO controller registers. **Return** @@ -4533,140 +4878,150 @@ The nvme command status if a response was received (see -.. c:type:: enum nvme_io_control_flags +.. c:type:: struct nvme_sanitize_nvm_args + Arguments for the NVMe Sanitize NVM command -**Constants** +**Definition** -``NVME_IO_DTYPE_STREAMS`` - *undescribed* +:: -``NVME_IO_DEAC`` - *undescribed* + 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_IO_PRINFO_PRCHK_REF`` - *undescribed* +**Members** -``NVME_IO_PRINFO_PRCHK_APP`` - *undescribed* +``result`` + The command completion result from CQE dword0 -``NVME_IO_PRINFO_PRCHK_GUARD`` - *undescribed* +``args_size`` + Size of :c:type:`struct nvme_sanitize_nvm_args ` -``NVME_IO_PRINFO_PRACT`` - *undescribed* +``fd`` + File descriptor of nvme device -``NVME_IO_FUA`` - *undescribed* +``timeout`` + Timeout in ms -``NVME_IO_LR`` - *undescribed* +``sanact`` + Sanitize action, see :c:type:`enum nvme_sanitize_sanact ` +``ovrpat`` + Overwrite pattern +``ause`` + Set to allow unrestriced sanitize exit +``owpass`` + Overwrite pass count -.. c:type:: enum nvme_io_dsm_flags +``oipbp`` + Set to overwrite invert pattern between passes +``nodas`` + Set to not deallocate blocks after sanitizing -**Constants** -``NVME_IO_DSM_FREQ_UNSPEC`` - *undescribed* -``NVME_IO_DSM_FREQ_TYPICAL`` - *undescribed* +.. c:function:: int nvme_sanitize_nvm (struct nvme_sanitize_nvm_args *args) -``NVME_IO_DSM_FREQ_RARE`` - *undescribed* + Start a sanitize operation -``NVME_IO_DSM_FREQ_READS`` - *undescribed* +**Parameters** -``NVME_IO_DSM_FREQ_WRITES`` - *undescribed* +``struct nvme_sanitize_nvm_args *args`` + :c:type:`struct nvme_sanitize_nvm_args ` argument structure -``NVME_IO_DSM_FREQ_RW`` - *undescribed* +**Description** -``NVME_IO_DSM_FREQ_ONCE`` - *undescribed* +A sanitize operation alters all user data in the NVM subsystem such that +recovery of any previous user data from any cache, the non-volatile media, +or any Controller Memory Buffer is not possible. -``NVME_IO_DSM_FREQ_PREFETCH`` - *undescribed* +The Sanitize command starts a sanitize operation or to recover from a +previously failed sanitize operation. The sanitize operation types that may +be supported are Block Erase, Crypto Erase, and Overwrite. All sanitize +operations are processed in the background, i.e., completion of the sanitize +command does not indicate completion of the sanitize operation. -``NVME_IO_DSM_FREQ_TEMP`` - *undescribed* +**Return** -``NVME_IO_DSM_LATENCY_NONE`` - *undescribed* +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -``NVME_IO_DSM_LATENCY_IDLE`` - *undescribed* -``NVME_IO_DSM_LATENCY_NORM`` - *undescribed* -``NVME_IO_DSM_LATENCY_LOW`` - *undescribed* -``NVME_IO_DSM_SEQ_REQ`` - *undescribed* +.. c:type:: struct nvme_dev_self_test_args -``NVME_IO_DSM_COMPRESSED`` - *undescribed* + Arguments for the NVMe Device Self Test command + +**Definition** +:: -.. c:function:: int nvme_read (int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u8 dsm, __u32 reftag, __u16 apptag, __u16 appmask, __u32 data_len, void * data, __u32 metadata_len, void * metadata) + struct nvme_dev_self_test_args { + __u32 *result; + int args_size; + int fd; + __u32 timeout; + __u32 nsid; + enum nvme_dst_stc stc; + }; - Submit an nvme user read command +**Members** -**Parameters** +``result`` + The command completion result from CQE dword0 -``int fd`` +``args_size`` + Size of :c:type:`struct nvme_dev_self_test_args ` + +``fd`` File descriptor of nvme device -``__u32 nsid`` - Namespace ID +``timeout`` + Timeout in ms -``__u64 slba`` - Starting logical block +``nsid`` + Namespace ID to test -``__u16 nlb`` - *undescribed* +``stc`` + Self test code, see :c:type:`enum nvme_dst_stc ` -``__u16 control`` - Command control flags, see :c:type:`enum nvme_io_control_flags `. -``__u8 dsm`` - Data set management attributes, see :c:type:`enum nvme_io_dsm_flags ` -``__u32 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. +.. c:function:: int nvme_dev_self_test (struct nvme_dev_self_test_args *args) -``__u16 apptag`` - This field specifies the Application Tag Mask expected value. - Used only if the namespace is formatted to use end-to-end - protection information. + Start or abort a self test -``__u16 appmask`` - This field specifies the Application Tag expected value. Used - only if the namespace is formatted to use end-to-end protection - information. +**Parameters** -``__u32 data_len`` - Length of user buffer, **data**, in bytes +``struct nvme_dev_self_test_args *args`` + :c:type:`struct nvme_dev_self_test ` argument structure -``void * data`` - Pointer to user address of the data buffer - metadata_len:Length of user buffer, **metadata**, in bytes +**Description** -``__u32 metadata_len`` - *undescribed* +The Device Self-test command starts a device self-test operation or abort a +device self-test operation. A device self-test operation is a diagnostic +testing sequence that tests the integrity and functionality of the +controller and may include testing of the media associated with namespaces. +The controller may return a response to this command immediately while +running the self-test in the background. -``void * metadata`` - Pointer to user address of the metadata buffer +Set the 'nsid' field to 0 to not include namepsaces in the test. Set to +0xffffffff to test all namespaces. All other values tests a specific +namespace, if present. **Return** @@ -4674,60 +5029,73 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_write (int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u8 dsm, __u16 dspec, __u32 reftag, __u16 apptag, __u16 appmask, __u32 data_len, void * data, __u32 metadata_len, void * metadata) - Submit an nvme user write command -**Parameters** +.. c:type:: struct nvme_virtual_mgmt_args -``int fd`` + Arguments for the NVMe Virtualization resource management command + +**Definition** + +:: + + 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; + }; + +**Members** + +``result`` + If successful, the CQE dword0 + +``args_size`` + Size of :c:type:`struct nvme_virtual_mgmt_args ` + +``fd`` File descriptor of nvme device -``__u32 nsid`` - Namespace ID +``timeout`` + Timeout in ms -``__u64 slba`` - Starting logical block +``act`` + Virtual resource action, see :c:type:`enum nvme_virt_mgmt_act ` -``__u16 nlb`` - *undescribed* +``rt`` + Resource type to modify, see :c:type:`enum nvme_virt_mgmt_rt ` -``__u16 control`` - Command control flags, see :c:type:`enum nvme_io_control_flags `. +``cntlid`` + Controller id for which resources are bing modified -``__u8 dsm`` - Data set management attributes, see :c:type:`enum nvme_io_dsm_flags ` +``nr`` + Number of resources being allocated or assigned -``__u16 dspec`` - Directive specific command, eg: stream identifier -``__u32 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. -``__u16 apptag`` - This field specifies the Application Tag Mask expected value. - Used only if the namespace is formatted to use end-to-end - protection information. +.. c:function:: int nvme_virtual_mgmt (struct nvme_virtual_mgmt_args *args) -``__u16 appmask`` - This field specifies the Application Tag expected value. Used - only if the namespace is formatted to use end-to-end protection - information. + Virtualization resource management -``__u32 data_len`` - Length of user buffer, **data**, in bytes +**Parameters** -``void * data`` - Pointer to user address of the data buffer - metadata_len:Length of user buffer, **metadata**, in bytes +``struct nvme_virtual_mgmt_args *args`` + :c:type:`struct nvme_virtual_mgmt_args ` argument structure -``__u32 metadata_len`` - *undescribed* +**Description** -``void * metadata`` - Pointer to user address of the metadata buffer +The Virtualization Management command is supported by primary controllers +that support the Virtualization Enhancements capability. This command is +used for several functions: + + - Modifying Flexible Resource allocation for the primary controller + - Assigning Flexible Resources for secondary controllers + - Setting the Online and Offline state for secondary controllers **Return** @@ -4735,9 +5103,9 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_compare (int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 reftag, __u16 apptag, __u16 appmask, __u32 data_len, void * data, __u32 metadata_len, void * metadata) +.. c:function:: int nvme_flush (int fd, __u32 nsid) - Submit an nvme user compare command + Send an nvme flush command **Parameters** @@ -4745,93 +5113,127 @@ The nvme command status if a response was received (see File descriptor of nvme device ``__u32 nsid`` - Namespace ID + Namespace identifier -``__u64 slba`` - Starting logical block +**Description** -``__u16 nlb`` - *undescribed* +The Flush command requests that the contents of volatile write cache be made +non-volatile. -``__u16 control`` - Command control flags, see :c:type:`enum nvme_io_control_flags `. +**Return** -``__u32 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. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -``__u16 apptag`` - This field specifies the Application Tag Mask expected value. - Used only if the namespace is formatted to use end-to-end - protection information. -``__u16 appmask`` - This field specifies the Application Tag expected value. Used - only if the namespace is formatted to use end-to-end protection - information. -``__u32 data_len`` - Length of user buffer, **data**, in bytes -``void * data`` - Pointer to user address of the data buffer - metadata_len:Length of user buffer, **metadata**, in bytes +.. c:type:: struct nvme_io_args -``__u32 metadata_len`` - *undescribed* + Arguments for NVMe I/O commands -``void * metadata`` - Pointer to user address of the metadata buffer +**Definition** -**Return** +:: -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. + 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; + __u8 dsm; + __u8 dspec; + }; +**Members** -.. c:function:: int nvme_write_zeros (int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 reftag, __u16 apptag, __u16 appmask) +``slba`` + Starting logical block - Submit an nvme write zeroes command +``storage_tag`` + This filed specifies Variable Sized Expected Logical Block + Storage Tag (ELBST) and Expected Logical Block Reference + Tag (ELBRT) -**Parameters** +``result`` + The command completion result from CQE dword0 -``int fd`` - File descriptor of nvme device +``data`` + Pointer to user address of the data buffer -``__u32 nsid`` - Namespace identifier +``metadata`` + Pointer to user address of the metadata buffer -``__u64 slba`` - Starting logical block +``args_size`` + Size of :c:type:`struct nvme_io_args ` -``__u16 nlb`` - Number of logical blocks to clear (0's based value) +``fd`` + File descriptor of nvme device -``__u16 control`` - Command control flags, see :c:type:`enum nvme_io_control_flags `. +``timeout`` + Timeout in ms -``__u32 reftag`` +``nsid`` + Namespace ID + +``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. -``__u16 apptag`` +``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 :c:type:`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. -``__u16 appmask`` +``appmask`` This field specifies the Application Tag expected value. Used only if the namespace is formatted to use end-to-end protection information. -**Description** +``dsm`` + Data set management attributes, see :c:type:`enum nvme_io_dsm_flags ` + +``dspec`` + Directive specific value + + -The Write Zeroes command is used to set a range of logical blocks to zero. -After successful completion of this command, the value returned by -subsequent reads of logical blocks in this range shall be all bytes cleared -to 0h until a write occurs to this LBA range. +.. c:function:: int nvme_io (struct nvme_io_args *args, __u8 opcode) + + Submit an nvme user I/O command + +**Parameters** + +``struct nvme_io_args *args`` + :c:type:`struct nvme_io_args ` argument structure + +``__u8 opcode`` + Opcode to execute **Return** @@ -4839,31 +5241,66 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_write_uncorrectable (int fd, __u32 nsid, __u64 slba, __u16 nlb) +.. c:function:: int nvme_read (struct nvme_io_args *args) - Submit an nvme write uncorrectable command + Submit an nvme user read command **Parameters** -``int fd`` - File descriptor of nvme device +``struct nvme_io_args *args`` + :c:type:`struct nvme_io_args ` argument structure -``__u32 nsid`` - Namespace identifier +**Return** -``__u64 slba`` - Starting logical block +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. + + +.. c:function:: int nvme_write (struct nvme_io_args *args) + + Submit an nvme user write command + +**Parameters** + +``struct nvme_io_args *args`` + :c:type:`struct nvme_io_args ` argument structure + +**Return** + +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. + + +.. c:function:: int nvme_compare (struct nvme_io_args *args) + + Submit an nvme user compare command + +**Parameters** + +``struct nvme_io_args *args`` + :c:type:`struct nvme_io_args ` argument structure + +**Return** + +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. + + +.. c:function:: int nvme_write_zeros (struct nvme_io_args *args) + + Submit an nvme write zeroes command + +**Parameters** -``__u16 nlb`` - Number of logical blocks to invalidate (0's based value) +``struct nvme_io_args *args`` + :c:type:`struct nvme_io_args ` argument structure **Description** -The Write Uncorrectable command is used to mark a range of logical blocks as -invalid. When the specified logical block(s) are read after this operation, -a failure is returned with Unrecovered Read Error status. To clear the -invalid logical block status, a write operation on those logical blocks is -required. +The Write Zeroes command sets a range of logical blocks to zero. After +successful completion of this command, the value returned by subsequent +reads of logical blocks in this range shall be all bytes cleared to 0h until +a write occurs to this LBA range. **Return** @@ -4871,41 +5308,36 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_verify (int fd, __u32 nsid, __u64 slba, __u16 nlb, __u16 control, __u32 reftag, __u16 apptag, __u16 appmask) +.. c:function:: int nvme_write_uncorrectable (struct nvme_io_args *args) - Send an nvme verify command + Submit an nvme write uncorrectable command **Parameters** -``int fd`` - File descriptor of nvme device +``struct nvme_io_args *args`` + :c:type:`struct nvme_io_args ` argument structure -``__u32 nsid`` - Namespace identifier +**Description** -``__u64 slba`` - Starting logical block +The Write Uncorrectable command marks a range of logical blocks as invalid. +When the specified logical block(s) are read after this operation, a failure +is returned with Unrecovered Read Error status. To clear the invalid logical +block status, a write operation on those logical blocks is required. -``__u16 nlb`` - Number of logical blocks to verify (0's based value) +**Return** -``__u16 control`` - Command control flags, see :c:type:`enum nvme_io_control_flags `. +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -``__u32 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. -``__u16 apptag`` - This field specifies the Application Tag Mask expected value. - Used only if the namespace is formatted to use end-to-end - protection information. +.. c:function:: int nvme_verify (struct nvme_io_args *args) -``__u16 appmask`` - This field specifies the Application Tag expected value. Used - only if the namespace is formatted to use end-to-end protection - information. + Send an nvme verify command + +**Parameters** + +``struct nvme_io_args *args`` + :c:type:`struct nvme_io_args ` argument structure **Description** @@ -4921,42 +5353,61 @@ The nvme command status if a response was received (see -.. c:type:: enum nvme_dsm_attributes - +.. c:type:: struct nvme_dsm_args -**Constants** + Arguments for the NVMe Dataset Management command -``NVME_DSMGMT_IDR`` - *undescribed* +**Definition** -``NVME_DSMGMT_IDW`` - *undescribed* +:: -``NVME_DSMGMT_AD`` - *undescribed* + 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; + }; +**Members** -.. c:function:: int nvme_dsm (int fd, __u32 nsid, __u32 attrs, __u16 nr_ranges, struct nvme_dsm_range * dsm) +``result`` + The command completion result from CQE dword0 - Send an nvme data set management command +``dsm`` + The data set management attributes -**Parameters** +``args_size`` + Size of :c:type:`struct nvme_dsm_args ` -``int fd`` +``fd`` File descriptor of nvme device -``__u32 nsid`` +``timeout`` + Timeout in ms + +``nsid`` Namespace identifier -``__u32 attrs`` +``attrs`` DSM attributes, see :c:type:`enum nvme_dsm_attributes ` - :c:type:`nr_ranges`: Number of block ranges in the data set management attributes -``__u16 nr_ranges`` - *undescribed* +``nr_ranges`` + Number of block ranges in the data set management attributes + -``struct nvme_dsm_range * dsm`` - The data set management attributes + +.. c:function:: int nvme_dsm (struct nvme_dsm_args *args) + + Send an nvme data set management command + +**Parameters** + +``struct nvme_dsm_args *args`` + :c:type:`struct nvme_dsm_args ` argument structure **Description** @@ -4974,80 +5425,100 @@ The nvme command status if a response was received (see -.. c:type:: enum nvme_reservation_rtype +.. c:type:: struct nvme_copy_args + Arguments for the NVMe Copy command -**Constants** - -``NVME_RESERVATION_RTYPE_WE`` - *undescribed* +**Definition** -``NVME_RESERVATION_RTYPE_EA`` - *undescribed* +:: -``NVME_RESERVATION_RTYPE_WERO`` - *undescribed* + 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_RESERVATION_RTYPE_EARO`` - *undescribed* +**Members** -``NVME_RESERVATION_RTYPE_WEAR`` - *undescribed* +``sdlba`` + Start destination LBA -``NVME_RESERVATION_RTYPE_EAAR`` - *undescribed* +``result`` + The command completion result from CQE dword0 +``copy`` + Range descriptior +``args_size`` + Size of :c:type:`struct nvme_copy_args ` +``fd`` + File descriptor of the nvme device -.. c:type:: enum nvme_reservation_racqa +``timeout`` + Timeout in ms +``nsid`` + Namespace identifier -**Constants** +``ilbrt`` + Initial logical block reference tag -``NVME_RESERVATION_RACQA_ACQUIRE`` - *undescribed* +``lr`` + Limited retry -``NVME_RESERVATION_RACQA_PREEMPT`` - *undescribed* +``fua`` + Force unit access -``NVME_RESERVATION_RACQA_PREEMPT_AND_ABORT`` - *undescribed* +``nr`` + Number of ranges +``dspec`` + Directive specific value -.. c:function:: int nvme_resv_acquire (int fd, __u32 nsid, enum nvme_reservation_rtype rtype, enum nvme_reservation_racqa racqa, bool iekey, __u64 crkey, __u64 nrkey) +``lbatm`` + Logical block application tag mask - Send an nvme reservation acquire +``lbat`` + Logical block application tag -**Parameters** +``prinfor`` + Protection information field for read -``int fd`` - File descriptor of nvme device +``prinfow`` + Protection information field for write -``__u32 nsid`` - Namespace identifier +``dtype`` + Directive type -``enum nvme_reservation_rtype rtype`` - The type of reservation to be create, see :c:type:`enum nvme_reservation_rtype ` +``format`` + Descriptor format -``enum nvme_reservation_racqa racqa`` - The action that is performed by the command, see :c:type:`enum nvme_reservation_racqa ` -``bool iekey`` - Set to ignore the existing key -``__u64 crkey`` - The current reservation key associated with the host +.. c:function:: int nvme_copy (struct nvme_copy_args *args) -``__u64 nrkey`` - The reservation key to be unregistered from the namespace if - the action is preempt -**Description** +**Parameters** -The Reservation Acquire command is used to acquire a reservation on a -namespace, preempt a reservation held on a namespace, and abort a -reservation held on a namespace. +``struct nvme_copy_args *args`` + :c:type:`struct nvme_copy_args ` argument structure **Return** @@ -5057,70 +5528,76 @@ The nvme command status if a response was received (see -.. c:type:: enum nvme_reservation_rrega - +.. c:type:: struct nvme_resv_acquire_args -**Constants** - -``NVME_RESERVATION_RREGA_REGISTER_KEY`` - *undescribed* - -``NVME_RESERVATION_RREGA_UNREGISTER_KEY`` - *undescribed* - -``NVME_RESERVATION_RREGA_REPLACE_KEY`` - *undescribed* + Arguments for the NVMe Reservation Acquire Comand +**Definition** +:: + 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; + }; -.. c:type:: enum nvme_reservation_cptpl +**Members** +``crkey`` + The current reservation key associated with the host -**Constants** +``nrkey`` + The reservation key to be unregistered from the namespace if + the action is preempt -``NVME_RESERVATION_CPTPL_NO_CHANGE`` - *undescribed* +``result`` + The command completion result from CQE dword0 -``NVME_RESERVATION_CPTPL_CLEAR`` - *undescribed* +``args_size`` + Size of :c:type:`struct nvme_resv_acquire_args ` -``NVME_RESERVATION_CPTPL_PERSIST`` - *undescribed* +``fd`` + File descriptor of nvme device +``timeout`` + Timeout in ms -.. c:function:: int nvme_resv_register (int fd, __u32 nsid, enum nvme_reservation_rrega rrega, enum nvme_reservation_cptpl cptpl, bool iekey, __u64 crkey, __u64 nrkey) +``nsid`` + Namespace identifier - Send an nvme reservation register +``rtype`` + The type of reservation to be create, see :c:type:`enum nvme_resv_rtype ` -**Parameters** +``racqa`` + The action that is performed by the command, see :c:type:`enum nvme_resv_racqa ` -``int fd`` - File descriptor of nvme device +``iekey`` + Set to ignore the existing key -``__u32 nsid`` - Namespace identifier -``enum nvme_reservation_rrega rrega`` - The registration action, see :c:type:`enum nvme_reservation_rrega ` -``enum nvme_reservation_cptpl cptpl`` - Change persist through power loss, see :c:type:`enum nvme_reservation_cptpl ` +.. c:function:: int nvme_resv_acquire (struct nvme_resv_acquire_args *args) -``bool iekey`` - Set to ignore the existing key + Send an nvme reservation acquire -``__u64 crkey`` - The current reservation key associated with the host +**Parameters** -``__u64 nrkey`` - The new reservation key to be register if action is register or - replace +``struct nvme_resv_acquire_args *args`` + :c:type:`struct nvme_resv_acquire ` argument structure **Description** -The Reservation Register command is used to register, unregister, or replace -a reservation key. +The Reservation Acquire command acquires a reservation on a namespace, +preempt a reservation held on a namespace, and abort a reservation held on a +namespace. **Return** @@ -5130,74 +5607,75 @@ The nvme command status if a response was received (see -.. c:type:: enum nvme_reservation_rrela +.. c:type:: struct nvme_resv_register_args + Arguments for the NVMe Reservation Register command -**Constants** +**Definition** -``NVME_RESERVATION_RRELA_RELEASE`` - *undescribed* +:: -``NVME_RESERVATION_RRELA_CLEAR`` - *undescribed* + 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; + }; +**Members** -.. c:function:: int nvme_resv_release (int fd, __u32 nsid, enum nvme_reservation_rtype rtype, enum nvme_reservation_rrela rrela, bool iekey, __u64 crkey) +``crkey`` + The current reservation key associated with the host - Send an nvme reservation release +``nrkey`` + The new reservation key to be register if action is register or + replace -**Parameters** +``result`` + The command completion result from CQE dword0 -``int fd`` +``args_size`` + Size of :c:type:`struct nvme_resv_register_args ` + +``fd`` File descriptor of nvme device -``__u32 nsid`` +``timeout`` + Timeout in ms + +``nsid`` Namespace identifier -``enum nvme_reservation_rtype rtype`` - The type of reservation to be create, see :c:type:`enum nvme_reservation_rtype ` +``rrega`` + The registration action, see :c:type:`enum nvme_resv_rrega ` -``enum nvme_reservation_rrela rrela`` - Reservation releast action, see :c:type:`enum nvme_reservation_rrela ` +``cptpl`` + Change persist through power loss, see :c:type:`enum nvme_resv_cptpl ` -``bool iekey`` +``iekey`` Set to ignore the existing key -``__u64 crkey`` - The current reservation key to release - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_resv_report (int fd, __u32 nsid, bool eds, __u32 len, struct nvme_reservation_status * report) +.. c:function:: int nvme_resv_register (struct nvme_resv_register_args *args) - Send an nvme reservation report + Send an nvme reservation register **Parameters** -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Namespace identifier - -``bool eds`` - Request extended Data Structure - -``__u32 len`` - Number of bytes to request transfered with this command - -``struct nvme_reservation_status * report`` - The user space destination address to store the reservation report +``struct nvme_resv_register_args *args`` + :c:type:`struct nvme_resv_register_args ` argument structure **Description** -Returns a Reservation Status data structure to memory that describes the -registration and reservation status of a namespace. See the defintion for -the returned structure, :c:type:`struct nvme_reservation_status `, for more details. +The Reservation Register command registers, unregisters, or replaces a +reservation key. **Return** @@ -5205,1137 +5683,3249 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: nvme_subsystem_t nvme_first_subsystem (nvme_root_t r) -**Parameters** +.. c:type:: struct nvme_resv_release_args -``nvme_root_t r`` + Arguments for the NVMe Reservation Release Command +**Definition** -.. c:function:: nvme_subsystem_t nvme_next_subsystem (nvme_root_t r, nvme_subsystem_t s) +:: + 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; + }; -**Parameters** +**Members** -``nvme_root_t r`` - *undescribed* - -``nvme_subsystem_t s`` - - -.. c:function:: nvme_ns_t nvme_ctrl_first_ns (nvme_ctrl_t c) +``crkey`` + The current reservation key to release +``result`` + The command completion result from CQE dword0 -**Parameters** +``args_size`` + Size of :c:type:`struct nvme_resv_release_args ` -``nvme_ctrl_t c`` +``fd`` + File descriptor of nvme device +``timeout`` + Timeout in ms -.. c:function:: nvme_ns_t nvme_ctrl_next_ns (nvme_ctrl_t c, nvme_ns_t n) +``nsid`` + Namespace identifier +``rtype`` + The type of reservation to be create, see :c:type:`enum nvme_resv_rtype ` -**Parameters** +``rrela`` + Reservation releast action, see :c:type:`enum nvme_resv_rrela ` -``nvme_ctrl_t c`` - *undescribed* +``iekey`` + Set to ignore the existing key -``nvme_ns_t n`` -.. c:function:: nvme_path_t nvme_ctrl_first_path (nvme_ctrl_t c) +.. c:function:: int nvme_resv_release (struct nvme_resv_release_args *args) + Send an nvme reservation release **Parameters** -``nvme_ctrl_t c`` - - -.. c:function:: nvme_path_t nvme_ctrl_next_path (nvme_ctrl_t c, nvme_path_t p) +``struct nvme_resv_release_args *args`` + :c:type:`struct nvme_resv_release_args ` argument structure +**Return** -**Parameters** +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -``nvme_ctrl_t c`` - *undescribed* -``nvme_path_t p`` -.. c:function:: nvme_ctrl_t nvme_subsystem_first_ctrl (nvme_subsystem_t s) +.. c:type:: struct nvme_resv_report_args + Arguments for the NVMe Reservation Report command -**Parameters** +**Definition** -``nvme_subsystem_t s`` +:: + 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; + }; -.. c:function:: nvme_ctrl_t nvme_subsystem_next_ctrl (nvme_subsystem_t s, nvme_ctrl_t c) +**Members** +``result`` + The command completion result from CQE dword0 -**Parameters** +``report`` + The user space destination address to store the reservation + report -``nvme_subsystem_t s`` - *undescribed* +``args_size`` + Size of :c:type:`struct nvme_resv_report_args ` -``nvme_ctrl_t c`` +``fd`` + File descriptor of nvme device +``timeout`` + Timeout in ms -.. c:function:: nvme_ns_t nvme_subsystem_first_ns (nvme_subsystem_t s) +``nsid`` + Namespace identifier +``len`` + Number of bytes to request transfered with this command -**Parameters** +``eds`` + Request extended Data Structure -``nvme_subsystem_t s`` -.. c:function:: nvme_ns_t nvme_subsystem_next_ns (nvme_subsystem_t s, nvme_ns_t n) +.. c:function:: int nvme_resv_report (struct nvme_resv_report_args *args) + Send an nvme reservation report **Parameters** -``nvme_subsystem_t s`` - *undescribed* +``struct nvme_resv_report_args *args`` + struct nvme_resv_report_args argument structure -``nvme_ns_t n`` +**Description** +Returns a Reservation Status data structure to memory that describes the +registration and reservation status of a namespace. See the defintion for +the returned structure, :c:type:`struct nvme_reservation_status `, for more details. -.. c:function:: nvme_for_each_subsystem_safe ( r, s, _s) +**Return** +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -**Parameters** -``r`` - *undescribed* -``s`` - *undescribed* -``_s`` - *undescribed* +.. c:type:: struct nvme_zns_mgmt_send_args + Arguments for the NVMe ZNS Management Send command -.. c:function:: nvme_for_each_subsystem ( r, s) +**Definition** +:: -**Parameters** + 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; + }; -``r`` - *undescribed* +**Members** -``s`` - *undescribed* +``slba`` + Starting logical block address +``result`` + The command completion result from CQE dword0 -.. c:function:: nvme_subsystem_for_each_ctrl_safe ( s, c, _c) +``data`` + Userspace address of the data +``args_size`` + Size of :c:type:`struct nvme_zns_mgmt_send_args ` -**Parameters** +``fd`` + File descriptor of nvme device -``s`` - *undescribed* +``timeout`` + timeout in ms -``c`` - *undescribed* +``nsid`` + Namespace ID -``_c`` - *undescribed* +``zsa`` + Zone send action +``data_len`` + Length of **data** -.. c:function:: nvme_subsystem_for_each_ctrl ( s, c) +``select_all`` + Select all flag +``zsaso`` + Zone Send Action Specific Option -**Parameters** -``s`` - *undescribed* -``c`` - *undescribed* +.. c:function:: int nvme_zns_mgmt_send (struct nvme_zns_mgmt_send_args *args) -.. c:function:: nvme_ctrl_for_each_ns_safe ( c, n, _n) +**Parameters** +``struct nvme_zns_mgmt_send_args *args`` + :c:type:`struct nvme_zns_mgmt_send_args ` argument structure -**Parameters** +**Return** -``c`` - *undescribed* +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -``n`` - *undescribed* -``_n`` - *undescribed* -.. c:function:: nvme_ctrl_for_each_ns ( c, n) +.. c:type:: struct nvme_zns_mgmt_recv_args + Arguments for the NVMe ZNS Management Receive command -**Parameters** +**Definition** -``c`` - *undescribed* +:: -``n`` - *undescribed* + 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; + }; +**Members** -.. c:function:: nvme_ctrl_for_each_path_safe ( c, p, _p) +``slba`` + Starting logical block address +``result`` + The command completion result from CQE dword0 -**Parameters** +``data`` + Userspace address of the data -``c`` - *undescribed* +``args_size`` + Size of :c:type:`struct nvme_zns_mgmt_recv_args ` -``p`` - *undescribed* +``fd`` + File descriptor of nvme device -``_p`` - *undescribed* +``timeout`` + timeout in ms +``nsid`` + Namespace ID -.. c:function:: nvme_ctrl_for_each_path ( c, p) +``zra`` + zone receive action +``data_len`` + Length of **data** -**Parameters** +``zrasf`` + Zone receive action specific field -``c`` - *undescribed* +``zras_feat`` + Zone receive action specific features -``p`` - *undescribed* -.. c:function:: nvme_subsystem_for_each_ns_safe ( s, n, _n) +.. c:function:: int nvme_zns_mgmt_recv (struct nvme_zns_mgmt_recv_args *args) **Parameters** -``s`` - *undescribed* +``struct nvme_zns_mgmt_recv_args *args`` + :c:type:`struct nvme_zns_mgmt_recv_args ` argument structure -``n`` - *undescribed* +**Return** -``_n`` - *undescribed* +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: nvme_subsystem_for_each_ns ( s, n) +.. c:function:: int nvme_zns_report_zones (int fd, __u32 nsid, __u64 slba, enum nvme_zns_report_options opts, bool extended, bool partial, __u32 data_len, void *data, __u32 timeout, __u32 *result) + Return the list of zones **Parameters** -``s`` - *undescribed* +``int fd`` + File descriptor of nvme device -``n`` - *undescribed* +``__u32 nsid`` + Namespace ID +``__u64 slba`` + Starting LBA -.. c:function:: int nvme_ns_get_fd (nvme_ns_t n) +``enum nvme_zns_report_options opts`` + Reporting options +``bool extended`` + Extended report -**Parameters** +``bool partial`` + Partial report requested -``nvme_ns_t n`` +``__u32 data_len`` + Length of the data buffer +``void *data`` + Userspace address of the report zones data -.. c:function:: int nvme_ns_get_nsid (nvme_ns_t n) +``__u32 timeout`` + timeout in ms +``__u32 *result`` + The command completion result from CQE dword0 -**Parameters** +**Return** -``nvme_ns_t n`` +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_ns_get_lba_size (nvme_ns_t n) -**Parameters** +.. c:type:: struct nvme_zns_append_args -``nvme_ns_t n`` + Arguments for the NVMe ZNS Append command +**Definition** -.. c:function:: uint64_t nvme_ns_get_lba_count (nvme_ns_t n) +:: + 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; + }; -**Parameters** +**Members** -``nvme_ns_t n`` +``zslba`` + Zone start logical block address +``result`` + The command completion result from CQE dword0 -.. c:function:: uint64_t nvme_ns_get_lba_util (nvme_ns_t n) +``data`` + Userspace address of the data +``metadata`` + Userspace address of the metadata -**Parameters** +``args_size`` + Size of :c:type:`struct nvme_zns_append_args ` -``nvme_ns_t n`` +``fd`` + File descriptor of nvme device +``timeout`` + Timeout in ms -.. c:function:: const char * nvme_ns_get_sysfs_dir (nvme_ns_t n) +``nsid`` + Namespace ID +``ilbrt`` + Initial logical block reference tag -**Parameters** +``data_len`` + Length of **data** -``nvme_ns_t n`` +``metadata_len`` + Length of **metadata** +``nlb`` + Number of logical blocks -.. c:function:: const char * nvme_ns_get_name (nvme_ns_t n) +``control`` +``lbat`` + Logical block application tag -**Parameters** +``lbatm`` + Logical block application tag mask -``nvme_ns_t n`` -.. c:function:: nvme_subsystem_t nvme_ns_get_subsystem (nvme_ns_t n) +.. c:function:: int nvme_zns_append (struct nvme_zns_append_args *args) + Append data to a zone **Parameters** -``nvme_ns_t n`` +``struct nvme_zns_append_args *args`` + :c:type:`struct nvme_zns_append_args ` argument structure +**Return** -.. c:function:: nvme_ctrl_t nvme_ns_get_ctrl (nvme_ns_t n) +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -**Parameters** +.. c:function:: int nvme_fw_download_seq (int fd, __u32 size, __u32 xfer, __u32 offset, void *buf) -``nvme_ns_t n`` +**Parameters** -.. c:function:: int nvme_ns_read (nvme_ns_t n, void * buf, off_t offset, size_t count) +``int fd`` + File descriptor of nvme device +``__u32 size`` + Total size of the firmware image to transfer -**Parameters** +``__u32 xfer`` + Maximum size to send with each partial transfer -``nvme_ns_t n`` - *undescribed* +``__u32 offset`` + Starting offset to send with this firmware downlaod -``void * buf`` - *undescribed* +``void *buf`` + Address of buffer containing all or part of the firmware image. -``off_t offset`` - *undescribed* +**Return** -``size_t count`` +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_ns_write (nvme_ns_t n, void * buf, off_t offset, size_t count) +.. c:function:: int nvme_get_ctrl_telemetry (int fd, bool rae, struct nvme_telemetry_log **log) **Parameters** -``nvme_ns_t n`` - *undescribed* - -``void * buf`` - *undescribed* - -``off_t offset`` - *undescribed* +``int fd`` + File descriptor of nvme device -``size_t count`` +``bool rae`` + Retain asynchronous events +``struct nvme_telemetry_log **log`` + On success, set to the value of the allocated and retreived log. -.. c:function:: int nvme_ns_verify (nvme_ns_t n, off_t offset, size_t count) +**Description** +The total size allocated can be calculated as: + (:c:type:`struct nvme_telemetry_log `.dalb3 + 1) * ``NVME_LOG_TELEM_BLOCK_SIZE``. -**Parameters** +**Return** -``nvme_ns_t n`` - *undescribed* +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -``off_t offset`` - *undescribed* -``size_t count`` +.. c:function:: int nvme_get_host_telemetry (int fd, struct nvme_telemetry_log **log) -.. c:function:: int nvme_ns_compare (nvme_ns_t n, void * buf, off_t offset, size_t count) +**Parameters** +``int fd`` + File descriptor of nvme device -**Parameters** +``struct nvme_telemetry_log **log`` + On success, set to the value of the allocated and retreived log. -``nvme_ns_t n`` - *undescribed* +**Description** -``void * buf`` - *undescribed* +The total size allocated can be calculated as: + (:c:type:`struct nvme_telemetry_log `.dalb3 + 1) * ``NVME_LOG_TELEM_BLOCK_SIZE``. -``off_t offset`` - *undescribed* +**Return** -``size_t count`` +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: int nvme_ns_write_zeros (nvme_ns_t n, off_t offset, size_t count) +.. c:function:: int nvme_get_new_host_telemetry (int fd, struct nvme_telemetry_log **log) **Parameters** -``nvme_ns_t n`` - *undescribed* +``int fd`` + File descriptor of nvme device -``off_t offset`` - *undescribed* +``struct nvme_telemetry_log **log`` + On success, set to the value of the allocated and retreived log. -``size_t count`` +**Description** +The total size allocated can be calculated as: + (:c:type:`struct nvme_telemetry_log `.dalb3 + 1) * ``NVME_LOG_TELEM_BLOCK_SIZE``. -.. c:function:: int nvme_ns_write_uncorrectable (nvme_ns_t n, off_t offset, size_t count) +**Return** +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -**Parameters** -``nvme_ns_t n`` - *undescribed* +.. c:function:: int nvme_get_log_page (int fd, __u32 nsid, __u8 log_id, bool rae, __u32 xfer_len, __u32 data_len, void *data) -``off_t offset`` - *undescribed* -``size_t count`` +**Parameters** +``int fd`` + File descriptor of nvme device -.. c:function:: int nvme_ns_flush (nvme_ns_t n) +``__u32 nsid`` + Namespace Identifier, if applicable. +``__u8 log_id`` + Log Identifier, see :c:type:`enum nvme_cmd_get_log_lid `. -**Parameters** +``bool rae`` + Retain asynchronous events -``nvme_ns_t n`` +``__u32 xfer_len`` + Max log transfer size per request to split the total. +``__u32 data_len`` + Total length of the log to transfer. -.. c:function:: int nvme_ns_identify (nvme_ns_t n, struct nvme_id_ns * ns) +``void *data`` + User address of at least :c:type:`data_len` to store the log. +**Return** -**Parameters** +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -``nvme_ns_t n`` - *undescribed* -``struct nvme_id_ns * ns`` +.. c:function:: int nvme_get_log_page_padded (int fd, __u32 nsid, __u8 log_id, bool rae, __u32 data_len, void *data) -.. c:function:: const char * nvme_path_get_name (nvme_path_t p) +**Parameters** +``int fd`` + File descriptor of nvme device -**Parameters** +``__u32 nsid`` + Namespace Identifier, if applicable. -``nvme_path_t p`` +``__u8 log_id`` + Log Identifier, see :c:type:`enum nvme_cmd_get_log_lid `. +``bool rae`` + Retain asynchronous events -.. c:function:: const char * nvme_path_get_sysfs_dir (nvme_path_t p) +``__u32 data_len`` + Total length of the log to transfer. +``void *data`` + User address of at least :c:type:`data_len` to store the log. -**Parameters** +**Description** -``nvme_path_t p`` +Calls nvme_get_log_page() with a default 4k transfer length, as that is +guarnateed by the protocol to be a safe transfer size. +**Return** -.. c:function:: const char * nvme_path_get_ana_state (nvme_path_t p) +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -**Parameters** +.. c:function:: int nvme_get_ana_log_len (int fd, size_t *analen) -``nvme_path_t p`` + Retreive size of the current ANA log +**Parameters** -.. c:function:: nvme_ctrl_t nvme_path_get_ctrl (nvme_path_t p) +``int fd`` + File descriptor of nvme device +``size_t *analen`` + Pointer to where the length will be set on success -**Parameters** +**Return** -``nvme_path_t p`` +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: nvme_ns_t nvme_path_get_ns (nvme_path_t p) +.. c:function:: int nvme_get_logical_block_size (int fd, __u32 nsid, int *blksize) + Retrieve block size **Parameters** -``nvme_path_t p`` - +``int fd`` + File descriptor of nvme device -.. c:function:: int nvme_ctrl_get_fd (nvme_ctrl_t c) +``__u32 nsid`` + Namespace id +``int *blksize`` + Pointer to where the block size will be set on success -**Parameters** +**Return** -``nvme_ctrl_t c`` +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: const char * nvme_ctrl_get_name (nvme_ctrl_t c) +.. c:function:: int nvme_get_lba_status_log (int fd, bool rae, struct nvme_lba_status_log **log) + Retreive the LBA Status log page **Parameters** -``nvme_ctrl_t c`` +``int fd`` + File descriptor of the nvme device +``bool rae`` + Retain asynchronous events + +``struct nvme_lba_status_log **log`` + On success, set to the value of the allocated and retreived log. -.. c:function:: const char * nvme_ctrl_get_sysfs_dir (nvme_ctrl_t c) +.. c:function:: int nvme_namespace_attach_ctrls (int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist) + + Attach namespace to controller(s) **Parameters** -``nvme_ctrl_t c`` +``int fd`` + File descriptor of nvme device +``__u32 nsid`` + Namespace ID to attach -.. c:function:: const char * nvme_ctrl_get_address (nvme_ctrl_t c) +``__u16 num_ctrls`` + Number of controllers in ctrlist +``__u16 *ctrlist`` + List of controller IDs to perform the attach action -**Parameters** +**Return** -``nvme_ctrl_t c`` +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: const char * nvme_ctrl_get_firmware (nvme_ctrl_t c) +.. c:function:: int nvme_namespace_detach_ctrls (int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist) + Detach namespace from controller(s) **Parameters** -``nvme_ctrl_t c`` +``int fd`` + File descriptor of nvme device +``__u32 nsid`` + Namespace ID to detach -.. c:function:: const char * nvme_ctrl_get_model (nvme_ctrl_t c) +``__u16 num_ctrls`` + Number of controllers in ctrlist +``__u16 *ctrlist`` + List of controller IDs to perform the detach action -**Parameters** +**Return** -``nvme_ctrl_t c`` +The nvme command status if a response was received (see +:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. -.. c:function:: const char * nvme_ctrl_get_state (nvme_ctrl_t c) +.. c:function:: int nvme_open (const char *name) + Open an nvme controller or namespace device **Parameters** -``nvme_ctrl_t c`` - +``const char *name`` + The basename of the device to open -.. c:function:: const char * nvme_ctrl_get_numa_node (nvme_ctrl_t c) +**Description** +This will look for the handle in /dev/ and validate the name and filetype +match linux conventions. -**Parameters** +**Return** -``nvme_ctrl_t c`` +A file descriptor for the device on a successful open, or -1 with +errno set otherwise. -.. c:function:: const char * nvme_ctrl_get_queue_count (nvme_ctrl_t c) -**Parameters** +.. c:type:: enum nvme_hmac_alg -``nvme_ctrl_t c`` + HMAC algorithm +**Constants** -.. c:function:: const char * nvme_ctrl_get_serial (nvme_ctrl_t c) +``NVME_HMAC_ALG_NONE`` + No HMAC algorithm +``NVME_HMAC_ALG_SHA2_256`` + SHA2-256 -**Parameters** +``NVME_HMAC_ALG_SHA2_384`` + SHA2-384 -``nvme_ctrl_t c`` +``NVME_HMAC_ALG_SHA2_512`` + SHA2-512 -.. c:function:: const char * nvme_ctrl_get_sqsize (nvme_ctrl_t c) +.. c:function:: int nvme_gen_dhchap_key (char *hostnqn, enum nvme_hmac_alg hmac, unsigned int key_len, unsigned char *secret, unsigned char *key) + DH-HMAC-CHAP key generation **Parameters** -``nvme_ctrl_t c`` +``char *hostnqn`` + Host NVMe Qualified Name +``enum nvme_hmac_alg hmac`` + HMAC algorithm -.. c:function:: const char * nvme_ctrl_get_transport (nvme_ctrl_t c) +``unsigned int key_len`` + Output key lenght +``unsigned char *secret`` + Secret to used for digest -**Parameters** +``unsigned char *key`` + Generated DH-HMAC-CHAP key -``nvme_ctrl_t c`` +**Return** +If key generation was successful the function returns 0 or +-1 with errno set otherwise. -.. c:function:: const char * nvme_ctrl_get_subsysnqn (nvme_ctrl_t c) +.. c:function:: void nvme_init_logging (nvme_root_t r, int lvl, bool log_pid, bool log_tstamp) + + initialize logging **Parameters** -``nvme_ctrl_t c`` +``nvme_root_t r`` + nvme_root_t context +``int lvl`` + logging level to set -.. c:function:: nvme_subsystem_t nvme_ctrl_get_subsystem (nvme_ctrl_t c) +``bool log_pid`` + boolean to enable logging of the PID +``bool log_tstamp`` + boolean to enable logging of the timestamp -**Parameters** +**Description** -``nvme_ctrl_t c`` +Sets the default logging variables for the library. -.. c:function:: int nvme_ctrl_identify (nvme_ctrl_t c, struct nvme_id_ctrl * id) +.. c:function:: nvme_root_t nvme_create_root (FILE *fp, int log_level) + Initialize root object **Parameters** -``nvme_ctrl_t c`` - *undescribed* +``FILE *fp`` + filedescriptor for logging messages + +``int log_level`` + logging level to use -``struct nvme_id_ctrl * id`` +**Return** + +initialized nvme_root_t object -.. c:function:: int nvme_ctrl_disconnect (nvme_ctrl_t c) +.. c:function:: void nvme_free_tree (nvme_root_t r) + Free root object **Parameters** -``nvme_ctrl_t c`` +``nvme_root_t r`` + nvme_root_t object + +**Description** + +Free an nvme_root_t object and all attached objects -.. c:function:: nvme_ctrl_t nvme_scan_ctrl (const char * name) +.. c:function:: nvme_host_t nvme_first_host (nvme_root_t r) + Start host iterator **Parameters** -``const char * name`` +``nvme_root_t r`` + nvme_root_t object +**Return** -.. c:function:: void nvme_free_ctrl (struct nvme_ctrl * c) +first nvme_host_t object in an iterator -**Parameters** +.. c:function:: nvme_host_t nvme_next_host (nvme_root_t r, nvme_host_t h) -``struct nvme_ctrl * c`` - *undescribed* + Next host iterator +**Parameters** -.. c:function:: void nvme_unlink_ctrl (struct nvme_ctrl * c) +``nvme_root_t r`` + nvme_root_t object +``nvme_host_t h`` + previous nvme_host_t iterator -**Parameters** +**Return** -``struct nvme_ctrl * c`` - *undescribed* +next nvme_host_t object in an iterator -.. c:function:: const char * nvme_subsystem_get_nqn (nvme_subsystem_t s) +.. c:function:: nvme_root_t nvme_host_get_root (nvme_host_t h) + Returns nvme_root_t object **Parameters** -``nvme_subsystem_t s`` +``nvme_host_t h`` + host + +**Return** +nvme_root_t object from **h** -.. c:function:: const char * nvme_subsystem_get_sysfs_dir (nvme_subsystem_t s) +.. c:function:: nvme_host_t nvme_lookup_host (nvme_root_t r, const char *hostnqn, const char *hostid) + + Lookup nvme_host_t object **Parameters** -``nvme_subsystem_t s`` +``nvme_root_t r`` + nvme_root_t object +``const char *hostnqn`` + Host NQN -.. c:function:: const char * nvme_subsystem_get_name (nvme_subsystem_t s) +``const char *hostid`` + Host ID +**Description** -**Parameters** +Lookup a nvme_host_t object based on **hostnqn** and **hostid** +or create one if not found. -``nvme_subsystem_t s`` +**Return** +nvme_host_t object -.. c:function:: nvme_root_t nvme_scan () +.. c:function:: const char * nvme_host_get_hostnqn (nvme_host_t h) + + Returns the host NQN **Parameters** +``nvme_host_t h`` + host -.. c:function:: void nvme_refresh_topology (nvme_root_t r) +**Return** +NVMe host NQN -**Parameters** -``nvme_root_t r`` - *undescribed* +.. c:function:: const char * nvme_host_get_hostid (nvme_host_t h) + Returns the host ID -.. c:function:: void nvme_free_tree (nvme_root_t r) +**Parameters** +``nvme_host_t h`` + host -**Parameters** +**Return** -``nvme_root_t r`` - *undescribed* +NVMe Host ID -.. c:function:: char * nvme_get_subsys_attr (nvme_subsystem_t s, const char * attr) +.. c:function:: const char * nvme_host_get_dhchap_key (nvme_host_t h) + return host key **Parameters** -``nvme_subsystem_t s`` - *undescribed* +``nvme_host_t h`` + Host for which the key should be returned + +**Return** -``const char * attr`` +DH-HMAC-CHAP host key or NULL if not set -.. c:function:: char * nvme_get_ctrl_attr (nvme_ctrl_t c, const char * attr) +.. c:function:: void nvme_host_set_dhchap_key (nvme_host_t h, const char *key) + set host key **Parameters** -``nvme_ctrl_t c`` - *undescribed* +``nvme_host_t h`` + Host for which the key should be set -``const char * attr`` +``const char *key`` + DH-HMAC-CHAP Key to set or NULL to clear existing key -.. c:function:: char * nvme_get_ns_attr (nvme_ns_t n, const char * attr) +.. c:function:: nvme_host_t nvme_default_host (nvme_root_t r) + Initializes the default host **Parameters** -``nvme_ns_t n`` - *undescribed* +``nvme_root_t r`` + nvme_root_t object -``const char * attr`` +**Description** + +Initializes the default host object based on the values in +/etc/nvme/hostnqn and /etc/nvme/hostid and attaches it to **r**. + +**Return** +nvme_host_t object -.. c:function:: char * nvme_get_path_attr (nvme_path_t p, const char * attr) +.. c:function:: nvme_subsystem_t nvme_first_subsystem (nvme_host_t h) + + Start subsystem iterator **Parameters** -``nvme_path_t p`` - *undescribed* +``nvme_host_t h`` + nvme_host_t object + +**Return** -``const char * attr`` +first nvme_subsystem_t object in an iterator -.. c:function:: __le16 cpu_to_le16 (uint16_t x) +.. c:function:: nvme_subsystem_t nvme_next_subsystem (nvme_host_t h, nvme_subsystem_t s) + Next subsystem iterator **Parameters** -``uint16_t x`` - 16-bit CPU value to turn to little endian. +``nvme_host_t h`` + nvme_host_t object +``nvme_subsystem_t s`` + previous nvme_subsystem_t iterator + +**Return** + +next nvme_subsystem_t object in an iterator -.. c:function:: __le32 cpu_to_le32 (uint32_t x) +.. c:function:: nvme_subsystem_t nvme_lookup_subsystem (struct nvme_host *h, const char *name, const char *subsysnqn) + + Lookup nvme_subsystem_t object **Parameters** -``uint32_t x`` - 32-bit CPU value to turn little endian. +``struct nvme_host *h`` + nvme_host_t object + +``const char *name`` + Name of the subsystem (may be NULL) +``const char *subsysnqn`` + Subsystem NQN -.. c:function:: __le64 cpu_to_le64 (uint64_t x) +**Description** +Lookup a nvme_subsystem_t object in **h** base on **name** (if present) +and **subsystemnqn** or create one if not found. -**Parameters** +**Return** -``uint64_t x`` - 64-bit CPU value to turn little endian. +nvme_subsystme_t object -.. c:function:: uint16_t le16_to_cpu (__le16 x) +.. c:function:: void nvme_free_subsystem (struct nvme_subsystem *s) + Free a subsystem **Parameters** -``__le16 x`` - 16-bit little endian value to turn to CPU. +``struct nvme_subsystem *s`` + subsystem + +**Description** + +Frees **s** and all related objects. -.. c:function:: uint32_t le32_to_cpu (__le32 x) +.. c:function:: nvme_host_t nvme_subsystem_get_host (nvme_subsystem_t s) + Returns nvme_host_t object **Parameters** -``__le32 x`` - 32-bit little endian value to turn to CPU. +``nvme_subsystem_t s`` + subsystem + +**Return** + +nvme_host_t object from **s** -.. c:function:: uint64_t le64_to_cpu (__le64 x) +.. c:function:: nvme_ns_t nvme_ctrl_first_ns (nvme_ctrl_t c) + Start namespace iterator **Parameters** -``__le64 x`` - 64-bit little endian value to turn to CPU. +``nvme_ctrl_t c`` + nvme_ctrl_t object +**Return** +first nvme_ns_t object of an **c** iterator -.. c:type:: enum nvme_constants +.. c:function:: nvme_ns_t nvme_ctrl_next_ns (nvme_ctrl_t c, nvme_ns_t n) - A place to stash various constant nvme values + Next namespace iterator -**Constants** +**Parameters** -``NVME_NSID_ALL`` - A broadcast value that is used to specify all - namespaces +``nvme_ctrl_t c`` + nvme_ctrl_t object -``NVME_NSID_NONE`` - The invalid namespace id, for when the nsid - parameter is not used in a command +``nvme_ns_t n`` + previous nvme_ns_t iterator -``NVME_UUID_NONE`` - Use to omit the uuid command parameter +**Return** -``NVME_CNTLID_NONE`` - Use to omit the cntlid command parameter +next nvme_ns_t object of an **c** iterator -``NVME_NVMSETID_NONE`` - Use to omit the nvmsetid command parameter -``NVME_LOG_LSP_NONE`` - Use to omit the log lsp command parameter +.. c:function:: nvme_path_t nvme_ctrl_first_path (nvme_ctrl_t c) -``NVME_LOG_LSI_NONE`` - Use to omit the log lsi command parameter + Start path iterator -``NVME_IDENTIFY_DATA_SIZE`` - The transfer size for nvme identify commands +**Parameters** -``NVME_ID_NVMSET_LIST_MAX`` - The largest possible nvmset index in identify - nvmeset +``nvme_ctrl_t c`` + nvme_ctrl_t object -``NVME_ID_UUID_LIST_MAX`` - The largest possible uuid index in identify - uuid list +**Return** -``NVME_ID_CTRL_LIST_MAX`` - The largest possible controller index in - identify controller list +First nvme_path_t object of an **c** iterator -``NVME_ID_NS_LIST_MAX`` - The largest possible namespace index in - identify namespace list -``NVME_ID_SECONDARY_CTRL_MAX`` - The largest possible secondary controller index - in identify secondary controller +.. c:function:: nvme_path_t nvme_ctrl_next_path (nvme_ctrl_t c, nvme_path_t p) -``NVME_ID_ND_DESCRIPTOR_MAX`` - *undescribed* + Next path iterator -``NVME_FEAT_LBA_RANGE_MAX`` - The largest possible LBA range index in feature - lba range type +**Parameters** -``NVME_LOG_ST_MAX_RESULTS`` - The largest possible self test result index in the - device self test log +``nvme_ctrl_t c`` + nvme_ctrl_t object -``NVME_LOG_TELEM_BLOCK_SIZE`` - Specification defined size of Telemetry Data Blocks +``nvme_path_t p`` + previous nvme_path_t object of an **c** iterator -``NVME_DSM_MAX_RANGES`` - The largest possible range index in a data-set - management command -``NVME_NQN_LENGTH`` - Max length for NVMe Qualified Name. +.. c:function:: nvme_ctrl_t nvme_subsystem_first_ctrl (nvme_subsystem_t s) -``NVMF_TRADDR_SIZE`` - *undescribed* + First ctrl iterator -``NVMF_TSAS_SIZE`` - *undescribed* +**Parameters** -``NVME_NIDT_EUI64_LEN`` - *undescribed* +``nvme_subsystem_t s`` + nvme_subsystem_t object -``NVME_NIDT_NGUID_LEN`` - *undescribed* +**Return** +First nvme_ctrl_t object of an **s** iterator +.. c:function:: nvme_ctrl_t nvme_subsystem_next_ctrl (nvme_subsystem_t s, nvme_ctrl_t c) -.. c:type:: enum nvme_register_offsets + Next ctrl iterator - The nvme controller registers for all transports. This is the layout of BAR0/1 for PCIe, and properties for fabrics. +**Parameters** -**Constants** +``nvme_subsystem_t s`` + nvme_subsystem_t object -``NVME_REG_CAP`` - Controller Capabilities +``nvme_ctrl_t c`` + previous nvme_ctrl_t object of an **s** iterator -``NVME_REG_VS`` - Version +**Return** -``NVME_REG_INTMS`` - Interrupt Mask Set +next nvme_ctrl_t object of an **s** iterator -``NVME_REG_INTMC`` - Interrupt Mask Clear -``NVME_REG_CC`` - Controller Configuration +.. c:function:: 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_REG_CSTS`` - Controller Status + Lookup nvme_ctrl_t object -``NVME_REG_NSSR`` - NVM Subsystem Reset +**Parameters** -``NVME_REG_AQA`` - Admin Queue Attributes +``nvme_subsystem_t s`` + nvme_subsystem_t object -``NVME_REG_ASQ`` - Admin SQ Base Address +``const char *transport`` + transport name -``NVME_REG_ACQ`` - Admin CQ Base Address +``const char *traddr`` + transport address -``NVME_REG_CMBLOC`` - Controller Memory Buffer Location +``const char *host_traddr`` + host transport address -``NVME_REG_CMBSZ`` - Controller Memory Buffer Size +``const char *host_iface`` + host interface name -``NVME_REG_BPINFO`` - Boot Partition Information +``const char *trsvcid`` + transport service identifier -``NVME_REG_BPRSEL`` - Boot Partition Read Select +**Description** -``NVME_REG_BPMBL`` - Boot Partition Memory Buffer Location +Lookup a nvme_ctrl_t object in **s** based on **transport**, **traddr**, +**host_traddr**, **host_iface**, and **trsvcid**. **transport** must be specified, +other fields may be required depending on the transport. A new +object is created if none is found. -``NVME_REG_CMBMSC`` - Controller Memory Buffer Memory Space Control +**Return** -``NVME_REG_CMBSTS`` - Controller Memory Buffer Status +nvme_ctrl_t object -``NVME_REG_PMRCAP`` - Persistent Memory Capabilities -``NVME_REG_PMRCTL`` - Persistent Memory Region Control +.. c:function:: nvme_ctrl_t nvme_create_ctrl (nvme_root_t r, const char *subsysnqn, const char *transport, const char *traddr, const char *host_traddr, const char *host_iface, const char *trsvcid) -``NVME_REG_PMRSTS`` - Persistent Memory Region Status + Allocate an unconnected NVMe controller -``NVME_REG_PMREBS`` - Persistent Memory Region Elasticity Buffer Size +**Parameters** -``NVME_REG_PMRSWTP`` - Memory Region Sustained Write Throughput +``nvme_root_t r`` + NVMe root element -``NVME_REG_PMRMSC`` - Persistent Memory Region Controller Memory Space Control +``const char *subsysnqn`` + Subsystem NQN -``NVME_REG_DBS`` - SQ 0 Tail Doorbell +``const char *transport`` + Transport type +``const char *traddr`` + Transport address -.. c:function:: bool nvme_is_64bit_reg (__u32 offset) +``const char *host_traddr`` + Host transport address - Checks if offset of the controller register is a know 64bit value. +``const char *host_iface`` + Host interface name + +``const char *trsvcid`` + Transport service ID + +**Description** + +Creates an unconnected nvme_ctrl_t object to be used for +nvme_add_ctrl(). + +**Return** + +nvme_ctrl_t object + + +.. c:function:: nvme_ns_t nvme_subsystem_first_ns (nvme_subsystem_t s) + + Start namespace iterator **Parameters** -``__u32 offset`` - Offset of controller register field in bytes +``nvme_subsystem_t s`` + nvme_subsystem_t object -**Description** +**Return** -This function does not care about transport so that the offset is not going -to be checked inside of this function for the unsupported fields in a -specific transport. For example, BPMBL(Boot Partition Memory Buffer -Location) register is not supported by fabrics, but it can be chcked here. +First nvme_ns_t object of an **s** iterator -Returns true if given offset is 64bit register, otherwise it returns false. +.. c:function:: nvme_ns_t nvme_subsystem_next_ns (nvme_subsystem_t s, nvme_ns_t n) + Next namespace iterator +**Parameters** -.. c:type:: enum nvme_psd_flags +``nvme_subsystem_t s`` + nvme_subsystem_t object - Possible flag values in nvme power state descriptor +``nvme_ns_t n`` + previous nvme_ns_t iterator -**Constants** +**Return** -``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. +Next nvme_ns_t object of an **s** iterator -``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. +.. c:function:: nvme_for_each_host_safe (r, h, _h) + Traverse host list +**Parameters** -.. c:type:: enum nvme_psd_ps +``r`` + nvme_root_t object - Known values for :c:type:`struct nvme_psd ` ``ips`` and ``aps``. Use with nvme_psd_power_scale() to extract the power scale field to match this enum. NVME_PSD_IPS_100_MICRO_WATT: 0.0001 watt scale NVME_PSD_IPS_10_MILLI_WATT: 0.01 watt scale +``h`` + nvme_host_t object -**Constants** +``_h`` + temporary nvme_host_t object -``NVME_PSD_PS_100_MICRO_WATT`` - *undescribed* -``NVME_PSD_PS_10_MILLI_WATT`` - *undescribed* +.. c:function:: nvme_for_each_host (r, h) + + Traverse host list +**Parameters** + +``r`` + nvme_root_t object -.. c:function:: unsigned nvme_psd_power_scale (__u8 ps) +``h`` + nvme_host_t object - power scale occupies the upper 3 bits + +.. c:function:: nvme_for_each_subsystem_safe (h, s, _s) + + Traverse subsystems **Parameters** -``__u8 ps`` - *undescribed* +``h`` + nvme_host_t object +``s`` + nvme_subsystem_t object +``_s`` + temporary nvme_subsystem_t object -.. c:type:: enum nvme_psd_workload +.. c:function:: nvme_for_each_subsystem (h, s) - Specifies a workload hint in the Power Management Feature (see :c:type:`struct nvme_psd `.apw) to inform the NVM subsystem or indicate the conditions for the active power level. + Traverse subsystems -**Constants** +**Parameters** -``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. +``h`` + nvme_host_t object -``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 - NVM subsystem are idle. The submission queue(s) - should be sufficiently large allowing the host to - ensure there are multiple commands pending at all - times during the workload. +``s`` + nvme_subsystem_t object +.. c:function:: nvme_subsystem_for_each_ctrl_safe (s, c, _c) + Traverse controllers -.. c:type:: struct nvme_id_psd +**Parameters** +``s`` + nvme_subsystem_t object -**Definition** +``c`` + nvme_ctrl_t object -:: +``_c`` + temporary nvme_ctrl_t object - struct nvme_id_psd { - __le16 mp; - __u8 rsvd2; - __u8 flags; - __le32 enlat; - __le32 exlat; - __u8 rrt; - __u8 rrl; - __u8 rwt; - __u8 rwl; - __le16 idlp; - __u8 ips; - __u8 rsvd19; - __le16 actp; - __u8 apws; - __u8 rsvd23[9]; - }; -**Members** +.. c:function:: nvme_subsystem_for_each_ctrl (s, c) -``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 :c:type:`enum nvme_psd_flags `). A value of 0 indicates - Maximum Power is not reported. + traverse controllers -``flags`` - Additional decoding flags, see :c:type:`enum nvme_psd_flags `. +**Parameters** -``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. +``s`` + nvme_subsystem_t object -``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. +``c`` + nvme_ctrl_t object -``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. +.. c:function:: nvme_ctrl_for_each_ns_safe (c, n, _n) -``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 + traverse namespaces -``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 +**Parameters** -``idlp`` - Idle Power indicates the typical power consumed by the NVM - subsystem over 30 seconds in this power state when idle. +``c`` + nvme_ctrl_t object -``ips`` - Idle Power Scale indicates the scale for :c:type:`struct nvme_id_psd `.idlp, - see :c:type:`enum nvme_psd_ps ` for decoding this field. +``n`` + nvme_ns_t object -``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. +``_n`` + temporary nvme_ns_t object -``apws`` - Bits 7-6: Active Power Scale(APS) indicates the scale for the :c:type:`struct - nvme_id_psd `.actp, see :c:type:`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 :c:type:`enum nvme_psd_workload ` for - decoding this field. +.. c:function:: nvme_ctrl_for_each_ns (c, n) + traverse namespaces +**Parameters** +``c`` + nvme_ctrl_t object -.. c:type:: struct nvme_id_ctrl +``n`` + nvme_ns_t object - Identify Controller data structure -**Definition** +.. c:function:: nvme_ctrl_for_each_path_safe (c, p, _p) -:: + Traverse paths - struct nvme_id_ctrl { - __le16 vid; - __le16 ssvid; - char sn[20]; - char mn[40]; - char fr[8]; - __u8 rab; - __u8 ieee[3]; - __u8 cmic; - __u8 mdts; - __le16 cntlid; +**Parameters** + +``c`` + nvme_ctrl_t object + +``p`` + nvme_path_t object + +``_p`` + temporary nvme_path_t object + + +.. c:function:: nvme_ctrl_for_each_path (c, p) + + Traverse paths + +**Parameters** + +``c`` + nvme_ctrl_t object + +``p`` + nvme_path_t object + + +.. c:function:: nvme_subsystem_for_each_ns_safe (s, n, _n) + + Traverse namespaces + +**Parameters** + +``s`` + nvme_subsystem_t object + +``n`` + nvme_ns_t object + +``_n`` + temporary nvme_ns_t object + + +.. c:function:: nvme_subsystem_for_each_ns (s, n) + + Traverse namespaces + +**Parameters** + +``s`` + nvme_subsystem_t object + +``n`` + nvme_ns_t object + + +.. c:function:: int nvme_ns_get_fd (nvme_ns_t n) + + Get associated filedescriptor + +**Parameters** + +``nvme_ns_t n`` + nvme_ns_t object + +**Return** + +Filedescriptor associated with **n** or -1 + + +.. c:function:: int nvme_ns_get_nsid (nvme_ns_t n) + + NSID of an nvme_ns_t object + +**Parameters** + +``nvme_ns_t n`` + nvme_ns_t object + +**Return** + +NSID of **n** + + +.. c:function:: int nvme_ns_get_lba_size (nvme_ns_t n) + + LBA size of an nvme_ns_t object + +**Parameters** + +``nvme_ns_t n`` + nvme_ns_t object + +**Return** + +LBA size of **n** + + +.. c:function:: int nvme_ns_get_meta_size (nvme_ns_t n) + + Metadata size of an nvme_ns_t object + +**Parameters** + +``nvme_ns_t n`` + nvme_ns_t object + +**Return** + +Metadata size of **n** + + +.. c:function:: uint64_t nvme_ns_get_lba_count (nvme_ns_t n) + + LBA count of an nvme_ns_t object + +**Parameters** + +``nvme_ns_t n`` + nvme_ns_t object + +**Return** + +LBA count of **n** + + +.. c:function:: uint64_t nvme_ns_get_lba_util (nvme_ns_t n) + + LBA utilisation of an nvme_ns_t object + +**Parameters** + +``nvme_ns_t n`` + nvme_ns_t object + +**Return** + +LBA utilisation of **n** + + +.. c:function:: enum nvme_csi nvme_ns_get_csi (nvme_ns_t n) + + Command set identifier of an nvme_ns_t object + +**Parameters** + +``nvme_ns_t n`` + nvme_ns_t object + +**Return** + +The namespace's command set identifier in use + + +.. c:function:: const uint8_t * nvme_ns_get_eui64 (nvme_ns_t n) + + 64-bit eui of an nvme_ns_t object + +**Parameters** + +``nvme_ns_t n`` + nvme_ns_t object + +**Description** + +Returns a pointer to the 64-bit eui + + +.. c:function:: const uint8_t * nvme_ns_get_nguid (nvme_ns_t n) + + 128-bit nguid of an nvme_ns_t object + +**Parameters** + +``nvme_ns_t n`` + nvme_ns_t object + +**Description** + +Returns a pointer to the 128-bit nguid + + +.. c:function:: void nvme_ns_get_uuid (nvme_ns_t n, uuid_t out) + + UUID of an nvme_ns_t object + +**Parameters** + +``nvme_ns_t n`` + nvme_ns_t object + +``uuid_t out`` + buffer for the UUID + +**Description** + +Copies the namespace's uuid into **out** + + +.. c:function:: const char * nvme_ns_get_sysfs_dir (nvme_ns_t n) + + sysfs directory of an nvme_ns_t object + +**Parameters** + +``nvme_ns_t n`` + nvme_ns_t object + +**Return** + +sysfs directory name of **n** + + +.. c:function:: const char * nvme_ns_get_name (nvme_ns_t n) + + sysfs name of an nvme_ns_t object + +**Parameters** + +``nvme_ns_t n`` + nvme_ns_t object + +**Return** + +sysfs name of **n** + + +.. c:function:: const char * nvme_ns_get_generic_name (nvme_ns_t n) + + Returns name of generic namesapce chardev. + +**Parameters** + +``nvme_ns_t n`` + Namespace instance + +**Return** + +Name of generic namespace chardev + + +.. c:function:: const char * nvme_ns_get_firmware (nvme_ns_t n) + + Firmware string of an nvme_ns_t object + +**Parameters** + +``nvme_ns_t n`` + nvme_ns_t object + +**Return** + +Firmware string of **n** + + +.. c:function:: const char * nvme_ns_get_serial (nvme_ns_t n) + + Serial number of an nvme_ns_t object + +**Parameters** + +``nvme_ns_t n`` + nvme_ns_t object + +**Return** + +Serial number string of **n** + + +.. c:function:: const char * nvme_ns_get_model (nvme_ns_t n) + + Model of an nvme_ns_t object + +**Parameters** + +``nvme_ns_t n`` + nvme_ns_t object + +**Return** + +Model string of **n** + + +.. c:function:: nvme_subsystem_t nvme_ns_get_subsystem (nvme_ns_t n) + + nvme_subsystem_t of an nvme_ns_t object + +**Parameters** + +``nvme_ns_t n`` + nvme_ns_t object + +**Return** + +nvme_subsystem_t object of **n** + + +.. c:function:: nvme_ctrl_t nvme_ns_get_ctrl (nvme_ns_t n) + + nvme_ctrl_t of an nvme_ns_t object + +**Parameters** + +``nvme_ns_t n`` + nvme_ns_t object + +**Description** + +nvme_ctrl_t object may be NULL for a multipathed namespace + +**Return** + +nvme_ctrl_t object of **n** if present + + +.. c:function:: void nvme_free_ns (struct nvme_ns *n) + + free an nvme_ns_t object + +**Parameters** + +``struct nvme_ns *n`` + nvme_ns_t object + + +.. c:function:: int nvme_ns_read (nvme_ns_t n, void *buf, off_t offset, size_t count) + + Read from a namespace + +**Parameters** + +``nvme_ns_t n`` + nvme_ns_t object + +``void *buf`` + buffer into which the data will be transferred + +``off_t offset`` + LBA offset of **n** + +``size_t count`` + Number of sectors in **buf** + +**Return** + +Number of sectors read or -1 on error. + + +.. c:function:: int nvme_ns_write (nvme_ns_t n, void *buf, off_t offset, size_t count) + + Write to a namespace + +**Parameters** + +``nvme_ns_t n`` + nvme_ns_t object + +``void *buf`` + buffer with data to be written + +``off_t offset`` + LBA offset of **n** + +``size_t count`` + Number of sectors in **buf** + +**Return** + +Number of sectors written or -1 on error + + +.. c:function:: int nvme_ns_verify (nvme_ns_t n, off_t offset, size_t count) + + Verify data on a namespace + +**Parameters** + +``nvme_ns_t n`` + nvme_ns_t object + +``off_t offset`` + LBA offset of **n** + +``size_t count`` + Number of sectors to be verified + +**Return** + +Number of sectors verified + + +.. c:function:: int nvme_ns_compare (nvme_ns_t n, void *buf, off_t offset, size_t count) + + Compare data on a namespace + +**Parameters** + +``nvme_ns_t n`` + nvme_ns_t object + +``void *buf`` + buffer with data to be compared + +``off_t offset`` + LBA offset of **n** + +``size_t count`` + Number of sectors in **buf** + +**Return** + +Number of sectors compared + + +.. c:function:: int nvme_ns_write_zeros (nvme_ns_t n, off_t offset, size_t count) + + Write zeros to a namespace + +**Parameters** + +``nvme_ns_t n`` + nvme_ns_t object + +``off_t offset`` + LBA offset in **n** + +``size_t count`` + Number of sectors to be written + +**Return** + +Number of sectors written + + +.. c:function:: int nvme_ns_write_uncorrectable (nvme_ns_t n, off_t offset, size_t count) + + Issus a 'write uncorrectable' command + +**Parameters** + +``nvme_ns_t n`` + nvme_ns_t object + +``off_t offset`` + LBA offset in **n** + +``size_t count`` + Number of sectors to be written + +**Return** + +Number of sectors written + + +.. c:function:: int nvme_ns_flush (nvme_ns_t n) + + Flush data to a namespace + +**Parameters** + +``nvme_ns_t n`` + nvme_ns_t object + +**Return** + +0 on success, -1 on error. + + +.. c:function:: int nvme_ns_identify (nvme_ns_t n, struct nvme_id_ns *ns) + + Issue an 'identify namespace' command + +**Parameters** + +``nvme_ns_t n`` + nvme_ns_t object + +``struct nvme_id_ns *ns`` + nvme_id_ns buffer + +**Description** + +Writes the data returned by the 'identify namespace' command +into **ns**. + +**Return** + +0 on success, -1 on error. + + +.. c:function:: int nvme_ns_identify_descs (nvme_ns_t n, struct nvme_ns_id_desc *descs) + + Issue an 'identify descriptors' command + +**Parameters** + +``nvme_ns_t n`` + nvme_ns_t object + +``struct nvme_ns_id_desc *descs`` + list of identify descriptors + +**Description** + +Writes the data returned by the 'identify descriptors' command +into **descs**. + +**Return** + +0 on success, -1 on error. + + +.. c:function:: const char * nvme_path_get_name (nvme_path_t p) + + sysfs name of an nvme_path_t object + +**Parameters** + +``nvme_path_t p`` + nvme_path_t object + +**Return** + +sysfs name of **p** + + +.. c:function:: const char * nvme_path_get_sysfs_dir (nvme_path_t p) + + sysfs directory of an nvme_path_t object + +**Parameters** + +``nvme_path_t p`` + nvme_path_t object + +**Return** + +sysfs directory of **p** + + +.. c:function:: const char * nvme_path_get_ana_state (nvme_path_t p) + + ANA state of an nvme_path_t object + +**Parameters** + +``nvme_path_t p`` + nvme_path_t object + +**Return** + +ANA (Asynchronous Namespace Access) state of **p** + + +.. c:function:: nvme_ctrl_t nvme_path_get_ctrl (nvme_path_t p) + + parent controller of an nvme_path_t object + +**Parameters** + +``nvme_path_t p`` + nvme_path_t object + +**Return** + +parent controller if present + + +.. c:function:: nvme_ns_t nvme_path_get_ns (nvme_path_t p) + + parent namespace of an nvme_path_t object + +**Parameters** + +``nvme_path_t p`` + nvme_path_t object + +**Return** + +parent namespace if present + + +.. c:function:: int nvme_ctrl_get_fd (nvme_ctrl_t c) + + Get associated filedescriptor + +**Parameters** + +``nvme_ctrl_t c`` + nvme_ctrl_t object + +**Return** + +Filedescriptor associated with **c** or -1 + + +.. c:function:: const char * nvme_ctrl_get_name (nvme_ctrl_t c) + + sysfs name of an nvme_ctrl_t object + +**Parameters** + +``nvme_ctrl_t c`` + nvme_ctrl_t object + +**Return** + +sysfs name of **c** + + +.. c:function:: const char * nvme_ctrl_get_sysfs_dir (nvme_ctrl_t c) + + sysfs directory of an nvme_ctrl_t object + +**Parameters** + +``nvme_ctrl_t c`` + nvme_ctrl_t object + +**Return** + +sysfs directory name of **c** + + +.. c:function:: const char * nvme_ctrl_get_address (nvme_ctrl_t c) + + Address string of an nvme_ctrl_t + +**Parameters** + +``nvme_ctrl_t c`` + nvme_ctrl_t object + +**Return** + +NVMe-over-Fabrics address string of **c** + + +.. c:function:: const char * nvme_ctrl_get_firmware (nvme_ctrl_t c) + + Firmware string of an nvme_ctrl_t object + +**Parameters** + +``nvme_ctrl_t c`` + nvme_ctrl_t object + +**Return** + +Firmware string of **c** + + +.. c:function:: const char * nvme_ctrl_get_model (nvme_ctrl_t c) + + Model of an nvme_ctrl_t object + +**Parameters** + +``nvme_ctrl_t c`` + nvme_ctrl_t object + +**Return** + +Model string of **c** + + +.. c:function:: const char * nvme_ctrl_get_state (nvme_ctrl_t c) + + Running state of an nvme_ctrl_t object + +**Parameters** + +``nvme_ctrl_t c`` + nvme_ctrl_t object + +**Return** + +string indicating the running state of **c** + + +.. c:function:: const char * nvme_ctrl_get_numa_node (nvme_ctrl_t c) + + NUMA node of an nvme_ctrl_t object + +**Parameters** + +``nvme_ctrl_t c`` + nvme_ctrl_t object + +**Return** + +string indicating the NUMA node + + +.. c:function:: const char * nvme_ctrl_get_queue_count (nvme_ctrl_t c) + + Queue count of an nvme_ctrl_t object + +**Parameters** + +``nvme_ctrl_t c`` + nvme_ctrl_t object + +**Return** + +Queue count of **c** + + +.. c:function:: const char * nvme_ctrl_get_serial (nvme_ctrl_t c) + + Serial number of an nvme_ctrl_t object + +**Parameters** + +``nvme_ctrl_t c`` + nvme_ctrl_t object + +**Return** + +Serial number string of **c** + + +.. c:function:: const char * nvme_ctrl_get_sqsize (nvme_ctrl_t c) + + SQ size of an nvme_ctrl_t object + +**Parameters** + +``nvme_ctrl_t c`` + nvme_ctrl_t object + +**Return** + +SQ size (as string) of **c** + + +.. c:function:: const char * nvme_ctrl_get_transport (nvme_ctrl_t c) + + Transport type of an nvme_ctrl_t object + +**Parameters** + +``nvme_ctrl_t c`` + nvme_ctrl_t object + +**Return** + +Transport type of **c** + + +.. c:function:: const char * nvme_ctrl_get_subsysnqn (nvme_ctrl_t c) + + Subsystem NQN of an nvme_ctrl_t object + +**Parameters** + +``nvme_ctrl_t c`` + nvme_ctrl_t object + +**Return** + +Subsystem NQN of **c** + + +.. c:function:: nvme_subsystem_t nvme_ctrl_get_subsystem (nvme_ctrl_t c) + + Parent subsystem of an nvme_ctrl_t object + +**Parameters** + +``nvme_ctrl_t c`` + nvme_ctrl_t object + +**Return** + +Parent nvme_subsystem_t object + + +.. c:function:: const char * nvme_ctrl_get_traddr (nvme_ctrl_t c) + + Transport address of an nvme_ctrl_t object + +**Parameters** + +``nvme_ctrl_t c`` + nvme_ctrl_t object + +**Return** + +Transport address of **c** + + +.. c:function:: const char * nvme_ctrl_get_trsvcid (nvme_ctrl_t c) + + Transport service identifier of an nvme_ctrl_t object + +**Parameters** + +``nvme_ctrl_t c`` + nvme_ctrl_t object + +**Return** + +Transport service identifier of **c** (if present) + + +.. c:function:: const char * nvme_ctrl_get_host_traddr (nvme_ctrl_t c) + + Host transport address of an nvme_ctrl_t object + +**Parameters** + +``nvme_ctrl_t c`` + nvme_ctrl_t object + +**Return** + +Host transport address of **c** (if present) + + +.. c:function:: const char * nvme_ctrl_get_host_iface (nvme_ctrl_t c) + + Host interface name of an nvme_ctrl_t object + +**Parameters** + +``nvme_ctrl_t c`` + nvme_ctrl_t object + +**Return** + +Host interface name of **c** (if present) + + +.. c:function:: const char * nvme_ctrl_get_dhchap_key (nvme_ctrl_t c) + + return controller key + +**Parameters** + +``nvme_ctrl_t c`` + controller for which the key should be returned + +**Return** + +DH-HMAC-CHAP controller key or NULL if not set + + +.. c:function:: void nvme_ctrl_set_dhchap_key (nvme_ctrl_t c, const char *key) + + set controller key + +**Parameters** + +``nvme_ctrl_t c`` + Controller for which the key should be set + +``const char *key`` + DH-HMAC-CHAP Key to set or NULL to clear existing key + + +.. c:function:: struct nvme_fabrics_config * nvme_ctrl_get_config (nvme_ctrl_t c) + + Fabrics configuration of an nvme_ctrl_t object + +**Parameters** + +``nvme_ctrl_t c`` + nvme_ctrl_t object + +**Return** + +Fabrics configuration of **c** + + +.. c:function:: void nvme_ctrl_set_discovered (nvme_ctrl_t c, bool discovered) + + Set the 'discovered' flag + +**Parameters** + +``nvme_ctrl_t c`` + nvme_ctrl_t object + +``bool discovered`` + value of the 'discovered' flag + +**Description** + +Set the 'discovered' flag of **c** to **discovered** + + +.. c:function:: bool nvme_ctrl_is_discovered (nvme_ctrl_t c) + + Returns the value of the 'discovered' flag + +**Parameters** + +``nvme_ctrl_t c`` + nvme_ctrl_t object + +**Return** + +Value of the 'discovered' flag of **c** + + +.. c:function:: void nvme_ctrl_set_persistent (nvme_ctrl_t c, bool persistent) + + Set the 'persistent' flag + +**Parameters** + +``nvme_ctrl_t c`` + nvme_ctrl_t object + +``bool persistent`` + value of the 'persistent' flag + +**Description** + +Set the 'persistent' flag of **c** to **persistent** + + +.. c:function:: bool nvme_ctrl_is_persistent (nvme_ctrl_t c) + + Returns the value of the 'persistent' flag + +**Parameters** + +``nvme_ctrl_t c`` + nvme_ctrl_t object + +**Return** + +Value of the 'persistent' flag of **c** + + +.. c:function:: void nvme_ctrl_set_discovery_ctrl (nvme_ctrl_t c, bool discovery) + + Set the 'discovery_ctrl' flag + +**Parameters** + +``nvme_ctrl_t c`` + Controller to be modified + +``bool discovery`` + value of the discovery_ctrl flag + +**Description** + +Sets the 'discovery_ctrl' flag in **c** to specify whether +**c** connects to a discovery subsystem. + + +.. c:function:: bool nvme_ctrl_is_discovery_ctrl (nvme_ctrl_t c) + + Check the 'discovery_ctrl' flag + +**Parameters** + +``nvme_ctrl_t c`` + Controller to be checked + +**Description** + +Returns the value of the 'discovery_ctrl' flag which specifies whether +**c** connects to a discovery subsystem. + +**Return** + +value of the 'discover_ctrl' flag + + +.. c:function:: int nvme_ctrl_identify (nvme_ctrl_t c, struct nvme_id_ctrl *id) + + Issues an 'identify controller' command + +**Parameters** + +``nvme_ctrl_t c`` + nvme_ctrl_t object + +``struct nvme_id_ctrl *id`` + identify controller data structure + +**Description** + +Issues an 'identify controller' command to **c** and copies the +data into **id**. + +**Return** + +0 on success or -1 on failure. + + +.. c:function:: int nvme_disconnect_ctrl (nvme_ctrl_t c) + + Disconnect a controller + +**Parameters** + +``nvme_ctrl_t c`` + nvme_ctrl_t object + +**Description** + +Issues a 'disconnect' fabrics command to **c** + +**Return** + +0 on success, -1 on failure. + + +.. c:function:: nvme_ctrl_t nvme_scan_ctrl (nvme_root_t r, const char *name) + + Scan on a controller + +**Parameters** + +``nvme_root_t r`` + nvme_root_t object + +``const char *name`` + name of the controller + +**Description** + +Scans a controller with sysfs name **name** and add it to **r**. + +**Return** + +nvme_ctrl_t object + + +.. c:function:: void nvme_rescan_ctrl (nvme_ctrl_t c) + + Rescan an existing nvme_ctrl_t object + +**Parameters** + +``nvme_ctrl_t c`` + nvme_ctrl_t object + + +.. c:function:: int nvme_init_ctrl (nvme_host_t h, nvme_ctrl_t c, int instance) + + Initialize nvme_ctrl_t object for an existing nvme controller. + +**Parameters** + +``nvme_host_t h`` + nvme_host_t object + +``nvme_ctrl_t c`` + nvme_ctrl_t object + +``int instance`` + Instance number (e.g. 1 for nvme1) + +**Return** + +The ioctl() return code. Typically 0 on success. + + +.. c:function:: void nvme_free_ctrl (struct nvme_ctrl *c) + + +**Parameters** + +``struct nvme_ctrl *c`` + + +.. c:function:: void nvme_unlink_ctrl (struct nvme_ctrl *c) + + +**Parameters** + +``struct nvme_ctrl *c`` + + +.. c:function:: const char * nvme_subsystem_get_nqn (nvme_subsystem_t s) + + +**Parameters** + +``nvme_subsystem_t s`` + + +.. c:function:: const char * nvme_subsystem_get_sysfs_dir (nvme_subsystem_t s) + + sysfs directory of an nvme_subsystem_t object + +**Parameters** + +``nvme_subsystem_t s`` + nvme_subsystem_t object + +**Return** + +sysfs directory name of **s** + + +.. c:function:: const char * nvme_subsystem_get_name (nvme_subsystem_t s) + + sysfs name of an nvme_subsystem_t object + +**Parameters** + +``nvme_subsystem_t s`` + nvme_subsystem_t object + +**Return** + +sysfs name of **s** + + +.. c:function:: const char * nvme_subsystem_get_type (nvme_subsystem_t s) + + Returns the type of a subsystem + +**Parameters** + +``nvme_subsystem_t s`` + Subsystem + +**Description** + +Returns the subsystem type of **s**. + +**Return** + +'nvm' or 'discovery' + + +.. c:function:: int nvme_scan_topology (nvme_root_t r, nvme_scan_filter_t f) + + Scan NVMe topology and apply filter + +**Parameters** + +``nvme_root_t r`` + nvme_root_t object + +``nvme_scan_filter_t f`` + filter to apply + +**Description** + +Scans the NVMe topology and filters out the resulting elements +by applying **f**. + +**Return** + +Number of elements scanned + + +.. c:function:: const char * nvme_host_get_hostnqn (nvme_host_t h) + + Host NQN of an nvme_host_t object + +**Parameters** + +``nvme_host_t h`` + nvme_host_t object + +**Return** + +Host NQN of **h** + + +.. c:function:: const char * nvme_host_get_hostid (nvme_host_t h) + + Host ID of an nvme_host_t object + +**Parameters** + +``nvme_host_t h`` + nvme_host_t object + +**Return** + +Host ID of **h** + + +.. c:function:: void nvme_free_host (nvme_host_t h) + + Free nvme_host_t object + +**Parameters** + +``nvme_host_t h`` + nvme_host_t object + + +.. c:function:: nvme_root_t nvme_scan (const char *config_file) + + Scan NVMe topology + +**Parameters** + +``const char *config_file`` + configuration file + +**Return** + +nvme_root_t object of found elements + + +.. c:function:: void nvme_read_config (nvme_root_t r, const char *config_file) + + Read NVMe json configuration file + +**Parameters** + +``nvme_root_t r`` + nvme_root_t object + +``const char *config_file`` + json configuration file + +**Description** + +Read in the contents of **config_file** and merge them with +the elements in **r**. + + +.. c:function:: void nvme_refresh_topology (nvme_root_t r) + + refresh nvme_root_t object contents + +**Parameters** + +``nvme_root_t r`` + nvme_root_t object + +**Description** + +Removes all elements in **r** and rescans the existing topology. + + +.. c:function:: int nvme_update_config (nvme_root_t r) + + Update JSON configuration + +**Parameters** + +``nvme_root_t r`` + nvme_root_t object + +**Description** + +Updates the JSON configuration file with the contents of **r**. + +**Return** + +0 on success, -1 on failure. + + +.. c:function:: int nvme_dump_config (nvme_root_t r) + + Print the JSON configuration + +**Parameters** + +``nvme_root_t r`` + nvme_root_t object + +**Description** + +Prints the current contents of the JSON configuration +file to stdout. + +**Return** + +0 on success, -1 on failure. + + +.. c:function:: char * nvme_get_attr (const char *d, const char *attr) + + Read sysfs attribute + +**Parameters** + +``const char *d`` + sysfs directory + +``const char *attr`` + sysfs attribute name + +**Return** + +string with the contents of **attr** + + +.. c:function:: char * nvme_get_subsys_attr (nvme_subsystem_t s, const char *attr) + + Read subsystem sysfs attribute + +**Parameters** + +``nvme_subsystem_t s`` + nvme_subsystem_t object + +``const char *attr`` + sysfs attribute name + +**Return** + +string with the contents of **attr** + + +.. c:function:: char * nvme_get_ctrl_attr (nvme_ctrl_t c, const char *attr) + + Read controller sysfs attribute + +**Parameters** + +``nvme_ctrl_t c`` + nvme_ctrl_t object + +``const char *attr`` + sysfs attribute name + +**Return** + +string with the contents of **attr** + + +.. c:function:: char * nvme_get_ns_attr (nvme_ns_t n, const char *attr) + + Read namespace sysfs attribute + +**Parameters** + +``nvme_ns_t n`` + nvme_ns_t object + +``const char *attr`` + sysfs attribute name + +**Return** + +string with the contents of **attr** + + +.. c:function:: nvme_ns_t nvme_subsystem_lookup_namespace (struct nvme_subsystem *s, __u32 nsid) + + lookup namespace by NSID + +**Parameters** + +``struct nvme_subsystem *s`` + nvme_subsystem_t object + +``__u32 nsid`` + namespace id + +**Return** + +nvme_ns_t of the namespace with id **nsid** in subsystem **s** + + +.. c:function:: char * nvme_get_path_attr (nvme_path_t p, const char *attr) + + Read path sysfs attribute + +**Parameters** + +``nvme_path_t p`` + nvme_path_t object + +``const char *attr`` + sysfs attribute name + +**Return** + +string with the contents of **attr** + + +.. c:function:: nvme_ns_t nvme_scan_namespace (const char *name) + + scan namespace based on sysfs name + +**Parameters** + +``const char *name`` + sysfs name of the namespace to scan + +**Return** + +nvme_ns_t object or NULL if not found. + + +.. c:function:: NVME_GET (value, name) + + extract field from complex value + +**Parameters** + +``value`` + The original value of a complex field + +``name`` + The name of the sub-field within an nvme value + +**Description** + +By convention, this library defines _SHIFT and _MASK such that mask can be +applied after the shift to isolate a specific set of bits that decode to a +sub-field. + +**Return** + +The 'name' field from 'value' + + +.. c:function:: NVME_SET (value, name) + + set field into complex value + +**Parameters** + +``value`` + The value to be set in its completed position + +``name`` + The name of the sub-field within an nvme value + +**Return** + +The + + + + +.. c:type:: enum nvme_constants + + A place to stash various constant nvme values + +**Constants** + +``NVME_NSID_ALL`` + A broadcast value that is used to specify all + namespaces + +``NVME_NSID_NONE`` + The invalid namespace id, for when the nsid + 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_NVMSETID_NONE`` + Use to omit a nvmsetid command parameter + +``NVME_DOMID_NONE`` + Use to omit a domid 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 + log pages log. + +``NVME_ID_NVMSET_LIST_MAX`` + The largest possible nvmset index in identify + nvmeset + +``NVME_ID_UUID_LIST_MAX`` + The largest possible uuid index in identify + uuid list + +``NVME_ID_CTRL_LIST_MAX`` + The largest possible controller index in + identify controller list + +``NVME_ID_NS_LIST_MAX`` + The largest possible namespace index in + identify namespace list + +``NVME_ID_SECONDARY_CTRL_MAX`` + The largest possible secondary controller index + 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 + index in the endurance group list + +``NVME_ID_ND_DESCRIPTOR_MAX`` + The largest possible namespace granularity + index in the namespace granularity descriptor + list + +``NVME_FEAT_LBA_RANGE_MAX`` + The largest possible LBA range index in feature + lba range type + +``NVME_LOG_ST_MAX_RESULTS`` + The largest possible self test result index in the + device self test log + +``NVME_LOG_TELEM_BLOCK_SIZE`` + Specification defined size of Telemetry Data Blocks + +``NVME_LOG_FID_SUPPORTED_EFFECTS_MAX`` + The largest possible FID index in the + feature identifiers effects log. + +``NVME_DSM_MAX_RANGES`` + The largest possible range index in a data-set + 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 + +``NVME_ZNS_CHANGED_ZONES_MAX`` + Max number of zones in the changed zones log + page + + + + +.. c:type:: enum nvme_csi + + Defined command set indicators + +**Constants** + +``NVME_CSI_NVM`` + NVM Command Set Indicator + +``NVME_CSI_ZNS`` + Zoned Namespace Command Set + + + + +.. c:type:: enum nvme_register_offsets + + controller registers for all transports. This is the layout of BAR0/1 for PCIe, and properties for fabrics. + +**Constants** + +``NVME_REG_CAP`` + Controller Capabilities + +``NVME_REG_VS`` + Version + +``NVME_REG_INTMS`` + Interrupt Mask Set + +``NVME_REG_INTMC`` + Interrupt Mask Clear + +``NVME_REG_CC`` + Controller Configuration + +``NVME_REG_CSTS`` + Controller Status + +``NVME_REG_NSSR`` + NVM Subsystem Reset + +``NVME_REG_AQA`` + Admin Queue Attributes + +``NVME_REG_ASQ`` + Admin SQ Base Address + +``NVME_REG_ACQ`` + Admin CQ Base Address + +``NVME_REG_CMBLOC`` + Controller Memory Buffer Location + +``NVME_REG_CMBSZ`` + Controller Memory Buffer Size + +``NVME_REG_BPINFO`` + Boot Partition Information + +``NVME_REG_BPRSEL`` + Boot Partition Read Select + +``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_PMRCAP`` + Persistent Memory Capabilities + +``NVME_REG_PMRCTL`` + Persistent Memory Region Control + +``NVME_REG_PMRSTS`` + Persistent Memory Region Status + +``NVME_REG_PMREBS`` + Persistent Memory Region Elasticity Buffer Size + +``NVME_REG_PMRSWTP`` + Memory Region Sustained Write Throughput + +``NVME_REG_PMRMSCL`` + Persistent Memory Region Controller Memory Space Control Lower + +``NVME_REG_PMRMSCU`` + Persistent Memory Region Controller Memory Space Control Upper + + +.. c:function:: bool nvme_is_64bit_reg (__u32 offset) + + Checks if offset of the controller register is a know 64bit value. + +**Parameters** + +``__u32 offset`` + Offset of controller register field in bytes + +**Description** + +This function does not care about transport so that the offset is not going +to be checked inside of this function for the unsupported fields in a +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. + + +.. c:function:: __u64 nvme_cmb_size (__u32 cmbsz) + + Calculate size of the controller memory buffer + +**Parameters** + +``__u32 cmbsz`` + Value from controller register ``NVME_REG_CMBSZ`` + +**Description** + +Returns size of controller memory buffer in bytes + + +.. c:function:: __u64 nvme_pmr_size (__u32 pmrebs) + + Calculate size of persistent memory region elasticity buffer + +**Parameters** + +``__u32 pmrebs`` + Value from controller register ``NVME_REG_PMREBS`` + +**Description** + +Returns size of controller persistent memory buffer in bytes + + +.. c:function:: __u64 nvme_pmr_throughput (__u32 pmrswtp) + + Calculate throughput of persistent memory buffer + +**Parameters** + +``__u32 pmrswtp`` + Value from controller register ``NVME_REG_PMRSWTP`` + +**Description** + +Returns throughput of controller persistent memory buffer in bytes/second + + + + +.. c:type:: enum nvme_psd_flags + + Possible flag values in nvme power state descriptor + +**Constants** + +``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. + +``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. + + + + +.. c:type:: enum nvme_psd_ps + + Known values for :c:type:`struct nvme_psd ` ``ips`` and ``aps``. Use with nvme_psd_power_scale() to extract the power scale field to match this enum. + +**Constants** + +``NVME_PSD_PS_100_MICRO_WATT`` + 0.0001 watt scale + +``NVME_PSD_PS_10_MILLI_WATT`` + 0.01 watt scale + + +.. c:function:: unsigned int nvme_psd_power_scale (__u8 ps) + + power scale occupies the upper 3 bits + +**Parameters** + +``__u8 ps`` + power scale value + + + + +.. c:type:: enum nvme_psd_workload + + Specifies a workload hint in the Power Management Feature (see :c:type:`struct nvme_psd `.apw) to inform the NVM subsystem or indicate the conditions for the active power level. + +**Constants** + +``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. + +``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 + NVM subsystem are idle. The submission queue(s) + should be sufficiently large allowing the host to + ensure there are multiple commands pending at all + times during the workload. + + + + +.. c:type:: struct nvme_id_psd + + +**Definition** + +:: + + struct nvme_id_psd { + __le16 mp; + __u8 rsvd2; + __u8 flags; + __le32 enlat; + __le32 exlat; + __u8 rrt; + __u8 rrl; + __u8 rwt; + __u8 rwl; + __le16 idlp; + __u8 ips; + __u8 rsvd19; + __le16 actp; + __u8 apws; + __u8 rsvd23[9]; + }; + +**Members** + +``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 :c:type:`enum nvme_psd_flags `). A value of 0 indicates + Maximum Power is not reported. + +``rsvd2`` + Reserved + +``flags`` + Additional decoding flags, see :c:type:`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. + +``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. + +``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. + +``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 + +``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 + +``idlp`` + Idle Power indicates the typical power consumed by the NVM + subsystem over 30 seconds in this power state when idle. + +``ips`` + Idle Power Scale indicates the scale for :c:type:`struct nvme_id_psd `.idlp, + see :c:type:`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. + +``apws`` + Bits 7-6: Active Power Scale(APS) indicates the scale for the :c:type:`struct + nvme_id_psd `.actp, see :c:type:`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 :c:type:`enum nvme_psd_workload ` for decoding this field. + +``rsvd23`` + Reserved + + + + + +.. c:type:: struct nvme_id_ctrl + + Identify Controller data structure + +**Definition** + +:: + + struct nvme_id_ctrl { + __le16 vid; + __le16 ssvid; + char sn[20]; + char mn[40]; + char fr[8]; + __u8 rab; + __u8 ieee[3]; + __u8 cmic; + __u8 mdts; + __le16 cntlid; __le32 ver; __le32 rtd3r; __le32 rtd3e; @@ -6386,7 +8976,10 @@ Returns true if given offset is 64bit register, otherwise it returns false. __le32 anagrpmax; __le32 nanagrpid; __le32 pels; - __u8 rsvd356[156]; + __le16 domainid; + __u8 rsvd358[10]; + __u8 megcap[16]; + __u8 rsvd384[128]; __u8 sqes; __u8 cqes; __le16 maxcmd; @@ -6394,5143 +8987,9142 @@ Returns true if given offset is 64bit register, otherwise it returns false. __le16 oncs; __le16 fuses; __u8 fna; - __u8 vwc; - __le16 awun; - __le16 awupf; - __u8 nvscc; - __u8 nwpc; - __le16 acwu; - __le16 ocfs; - __le32 sgls; - __le32 mnan; - __u8 rsvd544[224]; - char subnqn[NVME_NQN_LENGTH]; - __u8 rsvd1024[768]; - __le32 ioccsz; - __le32 iorcsz; - __le16 icdoff; - __u8 fcatt; - __u8 msdbd; - __le16 ofcs; - __u8 rsvd1806[242]; - struct nvme_id_psd psd[32]; - __u8 vs[1024]; + __u8 vwc; + __le16 awun; + __le16 awupf; + __u8 icsvscc; + __u8 nwpc; + __le16 acwu; + __le16 ocfs; + __le32 sgls; + __le32 mnan; + __u8 maxdna[16]; + __le32 maxcna; + __u8 rsvd564[204]; + char subnqn[NVME_NQN_LENGTH]; + __u8 rsvd1024[768]; + __le32 ioccsz; + __le32 iorcsz; + __le16 icdoff; + __u8 fcatt; + __u8 msdbd; + __le16 ofcs; + __u8 rsvd1806[242]; + struct nvme_id_psd psd[32]; + __u8 vs[1024]; + }; + +**Members** + +``vid`` + PCI Vendor ID, the company vendor identifier that is assigned by + 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 + +``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 :c:type:`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 + +``cntlid`` + Controller ID, the NVM subsystem unique controller identifier + associated with the controller. + +``ver`` + Version, this field contains the value reported in the Version + register, or property (see :c:type:`enum nvme_registers ` ``NVME_REG_VS``). + +``rtd3r`` + RTD3 Resume Latency, the expected latency in microseconds to resume + from Runtime D3 + +``rtd3e`` + RTD3 Exit Latency, the typical latency in microseconds to enter + 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 + +``cntrltype`` + Controller Type, see :c:type:`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 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 + +``rsvd134`` + Reserved + +``nvmsr`` + NVM Subsystem Report, see :c:type:`enum nvme_id_ctrl_nvmsr ` + +``vwci`` + VPD Write Cycle Information, see :c:type:`enum nvme_id_ctrl_vwci ` + +``mec`` + Management Endpoint Capabilities, see :c:type:`enum nvme_id_ctrl_mec ` + +``oacs`` + Optional Admin Command Support,the optional Admin commands and + features supported by the controller, see :c:type:`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. + +``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. + +``frmw`` + Firmware Updates indicates capabilities regarding firmware + updates. See :c:type:`enum nvme_id_ctrl_frmw `. + +``lpa`` + Log Page Attributes, see :c:type:`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. + +``npss`` + Number of Power States Supported, the number of NVM Express + power states supported by the controller, indicating the number + of valid entries in :c:type:`struct nvme_id_ctrl `.psd. This is a 0's + based value. + +``avscc`` + Admin Vendor Specific Command Configuration, see + :c:type:`enum nvme_id_ctrl_avscc `. + +``apsta`` + Autonomous Power State Transition Attributes, see + :c:type:`enum nvme_id_ctrl_apsta `. + +``wctemp`` + Warning Composite Temperature Threshold indicates + the minimum Composite Temperature field value (see :c:type:`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 :c:type:`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. + +``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. + +``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. + +``tnvmcap`` + Total NVM Capacity, the total NVM capacity in the NVM subsystem. + 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 + :c:type:`enum nvme_id_ctrl_rpmbs `. + +``edstt`` + Extended Device Self-test Time, if Device Self-test command is + supported (see :c:type:`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 :c:type:`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 + +``kas`` + Keep Alive Support indicates the granularity of the Keep Alive + Timer in 100 millisecond units. + +``hctma`` + Host Controlled Thermal Management Attributes, see + :c:type:`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``. + +``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``. + +``sanicap`` + Sanitize Capabilities, see :c:type:`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. + +``hmmaxd`` + Host Memory Maximum Descriptors Entries indicates the number of + 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. + +``endgidmax`` + Endurance Group Identifier Maximum, defines the maximum value of + 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. + +``anacap`` + Asymmetric Namespace Access Capabilities, see + :c:type:`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. + +``nanagrpid`` + Number of ANA Group Identifiers indicates the number of ANA + groups supported by this controller. + +``pels`` + Persistent Event Log Size indicates the maximum reportable size + for the Persistent Event Log. + +``domainid`` + Domain Identifier indicates the identifier of the domain + that contains this controller. + +``rsvd358`` + Reserved + +``megcap`` + Max Endurance Group Capacity indicates the maximum capacity + of a single Endurance Group. + +``rsvd384`` + Reserved + +``sqes`` + Submission Queue Entry Size, see :c:type:`enum nvme_id_ctrl_sqes `. + +``cqes`` + Completion Queue Entry Size, see :c:type:`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. + +``nn`` + Number of Namespaces indicates the maximum value of a valid + nsid for the NVM subsystem. If the MNAN (:c:type:`struct nvme_id_ctrl `.mnan + field is cleared to 0h, then this field also indicates the + maximum number of namespaces supported by the NVM subsystem. + +``oncs`` + Optional NVM Command Support, see :c:type:`enum nvme_id_ctrl_oncs `. + +``fuses`` + Fused Operation Support, see :c:type:`enum nvme_id_ctrl_fuses `. + +``fna`` + Format NVM Attributes, see :c:type:`enum nvme_id_ctrl_fna `. + +``vwc`` + Volatile Write Cache, see :c:type:`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. + +``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. + +``icsvscc`` + NVM Vendor Specific Command Configuration, see + :c:type:`enum nvme_id_ctrl_nvscc `. + +``nwpc`` + Namespace Write Protection Capabilities, see + :c:type:`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. + +``ocfs`` + Optional Copy Formats Supported, each bit n means controller + supports Copy Format n. + +``sgls`` + SGL Support, see :c:type:`enum nvme_id_ctrl_sgls ` + +``mnan`` + Maximum Number of Allowed Namespaces indicates the maximum + 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. + +``maxcna`` + Maximum I/O Controller Namespace Attachments indicates the + 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. + +``iorcsz`` + I/O Queue Response Capsule Supported Size, defines the maximum + 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. + +``fcatt`` + Fabrics Controller Attributes, see :c:type:`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. + +``ofcs`` + Optional Fabric Commands Support, see :c:type:`enum nvme_id_ctrl_ofcs `. + +``rsvd1806`` + Reserved + +``psd`` + Power State Descriptors, see :c:type:`struct nvme_id_psd `. + +``vs`` + Vendor Specific + + + + + +.. c:type:: enum nvme_id_ctrl_cmic + + Controller Multipath IO and Namespace Sharing Capabilities of the controller and NVM subsystem. + +**Constants** + +``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. + + + + +.. c:type:: enum nvme_id_ctrl_oaes + + Optional Asynchronous Events Supported + +**Constants** + +``NVME_CTRL_OAES_NA`` + Namespace Attribute Notices event supported + +``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 + +``NVME_CTRL_OAES_LBAS`` + LBA Status Information Notices event supported + +``NVME_CTRL_OAES_EGE`` + Endurance Group Events Aggregate Log Change + 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 + + + + +.. c:type:: enum nvme_id_ctrl_ctratt + + Controller attributes + +**Constants** + +``NVME_CTRL_CTRATT_128_ID`` + 128-bit Host Identifier supported + +``NVME_CTRL_CTRATT_NON_OP_PSP`` + Non-Operational Poser State Permissive Mode + 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 + +``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_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 + + + + +.. c:type:: enum nvme_id_ctrl_cntrltype + + Controller types + +**Constants** + +``NVME_CTRL_CNTRLTYPE_IO`` + NVM I/O controller + +``NVME_CTRL_CNTRLTYPE_DISCOVERY`` + Discovery controller + +``NVME_CTRL_CNTRLTYPE_ADMIN`` + Admin controller + + + + +.. c:type:: enum nvme_id_ctrl_nvmsr + + This field reports information associated with the NVM Subsystem, see :c:type:`struct nvme_id_ctrl `.nvmsr. + +**Constants** + +``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. + +``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. + + + + +.. c:type:: 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 :c:type:`struct nvme_id_ctrl `.vwci. + +**Constants** + +``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. + +``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. + + + + +.. c:type:: enum nvme_id_ctrl_mec + + Flags indicatings the capabilities of the Management Endpoint in the Controller, :c:type:`struct nvme_id_ctrl `.mec. + +**Constants** + +``NVME_CTRL_MEC_SMBUSME`` + If set, then the NVM Subsystem contains a Management + Endpoint on an SMBus/I2C port. + +``NVME_CTRL_MEC_PCIEME`` + If set, then the NVM Subsystem contains a Management + Endpoint on a PCIe port. + + + + +.. c:type:: enum nvme_id_ctrl_oacs + + Flags indicating the optional Admin commands and features supported by the controller, see :c:type:`struct nvme_id_ctrl `.oacs. + +**Constants** + +``NVME_CTRL_OACS_SECURITY`` + If set, then the controller supports the + Security Send and Security Receive commands. + +``NVME_CTRL_OACS_FORMAT`` + If set then the controller supports the Format + NVM command. + +``NVME_CTRL_OACS_FW`` + If set, then the controller supports the + Firmware Commit and Firmware Image Download commands. + +``NVME_CTRL_OACS_NS_MGMT`` + If set, then the controller supports the + Namespace Management capability + +``NVME_CTRL_OACS_SELF_TEST`` + If set, then the controller supports the Device + 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. + +``NVME_CTRL_OACS_VIRT_MGMT`` + If set, then the controller supports the + Virtualization Management command. + +``NVME_CTRL_OACS_DBBUF_CFG`` + If set, then the controller supports the + Doorbell Buffer Config command. + +``NVME_CTRL_OACS_LBA_STATUS`` + If set, then the controller supports the Get LBA + Status capability. + + + + +.. c:type:: enum nvme_id_ctrl_frmw + + Flags and values indicates capabilities regarding firmware updates from :c:type:`struct nvme_id_ctrl `.frmw. + +**Constants** + +``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. + +``NVME_CTRL_FRMW_FW_ACT_NO_RESET`` + If set, the controller supports firmware + activation without a reset. + + + + +.. c:type:: enum nvme_id_ctrl_lpa + + Flags indicating optional attributes for log pages that are accessed via the Get Log Page command. + +**Constants** + +``NVME_CTRL_LPA_SMART_PER_NS`` + +``NVME_CTRL_LPA_CMD_EFFECTS`` + +``NVME_CTRL_LPA_EXTENDED`` + +``NVME_CTRL_LPA_TELEMETRY`` + +``NVME_CTRL_LPA_PERSETENT_EVENT`` + + + + +.. c:type:: enum nvme_id_ctrl_avscc + + Flags indicating the configuration settings for Admin Vendor Specific command handling. + +**Constants** + +``NVME_CTRL_AVSCC_AVS`` + If set, all Admin Vendor Specific Commands use the + optional vendor specific command format with NDT and + NDM fields. + + + + +.. c:type:: enum nvme_id_ctrl_apsta + + Flags indicating the attributes of the autonomous power state transition feature. + +**Constants** + +``NVME_CTRL_APSTA_APST`` + If set, then the controller supports autonomous power + state transitions. + + + + +.. c:type:: enum nvme_id_ctrl_rpmbs + + This field indicates if the controller supports one or more Replay Protected Memory Blocks, from :c:type:`struct nvme_id_ctrl `.rpmbs. + +**Constants** + +``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_ACCESS_SIZE`` + Mask to get the value of Access Size + + + + +.. c:type:: enum nvme_id_ctrl_dsto + + Flags indicating the optional Device Self-test command or operation behaviors supported by the controller or NVM subsystem. + +**Constants** + +``NVME_CTRL_DSTO_ONE_DST`` + If set, then the NVM subsystem supports only one + device self-test operation in progress at a time. + + + + +.. c:type:: enum nvme_id_ctrl_hctm + + Flags indicate the attributes of the host controlled thermal management feature + +**Constants** + +``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``. + + + + +.. c:type:: enum nvme_id_ctrl_sanicap + + Indicates attributes for sanitize operations. + +**Constants** + +``NVME_CTRL_SANICAP_CES`` + Crypto Erase Support. If set, then the + 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. + +``NVME_CTRL_SANICAP_OWS`` + Overwrite Support. If set, then the controller + 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. + +``NVME_CTRL_SANICAP_NODMMAS`` + No-Deallocate Modifies Media After Sanitize, + mask to extract value. + + + + +.. c:type:: enum nvme_id_ctrl_anacap + + This field indicates the capabilities associated with Asymmetric Namespace Access Reporting. + +**Constants** + +``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. + +``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. + +``NVME_CTRL_ANACAP_GRPID_NO_CHG`` + If set, then the ANAGRPID field in the + Identify Namespace data structure + (:c:type:`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. + + + + +.. c:type:: enum nvme_id_ctrl_sqes + + Defines the required and maximum Submission Queue entry size when using the NVM Command Set. + +**Constants** + +``NVME_CTRL_SQES_MIN`` + Mask to get the value of the required Submission Queue + 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. + + + + +.. c:type:: enum nvme_id_ctrl_cqes + + Defines the required and maximum Completion Queue entry size when using the NVM Command Set. + +**Constants** + +``NVME_CTRL_CQES_MIN`` + Mask to get the value of the required Completion Queue + 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. + + + + +.. c:type:: enum nvme_id_ctrl_oncs + + This field indicates the optional NVM commands and features supported by the controller. + +**Constants** + +``NVME_CTRL_ONCS_COMPARE`` + If set, then the controller supports + the Compare command. + +``NVME_CTRL_ONCS_WRITE_UNCORRECTABLE`` + If set, then the controller supports + the Write Uncorrectable command. + +``NVME_CTRL_ONCS_DSM`` + If set, then the controller supports + the Dataset Management command. + +``NVME_CTRL_ONCS_WRITE_ZEROES`` + If set, then the controller supports + 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. + +``NVME_CTRL_ONCS_RESERVATIONS`` + If set, then the controller supports + reservations. + +``NVME_CTRL_ONCS_TIMESTAMP`` + If set, then the controller supports + the Timestamp feature. + +``NVME_CTRL_ONCS_VERIFY`` + If set, then the controller supports + the Verify command. + + + + +.. c:type:: enum nvme_id_ctrl_fuses + + This field indicates the fused operations that the controller supports. + +**Constants** + +``NVME_CTRL_FUSES_COMPARE_AND_WRITE`` + If set, then the controller supports the + Compare and Write fused operation. + + + + +.. c:type:: enum nvme_id_ctrl_fna + + This field indicates attributes for the Format NVM command. + +**Constants** + +``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. + +``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. + + + + +.. c:type:: enum nvme_id_ctrl_vwc + + +**Constants** + +``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``. + +``NVME_CTRL_VWC_FLUSH`` + Mask to get the value of the flush command behavior. + + + + +.. c:type:: enum nvme_id_ctrl_nvscc + + This field indicates the configuration settings for NVM Vendor Specific command handling. + +**Constants** + +``NVME_CTRL_NVSCC_FMT`` + If set, all NVM Vendor Specific Commands use the + format format with NDT and NDM fields. + + + + +.. c:type:: enum nvme_id_ctrl_nwpc + + This field indicates the optional namespace write protection capabilities supported by the controller. + +**Constants** + +``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. + +``NVME_CTRL_NWPC_WRITE_PROTECT_POWER_CYCLE`` + If set, then the controller + 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. + + + + +.. c:type:: enum nvme_id_ctrl_sgls + + This field indicates if SGLs are supported for the NVM Command Set and the particular SGL types supported. + +**Constants** + +``NVME_CTRL_SGLS_SUPPORTED`` + +``NVME_CTRL_SGLS_KEYED`` + +``NVME_CTRL_SGLS_BIT_BUCKET`` + +``NVME_CTRL_SGLS_MPTR_BYTE_ALIGNED`` + +``NVME_CTRL_SGLS_OVERSIZE`` + +``NVME_CTRL_SGLS_MPTR_SGL`` + +``NVME_CTRL_SGLS_OFFSET`` + +``NVME_CTRL_SGLS_TPORT`` + + + + +.. c:type:: enum nvme_id_ctrl_fcatt + + This field indicates attributes of the controller that are specific to NVMe over Fabrics. + +**Constants** + +``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. + + + + +.. c:type:: enum nvme_id_ctrl_ofcs + + Indicate whether the controller supports optional fabric commands. + +**Constants** + +``NVME_CTRL_OFCS_DISCONNECT`` + If set, then the controller supports the + Disconnect command and deletion of individual + I/O Queues. + + + + +.. c:type:: struct nvme_lbaf + + LBA Format Data Structure + +**Definition** + +:: + + struct nvme_lbaf { + __le16 ms; + __u8 ds; + __u8 rp; + }; + +**Members** + +``ms`` + Metadata Size indicates the number of metadata bytes provided per LBA + based on the LBA Data Size indicated. + +``ds`` + LBA Data Size indicates the LBA data size supported, reported as a + power of two. + +``rp`` + Relative Performance, see :c:type:`enum nvme_lbaf_rp `. + + + + + +.. c:type:: enum nvme_lbaf_rp + + This field indicates the relative performance of the LBA format indicated relative to other LBA formats supported by the controller. + +**Constants** + +``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 + + + + +.. c:type:: struct nvme_id_ns + + Identify Namespace data structure + +**Definition** + +:: + + struct nvme_id_ns { + __le64 nsze; + __le64 ncap; + __le64 nuse; + __u8 nsfeat; + __u8 nlbaf; + __u8 flbas; + __u8 mc; + __u8 dpc; + __u8 dps; + __u8 nmic; + __u8 rescap; + __u8 fpi; + __u8 dlfeat; + __le16 nawun; + __le16 nawupf; + __le16 nacwu; + __le16 nabsn; + __le16 nabo; + __le16 nabspf; + __le16 noiob; + __u8 nvmcap[16]; + __le16 npwg; + __le16 npwa; + __le16 npdg; + __le16 npda; + __le16 nows; + __le16 mssrl; + __le32 mcl; + __u8 msrc; + __u8 rsvd81[11]; + __le32 anagrpid; + __u8 rsvd96[3]; + __u8 nsattr; + __le16 nvmsetid; + __le16 endgid; + __u8 nguid[16]; + __u8 eui64[8]; + struct nvme_lbaf lbaf[64]; + __u8 vs[3712]; + }; + +**Members** + +``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. + +``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. + +``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. + +``nsfeat`` + Namespace Features, see :c:type:`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 :c:type:`struct nvme_id_ns `.lbaf. + +``flbas`` + Formatted LBA Size, see :c:type:`enum nvme_id_ns_flbas `. + +``mc`` + Metadata Capabilities, see :c:type:`enum nvme_id_ns_mc `. + +``dpc`` + End-to-end Data Protection Capabilities, see + :c:type:`enum nvme_id_ns_dpc `. + +``dps`` + End-to-end Data Protection Type Settings, see + :c:type:`enum nvme_id_ns_dps `. + +``nmic`` + Namespace Multi-path I/O and Namespace Sharing Capabilities, see + :c:type:`enum nvme_id_ns_nmic `. + +``rescap`` + Reservation Capabilities, see :c:type:`enum nvme_id_ns_rescap `. + +``fpi`` + Format Progress Indicator, see :c:type:`enum nvme_nd_ns_fpi `. + +``dlfeat`` + Deallocate Logical Block Features, see :c:type:`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. + +``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. + +``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. + +``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. + +``nabo`` + Namespace Atomic Boundary Offset indicates the LBA on this + 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. + +``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. + +``nvmcap`` + NVM Capacity indicates the total size of the NVM allocated to + 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. + +``npwa`` + Namespace Preferred Write Alignment indicates the recommended + 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. + +``npda`` + Namespace Preferred Deallocate Alignment indicates the + 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. + +``mssrl`` + +``mcl`` + +``msrc`` + +``rsvd81`` + Reserved + +``anagrpid`` + ANA Group Identifier indicates the ANA Group Identifier of the + ANA group of which the namespace is a member. + +``rsvd96`` + Reserved + +``nsattr`` + Namespace Attributes, see :c:type:`enum nvme_id_ns_attr `. + +``nvmsetid`` + NVM Set Identifier indicates the NVM Set with which this + namespace is associated. + +``endgid`` + Endurance Group Identifier indicates the Endurance Group with + 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 + +``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 + remains fixed throughout the life of the namespace and is + preserved across namespace and controller operations + +``lbaf`` + LBA Format, see :c:type:`struct nvme_lbaf `. + +``vs`` + Vendor Specific + + + + + +.. c:type:: enum nvme_id_nsfeat + + This field defines features of the namespace. + +**Constants** + +``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. + +``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. + +``NVME_NS_FEAT_DULBE`` + If set, indicates that the controller supports the + 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. + +``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 + + + + +.. c:type:: enum nvme_id_ns_flbas + + This field indicates the LBA data size & metadata size combination that the namespace has been formatted with + +**Constants** + +``NVME_NS_FLBAS_LOWER_MASK`` + Mask to get the index of one of the supported + LBA Formats's least significant + 4bits indicated in + :c:type:`struct nvme_id_ns `.lbaf. + +``NVME_NS_FLBAS_META_EXT`` + Applicable only if format contains metadata. If + this bit is set, indicates that the metadata is + transferred at the end of the data LBA, creating an + 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 + the supported LBA Formats's most significant + 2bits indicated in + :c:type:`struct nvme_id_ns `.lbaf. + + + + +.. c:type:: enum nvme_id_ns_mc + + This field indicates the capabilities for metadata. + +**Constants** + +``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. + +``NVME_NS_MC_SEPARATE`` + If set, indicates that the namespace supports the + metadata being transferred as part of an extended data LBA. + + + + +.. c:type:: enum nvme_id_ns_dpc + + This field indicates the capabilities for the end-to-end data protection feature. + +**Constants** + +``NVME_NS_DPC_PI_TYPE1`` + If set, indicates that the namespace supports + Protection Information Type 1. + +``NVME_NS_DPC_PI_TYPE2`` + If set, indicates that the namespace supports + Protection Information Type 2. + +``NVME_NS_DPC_PI_TYPE3`` + If set, indicates that the namespace supports + 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. + +``NVME_NS_DPC_PI_LAST`` + If set, indicates that the namespace supports + protection information transferred as the last eight + bytes of metadata. + + + + +.. c:type:: enum nvme_id_ns_dps + + This field indicates the Type settings for the end-to-end data protection feature. + +**Constants** + +``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. + + + + +.. c:type:: enum nvme_id_ns_nmic + + This field specifies multi-path I/O and namespace sharing capabilities of the namespace. + +**Constants** + +``NVME_NS_NMIC_SHARED`` + If set, then the namespace may be attached to two or + more controllers in the NVM subsystem concurrently + + + + +.. c:type:: enum nvme_id_ns_rescap + + This field indicates the reservation capabilities of the namespace. + +**Constants** + +``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. + +``NVME_NS_RESCAP_WERO`` + If set, indicates that the namespace supports the + Write Exclusive - Registrants Only reservation type. + +``NVME_NS_RESCAP_EARO`` + If set, indicates that the namespace supports the + Exclusive Access - Registrants Only reservation type. + +``NVME_NS_RESCAP_WEAR`` + If set, indicates that the namespace supports the + Write Exclusive - All Registrants reservation type. + +``NVME_NS_RESCAP_EAAR`` + If set, indicates that the namespace supports the + 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. + + + + +.. c:type:: 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. + +**Constants** + +``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. + + + + +.. c:type:: enum nvme_id_ns_dlfeat + + This field indicates information about features that affect deallocating logical blocks for this namespace. + +**Constants** + +``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_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 + + + + +.. c:type:: enum nvme_id_ns_attr + + Specifies attributes of the namespace. + +**Constants** + +``NVME_NS_NSATTR_WRITE_PROTECTED`` + If set, then the namespace is currently + write protected and all write access to the + namespace shall fail. + + + + +.. c:type:: struct nvme_ns_id_desc + + +**Definition** + +:: + + struct nvme_ns_id_desc { + __u8 nidt; + __u8 nidl; + __le16 rsvd; + __u8 nid[]; + }; + +**Members** + +``nidt`` + Namespace Identifier Type, see :c:type:`enum nvme_ns_id_desc_nidt ` + +``nidl`` + Namespace Identifier Length contains the length in bytes of the + :c:type:`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 :c:type:`struct nvme_id_ns `.nidl. + + + + + +.. c:type:: enum nvme_ns_id_desc_nidt + + Known namespace identifier types + +**Constants** + +``NVME_NIDT_EUI64`` + IEEE Extended Unique Identifier, the NID field contains a + 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. + +``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. + + + + +.. c:type:: struct nvme_nvmset_attr + + NVM Set Attributes Entry + +**Definition** + +:: + + struct nvme_nvmset_attr { + __le16 nvmsetid; + __le16 endgid; + __u8 rsvd4[4]; + __le32 rr4kt; + __le32 ows; + __u8 tnvmsetcap[16]; + __u8 unvmsetcap[16]; + __u8 rsvd48[80]; + }; + +**Members** + +``nvmsetid`` + NVM Set Identifier + +``endgid`` + Endurance Group Identifier + +``rsvd4`` + Reserved + +``rr4kt`` + Random 4 KiB Read Typical indicates the typical + time to complete a 4 KiB random read in 100 nanosecond units + when the NVM Set is in a Predictable Latency Mode Deterministic + Window and there is 1 outstanding command per NVM Set. + +``ows`` + Optimal Write Size + +``tnvmsetcap`` + Total NVM Set Capacity + +``unvmsetcap`` + Unallocated NVM Set Capacity + +``rsvd48`` + Reserved + + + + + +.. c:type:: struct nvme_id_nvmset_list + + +**Definition** + +:: + + struct nvme_id_nvmset_list { + __u8 nid; + __u8 rsvd1[127]; + struct nvme_nvmset_attr ent[NVME_ID_NVMSET_LIST_MAX]; + }; + +**Members** + +``nid`` + Nvmset id + +``rsvd1`` + Reserved + +``ent`` + nvmset id list + + + + + +.. c:type:: struct nvme_id_independent_id_ns + + +**Definition** + +:: + + struct nvme_id_independent_id_ns { + __u8 nsfeat; + __u8 nmic; + __u8 rescap; + __u8 fpi; + __le32 anagrpid; + __u8 nsattr; + __u8 rsvd9; + __le16 nvmsetid; + __le16 endgid; + __u8 nstat; + __u8 rsvd15[4081]; + }; + +**Members** + +``nsfeat`` + +``nmic`` + +``rescap`` + +``fpi`` + +``anagrpid`` + +``nsattr`` + +``rsvd9`` + +``nvmsetid`` + +``endgid`` + +``nstat`` + +``rsvd15`` + + + + + +.. c:type:: struct nvme_id_ns_granularity_desc + + +**Definition** + +:: + + struct nvme_id_ns_granularity_desc { + __le64 nszegran; + __le64 ncapgran; + }; + +**Members** + +``nszegran`` + +``ncapgran`` + + + + + +.. c:type:: struct nvme_id_ns_granularity_list + + +**Definition** + +:: + + struct nvme_id_ns_granularity_list { + __le32 attributes; + __u8 num_descriptors; + __u8 rsvd5[27]; + struct nvme_id_ns_granularity_desc entry[NVME_ID_ND_DESCRIPTOR_MAX]; + __u8 rsvd288[3808]; + }; + +**Members** + +``attributes`` + +``num_descriptors`` + +``rsvd5`` + +``entry`` + +``rsvd288`` + + + + + +.. c:type:: struct nvme_id_uuid_list_entry + + +**Definition** + +:: + + struct nvme_id_uuid_list_entry { + __u8 header; + __u8 rsvd1[15]; + __u8 uuid[16]; + }; + +**Members** + +``header`` + +``rsvd1`` + +``uuid`` + + + + + +.. c:type:: enum nvme_id_uuid + + +**Constants** + +``NVME_ID_UUID_HDR_ASSOCIATION_MASK`` + +``NVME_ID_UUID_ASSOCIATION_NONE`` + +``NVME_ID_UUID_ASSOCIATION_VENDOR`` + +``NVME_ID_UUID_ASSOCIATION_SUBSYSTEM_VENDOR`` + + + + +.. c:type:: struct nvme_id_uuid_list + + +**Definition** + +:: + + struct nvme_id_uuid_list { + __u8 rsvd0[32]; + struct nvme_id_uuid_list_entry entry[NVME_ID_UUID_LIST_MAX]; + }; + +**Members** + +``rsvd0`` + +``entry`` + + + + + +.. c:type:: struct nvme_ctrl_list + + +**Definition** + +:: + + struct nvme_ctrl_list { + __le16 num; + __le16 identifier[NVME_ID_CTRL_LIST_MAX]; + }; + +**Members** + +``num`` + +``identifier`` + + + + + +.. c:type:: struct nvme_ns_list + + +**Definition** + +:: + + struct nvme_ns_list { + __le32 ns[NVME_ID_NS_LIST_MAX]; + }; + +**Members** + +``ns`` + + + + + +.. c:type:: struct nvme_id_ctrl_nvm + + +**Definition** + +:: + + struct nvme_id_ctrl_nvm { + __u8 vsl; + __u8 wzsl; + __u8 wusl; + __u8 dmrl; + __u32 dmrsl; + __u64 dmsl; + __u8 rsvd16[4080]; + }; + +**Members** + +``vsl`` + +``wzsl`` + +``wusl`` + +``dmrl`` + +``dmrsl`` + +``dmsl`` + +``rsvd16`` + + + + + +.. c:type:: struct nvme_zns_lbafe + + +**Definition** + +:: + + struct nvme_zns_lbafe { + __le64 zsze; + __u8 zdes; + __u8 rsvd9[7]; + }; + +**Members** + +``zsze`` + +``zdes`` + +``rsvd9`` + + + + + +.. c:type:: struct nvme_zns_id_ns + + Zoned Namespace Command Set Specific Identify Namespace Data Structure + +**Definition** + +:: + + struct nvme_zns_id_ns { + __le16 zoc; + __le16 ozcs; + __le32 mar; + __le32 mor; + __le32 rrl; + __le32 frl; + __le32 rrl1; + __le32 rrl2; + __le32 rrl3; + __le32 frl1; + __le32 frl2; + __le32 frl3; + __le32 numzrwa; + __le16 zrwafg; + __le16 zrwasz; + __u8 zrwacap; + __u8 rsvd53[2763]; + struct nvme_zns_lbafe lbafe[64]; + __u8 vs[256]; + }; + +**Members** + +``zoc`` + Zone Operation Characteristics + +``ozcs`` + Optional Zoned Command Support + +``mar`` + Maximum Active Resources + +``mor`` + Maximum Open Resources + +``rrl`` + Reset Recommended Limit + +``frl`` + Finish Recommended Limit + +``rrl1`` + Reset Recommended Limit 1 + +``rrl2`` + Reset Recommended Limit 2 + +``rrl3`` + Reset Recommended Limit 3 + +``frl1`` + Finish Recommended Limit 1 + +``frl2`` + Finish Recommended Limit 2 + +``frl3`` + Finish Recommended Limit 3 + +``numzrwa`` + Number of ZRWA Resources + +``zrwafg`` + ZRWA Flush Granularity + +``zrwasz`` + ZRWA Size + +``zrwacap`` + ZRWA Capability + +``rsvd53`` + Reserved + +``lbafe`` + LBA Format Extension + +``vs`` + Vendor Specific + + + + + +.. c:type:: struct nvme_zns_id_ctrl + + +**Definition** + +:: + + struct nvme_zns_id_ctrl { + __u8 zasl; + __u8 rsvd1[4095]; + }; + +**Members** + +``zasl`` + +``rsvd1`` + Reserved + + + + + +.. c:type:: struct nvme_primary_ctrl_cap + + +**Definition** + +:: + + struct nvme_primary_ctrl_cap { + __le16 cntlid; + __le16 portid; + __u8 crt; + __u8 rsvd5[27]; + __le32 vqfrt; + __le32 vqrfa; + __le16 vqrfap; + __le16 vqprt; + __le16 vqfrsm; + __le16 vqgran; + __u8 rsvd48[16]; + __le32 vifrt; + __le32 virfa; + __le16 virfap; + __le16 viprt; + __le16 vifrsm; + __le16 vigran; + __u8 rsvd80[4016]; + }; + +**Members** + +``cntlid`` + +``portid`` + +``crt`` + +``rsvd5`` + +``vqfrt`` + +``vqrfa`` + +``vqrfap`` + +``vqprt`` + +``vqfrsm`` + +``vqgran`` + +``rsvd48`` + +``vifrt`` + +``virfa`` + +``virfap`` + +``viprt`` + +``vifrsm`` + +``vigran`` + +``rsvd80`` + + + + + +.. c:type:: struct nvme_secondary_ctrl + + +**Definition** + +:: + + struct nvme_secondary_ctrl { + __le16 scid; + __le16 pcid; + __u8 scs; + __u8 rsvd5[3]; + __le16 vfn; + __le16 nvq; + __le16 nvi; + __u8 rsvd14[18]; + }; + +**Members** + +``scid`` + +``pcid`` + +``scs`` + +``rsvd5`` + +``vfn`` + +``nvq`` + +``nvi`` + +``rsvd14`` + + + + + +.. c:type:: struct nvme_secondary_ctrl_list + + +**Definition** + +:: + + struct nvme_secondary_ctrl_list { + __u8 num; + __u8 rsvd[31]; + struct nvme_secondary_ctrl sc_entry[NVME_ID_SECONDARY_CTRL_MAX]; + }; + +**Members** + +``num`` + +``rsvd`` + +``sc_entry`` + + + + + +.. c:type:: struct nvme_id_iocs + + NVMe Identify IO Command Set data structure + +**Definition** + +:: + + struct nvme_id_iocs { + __u64 iocsc[512]; + }; + +**Members** + +``iocsc`` + List of supported IO Command Set Combination vectors + + + + + +.. c:type:: struct nvme_id_domain_attr + + Domain Attributes Entry + +**Definition** + +:: + + struct nvme_id_domain_attr { + __le16 dom_id; + __u8 rsvd2[14]; + __u8 dom_cap[16]; + __u8 unalloc_dom_cap[16]; + __u8 max_egrp_dom_cap[16]; + __u8 rsvd64[64]; + }; + +**Members** + +``dom_id`` + +``rsvd2`` + +``dom_cap`` + +``unalloc_dom_cap`` + +``max_egrp_dom_cap`` + +``rsvd64`` + + + + + +.. c:type:: struct nvme_id_domain_list + + +**Definition** + +:: + + struct nvme_id_domain_list { + __u8 num; + __u8 rsvd[127]; + struct nvme_id_domain_attr domain_attr[NVME_ID_DOMAIN_LIST_MAX]; + }; + +**Members** + +``num`` + Number of domain attributes + +``rsvd`` + Reserved + +``domain_attr`` + List of domain attributes + + + + + +.. c:type:: struct nvme_id_endurance_group_list + + +**Definition** + +:: + + struct nvme_id_endurance_group_list { + __le16 num; + __le16 identifier[NVME_ID_ENDURANCE_GROUP_LIST_MAX]; + }; + +**Members** + +``num`` + +``identifier`` + + + + + +.. c:type:: struct nvme_supported_log_pages + + +**Definition** + +:: + + struct nvme_supported_log_pages { + __le32 lid_support[NVME_LOG_SUPPORTED_LOG_PAGES_MAX]; + }; + +**Members** + +``lid_support`` + + +**Description** + +Supported Log Pages (Log Identifier 00h) + + + + +.. c:type:: struct nvme_error_log_page + + Error Information Log Entry (Log Identifier 01h) + +**Definition** + +:: + + struct nvme_error_log_page { + __le64 error_count; + __le16 sqid; + __le16 cmdid; + __le16 status_field; + __le16 parm_error_location; + __le64 lba; + __le32 nsid; + __u8 vs; + __u8 trtype; + __u8 rsvd[2]; + __le64 cs; + __le16 trtype_spec_info; + __u8 rsvd2[22]; + }; + +**Members** + +``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. + +``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``. + +``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``. + +``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. + +``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. + Bits 7-0: Byte in command that contained the error. + Valid values are 0 to 63. + +``lba`` + LBA: This field indicates the first LBA that experienced + the error condition, if applicable. + +``nsid`` + Namespace: This field indicates the NSID of the namespace + 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``. + +``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 :c:type:`enum nvme_trtype `. + +``rsvd`` + Reserved + +``cs`` + Command Specific Information: This field contains command + specific information. If used, the command definition + specifies the information returned. + +``trtype_spec_info`` + +``rsvd2`` + + + + + +.. c:type:: enum nvme_err_pel + + +**Constants** + +``NVME_ERR_PEL_BYTE_MASK`` + +``NVME_ERR_PEL_BIT_MASK`` + + + + +.. c:type:: struct nvme_smart_log + + SMART / Health Information Log (Log Identifier 02h) + +**Definition** + +:: + + struct nvme_smart_log { + __u8 critical_warning; + __u8 temperature[2]; + __u8 avail_spare; + __u8 spare_thresh; + __u8 percent_used; + __u8 endu_grp_crit_warn_sumry; + __u8 rsvd7[25]; + __u8 data_units_read[16]; + __u8 data_units_written[16]; + __u8 host_reads[16]; + __u8 host_writes[16]; + __u8 ctrl_busy_time[16]; + __u8 power_cycles[16]; + __u8 power_on_hours[16]; + __u8 unsafe_shutdowns[16]; + __u8 media_errors[16]; + __u8 num_err_log_entries[16]; + __le32 warning_temp_time; + __le32 critical_comp_time; + __le16 temp_sensor[8]; + __le32 thm_temp1_trans_count; + __le32 thm_temp2_trans_count; + __le32 thm_temp1_total_time; + __le32 thm_temp2_total_time; + __u8 rsvd232[280]; + }; + +**Members** + +``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 :c:type:`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. + +``avail_spare`` + Available Spare: Contains a normalized percentage (0% + 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. + +``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). + +``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 :c:type:`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. + +``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. + +``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. + +``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. + +``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. + +``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. + +``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. + +``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. + +``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``. + +``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. + +``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. + +``thm_temp2_total_time`` + Total Time For Thermal Management Temperature 2 + +``rsvd232`` + Reserved + + + + + +.. c:type:: enum nvme_smart_crit + + Critical Warning + +**Constants** + +``NVME_SMART_CRIT_SPARE`` + If set, then the available spare capacity has fallen + 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. + +``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. + +``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. + +``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. + +``NVME_SMART_CRIT_PMR_RO`` + If set, then the Persistent Memory Region has become + read-only or unreliable. + + + + +.. c:type:: enum nvme_smart_egcw + + Endurance Group Critical Warning Summary + +**Constants** + +``NVME_SMART_EGCW_SPARE`` + If set, then the available spare capacity of one or + 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. + + + + +.. c:type:: struct nvme_firmware_slot + + +**Definition** + +:: + + struct nvme_firmware_slot { + __u8 afi; + __u8 rsvd1[7]; + char frs[7][8]; + __u8 rsvd2[448]; + }; + +**Members** + +``afi`` + +``rsvd1`` + +``frs`` + +``rsvd2`` + + + + + +.. c:type:: struct nvme_cmd_effects_log + + +**Definition** + +:: + + struct nvme_cmd_effects_log { + __le32 acs[256]; + __le32 iocs[256]; + __u8 rsvd[2048]; + }; + +**Members** + +``acs`` + +``iocs`` + +``rsvd`` + + + + + +.. c:type:: enum nvme_cmd_effects + + +**Constants** + +``NVME_CMD_EFFECTS_CSUPP`` + +``NVME_CMD_EFFECTS_LBCC`` + +``NVME_CMD_EFFECTS_NCC`` + +``NVME_CMD_EFFECTS_NIC`` + +``NVME_CMD_EFFECTS_CCC`` + +``NVME_CMD_EFFECTS_CSE_MASK`` + +``NVME_CMD_EFFECTS_UUID_SEL`` + + + + +.. c:type:: struct nvme_st_result + + Self-test Result + +**Definition** + +:: + + struct nvme_st_result { + __u8 dsts; + __u8 seg; + __u8 vdi; + __u8 rsvd; + __le64 poh; + __le32 nsid; + __le64 flba; + __u8 sct; + __u8 sc; + __u8 vs[2]; + }; + +**Members** + +``dsts`` + Device Self-test Status: Indicates the device self-test code and the + status of the operation (see :c:type:`enum nvme_status_result ` and :c:type:`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. + +``vdi`` + Valid Diagnostic Information: Indicates the diagnostic failure + information that is reported. See :c:type:`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. + +``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. + +``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. + +``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 :c:type:`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. + +``vs`` + Vendor Specific. + + + + + +.. c:type:: enum nvme_status_result + + Result of the device self-test operation + +**Constants** + +``NVME_ST_RESULT_NO_ERR`` + Operation completed without error. + +``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. + +``NVME_ST_RESULT_ABORTED_FORMAT`` + Operation was aborted due to the processing + 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. + +``NVME_ST_RESULT_UNKNOWN_SEG_FAIL`` + Operation completed with a segment that failed + 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. + +``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 :c:type:`struct nvme_st_result `.dsts field. + + + + +.. c:type:: enum nvme_st_code + + Self-test Code value + +**Constants** + +``NVME_ST_CODE_RESERVED`` + Reserved. + +``NVME_ST_CODE_SHORT`` + Short device self-test operation. + +``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 + :c:type:`struct nvme_st_result `.dsts field. + + + + +.. c:type:: enum nvme_st_curr_op + + Current Device Self-Test Operation + +**Constants** + +``NVME_ST_CURR_OP_NOT_RUNNING`` + No device self-test operation in progress. + +``NVME_ST_CURR_OP_SHORT`` + Short device self-test operation in progress. + +``NVME_ST_CURR_OP_EXTENDED`` + Extended device self-test operation in progress. + +``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 + :c:type:`struct nvme_self_test_log `.current_operation field. + +``NVME_ST_CURR_OP_CMPL_MASK`` + Mask to get the current operation completion value + from the :c:type:`struct nvme_self_test_log `.completion field. + + + + +.. c:type:: enum nvme_st_valid_diag_info + + Valid Diagnostic Information + +**Constants** + +``NVME_ST_VALID_DIAG_INFO_NSID`` + NSID Valid: if set, then the contents of + 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. + +``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. + + + + +.. c:type:: struct nvme_self_test_log + + Device Self-test (Log Identifier 06h) + +**Definition** + +:: + + struct nvme_self_test_log { + __u8 current_operation; + __u8 completion; + __u8 rsvd[2]; + struct nvme_st_result result[NVME_LOG_ST_MAX_RESULTS]; + }; + +**Members** + +``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 :c:type:`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. + +``rsvd`` + Reserved + +``result`` + Self-test Result Data Structures, see :c:type:`struct nvme_st_result `. + + + + + +.. c:type:: enum nvme_cmd_get_log_telemetry_host_lsp + + +**Constants** + +``NVME_LOG_TELEM_HOST_LSP_RETAIN`` + +``NVME_LOG_TELEM_HOST_LSP_CREATE`` + + + + +.. c:type:: struct nvme_telemetry_log + + Retrieve internal data specific to the manufacturer. + +**Definition** + +:: + + struct nvme_telemetry_log { + __u8 lpi; + __u8 rsvd1[4]; + __u8 ieee[3]; + __le16 dalb1; + __le16 dalb2; + __le16 dalb3; + __u8 rsvd14[2]; + __le32 dalb4; + __u8 rsvd20[362]; + __u8 ctrlavail; + __u8 ctrldgn; + __u8 rsnident[128]; + __u8 data_area[]; + }; + +**Members** + +``lpi`` + Log Identifier, either ``NVME_LOG_LID_TELEMETRY_HOST`` or + ``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. + +``dalb1`` + Telemetry Controller-Initiated Data Area 1 Last Block is + 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. + +``dalb3`` + Telemetry Controller-Initiated Data Area 1 Last Block is + 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. + +``rsvd20`` + Reserved + +``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. + +``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. + +``data_area`` + Telemetry data blocks, vendor specific information data. + + +**Description** + +This log consists of a header describing the log and zero or more Telemetry +Data Blocks. All Telemetry Data Blocks are ``NVME_LOG_TELEM_BLOCK_SIZE``, 512 +bytes, in size. This log captures the controller’s internal state. + + + + +.. c:type:: struct nvme_endurance_group_log + + +**Definition** + +:: + + struct nvme_endurance_group_log { + __u8 critical_warning; + __u8 rsvd1[2]; + __u8 avl_spare; + __u8 avl_spare_threshold; + __u8 percent_used; + __u8 rsvd6[26]; + __u8 endurance_estimate[16]; + __u8 data_units_read[16]; + __u8 data_units_written[16]; + __u8 media_units_written[16]; + __u8 host_read_cmds[16]; + __u8 host_write_cmds[16]; + __u8 media_data_integrity_err[16]; + __u8 num_err_info_log_entries[16]; + __u8 rsvd160[352]; + }; + +**Members** + +``critical_warning`` + +``rsvd1`` + +``avl_spare`` + +``avl_spare_threshold`` + +``percent_used`` + +``rsvd6`` + +``endurance_estimate`` + +``data_units_read`` + +``data_units_written`` + +``media_units_written`` + +``host_read_cmds`` + +``host_write_cmds`` + +``media_data_integrity_err`` + +``num_err_info_log_entries`` + +``rsvd160`` + + + + + +.. c:type:: enum nvme_eg_critical_warning_flags + + +**Constants** + +``NVME_EG_CRITICAL_WARNING_SPARE`` + +``NVME_EG_CRITICAL_WARNING_DEGRADED`` + +``NVME_EG_CRITICAL_WARNING_READ_ONLY`` + + + + +.. c:type:: struct nvme_aggregate_endurance_group_event + + +**Definition** + +:: + + struct nvme_aggregate_endurance_group_event { + __le64 num_entries; + __le16 entries[]; + }; + +**Members** + +``num_entries`` + Number or entries + +``entries`` + List of entries + + + + + +.. c:type:: struct nvme_nvmset_predictable_lat_log + + +**Definition** + +:: + + struct nvme_nvmset_predictable_lat_log { + __u8 status; + __u8 rsvd1; + __le16 event_type; + __u8 rsvd4[28]; + __le64 dtwin_rt; + __le64 dtwin_wt; + __le64 dtwin_tmax; + __le64 ndwin_tmin_hi; + __le64 ndwin_tmin_lo; + __u8 rsvd72[56]; + __le64 dtwin_re; + __le64 dtwin_we; + __le64 dtwin_te; + __u8 rsvd152[360]; + }; + +**Members** + +``status`` + +``rsvd1`` + +``event_type`` + +``rsvd4`` + +``dtwin_rt`` + +``dtwin_wt`` + +``dtwin_tmax`` + +``ndwin_tmin_hi`` + +``ndwin_tmin_lo`` + +``rsvd72`` + +``dtwin_re`` + +``dtwin_we`` + +``dtwin_te`` + +``rsvd152`` + + + + + +.. c:type:: enum nvme_nvmeset_pl_status + + +**Constants** + +``NVME_NVMSET_PL_STATUS_DISABLED`` + +``NVME_NVMSET_PL_STATUS_DTWIN`` + +``NVME_NVMSET_PL_STATUS_NDWIN`` + + + + +.. c:type:: enum nvme_nvmset_pl_events + + +**Constants** + +``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`` + + + + +.. c:type:: struct nvme_aggregate_predictable_lat_event + + +**Definition** + +:: + + struct nvme_aggregate_predictable_lat_event { + __le64 num_entries; + __le16 entries[]; + }; + +**Members** + +``num_entries`` + Number of entries + +``entries`` + Entry list + + + + + +.. c:type:: struct nvme_ana_group_desc + + +**Definition** + +:: + + struct nvme_ana_group_desc { + __le32 grpid; + __le32 nnsids; + __le64 chgcnt; + __u8 state; + __u8 rsvd17[15]; + __le32 nsids[]; + }; + +**Members** + +``grpid`` + ANA group id + +``nnsids`` + Number of namespaces in **nsids** + +``chgcnt`` + Change counter + +``state`` + ANA state + +``rsvd17`` + Reserved + +``nsids`` + List of namespaces + + + + + +.. c:type:: enum nvme_ana_state + + +**Constants** + +``NVME_ANA_STATE_OPTIMIZED`` + +``NVME_ANA_STATE_NONOPTIMIZED`` + +``NVME_ANA_STATE_INACCESSIBLE`` + +``NVME_ANA_STATE_PERSISTENT_LOSS`` + +``NVME_ANA_STATE_CHANGE`` + + + + +.. c:type:: struct nvme_ana_log + + +**Definition** + +:: + + struct nvme_ana_log { + __le64 chgcnt; + __le16 ngrps; + __u8 rsvd10[6]; + struct nvme_ana_group_desc descs[]; + }; + +**Members** + +``chgcnt`` + +``ngrps`` + +``rsvd10`` + +``descs`` + + + + + +.. c:type:: struct nvme_persistent_event_log + + +**Definition** + +:: + + struct nvme_persistent_event_log { + __u8 lid; + __u8 rsvd1[3]; + __le32 tnev; + __le64 tll; + __u8 rv; + __u8 rsvd17; + __le16 lhl; + __le64 ts; + __u8 poh[16]; + __le64 pcc; + __le16 vid; + __le16 ssvid; + char sn[20]; + char mn[40]; + char subnqn[NVME_NQN_LENGTH]; + __le16 gen_number; + __le32 rci; + __u8 rsvd378[102]; + __u8 seb[32]; + }; + +**Members** + +``lid`` + +``rsvd1`` + +``tnev`` + +``tll`` + +``rv`` + +``rsvd17`` + +``lhl`` + +``ts`` + +``poh`` + +``pcc`` + +``vid`` + +``ssvid`` + +``sn`` + +``mn`` + +``subnqn`` + +``gen_number`` + +``rci`` + +``rsvd378`` + +``seb`` + + + + + +.. c:type:: struct nvme_persistent_event_entry + + +**Definition** + +:: + + struct nvme_persistent_event_entry { + __u8 etype; + __u8 etype_rev; + __u8 ehl; + __u8 rsvd3; + __le16 cntlid; + __le64 ets; + __u8 rsvd14[6]; + __le16 vsil; + __le16 el; + }; + +**Members** + +``etype`` + +``etype_rev`` + +``ehl`` + +``rsvd3`` + +``cntlid`` + +``ets`` + +``rsvd14`` + +``vsil`` + +``el`` + + + + + +.. c:type:: enum nvme_persistent_event_types + + +**Constants** + +``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`` + + + + +.. c:type:: struct nvme_fw_commit_event + + +**Definition** + +:: + + 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; + }; + +**Members** + +``old_fw_rev`` + +``new_fw_rev`` + +``fw_commit_action`` + +``fw_slot`` + +``sct_fw`` + +``sc_fw`` + +``vndr_assign_fw_commit_rc`` + + + + + +.. c:type:: struct nvme_time_stamp_change_event + + +**Definition** + +:: + + struct nvme_time_stamp_change_event { + __le64 previous_timestamp; + __le64 ml_secs_since_reset; + }; + +**Members** + +``previous_timestamp`` + +``ml_secs_since_reset`` + + + + + +.. c:type:: struct nvme_power_on_reset_info_list + + +**Definition** + +:: + + 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; + }; + +**Members** + +``cid`` + +``fw_act`` + +``op_in_prog`` + +``rsvd4`` + +``ctrl_power_cycle`` + +``power_on_ml_seconds`` + +``ctrl_time_stamp`` + + + + + +.. c:type:: struct nvme_nss_hw_err_event + + +**Definition** + +:: + + struct nvme_nss_hw_err_event { + __le16 nss_hw_err_event_code; + __u8 rsvd2[2]; + __u8 *add_hw_err_info; + }; + +**Members** + +``nss_hw_err_event_code`` + +``rsvd2`` + +``add_hw_err_info`` + + + + + +.. c:type:: struct nvme_change_ns_event + + +**Definition** + +:: + + struct nvme_change_ns_event { + __le32 nsmgt_cdw10; + __u8 rsvd4[4]; + __le64 nsze; + __u8 rsvd16[8]; + __le64 nscap; + __u8 flbas; + __u8 dps; + __u8 nmic; + __u8 rsvd35; + __le32 ana_grp_id; + __le16 nvmset_id; + __le16 rsvd42; + __le32 nsid; + }; + +**Members** + +``nsmgt_cdw10`` + +``rsvd4`` + +``nsze`` + +``rsvd16`` + +``nscap`` + +``flbas`` + +``dps`` + +``nmic`` + +``rsvd35`` + +``ana_grp_id`` + +``nvmset_id`` + +``rsvd42`` + +``nsid`` + + + + + +.. c:type:: struct nvme_format_nvm_start_event + + +**Definition** + +:: + + struct nvme_format_nvm_start_event { + __le32 nsid; + __u8 fna; + __u8 rsvd5[3]; + __le32 format_nvm_cdw10; + }; + +**Members** + +``nsid`` + +``fna`` + +``rsvd5`` + +``format_nvm_cdw10`` + + + + + +.. c:type:: struct nvme_format_nvm_compln_event + + +**Definition** + +:: + + struct nvme_format_nvm_compln_event { + __le32 nsid; + __u8 smallest_fpi; + __u8 format_nvm_status; + __le16 compln_info; + __le32 status_field; + }; + +**Members** + +``nsid`` + +``smallest_fpi`` + +``format_nvm_status`` + +``compln_info`` + +``status_field`` + + + + + +.. c:type:: struct nvme_sanitize_start_event + + +**Definition** + +:: + + struct nvme_sanitize_start_event { + __le32 sani_cap; + __le32 sani_cdw10; + __le32 sani_cdw11; + }; + +**Members** + +``sani_cap`` + +``sani_cdw10`` + +``sani_cdw11`` + + + + + +.. c:type:: struct nvme_sanitize_compln_event + + +**Definition** + +:: + + struct nvme_sanitize_compln_event { + __le16 sani_prog; + __le16 sani_status; + __le16 cmpln_info; + __u8 rsvd6[2]; + }; + +**Members** + +``sani_prog`` + +``sani_status`` + +``cmpln_info`` + +``rsvd6`` + + + + + +.. c:type:: struct nvme_set_feature_event + + +**Definition** + +:: + + struct nvme_set_feature_event { + __le32 layout; + __le32 cdw_mem[0]; + }; + +**Members** + +``layout`` + +``cdw_mem`` + + + + + +.. c:type:: struct nvme_thermal_exc_event + + +**Definition** + +:: + + struct nvme_thermal_exc_event { + __u8 over_temp; + __u8 threshold; + }; + +**Members** + +``over_temp`` + +``threshold`` + + + + + +.. c:type:: struct nvme_lba_rd + + +**Definition** + +:: + + struct nvme_lba_rd { + __le64 rslba; + __le32 rnlb; + __u8 rsvd12[4]; + }; + +**Members** + +``rslba`` + +``rnlb`` + +``rsvd12`` + + + + + +.. c:type:: struct nvme_lbas_ns_element + + +**Definition** + +:: + + struct nvme_lbas_ns_element { + __le32 neid; + __le32 nlrd; + __u8 ratype; + __u8 rsvd8[7]; + struct nvme_lba_rd lba_rd[]; + }; + +**Members** + +``neid`` + +``nlrd`` + +``ratype`` + +``rsvd8`` + +``lba_rd`` + + + + + +.. c:type:: enum nvme_lba_status_atype + + +**Constants** + +``NVME_LBA_STATUS_ATYPE_SCAN_UNTRACKED`` + +``NVME_LBA_STATUS_ATYPE_SCAN_TRACKED`` + + + + +.. c:type:: struct nvme_lba_status_log + + +**Definition** + +:: + + struct nvme_lba_status_log { + __le32 lslplen; + __le32 nlslne; + __le32 estulb; + __u8 rsvd12[2]; + __le16 lsgc; + struct nvme_lbas_ns_element elements[]; + }; + +**Members** + +``lslplen`` + +``nlslne`` + +``estulb`` + +``rsvd12`` + +``lsgc`` + +``elements`` + + + + + +.. c:type:: struct nvme_eg_event_aggregate_log + + +**Definition** + +:: + + struct nvme_eg_event_aggregate_log { + __le64 nr_entries; + __le16 egids[]; + }; + +**Members** + +``nr_entries`` + +``egids`` + + + + + +.. c:type:: enum nvme_fid_supported_effects + + +**Constants** + +``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`` + +**Description** + +FID Supported and Effects Data Structure definitions + + + + +.. c:type:: struct nvme_fid_supported_effects_log + + +**Definition** + +:: + + struct nvme_fid_supported_effects_log { + __le32 fid_support[NVME_LOG_FID_SUPPORTED_EFFECTS_MAX]; + }; + +**Members** + +``fid_support`` + + +**Description** + +Feature Identifiers Supported and Effects (Log Identifier 12h) + + + + +.. c:type:: struct nvme_boot_partition + + +**Definition** + +:: + + struct nvme_boot_partition { + __u8 lid; + __u8 rsvd1[3]; + __le32 bpinfo; + __u8 rsvd8[8]; + __u8 boot_partition_data[]; + }; + +**Members** + +``lid`` + +``rsvd1`` + +``bpinfo`` + +``rsvd8`` + +``boot_partition_data`` + + + + + +.. c:type:: struct nvme_media_unit_stat_desc + + +**Definition** + +:: + + struct nvme_media_unit_stat_desc { + __le16 muid; + __le16 domainid; + __le16 endgid; + __le16 nvmsetid; + __le16 cap_adj_fctr; + __u8 avl_spare; + __u8 percent_used; + __u8 mucs; + __u8 cio; + }; + +**Members** + +``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 + +``percent_used`` + Percentage Used + +``mucs`` + Number of Channels attached to media units + +``cio`` + Channel Identifiers Offset + + + + + +.. c:type:: struct nvme_media_unit_stat_log + + +**Definition** + +:: + + struct nvme_media_unit_stat_log { + __le16 nmu; + __le16 cchans; + __le16 sel_config; + __u8 rsvd6[10]; + struct nvme_media_unit_stat_desc mus_desc[]; + }; + +**Members** + +``nmu`` + Number unit status descriptor + +``cchans`` + Number of Channels + +``sel_config`` + Selected Configuration + +``rsvd6`` + Reserved + +``mus_desc`` + Media unit statistic descriptors + + + + + +.. c:type:: struct nvme_resv_notification_log + + +**Definition** + +:: + + struct nvme_resv_notification_log { + __le64 lpc; + __u8 rnlpt; + __u8 nalp; + __u8 rsvd9[2]; + __le32 nsid; + __u8 rsvd16[48]; }; **Members** -``vid`` - PCI Vendor ID, the company vendor identifier that is assigned by - the PCI SIG. +``lpc`` -``ssvid`` - PCI Subsystem Vendor ID, the company vendor identifier that is - assigned by the PCI SIG for the subsystem. +``rnlpt`` + See :c:type:`enum nvme_resv_notify_rnlpt `. -``sn`` - Serial Number in ascii +``nalp`` -``mn`` - Model Number in ascii +``rsvd9`` -``fr`` - Firmware Revision in ascii, the currently active firmware - revision for the NVM subsystem +``nsid`` -``rab`` - Recommended Arbitration Burst, reported as a power of two +``rsvd16`` -``ieee`` - IEEE assigned Organization Unique Identifier -``cmic`` - Controller Multipath IO and Namespace Sharing Capabilities of - the controller and NVM subsystem. See :c:type:`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 -``cntlid`` - Controller ID, the NVM subsystem unique controller identifier - associated with the controller. -``ver`` - Version, this field contains the value reported in the Version - register, or property (see :c:type:`enum nvme_registers ` ``NVME_REG_VS``). +.. c:type:: enum nvme_resv_notify_rnlpt -``rtd3r`` - RTD3 Resume Latency, the expected latency in microseconds to resume - from Runtime D3 -``rtd3e`` - RTD3 Exit Latency, the typical latency in microseconds to enter - Runtime D3. +**Constants** -``oaes`` - Optional Async Events Supported, see **enum** nvme_id_ctrl_oaes . +``NVME_RESV_NOTIFY_RNLPT_EMPTY`` -``ctratt`` - Controller Attributes, see **enum** nvme_id_ctrl_ctratt +``NVME_RESV_NOTIFY_RNLPT_REGISTRATION_PREEMPTED`` -``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. +``NVME_RESV_NOTIFY_RNLPT_RESERVATION_RELEASED`` -``cntrltype`` - Controller Type, see :c:type:`enum nvme_id_ctrl_cntrltype ` +``NVME_RESV_NOTIFY_RNLPT_RESERVATION_PREEMPTED`` -``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 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 +.. c:type:: struct nvme_sanitize_log_page -``nvmsr`` - NVM Subsystem Report, see :c:type:`enum nvme_id_ctrl_nvmsr ` + Sanitize Status (Log Identifier 81h) -``vwci`` - VPD Write Cycle Information, see :c:type:`enum nvme_id_ctrl_vwci ` +**Definition** -``mec`` - Management Endpoint Capabilities, see :c:type:`enum nvme_id_ctrl_mec ` +:: -``oacs`` - Optional Admin Command Support,the optional Admin commands and - features supported by the controller, see :c:type:`enum nvme_id_ctrl_oacs `. + struct nvme_sanitize_log_page { + __le16 sprog; + __le16 sstat; + __le32 scdw10; + __le32 eto; + __le32 etbe; + __le32 etce; + __le32 etond; + __le32 etbend; + __le32 etcend; + __u8 rsvd32[480]; + }; -``acl`` - Abort Command Limit, the maximum number of concurrently - executing Abort commands supported by the controller. This is a - 0's based value. +**Members** -``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. +``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``. + +``sstat`` + Sanitize Status (SSTAT): indicates the status associated with + the most recent sanitize operation. See :c:type:`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. + +``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. + +``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. + +``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. + +``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. + +``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. + +``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 -``frmw`` - Firmware Updates indicates capabilities regarding firmware - updates. See :c:type:`enum nvme_id_ctrl_frmw `. -``lpa`` - Log Page Attributes, see :c:type:`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. -``npss`` - Number of Power States Supported, the number of NVM Express - power states supported by the controller, indicating the number - of valid entries in :c:type:`struct nvme_id_ctrl `.psd. This is a 0's - based value. -``avscc`` - Admin Vendor Specific Command Configuration, see - :c:type:`enum nvme_id_ctrl_avscc `. +.. c:type:: enum nvme_sanitize_sstat -``apsta`` - Autonomous Power State Transition Attributes, see - :c:type:`enum nvme_id_ctrl_apsta `. + Sanitize Status (SSTAT) -``wctemp`` - Warning Composite Temperature Threshold indicates - the minimum Composite Temperature field value (see :c:type:`struct - nvme_smart_log `.critical_comp_time) that indicates an overheating - condition during which controller operation continues. +**Constants** -``cctemp`` - Critical Composite Temperature Threshold, field indicates the - minimum Composite Temperature field value (see :c:type:`struct - nvme_smart_log `.critical_comp_time) that indicates a critical - overheating condition. +``NVME_SANITIZE_SSTAT_STATUS_SHIFT`` + Shift amount to get the status value of + the most recent sanitize operation from + the :c:type:`struct nvme_sanitize_log_page `.sstat + field. -``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. +``NVME_SANITIZE_SSTAT_STATUS_MASK`` + Mask to get the status value of the most + recent sanitize operation. -``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. +``NVME_SANITIZE_SSTAT_STATUS_NEVER_SANITIZED`` + The NVM subsystem has never been + sanitized. -``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. +``NVME_SANITIZE_SSTAT_STATUS_COMPLETE_SUCCESS`` + The most recent sanitize operation + completed successfully including any + additional media modification. -``tnvmcap`` - Total NVM Capacity, the total NVM capacity in the NVM subsystem. - The value is in bytes. +``NVME_SANITIZE_SSTAT_STATUS_IN_PROGESS`` + A sanitize operation is currently in progress. -``unvmcap`` - Unallocated NVM Capacity, the unallocated NVM capacity in the - NVM subsystem. The value is in bytes. - **rpmbs** Replay Protected Memory Block Support, see - :c:type:`enum nvme_id_ctrl_rpmbs `. - **edstt** Extended Device Self-test Time, if Device Self-test command is - supported (see :c:type:`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. +``NVME_SANITIZE_SSTAT_STATUS_COMPLETED_FAILED`` + The most recent sanitize operation + failed. -``dsto`` - Device Self-test Options, see :c:type:`enum nvme_id_ctrl_dsto `. +``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. -``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 +``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. -``kas`` - Keep Alive Support indicates the granularity of the Keep Alive - Timer in 100 millisecond units. +``NVME_SANITIZE_SSTAT_COMPLETED_PASSES_MASK`` + Mask to get the number of completed + passes. -``hctma`` - Host Controlled Thermal Management Attributes, see :c:type:`enum nvme_id_ctrl_hctm `. +``NVME_SANITIZE_SSTAT_GLOBAL_DATA_ERASED_SHIFT`` + Shift amount to get the Global + Data Erased value from the + :c:type:`struct nvme_sanitize_log_page `.sstat field. -``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``. +``NVME_SANITIZE_SSTAT_GLOBAL_DATA_ERASED_MASK`` + Mask to get the Global Data Erased + value. -``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``. +``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. -``sanicap`` - Sanitize Capabilities, see :c:type:`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. -``hmmaxd`` - Host Memory Maximum Descriptors Entries indicates the number of - 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. +.. c:type:: struct nvme_zns_changed_zone_log -``endgidmax`` - Endurance Group Identifier Maximum, defines the maximum value of - a valid Endurance Group Identifier for any controller in the NVM - subsystem. + ZNS Changed Zone List log -``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. +**Definition** -``anacap`` - Asymmetric Namespace Access Capabilities, see - :c:type:`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. + struct nvme_zns_changed_zone_log { + __le16 nrzid; + __u8 rsvd2[6]; + __le64 zid[NVME_ZNS_CHANGED_ZONES_MAX]; + }; -``nanagrpid`` - Number of ANA Group Identifiers indicates the number of ANA - groups supported by this controller. +**Members** + +``nrzid`` + +``rsvd2`` + +``zid`` -``pels`` - Persistent Event Log Size indicates the maximum reportable size - for the Persistent Event Log. -``sqes`` - Submission Queue Entry Size, see :c:type:`enum nvme_id_ctrl_sqes `. -``cqes`` - Completion Queue Entry Size, see :c:type:`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. -``nn`` - Number of Namespaces indicates the maximum value of a valid - nsid for the NVM subsystem. If the MNAN (:c:type:`struct nvme_id_ctrl `.mnan - field is cleared to 0h, then this field also indicates the - maximum number of namespaces supported by the NVM. subsystem. +.. c:type:: enum nvme_zns_zt -``oncs`` - Optional NVM Command Support, see :c:type:`enum nvme_id_ctrl_oncs `. -``fuses`` - Fused Operation Support, see :c:type:`enum nvme_id_ctrl_fuses `. +**Constants** -``fna`` - Format NVM Attributes, see :c:type:`enum nvme_id_ctrl_fna `. +``NVME_ZONE_TYPE_SEQWRITE_REQ`` -``vwc`` - Volatile Write Cache, see :c:type:`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. -``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. -``nvscc`` - NVM Vendor Specific Command Configuration, see - :c:type:`enum nvme_id_ctrl_nvscc `. +.. c:type:: enum nvme_zns_za -``nwpc`` - Namespace Write Protection Capabilities, see - :c:type:`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. +**Constants** -``ocfs`` - Optional Copy Formats Supported, each bit n means controller supports - Copy Format n. +``NVME_ZNS_ZA_ZFC`` -``sgls`` - SGL Support, see :c:type:`enum nvme_id_ctrl_sgls ` +``NVME_ZNS_ZA_FZR`` -``mnan`` - Maximum Number of Allowed Namespaces indicates the maximum - number of namespaces supported by the NVM subsystem. +``NVME_ZNS_ZA_RZR`` -``subnqn`` - NVM Subsystem NVMe Qualified Name, UTF-8 null terminated string +``NVME_ZNS_ZA_ZRWAV`` -``ioccsz`` - I/O Queue Command Capsule Supported Size, defines the maximum - I/O command capsule size in 16 byte units. +``NVME_ZNS_ZA_ZDEV`` -``iorcsz`` - I/O Queue Response Capsule Supported Size, defines the maximum - 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. -``fcatt`` - Fabrics Controller Attributes, see :c:type:`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. +.. c:type:: enum nvme_zns_zs -``ofcs`` - Optional Fabric Commands Support, see :c:type:`enum nvme_id_ctrl_ofcs `. -``psd`` - Power State Descriptors, see :c:type:`struct nvme_id_psd `. +**Constants** -``vs`` - Vendor Specific +``NVME_ZNS_ZS_EMPTY`` +``NVME_ZNS_ZS_IMPL_OPEN`` +``NVME_ZNS_ZS_EXPL_OPEN`` +``NVME_ZNS_ZS_CLOSED`` +``NVME_ZNS_ZS_READ_ONLY`` -.. c:type:: enum nvme_id_ctrl_cmic +``NVME_ZNS_ZS_FULL`` +``NVME_ZNS_ZS_OFFLINE`` -**Constants** -``NVME_CTRL_CMIC_MULTI_PORT`` - *undescribed* -``NVME_CTRL_CMIC_MULTI_CTRL`` - *undescribed* -``NVME_CTRL_CMIC_MULTI_SRIOV`` - *undescribed* +.. c:type:: struct nvme_zns_desc -``NVME_CTRL_CMIC_MULTI_ANA_REPORTING`` - *undescribed* +**Definition** +:: + struct nvme_zns_desc { + __u8 zt; + __u8 zs; + __u8 za; + __u8 zai; + __u8 rsvd4[4]; + __le64 zcap; + __le64 zslba; + __le64 wp; + __u8 rsvd32[32]; + }; -.. c:type:: enum nvme_id_ctrl_oaes +**Members** - The typical latency in microseconds to enter Runtime D3 +``zt`` -**Constants** +``zs`` -``NVME_CTRL_OAES_NA`` - *undescribed* +``za`` -``NVME_CTRL_OAES_FA`` - *undescribed* +``zai`` -``NVME_CTRL_OAES_ANA`` - *undescribed* +``rsvd4`` -``NVME_CTRL_OAES_PLEA`` - *undescribed* +``zcap`` -``NVME_CTRL_OAES_LBAS`` - : +``zslba`` -``NVME_CTRL_OAES_EGE`` - *undescribed* +``wp`` +``rsvd32`` -.. c:type:: enum nvme_id_ctrl_ctratt -**Constants** +.. c:type:: struct nvme_zone_report -``NVME_CTRL_CTRATT_128_ID`` - *undescribed* -``NVME_CTRL_CTRATT_NON_OP_PSP`` - *undescribed* +**Definition** -``NVME_CTRL_CTRATT_NVM_SETS`` - *undescribed* +:: -``NVME_CTRL_CTRATT_READ_RECV_LVLS`` - *undescribed* + struct nvme_zone_report { + __le64 nr_zones; + __u8 rsvd8[56]; + struct nvme_zns_desc entries[]; + }; -``NVME_CTRL_CTRATT_ENDURANCE_GROUPS`` - *undescribed* +**Members** -``NVME_CTRL_CTRATT_PREDICTABLE_LAT`` - *undescribed* +``nr_zones`` + Number of descriptors in **entries** -``NVME_CTRL_CTRATT_TBKAS`` - *undescribed* +``rsvd8`` + Reserved -``NVME_CTRL_CTRATT_NAMESPACE_GRANULARITY`` - *undescribed* +``entries`` + Zoned namespace descriptors -``NVME_CTRL_CTRATT_SQ_ASSOCIATIONS`` - *undescribed* -``NVME_CTRL_CTRATT_UUID_LIST`` - *undescribed* +.. c:type:: struct nvme_lba_status_desc -.. c:type:: enum nvme_id_ctrl_cntrltype +**Definition** -**Constants** +:: -``NVME_CTRL_CNTRLTYPE_IO`` - *undescribed* + struct nvme_lba_status_desc { + __le64 dslba; + __le32 nlb; + __u8 rsvd12; + __u8 status; + __u8 rsvd14[2]; + }; -``NVME_CTRL_CNTRLTYPE_DISCOVERY`` - *undescribed* +**Members** -``NVME_CTRL_CNTRLTYPE_ADMIN`` - *undescribed* +``dslba`` +``nlb`` +``rsvd12`` +``status`` -.. c:type:: enum nvme_id_ctrl_nvmsr +``rsvd14`` - This field reports information associated with the NVM Subsystem, see :c:type:`struct nvme_id_ctrl `.nvmsr. -**Constants** -``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. -``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. +.. c:type:: struct nvme_lba_status +**Definition** -.. c:type:: 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 :c:type:`struct nvme_id_ctrl `.vwci. + struct nvme_lba_status { + __le32 nlsd; + __u8 cmpc; + __u8 rsvd5[3]; + struct nvme_lba_status_desc descs[]; + }; -**Constants** +**Members** -``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. +``nlsd`` -``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. +``cmpc`` +``rsvd5`` +``descs`` -.. c:type:: enum nvme_id_ctrl_mec - Flags indicatings the capabilities of the Management Endpoint in the Controller, :c:type:`struct nvme_id_ctrl `.mec. -**Constants** -``NVME_CTRL_MEC_SMBUSME`` - If set, then the NVM Subsystem contains a Management - Endpoint on an SMBus/I2C port. +.. c:type:: struct nvme_feat_auto_pst -``NVME_CTRL_MEC_PCIEME`` - If set, then the NVM Subsystem contains a Management - Endpoint on a PCIe port. +**Definition** +:: + struct nvme_feat_auto_pst { + __le64 apst_entry[32]; + }; -.. c:type:: enum nvme_id_ctrl_oacs +**Members** - Flags indicating the optional Admin commands and features supported by the controller, see :c:type:`struct nvme_id_ctrl `.oacs. +``apst_entry`` + See :c:type:`enum nvme_apst_entry ` -**Constants** -``NVME_CTRL_OACS_SECURITY`` - If set, then the controller supports the - Security Send and Security Receive commands. -``NVME_CTRL_OACS_FORMAT`` - If set then the controller supports the Format - NVM command. -``NVME_CTRL_OACS_FW`` - If set, then the controller supports the - Firmware Commit and Firmware Image Download commands. -``NVME_CTRL_OACS_NS_MGMT`` - If set, then the controller supports the - Namespace Management capability +.. c:type:: enum nvme_apst_entry -``NVME_CTRL_OACS_SELF_TEST`` - If set, then the controller supports the Device - Self-test command. -``NVME_CTRL_OACS_DIRECTIVES`` - If set, then the controller supports Directives - and the Directive Send and Directive Receive - commands. +**Constants** -``NVME_CTRL_OACS_NVME_MI`` - If set, then the controller supports the NVMe-MI - Send and NVMe-MI Receive commands. +``NVME_APST_ENTRY_ITPS_SHIFT`` -``NVME_CTRL_OACS_VIRT_MGMT`` - If set, then the controller supports the - Virtualization Management command. +``NVME_APST_ENTRY_ITPT_SHIFT`` -``NVME_CTRL_OACS_DBBUF_CFG`` - If set, then the controller supports the - Doorbell Buffer Config command. +``NVME_APST_ENTRY_ITPS_MASK`` -``NVME_CTRL_OACS_LBA_STATUS`` - If set, then the controller supports the Get LBA - Status capability. +``NVME_APST_ENTRY_ITPT_MASK`` -.. c:type:: enum nvme_id_ctrl_frmw +.. c:type:: struct nvme_metadata_element_desc - Flags and values indicates capabilities regarding firmware updates from :c:type:`struct nvme_id_ctrl `.frmw. + Metadata Element Descriptor -**Constants** +**Definition** -``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. + struct nvme_metadata_element_desc { + __u8 type; + __u8 rev; + __u16 len; + __u8 val[0]; + }; -``NVME_CTRL_FRMW_FW_ACT_NO_RESET`` - If set, the controller supports firmware - activation without a reset. +**Members** +``type`` + Element Type (ET) +``rev`` + Element Revision (ER) +``len`` + Element Length (ELEN) -.. c:type:: enum nvme_id_ctrl_lpa +``val`` + Element Value (EVAL), UTF-8 string - Flags indicating optional attributes for log pages that are accessed via the Get Log Page command. -**Constants** -``NVME_CTRL_LPA_SMART_PER_NS`` - *undescribed* -``NVME_CTRL_LPA_CMD_EFFECTS`` - *undescribed* -``NVME_CTRL_LPA_EXTENDED`` - *undescribed* +.. c:type:: struct nvme_host_metadata -``NVME_CTRL_LPA_TELEMETRY`` - *undescribed* + Host Metadata Data Structure -``NVME_CTRL_LPA_PERSETENT_EVENT`` - *undescribed* +**Definition** + +:: + + struct nvme_host_metadata { + __u8 ndesc; + __u8 rsvd1; + union { + struct nvme_metadata_element_desc descs[0]; + __u8 descs_buf[4094]; + }; + }; +**Members** +``ndesc`` + Number of metadata element descriptors +``rsvd1`` + Reserved -.. c:type:: enum nvme_id_ctrl_avscc +``{unnamed_union}`` + anonymous - Flags indicating the configuration settings for Admin Vendor Specific command handling. +``descs`` + Metadata element descriptors -**Constants** +``descs_buf`` + Metadata element descriptor buffer -``NVME_CTRL_AVSCC_AVS`` - If set, all Admin Vendor Specific Commands use the - optional vendor specific command format with NDT and - NDM fields. -.. c:type:: enum nvme_id_ctrl_apsta +.. c:type:: enum nvme_ctrl_metadata_type - Flags indicating the attributes of the autonomous power state transition feature. + Controller Metadata Element Types **Constants** -``NVME_CTRL_APSTA_APST`` - If set, then the controller supports autonomous power - state transitions. - +``NVME_CTRL_METADATA_OS_CTRL_NAME`` + Name of the controller in + the operating system. +``NVME_CTRL_METADATA_OS_DRIVER_NAME`` + Name of the driver in the + operating system. +``NVME_CTRL_METADATA_OS_DRIVER_VER`` + Version of the driver in + the operating system. -.. c:type:: enum nvme_id_ctrl_rpmbs - - This field indicates if the controller supports one or more Replay Protected Memory Blocks, from :c:type:`struct nvme_id_ctrl `.rpmbs. +``NVME_CTRL_METADATA_PRE_BOOT_CTRL_NAME`` + Name of the controller in + the pre-boot environment. -**Constants** +``NVME_CTRL_METADATA_PRE_BOOT_DRIVER_NAME`` + Name of the driver in the + pre-boot environment. -``NVME_CTRL_RPMBS_NR_UNITS`` - Mask to get the value of the Number of RPMB Units +``NVME_CTRL_METADATA_PRE_BOOT_DRIVER_VER`` + Version of the driver in the + pre-boot environment. -``NVME_CTRL_RPMBS_AUTH_METHOD`` - Mask to get the value of the Authentication Method +``NVME_CTRL_METADATA_SYS_PROC_MODEL`` + Model of the processor. -``NVME_CTRL_RPMBS_TOTAL_SIZE`` - Mask to get the value of Total Size +``NVME_CTRL_METADATA_CHIPSET_DRV_NAME`` + Chipset driver name. -``NVME_CTRL_RPMBS_ACCESS_SIZE`` - Mask to get the value of Access Size +``NVME_CTRL_METADATA_CHIPSET_DRV_VERSION`` + Chipsset 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. -.. c:type:: enum nvme_id_ctrl_dsto +``NVME_CTRL_METADATA_OS_DRIVER_FILENAME`` + Operating system driver filename. - Flags indicating the optional Device Self-test command or operation behaviors supported by the controller or NVM subsystem. +``NVME_CTRL_METADATA_DISPLAY_DRV_NAME`` + Display driver name. -**Constants** +``NVME_CTRL_METADATA_DISPLAY_DRV_VERSION`` + Display driver version. -``NVME_CTRL_DSTO_ONE_DST`` - If set, then the NVM subsystem supports only one - device self-test operation in progress at a time. +``NVME_CTRL_METADATA_HOST_DET_FAIL_REC`` + Failure record. -.. c:type:: enum nvme_id_ctrl_hctm +.. c:type:: enum nvme_ns_metadata_type - Flags indicate the attributes of the host controlled thermal management feature + Namespace Metadata Element Types **Constants** -``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``. +``NVME_NS_METADATA_OS_NS_NAME`` + Name of the namespace in the the + operating system +``NVME_NS_METADATA_PRE_BOOT_NS_NAME`` + Name of the namespace in the pre-boot + environment. +``NVME_NS_METADATA_OS_NS_QUAL_1`` + First qualifier of the Operating System + Namespace Name. +``NVME_NS_METADATA_OS_NS_QUAL_2`` + Second qualifier of the Operating System + Namespace Name. -.. c:type:: enum nvme_id_ctrl_sanicap - Indicates attributes for sanitize operations. -**Constants** -``NVME_CTRL_SANICAP_CES`` - Crypto Erase Support. If set, then the - controller supports the Crypto Erase sanitize operation. +.. c:type:: struct nvme_timestamp -``NVME_CTRL_SANICAP_BES`` - Block Erase Support. If set, then the controller - supports the Block Erase sanitize operation. -``NVME_CTRL_SANICAP_OWS`` - Overwrite Support. If set, then the controller - supports the Overwrite sanitize operation. +**Definition** -``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. +:: -``NVME_CTRL_SANICAP_NODMMAS`` - No-Deallocate Modifies Media After Sanitize, - mask to extract value. + struct nvme_timestamp { + __u8 timestamp[6]; + __u8 attr; + __u8 rsvd; + }; +**Members** +``timestamp`` +``attr`` -.. c:type:: enum nvme_id_ctrl_anacap +``rsvd`` - This field indicates the capabilities associated with Asymmetric Namespace Access Reporting. -**Constants** -``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. +.. c:type:: struct nvme_lba_range_type_entry -``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. +**Definition** -``NVME_CTRL_ANACAP_GRPID_NO_CHG`` - If set, then the ANAGRPID field in the - Identify Namespace data structure - (:c:type:`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. + struct nvme_lba_range_type_entry { + __u8 type; + __u8 attributes; + __u8 rsvd2[14]; + __u64 slba; + __u64 nlb; + __u8 guid[16]; + __u8 rsvd48[16]; + }; +**Members** +``type`` +``attributes`` -.. c:type:: enum nvme_id_ctrl_sqes +``rsvd2`` - Defines the required and maximum Submission Queue entry size when using the NVM Command Set. +``slba`` -**Constants** +``nlb`` -``NVME_CTRL_SQES_MIN`` - Mask to get the value of the required Submission Queue - Entry size when using the NVM Command Set. +``guid`` -``NVME_CTRL_SQES_MAX`` - Mask to get the value of the maximum Submission Queue - entry size when using the NVM Command Set. +``rsvd48`` -.. c:type:: enum - Defines the required and maximum Completion Queue entry size when using the NVM Command Set. +.. c:type:: enum nvme_lbart -**Constants** -``NVME_CTRL_CQES_MIN`` - Mask to get the value of the required Completion Queue - Entry size when using the NVM Command Set. +**Constants** -``NVME_CTRL_CQES_MAX`` - Mask to get the value of the maximum Completion Queue - entry size when using the NVM Command Set. +``NVME_LBART_TYPE_GP`` +``NVME_LBART_TYPE_FS`` +``NVME_LBART_TYPE_RAID`` +``NVME_LBART_TYPE_CACHE`` -.. c:type:: enum nvme_id_ctrl_oncs +``NVME_LBART_TYPE_SWAP`` - This field indicates the optional NVM commands and features supported by the controller. +``NVME_LBART_ATTRIB_TEMP`` -**Constants** +``NVME_LBART_ATTRIB_HIDE`` -``NVME_CTRL_ONCS_COMPARE`` - If set, then the controller supports - the Compare command. -``NVME_CTRL_ONCS_WRITE_UNCORRECTABLE`` - If set, then the controller supports - the Write Uncorrectable command. -``NVME_CTRL_ONCS_DSM`` - If set, then the controller supports - the Dataset Management command. -``NVME_CTRL_ONCS_WRITE_ZEROES`` - If set, then the controller supports - the Write Zeroes command. +.. c:type:: struct nvme_lba_range_type -``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. -``NVME_CTRL_ONCS_RESERVATIONS`` - If set, then the controller supports - reservations. +**Definition** -``NVME_CTRL_ONCS_TIMESTAMP`` - If set, then the controller supports - the Timestamp feature. +:: -``NVME_CTRL_ONCS_VERIFY`` - If set, then the controller supports - the Verify command. + struct nvme_lba_range_type { + struct nvme_lba_range_type_entry entry[NVME_FEAT_LBA_RANGE_MAX]; + }; +**Members** +``entry`` -.. c:type:: enum nvme_id_ctrl_fuses - This field indicates the fused operations that the controller supports. -**Constants** -``NVME_CTRL_FUSES_COMPARE_AND_WRITE`` - If set, then the controller supports the - Compare and Write fused operation. +.. c:type:: struct nvme_plm_config +**Definition** +:: -.. c:type:: enum nvme_id_ctrl_fna + struct nvme_plm_config { + __le16 ee; + __u8 rsvd2[30]; + __le64 dtwinrt; + __le64 dtwinwt; + __le64 dtwintt; + __u8 rsvd56[456]; + }; - This field indicates attributes for the Format NVM command. +**Members** -**Constants** +``ee`` -``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. +``rsvd2`` -``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. +``dtwinrt`` -``NVME_CTRL_FNA_CRYPTO_ERASE`` - If set, then cryptographic erase is - supported. If cleared, then cryptographic - erase is not supported. +``dtwinwt`` +``dtwintt`` +``rsvd56`` -.. c:type:: enum nvme_id_ctrl_vwc -**Constants** -``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``. +.. c:type:: struct nvme_feat_host_behavior -``NVME_CTRL_VWC_FLUSH`` - Mask to get the value of the flush command behavior. +**Definition** +:: + struct nvme_feat_host_behavior { + __u8 acre; + __u8 rsvd1[511]; + }; -.. c:type:: enum nvme_id_ctrl_nvscc +**Members** - This field indicates the configuration settings for NVM Vendor Specific command handling. +``acre`` -**Constants** +``rsvd1`` -``NVME_CTRL_NVSCC_FMT`` - If set, all NVM Vendor Specific Commands use the - format format with NDT and NDM fields. -.. c:type:: enum nvme_id_ctrl_nwpc +.. c:type:: enum (anonymous) - This field indicates the optional namespace write protection capabilities supported by the controller. **Constants** -``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. +``NVME_ENABLE_ACRE`` -``NVME_CTRL_NWPC_WRITE_PROTECT_POWER_CYCLE`` - If set, then the controller - 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. +.. c:type:: struct nvme_dsm_range -.. c:type:: enum nvme_id_ctrl_sgls +**Definition** - This field indicates if SGLs are supported for the NVM Command Set and the particular SGL types supported. +:: -**Constants** + struct nvme_dsm_range { + __le32 cattr; + __le32 nlb; + __le64 slba; + }; -``NVME_CTRL_SGLS_SUPPORTED`` - *undescribed* +**Members** -``NVME_CTRL_SGLS_KEYED`` - *undescribed* +``cattr`` -``NVME_CTRL_SGLS_BIT_BUCKET`` - *undescribed* +``nlb`` -``NVME_CTRL_SGLS_MPTR_BYTE_ALIGNED`` - *undescribed* +``slba`` -``NVME_CTRL_SGLS_OVERSIZE`` - *undescribed* -``NVME_CTRL_SGLS_MPTR_SGL`` - *undescribed* -``NVME_CTRL_SGLS_OFFSET`` - *undescribed* -``NVME_CTRL_SGLS_TPORT`` - *undescribed* +.. c:type:: struct nvme_copy_range +**Definition** -.. c:type:: enum nvme_id_ctrl_fcatt +:: - This field indicates attributes of the controller that are specific to NVMe over Fabrics. + struct nvme_copy_range { + __u8 rsvd0[8]; + __le64 slba; + __le16 nlb; + __u8 rsvd18[6]; + __le32 eilbrt; + __le16 elbatm; + __le16 elbat; + }; -**Constants** +**Members** -``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. +``rsvd0`` +``slba`` +``nlb`` +``rsvd18`` -.. c:type:: enum nvme_id_ctrl_ofcs +``eilbrt`` - Indicate whether the controller supports optional fabric commands. +``elbatm`` -**Constants** +``elbat`` -``NVME_CTRL_OFCS_DISCONNECT`` - If set, then the controller supports the - Disconnect command and deletion of individual - I/O Queues. -.. c:type:: struct nvme_lbaf +.. c:type:: struct nvme_registered_ctrl - LBA Format Data Structure **Definition** :: - struct nvme_lbaf { - __le16 ms; - __u8 ds; - __u8 rp; + struct nvme_registered_ctrl { + __le16 cntlid; + __u8 rcsts; + __u8 rsvd3[5]; + __le64 hostid; + __le64 rkey; }; **Members** -``ms`` - Metadata Size indicates the number of metadata bytes provided per LBA - based on the LBA Data Size indicated. +``cntlid`` -``ds`` - LBA Data Size indicates the LBA data size supported, reported as a - power of two. +``rcsts`` -``rp`` - Relative Performance, see :c:type:`enum nvme_lbaf_rp `. +``rsvd3`` +``hostid`` +``rkey`` -.. c:type:: enum nvme_lbaf_rp - This field indicates the relative performance of the LBA format indicated relative to other LBA formats supported by the controller. -**Constants** +.. c:type:: struct nvme_registered_ctrl_ext -``NVME_LBAF_RP_BEST`` - Best performance -``NVME_LBAF_RP_BETTER`` - Better performance +**Definition** -``NVME_LBAF_RP_GOOD`` - Good performance +:: -``NVME_LBAF_RP_DEGRADED`` - Degraded performance + struct nvme_registered_ctrl_ext { + __le16 cntlid; + __u8 rcsts; + __u8 rsvd3[5]; + __le64 rkey; + __u8 hostid[16]; + __u8 rsvd32[32]; + }; -``NVME_LBAF_RP_MASK`` - Mask to get the relative performance value from the - field +**Members** +``cntlid`` +``rcsts`` +``rsvd3`` -.. c:type:: struct nvme_id_ns +``rkey`` - Identify Namespace data structure +``hostid`` -**Definition** +``rsvd32`` -:: - struct nvme_id_ns { - __le64 nsze; - __le64 ncap; - __le64 nuse; - __u8 nsfeat; - __u8 nlbaf; - __u8 flbas; - __u8 mc; - __u8 dpc; - __u8 dps; - __u8 nmic; - __u8 rescap; - __u8 fpi; - __u8 dlfeat; - __le16 nawun; - __le16 nawupf; - __le16 nacwu; - __le16 nabsn; - __le16 nabo; - __le16 nabspf; - __le16 noiob; - __u8 nvmcap[16]; - __le16 npwg; - __le16 npwa; - __le16 npdg; - __le16 npda; - __le16 nows; - __u8 rsvd74[18]; - __le32 anagrpid; - __u8 rsvd96[3]; - __u8 nsattr; - __le16 nvmsetid; - __le16 endgid; - __u8 nguid[16]; - __u8 eui64[8]; - struct nvme_lbaf lbaf[16]; - __u8 rsvd192[192]; - __u8 vs[3712]; - }; -**Members** -``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. -``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. +.. c:type:: struct nvme_resv_status -``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. -``nsfeat`` - Namespace Features, see :c:type:`enum nvme_id_nsfeat `. +**Definition** -``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 :c:type:`struct nvme_id_ns `.labf. +:: -``flbas`` - Formatted LBA Size, see :c:type:`enum nvme_id_ns_flbas `. + struct nvme_resv_status { + __le32 gen; + __u8 rtype; + __u8 regctl[2]; + __u8 rsvd7[2]; + __u8 ptpls; + __u8 rsvd10[14]; + union { + struct { + __u8 rsvd24[40]; + struct nvme_registered_ctrl_ext regctl_eds[0]; + }; + struct nvme_registered_ctrl regctl_ds[0]; + }; + }; -``mc`` - Metadata Capabilities, see :c:type:`enum nvme_id_ns_mc `. +**Members** -``dpc`` - End-to-end Data Protection Capabilities, see - :c:type:`enum nvme_id_ns_dpc `. +``gen`` -``dps`` - End-to-end Data Protection Type Settings, see - :c:type:`enum nvme_id_ns_dps `. +``rtype`` -``nmic`` - Namespace Multi-path I/O and Namespace Sharing Capabilities, see - :c:type:`enum nvme_id_ns_nmic `. +``regctl`` -``rescap`` - Reservation Capabilities, see :c:type:`enum nvme_id_ns_rescap `. +``rsvd7`` -``fpi`` - Format Progress Indicator, see :c:type:`enum nvme_nd_ns_fpi `. +``ptpls`` -``dlfeat`` - Deallocate Logical Block Features, see :c:type:`enum nvme_id_ns_dlfeat `. +``rsvd10`` -``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. +``{unnamed_union}`` + anonymous -``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. +``{unnamed_struct}`` + anonymous -``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. +``rsvd24`` -``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. +``regctl_eds`` -``nabo`` - Namespace Atomic Boundary Offset indicates the LBA on this - namespace where the first atomic boundary starts. +``regctl_ds`` -``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. -``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. -``nvmcap`` - NVM Capacity indicates the total size of the NVM allocated to - 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. -``npwa`` - Namespace Preferred Write Alignment indicates the recommended - write alignment in logical blocks for this namespace. This is a - 0's based value. +.. c:type:: struct nvme_streams_directive_params -``npdg`` - Namespace Preferred Deallocate Granularity indicates the - 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 +**Definition** + +:: + + struct nvme_streams_directive_params { + __le16 msl; + __le16 nssa; + __le16 nsso; + __u8 nssc; + __u8 rsvd[9]; + __le32 sws; + __le16 sgs; + __le16 nsa; + __le16 nso; + __u8 rsvd2[6]; + }; + +**Members** -``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. +``msl`` -``anagrpid`` - ANA Group Identifier indicates the ANA Group Identifier of the - ANA group of which the namespace is a member. +``nssa`` -``nsattr`` - Namespace Attributes, see :c:type:`enum nvme_id_ns_attr `. +``nsso`` -``nvmsetid`` - NVM Set Identifier indicates the NVM Set with which this - namespace is associated. +``nssc`` -``endgid`` - Endurance Group Identifier indicates the Endurance Group with - which this namespace is associated. +``rsvd`` -``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 +``sws`` -``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 - remains fixed throughout the life of the namespace and is - preserved across namespace and controller operations +``sgs`` -``lbaf`` - LBA Format, see :c:type:`struct nvme_lbaf `. +``nsa`` -``vs`` - Vendor Specific +``nso`` +``rsvd2`` -.. c:type:: enum nvme_id_nsfeat - This field defines features of the namespace. +.. c:type:: struct nvme_streams_directive_status -**Constants** -``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. +**Definition** -``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. +:: -``NVME_NS_FEAT_DULBE`` - If set, indicates that the controller supports the - 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. + struct nvme_streams_directive_status { + __le16 osc; + __le16 sid[]; + }; -``NVME_NS_FEAT_ID_REUSE`` - *undescribed* +**Members** -``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 +``osc`` +``sid`` -.. c:type:: enum nvme_id_ns_flbas - This field indicates the LBA data size & metadata size combination that the namespace has been formatted with -**Constants** +.. c:type:: struct nvme_id_directives -``NVME_NS_FLBAS_LOWER_MASK`` - Mask to get the index of one of the supported LBA Formats's least significant - 4bits indicated in :c:type:`struct nvme_id_ns `.lbaf. -``NVME_NS_FLBAS_META_EXT`` - Applicable only if format contains metadata. If - this bit is set, indicates that the metadata is - transferred at the end of the data LBA, creating an - extended data LBA. If cleared, indicates that all - of the metadata for a command is transferred as a - separate contiguous buffer of data. +**Definition** -``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. +:: + struct nvme_id_directives { + __u8 supported[32]; + __u8 enabled[32]; + __u8 rsvd64[4032]; + }; -.. c:type:: enum nvme_id_ns_mc +**Members** - This field indicates the capabilities for metadata. +``supported`` -**Constants** +``enabled`` -``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. +``rsvd64`` -``NVME_NS_MC_SEPARATE`` - If set, indicates that the namespace supports the - metadata being transferred as part of an extended data LBA. -.. c:type:: enum nvme_id_ns_dpc +.. c:type:: enum (anonymous) - This field indicates the capabilities for the end-to-end data protection feature. **Constants** -``NVME_NS_DPC_PI_TYPE1`` - If set, indicates that the namespace supports - Protection Information Type 1. +``NVME_ID_DIR_ID_BIT`` + Identify directive is supported -``NVME_NS_DPC_PI_TYPE2`` - If set, indicates that the namespace supports - Protection Information Type 2. +``NVME_ID_DIR_SD_BIT`` + Streams directive is supported -``NVME_NS_DPC_PI_TYPE3`` - If set, indicates that the namespace supports - 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. -``NVME_NS_DPC_PI_LAST`` - If set, indicates that the namespace supports - protection information transferred as the last eight - bytes of metadata. +.. c:type:: struct nvme_host_mem_buf_attrs +**Definition** -.. c:type:: enum nvme_id_ns_dps +:: - This field indicates the Type settings for the end-to-end data protection feature. + struct nvme_host_mem_buf_attrs { + __le32 hsize; + __le32 hmdlal; + __le32 hmdlau; + __le32 hmdlec; + __u8 rsvd16[4080]; + }; -**Constants** +**Members** -``NVME_NS_DPS_PI_NONE`` - Protection information is not enabled +``hsize`` -``NVME_NS_DPS_PI_TYPE1`` - Protection information is enabled, Type 1 +``hmdlal`` -``NVME_NS_DPS_PI_TYPE2`` - Protection information is enabled, Type 2 +``hmdlau`` -``NVME_NS_DPS_PI_TYPE3`` - Protection information is enabled, Type 3 +``hmdlec`` -``NVME_NS_DPS_PI_MASK`` - Mask to get the value of the PI type +``rsvd16`` -``NVME_NS_DPS_PI_FIRST`` - If set, indicates that the protection information, if - enabled, is transferred as the first eight bytes of - metadata. -.. c:type:: enum nvme_id_ns_nmic +.. c:type:: enum nvme_ae_type - This field specifies multi-path I/O and namespace sharing capabilities of the namespace. **Constants** -``NVME_NS_NMIC_SHARED`` - If set, then the namespace may be attached to two or - more controllers in the NVM subsystem concurrently +``NVME_AER_ERROR`` +``NVME_AER_SMART`` +``NVME_AER_NOTICE`` +``NVME_AER_CSS`` -.. c:type:: enum nvme_id_ns_rescap +``NVME_AER_VS`` - This field indicates the reservation capabilities of the namespace. -**Constants** -``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. +.. c:type:: enum nvme_ae_info_error -``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. +**Constants** -``NVME_NS_RESCAP_EARO`` - If set, indicates that the namespace supports the - Exclusive Access - Registrants Only reservation type. +``NVME_AER_ERROR_INVALID_DB_REG`` -``NVME_NS_RESCAP_WEAR`` - If set, indicates that the namespace supports the - Write Exclusive - All Registrants reservation type. +``NVME_AER_ERROR_INVALID_DB_VAL`` -``NVME_NS_RESCAP_EAAR`` - If set, indicates that the namespace supports the - Exclusive Access - All Registrants reservation type. +``NVME_AER_ERROR_DIAG_FAILURE`` -``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. +``NVME_AER_ERROR_PERSISTENT_INTERNAL_ERROR`` +``NVME_AER_ERROR_TRANSIENT_INTERNAL_ERROR`` +``NVME_AER_ERROR_FW_IMAGE_LOAD_ERROR`` -.. c:type:: 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. -**Constants** +.. c:type:: enum nvme_ae_info_smart -``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. +**Constants** +``NVME_AER_SMART_SUBSYSTEM_RELIABILITY`` +``NVME_AER_SMART_TEMPERATURE_THRESHOLD`` +``NVME_AER_SMART_SPARE_THRESHOLD`` -.. c:type:: enum nvme_id_ns_dlfeat - This field indicates information about features that affect deallocating logical blocks for this namespace. -**Constants** -``NVME_NS_DLFEAT_RB`` - Mask to get the value of the read behavior +.. c:type:: enum nvme_ae_info_css_nvm -``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. +**Constants** -``NVME_NS_DLFEAT_RB_ALL_FS`` - A deallocated logical block returns all bytes - set to FFh. +``NVME_AER_CSS_NVM_RESERVATION`` -``NVME_NS_DLFEAT_WRITE_ZEROES`` - If set, indicates that the controller supports - the Deallocate bit in the Write Zeroes command - for this namespace. +``NVME_AER_CSS_NVM_SANITIZE_COMPLETED`` -``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 +``NVME_AER_CSS_NVM_UNEXPECTED_SANITIZE_DEALLOC`` -.. c:type:: enum nvme_id_ns_attr +.. c:type:: enum nvme_ae_info_notice - Specifies attributes of the namespace. **Constants** -``NVME_NS_NSATTR_WRITE_PROTECTED`` - If set, then the namespace is currently - write protected and all write access to the - namespace shall fail. +``NVME_AER_NOTICE_NS_CHANGED`` +``NVME_AER_NOTICE_FW_ACT_STARTING`` +``NVME_AER_NOTICE_TELEMETRY`` +``NVME_AER_NOTICE_ANA`` -.. c:type:: struct nvme_ns_id_desc +``NVME_AER_NOTICE_PL_EVENT`` +``NVME_AER_NOTICE_LBA_STATUS_ALERT`` -**Definition** +``NVME_AER_NOTICE_EG_EVENT`` + +``NVME_AER_NOTICE_DISC_CHANGED`` -:: - struct nvme_ns_id_desc { - __u8 nidt; - __u8 nidl; - __le16 reserved; - __u8 nid[]; - }; -**Members** -``nidt`` - Namespace Identifier Type, see :c:type:`enum nvme_ns_id_desc_nidt ` +.. c:type:: enum nvme_subsys_type -``nidl`` - Namespace Identifier Length contains the length in bytes of the - :c:type:`struct nvme_id_ns `.nid. + Type of the NVM subsystem. -``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 :c:type:`struct nvme_id_ns `.nidl. +**Constants** +``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). +``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. +``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. -.. c:type:: enum nvme_ns_id_desc_nidt - Known namespace identifier types + +.. c:type:: enum nvmf_disc_eflags + + Discovery Log Page entry flags. **Constants** -``NVME_NIDT_EUI64`` - IEEE Extended Unique Identifier, the NID field contains a - copy of the EUI64 field in the struct nvme_id_ns.eui64. +``NVMF_DISC_EFLAGS_NONE`` + Indicates that none of the DUPRETINFO or EPCSD + features are supported. -``NVME_NIDT_NGUID`` - Namespace Globally Unique Identifier, the NID field - contains a copy of the NGUID field in struct nvme_id_ns.nguid. +``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. -``NVME_NIDT_UUID`` - The NID field contains a 128-bit Universally Unique - Identifier (UUID) as specified in RFC 4122. +``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. -.. c:type:: struct nvme_nvmset_attr - NVM Set Attributes Entry +.. c:type:: struct nvmf_disc_log_entry + + Discovery Log Page entry **Definition** :: - struct nvme_nvmset_attr { - __le16 id; - __le16 endurance_group_id; - __u8 rsvd4[4]; - __le32 random_4k_read_typical; - __le32 opt_write_size; - __u8 total_nvmset_cap[16]; - __u8 unalloc_nvmset_cap[16]; - __u8 rsvd48[80]; + struct nvmf_disc_log_entry { + __u8 trtype; + __u8 adrfam; + __u8 subtype; + __u8 treq; + __le16 portid; + __le16 cntlid; + __le16 asqsz; + __le16 eflags; + __u8 rsvd12[20]; + char trsvcid[NVMF_TRSVCID_SIZE]; + __u8 rsvd64[192]; + char subnqn[NVME_NQN_LENGTH]; + char traddr[NVMF_TRADDR_SIZE]; + union tsas { + char common[NVMF_TSAS_SIZE]; + struct rdma { + __u8 qptype; + __u8 prtype; + __u8 cms; + __u8 rsvd3[5]; + __u16 pkey; + __u8 rsvd10[246]; + } rdma; + struct tcp { + __u8 sectype; + } tcp; + } tsas; }; **Members** -``id`` - NVM Set Identifier - -``endurance_group_id`` - Endurance Group Identifier +``trtype`` + Transport Type (TRTYPE): Specifies the NVMe Transport type. + See :c:type:`enum nvmf_trtype `. -``random_4k_read_typical`` - Random 4 KiB Read Typical indicates the typical - time to complete a 4 KiB random read in 100 - nanosecond units when the NVM Set is in a - Predictable Latency Mode Deterministic Window and - there is 1 outstanding command per NVM Set. +``adrfam`` + Address Family (ADRFAM): Specifies the address family. + See :c:type:`enum nvmf_addr_family `. +``subtype`` + Subsystem Type (SUBTYPE): Specifies the type of the NVM subsystem + that is indicated in this entry. See :c:type:`enum nvme_subsys_type `. +``treq`` + Transport Requirements (TREQ): Indicates requirements for the NVMe + Transport. See :c:type:`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). +``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. -.. c:type:: struct nvme_id_nvmset_list +``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. - **nid**; +``eflags`` + Entry Flags (EFLAGS): Indicates additional information related to + the current entry. See :c:type:`enum nvmf_disc_eflags `. -**Definition** +``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. - struct nvme_id_nvmset_list { - __u8 nid; - __u8 rsvd1[127]; - struct nvme_nvmset_attr ent[NVME_ID_NVMSET_LIST_MAX]; - }; +``rsvd64`` + Reserved -**Members** +``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). -``ent`` - ; +``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. +``tsas`` + Transport specific attribute settings -.. c:type:: struct nvme_id_ns_granularity_desc +.. c:type:: enum nvmf_trtype -**Definition** + Transport Type codes for Discovery Log Page entry TRTYPE field -:: +**Constants** - struct nvme_id_ns_granularity_desc { - __le64 namespace_size_granularity; - __le64 namespace_capacity_granularity; - }; +``NVMF_TRTYPE_UNSPECIFIED`` + Not indicated -**Members** +``NVMF_TRTYPE_RDMA`` + RDMA +``NVMF_TRTYPE_FC`` + Fibre Channel +``NVMF_TRTYPE_TCP`` + TCP +``NVMF_TRTYPE_LOOP`` + Intra-host Transport (i.e., loopback), reserved + for host usage. +``NVMF_TRTYPE_MAX`` + Maximum value for :c:type:`enum nvmf_trtype ` -.. c:type:: struct nvme_id_ns_granularity_list -**Definition** -:: +.. c:type:: enum nvmf_addr_family - struct nvme_id_ns_granularity_list { - __le32 attributes; - __u8 num_descriptors; - __u8 rsvd[27]; - struct nvme_id_ns_granularity_desc entry[NVME_ID_ND_DESCRIPTOR_MAX]; - __u8 rsvd288[3808]; - }; + Address Family codes for Discovery Log Page entry ADRFAM field -**Members** +**Constants** +``NVMF_ADDR_FAMILY_PCI`` + PCIe +``NVMF_ADDR_FAMILY_IP4`` + AF_INET: IPv4 address family. +``NVMF_ADDR_FAMILY_IP6`` + AF_INET6: IPv6 address family. +``NVMF_ADDR_FAMILY_IB`` + AF_IB: InfiniBand address family. -.. c:type:: struct nvme_id_uuid_list_entry +``NVMF_ADDR_FAMILY_FC`` + Fibre Channel address family. +``NVMF_ADDR_FAMILY_LOOP`` + Intra-host Transport (i.e., loopback), reserved + for host usage. -**Definition** -:: - struct nvme_id_uuid_list_entry { - __u8 header; - __u8 rsvd1[15]; - __u8 uuid[16]; - }; -**Members** +.. c:type:: enum nvmf_treq + Transport Requirements codes for Discovery Log Page entry TREQ field +**Constants** +``NVMF_TREQ_NOT_SPECIFIED`` + Not specified +``NVMF_TREQ_REQUIRED`` + Required -.. c:type:: enum +``NVMF_TREQ_NOT_REQUIRED`` + Not Required +``NVMF_TREQ_DISABLE_SQFLOW`` + SQ flow control disable supported -**Constants** -``NVME_ID_UUID_HDR_ASSOCIATION_MASK`` - *undescribed* -``NVME_ID_UUID_ASSOCIATION_NONE`` - *undescribed* -``NVME_ID_UUID_ASSOCIATION_VENDOR`` - *undescribed* +.. c:type:: enum nvmf_rdma_qptype -``NVME_ID_UUID_ASSOCIATION_SUBSYSTEM_VENDOR`` - *undescribed* + RDMA QP Service Type codes for Discovery Log Page entry TSAS RDMA_QPTYPE field +**Constants** +``NVMF_RDMA_QPTYPE_CONNECTED`` + Reliable Connected +``NVMF_RDMA_QPTYPE_DATAGRAM`` + Reliable Datagram -.. c:type:: struct nvme_id_uuid_list -**Definition** -:: +.. c:type:: enum nvmf_rdma_prtype - struct nvme_id_uuid_list { - __u8 rsvd0[32]; - struct nvme_id_uuid_list_entry entry[NVME_ID_UUID_LIST_MAX]; - }; + RDMA Provider Type codes for Discovery Log Page entry TSAS RDMA_PRTYPE field -**Members** +**Constants** +``NVMF_RDMA_PRTYPE_NOT_SPECIFIED`` + No Provider Specified +``NVMF_RDMA_PRTYPE_IB`` + InfiniBand +``NVMF_RDMA_PRTYPE_ROCE`` + InfiniBand RoCE +``NVMF_RDMA_PRTYPE_ROCEV2`` + InfiniBand RoCEV2 -.. c:type:: struct nvme_ctrl_list +``NVMF_RDMA_PRTYPE_IWARP`` + iWARP - **num**; -**Definition** -:: - struct nvme_ctrl_list { - __le16 num; - __le16 identifier[NVME_ID_CTRL_LIST_MAX]; - }; +.. c:type:: enum nvmf_rdma_cms -**Members** + RDMA Connection Management Service Type codes for Discovery Log Page entry TSAS RDMA_CMS field +**Constants** +``NVMF_RDMA_CMS_RDMA_CM`` + Sockets based endpoint addressing -.. c:type:: struct nvme_ns_list +.. c:type:: enum nvmf_tcp_sectype -**Definition** + Transport Specific Address Subtype Definition for NVMe/TCP Transport -:: +**Constants** - struct nvme_ns_list { - __le32 ns[NVME_ID_NS_LIST_MAX]; - }; +``NVMF_TCP_SECTYPE_NONE`` + No Security -**Members** +``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. -.. c:type:: struct nvme_primary_ctrl_cap +.. c:type:: struct nvmf_discovery_log + Discovery Log Page (Log Identifier 70h) **Definition** :: - struct nvme_primary_ctrl_cap { - __le16 cntlid; - __le16 portid; - __u8 crt; - __u8 rsvd5[27]; - __le32 vqfrt; - __le32 vqrfa; - __le16 vqrfap; - __le16 vqprt; - __le16 vqfrsm; - __le16 vqgran; - __u8 rsvd48[16]; - __le32 vifrt; - __le32 virfa; - __le16 virfap; - __le16 viprt; - __le16 vifrsm; - __le16 vigran; - __u8 rsvd80[4016]; + struct nvmf_discovery_log { + __le64 genctr; + __le64 numrec; + __le16 recfmt; + __u8 rsvd14[1006]; + struct nvmf_disc_log_entry entries[]; }; **Members** +``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). +``numrec`` + Number of Records (NUMREC): Indicates the number of records + 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. +``rsvd14`` + Reserved -.. c:type:: struct nvme_secondary_ctrl +``entries`` + Discovery Log Page Entries - see :c:type:`struct nvmf_disc_log_entry `. + + + +.. c:type:: struct nvmf_connect_data + + Data payload for the 'connect' command + **Definition** :: - struct nvme_secondary_ctrl { - __le16 scid; - __le16 pcid; - __u8 scs; - __u8 rsvd5[3]; - __le16 vfn; - __le16 nvq; - __le16 nvi; - __u8 rsvd14[18]; + struct nvmf_connect_data { + __u8 hostid[16]; + __le16 cntlid; + char rsvd4[238]; + char subsysnqn[NVME_NQN_LENGTH]; + char hostnqn[NVME_NQN_LENGTH]; + char rsvd5[256]; }; **Members** +``hostid`` + Host ID of the connecting host + +``cntlid`` + Requested controller ID + +``rsvd4`` + Reserved +``subsysnqn`` + Subsystem NQN to connect to +``hostnqn`` + Host NQN of the connecting host +``rsvd5`` + Reserved -.. c:type:: struct nvme_secondary_ctrl_list - **num**; + + + +.. c:type:: struct nvme_mi_read_nvm_ss_info + **Definition** :: - struct nvme_secondary_ctrl_list { - __u8 num; - __u8 rsvd[31]; - struct nvme_secondary_ctrl sc_entry[NVME_ID_SECONDARY_CTRL_MAX]; + struct nvme_mi_read_nvm_ss_info { + __u8 nump; + __u8 mjr; + __u8 mnr; + __u8 rsvd3[29]; }; **Members** +``nump`` +``mjr`` +``mnr`` +``rsvd3`` -.. c:type:: struct nvme_error_log_page + + + + +.. c:type:: struct nvme_mi_port_pcie **Definition** :: - struct nvme_error_log_page { - __le64 error_count; - __le16 sqid; - __le16 cmdid; - __le16 status_field; - __le16 parm_error_location; - __le64 lba; - __le32 nsid; - __u8 vs; - __u8 trtype; - __u8 rsvd[2]; - __le64 cs; - __le16 trtype_spec_info; - __u8 rsvd2[22]; + struct nvme_mi_port_pcie { + __u8 mps; + __u8 sls; + __u8 cls; + __u8 mlw; + __u8 nlw; + __u8 pn; + __u8 rsvd14[18]; }; **Members** +``mps`` +``sls`` +``cls`` +``mlw`` -.. c:type:: enum +``nlw`` +``pn`` -**Constants** - -``NVME_ERR_PEL_BYTE_MASK`` - *undescribed* +``rsvd14`` -``NVME_ERR_PEL_BIT_MASK`` - *undescribed* -.. c:type:: struct nvme_smart_log +.. c:type:: struct nvme_mi_port_smb **Definition** :: - struct nvme_smart_log { - __u8 critical_warning; - __u8 temperature[2]; - __u8 avail_spare; - __u8 spare_thresh; - __u8 percent_used; - __u8 endu_grp_crit_warn_sumry; - __u8 rsvd7[25]; - __u8 data_units_read[16]; - __u8 data_units_written[16]; - __u8 host_reads[16]; - __u8 host_writes[16]; - __u8 ctrl_busy_time[16]; - __u8 power_cycles[16]; - __u8 power_on_hours[16]; - __u8 unsafe_shutdowns[16]; - __u8 media_errors[16]; - __u8 num_err_log_entries[16]; - __le32 warning_temp_time; - __le32 critical_comp_time; - __le16 temp_sensor[8]; - __le32 thm_temp1_trans_count; - __le32 thm_temp2_trans_count; - __le32 thm_temp1_total_time; - __le32 thm_temp2_total_time; - __u8 rsvd232[280]; + struct nvme_mi_port_smb { + __u8 vpd_addr; + __u8 mvpd_freq; + __u8 mme_addr; + __u8 mme_freq; + __u8 nvmebm; + __u8 rsvd13[19]; }; **Members** +``vpd_addr`` +``mvpd_freq`` +``mme_addr`` +``mme_freq`` -.. c:type:: enum +``nvmebm`` +``rsvd13`` -**Constants** -``NVME_SMART_CRIT_SPARE`` - *undescribed* -``NVME_SMART_CRIT_TEMPERATURE`` - *undescribed* -``NVME_SMART_CRIT_DEGRADED`` - *undescribed* -``NVME_SMART_CRIT_MEDIA`` - *undescribed* +.. c:type:: struct nvme_mi_read_port_info -``NVME_SMART_CRIT_VOLATILE_MEMORY`` - *undescribed* -``NVME_SMART_CRIT_PMR_RO`` - *undescribed* +**Definition** +:: + struct nvme_mi_read_port_info { + __u8 portt; + __u8 rsvd1; + __le16 mmctptus; + __le32 meb; + union { + struct nvme_mi_port_pcie pcie; + struct nvme_mi_port_smb smb; + }; + }; +**Members** -.. c:type:: enum +``portt`` +``rsvd1`` -**Constants** +``mmctptus`` -``NVME_SMART_EGCW_SPARE`` - *undescribed* +``meb`` -``NVME_SMART_EGCW_DEGRADED`` - *undescribed* +``{unnamed_union}`` + anonymous -``NVME_SMART_EGCW_RO`` - *undescribed* +``pcie`` + +``smb`` -.. c:type:: struct nvme_firmware_slot + +.. c:type:: struct nvme_mi_read_ctrl_info **Definition** :: - struct nvme_firmware_slot { - __u8 afi; - __u8 resv[7]; - char frs[7][8]; - __u8 resv2[448]; + struct nvme_mi_read_ctrl_info { + __u8 portid; + __u8 rsvd1[4]; + __u8 prii; + __le16 pri; + __le16 vid; + __le16 did; + __le16 ssvid; + __le16 ssid; + __u8 rsvd16[16]; }; **Members** +``portid`` +``rsvd1`` +``prii`` +``pri`` -.. c:type:: struct nvme_cmd_effects_log - - -**Definition** +``vid`` -:: +``did`` - struct nvme_cmd_effects_log { - __le32 acs[256]; - __le32 iocs[256]; - __u8 rsvd[2048]; - }; +``ssvid`` -**Members** +``ssid`` +``rsvd16`` -.. c:type:: enum +.. c:type:: struct nvme_mi_osc -**Constants** -``NVME_CMD_EFFECTS_CSUPP`` - *undescribed* +**Definition** -``NVME_CMD_EFFECTS_LBCC`` - *undescribed* +:: -``NVME_CMD_EFFECTS_NCC`` - *undescribed* + struct nvme_mi_osc { + __u8 type; + __u8 opc; + }; -``NVME_CMD_EFFECTS_NIC`` - *undescribed* +**Members** -``NVME_CMD_EFFECTS_CCC`` - *undescribed* +``type`` -``NVME_CMD_EFFECTS_CSE_MASK`` - *undescribed* +``opc`` -``NVME_CMD_EFFECTS_UUID_SEL`` - *undescribed* -.. c:type:: struct nvme_st_result +.. c:type:: struct nvme_mi_read_sc_list **Definition** :: - struct nvme_st_result { - __u8 dsts; - __u8 seg; - __u8 vdi; - __u8 rsvd; - __le64 poh; - __le32 nsid; - __le64 flba; - __u8 sct; - __u8 sc; - __u8 vs[2]; + struct nvme_mi_read_sc_list { + __le16 numcmd; + struct nvme_mi_osc cmds[]; }; **Members** +``numcmd`` +``cmds`` -.. c:type:: enum -**Constants** +.. c:type:: struct nvme_mi_nvm_ss_health_status -``NVME_ST_RESULT_NO_ERR`` - *undescribed* -``NVME_ST_RESULT_ABORTED`` - *undescribed* +**Definition** -``NVME_ST_RESULT_CLR`` - *undescribed* +:: -``NVME_ST_RESULT_NS_REMOVED`` - *undescribed* + struct nvme_mi_nvm_ss_health_status { + __u8 nss; + __u8 sw; + __u8 ctemp; + __u8 pdlu; + __le16 ccs; + __u8 rsvd8[2]; + }; -``NVME_ST_RESULT_ABORTED_FORMAT`` - *undescribed* +**Members** -``NVME_ST_RESULT_FATAL_ERR`` - *undescribed* +``nss`` -``NVME_ST_RESULT_UNKNOWN_SEG_FAIL`` - *undescribed* +``sw`` -``NVME_ST_RESULT_KNOWN_SEG_FAIL`` - *undescribed* +``ctemp`` -``NVME_ST_RESULT_ABORTED_UNKNOWN`` - *undescribed* +``pdlu`` -``NVME_ST_RESULT_ABORTED_SANITIZE`` - *undescribed* +``ccs`` -``NVME_ST_RESULT_NOT_USED`` - *undescribed* +``rsvd8`` -``NVME_ST_RESULT_MASK`` - *undescribed* -.. c:type:: enum +.. c:type:: enum nvme_mi_css **Constants** -``NVME_ST_CODE_SHIFT`` - *undescribed* - -``NVME_ST_CODE_RESRVED`` - *undescribed* - -``NVME_ST_CODE_SHORT`` - *undescribed* - -``NVME_ST_CODE_EXTENDED`` - *undescribed* +``NVME_MI_CCS_RDY`` -``NVME_ST_CODE_VS`` - *undescribed* +``NVME_MI_CSS_CFS`` +``NVME_MI_CSS_SHST`` +``NVME_MI_CSS_NSSRO`` +``NVME_MI_CSS_CECO`` -.. c:type:: enum +``NVME_MI_CSS_NAC`` +``NVME_MI_CSS_FA`` -**Constants** +``NVME_MI_CSS_CSTS`` -``NVME_ST_VALID_DIAG_INFO_NSID`` - *undescribed* +``NVME_MI_CSS_CTEMP`` -``NVME_ST_VALID_DIAG_INFO_FLBA`` - *undescribed* +``NVME_MI_CSS_PDLU`` -``NVME_ST_VALID_DIAG_INFO_SCT`` - *undescribed* +``NVME_MI_CSS_SPARE`` -``NVME_ST_VALID_DIAG_INFO_SC`` - *undescribed* +``NVME_MI_CSS_CCWARN`` -.. c:type:: struct nvme_self_test_log +.. c:type:: struct nvme_mi_ctrl_health_status **Definition** :: - struct nvme_self_test_log { - __u8 current_operation; - __u8 completion; - __u8 rsvd[2]; - struct nvme_st_result result[NVME_LOG_ST_MAX_RESULTS]; + struct nvme_mi_ctrl_health_status { + __le16 ctlid; + __le16 csts; + __le16 ctemp; + __u8 pdlu; + __u8 spare; + __u8 cwarn; + __u8 rsvd9[7]; }; **Members** +``ctlid`` +``csts`` +``ctemp`` +``pdlu`` -.. c:type:: struct nvme_telemetry_log +``spare`` - Retrieve internal data specific to the manufacturer. +``cwarn`` -**Definition** +``rsvd9`` -:: - struct nvme_telemetry_log { - __u8 lpi; - __u8 rsvd1[4]; - __u8 ieee[3]; - __le16 dalb1; - __le16 dalb2; - __le16 dalb3; - __u8 rsvd14[368]; - __u8 ctrlavail; - __u8 ctrldgn; - __u8 rsnident[128]; - __u8 data_area[]; - }; -**Members** -``lpi`` - Log Identifier, either ``NVME_LOG_LID_TELEMETRY_HOST`` or - ``NVME_LOG_LID_TELEMETRY_CTRL`` -``ieee`` - IEEE OUI Identifier is the Organization Unique Identifier (OUI) - for the controller vendor that is able to interpret the data. +.. c:type:: enum nvme_mi_csts + + +**Constants** + +``NVME_MI_CSTS_RDY`` + +``NVME_MI_CSTS_CFS`` + +``NVME_MI_CSTS_SHST`` + +``NVME_MI_CSTS_NSSRO`` + +``NVME_MI_CSTS_CECO`` + +``NVME_MI_CSTS_NAC`` + +``NVME_MI_CSTS_FA`` + + -``dalb1`` - Telemetry Controller-Initiated Data Area 1 Last Block is - 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. +.. c:type:: enum nvme_mi_cwarn -``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. -``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 . +**Constants** -``rsnident`` - Reason Identifieris a vendor specific identifier that describes - the operating conditions of the controller at the time of - capture. +``NVME_MI_CWARN_ST`` -``data_area`` - Telemetry data blocks, vendor specific information data. +``NVME_MI_CWARN_TAUT`` +``NVME_MI_CWARN_RD`` -**Description** +``NVME_MI_CWARN_RO`` -This log consists of a header describing the log and zero or more Telemetry -Data Blocks. All Telemetry Data Blocks are ``NVME_LOG_TELEM_BLOCK_SIZE``, 512 -bytes, in size. This log captures the controller’s internal state. +``NVME_MI_CWARN_VMBF`` -.. c:type:: struct nvme_endurance_group_log +.. c:type:: struct nvme_mi_vpd_mra **Definition** :: - struct nvme_endurance_group_log { - __u8 critical_warning; - __u8 rsvd1[2]; - __u8 avl_spare; - __u8 avl_spare_threshold; - __u8 percent_used; - __u8 rsvd6[26]; - __u8 endurance_estimate[16]; - __u8 data_units_read[16]; - __u8 data_units_written[16]; - __u8 media_units_written[16]; - __u8 host_read_cmds[16]; - __u8 host_write_cmds[16]; - __u8 media_data_integrity_err[16]; - __u8 num_err_info_log_entries[16]; - __u8 rsvd160[352]; + struct nvme_mi_vpd_mra { + __u8 nmravn; + __u8 ff; + __u8 rsvd7[6]; + __u8 i18vpwr; + __u8 m18vpwr; + __u8 i33vpwr; + __u8 m33vpwr; + __u8 rsvd17; + __u8 m33vapsr; + __u8 i5vapsr; + __u8 m5vapsr; + __u8 i12vapsr; + __u8 m12vapsr; + __u8 mtl; + __u8 tnvmcap[16]; + __u8 rsvd37[27]; }; **Members** +``nmravn`` +``ff`` +``rsvd7`` +``i18vpwr`` -.. c:type:: enum nvme_eg_critical_warning_flags +``m18vpwr`` +``i33vpwr`` -**Constants** +``m33vpwr`` -``NVME_EG_CRITICAL_WARNING_SPARE`` - *undescribed* +``rsvd17`` -``NVME_EG_CRITICAL_WARNING_DEGRADED`` - *undescribed* +``m33vapsr`` -``NVME_EG_CRITICAL_WARNING_READ_ONLY`` - *undescribed* +``i5vapsr`` +``m5vapsr`` +``i12vapsr`` + +``m12vapsr`` + +``mtl`` + +``tnvmcap`` + +``rsvd37`` -.. c:type:: struct nvme_aggregate_endurance_group_event + + + +.. c:type:: struct nvme_mi_vpd_ppmra **Definition** :: - struct nvme_aggregate_endurance_group_event { - __le64 num_entries; - __le16 entries[]; + struct nvme_mi_vpd_ppmra { + __u8 nppmravn; + __u8 pn; + __u8 ppi; + __u8 ls; + __u8 mlw; + __u8 mctp; + __u8 refccap; + __u8 pi; + __u8 rsvd13[3]; }; **Members** +``nppmravn`` +``pn`` +``ppi`` +``ls`` -.. c:type:: struct nvme_nvmset_predictable_lat_log +``mlw`` +``mctp`` -**Definition** +``refccap`` -:: +``pi`` - struct nvme_nvmset_predictable_lat_log { - __u8 status; - __u8 rsvd1; - __le16 event_type; - __u8 rsvd4[28]; - __le64 dtwin_rt; - __le64 dtwin_wt; - __le64 dtwin_tmax; - __le64 dtwin_tmin_hi; - __le64 dtwin_tmin_lo; - __u8 rsvd72[56]; - __le64 dtwin_re; - __le64 dtwin_we; - __le64 dtwin_te; - __u8 rsvd152[360]; - }; +``rsvd13`` -**Members** +.. c:type:: struct nvme_mi_vpd_telem -.. c:type:: enum +**Definition** -**Constants** +:: -``NVME_NVMSET_PL_STATUS_DISABLED`` - *undescribed* + struct nvme_mi_vpd_telem { + __u8 type; + __u8 rev; + __u8 len; + __u8 data[0]; + }; -``NVME_NVMSET_PL_STATUS_DTWIN`` - *undescribed* +**Members** -``NVME_NVMSET_PL_STATUS_NDWIN`` - *undescribed* +``type`` + +``rev`` + +``len`` + +``data`` -.. c:type:: enum + +.. c:type:: enum nvme_mi_elem **Constants** -``NVME_NVMSET_PL_EVENT_DTWIN_READ_WARN`` - *undescribed* +``NVME_MI_ELEM_EED`` -``NVME_NVMSET_PL_EVENT_DTWIN_WRITE_WARN`` - *undescribed* +``NVME_MI_ELEM_USCE`` -``NVME_NVMSET_PL_EVENT_DTWIN_TIME_WARN`` - *undescribed* +``NVME_MI_ELEM_ECED`` -``NVME_NVMSET_PL_EVENT_DTWIN_EXCEEDED`` - *undescribed* +``NVME_MI_ELEM_LED`` -``NVME_NVMSET_PL_EVENT_DTWIN_EXCURSION`` - *undescribed* +``NVME_MI_ELEM_SMBMED`` + +``NVME_MI_ELEM_PCIESED`` + +``NVME_MI_ELEM_NVMED`` -.. c:type:: struct nvme_aggregate_predictable_lat_event +.. c:type:: struct nvme_mi_vpd_tra **Definition** :: - struct nvme_aggregate_predictable_lat_event { - __le64 num_entries; - __le16 entries[]; + struct nvme_mi_vpd_tra { + __u8 vn; + __u8 rsvd6; + __u8 ec; + struct nvme_mi_vpd_telem elems[0]; }; **Members** +``vn`` +``rsvd6`` + +``ec`` + +``elems`` -.. c:type:: struct nvme_ana_group_desc + + +.. c:type:: struct nvme_mi_vpd_mr_common **Definition** :: - struct nvme_ana_group_desc { - __le32 grpid; - __le32 nnsids; - __le64 chgcnt; - __u8 state; - __u8 rsvd17[15]; - __le32 nsids[]; + struct nvme_mi_vpd_mr_common { + __u8 type; + __u8 rf; + __u8 rlen; + __u8 rchksum; + __u8 hchksum; + union { + struct nvme_mi_vpd_mra nmra; + struct nvme_mi_vpd_ppmra ppmra; + struct nvme_mi_vpd_tra tmra; + }; }; **Members** +``type`` +``rf`` +``rlen`` +``rchksum`` -.. c:type:: enum nvme_ana_state - - -**Constants** +``hchksum`` -``NVME_ANA_STATE_OPTIMIZED`` - *undescribed* +``{unnamed_union}`` + anonymous -``NVME_ANA_STATE_NONOPTIMIZED`` - *undescribed* +``nmra`` -``NVME_ANA_STATE_INACCESSIBLE`` - *undescribed* +``ppmra`` -``NVME_ANA_STATE_PERSISTENT_LOSS`` - *undescribed* +``tmra`` -``NVME_ANA_STATE_CHANGE`` - *undescribed* -.. c:type:: struct nvme_ana_log +.. c:type:: struct nvme_mi_vpd_hdr **Definition** :: - struct nvme_ana_log { - __le64 chgcnt; - __le16 ngrps; - __u8 rsvd10[6]; - struct nvme_ana_group_desc descs[]; + struct nvme_mi_vpd_hdr { + __u8 ipmiver; + __u8 iuaoff; + __u8 ciaoff; + __u8 biaoff; + __u8 piaoff; + __u8 mrioff; + __u8 rsvd6; + __u8 chchk; + __u8 vpd[]; }; **Members** +``ipmiver`` +``iuaoff`` +``ciaoff`` +``biaoff`` -.. c:type:: struct nvme_persistent_event_log - - -**Definition** +``piaoff`` -:: +``mrioff`` - struct nvme_persistent_event_log { - __u8 lid; - __u8 rsvd1[3]; - __le32 ttl; - __u8 rv; - __u8 rsvd17; - __le16 lht; - __le64 ts; - __u8 poh[16]; - __le64 pcc; - __le16 vid; - __le16 ssvid; - char sn[20]; - char mn[40]; - char subnqn[NVME_NQN_LENGTH]; - __u8 rsvd372; - __u8 seb[32]; - }; +``rsvd6`` -**Members** +``chchk`` +``vpd`` -.. c:type:: struct nvme_lba_rd +.. c:type:: enum nvme_status_field -**Definition** + Defines all parts of the nvme status field: status code, status code type, and additional flags. -:: +**Constants** - struct nvme_lba_rd { - __le64 rslba; - __le32 rnlb; - __u8 rsvd12[4]; - }; +``NVME_SCT_GENERIC`` + Generic errors applicable to multiple opcodes -**Members** +``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 -.. c:type:: struct nvme_lbas_ns_element +``NVME_SC_MASK`` + Mask to get the value of the status code. +``NVME_SC_SUCCESS`` + Successful Completion: The command + completed without error. -**Definition** +``NVME_SC_INVALID_OPCODE`` + Invalid Command Opcode: A reserved coded + 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. - struct nvme_lbas_ns_element { - __le32 neid; - __le32 nrld; - __u8 ratype; - __u8 rsvd8[7]; - struct nvme_lba_rd lba_rd[]; - }; +``NVME_SC_CMDID_CONFLICT`` + Command ID Conflict: The command + identifier is already in use. -**Members** +``NVME_SC_DATA_XFER_ERROR`` + Data Transfer Error: Transferring the + 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. +``NVME_SC_INTERNAL`` + Internal Error: The command was not + 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. +``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. -.. c:type:: enum nvme_lba_status_atype +``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. +``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. -**Constants** +``NVME_SC_INVALID_NS`` + Invalid Namespace or Format: The + namespace or the format of that namespace + is invalid. -``NVME_LBA_STATUS_ATYPE_SCAN_UNTRACKED`` - *undescribed* +``NVME_SC_CMD_SEQ_ERROR`` + Command Sequence Error: The command was + aborted due to a protocol violation in a + multi-command sequence. -``NVME_LBA_STATUS_ATYPE_SCAN_TRACKED`` - *undescribed* +``NVME_SC_SGL_INVALID_LAST`` + Invalid SGL Segment Descriptor: The + 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. +``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. +``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. -.. c:type:: struct nvme_lba_status_log +``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. +``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. -**Definition** +``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. - struct nvme_lba_status_log { - __le32 lslplen; - __le32 nlslne; - __le32 estulb; - __u8 rsvd12[2]; - __le16 lsgc; - struct nvme_lbas_ns_element elements[]; - }; +``NVME_SC_OP_DENIED`` + Operation Denied: The command was denied + due to lack of access rights. Refer to + the appropriate security specification. -**Members** +``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. +``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. +``NVME_SC_KAT_EXPIRED`` + Keep Alive Timer Expired: The Keep Alive + Timer expired. +``NVME_SC_KAT_INVALID`` + Keep Alive Timeout Invalid: The Keep + 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. -.. c:type:: struct nvme_eg_event_aggregate_log +``NVME_SC_SANITIZE_FAILED`` + Sanitize Failed: The most recent sanitize + 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. -**Definition** +``NVME_SC_SGL_INVALID_GRANULARITY`` + SGL Data Block Granularity Invalid: The + 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. - struct nvme_eg_event_aggregate_log { - __le64 nr_entries; - __le16 egids[]; - }; +``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. -**Members** +``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. +``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. +``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. +``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. +``NVME_SC_LBA_RANGE`` + LBA Out of Range: The command references + an LBA that exceeds the size of the namespace. -.. c:type:: struct nvme_resv_notification_log +``NVME_SC_CAP_EXCEEDED`` + Capacity Exceeded: Execution of the + 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. -**Definition** +``NVME_SC_RESERVATION_CONFLICT`` + Reservation Conflict: The command was + 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. - struct nvme_resv_notification_log { - __le64 lpc; - __u8 rnlpt; - __u8 nalp; - __u8 rsvd9[2]; - __le32 nsid; - __u8 rsvd16[48]; - }; +``NVME_SC_CQ_INVALID`` + Completion Queue Invalid: The Completion + Queue identifier specified in the command + does not exist. -**Members** +``NVME_SC_QID_INVALID`` + Invalid Queue Identifier: The creation of + the I/O Completion Queue failed due to an + invalid queue identifier specified as + part of the command. An invalid queue + identifier is one that is currently in + use or one that is outside the range + supported by the controller. -``rnlpt`` - See :c:type:`enum nvme_resv_notify_rnlpt `. +``NVME_SC_QUEUE_SIZE`` + Invalid Queue Size: The host attempted to + 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. +``NVME_SC_ABORT_MISSING`` + Abort Command is missing: The abort + command is missing. +``NVME_SC_ASYNC_LIMIT`` + Asynchronous Event Request Limit + 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. -.. c:type:: enum nvme_resv_notify_rnlpt +``NVME_SC_FIRMWARE_IMAGE`` + Invalid Firmware Image: The firmware + 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. -**Constants** +``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. -``NVME_RESV_NOTIFY_RNLPT_EMPTY`` - *undescribed* +``NVME_SC_INVALID_FORMAT`` + Invalid Format: The LBA Format specified + is not supported. -``NVME_RESV_NOTIFY_RNLPT_REGISTRATION_PREEMPTED`` - *undescribed* +``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. -``NVME_RESV_NOTIFY_RNLPT_RESERVATION_RELEASED`` - *undescribed* +``NVME_SC_INVALID_QUEUE`` + Invalid Queue Deletion: Invalid I/O + Completion Queue specified to delete. -``NVME_RESV_NOTIFY_RNLPT_RESERVATION_PREEMPTED`` - *undescribed* +``NVME_SC_FEATURE_NOT_SAVEABLE`` + Feature Identifier Not Saveable: The + 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. +``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. +``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. -.. c:type:: struct nvme_sanitize_log_page +``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. +``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. -**Definition** +``NVME_SC_FW_ACTIVATE_PROHIBITED`` + Firmware Activation Prohibited: The image + 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. - struct nvme_sanitize_log_page { - __le16 sprog; - __le16 sstat; - __le32 scdw10; - __le32 eto; - __le32 etbe; - __le32 etce; - __le32 etond; - __le32 etbend; - __le32 etcend; - __u8 rsvd32[480]; - }; +``NVME_SC_NS_INSUFFICIENT_CAP`` + Namespace Insufficient Capacity: Creating + the namespace requires more free space + than is currently available. -**Members** +``NVME_SC_NS_ID_UNAVAILABLE`` + Namespace Identifier Unavailable: The + number of namespaces supported has been + exceeded. +``NVME_SC_NS_ALREADY_ATTACHED`` + Namespace Already Attached: The + 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. +``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. +``NVME_SC_THIN_PROV_NOT_SUPP`` + Thin Provisioning Not Supported: Thin + provisioning is not supported by the + controller. -.. c:type:: enum nvme_sanitize_sstat +``NVME_SC_CTRL_LIST_INVALID`` + Controller List Invalid: The controller + 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. -**Constants** +``NVME_SC_BP_WRITE_PROHIBITED`` + Boot Partition Write Prohibited: The + command is trying to modify a locked Boot + Partition. -``NVME_SANITIZE_SSTAT_STATUS_MASK`` - *undescribed* +``NVME_SC_INVALID_CTRL_ID`` + Invalid Controller Identifier: -``NVME_SANITIZE_SSTAT_STATUS_NEVER_SANITIZED`` - *undescribed* +``NVME_SC_INVALID_SEC_CTRL_STATE`` + Invalid Secondary Controller State -``NVME_SANITIZE_SSTAT_STATUS_COMPLETE_SUCCESS`` - *undescribed* +``NVME_SC_INVALID_CTRL_RESOURCES`` + Invalid Number of Controller Resources -``NVME_SANITIZE_SSTAT_STATUS_IN_PROGESS`` - *undescribed* +``NVME_SC_INVALID_RESOURCE_ID`` + Invalid Resource Identifier -``NVME_SANITIZE_SSTAT_STATUS_COMPLETED_FAILED`` - *undescribed* +``NVME_SC_PMR_SAN_PROHIBITED`` + Sanitize Prohibited While Persistent + Memory Region is Enabled -``NVME_SANITIZE_SSTAT_STATUS_ND_COMPLETE_SUCCESS`` - *undescribed* +``NVME_SC_ANA_GROUP_ID_INVALID`` + ANA Group Identifier Invalid: The specified + ANA Group Identifier (ANAGRPID) is not + supported in the submitted command. -``NVME_SANITIZE_SSTAT_COMPLETED_PASSES_MASK`` - *undescribed* +``NVME_SC_ANA_ATTACH_FAILED`` + ANA Attach Failed: The controller is not + attached to the namespace as a result + of an ANA condition. -``NVME_SANITIZE_SSTAT_COMPLETED_PASSES_SHIFT`` - *undescribed* +``NVME_SC_INSUFFICIENT_CAP`` + Insufficient Capacity: Requested operation + requires more free space than is currently + available. -``NVME_SANITIZE_SSTAT_GLOBAL_DATA_ERASED`` - *undescribed* +``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. +``NVME_SC_PROHIBIT_CMD_EXEC_NOT_SUPPORTED`` + Prohibition of Command Execution + Not Supported +``NVME_SC_IOCS_NOT_SUPPORTED`` + I/O Command Set Not Supported +``NVME_SC_IOCS_NOT_ENABLED`` + I/O Command Set Not Enabled -.. c:type:: struct nvme_lba_status_desc +``NVME_SC_IOCS_COMBINATION_REJECTED`` + I/O Command Set Combination Rejected +``NVME_SC_INVALID_IOCS`` + Invalid I/O Command Set -**Definition** +``NVME_SC_ID_UNAVAILABLE`` + Identifier Unavailable -:: +``NVME_SC_BAD_ATTRIBUTES`` + Conflicting Dataset Management Attributes - struct nvme_lba_status_desc { - __le64 dslba; - __le32 nlb; - __u8 rsvd12; - __u8 status; - __u8 rsvd14[2]; - }; +``NVME_SC_INVALID_PI`` + Invalid Protection Information -**Members** +``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. +``NVME_SC_CONNECT_CTRL_BUSY`` + Controller Busy: The controller is + already associated with a host. +``NVME_SC_CONNECT_INVALID_PARAM`` + Connect Invalid Parameters: One or more + of the command parameters. -.. c:type:: struct nvme_lba_status +``NVME_SC_CONNECT_RESTART_DISC`` + Connect Restart Discovery: The NVM + 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 -**Definition** +``NVME_SC_DISCONNECT_INVALID_QTYPE`` + Invalid Queue Type: The command was sent + on the wrong queue type. -:: +``NVME_SC_DISCOVERY_RESTART`` + Discover Restart: The snapshot of the + records is now invalid or out of date. - struct nvme_lba_status { - __le32 nlsd; - __u8 cmpc; - __u8 rsvd5[3]; - struct nvme_lba_status_desc descs[]; - }; +``NVME_SC_AUTH_REQUIRED`` + Authentication Required: NVMe in-band + authentication is required and the queue + has not yet been authenticated. -**Members** +``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. +``NVME_SC_ZNS_ZRWA_RESOURCES_UNAVAILABLE`` + ZRWA Resources Unavailable: + No ZRWAs are available. +``NVME_SC_ZNS_BOUNDARY_ERROR`` + Zone Boundary Error: The command specifies + logical blocks in more than one zone. +``NVME_SC_ZNS_FULL`` + Zone Is Full: The accessed zone is in the + ZSF:Full state. +``NVME_SC_ZNS_READ_ONLY`` + Zone Is Read Only: The accessed zone is + in the ZSRO:Read Only state. -.. c:type:: struct nvme_feat_auto_pst +``NVME_SC_ZNS_OFFLINE`` + Zone Is Offline: The accessed zone is + in the ZSO:Offline state. +``NVME_SC_ZNS_INVALID_WRITE`` + Zone Invalid Write: The write to a zone + was not at the write pointer. -**Definition** +``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. - struct nvme_feat_auto_pst { - __le64 apst_entry[32]; - }; +``NVME_SC_ZNS_INVAL_TRANSITION`` + Invalid Zone State Transition: The request + is not a valid zone state transition. -**Members** +``NVME_SC_WRITE_FAULT`` + Write Fault: The write data could not be + committed to the media. -``apst_entry`` - See :c:type:`enum nvme_apst_entry ` +``NVME_SC_READ_ERROR`` + Unrecovered Read Error: The read data + 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. +``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. +``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. +``NVME_SC_COMPARE_FAILED`` + Compare Failure: The command failed due + to a miscompare during a Compare command. -.. c:type:: enum nvme_apst_entry +``NVME_SC_ACCESS_DENIED`` + Access Denied: Access to the namespace + 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. -**Constants** +``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. -``NVME_APST_ENTRY_ITPS_MASK`` - *undescribed* +``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. -``NVME_APST_ENTRY_ITPS_SHIFT`` - *undescribed* +``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. -``NVME_APST_ENTRY_ITPT_MASK`` - *undescribed* +``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. -``NVME_APST_ENTRY_ITPT_SHIFT`` - *undescribed* +``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. +``NVME_SC_CTRL_PATH_ERROR`` + Controller Pathing Error: A pathing error + was detected by the controller. +``NVME_SC_HOST_PATH_ERROR`` + Host Pathing Error: A pathing error was + detected by the host. +``NVME_SC_CMD_ABORTED_BY_HOST`` + Command Aborted By Host: The command was + aborted as a result of host action. -.. c:type:: struct nvme_timestamp +``NVME_SC_CRD`` + Mask to get value of Command Retry Delay + index - timestamp: +``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. -**Definition** +``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. -:: - struct nvme_timestamp { - __u8 timestamp[6]; - __u8 attr; - __u8 rsvd; - }; +.. c:function:: __u16 nvme_status_code_type (__u16 status_field) -**Members** + Returns the NVMe Status Code Type +**Parameters** +``__u16 status_field`` + The NVMe Completion Queue Entry's Status Field +**Description** +See :c:type:`enum nvme_status_field ` -.. c:type:: struct nvme_lba_range_type_entry +.. c:function:: __u16 nvme_status_code (__u16 status_field) -**Definition** + Returns the NVMe Status Code -:: +**Parameters** - struct nvme_lba_range_type_entry { - __u8 type; - __u8 attributes; - __u8 rsvd2[14]; - __u64 slba; - __u64 nlb; - __u8 guid[16]; - __u8 rsvd48[16]; - }; +``__u16 status_field`` + The NVMe Completion Queue Entry's Status Field -**Members** +**Description** +See :c:type:`enum nvme_status_field ` -.. c:type:: enum +.. c:type:: enum nvme_admin_opcode + Known NVMe admin opcodes **Constants** -``NVME_LBART_TYPE_GP`` - *undescribed* +``nvme_admin_delete_sq`` -``NVME_LBART_TYPE_FS`` - *undescribed* +``nvme_admin_create_sq`` -``NVME_LBART_TYPE_RAID`` - *undescribed* +``nvme_admin_get_log_page`` -``NVME_LBART_TYPE_CACHE`` - *undescribed* +``nvme_admin_delete_cq`` -``NVME_LBART_TYPE_SWAP`` - *undescribed* +``nvme_admin_create_cq`` -``NVME_LBART_ATTRIB_TEMP`` - *undescribed* +``nvme_admin_identify`` -``NVME_LBART_ATTRIB_HIDE`` - *undescribed* +``nvme_admin_abort_cmd`` +``nvme_admin_set_features`` +``nvme_admin_get_features`` +``nvme_admin_async_event`` -.. c:type:: struct nvme_lba_range_type +``nvme_admin_ns_mgmt`` +``nvme_admin_fw_commit`` -**Definition** +``nvme_admin_fw_activate`` -:: +``nvme_admin_fw_download`` - struct nvme_lba_range_type { - struct nvme_lba_range_type_entry entry[NVME_FEAT_LBA_RANGE_MAX]; - }; +``nvme_admin_dev_self_test`` -**Members** +``nvme_admin_ns_attach`` +``nvme_admin_keep_alive`` +``nvme_admin_directive_send`` +``nvme_admin_directive_recv`` +``nvme_admin_virtual_mgmt`` -.. c:type:: struct nvme_plm_config +``nvme_admin_nvme_mi_send`` - **ee**; **dtwinrt**; **dtwinwt**; **dtwintt**; +``nvme_admin_nvme_mi_recv`` -**Definition** +``nvme_admin_capacity_mgmt`` -:: +``nvme_admin_lockdown`` - struct nvme_plm_config { - __le16 ee; - __u8 rsvd2[30]; - __le64 dtwinrt; - __le64 dtwinwt; - __le64 dtwintt; - __u8 rsvd56[456]; - }; +``nvme_admin_dbbuf`` -**Members** +``nvme_admin_fabrics`` +``nvme_admin_format_nvm`` +``nvme_admin_security_send`` +``nvme_admin_security_recv`` +``nvme_admin_sanitize_nvm`` -.. c:type:: struct nvme_feat_host_behavior +``nvme_admin_get_lba_status`` -**Definition** -:: - struct nvme_feat_host_behavior { - __u8 acre; - __u8 rsvd1[511]; - }; +.. c:type:: enum nvme_identify_cns -**Members** +**Constants** +``NVME_IDENTIFY_CNS_NS`` +``NVME_IDENTIFY_CNS_CTRL`` +``NVME_IDENTIFY_CNS_NS_ACTIVE_LIST`` -.. c:type:: enum +``NVME_IDENTIFY_CNS_NS_DESC_LIST`` +``NVME_IDENTIFY_CNS_NVMSET_LIST`` -**Constants** +``NVME_IDENTIFY_CNS_CSI_NS`` -``NVME_ENABLE_ACRE`` - *undescribed* +``NVME_IDENTIFY_CNS_CSI_CTRL`` +``NVME_IDENTIFY_CNS_CSI_NS_ACTIVE_LIST`` +``NVME_IDENTIFY_CNS_CSI_INDEPENDENT_ID_NS`` +``NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST`` -.. c:type:: struct nvme_dsm_range +``NVME_IDENTIFY_CNS_ALLOCATED_NS`` +``NVME_IDENTIFY_CNS_NS_CTRL_LIST`` -**Definition** +``NVME_IDENTIFY_CNS_CTRL_LIST`` -:: +``NVME_IDENTIFY_CNS_PRIMARY_CTRL_CAP`` - struct nvme_dsm_range { - __le32 cattr; - __le32 nlb; - __le64 slba; - }; +``NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST`` -**Members** +``NVME_IDENTIFY_CNS_NS_GRANULARITY`` +``NVME_IDENTIFY_CNS_UUID_LIST`` +``NVME_IDENTIFY_CNS_DOMAIN_LIST`` +``NVME_IDENTIFY_CNS_ENDURANCE_GROUP_ID`` +``NVME_IDENTIFY_CNS_CSS_ALLOCATED_NS_LIST`` -.. c:type:: struct nvme_registered_ctrl +``NVME_IDENTIFY_CNS_COMMAND_SET_STRUCTURE`` + Base Specification 2.0a section 5.17.2.21 -**Definition** -:: - struct nvme_registered_ctrl { - __le16 cntlid; - __u8 rcsts; - __u8 rsvd3[5]; - __le64 hostid; - __le64 rkey; - }; +.. c:type:: enum nvme_cmd_get_log_lid -**Members** +**Constants** + +``NVME_LOG_LID_SUPPORTED_LOG_PAGES`` +``NVME_LOG_LID_ERROR`` +``NVME_LOG_LID_SMART`` +``NVME_LOG_LID_FW_SLOT`` -.. c:type:: struct nvme_registered_ctrl_ext +``NVME_LOG_LID_CHANGED_NS`` +``NVME_LOG_LID_CMD_EFFECTS`` -**Definition** +``NVME_LOG_LID_DEVICE_SELF_TEST`` -:: +``NVME_LOG_LID_TELEMETRY_HOST`` - struct nvme_registered_ctrl_ext { - __le16 cntlid; - __u8 rcsts; - __u8 rsvd3[5]; - __le64 rkey; - __u8 hostid[16]; - __u8 rsvd32[32]; - }; +``NVME_LOG_LID_TELEMETRY_CTRL`` -**Members** +``NVME_LOG_LID_ENDURANCE_GROUP`` +``NVME_LOG_LID_PREDICTABLE_LAT_NVMSET`` +``NVME_LOG_LID_PREDICTABLE_LAT_AGG`` +``NVME_LOG_LID_ANA`` +``NVME_LOG_LID_PERSISTENT_EVENT`` -.. c:type:: struct nvme_reservation_status +``NVME_LOG_LID_LBA_STATUS`` - { +``NVME_LOG_LID_ENDURANCE_GRP_EVT`` -**Definition** +``NVME_LOG_LID_MEDIA_UNIT_STATUS`` -:: +``NVME_LOG_LID_FID_SUPPORTED_EFFECTS`` - struct nvme_reservation_status { - __le32 gen; - __u8 rtype; - __u8 regctl[2]; - __u8 rsvd7[2]; - __u8 ptpls; - __u8 rsvd10[14]; - union { - struct { - __u8 rsvd24[40]; - struct nvme_registered_ctrl_ext regctl_eds[0]; - }; - struct nvme_registered_ctrl regctl_ds[0]; - }; - }; +``NVME_LOG_LID_BOOT_PARTITION`` -**Members** +``NVME_LOG_LID_DISCOVER`` -``{unnamed_union}`` - anonymous +``NVME_LOG_LID_RESERVATION`` -``{unnamed_struct}`` - anonymous +``NVME_LOG_LID_SANITIZE`` +``NVME_LOG_LID_ZNS_CHANGED_ZONES`` -.. c:type:: struct nvme_streams_directive_params +.. c:type:: enum nvme_features_id -**Definition** +**Constants** -:: +``NVME_FEAT_FID_ARBITRATION`` - struct nvme_streams_directive_params { - __le16 msl; - __le16 nssa; - __le16 nsso; - __u8 nssc; - __u8 rsvd[9]; - __le32 sws; - __le16 sgs; - __le16 nsa; - __le16 nso; - __u8 rsvd2[6]; - }; +``NVME_FEAT_FID_POWER_MGMT`` -**Members** +``NVME_FEAT_FID_LBA_RANGE`` +``NVME_FEAT_FID_TEMP_THRESH`` +``NVME_FEAT_FID_ERR_RECOVERY`` +``NVME_FEAT_FID_VOLATILE_WC`` +``NVME_FEAT_FID_NUM_QUEUES`` -.. c:type:: struct nvme_streams_directive_status +``NVME_FEAT_FID_IRQ_COALESCE`` +``NVME_FEAT_FID_IRQ_CONFIG`` -**Definition** +``NVME_FEAT_FID_WRITE_ATOMIC`` -:: +``NVME_FEAT_FID_ASYNC_EVENT`` - struct nvme_streams_directive_status { - __le16 osc; - __le16 sid[]; - }; +``NVME_FEAT_FID_AUTO_PST`` -**Members** +``NVME_FEAT_FID_HOST_MEM_BUF`` +``NVME_FEAT_FID_TIMESTAMP`` +``NVME_FEAT_FID_KATO`` +``NVME_FEAT_FID_HCTM`` +``NVME_FEAT_FID_NOPSC`` -.. c:type:: struct nvme_id_directives +``NVME_FEAT_FID_RRL`` +``NVME_FEAT_FID_PLM_CONFIG`` -**Definition** +``NVME_FEAT_FID_PLM_WINDOW`` -:: +``NVME_FEAT_FID_LBA_STS_INTERVAL`` - struct nvme_id_directives { - __u8 supported[32]; - __u8 enabled[32]; - __u8 rsvd64[4032]; - }; +``NVME_FEAT_FID_HOST_BEHAVIOR`` -**Members** +``NVME_FEAT_FID_SANITIZE`` +``NVME_FEAT_FID_ENDURANCE_EVT_CFG`` +``NVME_FEAT_FID_IOCS_PROFILE`` +``NVME_FEAT_FID_SPINUP_CONTROL`` +``NVME_FEAT_FID_CTRL_METADATA`` + Controller Metadata -.. c:type:: enum +``NVME_FEAT_FID_NS_METADATA`` + Namespace Metadata +``NVME_FEAT_FID_SW_PROGRESS`` -**Constants** +``NVME_FEAT_FID_HOST_ID`` -``NVME_ID_DIR_ID_BIT`` - *undescribed* +``NVME_FEAT_FID_RESV_MASK`` -``NVME_ID_DIR_SD_BIT`` - *undescribed* +``NVME_FEAT_FID_RESV_PERSIST`` +``NVME_FEAT_FID_WRITE_PROTECT`` -.. c:type:: enum nvme_ae_type +.. c:type:: enum nvme_feat **Constants** -``NVME_AER_ERROR`` - *undescribed* +``NVME_FEAT_ARBITRATION_BURST_SHIFT`` -``NVME_AER_SMART`` - *undescribed* +``NVME_FEAT_ARBITRATION_BURST_MASK`` -``NVME_AER_NOTICE`` - *undescribed* +``NVME_FEAT_ARBITRATION_LPW_SHIFT`` -``NVME_AER_CSS`` - *undescribed* +``NVME_FEAT_ARBITRATION_LPW_MASK`` -``NVME_AER_VS`` - *undescribed* +``NVME_FEAT_ARBITRATION_MPW_SHIFT`` +``NVME_FEAT_ARBITRATION_MPW_MASK`` +``NVME_FEAT_ARBITRATION_HPW_SHIFT`` +``NVME_FEAT_ARBITRATION_HPW_MASK`` -.. c:type:: enum nvme_ae_info_error +``NVME_FEAT_PWRMGMT_PS_SHIFT`` +``NVME_FEAT_PWRMGMT_PS_MASK`` -**Constants** +``NVME_FEAT_PWRMGMT_WH_SHIFT`` -``NVME_AER_ERROR_INVALID_DB_REG`` - *undescribed* +``NVME_FEAT_PWRMGMT_WH_MASK`` -``NVME_AER_ERROR_INVALID_DB_VAL`` - *undescribed* +``NVME_FEAT_LBAR_NR_SHIFT`` -``NVME_AER_ERROR_DIAG_FAILURE`` - *undescribed* +``NVME_FEAT_LBAR_NR_MASK`` -``NVME_AER_ERROR_PERSISTENT_INTERNAL_ERROR`` - *undescribed* +``NVME_FEAT_TT_TMPTH_SHIFT`` -``NVME_AER_ERROR_TRANSIENT_INTERNAL_ERROR`` - *undescribed* +``NVME_FEAT_TT_TMPTH_MASK`` -``NVME_AER_ERROR_FW_IMAGE_LOAD_ERROR`` - *undescribed* +``NVME_FEAT_TT_TMPSEL_SHIFT`` +``NVME_FEAT_TT_TMPSEL_MASK`` +``NVME_FEAT_TT_THSEL_SHIFT`` +``NVME_FEAT_TT_THSEL_MASK`` -.. c:type:: enum nvme_ae_info_smart +``NVME_FEAT_ERROR_RECOVERY_TLER_SHIFT`` +``NVME_FEAT_ERROR_RECOVERY_TLER_MASK`` -**Constants** +``NVME_FEAT_ERROR_RECOVERY_DULBE_SHIFT`` -``NVME_AER_SMART_SUBSYSTEM_RELIABILITY`` - *undescribed* +``NVME_FEAT_ERROR_RECOVERY_DULBE_MASK`` -``NVME_AER_SMART_TEMPERATURE_THRESHOLD`` - *undescribed* +``NVME_FEAT_VWC_WCE_SHIFT`` -``NVME_AER_SMART_SPARE_THRESHOLD`` - *undescribed* +``NVME_FEAT_VWC_WCE_MASK`` +``NVME_FEAT_NRQS_NSQR_SHIFT`` +``NVME_FEAT_NRQS_NSQR_MASK`` +``NVME_FEAT_NRQS_NCQR_SHIFT`` -.. c:type:: enum nvme_ae_info_css_nvm +``NVME_FEAT_NRQS_NCQR_MASK`` +``NVME_FEAT_IRQC_THR_SHIFT`` -**Constants** +``NVME_FEAT_IRQC_THR_MASK`` -``NVME_AER_CSS_NVM_RESERVATION`` - *undescribed* +``NVME_FEAT_IRQC_TIME_SHIFT`` -``NVME_AER_CSS_NVM_SANITIZE_COMPLETED`` - *undescribed* +``NVME_FEAT_IRQC_TIME_MASK`` -``NVME_AER_CSS_NVM_UNEXPECTED_SANITIZE_DEALLOC`` - *undescribed* +``NVME_FEAT_ICFG_IV_SHIFT`` +``NVME_FEAT_ICFG_IV_MASK`` +``NVME_FEAT_ICFG_CD_SHIFT`` +``NVME_FEAT_ICFG_CD_MASK`` -.. c:type:: enum nvme_ae_info_notice +``NVME_FEAT_WA_DN_SHIFT`` +``NVME_FEAT_WA_DN_MASK`` -**Constants** +``NVME_FEAT_AE_SMART_SHIFT`` -``NVME_AER_NOTICE_NS_CHANGED`` - *undescribed* +``NVME_FEAT_AE_SMART_MASK`` -``NVME_AER_NOTICE_FW_ACT_STARTING`` - *undescribed* +``NVME_FEAT_AE_NAN_SHIFT`` -``NVME_AER_NOTICE_TELEMETRY`` - *undescribed* +``NVME_FEAT_AE_NAN_MASK`` -``NVME_AER_NOTICE_ANA`` - *undescribed* +``NVME_FEAT_AE_FW_SHIFT`` -``NVME_AER_NOTICE_PL_EVENT`` - *undescribed* +``NVME_FEAT_AE_FW_MASK`` -``NVME_AER_NOTICE_LBA_STATUS_ALERT`` - *undescribed* +``NVME_FEAT_AE_TELEM_SHIFT`` -``NVME_AER_NOTICE_EG_EVENT`` - *undescribed* +``NVME_FEAT_AE_TELEM_MASK`` -``NVME_AER_NOTICE_DISC_CHANGED`` - *undescribed* +``NVME_FEAT_AE_ANA_SHIFT`` +``NVME_FEAT_AE_ANA_MASK`` +``NVME_FEAT_AE_PLA_SHIFT`` +``NVME_FEAT_AE_PLA_MASK`` -.. c:type:: enum nvme_subsys_type +``NVME_FEAT_AE_LBAS_SHIFT`` +``NVME_FEAT_AE_LBAS_MASK`` -**Constants** +``NVME_FEAT_AE_EGA_SHIFT`` -``NVME_NQN_DISC`` - Discovery type target subsystem +``NVME_FEAT_AE_EGA_MASK`` -``NVME_NQN_NVME`` - NVME type target subsystem +``NVME_FEAT_APST_APSTE_SHIFT`` +``NVME_FEAT_APST_APSTE_MASK`` +``NVME_FEAT_HMEM_EHM_SHIFT`` +``NVME_FEAT_HMEM_EHM_MASK`` -.. c:type:: struct nvmf_disc_log_entry +``NVME_FEAT_HCTM_TMT2_SHIFT`` - Discovery log page entry +``NVME_FEAT_HCTM_TMT2_MASK`` -**Definition** +``NVME_FEAT_HCTM_TMT1_SHIFT`` -:: +``NVME_FEAT_HCTM_TMT1_MASK`` - struct nvmf_disc_log_entry { - __u8 trtype; - __u8 adrfam; - __u8 subtype; - __u8 treq; - __le16 portid; - __le16 cntlid; - __le16 asqsz; - __u8 rsvd10[22]; - char trsvcid[NVMF_TRSVCID_SIZE]; - __u8 rsvd64[192]; - char subnqn[NVME_NQN_LENGTH]; - char traddr[NVMF_TRADDR_SIZE]; - union tsas { - char common[NVMF_TSAS_SIZE]; - struct rdma { - __u8 qptype; - __u8 prtype; - __u8 cms; - __u8 rsvd3[5]; - __u16 pkey; - __u8 rsvd10[246]; - } rdma; - struct tcp { - __u8 sectype; - } tcp; - } tsas; - }; +``NVME_FEAT_NOPS_NOPPME_SHIFT`` -**Members** +``NVME_FEAT_NOPS_NOPPME_MASK`` +``NVME_FEAT_RRL_RRL_SHIFT`` +``NVME_FEAT_RRL_RRL_MASK`` +``NVME_FEAT_PLM_PLME_SHIFT`` +``NVME_FEAT_PLM_PLME_MASK`` -.. c:type:: enum +``NVME_FEAT_PLMW_WS_SHIFT`` - Transport Type codes for Discovery Log Page entry TRTYPE field +``NVME_FEAT_PLMW_WS_MASK`` -**Constants** +``NVME_FEAT_LBAS_LSIRI_SHIFT`` -``NVMF_TRTYPE_UNSPECIFIED`` - Not indicated +``NVME_FEAT_LBAS_LSIRI_MASK`` -``NVMF_TRTYPE_RDMA`` - RDMA +``NVME_FEAT_LBAS_LSIPI_SHIFT`` -``NVMF_TRTYPE_FC`` - Fibre Channel +``NVME_FEAT_LBAS_LSIPI_MASK`` -``NVMF_TRTYPE_TCP`` - TCP +``NVME_FEAT_SC_NODRM_SHIFT`` -``NVMF_TRTYPE_LOOP`` - Reserved for host usage +``NVME_FEAT_SC_NODRM_MASK`` -``NVMF_TRTYPE_MAX`` - *undescribed* +``NVME_FEAT_EG_ENDGID_SHIFT`` +``NVME_FEAT_EG_ENDGID_MASK`` +``NVME_FEAT_EG_EGCW_SHIFT`` +``NVME_FEAT_EG_EGCW_MASK`` -.. c:type:: enum +``NVME_FEAT_SPM_PBSLC_SHIFT`` - Address Family codes for Discovery Log Page entry ADRFAM field +``NVME_FEAT_SPM_PBSLC_MASK`` -**Constants** +``NVME_FEAT_HOSTID_EXHID_SHIFT`` -``NVMF_ADDR_FAMILY_PCI`` - PCIe +``NVME_FEAT_HOSTID_EXHID_MASK`` -``NVMF_ADDR_FAMILY_IP4`` - IPv4 +``NVME_FEAT_RM_REGPRE_SHIFT`` -``NVMF_ADDR_FAMILY_IP6`` - IPv6 +``NVME_FEAT_RM_REGPRE_MASK`` -``NVMF_ADDR_FAMILY_IB`` - InfiniBand +``NVME_FEAT_RM_RESREL_SHIFT`` -``NVMF_ADDR_FAMILY_FC`` - Fibre Channel +``NVME_FEAT_RM_RESREL_MASK`` +``NVME_FEAT_RM_RESPRE_SHIFT`` +``NVME_FEAT_RM_RESPRE_MASK`` +``NVME_FEAT_RP_PTPL_SHIFT`` -.. c:type:: enum +``NVME_FEAT_RP_PTPL_MASK`` - Transport Requirements codes for Discovery Log Page entry TREQ field +``NVME_FEAT_WP_WPS_SHIFT`` -**Constants** +``NVME_FEAT_WP_WPS_MASK`` -``NVMF_TREQ_NOT_SPECIFIED`` - Not specified +``NVME_FEAT_IOCSP_IOCSCI_SHIFT`` -``NVMF_TREQ_REQUIRED`` - Required +``NVME_FEAT_IOCSP_IOCSCI_MASK`` -``NVMF_TREQ_NOT_REQUIRED`` - Not Required -``NVMF_TREQ_DISABLE_SQFLOW`` - SQ flow control disable supported +.. c:type:: enum nvme_get_features_sel -.. c:type:: enum +**Constants** - RDMA QP Service Type codes for Discovery Log Page entry TSAS RDMA_QPTYPE field +``NVME_GET_FEATURES_SEL_CURRENT`` -**Constants** +``NVME_GET_FEATURES_SEL_DEFAULT`` -``NVMF_RDMA_QPTYPE_CONNECTED`` - Reliable Connected +``NVME_GET_FEATURES_SEL_SAVED`` -``NVMF_RDMA_QPTYPE_DATAGRAM`` - Reliable Datagram +``NVME_GET_FEATURES_SEL_SUPPORTED`` -.. c:type:: enum +.. c:type:: enum nvme_cmd_format_mset - RDMA Provider Type codes for Discovery Log Page entry TSAS RDMA_PRTYPE field + Format NVM - Metadata Settings **Constants** -``NVMF_RDMA_PRTYPE_NOT_SPECIFIED`` - No Provider Specified +``NVME_FORMAT_MSET_SEPARATE`` + indicates that the metadata is transferred + as part of a separate buffer. -``NVMF_RDMA_PRTYPE_IB`` - InfiniBand +``NVME_FORMAT_MSET_EXTENDED`` + indicates that the metadata is transferred + as part of an extended data LBA. -``NVMF_RDMA_PRTYPE_ROCE`` - InfiniBand RoCE -``NVMF_RDMA_PRTYPE_ROCEV2`` - InfiniBand RoCEV2 -``NVMF_RDMA_PRTYPE_IWARP`` - iWARP +.. c:type:: enum nvme_cmd_format_pi + Format NVM - Protection Information +**Constants** -.. c:type:: enum +``NVME_FORMAT_PI_DISABLE`` + Protection information is not enabled. - RDMA Connection Management Service Type codes for Discovery Log Page entry TSAS RDMA_CMS field +``NVME_FORMAT_PI_TYPE1`` + Protection information is enabled, Type 1. -**Constants** +``NVME_FORMAT_PI_TYPE2`` + Protection information is enabled, Type 2. -``NVMF_RDMA_CMS_RDMA_CM`` - Sockets based endpoint addressing +``NVME_FORMAT_PI_TYPE3`` + Protection information is enabled, Type 3. -.. c:type:: enum +.. c:type:: enum nvme_cmd_format_pil + Format NVM - Protection Information Location **Constants** -``NVMF_TCP_SECTYPE_NONE`` - No Security - -``NVMF_TCP_SECTYPE_TLS`` - Transport Layer Security +``NVME_FORMAT_PIL_LAST`` + Protection information is transferred as the last + bytes of metadata. +``NVME_FORMAT_PIL_FIRST`` + Protection information is transferred as the first + bytes of metadata. -.. c:type:: struct nvmf_discovery_log +.. c:type:: enum nvme_cmd_format_ses -**Definition** + Format NVM - Secure Erase Settings -:: +**Constants** - struct nvmf_discovery_log { - __le64 genctr; - __le64 numrec; - __le16 recfmt; - __u8 rsvd14[1006]; - struct nvmf_disc_log_entry entries[]; - }; +``NVME_FORMAT_SES_NONE`` + No secure erase operation requested. -**Members** +``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. +``NVME_FORMAT_SES_CRYPTO_ERASE`` + Cryptographic Erase: All user data shall + be erased cryptographically. This is + accomplished by deleting the encryption key. -.. c:type:: struct nvmf_connect_data +.. c:type:: enum nvme_ns_mgmt_sel -**Definition** +**Constants** -:: +``NVME_NS_MGMT_SEL_CREATE`` - struct nvmf_connect_data { - __u8 hostid[16]; - __le16 cntlid; - char rsvd4[238]; - char subsysnqn[NVME_NQN_LENGTH]; - char hostnqn[NVME_NQN_LENGTH]; - char rsvd5[256]; - }; +``NVME_NS_MGMT_SEL_DELETE`` -**Members** -``cntlid`` - **subsysnqn** - **hostnqn** +.. c:type:: enum nvme_ns_attach_sel +**Constants** -.. c:type:: struct nvme_mi_read_nvm_ss_info +``NVME_NS_ATTACH_SEL_CTRL_ATTACH`` +``NVME_NS_ATTACH_SEL_CTRL_DEATTACH`` -**Definition** -:: - struct nvme_mi_read_nvm_ss_info { - __u8 nump; - __u8 mjr; - __u8 mnr; - __u8 rsvd3[29]; - }; -**Members** +.. c:type:: enum nvme_fw_commit_ca +**Constants** +``NVME_FW_COMMIT_CA_REPLACE`` +``NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE`` -.. c:type:: struct nvme_mi_port_pcie +``NVME_FW_COMMIT_CA_SET_ACTIVE`` +``NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE_IMMEDIATE`` -**Definition** +``NVME_FW_COMMIT_CA_REPLACE_BOOT_PARTITION`` -:: +``NVME_FW_COMMIT_CA_ACTIVATE_BOOT_PARTITION`` - struct nvme_mi_port_pcie { - __u8 mps; - __u8 sls; - __u8 cls; - __u8 mlw; - __u8 nlw; - __u8 pn; - __u8 rsvd14[18]; - }; -**Members** +.. c:type:: enum nvme_directive_dtype +**Constants** -.. c:type:: struct nvme_mi_port_smb +``NVME_DIRECTIVE_DTYPE_IDENTIFY`` +``NVME_DIRECTIVE_DTYPE_STREAMS`` -**Definition** -:: - struct nvme_mi_port_smb { - __u8 vpd_addr; - __u8 mvpd_freq; - __u8 mme_addr; - __u8 mme_freq; - __u8 nvmebm; - __u8 rsvd13[19]; - }; -**Members** +.. c:type:: enum nvme_directive_receive_doper +**Constants** +``NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM`` +``NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM`` -.. c:type:: struct nvme_mi_read_port_info +``NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS`` +``NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE`` -**Definition** -:: - struct nvme_mi_read_port_info { - __u8 portt; - __u8 rsvd1; - __le16 mmctptus; - __le32 meb; - union { - struct nvme_mi_port_pcie pcie; - struct nvme_mi_port_smb smb; - }; - }; -**Members** +.. c:type:: enum nvme_directive_send_doper -``portt`` - **mmctptus**; -``{unnamed_union}`` - anonymous +**Constants** +``NVME_DIRECTIVE_SEND_IDENTIFY_DOPER_ENDIR`` +``NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_IDENTIFIER`` +``NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE`` -.. c:type:: struct nvme_mi_read_ctrl_info - **portid**; **prii**; **pri**; **vid**; **did**; **ssvid**; **ssid**; -**Definition** +.. c:type:: enum nvme_directive_send_identify_endir -:: - struct nvme_mi_read_ctrl_info { - __u8 portid; - __u8 rsvd1[4]; - __u8 prii; - __le16 pri; - __le16 vid; - __le16 did; - __le16 ssvid; - __le16 ssid; - __u8 rsvd16[16]; - }; +**Constants** -**Members** +``NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_DISABLE`` +``NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_ENABLE`` -.. c:type:: struct nvme_mi_osc +.. c:type:: enum nvme_sanitize_sanact - **type**; **opc**; + Sanitize Action -**Definition** +**Constants** -:: +``NVME_SANITIZE_SANACT_EXIT_FAILURE`` + Exit Failure Mode. - struct nvme_mi_osc { - __u8 type; - __u8 opc; - }; +``NVME_SANITIZE_SANACT_START_BLOCK_ERASE`` + Start a Block Erase sanitize operation. -**Members** +``NVME_SANITIZE_SANACT_START_OVERWRITE`` + Start an Overwrite sanitize operation. +``NVME_SANITIZE_SANACT_START_CRYPTO_ERASE`` + Start a Crypto Erase sanitize operation. -.. c:type:: struct nvme_mi_read_sc_list +.. c:type:: enum nvme_dst_stc + Action taken by the Device Self-test command -**Definition** +**Constants** -:: +``NVME_DST_STC_SHORT`` + Start a short device self-test operation - struct nvme_mi_read_sc_list { - __le16 numcmd; - struct nvme_mi_osc cmds[]; - }; +``NVME_DST_STC_LONG`` + Start an extended device self-test operation -**Members** +``NVME_DST_STC_VS`` + Start a vendor specific device self-test operation +``NVME_DST_STC_ABORT`` + Abort device self-test operation -.. c:type:: struct nvme_mi_nvm_ss_health_status +.. c:type:: enum nvme_virt_mgmt_act -**Definition** +**Constants** -:: +``NVME_VIRT_MGMT_ACT_PRIM_CTRL_FLEX_ALLOC`` - struct nvme_mi_nvm_ss_health_status { - __u8 nss; - __u8 sw; - __u8 ctemp; - __u8 pdlu; - __le16 ccs; - __u8 rsvd8[2]; - }; +``NVME_VIRT_MGMT_ACT_OFFLINE_SEC_CTRL`` -**Members** +``NVME_VIRT_MGMT_ACT_ASSIGN_SEC_CTRL`` +``NVME_VIRT_MGMT_ACT_ONLINE_SEC_CTRL`` -.. c:type:: enum +.. c:type:: enum nvme_virt_mgmt_rt **Constants** -``NVME_MI_CCS_RDY`` - *undescribed* +``NVME_VIRT_MGMT_RT_VQ_RESOURCE`` -``NVME_MI_CSS_CFS`` - *undescribed* +``NVME_VIRT_MGMT_RT_VI_RESOURCE`` -``NVME_MI_CSS_SHST`` - *undescribed* -``NVME_MI_CSS_NSSRO`` - *undescribed* -``NVME_MI_CSS_CECO`` - *undescribed* -``NVME_MI_CSS_NAC`` - *undescribed* +.. c:type:: enum nvme_ns_write_protect_cfg -``NVME_MI_CSS_FA`` - *undescribed* -``NVME_MI_CSS_CSTS`` - *undescribed* +**Constants** -``NVME_MI_CSS_CTEMP`` - *undescribed* +``NVME_NS_WP_CFG_NONE`` -``NVME_MI_CSS_PDLU`` - *undescribed* +``NVME_NS_WP_CFG_PROTECT`` -``NVME_MI_CSS_SPARE`` - *undescribed* +``NVME_NS_WP_CFG_PROTECT_POWER_CYCLE`` -``NVME_MI_CSS_CCWARN`` - *undescribed* +``NVME_NS_WP_CFG_PROTECT_PERMANENT`` -.. c:type:: struct nvme_mi_ctrl_heal_status +.. c:type:: enum nvme_log_ana_lsp -**Definition** +**Constants** -:: +``NVME_LOG_ANA_LSP_RGO_NAMESPACES`` - struct nvme_mi_ctrl_heal_status { - __le16 ctlid; - __le16 csts; - __le16 ctemp; - __u8 pdlu; - __u8 spare; - __u8 cwarn; - __u8 rsvd9[7]; - }; +``NVME_LOG_ANA_LSP_RGO_GROUPS_ONLY`` -**Members** +.. c:type:: enum nvme_pevent_log_action -.. c:type:: enum +**Constants** +``NVME_PEVENT_LOG_READ`` -**Constants** +``NVME_PEVENT_LOG_EST_CTX_AND_READ`` -``NVME_MI_CSTS_RDY`` - *undescribed* +``NVME_PEVENT_LOG_RELEASE_CTX`` -``NVME_MI_CSTS_CFS`` - *undescribed* -``NVME_MI_CSTS_SHST`` - *undescribed* -``NVME_MI_CSTS_NSSRO`` - *undescribed* -``NVME_MI_CSTS_CECO`` - *undescribed* +.. c:type:: enum nvme_feat_tmpthresh_thsel -``NVME_MI_CSTS_NAC`` - *undescribed* -``NVME_MI_CSTS_FA`` - *undescribed* +**Constants** -``NVME_MI_CWARN_ST`` - *undescribed* +``NVME_FEATURE_TEMPTHRESH_THSEL_OVER`` -``NVME_MI_CWARN_TAUT`` - *undescribed* +``NVME_FEATURE_TEMPTHRESH_THSEL_UNDER`` -``NVME_MI_CWARN_RD`` - *undescribed* -``NVME_MI_CWARN_RO`` - *undescribed* -``NVME_MI_CWARN_VMBF`` - *undescribed* +.. c:type:: enum nvme_features_async_event_config_flags +**Constants** -.. c:type:: struct nvme_mi_vpd_mra +``NVME_FEATURE_AENCFG_SMART_CRIT_SPARE`` - **nmravn**; **ff**; **i18vpwr**; **m18vpwr**; **i33vpwr**; **m33vpwr**; **m33vapsr**; **i5vapsr**; **m5vapsr**; **i12vapsr**; **m12vapsr**; **mtl**; **tnvmcap**[16]; +``NVME_FEATURE_AENCFG_SMART_CRIT_TEMPERATURE`` -**Definition** +``NVME_FEATURE_AENCFG_SMART_CRIT_DEGRADED`` -:: +``NVME_FEATURE_AENCFG_SMART_CRIT_READ_ONLY`` - struct nvme_mi_vpd_mra { - __u8 nmravn; - __u8 ff; - __u8 rsvd7[6]; - __u8 i18vpwr; - __u8 m18vpwr; - __u8 i33vpwr; - __u8 m33vpwr; - __u8 rsvd17; - __u8 m33vapsr; - __u8 i5vapsr; - __u8 m5vapsr; - __u8 i12vapsr; - __u8 m12vapsr; - __u8 mtl; - __u8 tnvmcap[16]; - __u8 rsvd37[27]; - }; +``NVME_FEATURE_AENCFG_SMART_CRIT_VOLATILE_BACKUP`` -**Members** +``NVME_FEATURE_AENCFG_SMART_CRIT_READ_ONLY_PMR`` +``NVME_FEATURE_AENCFG_NOTICE_NAMESPACE_ATTRIBUTES`` +``NVME_FEATURE_AENCFG_NOTICE_FIRMWARE_ACTIVATION`` +``NVME_FEATURE_AENCFG_NOTICE_TELEMETRY_LOG`` +``NVME_FEATURE_AENCFG_NOTICE_ANA_CHANGE`` -.. c:type:: struct nvme_mi_vpd_ppmra +``NVME_FEATURE_AENCFG_NOTICE_PL_EVENT`` +``NVME_FEATURE_AENCFG_NOTICE_LBA_STATUS`` -**Definition** +``NVME_FEATURE_AENCFG_NOTICE_EG_EVENT`` -:: +``NVME_FEATURE_AENCFG_NOTICE_DISCOVERY_CHANGE`` - struct nvme_mi_vpd_ppmra { - __u8 nppmravn; - __u8 pn; - __u8 ppi; - __u8 ls; - __u8 mlw; - __u8 mctp; - __u8 refccap; - __u8 pi; - __u8 rsvd13[3]; - }; -**Members** +.. c:type:: enum nvme_feat_plm_window_select +**Constants** -.. c:type:: struct nvme_mi_vpd_telem +``NVME_FEATURE_PLM_DTWIN`` +``NVME_FEATURE_PLM_NDWIN`` -**Definition** -:: - struct nvme_mi_vpd_telem { - __u8 type; - __u8 rev; - __u8 len; - __u8 data[0]; - }; -**Members** +.. c:type:: enum nvme_feat_resv_notify_flags +**Constants** +``NVME_FEAT_RESV_NOTIFY_REGPRE`` +``NVME_FEAT_RESV_NOTIFY_RESREL`` -.. c:type:: enum +``NVME_FEAT_RESV_NOTIFY_RESPRE`` -**Constants** -``NVME_MI_ELEM_EED`` - *undescribed* -``NVME_MI_ELEM_USCE`` - *undescribed* +.. c:type:: enum nvme_feat_nswpcfg_state -``NVME_MI_ELEM_ECED`` - *undescribed* -``NVME_MI_ELEM_LED`` - *undescribed* +**Constants** + +``NVME_FEAT_NS_NO_WRITE_PROTECT`` + +``NVME_FEAT_NS_WRITE_PROTECT`` -``NVME_MI_ELEM_SMBMED`` - *undescribed* +``NVME_FEAT_NS_WRITE_PROTECT_PWR_CYCLE`` -``NVME_MI_ELEM_PCIESED`` - *undescribed* +``NVME_FEAT_NS_WRITE_PROTECT_PERMANENT`` -``NVME_MI_ELEM_NVMED`` - *undescribed* +.. c:type:: enum nvme_fctype -.. c:type:: struct nvme_mi_vpd_tra +**Constants** -**Definition** +``nvme_fabrics_type_property_set`` -:: +``nvme_fabrics_type_connect`` - struct nvme_mi_vpd_tra { - __u8 vn; - __u8 rsvd6; - __u8 ec; - struct nvme_mi_vpd_telem elems[0]; - }; +``nvme_fabrics_type_property_get`` -**Members** +``nvme_fabrics_type_auth_send`` +``nvme_fabrics_type_auth_receive`` +``nvme_fabrics_type_disconnect`` -.. c:type:: struct nvme_mi_vpd_mr_common +.. c:type:: enum nvme_io_opcode -**Definition** -:: +**Constants** - struct nvme_mi_vpd_mr_common { - __u8 type; - __u8 rf; - __u8 rlen; - __u8 rchksum; - __u8 hchksum; - union { - struct nvme_mi_vpd_mra nmra; - struct nvme_mi_vpd_ppmra ppmra; - struct nvme_mi_vpd_tra tmra; - }; - }; +``nvme_cmd_flush`` -**Members** +``nvme_cmd_write`` -``{unnamed_union}`` - anonymous +``nvme_cmd_read`` +``nvme_cmd_write_uncor`` +``nvme_cmd_compare`` +``nvme_cmd_write_zeroes`` +``nvme_cmd_dsm`` -.. c:type:: struct nvme_mi_vpd_hdr +``nvme_cmd_verify`` +``nvme_cmd_resv_register`` -**Definition** +``nvme_cmd_resv_report`` -:: +``nvme_cmd_resv_acquire`` - struct nvme_mi_vpd_hdr { - __u8 ipmiver; - __u8 iuaoff; - __u8 ciaoff; - __u8 biaoff; - __u8 piaoff; - __u8 mrioff; - __u8 rsvd6; - __u8 chchk; - __u8 vpd[]; - }; +``nvme_cmd_resv_release`` -**Members** +``nvme_cmd_copy`` +``nvme_zns_cmd_mgmt_send`` +``nvme_zns_cmd_mgmt_recv`` +``nvme_zns_cmd_append`` -.. c:type:: enum nvme_status_field - Defines all parts of the nvme status field: status code, status code type, and additional flags. -**Constants** +.. c:type:: enum nvme_io_control_flags -``NVME_SCT_GENERIC`` - Generic errors applicable to multiple opcodes -``NVME_SCT_CMD_SPECIFIC`` - Errors associated to a specific opcode +**Constants** -``NVME_SCT_MEDIA`` - Errors associated with media and data integrity +``NVME_IO_DTYPE_STREAMS`` -``NVME_SCT_PATH`` - Errors associated with the paths connection +``NVME_IO_DEAC`` -``NVME_SCT_VS`` - Vendor specific errors +``NVME_IO_ZNS_APPEND_PIREMAP`` -``NVME_SCT_MASK`` - Mask to get the value of the Status Code Type +``NVME_IO_PRINFO_PRCHK_REF`` -``NVME_SC_MASK`` - Mask to get the value of the status code. +``NVME_IO_PRINFO_PRCHK_APP`` -``NVME_SC_SUCCESS`` - Successful Completion: The command - completed without error. +``NVME_IO_PRINFO_PRCHK_GUARD`` -``NVME_SC_INVALID_OPCODE`` - Invalid Command Opcode: A reserved coded - value or an unsupported value in the - command opcode field. +``NVME_IO_PRINFO_PRACT`` -``NVME_SC_INVALID_FIELD`` - Invalid Field in Command: A reserved - coded value or an unsupported value in a - defined field. +``NVME_IO_FUA`` -``NVME_SC_CMDID_CONFLICT`` - Command ID Conflict: The command - identifier is already in use. +``NVME_IO_LR`` -``NVME_SC_DATA_XFER_ERROR`` - Data Transfer Error: Transferring the - 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. -``NVME_SC_INTERNAL`` - Internal Error: The command was not - 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. +.. c:type:: enum nvme_io_dsm_flags -``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. -``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. +**Constants** -``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. +``NVME_IO_DSM_FREQ_UNSPEC`` -``NVME_SC_INVALID_NS`` - Invalid Namespace or Format: The - namespace or the format of that namespace - is invalid. +``NVME_IO_DSM_FREQ_TYPICAL`` -``NVME_SC_CMD_SEQ_ERROR`` - Command Sequence Error: The command was - aborted due to a protocol violation in a - multi-command sequence. +``NVME_IO_DSM_FREQ_RARE`` -``NVME_SC_SGL_INVALID_LAST`` - Invalid SGL Segment Descriptor: The - command includes an invalid SGL Last - Segment or SGL Segment descriptor. +``NVME_IO_DSM_FREQ_READS`` -``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. +``NVME_IO_DSM_FREQ_WRITES`` -``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. +``NVME_IO_DSM_FREQ_RW`` -``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. +``NVME_IO_DSM_FREQ_ONCE`` -``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. +``NVME_IO_DSM_FREQ_PREFETCH`` -``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_IO_DSM_FREQ_TEMP`` -``NVME_SC_PRP_INVALID_OFFSET`` - PRP Offset Invalid: The Offset field for - a PRP entry is invalid. +``NVME_IO_DSM_LATENCY_NONE`` -``NVME_SC_AWU_EXCEEDED`` - Atomic Write Unit Exceeded: The length - specified exceeds the atomic write unit size. +``NVME_IO_DSM_LATENCY_IDLE`` -``NVME_SC_OP_DENIED`` - Operation Denied: The command was denied - due to lack of access rights. Refer to - the appropriate security specification. +``NVME_IO_DSM_LATENCY_NORM`` -``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. +``NVME_IO_DSM_LATENCY_LOW`` -``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. +``NVME_IO_DSM_SEQ_REQ`` -``NVME_SC_KAT_EXPIRED`` - Keep Alive Timer Expired: The Keep Alive - Timer expired. +``NVME_IO_DSM_COMPRESSED`` -``NVME_SC_KAT_INVALID`` - Keep Alive Timeout Invalid: The Keep - 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. -``NVME_SC_SANITIZE_FAILED`` - Sanitize Failed: The most recent sanitize - 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. +.. c:type:: enum nvme_dsm_attributes -``NVME_SC_SGL_INVALID_GRANULARITY`` - SGL Data Block Granularity Invalid: The - 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. +**Constants** -``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. +``NVME_DSMGMT_IDR`` -``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. +``NVME_DSMGMT_IDW`` -``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. +``NVME_DSMGMT_AD`` -``NVME_SC_LBA_RANGE`` - LBA Out of Range: The command references - 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. -``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. -``NVME_SC_RESERVATION_CONFLICT`` - Reservation Conflict: The command was - aborted due to a conflict with a - reservation held on the accessed - namespace. +.. c:type:: enum nvme_resv_rtype -``NVME_SC_FORMAT_IN_PROGRESS`` - Format In Progress: A Format NVM command - is in progress on the namespace. -``NVME_SC_CQ_INVALID`` - Completion Queue Invalid: The Completion - Queue identifier specified in the command - does not exist. +**Constants** -``NVME_SC_QID_INVALID`` - Invalid Queue Identifier: The creation of - the I/O Completion Queue failed due to an - invalid queue identifier specified as - part of the command. An invalid queue - identifier is one that is currently in - use or one that is outside the range - supported by the controller. +``NVME_RESERVATION_RTYPE_WE`` -``NVME_SC_QUEUE_SIZE`` - Invalid Queue Size: The host attempted to - create an I/O Completion Queue with an - invalid number of entries. +``NVME_RESERVATION_RTYPE_EA`` -``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. +``NVME_RESERVATION_RTYPE_WERO`` -``NVME_SC_ABORT_MISSING`` - Abort Command is missing: The abort - command is missing. +``NVME_RESERVATION_RTYPE_EARO`` -``NVME_SC_ASYNC_LIMIT`` - Asynchronous Event Request Limit - Exceeded: The number of concurrently - outstanding Asynchronous Event Request - commands has been exceeded. +``NVME_RESERVATION_RTYPE_WEAR`` -``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. +``NVME_RESERVATION_RTYPE_EAAR`` -``NVME_SC_FIRMWARE_IMAGE`` - Invalid Firmware Image: The firmware - 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. -``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. -``NVME_SC_INVALID_FORMAT`` - Invalid Format: The LBA Format specified - is not supported. +.. c:type:: enum nvme_resv_racqa -``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. -``NVME_SC_INVALID_QUEUE`` - Invalid Queue Deletion: Invalid I/O - Completion Queue specified to delete. +**Constants** -``NVME_SC_FEATURE_NOT_SAVEABLE`` - Feature Identifier Not Saveable: The - Feature Identifier specified does not - support a saveable value. +``NVME_RESERVATION_RACQA_ACQUIRE`` -``NVME_SC_FEATURE_NOT_CHANGEABLE`` - Feature Not Changeable: The Feature - Identifier is not able to be changed. +``NVME_RESERVATION_RACQA_PREEMPT`` -``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. +``NVME_RESERVATION_RACQA_PREEMPT_AND_ABORT`` -``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. -``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. -``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. -``NVME_SC_FW_ACTIVATE_PROHIBITED`` - Firmware Activation Prohibited: The image - specified is being prohibited from - activation by the controller for vendor - specific reasons. +.. c:type:: enum nvme_resv_rrega -``NVME_SC_OVERLAPPING_RANGE`` - Overlapping Range: The downloaded - firmware image has overlapping ranges. -``NVME_SC_NS_INSUFFICIENT_CAP`` - Namespace Insufficient Capacity: Creating - the namespace requires more free space - than is currently available. +**Constants** -``NVME_SC_NS_ID_UNAVAILABLE`` - Namespace Identifier Unavailable: The - number of namespaces supported has been - exceeded. +``NVME_RESERVATION_RREGA_REGISTER_KEY`` -``NVME_SC_NS_ALREADY_ATTACHED`` - Namespace Already Attached: The - controller is already attached to the - namespace specified. +``NVME_RESERVATION_RREGA_UNREGISTER_KEY`` -``NVME_SC_NS_IS_PRIVATE`` - Namespace Is Private: The namespace is - private and is already attached to one - controller. +``NVME_RESERVATION_RREGA_REPLACE_KEY`` -``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. -``NVME_SC_THIN_PROV_NOT_SUPP`` - Thin Provisioning Not Supported: Thin - provisioning is not supported by the - controller. -``NVME_SC_CTRL_LIST_INVALID`` - Controller List Invalid: The controller - list provided contains invalid controller - ids. -``NVME_SC_SELF_TEST_IN_PROGRESS`` - Device Self-test In Progress: +.. c:type:: enum nvme_resv_cptpl -``NVME_SC_BP_WRITE_PROHIBITED`` - Boot Partition Write Prohibited: The - command is trying to modify a locked Boot - Partition. -``NVME_SC_INVALID_CTRL_ID`` - Invalid Controller Identifier: +**Constants** -``NVME_SC_INVALID_SEC_CTRL_STATE`` - Invalid Secondary Controller State +``NVME_RESERVATION_CPTPL_NO_CHANGE`` -``NVME_SC_INVALID_CTRL_RESOURCES`` - Invalid Number of Controller Resources +``NVME_RESERVATION_CPTPL_CLEAR`` -``NVME_SC_INVALID_RESOURCE_ID`` - Invalid Resource Identifier +``NVME_RESERVATION_CPTPL_PERSIST`` -``NVME_SC_PMR_SAN_PROHIBITED`` - Sanitize Prohibited While Persistent - Memory Region is Enabled -``NVME_SC_ANA_GROUP_ID_INVALID`` - ANA Group Identifier Invalid -``NVME_SC_ANA_ATTACH_FAILED`` - ANA Attach Failed -``NVME_SC_BAD_ATTRIBUTES`` - Conflicting Dataset Management Attributes +.. c:type:: enum nvme_resv_rrela -``NVME_SC_INVALID_PI`` - Invalid Protection Information -``NVME_SC_READ_ONLY`` - Attempted Write to Read Only Range +**Constants** -``NVME_SC_CONNECT_FORMAT`` - Incompatible Format: The NVM subsystem - does not support the record format - specified by the host. +``NVME_RESERVATION_RRELA_RELEASE`` -``NVME_SC_CONNECT_CTRL_BUSY`` - Controller Busy: The controller is - already associated with a host. +``NVME_RESERVATION_RRELA_CLEAR`` -``NVME_SC_CONNECT_INVALID_PARAM`` - Connect Invalid Parameters: One or more - of the command parameters. -``NVME_SC_CONNECT_RESTART_DISC`` - Connect Restart Discovery: The NVM - 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 -``NVME_SC_DISCONNECT_INVALID_QTYPE`` - Invalid Queue Type: The command was sent - on the wrong queue type. +.. c:type:: enum nvme_zns_send_action -``NVME_SC_DISCOVERY_RESTART`` - Discover Restart: The snapshot of the - 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. +**Constants** -``NVME_SC_WRITE_FAULT`` - Write Fault: The write data could not be - committed to the media. +``NVME_ZNS_ZSA_CLOSE`` -``NVME_SC_READ_ERROR`` - Unrecovered Read Error: The read data - could not be recovered from the media. +``NVME_ZNS_ZSA_FINISH`` -``NVME_SC_GUARD_CHECK`` - End-to-end Guard Check Error: The command - was aborted due to an end-to-end guard - check failure. +``NVME_ZNS_ZSA_OPEN`` -``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. +``NVME_ZNS_ZSA_RESET`` -``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. +``NVME_ZNS_ZSA_OFFLINE`` -``NVME_SC_COMPARE_FAILED`` - Compare Failure: The command failed due - to a miscompare during a Compare command. +``NVME_ZNS_ZSA_SET_DESC_EXT`` -``NVME_SC_ACCESS_DENIED`` - Access Denied: Access to the namespace - and/or LBA range is denied due to lack of - access rights. +``NVME_ZNS_ZSA_ZRWA_FLUSH`` -``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. -``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. -``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. -``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. +.. c:type:: enum nvme_zns_recv_action -``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. -``NVME_SC_CTRL_PATH_ERROR`` - Controller Pathing Error: A pathing error - was detected by the controller. +**Constants** -``NVME_SC_HOST_PATH_ERROR`` - Host Pathing Error: A pathing error was - detected by the host. +``NVME_ZNS_ZRA_REPORT_ZONES`` -``NVME_SC_CMD_ABORTED_BY_HOST`` - Command Aborted By Host: The command was - aborted as a result of host action. +``NVME_ZNS_ZRA_EXTENDED_REPORT_ZONES`` -``NVME_SC_CRD`` - Mask to get value of Command Retry Delay - 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. -``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. +.. c:type:: enum nvme_zns_report_options -.. c:function:: __u16 nvme_status_code_type (__u16 status_field) - Returns the NVMe Status Code Type +**Constants** -**Parameters** +``NVME_ZNS_ZRAS_REPORT_ALL`` -``__u16 status_field`` - The NVMe Completion Queue Entry's Status Field +``NVME_ZNS_ZRAS_REPORT_EMPTY`` -**Description** +``NVME_ZNS_ZRAS_REPORT_IMPL_OPENED`` -See :c:type:`enum nvme_status_field ` +``NVME_ZNS_ZRAS_REPORT_EXPL_OPENED`` +``NVME_ZNS_ZRAS_REPORT_CLOSED`` -.. c:function:: __u16 nvme_status_code (__u16 status_field) +``NVME_ZNS_ZRAS_REPORT_FULL`` - Returns the NVMe Status Code +``NVME_ZNS_ZRAS_REPORT_READ_ONLY`` -**Parameters** +``NVME_ZNS_ZRAS_REPORT_OFFLINE`` -``__u16 status_field`` - The NVMe Completion Queue Entry's Status Field -**Description** -See :c:type:`enum nvme_status_field ` +.. c:type:: struct nvme_fabrics_config + + Defines all linux nvme fabrics initiator options -.. c:function:: __u8 nvme_status_to_errno (int status, bool fabrics) +**Definition** - Converts nvme return status to errno +:: -**Parameters** + struct nvme_fabrics_config { + char *host_traddr; + char *host_iface; + int queue_size; + int nr_io_queues; + int reconnect_delay; + int ctrl_loss_tmo; + int fast_io_fail_tmo; + int keep_alive_tmo; + int nr_write_queues; + int nr_poll_queues; + int tos; + bool duplicate_connect; + bool disable_sqflow; + bool hdr_digest; + bool data_digest; + bool tls; + }; -``int status`` - Return status from an nvme passthrough commmand +**Members** -``bool fabrics`` - Set to true if :c:type:`status` is to a fabrics target. +``host_traddr`` + Host transport address -**Return** +``host_iface`` + Host interface name -An errno representing the nvme status if it is an nvme status field, -or unchanged status is < 0 since errno is already set. +``queue_size`` + Number of IO queue entries +``nr_io_queues`` + Number of controller IO queues to establish -.. c:function:: int nvme_fw_download_seq (int fd, __u32 size, __u32 xfer, __u32 offset, void * buf) +``reconnect_delay`` + Time between two consecutive reconnect attempts. +``ctrl_loss_tmo`` + Override the default controller reconnect attempt timeout in seconds -**Parameters** +``fast_io_fail_tmo`` + Set the fast I/O fail timeout in seconds. -``int fd`` - File descriptor of nvme device +``keep_alive_tmo`` + Override the default keep-alive-timeout to this value in seconds -``__u32 size`` - Total size of the firmware image to transfer +``nr_write_queues`` + Number of queues to use for exclusively for writing -``__u32 xfer`` - Maximum size to send with each partial transfer +``nr_poll_queues`` + Number of queues to reserve for polling completions -``__u32 offset`` - Starting offset to send with this firmware downlaod +``tos`` + Type of service -``void * buf`` - Address of buffer containing all or part of the firmware image. +``duplicate_connect`` + Allow multiple connections to the same target -**Return** +``disable_sqflow`` + Disable controller sq flow control -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. +``hdr_digest`` + Generate/verify header digest (TCP) +``data_digest`` + Generate/verify data digest (TCP) -.. c:function:: int nvme_get_ctrl_telemetry (int fd, bool rae, struct nvme_telemetry_log ** log) +``tls`` + Start TLS on the connection (TCP) -**Parameters** -``int fd`` - File descriptor of nvme device +.. c:function:: const char * nvmf_trtype_str (__u8 trtype) -``bool rae`` - Retain asynchronous events + Decode TRTYPE field -``struct nvme_telemetry_log ** log`` - On success, set to the value of the allocated and retreived log. +**Parameters** + +``__u8 trtype`` + value to be decoded **Description** -The total size allocated can be calculated as: - (:c:type:`struct nvme_telemetry_log `.dalb3 + 1) * ``NVME_LOG_TELEM_BLOCK_SIZE``. +Decode the transport type field in the discovery +log page entry. **Return** -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. +decoded string -.. c:function:: int nvme_get_host_telemetry (int fd, struct nvme_telemetry_log ** log) +.. c:function:: const char * nvmf_adrfam_str (__u8 adrfam) + Decode ADRFAM field **Parameters** -``int fd`` - File descriptor of nvme device - -``struct nvme_telemetry_log ** log`` - On success, set to the value of the allocated and retreived log. +``__u8 adrfam`` + value to be decoded **Description** -The total size allocated can be calculated as: - (:c:type:`struct nvme_telemetry_log `.dalb3 + 1) * ``NVME_LOG_TELEM_BLOCK_SIZE``. +Decode the address family field in the discovery +log page entry. **Return** -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. +decoded string -.. c:function:: int nvme_get_new_host_telemetry (int fd, struct nvme_telemetry_log ** log) +.. c:function:: const char * nvmf_subtype_str (__u8 subtype) + Decode SUBTYPE field **Parameters** -``int fd`` - File descriptor of nvme device - -``struct nvme_telemetry_log ** log`` - On success, set to the value of the allocated and retreived log. +``__u8 subtype`` + value to be decoded **Description** -The total size allocated can be calculated as: - (:c:type:`struct nvme_telemetry_log `.dalb3 + 1) * ``NVME_LOG_TELEM_BLOCK_SIZE``. +Decode the subsystem type field in the discovery +log page entry. **Return** -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. +decoded string -.. c:function:: void nvme_init_id_ns (struct nvme_id_ns * ns, __u64 nsze, __u64 ncap, __u8 flbas, __u8 dps, __u8 nmic, __u32 anagrpid, __u16 nvmsetid) +.. c:function:: const char * nvmf_treq_str (__u8 treq) - Initialize an Identify Namepsace structure for creation. + Decode TREQ field **Parameters** -``struct nvme_id_ns * ns`` - Address of the Identify Namespace structure to initialize +``__u8 treq`` + value to be decoded -``__u64 nsze`` - Namespace size +**Description** -``__u64 ncap`` - namespace capacity +Decode the transport requirements field in the +discovery log page entry. -``__u8 flbas`` - formatted logical block size settings +**Return** -``__u8 dps`` - Data protection settings +decoded string -``__u8 nmic`` - Namespace sharing capabilities -``__u32 anagrpid`` - ANA group identifier +.. c:function:: const char * nvmf_eflags_str (__u16 eflags) -``__u16 nvmsetid`` - NVM Set identifer + Decode EFLAGS field -**Description** +**Parameters** -This is intended to be used with a namespace management "create", see -:c:type:`nvme_ns_mgmt_create`(). +``__u16 eflags`` + value to be decoded +**Description** -.. c:function:: void nvme_init_ctrl_list (struct nvme_ctrl_list * cntlist, __u16 num_ctrls, __u16 * ctrlist) +Decode the EFLAGS field in the discovery log page +entry. - Initialize an nvme_ctrl_list structure from an array. +**Return** -**Parameters** +decoded string -``struct nvme_ctrl_list * cntlist`` - The controller list structure to initialize -``__u16 num_ctrls`` - The number of controllers in the array, :c:type:`ctrlist`. +.. c:function:: const char * nvmf_sectype_str (__u8 sectype) -``__u16 * ctrlist`` - An array of controller identifiers in CPU native endian. + Decode SECTYPE field -**Description** +**Parameters** -This is intended to be used with any command that takes a controller list -argument. See :c:type:`nvme_ns_attach_ctrls`() and :c:type:`nvme_ns_detach`(). +``__u8 sectype`` + value to be decoded +**Description** -.. c:function:: void nvme_init_dsm_range (struct nvme_dsm_range * dsm, __u32 * ctx_attrs, __u32 * llbas, __u64 * slbas, __u16 nr_ranges) +Decode the SECTYPE field in the discovery log page +entry. - Constructs a data set range structure +**Return** -**Parameters** +decoded string -``struct nvme_dsm_range * dsm`` - DSM range array -``__u32 * ctx_attrs`` - Array of context attributes +.. c:function:: const char * nvmf_prtype_str (__u8 prtype) -``__u32 * llbas`` - Array of length in logical blocks + Decode RDMA Provider type field -``__u64 * slbas`` - Array of starting logical blocks +**Parameters** -``__u16 nr_ranges`` - The size of the dsm arrays +``__u8 prtype`` + value to be decoded **Description** -Each array must be the same size of size 'nr_ranges'. This is intended to be -used with constructing a payload for :c:type:`nvme_dsm`(). +Decode the RDMA Provider type field in the discovery +log page entry. **Return** -The nvme command status if a response was received or -errno -otherwise. +decoded string -.. c:function:: int __nvme_get_log_page (int fd, __u32 nsid, __u8 log_id, bool rae, __u32 xfer_len, __u32 data_len, void * data) +.. c:function:: const char * nvmf_qptype_str (__u8 qptype) + Decode RDMA QP Service type field **Parameters** -``int fd`` - File descriptor of nvme device +``__u8 qptype`` + value to be decoded -``__u32 nsid`` - Namespace Identifier, if applicable. +**Description** -``__u8 log_id`` - Log Identifier, see :c:type:`enum nvme_cmd_get_log_lid `. +Decode the RDMA QP Service type field in the discovery log page +entry. -``bool rae`` - Retain asynchronous events +**Return** -``__u32 xfer_len`` - Max log transfer size per request to split the total. +decoded string -``__u32 data_len`` - Total length of the log to transfer. -``void * data`` - User address of at least :c:type:`data_len` to store the log. +.. c:function:: const char * nvmf_cms_str (__u8 cms) + + Decode RDMA connection management service field + +**Parameters** + +``__u8 cms`` + value to be decoded + +**Description** + +Decode the RDMA connection management service field in the discovery +log page entry. **Return** -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. +decoded string -.. c:function:: int nvme_get_log_page (int fd, __u32 nsid, __u8 log_id, bool rae, __u32 data_len, void * data) +.. c:function:: void nvmf_default_config (struct nvme_fabrics_config *cfg) + Default values for fabrics configuration **Parameters** -``int fd`` - File descriptor of nvme device +``struct nvme_fabrics_config *cfg`` + config values to set -``__u32 nsid`` - Namespace Identifier, if applicable. +**Description** -``__u8 log_id`` - Log Identifier, see :c:type:`enum nvme_cmd_get_log_lid `. +Initializes **cfg** with default values. -``bool rae`` - Retain asynchronous events -``__u32 data_len`` - Total length of the log to transfer. +.. c:function:: int nvmf_add_ctrl (nvme_host_t h, nvme_ctrl_t c, const struct nvme_fabrics_config *cfg) -``void * data`` - User address of at least :c:type:`data_len` to store the log. + Connect a controller and update topology + +**Parameters** + +``nvme_host_t h`` + Host to which the controller should be attached + +``nvme_ctrl_t c`` + Controller to be connected + +``const struct nvme_fabrics_config *cfg`` + Default configuration for the controller **Description** -Calls __nvme_get_log_page() with a default 4k transfer length, as that is -guarnateed by the protocol to be a safe transfer size. +Issues a 'connect' command to the NVMe-oF controller and inserts **c** +into the topology using **h** as parent. +**c** must be initialized and not connected to the topology. **Return** -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. +0 on success; on failure errno is set and -1 is returned. -.. c:function:: int nvme_get_ana_log_len (int fd, size_t * analen) +.. c:function:: int nvmf_get_discovery_log (nvme_ctrl_t c, struct nvmf_discovery_log **logp, int max_retries) - Retreive size of the current ANA log + Return the discovery log page **Parameters** -``int fd`` - File descriptor of nvme device +``nvme_ctrl_t c`` + Discover controller to use -``size_t * analen`` - Pointer to where the length will be set on success +``struct nvmf_discovery_log **logp`` + Pointer to the log page to be returned + +``int max_retries`` + maximum number of log page entries to be returned **Return** -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. +0 on success; on failure -1 is returned and errno is set -.. c:function:: int nvme_namespace_attach_ctrls (int fd, __u32 nsid, __u16 num_ctrls, __u16 * ctrlist) +.. c:function:: char * nvmf_hostnqn_generate () - Attach namespace to controller(s) + Generate a machine specific host nqn **Parameters** -``int fd`` - File descriptor of nvme device +**Return** -``__u32 nsid`` - Namespace ID to attach +An nvm namespace qualified name string based on the machine +identifier, or NULL if not successful. -``__u16 num_ctrls`` - Number of controllers in ctrlist -``__u16 * ctrlist`` - List of controller IDs to perform the attach action +.. c:function:: char * nvmf_hostnqn_from_file () + + Reads the host nvm qualified name from the config default location in /etc/nvme/ + +**Parameters** **Return** -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. +The host nqn, or NULL if unsuccessful. If found, the caller +is responsible to free the string. -.. c:function:: int nvme_namespace_detach_ctrls (int fd, __u32 nsid, __u16 num_ctrls, __u16 * ctrlist) +.. c:function:: char * nvmf_hostid_from_file () - Detach namespace from controller(s) + Reads the host identifier from the config default location in /etc/nvme/. **Parameters** -``int fd`` - File descriptor of nvme device +**Return** -``__u32 nsid`` - Namespace ID to detach +The host identifier, or NULL if unsuccessful. If found, the caller + is responsible to free the string. -``__u16 num_ctrls`` - Number of controllers in ctrlist -``__u16 * ctrlist`` - List of controller IDs to perform the detach action +.. c:function:: nvme_ctrl_t nvmf_connect_disc_entry (nvme_host_t h, struct nvmf_disc_log_entry *e, const struct nvme_fabrics_config *defcfg, bool *discover) + + Connect controller based on the discovery log page entry + +**Parameters** + +``nvme_host_t h`` + Host to which the controller should be connected + +``struct nvmf_disc_log_entry *e`` + Discovery log page entry + +``const struct nvme_fabrics_config *defcfg`` + Default configurationn to be used for the new controller + +``bool *discover`` + Set to 'true' if the new controller is a discovery controller **Return** -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. +Pointer to the new controller -.. c:function:: int nvme_get_feature_length (int fid, __u32 cdw11, __u32 * len) +.. c:function:: void nvme_chomp (char *s, int l) - Retreive the command payload length for a specific feature identifier + Strip trailing white space **Parameters** -``int fid`` - Feature identifier, see :c:type:`enum nvme_features_id `. +``char *s`` + String to strip -``__u32 cdw11`` - The cdw11 value may affect the transfer (only known fid is - ``NVME_FEAT_FID_HOST_ID``) +``int l`` + Maximum length of string -``__u32 * 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 -recognize :c:type:`fid`. +.. c:type:: enum nvme_connect_err -.. c:function:: int nvme_get_directive_receive_length (enum nvme_directive_dtype dtype, enum nvme_directive_receive_doper doper, __u32 * len) + nvme connect error codes +**Constants** -**Parameters** +``ENVME_CONNECT_RESOLVE`` + failed to resolve host -``enum nvme_directive_dtype dtype`` - Directive type, see :c:type:`enum nvme_directive_dtype ` +``ENVME_CONNECT_ADDRFAM`` + unrecognized address family -``enum nvme_directive_receive_doper doper`` - Directive receive operation, see :c:type:`enum nvme_directive_receive_doper ` +``ENVME_CONNECT_TRADDR`` + failed to get traddr -``__u32 * len`` - On success, set to this directives payload length in bytes. +``ENVME_CONNECT_TARG`` + need a transport (-t) argument -**Return** +``ENVME_CONNECT_AARG`` + need a address (-a) argument -0 on success, -1 with errno set to EINVAL if the function did not -recognize :c:type:`dtype` or :c:type:`doper`. +``ENVME_CONNECT_OPEN`` + failed to open nvme-fabrics device +``ENVME_CONNECT_WRITE`` + failed to write to nvme-fabrics device -.. c:function:: int nvme_open (const char * name) +``ENVME_CONNECT_READ`` + failed to read from nvme-fabrics device - Open an nvme controller or namespace device +``ENVME_CONNECT_PARSE`` + failed to parse ctrl info -**Parameters** +``ENVME_CONNECT_INVAL_TR`` + invalid transport type -``const char * name`` - The basename of the device to open +``ENVME_CONNECT_LOOKUP_SUBSYS_NAME`` + failed to lookup subsystem name -**Description** +``ENVME_CONNECT_LOOKUP_SUBSYS`` + failed to lookup subsystem -This will look for the handle in /dev/ and validate the name and filetype -match linux conventions. -**Return** +.. c:function:: __u8 nvme_status_to_errno (int status, bool fabrics) -A file descriptor for the device on a successful open, or -1 with -errno set otherwise. + Converts nvme return status to errno +**Parameters** +``int status`` + Return status from an nvme passthrough commmand +``bool fabrics`` + Set to true if :c:type:`status` is to a fabrics target. -.. c:type:: struct nvme_fabrics_config +**Return** - Defines all linux nvme fabrics initiator options +An errno representing the nvme status if it is an nvme status field, +or unchanged status is < 0 since errno is already set. -**Definition** -:: +.. c:function:: const char * nvme_status_to_string (int status, bool fabrics) - struct nvme_fabrics_config { - const char *transport; - const char *traddr; - const char *trsvcid; - const char *nqn; - const char *hostnqn; - const char *host_traddr; - const char *hostid; - int queue_size; - int nr_io_queues; - int reconnect_delay; - int ctrl_loss_tmo; - int keep_alive_tmo; - int nr_write_queues; - int nr_poll_queues; - int tos; - bool duplicate_connect; - bool disable_sqflow; - bool hdr_digest; - bool data_digest; - }; + Returns string describing nvme return status. -**Members** +**Parameters** -``transport`` - The fabric transport to use, either loop, fc, tcp, or rdma +``int status`` + Return status from an nvme passthrough commmand -``traddr`` - Transport Address for the target, format specific to transport type +``bool fabrics`` + Set to true if :c:type:`status` is to a fabrics target. -``trsvcid`` - Transport Service Identifier, specific to the transport type +**Return** -``nqn`` - Target NVMe Qualified Name +String representation of the nvme status if it is an nvme status field, +or a standard errno string if status is < 0. -``hostnqn`` - Host NVMe Qualified Name -``host_traddr`` - Host Transport Address +.. c:function:: const char * nvme_errno_to_string (int err) -``hostid`` - Host Identifier + Returns string describing nvme connect failures -``queue_size`` - Number of IO queue entries +**Parameters** -``nr_io_queues`` - Number of controller IO queues to establish +``int err`` + Returned error code from nvme_add_ctrl() -``reconnect_delay`` - Time between two consecutive reconnect attempts. +**Return** -``ctrl_loss_tmo`` - Override the default controller reconnect attempt timeout in seconds +String representation of the nvme connect error codes -``keep_alive_tmo`` - Override the default keep-alive-timeout to this value in seconds -``nr_write_queues`` - Number of queues to use for exclusively for writing +.. c:function:: void nvme_init_id_ns (struct nvme_id_ns *ns, __u64 nsze, __u64 ncap, __u8 flbas, __u8 dps, __u8 nmic, __u32 anagrpid, __u16 nvmsetid) -``nr_poll_queues`` - Number of queues to reserve for polling completions + Initialize an Identify Namepsace structure for creation. -``tos`` - Type of service +**Parameters** -``duplicate_connect`` - Allow multiple connections to the same target +``struct nvme_id_ns *ns`` + Address of the Identify Namespace structure to initialize -``disable_sqflow`` - Disable controller sq flow control +``__u64 nsze`` + Namespace size -``hdr_digest`` - Generate/verify header digest (TCP) +``__u64 ncap`` + namespace capacity -``data_digest`` - Generate/verify data digest (TCP) +``__u8 flbas`` + formatted logical block size settings +``__u8 dps`` + Data protection settings +``__u8 nmic`` + Namespace sharing capabilities -.. c:function:: int nvmf_add_ctrl_opts (struct nvme_fabrics_config * cfg) +``__u32 anagrpid`` + ANA group identifier +``__u16 nvmsetid`` + NVM Set identifer -**Parameters** +**Description** -``struct nvme_fabrics_config * cfg`` +This is intended to be used with a namespace management "create", see +nvme_ns_mgmt_create(). -.. c:function:: nvme_ctrl_t nvmf_add_ctrl (struct nvme_fabrics_config * cfg) +.. c:function:: void nvme_init_ctrl_list (struct nvme_ctrl_list *cntlist, __u16 num_ctrls, __u16 *ctrlist) + Initialize an nvme_ctrl_list structure from an array. **Parameters** -``struct nvme_fabrics_config * cfg`` +``struct nvme_ctrl_list *cntlist`` + The controller list structure to initialize + +``__u16 num_ctrls`` + The number of controllers in the array, :c:type:`ctrlist`. + +``__u16 *ctrlist`` + An array of controller identifiers in CPU native endian. + +**Description** + +This is intended to be used with any command that takes a controller list +argument. See nvme_ns_attach_ctrls() and nvme_ns_detach(). -.. c:function:: int nvmf_get_discovery_log (nvme_ctrl_t c, struct nvmf_discovery_log ** logp, int max_retries) +.. c:function:: void nvme_init_dsm_range (struct nvme_dsm_range *dsm, __u32 *ctx_attrs, __u32 *llbas, __u64 *slbas, __u16 nr_ranges) + Constructs a data set range structure **Parameters** -``nvme_ctrl_t c`` - *undescribed* +``struct nvme_dsm_range *dsm`` + DSM range array -``struct nvmf_discovery_log ** logp`` - *undescribed* +``__u32 *ctx_attrs`` + Array of context attributes -``int max_retries`` +``__u32 *llbas`` + Array of length in logical blocks +``__u64 *slbas`` + Array of starting logical blocks -.. c:function:: char * nvmf_hostnqn_generate () +``__u16 nr_ranges`` + The size of the dsm arrays - Generate a machine specific host nqn +**Description** -**Parameters** +Each array must be the same size of size 'nr_ranges'. This is intended to be +used with constructing a payload for nvme_dsm(). **Return** -An nvm namespace qualifieid name string based on the machine -identifier, or NULL if not successful. +The nvme command status if a response was received or -errno +otherwise. -.. c:function:: char * nvmf_hostnqn_from_file () +.. c:function:: void nvme_init_copy_range (struct nvme_copy_range *copy, __u16 *nlbs, __u64 *slbas, __u32 *eilbrts, __u32 *elbatms, __u32 *elbats, __u16 nr) - Reads the host nvm qualified name from the config default location in /etc/nvme/ + Constructs a copy range structure **Parameters** -**Return** +``struct nvme_copy_range *copy`` + Copy range array -The host nqn, or NULL if unsuccessful. If found, the caller -is responsible to free the string. +``__u16 *nlbs`` + Number of logical blocks +``__u64 *slbas`` + Starting LBA -.. c:function:: char * nvmf_hostid_from_file () +``__u32 *eilbrts`` + Expected initial logical block reference tag - Reads the host identifier from the config default location in /etc/nvme/. +``__u32 *elbatms`` + Expected logical block application tag mask + +``__u32 *elbats`` + Expected logical block application tag + +``__u16 nr`` + Number of descriptors to construct + + +.. c:function:: int nvme_get_feature_length (int fid, __u32 cdw11, __u32 *len) + + Retreive the command payload length for a specific feature identifier **Parameters** +``int fid`` + Feature identifier, see :c:type:`enum nvme_features_id `. + +``__u32 cdw11`` + The cdw11 value may affect the transfer (only known fid is + ``NVME_FEAT_FID_HOST_ID``) + +``__u32 *len`` + On success, set to this features payload length in bytes. + **Return** -The host identifier, or NULL if unsuccessful. If found, the caller - is responsible to free the string. +0 on success, -1 with errno set to EINVAL if the function did not +recognize :c:type:`fid`. -.. c:function:: nvme_ctrl_t nvmf_connect_disc_entry (struct nvmf_disc_log_entry * e, const struct nvme_fabrics_config * defcfg, bool * discover) +.. c:function:: int nvme_get_directive_receive_length (enum nvme_directive_dtype dtype, enum nvme_directive_receive_doper doper, __u32 *len) **Parameters** -``struct nvmf_disc_log_entry * e`` - *undescribed* +``enum nvme_directive_dtype dtype`` + Directive type, see :c:type:`enum nvme_directive_dtype ` -``const struct nvme_fabrics_config * defcfg`` - *undescribed* +``enum nvme_directive_receive_doper doper`` + Directive receive operation, see :c:type:`enum nvme_directive_receive_doper ` -``bool * discover`` +``__u32 *len`` + On success, set to this directives payload length in bytes. **Return** -An +0 on success, -1 with errno set to EINVAL if the function did not +recognize :c:type:`dtype` or :c:type:`doper`. From 7cfbc01916487f5ac55097c895cc9b0db59ee387 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 2 Feb 2022 13:00:08 +0100 Subject: [PATCH 0428/1564] Add documentation section descriptions Add DOC: statements to the header files to have each header file start its own section in the API documentation. Signed-off-by: Hannes Reinecke --- doc/index.rst | 2 ++ doc/libnvme.rst | 56 ++++++++++++++++++++++++++++++++++++++++++++++ src/nvme/fabrics.h | 6 +++++ src/nvme/filters.h | 6 +++++ src/nvme/ioctl.h | 6 +++++ src/nvme/linux.h | 6 +++++ src/nvme/log.h | 6 +++++ src/nvme/tree.h | 6 +++++ src/nvme/types.h | 6 +++++ src/nvme/util.h | 6 +++++ 10 files changed, 106 insertions(+) diff --git a/doc/index.rst b/doc/index.rst index f435859465..716808a9f0 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -10,6 +10,8 @@ Welcome to libnvme's documentation! :maxdepth: 2 :caption: Contents: + index + libnvme Indices and tables diff --git a/doc/libnvme.rst b/doc/libnvme.rst index 975f0d8e26..05f87bae78 100644 --- a/doc/libnvme.rst +++ b/doc/libnvme.rst @@ -1,3 +1,10 @@ +.. _filters.h: + +**filters.h** + + +libnvme directory filter + .. c:function:: int nvme_namespace_filter (const struct dirent *d) @@ -76,6 +83,13 @@ ``struct dirent ***namespaces`` +.. _ioctl.h: + +**ioctl.h** + + +Linux NVMe ioctl interface functions + .. c:type:: struct nvme_passthru_cmd @@ -6105,6 +6119,13 @@ The nvme command status if a response was received (see :c:type:`enum nvme_status_field `) or -1 with errno set otherwise. +.. _linux.h: + +**linux.h** + + +linux-specific utility functions + .. c:function:: int nvme_fw_download_seq (int fd, __u32 size, __u32 xfer, __u32 offset, void *buf) @@ -6437,6 +6458,13 @@ If key generation was successful the function returns 0 or -1 with errno set otherwise. +.. _log.h: + +**log.h** + + +logging functions + .. c:function:: void nvme_init_logging (nvme_root_t r, int lvl, bool log_pid, bool log_tstamp) initialize logging @@ -6460,6 +6488,13 @@ If key generation was successful the function returns 0 or Sets the default logging variables for the library. +.. _tree.h: + +**tree.h** + + +libnvme tree object interface + .. c:function:: nvme_root_t nvme_create_root (FILE *fp, int log_level) Initialize root object @@ -8424,6 +8459,13 @@ string with the contents of **attr** nvme_ns_t object or NULL if not found. +.. _types.h: + +**types.h** + + +NVMe standard definitions + .. c:function:: NVME_GET (value, name) extract field from complex value @@ -17488,6 +17530,13 @@ See :c:type:`enum nvme_status_field ` ``NVME_ZNS_ZRAS_REPORT_OFFLINE`` +.. _fabrics.h: + +**fabrics.h** + + +Fabrics-specific definitions. + .. c:type:: struct nvme_fabrics_config @@ -17872,6 +17921,13 @@ Pointer to the new controller Maximum length of string +.. _util.h: + +**util.h** + + +libnvme utility functions + .. c:type:: enum nvme_connect_err diff --git a/src/nvme/fabrics.h b/src/nvme/fabrics.h index d47277dc0c..183fd4e724 100644 --- a/src/nvme/fabrics.h +++ b/src/nvme/fabrics.h @@ -13,6 +13,12 @@ #include #include "tree.h" +/** + * DOC: fabrics.h + * + * Fabrics-specific definitions. + */ + /* default to 600 seconds of reconnect attempts before giving up */ #define NVMF_DEF_CTRL_LOSS_TMO 600 diff --git a/src/nvme/filters.h b/src/nvme/filters.h index cf10cdb86d..9156d5a900 100644 --- a/src/nvme/filters.h +++ b/src/nvme/filters.h @@ -12,6 +12,12 @@ #include #include "tree.h" +/** + * DOC: filters.h + * + * libnvme directory filter + */ + /** * nvme_namespace_filter() - * @d: diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 02768097fc..c015938779 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -24,6 +24,12 @@ #ifndef _LINUX_NVME_IOCTL_H #define _LINUX_NVME_IOCTL_H +/** + * DOC: ioctl.h + * + * Linux NVMe ioctl interface functions + */ + /* '0' is interpreted by the kernel to mean 'apply the default timeout' */ #define NVME_DEFAULT_IOCTL_TIMEOUT 0 diff --git a/src/nvme/linux.h b/src/nvme/linux.h index 83820c410b..11c970105a 100644 --- a/src/nvme/linux.h +++ b/src/nvme/linux.h @@ -13,6 +13,12 @@ #include "types.h" +/** + * DOC: linux.h + * + * linux-specific utility functions + */ + /** * nvme_fw_download_seq() - * @fd: File descriptor of nvme device diff --git a/src/nvme/log.h b/src/nvme/log.h index eea652d687..a2e5edf6c8 100644 --- a/src/nvme/log.h +++ b/src/nvme/log.h @@ -15,6 +15,12 @@ # define DEFAULT_LOGLEVEL LOG_NOTICE #endif +/** + * DOC: log.h + * + * logging functions + */ + /** * nvme_init_logging() - initialize logging * @r: nvme_root_t context diff --git a/src/nvme/tree.h b/src/nvme/tree.h index 70643c4bfb..da0da7b6fe 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -21,6 +21,12 @@ #include "ioctl.h" #include "util.h" +/** + * DOC: tree.h + * + * libnvme tree object interface + */ + typedef struct nvme_ns *nvme_ns_t; typedef struct nvme_path *nvme_path_t; typedef struct nvme_ctrl *nvme_ctrl_t; diff --git a/src/nvme/types.h b/src/nvme/types.h index 4542a09a58..b0bce17b7e 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -15,6 +15,12 @@ #include +/** + * DOC: types.h + * + * NVMe standard definitions + */ + /** * NVME_GET() - extract field from complex value * @value: The original value of a complex field diff --git a/src/nvme/util.h b/src/nvme/util.h index 1308031716..413413bdc2 100644 --- a/src/nvme/util.h +++ b/src/nvme/util.h @@ -11,6 +11,12 @@ #include "types.h" +/** + * DOC: util.h + * + * libnvme utility functions + */ + /** * enum nvme_connect_err - nvme connect error codes * @ENVME_CONNECT_RESOLVE: failed to resolve host From abbee81b75835e1a322c6d48c227694b5c9feee8 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 2 Feb 2022 13:17:00 +0100 Subject: [PATCH 0429/1564] Fixup wrong kernel-doc annotations Some function descriptions weren't properly specified. Signed-off-by: Hannes Reinecke --- src/nvme/fabrics.h | 2 +- src/nvme/tree.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nvme/fabrics.h b/src/nvme/fabrics.h index 183fd4e724..7926707dbd 100644 --- a/src/nvme/fabrics.h +++ b/src/nvme/fabrics.h @@ -161,7 +161,7 @@ const char *nvmf_qptype_str(__u8 qptype); const char *nvmf_cms_str(__u8 cms); /** - * nvmf_default_config - Default values for fabrics configuration + * nvmf_default_config() - Default values for fabrics configuration * @cfg: config values to set * * Initializes @cfg with default values. diff --git a/src/nvme/tree.h b/src/nvme/tree.h index da0da7b6fe..ce164d28bd 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -1146,7 +1146,7 @@ char *nvme_get_ctrl_attr(nvme_ctrl_t c, const char *attr); char *nvme_get_ns_attr(nvme_ns_t n, const char *attr); /** - * nvme_subsystem_lookup_namespace - lookup namespace by NSID + * nvme_subsystem_lookup_namespace() - lookup namespace by NSID * @s: nvme_subsystem_t object * @nsid: namespace id * From b6cd4cbf1180f2153f65eae9cbf3edbc4ddcb111 Mon Sep 17 00:00:00 2001 From: Martin Belanger Date: Wed, 2 Feb 2022 09:41:02 -0500 Subject: [PATCH 0430/1564] fix license info Signed-off-by: Martin Belanger --- doc/meson.build | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/meson.build b/doc/meson.build index d4bbf56645..1bb3444fdc 100644 --- a/doc/meson.build +++ b/doc/meson.build @@ -1,7 +1,7 @@ -# SPDX-License-Identifier: BSD-3 +# SPDX-License-Identifier: LGPL-2.1-or-later # -# This file is part of STorage Appliance Services (STAS). -# Copyright (c) 2021 Dell Inc. +# This file is part of libnvme. +# Copyright (c) 2022 Dell Inc. # # Authors: Martin Belanger # From 135f2769ff16504290dfcf7fe67c9b598301576e Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 3 Feb 2022 08:45:51 +0100 Subject: [PATCH 0431/1564] tree: fixup memory leak in nvme_scan_ctrl() 'subsysname' was never freed. Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 8d67ec014f..a817823d73 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -1287,7 +1287,10 @@ nvme_ctrl_t nvme_scan_ctrl(nvme_root_t r, const char *name) return NULL; } subsysname = nvme_ctrl_lookup_subsystem_name(r, name); + /* subsysname might be NULL here */ s = nvme_lookup_subsystem(h, subsysname, subsysnqn); + if (subsysname) + free(subsysname); free(subsysnqn); if (!s) { free(path); From 2f59761436c6169fe04a10f41ffdc4bfebe8db3f Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 3 Feb 2022 09:46:33 +0100 Subject: [PATCH 0432/1564] tree: restart controller lookup nvme_lookup_ctrl() might match more than one controller (eg for loop devices), in which case the iterator will only ever find the first one. So add a parameter 'p' to nvme_lookup_ctrl() to re-start the iteration at a given point instead of just the first one. Signed-off-by: Hannes Reinecke --- src/nvme/json.c | 22 +++++++++++++--------- src/nvme/tree.c | 41 +++++++++++++++++++++++++++++++++-------- src/nvme/tree.h | 7 +++++-- 3 files changed, 51 insertions(+), 19 deletions(-) diff --git a/src/nvme/json.c b/src/nvme/json.c index ebc1ae4f99..f34cb86573 100644 --- a/src/nvme/json.c +++ b/src/nvme/json.c @@ -76,7 +76,7 @@ static void json_update_attributes(nvme_ctrl_t c, static void json_parse_port(nvme_subsystem_t s, struct json_object *port_obj) { - nvme_ctrl_t c; + nvme_ctrl_t c, p; struct json_object *attr_obj; const char *transport, *traddr = NULL; const char *host_traddr = NULL, *host_iface = NULL, *trsvcid = NULL; @@ -97,14 +97,18 @@ static void json_parse_port(nvme_subsystem_t s, struct json_object *port_obj) attr_obj = json_object_object_get(port_obj, "trsvcid"); if (attr_obj) trsvcid = json_object_get_string(attr_obj); - c = nvme_lookup_ctrl(s, transport, traddr, host_traddr, - host_iface, trsvcid); - if (c) { - attr_obj = json_object_object_get(port_obj, "dhchap_key"); - if (attr_obj) - nvme_ctrl_set_dhchap_key(c, json_object_get_string(attr_obj)); - json_update_attributes(c, port_obj); - } + p = NULL; + do { + c = nvme_lookup_ctrl(s, transport, traddr, host_traddr, + host_iface, trsvcid, p); + if (c) { + attr_obj = json_object_object_get(port_obj, "dhchap_key"); + if (attr_obj) + nvme_ctrl_set_dhchap_key(c, json_object_get_string(attr_obj)); + json_update_attributes(c, port_obj); + } + p = c; + } while (c); } static void json_parse_subsys(nvme_host_t h, struct json_object *subsys_obj) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index a817823d73..9f22b1550d 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -977,16 +977,18 @@ struct nvme_ctrl *nvme_create_ctrl(nvme_root_t r, return c; } -struct nvme_ctrl *nvme_lookup_ctrl(struct nvme_subsystem *s, const char *transport, - const char *traddr, const char *host_traddr, - const char *host_iface, const char *trsvcid) +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 = s->h ? s->h->r : NULL; struct nvme_ctrl *c; if (!s || !transport) return NULL; - nvme_subsystem_for_each_ctrl(s, c) { + 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)) continue; if (traddr && c->traddr && @@ -1166,7 +1168,7 @@ int nvme_init_ctrl(nvme_host_t h, nvme_ctrl_t c, int instance) static nvme_ctrl_t nvme_ctrl_alloc(nvme_root_t r, nvme_subsystem_t s, const char *path, const char *name) { - nvme_ctrl_t c; + nvme_ctrl_t c, p; char *addr = NULL, *address = NULL, *a, *e; char *transport, *traddr = NULL, *trsvcid = NULL; char *host_traddr = NULL, *host_iface = NULL; @@ -1228,13 +1230,36 @@ static nvme_ctrl_t nvme_ctrl_alloc(nvme_root_t r, nvme_subsystem_t s, } } skip_address: - c = nvme_lookup_ctrl(s, transport, traddr, - host_traddr, host_iface, trsvcid); + p = NULL; + do { + c = nvme_lookup_ctrl(s, transport, traddr, + host_traddr, host_iface, trsvcid, p); + if (c) { + if (!c->name) + break; + if (!strcmp(c->name, name)) { + nvme_msg(r, LOG_DEBUG, + "%s: found existing ctrl %s\n", + __func__, c->name); + break; + } + nvme_msg(r, LOG_DEBUG, "%s: skipping ctrl %s\n", + __func__, c->name); + p = c; + } + } while (c); + if (!c) + c = p; free(transport); if (address) free(address); if (!c) { - errno = ENOMEM; + if (!p) { + nvme_msg(r, LOG_ERR, "%s: failed to lookup ctrl\n", + __func__); + errno = ENODEV; + } else + errno = ENOMEM; return NULL; } c->address = addr; diff --git a/src/nvme/tree.h b/src/nvme/tree.h index 70643c4bfb..585ed941e3 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -235,17 +235,20 @@ nvme_ctrl_t nvme_subsystem_next_ctrl(nvme_subsystem_t s, nvme_ctrl_t c); * @host_traddr: host transport address * @host_iface: host interface name * @trsvcid: transport service identifier + * @p: previous nvme_ctrl_t object * * Lookup a nvme_ctrl_t object in @s based on @transport, @traddr, * @host_traddr, @host_iface, and @trsvcid. @transport must be specified, * other fields may be required depending on the transport. A new - * object is created if none is found. + * object is created if none is found. If @p is specified the lookup + * will start at @p instead of the first controller. * * Return: nvme_ctrl_t object */ 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); + const char *host_iface, const char *trsvcid, + nvme_ctrl_t p); /** From aff82d90595d8cf5175ff69b3691592384efcd57 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 2 Feb 2022 13:18:27 +0100 Subject: [PATCH 0433/1564] Add scripts to regenerate documentation Import the 'kernel-doc' script from the linux kernel sources and add scripts to regenerate libnvme.rst and man-pages. Signed-off-by: Hannes Reinecke [dwagner: moved scripts from internal to doc] Signed-off-by: Daniel Wagner --- doc/kernel-doc | 2523 ++++++++++++++++++++++++++++++++++++++++++++++ doc/regen-man.sh | 19 + doc/regen-rst.sh | 9 + 3 files changed, 2551 insertions(+) create mode 100755 doc/kernel-doc create mode 100755 doc/regen-man.sh create mode 100755 doc/regen-rst.sh diff --git a/doc/kernel-doc b/doc/kernel-doc new file mode 100755 index 0000000000..4900c3ade7 --- /dev/null +++ b/doc/kernel-doc @@ -0,0 +1,2523 @@ +#!/usr/bin/env perl +# SPDX-License-Identifier: GPL-2.0 + +use warnings; +use strict; + +## Copyright (c) 1998 Michael Zucchi, All Rights Reserved ## +## Copyright (C) 2000, 1 Tim Waugh ## +## Copyright (C) 2001 Simon Huggins ## +## Copyright (C) 2005-2012 Randy Dunlap ## +## Copyright (C) 2012 Dan Luedtke ## +## ## +## #define enhancements by Armin Kuster ## +## Copyright (c) 2000 MontaVista Software, Inc. ## +## ## +## This software falls under the GNU General Public License. ## +## Please read the COPYING file for more information ## + +# 18/01/2001 - Cleanups +# Functions prototyped as foo(void) same as foo() +# Stop eval'ing where we don't need to. +# -- huggie@earth.li + +# 27/06/2001 - Allowed whitespace after initial "/**" and +# allowed comments before function declarations. +# -- Christian Kreibich + +# Still to do: +# - add perldoc documentation +# - Look more closely at some of the scarier bits :) + +# 26/05/2001 - Support for separate source and object trees. +# Return error code. +# Keith Owens + +# 23/09/2001 - Added support for typedefs, structs, enums and unions +# Support for Context section; can be terminated using empty line +# Small fixes (like spaces vs. \s in regex) +# -- Tim Jansen + +# 25/07/2012 - Added support for HTML5 +# -- Dan Luedtke + +sub usage { + my $message = <<"EOF"; +Usage: $0 [OPTION ...] FILE ... + +Read C language source or header FILEs, extract embedded documentation comments, +and print formatted documentation to standard output. + +The documentation comments are identified by "/**" opening comment mark. See +Documentation/doc-guide/kernel-doc.rst for the documentation comment syntax. + +Output format selection (mutually exclusive): + -man Output troff manual page format. This is the default. + -rst Output reStructuredText format. + -none Do not output documentation, only warnings. + +Output format selection modifier (affects only ReST output): + + -sphinx-version Use the ReST C domain dialect compatible with an + specific Sphinx Version. + If not specified, kernel-doc will auto-detect using + the sphinx-build version found on PATH. + +Output selection (mutually exclusive): + -export Only output documentation for symbols that have been + exported using EXPORT_SYMBOL() or EXPORT_SYMBOL_GPL() + in any input FILE or -export-file FILE. + -internal Only output documentation for symbols that have NOT been + exported using EXPORT_SYMBOL() or EXPORT_SYMBOL_GPL() + in any input FILE or -export-file FILE. + -function NAME Only output documentation for the given function(s) + or DOC: section title(s). All other functions and DOC: + sections are ignored. May be specified multiple times. + -nosymbol NAME Exclude the specified symbols from the output + documentation. May be specified multiple times. + +Output selection modifiers: + -no-doc-sections Do not output DOC: sections. + -enable-lineno Enable output of #define LINENO lines. Only works with + reStructuredText format. + -export-file FILE Specify an additional FILE in which to look for + EXPORT_SYMBOL() and EXPORT_SYMBOL_GPL(). To be used with + -export or -internal. May be specified multiple times. + +Other parameters: + -v Verbose output, more warnings and other information. + -h Print this help. + -Werror Treat warnings as errors. + +EOF + print $message; + exit 1; +} + +# +# format of comments. +# In the following table, (...)? signifies optional structure. +# (...)* signifies 0 or more structure elements +# /** +# * function_name(:)? (- short description)? +# (* @parameterx: (description of parameter x)?)* +# (* a blank line)? +# * (Description:)? (Description of function)? +# * (section header: (section description)? )* +# (*)?*/ +# +# So .. the trivial example would be: +# +# /** +# * my_function +# */ +# +# If the Description: header tag is omitted, then there must be a blank line +# after the last parameter specification. +# e.g. +# /** +# * my_function - does my stuff +# * @my_arg: its mine damnit +# * +# * Does my stuff explained. +# */ +# +# or, could also use: +# /** +# * my_function - does my stuff +# * @my_arg: its mine damnit +# * Description: Does my stuff explained. +# */ +# etc. +# +# Besides functions you can also write documentation for structs, unions, +# enums and typedefs. Instead of the function name you must write the name +# of the declaration; the struct/union/enum/typedef must always precede +# the name. Nesting of declarations is not supported. +# Use the argument mechanism to document members or constants. +# e.g. +# /** +# * struct my_struct - short description +# * @a: first member +# * @b: second member +# * +# * Longer description +# */ +# struct my_struct { +# int a; +# int b; +# /* private: */ +# int c; +# }; +# +# All descriptions can be multiline, except the short function description. +# +# For really longs structs, you can also describe arguments inside the +# body of the struct. +# eg. +# /** +# * struct my_struct - short description +# * @a: first member +# * @b: second member +# * +# * Longer description +# */ +# struct my_struct { +# int a; +# int b; +# /** +# * @c: This is longer description of C +# * +# * You can use paragraphs to describe arguments +# * using this method. +# */ +# int c; +# }; +# +# This should be use only for struct/enum members. +# +# You can also add additional sections. When documenting kernel functions you +# should document the "Context:" of the function, e.g. whether the functions +# can be called form interrupts. Unlike other sections you can end it with an +# empty line. +# A non-void function should have a "Return:" section describing the return +# value(s). +# Example-sections should contain the string EXAMPLE so that they are marked +# appropriately in DocBook. +# +# Example: +# /** +# * user_function - function that can only be called in user context +# * @a: some argument +# * Context: !in_interrupt() +# * +# * Some description +# * Example: +# * user_function(22); +# */ +# ... +# +# +# All descriptive text is further processed, scanning for the following special +# patterns, which are highlighted appropriately. +# +# 'funcname()' - function +# '$ENVVAR' - environmental variable +# '&struct_name' - name of a structure (up to two words including 'struct') +# '&struct_name.member' - name of a structure member +# '@parameter' - name of a parameter +# '%CONST' - name of a constant. +# '``LITERAL``' - literal string without any spaces on it. + +## init lots of data + +my $errors = 0; +my $warnings = 0; +my $anon_struct_union = 0; + +# match expressions used to find embedded type information +my $type_constant = '\b``([^\`]+)``\b'; +my $type_constant2 = '\%([-_\w]+)'; +my $type_func = '(\w+)\(\)'; +my $type_param = '\@(\w*((\.\w+)|(->\w+))*(\.\.\.)?)'; +my $type_param_ref = '([\!]?)\@(\w*((\.\w+)|(->\w+))*(\.\.\.)?)'; +my $type_fp_param = '\@(\w+)\(\)'; # Special RST handling for func ptr params +my $type_fp_param2 = '\@(\w+->\S+)\(\)'; # Special RST handling for structs with func ptr params +my $type_env = '(\$\w+)'; +my $type_enum = '\&(enum\s*([_\w]+))'; +my $type_struct = '\&(struct\s*([_\w]+))'; +my $type_typedef = '\&(typedef\s*([_\w]+))'; +my $type_union = '\&(union\s*([_\w]+))'; +my $type_member = '\&([_\w]+)(\.|->)([_\w]+)'; +my $type_fallback = '\&([_\w]+)'; +my $type_member_func = $type_member . '\(\)'; + +# Output conversion substitutions. +# One for each output format + +# these are pretty rough +my @highlights_man = ( + [$type_constant, "\$1"], + [$type_constant2, "\$1"], + [$type_func, "\\\\fB\$1\\\\fP"], + [$type_enum, "\\\\fI\$1\\\\fP"], + [$type_struct, "\\\\fI\$1\\\\fP"], + [$type_typedef, "\\\\fI\$1\\\\fP"], + [$type_union, "\\\\fI\$1\\\\fP"], + [$type_param, "\\\\fI\$1\\\\fP"], + [$type_param_ref, "\\\\fI\$1\$2\\\\fP"], + [$type_member, "\\\\fI\$1\$2\$3\\\\fP"], + [$type_fallback, "\\\\fI\$1\\\\fP"] + ); +my $blankline_man = ""; + +# rst-mode +my @highlights_rst = ( + [$type_constant, "``\$1``"], + [$type_constant2, "``\$1``"], + # Note: need to escape () to avoid func matching later + [$type_member_func, "\\:c\\:type\\:`\$1\$2\$3\\\\(\\\\) <\$1>`"], + [$type_member, "\\:c\\:type\\:`\$1\$2\$3 <\$1>`"], + [$type_fp_param, "**\$1\\\\(\\\\)**"], + [$type_fp_param2, "**\$1\\\\(\\\\)**"], + [$type_func, "\$1()"], + [$type_enum, "\\:c\\:type\\:`\$1 <\$2>`"], + [$type_struct, "\\:c\\:type\\:`\$1 <\$2>`"], + [$type_typedef, "\\:c\\:type\\:`\$1 <\$2>`"], + [$type_union, "\\:c\\:type\\:`\$1 <\$2>`"], + # in rst this can refer to any type + [$type_fallback, "\\:c\\:type\\:`\$1`"], + [$type_param_ref, "**\$1\$2**"] + ); +my $blankline_rst = "\n"; + +# read arguments +if ($#ARGV == -1) { + usage(); +} + +my $kernelversion; +my ($sphinx_major, $sphinx_minor, $sphinx_patch); + +my $dohighlight = ""; + +my $verbose = 0; +my $Werror = 0; +my $output_mode = "rst"; +my $output_preformatted = 0; +my $no_doc_sections = 0; +my $enable_lineno = 0; +my @highlights = @highlights_rst; +my $blankline = $blankline_rst; +my $modulename = "Kernel API"; + +use constant { + OUTPUT_ALL => 0, # output all symbols and doc sections + OUTPUT_INCLUDE => 1, # output only specified symbols + OUTPUT_EXPORTED => 2, # output exported symbols + OUTPUT_INTERNAL => 3, # output non-exported symbols +}; +my $output_selection = OUTPUT_ALL; +my $show_not_found = 0; # No longer used + +my @export_file_list; + +my @build_time; +if (defined($ENV{'KBUILD_BUILD_TIMESTAMP'}) && + (my $seconds = `date -d"${ENV{'KBUILD_BUILD_TIMESTAMP'}}" +%s`) ne '') { + @build_time = gmtime($seconds); +} else { + @build_time = localtime; +} + +my $man_date = ('January', 'February', 'March', 'April', 'May', 'June', + 'July', 'August', 'September', 'October', + 'November', 'December')[$build_time[4]] . + " " . ($build_time[5]+1900); + +# Essentially these are globals. +# They probably want to be tidied up, made more localised or something. +# CAVEAT EMPTOR! Some of the others I localised may not want to be, which +# could cause "use of undefined value" or other bugs. +my ($function, %function_table, %parametertypes, $declaration_purpose); +my %nosymbol_table = (); +my $declaration_start_line; +my ($type, $declaration_name, $return_type); +my ($newsection, $newcontents, $prototype, $brcount, %source_map); + +if (defined($ENV{'KBUILD_VERBOSE'})) { + $verbose = "$ENV{'KBUILD_VERBOSE'}"; +} + +if (defined($ENV{'KCFLAGS'})) { + my $kcflags = "$ENV{'KCFLAGS'}"; + + if ($kcflags =~ /Werror/) { + $Werror = 1; + } +} + +if (defined($ENV{'KDOC_WERROR'})) { + $Werror = "$ENV{'KDOC_WERROR'}"; +} + +# Generated docbook code is inserted in a template at a point where +# docbook v3.1 requires a non-zero sequence of RefEntry's; see: +# https://www.oasis-open.org/docbook/documentation/reference/html/refentry.html +# We keep track of number of generated entries and generate a dummy +# if needs be to ensure the expanded template can be postprocessed +# into html. +my $section_counter = 0; + +my $lineprefix=""; + +# Parser states +use constant { + STATE_NORMAL => 0, # normal code + STATE_NAME => 1, # looking for function name + STATE_BODY_MAYBE => 2, # body - or maybe more description + STATE_BODY => 3, # the body of the comment + STATE_BODY_WITH_BLANK_LINE => 4, # the body, which has a blank line + STATE_PROTO => 5, # scanning prototype + STATE_DOCBLOCK => 6, # documentation block + STATE_INLINE => 7, # gathering doc outside main block +}; +my $state; +my $in_doc_sect; +my $leading_space; + +# Inline documentation state +use constant { + STATE_INLINE_NA => 0, # not applicable ($state != STATE_INLINE) + STATE_INLINE_NAME => 1, # looking for member name (@foo:) + STATE_INLINE_TEXT => 2, # looking for member documentation + STATE_INLINE_END => 3, # done + STATE_INLINE_ERROR => 4, # error - Comment without header was found. + # Spit a warning as it's not + # proper kernel-doc and ignore the rest. +}; +my $inline_doc_state; + +#declaration types: can be +# 'function', 'struct', 'union', 'enum', 'typedef' +my $decl_type; + +# Name of the kernel-doc identifier for non-DOC markups +my $identifier; + +my $doc_start = '^/\*\*\s*$'; # Allow whitespace at end of comment start. +my $doc_end = '\*/'; +my $doc_com = '\s*\*\s*'; +my $doc_com_body = '\s*\* ?'; +my $doc_decl = $doc_com . '(\w+)'; +# @params and a strictly limited set of supported section names +# Specifically: +# Match @word: +# @...: +# @{section-name}: +# while trying to not match literal block starts like "example::" +# +my $doc_sect = $doc_com . + '\s*(\@[.\w]+|\@\.\.\.|description|context|returns?|notes?|examples?)\s*:([^:].*)?$'; +my $doc_content = $doc_com_body . '(.*)'; +my $doc_block = $doc_com . 'DOC:\s*(.*)?'; +my $doc_inline_start = '^\s*/\*\*\s*$'; +my $doc_inline_sect = '\s*\*\s*(@\s*[\w][\w\.]*\s*):(.*)'; +my $doc_inline_end = '^\s*\*/\s*$'; +my $doc_inline_oneline = '^\s*/\*\*\s*(@[\w\s]+):\s*(.*)\s*\*/\s*$'; +my $export_symbol = '^\s*EXPORT_SYMBOL(_GPL)?\s*\(\s*(\w+)\s*\)\s*;'; +my $function_pointer = qr{([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)}; +my $attribute = qr{__attribute__\s*\(\([a-z0-9,_\*\s\(\)]*\)\)}i; + +my %parameterdescs; +my %parameterdesc_start_lines; +my @parameterlist; +my %sections; +my @sectionlist; +my %section_start_lines; +my $sectcheck; +my $struct_actual; + +my $contents = ""; +my $new_start_line = 0; + +# the canonical section names. see also $doc_sect above. +my $section_default = "Description"; # default section +my $section_intro = "Introduction"; +my $section = $section_default; +my $section_context = "Context"; +my $section_return = "Return"; + +my $undescribed = "-- undescribed --"; + +reset_state(); + +while ($ARGV[0] =~ m/^--?(.*)/) { + my $cmd = $1; + shift @ARGV; + if ($cmd eq "man") { + $output_mode = "man"; + @highlights = @highlights_man; + $blankline = $blankline_man; + } elsif ($cmd eq "rst") { + $output_mode = "rst"; + @highlights = @highlights_rst; + $blankline = $blankline_rst; + } elsif ($cmd eq "none") { + $output_mode = "none"; + } elsif ($cmd eq "module") { # not needed for XML, inherits from calling document + $modulename = shift @ARGV; + } elsif ($cmd eq "function") { # to only output specific functions + $output_selection = OUTPUT_INCLUDE; + $function = shift @ARGV; + $function_table{$function} = 1; + } elsif ($cmd eq "nosymbol") { # Exclude specific symbols + my $symbol = shift @ARGV; + $nosymbol_table{$symbol} = 1; + } elsif ($cmd eq "export") { # only exported symbols + $output_selection = OUTPUT_EXPORTED; + %function_table = (); + } elsif ($cmd eq "internal") { # only non-exported symbols + $output_selection = OUTPUT_INTERNAL; + %function_table = (); + } elsif ($cmd eq "export-file") { + my $file = shift @ARGV; + push(@export_file_list, $file); + } elsif ($cmd eq "v") { + $verbose = 1; + } elsif ($cmd eq "Werror") { + $Werror = 1; + } elsif (($cmd eq "h") || ($cmd eq "help")) { + usage(); + } elsif ($cmd eq 'no-doc-sections') { + $no_doc_sections = 1; + } elsif ($cmd eq 'enable-lineno') { + $enable_lineno = 1; + } elsif ($cmd eq 'show-not-found') { + $show_not_found = 1; # A no-op but don't fail + } elsif ($cmd eq "sphinx-version") { + my $ver_string = shift @ARGV; + if ($ver_string =~ m/^(\d+)(\.\d+)?(\.\d+)?/) { + $sphinx_major = $1; + if (defined($2)) { + $sphinx_minor = substr($2,1); + } else { + $sphinx_minor = 0; + } + if (defined($3)) { + $sphinx_patch = substr($3,1) + } else { + $sphinx_patch = 0; + } + } else { + die "Sphinx version should either major.minor or major.minor.patch format\n"; + } + } else { + # Unknown argument + usage(); + } +} + +# continue execution near EOF; + +# The C domain dialect changed on Sphinx 3. So, we need to check the +# version in order to produce the right tags. +sub findprog($) +{ + foreach(split(/:/, $ENV{PATH})) { + return "$_/$_[0]" if(-x "$_/$_[0]"); + } +} + +sub get_sphinx_version() +{ + my $ver; + + my $cmd = "sphinx-build"; + if (!findprog($cmd)) { + my $cmd = "sphinx-build3"; + if (!findprog($cmd)) { + $sphinx_major = 1; + $sphinx_minor = 2; + $sphinx_patch = 0; + printf STDERR "Warning: Sphinx version not found. Using default (Sphinx version %d.%d.%d)\n", + $sphinx_major, $sphinx_minor, $sphinx_patch; + return; + } + } + + open IN, "$cmd --version 2>&1 |"; + while () { + if (m/^\s*sphinx-build\s+([\d]+)\.([\d\.]+)(\+\/[\da-f]+)?$/) { + $sphinx_major = $1; + $sphinx_minor = $2; + $sphinx_patch = $3; + last; + } + # Sphinx 1.2.x uses a different format + if (m/^\s*Sphinx.*\s+([\d]+)\.([\d\.]+)$/) { + $sphinx_major = $1; + $sphinx_minor = $2; + $sphinx_patch = $3; + last; + } + } + close IN; +} + +# get kernel version from env +sub get_kernel_version() { + my $version = 'unknown kernel version'; + + if (defined($ENV{'KERNELVERSION'})) { + $version = $ENV{'KERNELVERSION'}; + } + return $version; +} + +# +sub print_lineno { + my $lineno = shift; + if ($enable_lineno && defined($lineno)) { + print "#define LINENO " . $lineno . "\n"; + } +} +## +# dumps section contents to arrays/hashes intended for that purpose. +# +sub dump_section { + my $file = shift; + my $name = shift; + my $contents = join "\n", @_; + + if ($name =~ m/$type_param/) { + $name = $1; + $parameterdescs{$name} = $contents; + $sectcheck = $sectcheck . $name . " "; + $parameterdesc_start_lines{$name} = $new_start_line; + $new_start_line = 0; + } elsif ($name eq "@\.\.\.") { + $name = "..."; + $parameterdescs{$name} = $contents; + $sectcheck = $sectcheck . $name . " "; + $parameterdesc_start_lines{$name} = $new_start_line; + $new_start_line = 0; + } else { + if (defined($sections{$name}) && ($sections{$name} ne "")) { + # Only warn on user specified duplicate section names. + if ($name ne $section_default) { + print STDERR "${file}:$.: warning: duplicate section name '$name'\n"; + ++$warnings; + } + $sections{$name} .= $contents; + } else { + $sections{$name} = $contents; + push @sectionlist, $name; + $section_start_lines{$name} = $new_start_line; + $new_start_line = 0; + } + } +} + +## +# dump DOC: section after checking that it should go out +# +sub dump_doc_section { + my $file = shift; + my $name = shift; + my $contents = join "\n", @_; + + if ($no_doc_sections) { + return; + } + + return if (defined($nosymbol_table{$name})); + + if (($output_selection == OUTPUT_ALL) || + (($output_selection == OUTPUT_INCLUDE) && + defined($function_table{$name}))) + { + dump_section($file, $name, $contents); + output_blockhead({'sectionlist' => \@sectionlist, + 'sections' => \%sections, + 'module' => $modulename, + 'content-only' => ($output_selection != OUTPUT_ALL), }); + } +} + +## +# output function +# +# parameterdescs, a hash. +# function => "function name" +# parameterlist => @list of parameters +# parameterdescs => %parameter descriptions +# sectionlist => @list of sections +# sections => %section descriptions +# + +sub output_highlight { + my $contents = join "\n",@_; + my $line; + +# DEBUG +# if (!defined $contents) { +# use Carp; +# confess "output_highlight got called with no args?\n"; +# } + +# print STDERR "contents b4:$contents\n"; + eval $dohighlight; + die $@ if $@; +# print STDERR "contents af:$contents\n"; + + foreach $line (split "\n", $contents) { + if (! $output_preformatted) { + $line =~ s/^\s*//; + } + if ($line eq ""){ + if (! $output_preformatted) { + print $lineprefix, $blankline; + } + } else { + if ($output_mode eq "man" && substr($line, 0, 1) eq ".") { + print "\\&$line"; + } else { + print $lineprefix, $line; + } + } + print "\n"; + } +} + +## +# output function in man +sub output_function_man(%) { + my %args = %{$_[0]}; + my ($parameter, $section); + my $count; + + print ".TH \"$args{'function'}\" 9 \"$args{'function'}\" \"$man_date\" \"libnvme API manual\" LINUX\n"; + + print ".SH NAME\n"; + print $args{'function'} . " \\- " . $args{'purpose'} . "\n"; + + print ".SH SYNOPSIS\n"; + if ($args{'functiontype'} ne "") { + print ".B \"" . $args{'functiontype'} . "\" " . $args{'function'} . "\n"; + } else { + print ".B \"" . $args{'function'} . "\n"; + } + $count = 0; + my $parenth = "("; + my $post = ","; + foreach my $parameter (@{$args{'parameterlist'}}) { + if ($count == $#{$args{'parameterlist'}}) { + $post = ");"; + } + $type = $args{'parametertypes'}{$parameter}; + if ($type =~ m/$function_pointer/) { + # pointer-to-function + print ".BI \"" . $parenth . $1 . "\" " . " \") (" . $2 . ")" . $post . "\"\n"; + } else { + $type =~ s/([^\*])$/$1 /; + print ".BI \"" . $parenth . $type . "\" " . " \"" . $post . "\"\n"; + } + $count++; + $parenth = ""; + } + + print ".SH ARGUMENTS\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + my $parameter_name = $parameter; + $parameter_name =~ s/\[.*//; + + print ".IP \"" . $parameter . "\" 12\n"; + output_highlight($args{'parameterdescs'}{$parameter_name}); + } + foreach $section (@{$args{'sectionlist'}}) { + print ".SH \"", uc $section, "\"\n"; + output_highlight($args{'sections'}{$section}); + } +} + +## +# output enum in man +sub output_enum_man(%) { + my %args = %{$_[0]}; + my ($parameter, $section); + my $count; + + print ".TH \"$args{'module'}\" 9 \"enum $args{'enum'}\" \"$man_date\" \"API Manual\" LINUX\n"; + + print ".SH NAME\n"; + print "enum " . $args{'enum'} . " \\- " . $args{'purpose'} . "\n"; + + print ".SH SYNOPSIS\n"; + print "enum " . $args{'enum'} . " {\n"; + $count = 0; + foreach my $parameter (@{$args{'parameterlist'}}) { + print ".br\n.BI \" $parameter\"\n"; + if ($count == $#{$args{'parameterlist'}}) { + print "\n};\n"; + last; + } + else { + print ", \n.br\n"; + } + $count++; + } + + print ".SH Constants\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + my $parameter_name = $parameter; + $parameter_name =~ s/\[.*//; + + print ".IP \"" . $parameter . "\" 12\n"; + output_highlight($args{'parameterdescs'}{$parameter_name}); + } + foreach $section (@{$args{'sectionlist'}}) { + print ".SH \"$section\"\n"; + output_highlight($args{'sections'}{$section}); + } +} + +## +# output struct in man +sub output_struct_man(%) { + my %args = %{$_[0]}; + my ($parameter, $section); + + print ".TH \"$args{'module'}\" 9 \"" . $args{'type'} . " " . $args{'struct'} . "\" \"$man_date\" \"API Manual\" LINUX\n"; + + print ".SH NAME\n"; + print $args{'type'} . " " . $args{'struct'} . " \\- " . $args{'purpose'} . "\n"; + + my $declaration = $args{'definition'}; + $declaration =~ s/\t/ /g; + $declaration =~ s/\n/"\n.br\n.BI \"/g; + print ".SH SYNOPSIS\n"; + print $args{'type'} . " " . $args{'struct'} . " {\n.br\n"; + print ".BI \"$declaration\n};\n.br\n\n"; + + print ".SH Members\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + ($parameter =~ /^#/) && next; + + my $parameter_name = $parameter; + $parameter_name =~ s/\[.*//; + + ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; + print ".IP \"" . $parameter . "\" 12\n"; + output_highlight($args{'parameterdescs'}{$parameter_name}); + } + foreach $section (@{$args{'sectionlist'}}) { + print ".SH \"$section\"\n"; + output_highlight($args{'sections'}{$section}); + } +} + +## +# output typedef in man +sub output_typedef_man(%) { + my %args = %{$_[0]}; + my ($parameter, $section); + + print ".TH \"$args{'module'}\" 9 \"$args{'typedef'}\" \"$man_date\" \"API Manual\" LINUX\n"; + + print ".SH NAME\n"; + print "typedef " . $args{'typedef'} . " \\- " . $args{'purpose'} . "\n"; + + foreach $section (@{$args{'sectionlist'}}) { + print ".SH \"$section\"\n"; + output_highlight($args{'sections'}{$section}); + } +} + +sub output_blockhead_man(%) { + my %args = %{$_[0]}; + my ($parameter, $section); + my $count; + + print ".TH \"$args{'module'}\" 9 \"$args{'module'}\" \"$man_date\" \"API Manual\" LINUX\n"; + + foreach $section (@{$args{'sectionlist'}}) { + print ".SH \"$section\"\n"; + output_highlight($args{'sections'}{$section}); + } +} + +## +# output in restructured text +# + +# +# This could use some work; it's used to output the DOC: sections, and +# starts by putting out the name of the doc section itself, but that tends +# to duplicate a header already in the template file. +# +sub output_blockhead_rst(%) { + my %args = %{$_[0]}; + my ($parameter, $section); + + foreach $section (@{$args{'sectionlist'}}) { + next if (defined($nosymbol_table{$section})); + + if ($output_selection != OUTPUT_INCLUDE) { + print ".. _$section:\n\n"; + print "**$section**\n\n"; + } + print_lineno($section_start_lines{$section}); + output_highlight_rst($args{'sections'}{$section}); + print "\n"; + } +} + +# +# Apply the RST highlights to a sub-block of text. +# +sub highlight_block($) { + # The dohighlight kludge requires the text be called $contents + my $contents = shift; + eval $dohighlight; + die $@ if $@; + return $contents; +} + +# +# Regexes used only here. +# +my $sphinx_literal = '^[^.].*::$'; +my $sphinx_cblock = '^\.\.\ +code-block::'; + +sub output_highlight_rst { + my $input = join "\n",@_; + my $output = ""; + my $line; + my $in_literal = 0; + my $litprefix; + my $block = ""; + + foreach $line (split "\n",$input) { + # + # If we're in a literal block, see if we should drop out + # of it. Otherwise pass the line straight through unmunged. + # + if ($in_literal) { + if (! ($line =~ /^\s*$/)) { + # + # If this is the first non-blank line in a literal + # block we need to figure out what the proper indent is. + # + if ($litprefix eq "") { + $line =~ /^(\s*)/; + $litprefix = '^' . $1; + $output .= $line . "\n"; + } elsif (! ($line =~ /$litprefix/)) { + $in_literal = 0; + } else { + $output .= $line . "\n"; + } + } else { + $output .= $line . "\n"; + } + } + # + # Not in a literal block (or just dropped out) + # + if (! $in_literal) { + $block .= $line . "\n"; + if (($line =~ /$sphinx_literal/) || ($line =~ /$sphinx_cblock/)) { + $in_literal = 1; + $litprefix = ""; + $output .= highlight_block($block); + $block = "" + } + } + } + + if ($block) { + $output .= highlight_block($block); + } + foreach $line (split "\n", $output) { + print $lineprefix . $line . "\n"; + } +} + +sub output_function_rst(%) { + my %args = %{$_[0]}; + my ($parameter, $section); + my $oldprefix = $lineprefix; + my $start = ""; + my $is_macro = 0; + + if ($sphinx_major < 3) { + if ($args{'typedef'}) { + print ".. c:type:: ". $args{'function'} . "\n\n"; + print_lineno($declaration_start_line); + print " **Typedef**: "; + $lineprefix = ""; + output_highlight_rst($args{'purpose'}); + $start = "\n\n**Syntax**\n\n ``"; + $is_macro = 1; + } else { + print ".. c:function:: "; + } + } else { + if ($args{'typedef'} || $args{'functiontype'} eq "") { + $is_macro = 1; + print ".. c:macro:: ". $args{'function'} . "\n\n"; + } else { + print ".. c:function:: "; + } + + if ($args{'typedef'}) { + print_lineno($declaration_start_line); + print " **Typedef**: "; + $lineprefix = ""; + output_highlight_rst($args{'purpose'}); + $start = "\n\n**Syntax**\n\n ``"; + } else { + print "``" if ($is_macro); + } + } + if ($args{'functiontype'} ne "") { + $start .= $args{'functiontype'} . " " . $args{'function'} . " ("; + } else { + $start .= $args{'function'} . " ("; + } + print $start; + + my $count = 0; + foreach my $parameter (@{$args{'parameterlist'}}) { + if ($count ne 0) { + print ", "; + } + $count++; + $type = $args{'parametertypes'}{$parameter}; + + if ($type =~ m/$function_pointer/) { + # pointer-to-function + print $1 . $parameter . ") (" . $2 . ")"; + } else { + print $type; + } + } + if ($is_macro) { + print ")``\n\n"; + } else { + print ")\n\n"; + } + if (!$args{'typedef'}) { + print_lineno($declaration_start_line); + $lineprefix = " "; + output_highlight_rst($args{'purpose'}); + print "\n"; + } + + print "**Parameters**\n\n"; + $lineprefix = " "; + foreach $parameter (@{$args{'parameterlist'}}) { + my $parameter_name = $parameter; + $parameter_name =~ s/\[.*//; + $type = $args{'parametertypes'}{$parameter}; + + if ($type ne "") { + print "``$type``\n"; + } else { + print "``$parameter``\n"; + } + + print_lineno($parameterdesc_start_lines{$parameter_name}); + + if (defined($args{'parameterdescs'}{$parameter_name}) && + $args{'parameterdescs'}{$parameter_name} ne $undescribed) { + output_highlight_rst($args{'parameterdescs'}{$parameter_name}); + } else { + print " *undescribed*\n"; + } + print "\n"; + } + + $lineprefix = $oldprefix; + output_section_rst(@_); +} + +sub output_section_rst(%) { + my %args = %{$_[0]}; + my $section; + my $oldprefix = $lineprefix; + $lineprefix = ""; + + foreach $section (@{$args{'sectionlist'}}) { + print "**$section**\n\n"; + print_lineno($section_start_lines{$section}); + output_highlight_rst($args{'sections'}{$section}); + print "\n"; + } + print "\n"; + $lineprefix = $oldprefix; +} + +sub output_enum_rst(%) { + my %args = %{$_[0]}; + my ($parameter); + my $oldprefix = $lineprefix; + my $count; + + if ($sphinx_major < 3) { + my $name = "enum " . $args{'enum'}; + print "\n\n.. c:type:: " . $name . "\n\n"; + } else { + my $name = $args{'enum'}; + print "\n\n.. c:enum:: " . $name . "\n\n"; + } + print_lineno($declaration_start_line); + $lineprefix = " "; + output_highlight_rst($args{'purpose'}); + print "\n"; + + print "**Constants**\n\n"; + $lineprefix = " "; + foreach $parameter (@{$args{'parameterlist'}}) { + print "``$parameter``\n"; + if ($args{'parameterdescs'}{$parameter} ne $undescribed) { + output_highlight_rst($args{'parameterdescs'}{$parameter}); + } else { + print " *undescribed*\n"; + } + print "\n"; + } + + $lineprefix = $oldprefix; + output_section_rst(@_); +} + +sub output_typedef_rst(%) { + my %args = %{$_[0]}; + my ($parameter); + my $oldprefix = $lineprefix; + my $name; + + if ($sphinx_major < 3) { + $name = "typedef " . $args{'typedef'}; + } else { + $name = $args{'typedef'}; + } + print "\n\n.. c:type:: " . $name . "\n\n"; + print_lineno($declaration_start_line); + $lineprefix = " "; + output_highlight_rst($args{'purpose'}); + print "\n"; + + $lineprefix = $oldprefix; + output_section_rst(@_); +} + +sub output_struct_rst(%) { + my %args = %{$_[0]}; + my ($parameter); + my $oldprefix = $lineprefix; + + if ($sphinx_major < 3) { + my $name = $args{'type'} . " " . $args{'struct'}; + print "\n\n.. c:type:: " . $name . "\n\n"; + } else { + my $name = $args{'struct'}; + if ($args{'type'} eq 'union') { + print "\n\n.. c:union:: " . $name . "\n\n"; + } else { + print "\n\n.. c:struct:: " . $name . "\n\n"; + } + } + print_lineno($declaration_start_line); + $lineprefix = " "; + output_highlight_rst($args{'purpose'}); + print "\n"; + + print "**Definition**\n\n"; + print "::\n\n"; + my $declaration = $args{'definition'}; + $declaration =~ s/\t/ /g; + print " " . $args{'type'} . " " . $args{'struct'} . " {\n$declaration };\n\n"; + + print "**Members**\n\n"; + $lineprefix = " "; + foreach $parameter (@{$args{'parameterlist'}}) { + ($parameter =~ /^#/) && next; + + my $parameter_name = $parameter; + $parameter_name =~ s/\[.*//; + + ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; + $type = $args{'parametertypes'}{$parameter}; + print_lineno($parameterdesc_start_lines{$parameter_name}); + print "``" . $parameter . "``\n"; + output_highlight_rst($args{'parameterdescs'}{$parameter_name}); + print "\n"; + } + print "\n"; + + $lineprefix = $oldprefix; + output_section_rst(@_); +} + +## none mode output functions + +sub output_function_none(%) { +} + +sub output_enum_none(%) { +} + +sub output_typedef_none(%) { +} + +sub output_struct_none(%) { +} + +sub output_blockhead_none(%) { +} + +## +# generic output function for all types (function, struct/union, typedef, enum); +# calls the generated, variable output_ function name based on +# functype and output_mode +sub output_declaration { + no strict 'refs'; + my $name = shift; + my $functype = shift; + my $func = "output_${functype}_$output_mode"; + + return if (defined($nosymbol_table{$name})); + + if (($output_selection == OUTPUT_ALL) || + (($output_selection == OUTPUT_INCLUDE || + $output_selection == OUTPUT_EXPORTED) && + defined($function_table{$name})) || + ($output_selection == OUTPUT_INTERNAL && + !($functype eq "function" && defined($function_table{$name})))) + { + &$func(@_); + $section_counter++; + } +} + +## +# generic output function - calls the right one based on current output mode. +sub output_blockhead { + no strict 'refs'; + my $func = "output_blockhead_" . $output_mode; + &$func(@_); + $section_counter++; +} + +## +# takes a declaration (struct, union, enum, typedef) and +# invokes the right handler. NOT called for functions. +sub dump_declaration($$) { + no strict 'refs'; + my ($prototype, $file) = @_; + my $func = "dump_" . $decl_type; + &$func(@_); +} + +sub dump_union($$) { + dump_struct(@_); +} + +sub dump_struct($$) { + my $x = shift; + my $file = shift; + my $decl_type; + my $members; + my $type = qr{struct|union}; + # For capturing struct/union definition body, i.e. "{members*}qualifiers*" + my $qualifiers = qr{$attribute|__packed|__aligned|____cacheline_aligned_in_smp|____cacheline_aligned}; + my $definition_body = qr{\{(.*)\}\s*$qualifiers*}; + my $struct_members = qr{($type)([^\{\};]+)\{([^\{\}]*)\}([^\{\}\;]*)\;}; + + if ($x =~ /($type)\s+(\w+)\s*$definition_body/) { + $decl_type = $1; + $declaration_name = $2; + $members = $3; + } elsif ($x =~ /typedef\s+($type)\s*$definition_body\s*(\w+)\s*;/) { + $decl_type = $1; + $declaration_name = $3; + $members = $2; + } + + if ($members) { + if ($identifier ne $declaration_name) { + print STDERR "${file}:$.: warning: expecting prototype for $decl_type $identifier. Prototype was for $decl_type $declaration_name instead\n"; + return; + } + + # ignore members marked private: + $members =~ s/\/\*\s*private:.*?\/\*\s*public:.*?\*\///gosi; + $members =~ s/\/\*\s*private:.*//gosi; + # strip comments: + $members =~ s/\/\*.*?\*\///gos; + # strip attributes + $members =~ s/\s*$attribute/ /gi; + $members =~ s/\s*__aligned\s*\([^;]*\)/ /gos; + $members =~ s/\s*__packed\s*/ /gos; + $members =~ s/\s*CRYPTO_MINALIGN_ATTR/ /gos; + $members =~ s/\s*____cacheline_aligned_in_smp/ /gos; + $members =~ s/\s*____cacheline_aligned/ /gos; + # unwrap struct_group(): + # - first eat non-declaration parameters and rewrite for final match + # - then remove macro, outer parens, and trailing semicolon + $members =~ s/\bstruct_group\s*\(([^,]*,)/STRUCT_GROUP(/gos; + $members =~ s/\bstruct_group_(attr|tagged)\s*\(([^,]*,){2}/STRUCT_GROUP(/gos; + $members =~ s/\b__struct_group\s*\(([^,]*,){3}/STRUCT_GROUP(/gos; + $members =~ s/\bSTRUCT_GROUP(\(((?:(?>[^)(]+)|(?1))*)\))[^;]*;/$2/gos; + + my $args = qr{([^,)]+)}; + # replace DECLARE_BITMAP + $members =~ s/__ETHTOOL_DECLARE_LINK_MODE_MASK\s*\(([^\)]+)\)/DECLARE_BITMAP($1, __ETHTOOL_LINK_MODE_MASK_NBITS)/gos; + $members =~ s/DECLARE_PHY_INTERFACE_MASK\s*\(([^\)]+)\)/DECLARE_BITMAP($1, PHY_INTERFACE_MODE_MAX)/gos; + $members =~ s/DECLARE_BITMAP\s*\($args,\s*$args\)/unsigned long $1\[BITS_TO_LONGS($2)\]/gos; + # replace DECLARE_HASHTABLE + $members =~ s/DECLARE_HASHTABLE\s*\($args,\s*$args\)/unsigned long $1\[1 << (($2) - 1)\]/gos; + # replace DECLARE_KFIFO + $members =~ s/DECLARE_KFIFO\s*\($args,\s*$args,\s*$args\)/$2 \*$1/gos; + # replace DECLARE_KFIFO_PTR + $members =~ s/DECLARE_KFIFO_PTR\s*\($args,\s*$args\)/$2 \*$1/gos; + # replace DECLARE_FLEX_ARRAY + $members =~ s/(?:__)?DECLARE_FLEX_ARRAY\s*\($args,\s*$args\)/$1 $2\[\]/gos; + my $declaration = $members; + + # Split nested struct/union elements as newer ones + while ($members =~ m/$struct_members/) { + my $newmember; + my $maintype = $1; + my $ids = $4; + my $content = $3; + foreach my $id(split /,/, $ids) { + $newmember .= "$maintype $id; "; + + $id =~ s/[:\[].*//; + $id =~ s/^\s*\**(\S+)\s*/$1/; + foreach my $arg (split /;/, $content) { + next if ($arg =~ m/^\s*$/); + if ($arg =~ m/^([^\(]+\(\*?\s*)([\w\.]*)(\s*\).*)/) { + # pointer-to-function + my $type = $1; + my $name = $2; + my $extra = $3; + next if (!$name); + if ($id =~ m/^\s*$/) { + # anonymous struct/union + $newmember .= "$type$name$extra; "; + } else { + $newmember .= "$type$id.$name$extra; "; + } + } else { + my $type; + my $names; + $arg =~ s/^\s+//; + $arg =~ s/\s+$//; + # Handle bitmaps + $arg =~ s/:\s*\d+\s*//g; + # Handle arrays + $arg =~ s/\[.*\]//g; + # The type may have multiple words, + # and multiple IDs can be defined, like: + # const struct foo, *bar, foobar + # So, we remove spaces when parsing the + # names, in order to match just names + # and commas for the names + $arg =~ s/\s*,\s*/,/g; + if ($arg =~ m/(.*)\s+([\S+,]+)/) { + $type = $1; + $names = $2; + } else { + $newmember .= "$arg; "; + next; + } + foreach my $name (split /,/, $names) { + $name =~ s/^\s*\**(\S+)\s*/$1/; + next if (($name =~ m/^\s*$/)); + if ($id =~ m/^\s*$/) { + # anonymous struct/union + $newmember .= "$type $name; "; + } else { + $newmember .= "$type $id.$name; "; + } + } + } + } + } + $members =~ s/$struct_members/$newmember/; + } + + # Ignore other nested elements, like enums + $members =~ s/(\{[^\{\}]*\})//g; + + create_parameterlist($members, ';', $file, $declaration_name); + check_sections($file, $declaration_name, $decl_type, $sectcheck, $struct_actual); + + # Adjust declaration for better display + $declaration =~ s/([\{;])/$1\n/g; + $declaration =~ s/\}\s+;/};/g; + # Better handle inlined enums + do {} while ($declaration =~ s/(enum\s+\{[^\}]+),([^\n])/$1,\n$2/); + + my @def_args = split /\n/, $declaration; + my $level = 1; + $declaration = ""; + foreach my $clause (@def_args) { + $clause =~ s/^\s+//; + $clause =~ s/\s+$//; + $clause =~ s/\s+/ /; + next if (!$clause); + $level-- if ($clause =~ m/(\})/ && $level > 1); + if (!($clause =~ m/^\s*#/)) { + $declaration .= "\t" x $level; + } + $declaration .= "\t" . $clause . "\n"; + $level++ if ($clause =~ m/(\{)/ && !($clause =~m/\}/)); + } + output_declaration($declaration_name, + 'struct', + {'struct' => $declaration_name, + 'module' => $modulename, + 'definition' => $declaration, + 'parameterlist' => \@parameterlist, + 'parameterdescs' => \%parameterdescs, + 'parametertypes' => \%parametertypes, + 'sectionlist' => \@sectionlist, + 'sections' => \%sections, + 'purpose' => $declaration_purpose, + 'type' => $decl_type + }); + } + else { + print STDERR "${file}:$.: error: Cannot parse struct or union!\n"; + ++$errors; + } +} + + +sub show_warnings($$) { + my $functype = shift; + my $name = shift; + + return 0 if (defined($nosymbol_table{$name})); + + return 1 if ($output_selection == OUTPUT_ALL); + + if ($output_selection == OUTPUT_EXPORTED) { + if (defined($function_table{$name})) { + return 1; + } else { + return 0; + } + } + if ($output_selection == OUTPUT_INTERNAL) { + if (!($functype eq "function" && defined($function_table{$name}))) { + return 1; + } else { + return 0; + } + } + if ($output_selection == OUTPUT_INCLUDE) { + if (defined($function_table{$name})) { + return 1; + } else { + return 0; + } + } + die("Please add the new output type at show_warnings()"); +} + +sub dump_enum($$) { + my $x = shift; + my $file = shift; + my $members; + + + $x =~ s@/\*.*?\*/@@gos; # strip comments. + # strip #define macros inside enums + $x =~ s@#\s*((define|ifdef)\s+|endif)[^;]*;@@gos; + + if ($x =~ /typedef\s+enum\s*\{(.*)\}\s*(\w*)\s*;/) { + $declaration_name = $2; + $members = $1; + } elsif ($x =~ /enum\s+(\w*)\s*\{(.*)\}/) { + $declaration_name = $1; + $members = $2; + } + + if ($members) { + if ($identifier ne $declaration_name) { + if ($identifier eq "") { + print STDERR "${file}:$.: warning: wrong kernel-doc identifier on line:\n"; + } else { + print STDERR "${file}:$.: warning: expecting prototype for enum $identifier. Prototype was for enum $declaration_name instead\n"; + } + return; + } + $declaration_name = "(anonymous)" if ($declaration_name eq ""); + + my %_members; + + $members =~ s/\s+$//; + + foreach my $arg (split ',', $members) { + $arg =~ s/^\s*(\w+).*/$1/; + push @parameterlist, $arg; + if (!$parameterdescs{$arg}) { + $parameterdescs{$arg} = $undescribed; + if (show_warnings("enum", $declaration_name)) { + print STDERR "${file}:$.: warning: Enum value '$arg' not described in enum '$declaration_name'\n"; + } + } + $_members{$arg} = 1; + } + + while (my ($k, $v) = each %parameterdescs) { + if (!exists($_members{$k})) { + if (show_warnings("enum", $declaration_name)) { + print STDERR "${file}:$.: warning: Excess enum value '$k' description in '$declaration_name'\n"; + } + } + } + + output_declaration($declaration_name, + 'enum', + {'enum' => $declaration_name, + 'module' => $modulename, + 'parameterlist' => \@parameterlist, + 'parameterdescs' => \%parameterdescs, + 'sectionlist' => \@sectionlist, + 'sections' => \%sections, + 'purpose' => $declaration_purpose + }); + } else { + print STDERR "${file}:$.: error: Cannot parse enum!\n"; + ++$errors; + } +} + +my $typedef_type = qr { ((?:\s+[\w\*]+\b){1,8})\s* }x; +my $typedef_ident = qr { \*?\s*(\w\S+)\s* }x; +my $typedef_args = qr { \s*\((.*)\); }x; + +my $typedef1 = qr { typedef$typedef_type\($typedef_ident\)$typedef_args }x; +my $typedef2 = qr { typedef$typedef_type$typedef_ident$typedef_args }x; + +sub dump_typedef($$) { + my $x = shift; + my $file = shift; + + $x =~ s@/\*.*?\*/@@gos; # strip comments. + + # Parse function typedef prototypes + if ($x =~ $typedef1 || $x =~ $typedef2) { + $return_type = $1; + $declaration_name = $2; + my $args = $3; + $return_type =~ s/^\s+//; + + if ($identifier ne $declaration_name) { + print STDERR "${file}:$.: warning: expecting prototype for typedef $identifier. Prototype was for typedef $declaration_name instead\n"; + return; + } + + create_parameterlist($args, ',', $file, $declaration_name); + + output_declaration($declaration_name, + 'function', + {'function' => $declaration_name, + 'typedef' => 1, + 'module' => $modulename, + 'functiontype' => $return_type, + 'parameterlist' => \@parameterlist, + 'parameterdescs' => \%parameterdescs, + 'parametertypes' => \%parametertypes, + 'sectionlist' => \@sectionlist, + 'sections' => \%sections, + 'purpose' => $declaration_purpose + }); + return; + } + + while (($x =~ /\(*.\)\s*;$/) || ($x =~ /\[*.\]\s*;$/)) { + $x =~ s/\(*.\)\s*;$/;/; + $x =~ s/\[*.\]\s*;$/;/; + } + + if ($x =~ /typedef.*\s+(\w+)\s*;/) { + $declaration_name = $1; + + if ($identifier ne $declaration_name) { + print STDERR "${file}:$.: warning: expecting prototype for typedef $identifier. Prototype was for typedef $declaration_name instead\n"; + return; + } + + output_declaration($declaration_name, + 'typedef', + {'typedef' => $declaration_name, + 'module' => $modulename, + 'sectionlist' => \@sectionlist, + 'sections' => \%sections, + 'purpose' => $declaration_purpose + }); + } + else { + print STDERR "${file}:$.: error: Cannot parse typedef!\n"; + ++$errors; + } +} + +sub save_struct_actual($) { + my $actual = shift; + + # strip all spaces from the actual param so that it looks like one string item + $actual =~ s/\s*//g; + $struct_actual = $struct_actual . $actual . " "; +} + +sub create_parameterlist($$$$) { + my $args = shift; + my $splitter = shift; + my $file = shift; + my $declaration_name = shift; + my $type; + my $param; + + # temporarily replace commas inside function pointer definition + my $arg_expr = qr{\([^\),]+}; + while ($args =~ /$arg_expr,/) { + $args =~ s/($arg_expr),/$1#/g; + } + + foreach my $arg (split($splitter, $args)) { + # strip comments + $arg =~ s/\/\*.*\*\///; + # strip leading/trailing spaces + $arg =~ s/^\s*//; + $arg =~ s/\s*$//; + $arg =~ s/\s+/ /; + + if ($arg =~ /^#/) { + # Treat preprocessor directive as a typeless variable just to fill + # corresponding data structures "correctly". Catch it later in + # output_* subs. + push_parameter($arg, "", "", $file); + } elsif ($arg =~ m/\(.+\)\s*\(/) { + # pointer-to-function + $arg =~ tr/#/,/; + $arg =~ m/[^\(]+\(\*?\s*([\w\[\]\.]*)\s*\)/; + $param = $1; + $type = $arg; + $type =~ s/([^\(]+\(\*?)\s*$param/$1/; + save_struct_actual($param); + push_parameter($param, $type, $arg, $file, $declaration_name); + } elsif ($arg) { + $arg =~ s/\s*:\s*/:/g; + $arg =~ s/\s*\[/\[/g; + + my @args = split('\s*,\s*', $arg); + if ($args[0] =~ m/\*/) { + $args[0] =~ s/(\*+)\s*/ $1/; + } + + my @first_arg; + if ($args[0] =~ /^(.*\s+)(.*?\[.*\].*)$/) { + shift @args; + push(@first_arg, split('\s+', $1)); + push(@first_arg, $2); + } else { + @first_arg = split('\s+', shift @args); + } + + unshift(@args, pop @first_arg); + $type = join " ", @first_arg; + + foreach $param (@args) { + if ($param =~ m/^(\*+)\s*(.*)/) { + save_struct_actual($2); + + push_parameter($2, "$type $1", $arg, $file, $declaration_name); + } + elsif ($param =~ m/(.*?):(\d+)/) { + if ($type ne "") { # skip unnamed bit-fields + save_struct_actual($1); + push_parameter($1, "$type:$2", $arg, $file, $declaration_name) + } + } + else { + save_struct_actual($param); + push_parameter($param, $type, $arg, $file, $declaration_name); + } + } + } + } +} + +sub push_parameter($$$$$) { + my $param = shift; + my $type = shift; + my $org_arg = shift; + my $file = shift; + my $declaration_name = shift; + + if (($anon_struct_union == 1) && ($type eq "") && + ($param eq "}")) { + return; # ignore the ending }; from anon. struct/union + } + + $anon_struct_union = 0; + $param =~ s/[\[\)].*//; + + if ($type eq "" && $param =~ /\.\.\.$/) + { + if (!$param =~ /\w\.\.\.$/) { + # handles unnamed variable parameters + $param = "..."; + } + elsif ($param =~ /\w\.\.\.$/) { + # for named variable parameters of the form `x...`, remove the dots + $param =~ s/\.\.\.$//; + } + if (!defined $parameterdescs{$param} || $parameterdescs{$param} eq "") { + $parameterdescs{$param} = "variable arguments"; + } + } + elsif ($type eq "" && ($param eq "" or $param eq "void")) + { + $param="void"; + $parameterdescs{void} = "no arguments"; + } + elsif ($type eq "" && ($param eq "struct" or $param eq "union")) + # handle unnamed (anonymous) union or struct: + { + $type = $param; + $param = "{unnamed_" . $param . "}"; + $parameterdescs{$param} = "anonymous\n"; + $anon_struct_union = 1; + } + + # warn if parameter has no description + # (but ignore ones starting with # as these are not parameters + # but inline preprocessor statements); + # Note: It will also ignore void params and unnamed structs/unions + if (!defined $parameterdescs{$param} && $param !~ /^#/) { + $parameterdescs{$param} = $undescribed; + + if (show_warnings($type, $declaration_name) && $param !~ /\./) { + print STDERR + "${file}:$.: warning: Function parameter or member '$param' not described in '$declaration_name'\n"; + ++$warnings; + } + } + + # strip spaces from $param so that it is one continuous string + # on @parameterlist; + # this fixes a problem where check_sections() cannot find + # a parameter like "addr[6 + 2]" because it actually appears + # as "addr[6", "+", "2]" on the parameter list; + # but it's better to maintain the param string unchanged for output, + # so just weaken the string compare in check_sections() to ignore + # "[blah" in a parameter string; + ###$param =~ s/\s*//g; + push @parameterlist, $param; + $org_arg =~ s/\s\s+/ /g; + $parametertypes{$param} = $org_arg; +} + +sub check_sections($$$$$) { + my ($file, $decl_name, $decl_type, $sectcheck, $prmscheck) = @_; + my @sects = split ' ', $sectcheck; + my @prms = split ' ', $prmscheck; + my $err; + my ($px, $sx); + my $prm_clean; # strip trailing "[array size]" and/or beginning "*" + + foreach $sx (0 .. $#sects) { + $err = 1; + foreach $px (0 .. $#prms) { + $prm_clean = $prms[$px]; + $prm_clean =~ s/\[.*\]//; + $prm_clean =~ s/$attribute//i; + # ignore array size in a parameter string; + # however, the original param string may contain + # spaces, e.g.: addr[6 + 2] + # and this appears in @prms as "addr[6" since the + # parameter list is split at spaces; + # hence just ignore "[..." for the sections check; + $prm_clean =~ s/\[.*//; + + ##$prm_clean =~ s/^\**//; + if ($prm_clean eq $sects[$sx]) { + $err = 0; + last; + } + } + if ($err) { + if ($decl_type eq "function") { + print STDERR "${file}:$.: warning: " . + "Excess function parameter " . + "'$sects[$sx]' " . + "description in '$decl_name'\n"; + ++$warnings; + } + } + } +} + +## +# Checks the section describing the return value of a function. +sub check_return_section { + my $file = shift; + my $declaration_name = shift; + my $return_type = shift; + + # Ignore an empty return type (It's a macro) + # Ignore functions with a "void" return type. (But don't ignore "void *") + if (($return_type eq "") || ($return_type =~ /void\s*\w*\s*$/)) { + return; + } + + if (!defined($sections{$section_return}) || + $sections{$section_return} eq "") { + print STDERR "${file}:$.: warning: " . + "No description found for return value of " . + "'$declaration_name'\n"; + ++$warnings; + } +} + +## +# takes a function prototype and the name of the current file being +# processed and spits out all the details stored in the global +# arrays/hashes. +sub dump_function($$) { + my $prototype = shift; + my $file = shift; + my $noret = 0; + + print_lineno($new_start_line); + + $prototype =~ s/^static +//; + $prototype =~ s/^extern +//; + $prototype =~ s/^asmlinkage +//; + $prototype =~ s/^inline +//; + $prototype =~ s/^__inline__ +//; + $prototype =~ s/^__inline +//; + $prototype =~ s/^__always_inline +//; + $prototype =~ s/^noinline +//; + $prototype =~ s/__init +//; + $prototype =~ s/__init_or_module +//; + $prototype =~ s/__deprecated +//; + $prototype =~ s/__flatten +//; + $prototype =~ s/__meminit +//; + $prototype =~ s/__must_check +//; + $prototype =~ s/__weak +//; + $prototype =~ s/__sched +//; + $prototype =~ s/__printf\s*\(\s*\d*\s*,\s*\d*\s*\) +//; + $prototype =~ s/__alloc_size\s*\(\s*\d+\s*(?:,\s*\d+\s*)?\) +//; + my $define = $prototype =~ s/^#\s*define\s+//; #ak added + $prototype =~ s/__attribute_const__ +//; + $prototype =~ s/__attribute__\s*\(\( + (?: + [\w\s]++ # attribute name + (?:\([^)]*+\))? # attribute arguments + \s*+,? # optional comma at the end + )+ + \)\)\s+//x; + + # Yes, this truly is vile. We are looking for: + # 1. Return type (may be nothing if we're looking at a macro) + # 2. Function name + # 3. Function parameters. + # + # All the while we have to watch out for function pointer parameters + # (which IIRC is what the two sections are for), C types (these + # regexps don't even start to express all the possibilities), and + # so on. + # + # If you mess with these regexps, it's a good idea to check that + # the following functions' documentation still comes out right: + # - parport_register_device (function pointer parameters) + # - atomic_set (macro) + # - pci_match_device, __copy_to_user (long return type) + my $name = qr{[a-zA-Z0-9_~:]+}; + my $prototype_end1 = qr{[^\(]*}; + my $prototype_end2 = qr{[^\{]*}; + my $prototype_end = qr{\(($prototype_end1|$prototype_end2)\)}; + my $type1 = qr{[\w\s]+}; + my $type2 = qr{$type1\*+}; + + if ($define && $prototype =~ m/^()($name)\s+/) { + # This is an object-like macro, it has no return type and no parameter + # list. + # Function-like macros are not allowed to have spaces between + # declaration_name and opening parenthesis (notice the \s+). + $return_type = $1; + $declaration_name = $2; + $noret = 1; + } elsif ($prototype =~ m/^()($name)\s*$prototype_end/ || + $prototype =~ m/^($type1)\s+($name)\s*$prototype_end/ || + $prototype =~ m/^($type2+)\s*($name)\s*$prototype_end/) { + $return_type = $1; + $declaration_name = $2; + my $args = $3; + + create_parameterlist($args, ',', $file, $declaration_name); + } else { + print STDERR "${file}:$.: warning: cannot understand function prototype: '$prototype'\n"; + return; + } + + if ($identifier ne $declaration_name) { + print STDERR "${file}:$.: warning: expecting prototype for $identifier(). Prototype was for $declaration_name() instead\n"; + return; + } + + my $prms = join " ", @parameterlist; + check_sections($file, $declaration_name, "function", $sectcheck, $prms); + + # This check emits a lot of warnings at the moment, because many + # functions don't have a 'Return' doc section. So until the number + # of warnings goes sufficiently down, the check is only performed in + # verbose mode. + # TODO: always perform the check. + if ($verbose && !$noret) { + check_return_section($file, $declaration_name, $return_type); + } + + # The function parser can be called with a typedef parameter. + # Handle it. + if ($return_type =~ /typedef/) { + output_declaration($declaration_name, + 'function', + {'function' => $declaration_name, + 'typedef' => 1, + 'module' => $modulename, + 'functiontype' => $return_type, + 'parameterlist' => \@parameterlist, + 'parameterdescs' => \%parameterdescs, + 'parametertypes' => \%parametertypes, + 'sectionlist' => \@sectionlist, + 'sections' => \%sections, + 'purpose' => $declaration_purpose + }); + } else { + output_declaration($declaration_name, + 'function', + {'function' => $declaration_name, + 'module' => $modulename, + 'functiontype' => $return_type, + 'parameterlist' => \@parameterlist, + 'parameterdescs' => \%parameterdescs, + 'parametertypes' => \%parametertypes, + 'sectionlist' => \@sectionlist, + 'sections' => \%sections, + 'purpose' => $declaration_purpose + }); + } +} + +sub reset_state { + $function = ""; + %parameterdescs = (); + %parametertypes = (); + @parameterlist = (); + %sections = (); + @sectionlist = (); + $sectcheck = ""; + $struct_actual = ""; + $prototype = ""; + + $state = STATE_NORMAL; + $inline_doc_state = STATE_INLINE_NA; +} + +sub tracepoint_munge($) { + my $file = shift; + my $tracepointname = 0; + my $tracepointargs = 0; + + if ($prototype =~ m/TRACE_EVENT\((.*?),/) { + $tracepointname = $1; + } + if ($prototype =~ m/DEFINE_SINGLE_EVENT\((.*?),/) { + $tracepointname = $1; + } + if ($prototype =~ m/DEFINE_EVENT\((.*?),(.*?),/) { + $tracepointname = $2; + } + $tracepointname =~ s/^\s+//; #strip leading whitespace + if ($prototype =~ m/TP_PROTO\((.*?)\)/) { + $tracepointargs = $1; + } + if (($tracepointname eq 0) || ($tracepointargs eq 0)) { + print STDERR "${file}:$.: warning: Unrecognized tracepoint format: \n". + "$prototype\n"; + } else { + $prototype = "static inline void trace_$tracepointname($tracepointargs)"; + $identifier = "trace_$identifier"; + } +} + +sub syscall_munge() { + my $void = 0; + + $prototype =~ s@[\r\n]+@ @gos; # strip newlines/CR's +## if ($prototype =~ m/SYSCALL_DEFINE0\s*\(\s*(a-zA-Z0-9_)*\s*\)/) { + if ($prototype =~ m/SYSCALL_DEFINE0/) { + $void = 1; +## $prototype = "long sys_$1(void)"; + } + + $prototype =~ s/SYSCALL_DEFINE.*\(/long sys_/; # fix return type & func name + if ($prototype =~ m/long (sys_.*?),/) { + $prototype =~ s/,/\(/; + } elsif ($void) { + $prototype =~ s/\)/\(void\)/; + } + + # now delete all of the odd-number commas in $prototype + # so that arg types & arg names don't have a comma between them + my $count = 0; + my $len = length($prototype); + if ($void) { + $len = 0; # skip the for-loop + } + for (my $ix = 0; $ix < $len; $ix++) { + if (substr($prototype, $ix, 1) eq ',') { + $count++; + if ($count % 2 == 1) { + substr($prototype, $ix, 1) = ' '; + } + } + } +} + +sub process_proto_function($$) { + my $x = shift; + my $file = shift; + + $x =~ s@\/\/.*$@@gos; # strip C99-style comments to end of line + + if ($x =~ m#\s*/\*\s+MACDOC\s*#io || ($x =~ /^#/ && $x !~ /^#\s*define/)) { + # do nothing + } + elsif ($x =~ /([^\{]*)/) { + $prototype .= $1; + } + + if (($x =~ /\{/) || ($x =~ /\#\s*define/) || ($x =~ /;/)) { + $prototype =~ s@/\*.*?\*/@@gos; # strip comments. + $prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's. + $prototype =~ s@^\s+@@gos; # strip leading spaces + + # Handle prototypes for function pointers like: + # int (*pcs_config)(struct foo) + $prototype =~ s@^(\S+\s+)\(\s*\*(\S+)\)@$1$2@gos; + + if ($prototype =~ /SYSCALL_DEFINE/) { + syscall_munge(); + } + if ($prototype =~ /TRACE_EVENT/ || $prototype =~ /DEFINE_EVENT/ || + $prototype =~ /DEFINE_SINGLE_EVENT/) + { + tracepoint_munge($file); + } + dump_function($prototype, $file); + reset_state(); + } +} + +sub process_proto_type($$) { + my $x = shift; + my $file = shift; + + $x =~ s@[\r\n]+@ @gos; # strip newlines/cr's. + $x =~ s@^\s+@@gos; # strip leading spaces + $x =~ s@\s+$@@gos; # strip trailing spaces + $x =~ s@\/\/.*$@@gos; # strip C99-style comments to end of line + + if ($x =~ /^#/) { + # To distinguish preprocessor directive from regular declaration later. + $x .= ";"; + } + + while (1) { + if ( $x =~ /([^\{\};]*)([\{\};])(.*)/ ) { + if( length $prototype ) { + $prototype .= " " + } + $prototype .= $1 . $2; + ($2 eq '{') && $brcount++; + ($2 eq '}') && $brcount--; + if (($2 eq ';') && ($brcount == 0)) { + dump_declaration($prototype, $file); + reset_state(); + last; + } + $x = $3; + } else { + $prototype .= $x; + last; + } + } +} + + +sub map_filename($) { + my $file; + my ($orig_file) = @_; + + if (defined($ENV{'SRCTREE'})) { + $file = "$ENV{'SRCTREE'}" . "/" . $orig_file; + } else { + $file = $orig_file; + } + + if (defined($source_map{$file})) { + $file = $source_map{$file}; + } + + return $file; +} + +sub process_export_file($) { + my ($orig_file) = @_; + my $file = map_filename($orig_file); + + if (!open(IN,"<$file")) { + print STDERR "Error: Cannot open file $file\n"; + ++$errors; + return; + } + + while () { + if (/$export_symbol/) { + next if (defined($nosymbol_table{$2})); + $function_table{$2} = 1; + } + } + + close(IN); +} + +# +# Parsers for the various processing states. +# +# STATE_NORMAL: looking for the /** to begin everything. +# +sub process_normal() { + if (/$doc_start/o) { + $state = STATE_NAME; # next line is always the function name + $in_doc_sect = 0; + $declaration_start_line = $. + 1; + } +} + +# +# STATE_NAME: Looking for the "name - description" line +# +sub process_name($$) { + my $file = shift; + my $descr; + + if (/$doc_block/o) { + $state = STATE_DOCBLOCK; + $contents = ""; + $new_start_line = $.; + + if ( $1 eq "" ) { + $section = $section_intro; + } else { + $section = $1; + } + } elsif (/$doc_decl/o) { + $identifier = $1; + my $is_kernel_comment = 0; + my $decl_start = qr{$doc_com}; + # test for pointer declaration type, foo * bar() - desc + my $fn_type = qr{\w+\s*\*\s*}; + my $parenthesis = qr{\(\w*\)}; + my $decl_end = qr{[-:].*}; + if (/^$decl_start([\w\s]+?)$parenthesis?\s*$decl_end?$/) { + $identifier = $1; + } + if ($identifier =~ m/^(struct|union|enum|typedef)\b\s*(\S*)/) { + $decl_type = $1; + $identifier = $2; + $is_kernel_comment = 1; + } + # Look for foo() or static void foo() - description; or misspelt + # identifier + elsif (/^$decl_start$fn_type?(\w+)\s*$parenthesis?\s*$decl_end?$/ || + /^$decl_start$fn_type?(\w+.*)$parenthesis?\s*$decl_end$/) { + $identifier = $1; + $decl_type = 'function'; + $identifier =~ s/^define\s+//; + $is_kernel_comment = 1; + } + $identifier =~ s/\s+$//; + + $state = STATE_BODY; + # if there's no @param blocks need to set up default section + # here + $contents = ""; + $section = $section_default; + $new_start_line = $. + 1; + if (/[-:](.*)/) { + # strip leading/trailing/multiple spaces + $descr= $1; + $descr =~ s/^\s*//; + $descr =~ s/\s*$//; + $descr =~ s/\s+/ /g; + $declaration_purpose = $descr; + $state = STATE_BODY_MAYBE; + } else { + $declaration_purpose = ""; + } + + if (!$is_kernel_comment) { + print STDERR "${file}:$.: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst\n"; + print STDERR $_; + ++$warnings; + $state = STATE_NORMAL; + } + + if (($declaration_purpose eq "") && $verbose) { + print STDERR "${file}:$.: warning: missing initial short description on line:\n"; + print STDERR $_; + ++$warnings; + } + + if ($identifier eq "" && $decl_type ne "enum") { + print STDERR "${file}:$.: warning: wrong kernel-doc identifier on line:\n"; + print STDERR $_; + ++$warnings; + $state = STATE_NORMAL; + } + + if ($verbose) { + print STDERR "${file}:$.: info: Scanning doc for $decl_type $identifier\n"; + } + } else { + print STDERR "${file}:$.: warning: Cannot understand $_ on line $.", + " - I thought it was a doc line\n"; + ++$warnings; + $state = STATE_NORMAL; + } +} + + +# +# STATE_BODY and STATE_BODY_MAYBE: the bulk of a kerneldoc comment. +# +sub process_body($$) { + my $file = shift; + + # Until all named variable macro parameters are + # documented using the bare name (`x`) rather than with + # dots (`x...`), strip the dots: + if ($section =~ /\w\.\.\.$/) { + $section =~ s/\.\.\.$//; + + if ($verbose) { + print STDERR "${file}:$.: warning: Variable macro arguments should be documented without dots\n"; + ++$warnings; + } + } + + if ($state == STATE_BODY_WITH_BLANK_LINE && /^\s*\*\s?\S/) { + dump_section($file, $section, $contents); + $section = $section_default; + $new_start_line = $.; + $contents = ""; + } + + if (/$doc_sect/i) { # case insensitive for supported section names + $newsection = $1; + $newcontents = $2; + + # map the supported section names to the canonical names + if ($newsection =~ m/^description$/i) { + $newsection = $section_default; + } elsif ($newsection =~ m/^context$/i) { + $newsection = $section_context; + } elsif ($newsection =~ m/^returns?$/i) { + $newsection = $section_return; + } elsif ($newsection =~ m/^\@return$/) { + # special: @return is a section, not a param description + $newsection = $section_return; + } + + if (($contents ne "") && ($contents ne "\n")) { + if (!$in_doc_sect && $verbose) { + print STDERR "${file}:$.: warning: contents before sections\n"; + ++$warnings; + } + dump_section($file, $section, $contents); + $section = $section_default; + } + + $in_doc_sect = 1; + $state = STATE_BODY; + $contents = $newcontents; + $new_start_line = $.; + while (substr($contents, 0, 1) eq " ") { + $contents = substr($contents, 1); + } + if ($contents ne "") { + $contents .= "\n"; + } + $section = $newsection; + $leading_space = undef; + } elsif (/$doc_end/) { + if (($contents ne "") && ($contents ne "\n")) { + dump_section($file, $section, $contents); + $section = $section_default; + $contents = ""; + } + # look for doc_com + + doc_end: + if ($_ =~ m'\s*\*\s*[a-zA-Z_0-9:\.]+\*/') { + print STDERR "${file}:$.: warning: suspicious ending line: $_"; + ++$warnings; + } + + $prototype = ""; + $state = STATE_PROTO; + $brcount = 0; + $new_start_line = $. + 1; + } elsif (/$doc_content/) { + if ($1 eq "") { + if ($section eq $section_context) { + dump_section($file, $section, $contents); + $section = $section_default; + $contents = ""; + $new_start_line = $.; + $state = STATE_BODY; + } else { + if ($section ne $section_default) { + $state = STATE_BODY_WITH_BLANK_LINE; + } else { + $state = STATE_BODY; + } + $contents .= "\n"; + } + } elsif ($state == STATE_BODY_MAYBE) { + # Continued declaration purpose + chomp($declaration_purpose); + $declaration_purpose .= " " . $1; + $declaration_purpose =~ s/\s+/ /g; + } else { + my $cont = $1; + if ($section =~ m/^@/ || $section eq $section_context) { + if (!defined $leading_space) { + if ($cont =~ m/^(\s+)/) { + $leading_space = $1; + } else { + $leading_space = ""; + } + } + $cont =~ s/^$leading_space//; + } + $contents .= $cont . "\n"; + } + } else { + # i dont know - bad line? ignore. + print STDERR "${file}:$.: warning: bad line: $_"; + ++$warnings; + } +} + + +# +# STATE_PROTO: reading a function/whatever prototype. +# +sub process_proto($$) { + my $file = shift; + + if (/$doc_inline_oneline/) { + $section = $1; + $contents = $2; + if ($contents ne "") { + $contents .= "\n"; + dump_section($file, $section, $contents); + $section = $section_default; + $contents = ""; + } + } elsif (/$doc_inline_start/) { + $state = STATE_INLINE; + $inline_doc_state = STATE_INLINE_NAME; + } elsif ($decl_type eq 'function') { + process_proto_function($_, $file); + } else { + process_proto_type($_, $file); + } +} + +# +# STATE_DOCBLOCK: within a DOC: block. +# +sub process_docblock($$) { + my $file = shift; + + if (/$doc_end/) { + dump_doc_section($file, $section, $contents); + $section = $section_default; + $contents = ""; + $function = ""; + %parameterdescs = (); + %parametertypes = (); + @parameterlist = (); + %sections = (); + @sectionlist = (); + $prototype = ""; + $state = STATE_NORMAL; + } elsif (/$doc_content/) { + if ( $1 eq "" ) { + $contents .= $blankline; + } else { + $contents .= $1 . "\n"; + } + } +} + +# +# STATE_INLINE: docbook comments within a prototype. +# +sub process_inline($$) { + my $file = shift; + + # First line (state 1) needs to be a @parameter + if ($inline_doc_state == STATE_INLINE_NAME && /$doc_inline_sect/o) { + $section = $1; + $contents = $2; + $new_start_line = $.; + if ($contents ne "") { + while (substr($contents, 0, 1) eq " ") { + $contents = substr($contents, 1); + } + $contents .= "\n"; + } + $inline_doc_state = STATE_INLINE_TEXT; + # Documentation block end */ + } elsif (/$doc_inline_end/) { + if (($contents ne "") && ($contents ne "\n")) { + dump_section($file, $section, $contents); + $section = $section_default; + $contents = ""; + } + $state = STATE_PROTO; + $inline_doc_state = STATE_INLINE_NA; + # Regular text + } elsif (/$doc_content/) { + if ($inline_doc_state == STATE_INLINE_TEXT) { + $contents .= $1 . "\n"; + # nuke leading blank lines + if ($contents =~ /^\s*$/) { + $contents = ""; + } + } elsif ($inline_doc_state == STATE_INLINE_NAME) { + $inline_doc_state = STATE_INLINE_ERROR; + print STDERR "${file}:$.: warning: "; + print STDERR "Incorrect use of kernel-doc format: $_"; + ++$warnings; + } + } +} + + +sub process_file($) { + my $file; + my $initial_section_counter = $section_counter; + my ($orig_file) = @_; + + $file = map_filename($orig_file); + + if (!open(IN_FILE,"<$file")) { + print STDERR "Error: Cannot open file $file\n"; + ++$errors; + return; + } + + $. = 1; + + $section_counter = 0; + while () { + while (s/\\\s*$//) { + $_ .= ; + } + # Replace tabs by spaces + while ($_ =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {}; + # Hand this line to the appropriate state handler + if ($state == STATE_NORMAL) { + process_normal(); + } elsif ($state == STATE_NAME) { + process_name($file, $_); + } elsif ($state == STATE_BODY || $state == STATE_BODY_MAYBE || + $state == STATE_BODY_WITH_BLANK_LINE) { + process_body($file, $_); + } elsif ($state == STATE_INLINE) { # scanning for inline parameters + process_inline($file, $_); + } elsif ($state == STATE_PROTO) { + process_proto($file, $_); + } elsif ($state == STATE_DOCBLOCK) { + process_docblock($file, $_); + } + } + + # Make sure we got something interesting. + if ($initial_section_counter == $section_counter && $ + output_mode ne "none") { + if ($output_selection == OUTPUT_INCLUDE) { + print STDERR "${file}:1: warning: '$_' not found\n" + for keys %function_table; + } + else { + print STDERR "${file}:1: warning: no structured comments found\n"; + } + } + close IN_FILE; +} + + +if ($output_mode eq "rst") { + get_sphinx_version() if (!$sphinx_major); +} + +$kernelversion = get_kernel_version(); + +# generate a sequence of code that will splice in highlighting information +# using the s// operator. +for (my $k = 0; $k < @highlights; $k++) { + my $pattern = $highlights[$k][0]; + my $result = $highlights[$k][1]; +# print STDERR "scanning pattern:$pattern, highlight:($result)\n"; + $dohighlight .= "\$contents =~ s:$pattern:$result:gs;\n"; +} + +# Read the file that maps relative names to absolute names for +# separate source and object directories and for shadow trees. +if (open(SOURCE_MAP, "<.tmp_filelist.txt")) { + my ($relname, $absname); + while() { + chop(); + ($relname, $absname) = (split())[0..1]; + $relname =~ s:^/+::; + $source_map{$relname} = $absname; + } + close(SOURCE_MAP); +} + +if ($output_selection == OUTPUT_EXPORTED || + $output_selection == OUTPUT_INTERNAL) { + + push(@export_file_list, @ARGV); + + foreach (@export_file_list) { + chomp; + process_export_file($_); + } +} + +foreach (@ARGV) { + chomp; + process_file($_); +} +if ($verbose && $errors) { + print STDERR "$errors errors\n"; +} +if ($verbose && $warnings) { + print STDERR "$warnings warnings\n"; +} + +if ($Werror && $warnings) { + print STDERR "$warnings warnings as Errors\n"; + exit($warnings); +} else { + exit($output_mode eq "none" ? 0 : $errors) +} diff --git a/doc/regen-man.sh b/doc/regen-man.sh new file mode 100755 index 0000000000..94b60a1673 --- /dev/null +++ b/doc/regen-man.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +API_FILES="src/nvme/filters.h src/nvme/ioctl.h src/nvme/linux.h src/nvme/log.h src/nvme/tree.h src/nvme/types.h src/nvme/fabrics.h src/nvme/util.h" +MAN=doc/man + +for file in $API_FILES ; do + for func in $(sed -n 's/ \* \([a-z_]*\)() -.*/\1/p' $file); do + echo "Updating ${func}.2" + ./doc/kernel-doc -man -function $func $file > ${MAN}/${func}.2 + done + for struct in $(sed -n 's/ \* struct \([a-z_]*\) -.*/\1/p' $file); do + echo "Updating ${struct}.2" + ./doc/kernel-doc -man -function $struct $file > ${MAN}/${struct}.2 + done + for enum in $(sed -n 's/ \* enum \([a-z_]*\) -.*/\1/p' $file); do + echo "Updating ${enum}.2" + ./doc/kernel-doc -man -function $enum $file > ${MAN}/${enum}.2 + done +done diff --git a/doc/regen-rst.sh b/doc/regen-rst.sh new file mode 100755 index 0000000000..25be581bd0 --- /dev/null +++ b/doc/regen-rst.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +API_FILES="filters.h ioctl.h linux.h log.h tree.h types.h fabrics.h util.h" +DOC_ROOT=doc + +rm ${DOC_ROOT}/libnvme.rst +for file in $API_FILES ; do + ./doc/kernel-doc -rst src/nvme/$file >> ${DOC_ROOT}/libnvme.rst +done From 8ff275308a65fe41fa261053772bf041946100ff Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 3 Feb 2022 11:05:49 +0100 Subject: [PATCH 0434/1564] tree: loop controllers can have transport addresses Loop controllers may have transport addresses, so we need to parse them to allocated correct objects. Signed-off-by: Hannes Reinecke --- src/nvme/fabrics.c | 5 +++-- src/nvme/tree.c | 18 +++++++++--------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index d8f4be25fc..2c05788a7a 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -581,9 +581,8 @@ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, case NVMF_TRTYPE_FC: switch (e->adrfam) { case NVMF_ADDR_FAMILY_FC: - nvme_chomp(e->traddr, NVMF_TRADDR_SIZE), + nvme_chomp(e->traddr, NVMF_TRADDR_SIZE); traddr = e->traddr; - trsvcid = NULL; break; default: nvme_msg(h->r, LOG_ERR, @@ -593,6 +592,8 @@ nvme_ctrl_t nvmf_connect_disc_entry(nvme_host_t h, return NULL; } case NVMF_TRTYPE_LOOP: + nvme_chomp(e->traddr, NVMF_TRADDR_SIZE); + traddr = strlen(e->traddr) ? e->traddr : NULL; break; default: nvme_msg(h->r, LOG_ERR, "skipping unsupported transport %d\n", diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 9f22b1550d..32c19fb4d8 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -1122,13 +1122,11 @@ int nvme_init_ctrl(nvme_host_t h, nvme_ctrl_t c, int instance) goto out_free_name; } - if (strcmp(c->transport, "loop")) { - c->address = nvme_get_attr(path, "address"); - if (!c->address) { - errno = ENVME_CONNECT_INVAL_TR; - ret = -1; - goto out_free_name; - } + c->address = nvme_get_attr(path, "address"); + if (!c->address && strcmp(c->transport, "loop")) { + errno = ENVME_CONNECT_INVAL_TR; + ret = -1; + goto out_free_name; } subsys_name = nvme_ctrl_lookup_subsystem_name(h->r, name); @@ -1179,13 +1177,15 @@ static nvme_ctrl_t nvme_ctrl_alloc(nvme_root_t r, nvme_subsystem_t s, errno = ENXIO; return NULL; } - if (!strcmp(transport, "loop")) - goto skip_address; /* Parse 'address' string into components */ addr = nvme_get_attr(path, "address"); if (!addr) { char *rpath = NULL, *p = NULL, *_a = NULL; + /* loop transport might not have an address */ + if (!strcmp(transport, "loop")) + goto skip_address; + /* Older kernel don't support pcie transport addresses */ if (strcmp(transport, "pcie")) { free(transport); From 3785918e2b2e2930412b82cf01384b996205be71 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 3 Feb 2022 11:34:51 +0100 Subject: [PATCH 0435/1564] tree: loop address may be NULL Return an empty string in nvme_ctrl_get_address() and not a NULL to get a better output. Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 2 +- src/nvme/tree.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 32c19fb4d8..685dbe1833 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -669,7 +669,7 @@ const char *nvme_ctrl_get_subsysnqn(nvme_ctrl_t c) const char *nvme_ctrl_get_address(nvme_ctrl_t c) { - return c->address; + return c->address ? c->address : ""; } const char *nvme_ctrl_get_firmware(nvme_ctrl_t c) diff --git a/src/nvme/tree.h b/src/nvme/tree.h index 585ed941e3..6b5cf4ed3a 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -735,7 +735,8 @@ const char *nvme_ctrl_get_sysfs_dir(nvme_ctrl_t c); * nvme_ctrl_get_address() - Address string of an nvme_ctrl_t * @c: nvme_ctrl_t object * - * Return: NVMe-over-Fabrics address string of @c + * Return: NVMe-over-Fabrics address string of @c or empty string + * of no address is present. */ const char *nvme_ctrl_get_address(nvme_ctrl_t c); From fe89efaf32509b416c4519d45b7ac82c88b4a93d Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 3 Feb 2022 12:28:13 +0100 Subject: [PATCH 0436/1564] tree: do not set dhchap_key to 'none' When no dhchap key is set the kernel will set the sysfs attribute to 'none'. And we shouldn't display this value in our internal tree as it really means 'not set'. Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 04420bc229..54a33b4bf0 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -505,6 +505,10 @@ static int nvme_scan_subsystem(struct nvme_root *r, const char *name, if (h->dhchap_key) free(h->dhchap_key); h->dhchap_key = nvme_get_attr(path, "dhchap_secret"); + if (h->dhchap_key && !strcmp(h->dhchap_key, "none")) { + free(h->dhchap_key); + h->dhchap_key = NULL; + } } } if (!h) @@ -1106,6 +1110,10 @@ static int nvme_configure_ctrl(nvme_root_t r, nvme_ctrl_t c, const char *path, c->serial = nvme_get_ctrl_attr(c, "serial"); c->sqsize = nvme_get_ctrl_attr(c, "sqsize"); c->dhchap_key = nvme_get_ctrl_attr(c, "dhchap_ctrl_secret"); + if (c->dhchap_key && !strcmp(c->dhchap_key, "none")) { + free(c->dhchap_key); + c->dhchap_key = NULL; + } return 0; } @@ -1306,6 +1314,10 @@ nvme_ctrl_t nvme_scan_ctrl(nvme_root_t r, const char *name) if (h->dhchap_key) free(h->dhchap_key); h->dhchap_key = nvme_get_attr(path, "dhchap_secret"); + if (h->dhchap_key && !strcmp(h->dhchap_key, "none")) { + free(h->dhchap_key); + h->dhchap_key = NULL; + } } if (!h) { h = nvme_default_host(r); From 071a8a18cee539ccdcdf924457c0802ac77e1f83 Mon Sep 17 00:00:00 2001 From: Arunpandian J Date: Thu, 3 Feb 2022 13:55:36 +0530 Subject: [PATCH 0437/1564] nvme: Add Supported Capacity Configuration List log page(LID: 0x11) Reviewed-by: Steven Seungcheol Lee Signed-off-by: Arunpandian J --- src/nvme/ioctl.h | 32 ++++++++++++++++ src/nvme/types.h | 97 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 129 insertions(+) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 02768097fc..8d3ba4f5e8 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -1797,6 +1797,38 @@ static inline int nvme_get_log_media_unit_stat(int fd, __u16 domid, return nvme_get_log(&args); } +/** + * nvme_get_log_support_cap_config_list() - + * @fd: File descriptor of nvme device + * @domid: Domain Identifier selection, if supported + * + * 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_support_cap_config_list(int fd, __u16 domid, + struct nvme_supported_cap_config_list_log *cap) +{ + struct nvme_get_log_args args = { + .lpo = 0, + .result = NULL, + .log = cap, + .args_size = sizeof(args), + .fd = fd, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .lid = NVME_LOG_LID_SUPPORTED_CAP_CONFIG_LIST, + .len = sizeof(*cap), + .nsid = NVME_NSID_NONE, + .csi = NVME_CSI_NVM, + .lsi = NVME_LOG_LSI_NONE, + .domid = domid, + .lsp = NVME_LOG_LSP_NONE, + .uuidx = NVME_UUID_NONE, + .rae = false, + .ot = false, + }; + return nvme_get_log(&args); +} + /** * nvme_get_log_reservation() - * @fd: File descriptor of nvme device diff --git a/src/nvme/types.h b/src/nvme/types.h index 4542a09a58..8465c7ee19 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -3543,6 +3543,101 @@ struct nvme_media_unit_stat_log { struct nvme_media_unit_stat_desc mus_desc[]; }; +/** + * 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 { + __le16 muid; + __u8 rsvd2[4]; + __le16 mudl; +}; + +/** + * struct nvme_channel_config_desc - + * @chanid: Channel Identifier + * @chmus: Number Channel Media Units + * + * Channel Configuration Descriptor + * Structure Definitions + */ +struct nvme_channel_config_desc { + __le16 chanid; + __le16 chmus; + struct nvme_media_unit_config_desc mu_config_desc[]; +}; + +/** + * struct nvme_channel_config_desc - + * @egchans: Number of Channels + * + * Endurance group Channel Configuration Descriptor + * Structure Definitions + */ +struct nvme_end_grp_chan_desc { + __le16 egchans; + struct nvme_channel_config_desc chan_config_desc[]; +}; + +/** + * struct nvme_end_grp_config_desc - + * @endgid: Endurance Group Identifier + * @cap_adj_factor: Capacity Adjustment Factor + * @tegcap: Total Endurance Group Capacity + * @segcap: Spare Endurance Group Capacity + * @end_est: Endurance Estimate + * @egsets: Number of NVM Sets + * @nvmsetid: NVM Set Identifier + * + * Endurance Group Configuration Descriptor + * Structure Definitions + */ +struct nvme_end_grp_config_desc { + __le16 endgid; + __le16 cap_adj_factor; + __u8 rsvd4[12]; + __u8 tegcap[16]; + __u8 segcap[16]; + __u8 end_est[16]; + __u8 rsvd64[16]; + __le16 egsets; + __le16 nvmsetid[]; +}; + +/** + * struct nvme_cap_config_desc - + * @cap_config_id: Capacity Configuration Identifier + * @domainid: Domain Identifier + * @egcn: Number Endurance Group Configuration + * Descriptors + * + * Capacity Configuration structure definitions + */ +struct nvme_capacity_config_desc { + __le16 cap_config_id; + __le16 domainid; + __le16 egcn; + __u8 rsvd6[26]; + struct nvme_end_grp_config_desc egcd[]; +}; + +/** + * 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 { + __u8 sccn; + __u8 rsvd1[15]; + struct nvme_capacity_config_desc cap_config_desc[]; +}; + /** * struct nvme_resv_notification_log - * @lpc: @@ -5718,6 +5813,7 @@ enum nvme_identify_cns { * @NVME_LOG_LID_LBA_STATUS: * @NVME_LOG_LID_ENDURANCE_GRP_EVT: * @NVME_LOG_LID_MEDIA_UNIT_STATUS: + * @NVME_LOG_LID_SUPPORTED_CAP_CONFIG_LIST: * @NVME_LOG_LID_FID_SUPPORTED_EFFECTS: * @NVME_LOG_LID_BOOT_PARTITION: * @NVME_LOG_LID_DISCOVER: @@ -5743,6 +5839,7 @@ enum nvme_cmd_get_log_lid { NVME_LOG_LID_LBA_STATUS = 0x0e, NVME_LOG_LID_ENDURANCE_GRP_EVT = 0x0f, NVME_LOG_LID_MEDIA_UNIT_STATUS = 0x10, + NVME_LOG_LID_SUPPORTED_CAP_CONFIG_LIST = 0x11, NVME_LOG_LID_FID_SUPPORTED_EFFECTS = 0x12, NVME_LOG_LID_BOOT_PARTITION = 0x15, NVME_LOG_LID_DISCOVER = 0x70, From 7d8125665c5439e20b609ed8764563097f9d36cc Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 4 Feb 2022 08:44:01 +0100 Subject: [PATCH 0438/1564] tree: do not print function twice nvme_msg() already prints out the function name, no need to specify it in the message itself. Signed-off-by: Hannes Reinecke --- src/nvme/tree.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 54a33b4bf0..c9a0c42cff 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -1258,12 +1258,10 @@ static nvme_ctrl_t nvme_ctrl_alloc(nvme_root_t r, nvme_subsystem_t s, break; if (!strcmp(c->name, name)) { nvme_msg(r, LOG_DEBUG, - "%s: found existing ctrl %s\n", - __func__, c->name); + "found existing ctrl %s\n", c->name); break; } - nvme_msg(r, LOG_DEBUG, "%s: skipping ctrl %s\n", - __func__, c->name); + nvme_msg(r, LOG_DEBUG, "skipping ctrl %s\n", c->name); p = c; } } while (c); @@ -1274,8 +1272,7 @@ static nvme_ctrl_t nvme_ctrl_alloc(nvme_root_t r, nvme_subsystem_t s, free(address); if (!c) { if (!p) { - nvme_msg(r, LOG_ERR, "%s: failed to lookup ctrl\n", - __func__); + nvme_msg(r, LOG_ERR, "failed to lookup ctrl\n"); errno = ENODEV; } else errno = ENOMEM; @@ -1796,15 +1793,13 @@ static int nvme_ctrl_scan_namespace(nvme_root_t r, struct nvme_ctrl *c, struct nvme_ns *n; if (!c->s) { - nvme_msg(r, LOG_DEBUG, "%s: no subsystem for %s\n", - __func__, name); + nvme_msg(r, LOG_DEBUG, "no subsystem for %s\n", name); errno = EINVAL; return -1; } n = __nvme_scan_namespace(c->sysfs_dir, name); if (!n) { - nvme_msg(r, LOG_DEBUG, "%s: failed to scan namespace %s\n", - __func__, name); + nvme_msg(r, LOG_DEBUG, "failed to scan namespace %s\n", name); return -1; } @@ -1821,8 +1816,7 @@ static int nvme_subsystem_scan_namespace(nvme_root_t r, nvme_subsystem_t s, n = __nvme_scan_namespace(s->sysfs_dir, name); if (!n) { - nvme_msg(r, LOG_DEBUG, "%s: failed to scan namespace %s\n", - __func__, name); + nvme_msg(r, LOG_DEBUG, "failed to scan namespace %s\n", name); return -1; } @@ -1844,8 +1838,7 @@ struct nvme_ns *nvme_subsystem_lookup_namespace(struct nvme_subsystem *s, return NULL; n = __nvme_scan_namespace(s->sysfs_dir, name); if (!n) { - nvme_msg(r, LOG_DEBUG, "%s: failed to scan namespace %d\n", - __func__, nsid); + nvme_msg(r, LOG_DEBUG, "failed to scan namespace %d\n", nsid); free(name); return NULL; } From c06fcce8948cfeacbfc7087957a4d86f99c0e41e Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 4 Feb 2022 08:55:14 +0100 Subject: [PATCH 0439/1564] json: remove wrapper definitions Switch to JSON-C API. Signed-off-by: Hannes Reinecke --- src/nvme/json.c | 70 +++++++++++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/src/nvme/json.c b/src/nvme/json.c index 50bc6405fd..f25991e7c8 100644 --- a/src/nvme/json.c +++ b/src/nvme/json.c @@ -18,15 +18,6 @@ #include "log.h" #include "private.h" -#define json_object_add_value_string(o, k, v) \ - json_object_object_add(o, k, json_object_new_string(v)) -#define json_object_add_value_int(o, k, v) \ - json_object_object_add(o, k, json_object_new_int(v)) -#define json_object_add_value_bool(o, k, v) \ - json_object_object_add(o, k, json_object_new_boolean(v)) -#define json_object_add_value_string(o, k, v) \ - json_object_object_add(o, k, json_object_new_string(v)) - #define JSON_UPDATE_INT_OPTION(c, k, a, o) \ if (!strcmp(# a, k ) && !c->a) c->a = json_object_get_int(o); #define JSON_UPDATE_BOOL_OPTION(c, k, a, o) \ @@ -194,13 +185,18 @@ int json_read_config(nvme_root_t r, const char *config_file) return 0; } -#define JSON_STRING_OPTION(c, p, o) \ - if ((c)->o && strcmp((c)->o, "none")) \ - json_object_add_value_string((p), # o , (c)->o) +#define JSON_STRING_OPTION(c, p, o) \ + if ((c)->o && strcmp((c)->o, "none")) \ + json_object_object_add((p), # o , \ + json_object_new_string((c)->o)) #define JSON_INT_OPTION(c, p, o, d) \ - if ((c)->o != d) json_object_add_value_int((p), # o , (c)->o) + if ((c)->o != d) \ + json_object_object_add((p), # o , \ + json_object_new_int((c)->o)) #define JSON_BOOL_OPTION(c, p, o) \ - if ((c)->o) json_object_add_value_bool((p), # o , (c)->o) + if ((c)->o) \ + json_object_object_add((p), # o , \ + json_object_new_boolean((c)->o)) static void json_update_port(struct json_object *ctrl_array, nvme_ctrl_t c) { @@ -209,23 +205,28 @@ static void json_update_port(struct json_object *ctrl_array, nvme_ctrl_t c) const char *transport, *value; transport = nvme_ctrl_get_transport(c); - json_object_add_value_string(port_obj, "transport", transport); + json_object_object_add(port_obj, "transport", + json_object_new_string(transport)); value = nvme_ctrl_get_traddr(c); if (value) - json_object_add_value_string(port_obj, "traddr", value); + json_object_object_add(port_obj, "traddr", + json_object_new_string(value)); value = nvme_ctrl_get_host_traddr(c); if (value) - json_object_add_value_string(port_obj, "host_traddr", value); + json_object_object_add(port_obj, "host_traddr", + json_object_new_string(value)); value = nvme_ctrl_get_host_iface(c); if (value) - json_object_add_value_string(port_obj, "host_iface", value); + json_object_object_add(port_obj, "host_iface", + json_object_new_string(value)); value = nvme_ctrl_get_trsvcid(c); if (value) - json_object_add_value_string(port_obj, "trsvcid", value); + json_object_object_add(port_obj, "trsvcid", + json_object_new_string(value)); value = nvme_ctrl_get_dhchap_key(c); if (value) - json_object_add_value_string(port_obj, "dhchap_key", - value); + json_object_object_add(port_obj, "dhchap_key", + json_object_new_string(value)); JSON_INT_OPTION(cfg, port_obj, nr_io_queues, 0); JSON_INT_OPTION(cfg, port_obj, nr_write_queues, 0); JSON_INT_OPTION(cfg, port_obj, nr_poll_queues, 0); @@ -244,9 +245,11 @@ static void json_update_port(struct json_object *ctrl_array, nvme_ctrl_t c) JSON_BOOL_OPTION(cfg, port_obj, data_digest); JSON_BOOL_OPTION(cfg, port_obj, tls); if (nvme_ctrl_is_persistent(c)) - json_object_add_value_bool(port_obj, "persistent", true); + json_object_object_add(port_obj, "persistent", + json_object_new_boolean(true)); if (nvme_ctrl_is_discovery_ctrl(c)) - json_object_add_value_bool(port_obj, "discovery", true); + json_object_object_add(port_obj, "discovery", + json_object_new_boolean(true)); json_object_array_add(ctrl_array, port_obj); } @@ -262,8 +265,8 @@ static void json_update_subsys(struct json_object *subsys_array, if (!strcmp(subsysnqn, NVME_DISC_SUBSYS_NAME)) return; - json_object_add_value_string(subsys_obj, "nqn", - nvme_subsystem_get_nqn(s)); + json_object_object_add(subsys_obj, "nqn", + json_object_new_string(subsysnqn)); port_array = json_object_new_array(); nvme_subsystem_for_each_ctrl(s, c) { json_update_port(port_array, c); @@ -285,19 +288,22 @@ int json_update_config(nvme_root_t r, const char *config_file) json_root = json_object_new_array(); nvme_for_each_host(r, h) { nvme_subsystem_t s; - const char *hostid, *dhchap_key; + const char *hostnqn, *hostid, *dhchap_key; host_obj = json_object_new_object(); - json_object_add_value_string(host_obj, "hostnqn", - nvme_host_get_hostnqn(h)); + if (!host_obj) + continue; + hostnqn = nvme_host_get_hostnqn(h); + json_object_object_add(host_obj, "hostnqn", + json_object_new_string(hostnqn)); hostid = nvme_host_get_hostid(h); if (hostid) - json_object_add_value_string(host_obj, "hostid", - hostid); + json_object_object_add(host_obj, "hostid", + json_object_new_string(hostid)); dhchap_key = nvme_host_get_dhchap_key(h); if (dhchap_key) - json_object_add_value_string(host_obj, "dhchap_key", - dhchap_key); + json_object_object_add(host_obj, "dhchap_key", + json_object_new_string(dhchap_key)); subsys_array = json_object_new_array(); nvme_for_each_subsystem(h, s) { json_update_subsys(subsys_array, s); From c139cecbcdf380fd77f002e868e2313795191ba4 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 4 Feb 2022 09:06:45 +0100 Subject: [PATCH 0440/1564] Make JSON-C mandatory during built We already have a JSON-C subproject, so we can make it mandatory during build anyway. Signed-off-by: Hannes Reinecke --- meson.build | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 02cc4fb8e4..3c95b0d1a0 100644 --- a/meson.build +++ b/meson.build @@ -40,7 +40,10 @@ libuuid_dep = dependency('uuid', required: true) conf.set('CONFIG_LIBUUID', libuuid_dep.found(), description: 'Is libuuid required?') # Check for json-c availability -json_c_dep = dependency('json-c', version: '>=0.13', fallback : ['json-c', 'json_c_dep']) +json_c_dep = dependency('json-c', + version: '>=0.13', + required: true, + fallback : ['json-c', 'json_c_dep']) conf.set('CONFIG_JSONC', json_c_dep.found(), description: 'Is json-c required?') # Check for OpenSSL availability From 4c3806fc41515a5f8ec61daf526b10f99fcd4c0a Mon Sep 17 00:00:00 2001 From: Arunpandian J Date: Fri, 4 Feb 2022 14:42:36 +0530 Subject: [PATCH 0441/1564] nvme: Add Enhanced Controller Meta Data(FID: 0x7D) Reviewed-by: Steven Seungcheol Lee Signed-off-by: Arunpandian J --- src/nvme/types.h | 2 ++ src/nvme/util.c | 1 + 2 files changed, 3 insertions(+) diff --git a/src/nvme/types.h b/src/nvme/types.h index a400dfbcd1..13b3b01523 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -5882,6 +5882,7 @@ enum nvme_cmd_get_log_lid { * @NVME_FEAT_FID_ENDURANCE_EVT_CFG: * @NVME_FEAT_FID_IOCS_PROFILE: * @NVME_FEAT_FID_SPINUP_CONTROL: + * @NVME_FEAT_FID_ENH_CTRL_METADATA: Enhanced Controller Metadata * @NVME_FEAT_FID_CTRL_METADATA: Controller Metadata * @NVME_FEAT_FID_NS_METADATA: Namespace Metadata * @NVME_FEAT_FID_SW_PROGRESS: @@ -5917,6 +5918,7 @@ enum nvme_features_id { NVME_FEAT_FID_ENDURANCE_EVT_CFG = 0x18, NVME_FEAT_FID_IOCS_PROFILE = 0x19, /* XXX: Placeholder until assigned */ NVME_FEAT_FID_SPINUP_CONTROL = 0x1a, + NVME_FEAT_FID_ENH_CTRL_METADATA = 0x7d, NVME_FEAT_FID_CTRL_METADATA = 0x7e, NVME_FEAT_FID_NS_METADATA = 0x7f, NVME_FEAT_FID_SW_PROGRESS = 0x80, diff --git a/src/nvme/util.c b/src/nvme/util.c index 34bd548773..1123a4c917 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -439,6 +439,7 @@ int nvme_get_feature_length(int fid, __u32 cdw11, __u32 *len) case NVME_FEAT_FID_WRITE_PROTECT: *len = 0; break; + case NVME_FEAT_FID_ENH_CTRL_METADATA: case NVME_FEAT_FID_CTRL_METADATA: case NVME_FEAT_FID_NS_METADATA: *len = sizeof(struct nvme_host_metadata); From 8e613b899e1f400e311ad09f0eff05c946d34f63 Mon Sep 17 00:00:00 2001 From: Steven Seungcheol Lee Date: Mon, 17 Jan 2022 11:35:54 +0900 Subject: [PATCH 0442/1564] ioctl: Modify identify command argument based on spec CNS Specific identifier presents all names below for DWORD11 bits [15:00] NVM Set Identifier(NVM Set List (04h)) Domain Identifier(Domain List (18h)) Endurance Group Identifier(Endurance Group List (19h)) Signed-off-by: Steven Seungcheol Lee --- src/nvme/ioctl.c | 9 ++---- src/nvme/ioctl.h | 71 ++++++++++++++++++------------------------------ src/nvme/types.h | 6 ++-- 3 files changed, 33 insertions(+), 53 deletions(-) diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 88b0a1389e..7dd8787805 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -240,14 +240,12 @@ enum nvme_cmd_dword_fields { NVME_LOG_CDW14_OT_MASK = 0x1, NVME_IDENTIFY_CDW10_CNS_SHIFT = 0, NVME_IDENTIFY_CDW10_CNTID_SHIFT = 16, - NVME_IDENTIFY_CDW11_NVMSETID_SHIFT = 0, - NVME_IDENTIFY_CDW11_DOMID_SHIFT = 0, + NVME_IDENTIFY_CDW11_CNSSPECID_SHIFT = 0, NVME_IDENTIFY_CDW14_UUID_SHIFT = 0, NVME_IDENTIFY_CDW11_CSI_SHIFT = 24, NVME_IDENTIFY_CDW10_CNS_MASK = 0xff, NVME_IDENTIFY_CDW10_CNTID_MASK = 0xffff, - NVME_IDENTIFY_CDW11_NVMSETID_MASK = 0xffff, - NVME_IDENTIFY_CDW11_DOMID_MASK = 0xffff, + NVME_IDENTIFY_CDW11_CNSSPECID_MASK = 0xffff, NVME_IDENTIFY_CDW14_UUID_MASK = 0x7f, NVME_IDENTIFY_CDW11_CSI_MASK = 0xff, NVME_NAMESPACE_ATTACH_CDW10_SEL_SHIFT = 0, @@ -369,8 +367,7 @@ int nvme_identify(struct nvme_identify_args *args) { __u32 cdw10 = NVME_SET(args->cntid, IDENTIFY_CDW10_CNTID) | NVME_SET(args->cns, IDENTIFY_CDW10_CNS); - __u32 cdw11 = NVME_SET(args->nvmsetid, IDENTIFY_CDW11_NVMSETID) | - NVME_SET(args->domid, IDENTIFY_CDW11_DOMID) | + __u32 cdw11 = NVME_SET(args->cns_specific_id, IDENTIFY_CDW11_CNSSPECID) | NVME_SET(args->csi, IDENTIFY_CDW11_CSI); __u32 cdw14 = NVME_SET(args->uuidx, IDENTIFY_CDW14_UUID); diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 56745c2272..7bbfa4ae00 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -381,18 +381,17 @@ 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 - * @nvmsetid: The NVMe Set ID if CNS is 04h - * @domid: Domain identifier, if applicable - * @uuidx: UUID Index if controller supports this id selection method + * @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; @@ -404,8 +403,7 @@ struct nvme_identify_args { enum nvme_csi csi; __u32 nsid; __u16 cntid; - __u16 nvmsetid; - __u16 domid; + __u16 cns_specific_id; __u8 uuidx; } __attribute__((packed, aligned(__alignof__(__u32*)))); @@ -434,8 +432,7 @@ static int nvme_identify_cns_nsid(int fd, enum nvme_identify_cns cns, .csi = NVME_CSI_NVM, .nsid = nsid, .cntid = NVME_CNTLID_NONE, - .nvmsetid = NVME_NVMSETID_NONE, - .domid = NVME_DOMID_NONE, + .cns_specific_id = NVME_CNSSPECID_NONE, .uuidx = NVME_UUID_NONE, }; @@ -574,8 +571,7 @@ static inline int nvme_identify_ctrl_list(int fd, __u16 cntid, .csi = NVME_CSI_NVM, .nsid = NVME_NSID_NONE, .cntid = cntid, - .nvmsetid = NVME_NVMSETID_NONE, - .domid = NVME_DOMID_NONE, + .cns_specific_id = NVME_CNSSPECID_NONE, .uuidx = NVME_UUID_NONE, }; @@ -611,8 +607,7 @@ static inline int nvme_identify_nsid_ctrl_list(int fd, __u32 nsid, __u16 cntid, .csi = NVME_CSI_NVM, .nsid = nsid, .cntid = cntid, - .nvmsetid = NVME_NVMSETID_NONE, - .domid = NVME_DOMID_NONE, + .cns_specific_id = NVME_CNSSPECID_NONE, .uuidx = NVME_UUID_NONE, }; @@ -672,8 +667,7 @@ static inline int nvme_identify_nvmset_list(int fd, __u16 nvmsetid, .csi = NVME_CSI_NVM, .nsid = NVME_NSID_NONE, .cntid = NVME_CNTLID_NONE, - .nvmsetid = nvmsetid, - .domid = NVME_DOMID_NONE, + .cns_specific_id = nvmsetid, .uuidx = NVME_UUID_NONE, }; @@ -705,8 +699,7 @@ static inline int nvme_identify_primary_ctrl(int fd, __u16 cntid, .csi = NVME_CSI_NVM, .nsid = NVME_NSID_NONE, .cntid = cntid, - .nvmsetid = NVME_NVMSETID_NONE, - .domid = NVME_DOMID_NONE, + .cns_specific_id = NVME_CNSSPECID_NONE, .uuidx = NVME_UUID_NONE, }; @@ -744,8 +737,7 @@ static inline int nvme_identify_secondary_ctrl_list(int fd, __u32 nsid, .csi = NVME_CSI_NVM, .nsid = nsid, .cntid = cntid, - .nvmsetid = NVME_NVMSETID_NONE, - .domid = NVME_DOMID_NONE, + .cns_specific_id = NVME_CNSSPECID_NONE, .uuidx = NVME_UUID_NONE, }; @@ -817,8 +809,7 @@ static inline int nvme_identify_ns_csi(int fd, __u32 nsid, .csi = csi, .nsid = nsid, .cntid = NVME_CNTLID_NONE, - .nvmsetid = NVME_NVMSETID_NONE, - .domid = NVME_DOMID_NONE, + .cns_specific_id = NVME_CNSSPECID_NONE, .uuidx = NVME_UUID_NONE, }; @@ -846,8 +837,7 @@ static inline int nvme_identify_ctrl_csi(int fd, enum nvme_csi csi, void *data) .csi = csi, .nsid = NVME_NSID_NONE, .cntid = NVME_CNTLID_NONE, - .nvmsetid = NVME_NVMSETID_NONE, - .domid = NVME_DOMID_NONE, + .cns_specific_id = NVME_CNSSPECID_NONE, .uuidx = NVME_UUID_NONE, }; @@ -884,8 +874,7 @@ static inline int nvme_identify_active_ns_list_csi(int fd, __u32 nsid, .csi = csi, .nsid = nsid, .cntid = NVME_CNTLID_NONE, - .nvmsetid = NVME_NVMSETID_NONE, - .domid = NVME_DOMID_NONE, + .cns_specific_id = NVME_CNSSPECID_NONE, .uuidx = NVME_UUID_NONE, }; @@ -922,8 +911,7 @@ static inline int nvme_identify_allocated_ns_list_csi(int fd, __u32 nsid, .csi = csi, .nsid = nsid, .cntid = NVME_CNTLID_NONE, - .nvmsetid = NVME_NVMSETID_NONE, - .domid = NVME_DOMID_NONE, + .cns_specific_id = NVME_CNSSPECID_NONE, .uuidx = NVME_UUID_NONE, }; @@ -953,8 +941,7 @@ static inline int nvme_identify_independent_identify_ns(int fd, __u32 nsid, .csi = NVME_CSI_NVM, .nsid = nsid, .cntid = NVME_CNTLID_NONE, - .nvmsetid = NVME_NVMSETID_NONE, - .domid = NVME_DOMID_NONE, + .cns_specific_id = NVME_CNSSPECID_NONE, .uuidx = NVME_UUID_NONE, }; @@ -1003,8 +990,7 @@ static inline int nvme_identify_domain_list(int fd, __u16 domid, .csi = NVME_CSI_NVM, .nsid = NVME_NSID_NONE, .cntid = NVME_CNTLID_NONE, - .nvmsetid = NVME_NVMSETID_NONE, - .domid = domid, + .cns_specific_id = domid, .uuidx = NVME_UUID_NONE, }; @@ -1033,8 +1019,7 @@ static inline int nvme_identify_endurance_group_list(int fd, __u16 endgrp_id, .csi = NVME_CSI_NVM, .nsid = NVME_NSID_NONE, .cntid = NVME_CNTLID_NONE, - .nvmsetid = NVME_NVMSETID_NONE, - .domid = endgrp_id, + .cns_specific_id = endgrp_id, .uuidx = NVME_UUID_NONE, }; @@ -1066,8 +1051,7 @@ static inline int nvme_identify_iocs(int fd, __u16 cntlid, .csi = NVME_CSI_NVM, .nsid = NVME_NSID_NONE, .cntid = cntlid, - .nvmsetid = NVME_NVMSETID_NONE, - .domid = NVME_DOMID_NONE, + .cns_specific_id = NVME_CNSSPECID_NONE, .uuidx = NVME_UUID_NONE, }; @@ -1096,8 +1080,7 @@ static inline int nvme_zns_identify_ns(int fd, __u32 nsid, .csi = NVME_CSI_ZNS, .nsid = nsid, .cntid = NVME_CNTLID_NONE, - .nvmsetid = NVME_NVMSETID_NONE, - .domid = NVME_DOMID_NONE, + .cns_specific_id = NVME_CNSSPECID_NONE, }; return nvme_identify(&args); diff --git a/src/nvme/types.h b/src/nvme/types.h index a400dfbcd1..13f446b74a 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -53,7 +53,7 @@ * 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_NVMSETID_NONE: Use to omit a nvmsetid command parameter + * @NVME_CNSSPECID_NONE: Use to omit a cns_specific_id command parameter * @NVME_DOMID_NONE: Use to omit a domid 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 @@ -98,8 +98,8 @@ enum nvme_constants { NVME_NSID_NONE = 0, NVME_UUID_NONE = 0, NVME_CNTLID_NONE = 0, - NVME_NVMSETID_NONE = 0, - NVME_DOMID_NONE = 0, + NVME_CNSSPECID_NONE = 0, + NVME_DOMID_NONE = 0, NVME_LOG_LSP_NONE = 0, NVME_LOG_LSI_NONE = 0, NVME_LOG_LPO_NONE = 0, From d3357844687578294e5290e58f153c7d6dbc8c5c Mon Sep 17 00:00:00 2001 From: Steven Seungcheol Lee Date: Mon, 17 Jan 2022 12:12:36 +0900 Subject: [PATCH 0443/1564] types: Add NVM Command Set id-ns structure Add uuid index argument on nvme_identify_ns_csi Signed-off-by: Steven Seungcheol Lee --- src/nvme/ioctl.h | 5 +++-- src/nvme/types.h | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 7bbfa4ae00..34ce058a7e 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -790,13 +790,14 @@ static inline int nvme_identify_uuid(int fd, struct nvme_id_uuid_list *uuid_list * nvme_identify_ns_csi() - * @fd: File descriptor of nvme device * @nsid: Namespace to identify + * @uuidx: UUID Index for differentiating vendor specific encoding * @csi: Command Set Identifier * @data: User space destination address to transfer the 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_identify_ns_csi(int fd, __u32 nsid, +static inline int nvme_identify_ns_csi(int fd, __u32 nsid, __u8 uuidx, enum nvme_csi csi, void *data) { struct nvme_identify_args args = { @@ -810,7 +811,7 @@ static inline int nvme_identify_ns_csi(int fd, __u32 nsid, .nsid = nsid, .cntid = NVME_CNTLID_NONE, .cns_specific_id = NVME_CNSSPECID_NONE, - .uuidx = NVME_UUID_NONE, + .uuidx = uuidx, }; return nvme_identify(&args); diff --git a/src/nvme/types.h b/src/nvme/types.h index 13f446b74a..7e00426e1e 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -2129,6 +2129,22 @@ struct nvme_id_ctrl_nvm { __u8 rsvd16[4080]; }; +/** + * struct nvme_nvm_id_ns - + * @lbstm: Logical Block Storage Tag Mask + * @pic: Protection Information Capabilities + * @rsvd9: Reserved + * @elbaf: List of Extended LBA Format Support + * @rsvd268: Reserved + */ +struct nvme_nvm_id_ns { + __le64 lbstm; + __u8 pic; + __u8 rsvd9[3]; + __le32 elbaf[64]; + __u8 rsvd268[3828]; +}; + /** * struct nvme_zns_lbafe - * @zsze: From 4203a3737e23ed37bcf84b445ceffa0fff43457a Mon Sep 17 00:00:00 2001 From: Steven Seungcheol Lee Date: Mon, 17 Jan 2022 12:22:22 +0900 Subject: [PATCH 0444/1564] ioctl: Add identify ioctl for CNS 09h, 0Ah 09h - Identify Namespace data structure for the specified User Data Format index containing the namespace capabilities for the NVM Command Set. 0Ah - I/O Command Set specific Identify Namespace data structure for the specified User Data Format index containing the namespace capabilities for the I/O Command Set specified in the CSI field. Signed-off-by: Steven Seungcheol Lee --- src/libnvme.map | 2 ++ src/nvme/ioctl.h | 69 ++++++++++++++++++++++++++++++++++++++++++++++++ src/nvme/types.h | 2 ++ 3 files changed, 73 insertions(+) diff --git a/src/libnvme.map b/src/libnvme.map index 5f3e9b5e16..7393e3cdc4 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -156,6 +156,8 @@ LIBNVME_1_0 { nvme_identify_domain_list; nvme_identify_endurance_group_list; nvme_identify_independent_identify_ns; + nvme_identify_ns_csi_user_data_format; + nvme_identify_iocs_ns_csi_user_data_format; nvme_identify_iocs; nvme_identify_ns; nvme_identify_ns_descs; diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 34ce058a7e..9ad2eb948a 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -949,6 +949,75 @@ static inline int nvme_identify_independent_identify_ns(int fd, __u32 nsid, return nvme_identify(&args); } +/** + * nvme_identify_ns_csi_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 + * + * Identify Namespace data structure for the specified User Data Format + * index containing the namespace capabilities for the NVM Command Set. + * + * 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_identify_ns_csi_user_data_format(int fd, + __u16 user_data_format, __u8 uuidx, + enum nvme_csi csi, void *data) +{ + struct nvme_identify_args args = { + .result = NULL, + .data = data, + .args_size = sizeof(args), + .fd = fd, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .cns = NVME_IDENTIFY_CNS_NS_USER_DATA_FORMAT, + .csi = csi, + .nsid = NVME_NSID_NONE, + .cntid = NVME_CNTLID_NONE, + .cns_specific_id = user_data_format, + .uuidx = uuidx, + }; + + return nvme_identify(&args); +} + +/** + * nvme_identify_iocs_ns_csi_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 + * + * I/O Command Set specific Identify Namespace data structure for + * the specified User Data Format index containing the namespace + * capabilities for the I/O Command Set specified in the CSI field. + * + * 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_identify_iocs_ns_csi_user_data_format(int fd, + __u16 user_data_format, __u8 uuidx, + enum nvme_csi csi, void *data) +{ + struct nvme_identify_args args = { + .result = NULL, + .data = data, + .args_size = sizeof(args), + .fd = fd, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .cns = NVME_IDENTIFY_CNS_CSI_NS_USER_DATA_FORMAT, + .csi = csi, + .nsid = NVME_NSID_NONE, + .cntid = NVME_CNTLID_NONE, + .cns_specific_id = user_data_format, + .uuidx = uuidx, + }; + + return nvme_identify(&args); +} + /** * nvme_nvm_identify_ctrl() - * @fd: File descriptor of nvme device diff --git a/src/nvme/types.h b/src/nvme/types.h index 7e00426e1e..8fa16771a6 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -5802,6 +5802,8 @@ enum nvme_identify_cns { NVME_IDENTIFY_CNS_CSI_CTRL = 0x06, NVME_IDENTIFY_CNS_CSI_NS_ACTIVE_LIST = 0x07, NVME_IDENTIFY_CNS_CSI_INDEPENDENT_ID_NS = 0x08, + NVME_IDENTIFY_CNS_NS_USER_DATA_FORMAT = 0x09, + NVME_IDENTIFY_CNS_CSI_NS_USER_DATA_FORMAT = 0x0A, NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST = 0x10, NVME_IDENTIFY_CNS_ALLOCATED_NS = 0x11, NVME_IDENTIFY_CNS_NS_CTRL_LIST = 0x12, From b4cb6a06f4f031e52e90bb8bf1a61ef02a2fb9be Mon Sep 17 00:00:00 2001 From: Steven Seungcheol Lee Date: Thu, 23 Dec 2021 10:51:38 +0900 Subject: [PATCH 0445/1564] nvme: Add nulbaf(Number of Unique Capability LBA Formats) field on nvmd_id_ns Add explaination for mssrl, mcl, src Based on spec NVMe - TP 4095 Namespace Capability Reporting 2021.06.28 - Ratified --- src/nvme/types.h | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/nvme/types.h b/src/nvme/types.h index 8fa16771a6..669b95a691 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -1651,10 +1651,20 @@ enum nvme_lbaf_rp { * @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. - * @mssrl: - * @mcl: - * @msrc: + * @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. + * @mcl: Maximum Copy Length indicates the maximum number of logical + * 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. * @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. + * @rsvd83: Reserved * @anagrpid: ANA Group Identifier indicates the ANA Group Identifier of the * ANA group of which the namespace is a member. * @rsvd96: Reserved @@ -1706,7 +1716,9 @@ struct nvme_id_ns { __le16 mssrl; __le32 mcl; __u8 msrc; - __u8 rsvd81[11]; + __u8 rsvd81; + __u8 nulbaf; + __u8 rsvd83[9]; __le32 anagrpid; __u8 rsvd96[3]; __u8 nsattr; From 280337845a483c2d8cb0cc621efb687efba02df4 Mon Sep 17 00:00:00 2001 From: Steven Seungcheol Lee Date: Fri, 4 Feb 2022 17:23:31 +0900 Subject: [PATCH 0446/1564] nvme: get log domain id included in Log Specific Identifier domid was not used in nvme_get_log as well Signed-off-by: Steven Seungcheol Lee --- src/nvme/ioctl.h | 25 +++---------------------- src/nvme/types.h | 2 -- 2 files changed, 3 insertions(+), 24 deletions(-) diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 9ad2eb948a..d808b1109c 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -1182,8 +1182,7 @@ static inline int nvme_zns_identify_ctrl(int fd, struct nvme_zns_id_ctrl *id) * @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: Endurance group information - * @domid: Domain Identifier selection, if supported + * @lsi: Log Specific Identifier * @lsp: Log specific field * @uuidx: UUID selection, if supported * @rae: Retain asynchronous events @@ -1203,7 +1202,6 @@ struct nvme_get_log_args { __u32 nsid; enum nvme_csi csi; __u16 lsi; - __u16 domid; __u8 lsp; __u8 uuidx; bool rae; @@ -1235,7 +1233,6 @@ static inline int nvme_get_nsid_log(int fd, bool rae, .nsid = nsid, .csi = NVME_CSI_NVM, .lsi = NVME_LOG_LSI_NONE, - .domid = NVME_DOMID_NONE, .lsp = NVME_LOG_LSP_NONE, .uuidx = NVME_UUID_NONE, .rae = false, @@ -1380,7 +1377,6 @@ static inline int nvme_get_log_cmd_effects(int fd, enum nvme_csi csi, .nsid = NVME_NSID_ALL, .csi = csi, .lsi = NVME_LOG_LSI_NONE, - .domid = NVME_DOMID_NONE, .lsp = NVME_LOG_LSP_NONE, .uuidx = NVME_UUID_NONE, .rae = false, @@ -1428,7 +1424,6 @@ static inline int nvme_get_log_create_telemetry_host(int fd, .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, .lsi = NVME_LOG_LSI_NONE, - .domid = NVME_DOMID_NONE, .lsp = NVME_LOG_TELEM_HOST_LSP_CREATE, .uuidx = NVME_UUID_NONE, .rae = false, @@ -1465,7 +1460,6 @@ static inline int nvme_get_log_telemetry_host(int fd, __u64 offset, .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, .lsi = NVME_LOG_LSI_NONE, - .domid = NVME_DOMID_NONE, .lsp = NVME_LOG_TELEM_HOST_LSP_RETAIN, .uuidx = NVME_UUID_NONE, .rae = false, @@ -1497,7 +1491,6 @@ static inline int nvme_get_log_telemetry_ctrl(int fd, bool rae, .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, .lsi = NVME_LOG_LSI_NONE, - .domid = NVME_DOMID_NONE, .lsp = NVME_LOG_LSP_NONE, .uuidx = NVME_UUID_NONE, .rae = rae, @@ -1537,7 +1530,6 @@ static inline int nvme_get_log_endurance_group(int fd, __u16 endgid, .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, .lsi = endgid, - .domid = NVME_DOMID_NONE, .lsp = NVME_LOG_LSP_NONE, .uuidx = NVME_UUID_NONE, .rae = false, @@ -1570,7 +1562,6 @@ static inline int nvme_get_log_predictable_lat_nvmset(int fd, __u16 nvmsetid, .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, .lsi = nvmsetid, - .domid = NVME_DOMID_NONE, .lsp = NVME_LOG_LSP_NONE, .uuidx = NVME_UUID_NONE, .rae = false, @@ -1602,7 +1593,6 @@ static inline int nvme_get_log_predictable_lat_event(int fd, bool rae, .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, .lsi = NVME_LOG_LSI_NONE, - .domid = NVME_DOMID_NONE, .lsp = NVME_LOG_LSP_NONE, .uuidx = NVME_UUID_NONE, .rae = rae, @@ -1644,7 +1634,6 @@ 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, - .domid = NVME_DOMID_NONE, .lsp = lsp, .uuidx = NVME_UUID_NONE, .rae = false, @@ -1692,7 +1681,6 @@ static inline int nvme_get_log_lba_status(int fd, bool rae, .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, .lsi = NVME_LOG_LSI_NONE, - .domid = NVME_DOMID_NONE, .lsp = NVME_LOG_LSP_NONE, .uuidx = NVME_UUID_NONE, .rae = rae, @@ -1724,7 +1712,6 @@ static inline int nvme_get_log_endurance_grp_evt(int fd, bool rae, .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, .lsi = NVME_LOG_LSI_NONE, - .domid = NVME_DOMID_NONE, .lsp = NVME_LOG_LSP_NONE, .uuidx = NVME_UUID_NONE, .rae = rae, @@ -1776,7 +1763,6 @@ static inline int nvme_get_log_boot_partition(int fd, bool rae, .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, .lsi = NVME_LOG_LSI_NONE, - .domid = NVME_DOMID_NONE, .lsp = NVME_LOG_LSP_NONE, .uuidx = NVME_UUID_NONE, .rae = rae, @@ -1814,7 +1800,6 @@ static inline int nvme_get_log_discovery(int fd, bool rae, .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, .lsi = NVME_LOG_LSI_NONE, - .domid = NVME_DOMID_NONE, .lsp = NVME_LOG_LSP_NONE, .uuidx = NVME_UUID_NONE, .rae = rae, @@ -1846,8 +1831,7 @@ static inline int nvme_get_log_media_unit_stat(int fd, __u16 domid, .len = sizeof(*mus), .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, - .lsi = NVME_LOG_LSI_NONE, - .domid = domid, + .lsi = domid, .lsp = NVME_LOG_LSP_NONE, .uuidx = NVME_UUID_NONE, .rae = false, @@ -1878,8 +1862,7 @@ static inline int nvme_get_log_support_cap_config_list(int fd, __u16 domid, .len = sizeof(*cap), .nsid = NVME_NSID_NONE, .csi = NVME_CSI_NVM, - .lsi = NVME_LOG_LSI_NONE, - .domid = domid, + .lsi = domid, .lsp = NVME_LOG_LSP_NONE, .uuidx = NVME_UUID_NONE, .rae = false, @@ -1947,7 +1930,6 @@ static inline int nvme_get_log_zns_changed_zones(int fd, __u32 nsid, bool rae, .nsid = nsid, .csi = NVME_CSI_ZNS, .lsi = NVME_LOG_LSI_NONE, - .domid = NVME_DOMID_NONE, .lsp = NVME_LOG_LSP_NONE, .uuidx = NVME_UUID_NONE, .rae = rae, @@ -1979,7 +1961,6 @@ static inline int nvme_get_log_persistent_event(int fd, .nsid = NVME_NSID_ALL, .csi = NVME_CSI_NVM, .lsi = NVME_LOG_LSI_NONE, - .domid = NVME_DOMID_NONE, .lsp = NVME_LOG_LSP_NONE, .uuidx = NVME_UUID_NONE, .rae = false, diff --git a/src/nvme/types.h b/src/nvme/types.h index 669b95a691..a13d3c6345 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -54,7 +54,6 @@ * @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_DOMID_NONE: Use to omit a domid 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 @@ -99,7 +98,6 @@ enum nvme_constants { NVME_UUID_NONE = 0, NVME_CNTLID_NONE = 0, NVME_CNSSPECID_NONE = 0, - NVME_DOMID_NONE = 0, NVME_LOG_LSP_NONE = 0, NVME_LOG_LSI_NONE = 0, NVME_LOG_LPO_NONE = 0, From 58b923c6664ee843f7aac5aaf0dc7deb385b670e Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 3 Feb 2022 11:38:35 +0100 Subject: [PATCH 0447/1564] doc: Remove unused make.bat file The file was added by the initial doc experiment commit. It's not used. Remove it. Signed-off-by: Daniel Wagner --- doc/make.bat | 35 ----------------------------------- 1 file changed, 35 deletions(-) delete mode 100644 doc/make.bat diff --git a/doc/make.bat b/doc/make.bat deleted file mode 100644 index 2119f51099..0000000000 --- a/doc/make.bat +++ /dev/null @@ -1,35 +0,0 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=. -set BUILDDIR=_build - -if "%1" == "" goto help - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ - exit /b 1 -) - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% - -:end -popd From 022a63d4b56b75ab54806255882efd678480c5ad Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 3 Feb 2022 17:50:49 +0100 Subject: [PATCH 0448/1564] tree: Remove doublicated declaration nvme_host_get_hostnqn() and nvme_host_get_hostid() are declared twice. Remove one. Signed-off-by: Daniel Wagner --- src/nvme/tree.h | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/nvme/tree.h b/src/nvme/tree.h index 76c83fac1e..306fdfba46 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -92,22 +92,6 @@ nvme_root_t nvme_host_get_root(nvme_host_t h); nvme_host_t nvme_lookup_host(nvme_root_t r, const char *hostnqn, const char *hostid); -/** - * nvme_host_get_hostnqn() - Returns the host NQN - * @h: host - * - * Return: NVMe host NQN - */ -const char *nvme_host_get_hostnqn(nvme_host_t h); - -/** - * nvme_host_get_hostid() - Returns the host ID - * @h: host - * - * Return: NVMe Host ID - */ -const char *nvme_host_get_hostid(nvme_host_t h); - /** * nvme_host_get_dhchap_key() - return host key * @h: Host for which the key should be returned From 660d39348f1ebe5b0560a5d3c42ae23224a5254f Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Fri, 4 Feb 2022 12:14:54 +0100 Subject: [PATCH 0449/1564] types: Fix doc description Signed-off-by: Daniel Wagner --- src/nvme/types.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/nvme/types.h b/src/nvme/types.h index 1de4d3164e..cabb461eee 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -3604,7 +3604,7 @@ struct nvme_channel_config_desc { }; /** - * struct nvme_channel_config_desc - + * struct nvme_end_grp_chan_desc - * @egchans: Number of Channels * * Endurance group Channel Configuration Descriptor @@ -4165,10 +4165,10 @@ struct nvme_feat_host_behavior { }; /** - * enum - + * enum nvme_host_behavior_support - * @NVME_ENABLE_ACRE: */ -enum { +enum nvme_host_behavior_support { NVME_ENABLE_ACRE = 1 << 0, }; @@ -4315,11 +4315,11 @@ struct nvme_id_directives { }; /** - * enum - + * enum nvme_directive_types - * @NVME_ID_DIR_ID_BIT: Identify directive is supported * @NVME_ID_DIR_SD_BIT: Streams directive is supported */ -enum { +enum nvme_directive_types { NVME_ID_DIR_ID_BIT = 0, NVME_ID_DIR_SD_BIT = 1, }; From c83256dc7a1b5ce4b3c18bc8cb986fd9f0b4d014 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Thu, 3 Feb 2022 18:00:15 +0100 Subject: [PATCH 0450/1564] doc: Mesonize documentation generation Introduce a new config flag -Ddocs-build=true which controls if the build system should generate documentation or not. If disabled but -Ddocs=man is used then the pre compiled documentation will be installed. Furthmore, we are hooking up the sphinx tooling so that we generate the HTML documentation ouf of the rst files. Signed-off-by: Daniel Wagner --- doc/libnvme.rst | 18184 ---------------------------------------- doc/list-man-pages.sh | 15 + doc/meson.build | 107 +- doc/regen-man.sh | 19 - doc/regen-rst.sh | 9 - doc/update-docs.sh | 17 + meson_options.txt | 6 +- 7 files changed, 125 insertions(+), 18232 deletions(-) delete mode 100644 doc/libnvme.rst create mode 100755 doc/list-man-pages.sh delete mode 100755 doc/regen-man.sh delete mode 100755 doc/regen-rst.sh create mode 100755 doc/update-docs.sh diff --git a/doc/libnvme.rst b/doc/libnvme.rst deleted file mode 100644 index 05f87bae78..0000000000 --- a/doc/libnvme.rst +++ /dev/null @@ -1,18184 +0,0 @@ -.. _filters.h: - -**filters.h** - - -libnvme directory filter - -.. c:function:: int nvme_namespace_filter (const struct dirent *d) - - -**Parameters** - -``const struct dirent *d`` - - -.. c:function:: int nvme_paths_filter (const struct dirent *d) - - -**Parameters** - -``const struct dirent *d`` - - -.. c:function:: int nvme_ctrls_filter (const struct dirent *d) - - -**Parameters** - -``const struct dirent *d`` - - -.. c:function:: int nvme_subsys_filter (const struct dirent *d) - - -**Parameters** - -``const struct dirent *d`` - - -.. c:function:: int nvme_scan_subsystems (struct dirent ***subsys) - - -**Parameters** - -``struct dirent ***subsys`` - - -.. c:function:: int nvme_scan_subsystem_namespaces (nvme_subsystem_t s, struct dirent ***namespaces) - - -**Parameters** - -``nvme_subsystem_t s`` - -``struct dirent ***namespaces`` - - -.. c:function:: int nvme_scan_ctrls (struct dirent ***ctrls) - - -**Parameters** - -``struct dirent ***ctrls`` - - -.. c:function:: int nvme_scan_ctrl_namespace_paths (nvme_ctrl_t c, struct dirent ***namespaces) - - -**Parameters** - -``nvme_ctrl_t c`` - -``struct dirent ***namespaces`` - - -.. c:function:: int nvme_scan_ctrl_namespaces (nvme_ctrl_t c, struct dirent ***namespaces) - - -**Parameters** - -``nvme_ctrl_t c`` - -``struct dirent ***namespaces`` - - -.. _ioctl.h: - -**ioctl.h** - - -Linux NVMe ioctl interface functions - - - -.. c:type:: struct nvme_passthru_cmd - - -**Definition** - -:: - - struct nvme_passthru_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 result; - }; - -**Members** - -``opcode`` - Operation code, see :c:type:`enum nvme_io_opcodes ` and :c:type:`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 - -``result`` - Set on completion to the command's CQE DWORD 0 controller response - - - - - -.. c:type:: struct nvme_passthru_cmd64 - - -**Definition** - -:: - - 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; - }; - -**Members** - -``opcode`` - Operation code, see :c:type:`enum nvme_io_opcodes ` and :c:type:`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 impicit struct pad - -``result`` - Set on completion to the command's CQE DWORD 0-1 controller response - - - -.. c:function:: int nvme_submit_admin_passthru64 (int fd, struct nvme_passthru_cmd64 *cmd, __u64 *result) - - Submit a 64-bit nvme passthrough admin command - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``struct nvme_passthru_cmd64 *cmd`` - The nvme admin command to send - -``__u64 *result`` - Optional field to return the result from the CQE DW0-1 - -**Description** - -Uses NVME_IOCTL_ADMIN64_CMD for the ioctl request. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_admin_passthru64 (int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, __u32 data_len, void *data, __u32 metadata_len, void *metadata, __u32 timeout_ms, __u64 *result) - - Submit an nvme passthrough command - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u8 opcode`` - The nvme io command to send - -``__u8 flags`` - NVMe command flags (not used) - -``__u16 rsvd`` - Reserevd for future use - -``__u32 nsid`` - Namespace identifier - -``__u32 cdw2`` - Command dword 2 - -``__u32 cdw3`` - Command dword 3 - -``__u32 cdw10`` - Command dword 10 - -``__u32 cdw11`` - Command dword 11 - -``__u32 cdw12`` - Command dword 12 - -``__u32 cdw13`` - Command dword 13 - -``__u32 cdw14`` - Command dword 14 - -``__u32 cdw15`` - Command dword 15 - -``__u32 data_len`` - Length of the data transfered in this command in bytes - -``void *data`` - Pointer to user address of the data buffer - -``__u32 metadata_len`` - Length of metadata transfered in this command - -``void *metadata`` - Pointer to user address of the metadata buffer - -``__u32 timeout_ms`` - How long the kernel waits for the command to complete - -``__u64 *result`` - Optional field to return the result from the CQE dword 0 - -**Description** - -Parameterized form of nvme_submit_admin_passthru64(). This sets up and -submits a :c:type:`struct nvme_passthru_cmd64 `. - -Known values for **opcode** are defined in :c:type:`enum nvme_admin_opcode `. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_submit_admin_passthru (int fd, struct nvme_passthru_cmd *cmd, __u32 *result) - - Submit an nvme passthrough admin command - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``struct nvme_passthru_cmd *cmd`` - The nvme admin command to send - -``__u32 *result`` - Optional field to return the result from the CQE DW0 - -**Description** - -Uses NVME_IOCTL_ADMIN_CMD for the ioctl request. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_admin_passthru (int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, __u32 data_len, void *data, __u32 metadata_len, void *metadata, __u32 timeout_ms, __u32 *result) - - Submit an nvme passthrough command - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u8 opcode`` - The nvme io command to send - -``__u8 flags`` - NVMe command flags (not used) - -``__u16 rsvd`` - Reserevd for future use - -``__u32 nsid`` - Namespace identifier - -``__u32 cdw2`` - Command dword 2 - -``__u32 cdw3`` - Command dword 3 - -``__u32 cdw10`` - Command dword 10 - -``__u32 cdw11`` - Command dword 11 - -``__u32 cdw12`` - Command dword 12 - -``__u32 cdw13`` - Command dword 13 - -``__u32 cdw14`` - Command dword 14 - -``__u32 cdw15`` - Command dword 15 - -``__u32 data_len`` - Length of the data transfered in this command in bytes - -``void *data`` - Pointer to user address of the data buffer - -``__u32 metadata_len`` - Length of metadata transfered in this command - -``void *metadata`` - Pointer to user address of the metadata buffer - -``__u32 timeout_ms`` - How long the kernel waits for the command to complete - -``__u32 *result`` - Optional field to return the result from the CQE dword 0 - -**Description** - -Parameterized form of nvme_submit_admin_passthru(). This sets up and -submits a :c:type:`struct nvme_passthru_cmd `. - -Known values for **opcode** are defined in :c:type:`enum nvme_admin_opcode `. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_submit_io_passthru64 (int fd, struct nvme_passthru_cmd64 *cmd, __u64 *result) - - Submit a 64-bit nvme passthrough command - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``struct nvme_passthru_cmd64 *cmd`` - The nvme io command to send - -``__u64 *result`` - Optional field to return the result from the CQE DW0-1 - -**Description** - -Uses NVME_IOCTL_IO64_CMD for the ioctl request. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_io_passthru64 (int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, __u32 data_len, void *data, __u32 metadata_len, void *metadata, __u32 timeout_ms, __u64 *result) - - Submit an nvme io passthrough command - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u8 opcode`` - The nvme io command to send - -``__u8 flags`` - NVMe command flags (not used) - -``__u16 rsvd`` - Reserevd for future use - -``__u32 nsid`` - Namespace identifier - -``__u32 cdw2`` - Command dword 2 - -``__u32 cdw3`` - Command dword 3 - -``__u32 cdw10`` - Command dword 10 - -``__u32 cdw11`` - Command dword 11 - -``__u32 cdw12`` - Command dword 12 - -``__u32 cdw13`` - Command dword 13 - -``__u32 cdw14`` - Command dword 14 - -``__u32 cdw15`` - Command dword 15 - -``__u32 data_len`` - Length of the data transfered in this command in bytes - -``void *data`` - Pointer to user address of the data buffer - -``__u32 metadata_len`` - Length of metadata transfered in this command - -``void *metadata`` - Pointer to user address of the metadata buffer - -``__u32 timeout_ms`` - How long the kernel waits for the command to complete - -``__u64 *result`` - Optional field to return the result from the CQE dword 0 - -**Description** - -Parameterized form of nvme_submit_io_passthru64(). This sets up and submits -a :c:type:`struct nvme_passthru_cmd64 `. - -Known values for **opcode** are defined in :c:type:`enum nvme_io_opcode `. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_submit_io_passthru (int fd, struct nvme_passthru_cmd *cmd, __u32 *result) - - Submit an nvme passthrough command - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``struct nvme_passthru_cmd *cmd`` - The nvme io command to send - -``__u32 *result`` - Optional field to return the result from the CQE DW0 - -**Description** - -Uses NVME_IOCTL_IO_CMD for the ioctl request. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_io_passthru (int fd, __u8 opcode, __u8 flags, __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, __u32 cdw14, __u32 cdw15, __u32 data_len, void *data, __u32 metadata_len, void *metadata, __u32 timeout_ms, __u32 *result) - - Submit an nvme io passthrough command - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u8 opcode`` - The nvme io command to send - -``__u8 flags`` - NVMe command flags (not used) - -``__u16 rsvd`` - Reserevd for future use - -``__u32 nsid`` - Namespace identifier - -``__u32 cdw2`` - Command dword 2 - -``__u32 cdw3`` - Command dword 3 - -``__u32 cdw10`` - Command dword 10 - -``__u32 cdw11`` - Command dword 11 - -``__u32 cdw12`` - Command dword 12 - -``__u32 cdw13`` - Command dword 13 - -``__u32 cdw14`` - Command dword 14 - -``__u32 cdw15`` - Command dword 15 - -``__u32 data_len`` - Length of the data transfered in this command in bytes - -``void *data`` - Pointer to user address of the data buffer - -``__u32 metadata_len`` - Length of metadata transfered in this command - -``void *metadata`` - Pointer to user address of the metadata buffer - -``__u32 timeout_ms`` - How long the kernel waits for the command to complete - -``__u32 *result`` - Optional field to return the result from the CQE dword 0 - -**Description** - -Parameterized form of nvme_submit_io_passthru(). This sets up and submits -a :c:type:`struct nvme_passthru_cmd `. - -Known values for **opcode** are defined in :c:type:`enum nvme_io_opcode `. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_subsystem_reset (int fd) - - Initiate a subsystem reset - -**Parameters** - -``int fd`` - File descriptor of nvme device - -**Description** - -This should only be sent to controller handles, not to namespaces. - -**Return** - -Zero if a subsystem reset was initiated or -1 with errno set -otherwise. - - -.. c:function:: int nvme_ctrl_reset (int fd) - - Initiate a controller reset - -**Parameters** - -``int fd`` - File descriptor of nvme device - -**Description** - -This should only be sent to controller handles, not to namespaces. - -**Return** - -0 if a reset was initiated or -1 with errno set otherwise. - - -.. c:function:: int nvme_ns_rescan (int fd) - - Initiate a controller rescan - -**Parameters** - -``int fd`` - File descriptor of nvme device - -**Description** - -This should only be sent to controller handles, not to namespaces. - -**Return** - -0 if a rescan was initiated or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_nsid (int fd, __u32 *nsid) - - Retrieve the NSID from a namespace file descriptor - -**Parameters** - -``int fd`` - File descriptor of nvme namespace - -``__u32 *nsid`` - User pointer to namespace id - -**Description** - -This should only be sent to namespace handles, not to controllers. The -kernel's interface returns the nsid as the return value. This is unfortunate -for many architectures that are incapable of allowing distinguishing a -namespace id > 0x80000000 from a negative error number. - -**Return** - -0 if **nsid** was set successfully or -1 with errno set otherwise. - - - - -.. c:type:: struct nvme_identify_args - - Arguments for the NVMe Identify command - -**Definition** - -:: - - 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 nvmsetid; - __u16 domid; - __u8 uuidx; - }; - -**Members** - -``result`` - The command completion result from CQE dword0 - -``data`` - User space destination address to transfer the data - -``args_size`` - Size of :c:type:`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 - -``nvmsetid`` - The NVMe Set ID if CNS is 04h - -``domid`` - Domain identifier, if applicable - -``uuidx`` - UUID Index if controller supports this id selection method - - - -.. c:function:: int nvme_identify (struct nvme_identify_args *args) - - Send the NVMe Identify command - -**Parameters** - -``struct nvme_identify_args *args`` - :c:type:`struct nvme_identify_args ` argument structure - -**Description** - -The Identify command returns a data buffer that describes information about -the NVM subsystem, the controller or the namespace(s). - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_identify_ctrl (int fd, struct nvme_id_ctrl *id) - - Retrieves nvme identify controller - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``struct nvme_id_ctrl *id`` - User space destination address to transfer the data, - -**Description** - -Sends nvme identify with CNS value ``NVME_IDENTIFY_CNS_CTRL``. - -See :c:type:`struct nvme_id_ctrl ` for details on the data returned. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_identify_ns (int fd, __u32 nsid, struct nvme_id_ns *ns) - - Retrieves nvme identify namespace - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Namespace to identify - -``struct nvme_id_ns *ns`` - User space destination address to transfer the data - -**Description** - -If the Namespace Identifier (NSID) field specifies an active NSID, then the -Identify Namespace data structure is returned to the host for that specified -namespace. - -If the controller supports the Namespace Management capability and the NSID -field is set to ``NVME_NSID_ALL``, then the controller returns an Identify Namespace -data structure that specifies capabilities that are common across namespaces -for this controller. - -See :c:type:`struct nvme_id_ns ` for details on the structure returned. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_identify_allocated_ns (int fd, __u32 nsid, struct nvme_id_ns *ns) - - Same as nvme_identify_ns, but only for allocated namespaces - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Namespace to identify - -``struct nvme_id_ns *ns`` - User space destination address to transfer the data - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_identify_active_ns_list (int fd, __u32 nsid, struct nvme_ns_list *list) - - Retrieves active namespaces id list - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Return namespaces greater than this identifer - -``struct nvme_ns_list *list`` - User space destination address to transfer the data - -**Description** - -A list of 1024 namespace IDs is returned to the host containing NSIDs in -increasing order that are greater than the value specified in the Namespace -Identifier (nsid) field of the command. - -See :c:type:`struct nvme_ns_list ` for the definition of the returned structure. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_identify_allocated_ns_list (int fd, __u32 nsid, struct nvme_ns_list *list) - - Retrieves allocated namespace id list - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Return namespaces greater than this identifer - -``struct nvme_ns_list *list`` - User space destination address to transfer the data - -**Description** - -A list of 1024 namespace IDs is returned to the host containing NSIDs in -increasing order that are greater than the value specified in the Namespace -Identifier (nsid) field of the command. - -See :c:type:`struct nvme_ns_list ` for the definition of the returned structure. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_identify_ctrl_list (int fd, __u16 cntid, struct nvme_ctrl_list *cntlist) - - Retrieves identify controller list - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u16 cntid`` - Starting CNTLID to return in the list - -``struct nvme_ctrl_list *cntlist`` - User space destination address to transfer the data - -**Description** - -Up to 2047 controller identifiers is returned containing a controller -identifier greater than or equal to the controller identifier specified in -**cntid**. - -See :c:type:`struct nvme_ctrl_list ` for a definition of the structure returned. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_identify_nsid_ctrl_list (int fd, __u32 nsid, __u16 cntid, struct nvme_ctrl_list *cntlist) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Return controllers that are attached to this nsid - -``__u16 cntid`` - Starting CNTLID to return in the list - -``struct nvme_ctrl_list *cntlist`` - User space destination address to transfer the data - -**Description** - -Up to 2047 controller identifiers is returned containing a controller -identifier greater than or equal to the controller identifier specified in -**cntid**. - -See :c:type:`struct nvme_ctrl_list ` for a definition of the structure returned. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 - - -.. c:function:: int nvme_identify_ns_descs (int fd, __u32 nsid, struct nvme_ns_id_desc *descs) - - Retrieves namespace descriptor list - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - The namespace id to retrieve destriptors - -``struct nvme_ns_id_desc *descs`` - User space destination address to transfer the data - -**Description** - -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'. - -See :c:type:`struct nvme_ns_id_desc ` for the definition of the returned structure. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_identify_nvmset_list (int fd, __u16 nvmsetid, struct nvme_id_nvmset_list *nvmset) - - Retrieves NVM Set List - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u16 nvmsetid`` - NVM Set Identifier - -``struct nvme_id_nvmset_list *nvmset`` - User space destination address to transfer the data - -**Description** - -Retrieves an NVM Set List, :c:type:`struct nvme_id_nvmset_list `. The data structure -is an ordered list by NVM Set Identifier, starting with the first NVM Set -Identifier supported by the NVM subsystem that is equal to or greater than -the NVM Set Identifier. - -See :c:type:`struct nvme_id_nvmset_list ` for the defintion of the returned structure. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_identify_primary_ctrl (int fd, __u16 cntid, struct nvme_primary_ctrl_cap *cap) - - Retrieve NVMe Primary Controller identification - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u16 cntid`` - Return controllers starting at this identifier - -``struct nvme_primary_ctrl_cap *cap`` - User space destination buffer address to transfer the data - -**Description** - -See :c:type:`struct nvme_primary_ctrl_cap ` for the defintion of the returned structure, **cap**. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_identify_secondary_ctrl_list (int fd, __u32 nsid, __u16 cntid, struct nvme_secondary_ctrl_list *sc_list) - - Retrieves secondary controller list - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Namespace identifier - -``__u16 cntid`` - Return controllers starting at this identifier - -``struct nvme_secondary_ctrl_list *sc_list`` - User space destination address to transfer the data - -**Description** - -A Secondary Controller List is returned to the host for up to 127 secondary -controllers associated with the primary controller processing this command. -The list contains entries for controller identifiers greater than or equal -to the value specified in the Controller Identifier (cntid). - -See :c:type:`struct nvme_secondary_ctrls_list ` for a defintion of the returned -structure. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_identify_ns_granularity (int fd, struct nvme_id_ns_granularity_list *gr_list) - - Retrieves namespace granularity identification - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``struct nvme_id_ns_granularity_list *gr_list`` - User space destination address to transfer the data - -**Description** - -If the controller supports reporting of Namespace Granularity, then a -Namespace Granularity List is returned to the host for up to sixteen -namespace granularity descriptors - -See :c:type:`struct nvme_id_ns_granularity_list ` for the definition of the returned -structure. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_identify_uuid (int fd, struct nvme_id_uuid_list *uuid_list) - - Retrieves device's UUIDs - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``struct nvme_id_uuid_list *uuid_list`` - User space destination address to transfer the data - -**Description** - -Each UUID List entry is either 0h, the NVMe Invalid UUID, or a valid UUID. -Valid UUIDs are those which are non-zero and are not the NVMe Invalid UUID. - -See :c:type:`struct nvme_id_uuid_list ` for the definition of the returned structure. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_identify_ns_csi (int fd, __u32 nsid, enum nvme_csi csi, void *data) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Namespace to identify - -``enum nvme_csi csi`` - Command Set Identifier - -``void *data`` - User space destination address to transfer the data - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_identify_ctrl_csi (int fd, enum nvme_csi csi, void *data) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_csi csi`` - Command Set Identifier - -``void *data`` - User space destination address to transfer the data - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_identify_active_ns_list_csi (int fd, __u32 nsid, enum nvme_csi csi, struct nvme_ns_list *ns_list) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Return namespaces greater than this identifier - -``enum nvme_csi csi`` - Command Set Identifier - -``struct nvme_ns_list *ns_list`` - User space destination address to transfer the data - -**Description** - -A list of 1024 namespace IDs is returned to the host containing active -NSIDs in increasing order that are greater than the value specified in -the Namespace Identifier (nsid) field of the command and matching the -I/O Command Set specified in the **csi** argument. - -See :c:type:`struct nvme_ns_list ` for the definition of the returned structure. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_identify_allocated_ns_list_csi (int fd, __u32 nsid, enum nvme_csi csi, struct nvme_ns_list *ns_list) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Return namespaces greater than this identifier - -``enum nvme_csi csi`` - Command Set Identifier - -``struct nvme_ns_list *ns_list`` - User space destination address to transfer the data - -**Description** - -A list of 1024 namespace IDs is returned to the host containing allocated -NSIDs in increasing order that are greater than the value specified in -the **nsid** field of the command and matching the I/O Command Set -specified in the **csi** argument. - -See :c:type:`struct nvme_ns_list ` for the definition of the returned structure. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_identify_independent_identify_ns (int fd, __u32 nsid, struct nvme_id_independent_id_ns *ns) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Return namespaces greater than this identifier - -``struct nvme_id_independent_id_ns *ns`` - I/O Command Set Independent Identify Namespace data - structure - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_nvm_identify_ctrl (int fd, struct nvme_id_ctrl_nvm *id) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``struct nvme_id_ctrl_nvm *id`` - User space destination address to transfer the data - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_identify_domain_list (int fd, __u16 domid, struct nvme_id_domain_list *list) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u16 domid`` - Domain ID - -``struct nvme_id_domain_list *list`` - User space destiantion address to transfer data - -**Description** - -A list of 31 domain IDs is returned to the host containing domain -attributes in increasing order that are greater than the value -specified in the **domid** field. - -See :c:type:`struct nvme_identify_domain_attr ` for the definition of the -returned structure. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_identify_endurance_group_list (int fd, __u16 endgrp_id, struct nvme_id_endurance_group_list *list) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u16 endgrp_id`` - Endurance group identifier - -``struct nvme_id_endurance_group_list *list`` - Array of endurance group identifiers - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_identify_iocs (int fd, __u16 cntlid, struct nvme_id_iocs *iocs) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u16 cntlid`` - Controller ID - -``struct nvme_id_iocs *iocs`` - User space destination address to transfer the data - -**Description** - -Retrieves list of the controller's supported io command set vectors. See -:c:type:`struct nvme_id_iocs `. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_zns_identify_ns (int fd, __u32 nsid, struct nvme_zns_id_ns *data) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Namespace to identify - -``struct nvme_zns_id_ns *data`` - User space destination address to transfer the data - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_zns_identify_ctrl (int fd, struct nvme_zns_id_ctrl *id) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``struct nvme_zns_id_ctrl *id`` - User space destination address to transfer the data - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - - - -.. c:type:: struct nvme_get_log_args - - Arguments for the NVMe Admin Get Log command - -**Definition** - -:: - - 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; - __u16 domid; - __u8 lsp; - __u8 uuidx; - bool rae; - bool ot; - }; - -**Members** - -``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 :c:type:`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 :c:type:`enum nvme_csi ` for known values - -``lsi`` - Endurance group information - -``domid`` - Domain Identifier selection, if supported - -``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. - - - -.. c:function:: int nvme_get_log (struct nvme_get_log_args *args) - - NVMe Admin Get Log command - -**Parameters** - -``struct nvme_get_log_args *args`` - :c:type:`struct nvme_get_log_args ` argument structure - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_log_supported_log_pages (int fd, bool rae, struct nvme_supported_log_pages *log) - - Retrieve nmve supported log pages - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``bool rae`` - Retain asynchronous events - -``struct nvme_supported_log_pages *log`` - Array of LID supported and Effects data structures - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_log_error (int fd, unsigned nr_entries, bool rae, struct nvme_error_log_page *err_log) - - Retrieve nvme error log - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``unsigned nr_entries`` - Number of error log entries allocated - -``bool rae`` - Retain asynchronous events - -``struct nvme_error_log_page *err_log`` - Array of error logs of size 'entries' - -**Description** - -This log page describes extended error information for a command that -completed with error, or may report an error that is not specific to a -particular command. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_log_smart (int fd, __u32 nsid, bool rae, struct nvme_smart_log *smart_log) - - Retrieve nvme smart log - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Optional namespace identifier - -``bool rae`` - Retain asynchronous events - -``struct nvme_smart_log *smart_log`` - User address to store the smart log - -**Description** - -This log page provides SMART and general health information. The information -provided is over the life of the controller and is retained across power -cycles. To request the controller log page, the namespace identifier -specified is FFFFFFFFh. The controller may also support requesting the log -page on a per namespace basis, as indicated by bit 0 of the LPA field in the -Identify Controller data structure. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_log_fw_slot (int fd, bool rae, struct nvme_firmware_slot *fw_log) - - Retrieves the controller firmware log - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``bool rae`` - Retain asynchronous events - -``struct nvme_firmware_slot *fw_log`` - User address to store the log page - -**Description** - -This log page describes the firmware revision stored in each firmware slot -supported. The firmware revision is indicated as an ASCII string. The log -page also indicates the active slot number. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_log_changed_ns_list (int fd, bool rae, struct nvme_ns_list *ns_log) - - Retrieve namespace changed list - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``bool rae`` - Retain asynchronous events - -``struct nvme_ns_list *ns_log`` - User address to store the log page - -**Description** - -This log page describes namespaces attached to this controller that have -changed since the last time the namespace was identified, been added, or -deleted. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_log_cmd_effects (int fd, enum nvme_csi csi, struct nvme_cmd_effects_log *effects_log) - - Retrieve nvme command effects log - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_csi csi`` - Command Set Identifier - -``struct nvme_cmd_effects_log *effects_log`` - User address to store the effects log - -**Description** - -This log page describes the commands that the controller supports and the -effects of those commands on the state of the NVM subsystem. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_log_device_self_test (int fd, struct nvme_self_test_log *log) - - Retrieve the device self test log - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``struct nvme_self_test_log *log`` - Userspace address of the log payload - -**Description** - -The log page indicates the status of an in progress self test and the -percent complete of that operation, and the results of the previous 20 -self-test operations. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_log_create_telemetry_host (int fd, struct nvme_telemetry_log *log) - - Create host telemetry log - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``struct nvme_telemetry_log *log`` - Userspace address of the log payload - - -.. c:function:: int nvme_get_log_telemetry_host (int fd, __u64 offset, __u32 len, void *log) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u64 offset`` - Offset into the telemetry data - -``__u32 len`` - Length of provided user buffer to hold the log data in bytes - -``void *log`` - User address for log page data - -**Description** - -Retreives 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 -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_log_telemetry_ctrl (int fd, bool rae, __u64 offset, __u32 len, void *log) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``bool rae`` - Retain asynchronous events - -``__u64 offset`` - Offset into the telemetry data - -``__u32 len`` - Length of provided user buffer to hold the log data in bytes - -``void *log`` - User address for log page data - - -.. c:function:: int nvme_get_log_endurance_group (int fd, __u16 endgid, struct nvme_endurance_group_log *log) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u16 endgid`` - Starting group identifier to return in the list - -``struct nvme_endurance_group_log *log`` - User address to store the endurance log - -**Description** - -This log page indicates if an Endurance Group Event has occurred for a -particular Endurance Group. If an Endurance Group Event has occurred, the -details of the particular event are included in the Endurance Group -Information log page for that Endurance Group. An asynchronous event is -generated when an entry for an Endurance Group is newly added to this log -page. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_log_predictable_lat_nvmset (int fd, __u16 nvmsetid, struct nvme_nvmset_predictable_lat_log *log) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u16 nvmsetid`` - NVM set id - -``struct nvme_nvmset_predictable_lat_log *log`` - User address to store the predictable latency log - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_log_predictable_lat_event (int fd, bool rae, __u32 offset, __u32 len, void *log) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``bool rae`` - Retain asynchronous events - -``__u32 offset`` - -``__u32 len`` - -``void *log`` - - -.. c:function:: int nvme_get_log_ana (int fd, enum nvme_log_ana_lsp lsp, bool rae, __u64 offset, __u32 len, void *log) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_log_ana_lsp lsp`` - Log specific, see :c:type:`enum nvme_get_log_ana_lsp ` - -``bool rae`` - Retain asynchronous events - -``__u64 offset`` - Offset to the start of the log page - -``__u32 len`` - The allocated length of the log page - -``void *log`` - User address to store the ana log - -**Description** - -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 :c:type:`struct nvme_ana_rsp_hdr ` for the defintion of the returned structure. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_log_ana_groups (int fd, bool rae, __u32 len, struct nvme_ana_group_desc *log) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``bool rae`` - Retain asynchronous events - -``__u32 len`` - The allocated length of the log page - -``struct nvme_ana_group_desc *log`` - User address to store the ana group log - -**Description** - -See :c:type:`struct nvme_ana_group_desc ` for the defintion of the returned structure. - - -.. c:function:: int nvme_get_log_lba_status (int fd, bool rae, __u64 offset, __u32 len, void *log) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``bool rae`` - Retain asynchronous events - -``__u64 offset`` - Offset to the start of the log page - -``__u32 len`` - The allocated length of the log page - -``void *log`` - User address to store the log page - - -.. c:function:: int nvme_get_log_endurance_grp_evt (int fd, bool rae, __u32 offset, __u32 len, void *log) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``bool rae`` - Retain asynchronous events - -``__u32 offset`` - Offset to the start of the log page - -``__u32 len`` - The allocated length of the log page - -``void *log`` - User address to store the log page - - -.. c:function:: int nvme_get_log_fid_supported_effects (int fd, bool rae, struct nvme_fid_supported_effects_log *log) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``bool rae`` - Retain asynchronous events - -``struct nvme_fid_supported_effects_log *log`` - FID Supported and Effects data structure - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise - - -.. c:function:: int nvme_get_log_boot_partition (int fd, bool rae, __u8 lsp, __u32 len, struct nvme_boot_partition *part) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``bool rae`` - Retain asynchronous events - -``__u8 lsp`` - The log specified field of LID - -``__u32 len`` - The allocated size, minimum - struct nvme_boot_partition - -``struct nvme_boot_partition *part`` - User address to store the log page - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise - - -.. c:function:: int nvme_get_log_discovery (int fd, bool rae, __u32 offset, __u32 len, void *log) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``bool rae`` - Retain asynchronous events - -``__u32 offset`` - Offset of this log to retrieve - -``__u32 len`` - The allocated size for this portion of the log - -``void *log`` - User address to store the discovery log - -**Description** - -Supported only by fabrics discovery controllers, returning discovery -records. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_log_media_unit_stat (int fd, __u16 domid, struct nvme_media_unit_stat_log *mus) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u16 domid`` - Domain Identifier selection, if supported - -``struct nvme_media_unit_stat_log *mus`` - User address to store the Media Unit statistics log - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise - - -.. c:function:: int nvme_get_log_reservation (int fd, bool rae, struct nvme_resv_notification_log *log) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``bool rae`` - Retain asynchronous events - -``struct nvme_resv_notification_log *log`` - User address to store the reservation log - - -.. c:function:: int nvme_get_log_sanitize (int fd, bool rae, struct nvme_sanitize_log_page *log) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``bool rae`` - Retain asynchronous events - -``struct nvme_sanitize_log_page *log`` - User address to store the sanitize log - -**Description** - -The Sanitize Status log page reports sanitize operation time estimates and -information about the most recent sanitize operation. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_log_zns_changed_zones (int fd, __u32 nsid, bool rae, struct nvme_zns_changed_zone_log *log) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Namespace ID - -``bool rae`` - Retain asynchronous events - -``struct nvme_zns_changed_zone_log *log`` - User address to store the changed zone log - -**Description** - -The list of zones that have changed state due to an exceptional event. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_log_persistent_event (int fd, enum nvme_pevent_log_action action, __u32 size, void *pevent_log) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_pevent_log_action action`` - Action the controller should take during processing this command - -``__u32 size`` - Size of **pevent_log** - -``void *pevent_log`` - User address to store the persistent event log - - - - -.. c:type:: struct nvme_set_features_args - - Arguments for the NVMe Admin Set Feature command - -**Definition** - -:: - - struct nvme_set_features_args { - __u32 *result; - void *data; - int args_size; - int fd; - __u32 timeout; - __u32 nsid; - __u32 cdw11; - __u32 cdw12; - __u32 cdw15; - __u32 data_len; - bool save; - __u8 uuidx; - __u8 fid; - }; - -**Members** - -``result`` - The command completion result from CQE dword0 - -``data`` - User address of feature data, if applicable - -``args_size`` - Size of :c:type:`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 - - - -.. c:function:: int nvme_set_features (struct nvme_set_features_args *args) - - Set a feature attribute - -**Parameters** - -``struct nvme_set_features_args *args`` - :c:type:`struct nvme_set_features_args ` argument structure - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_set_features_data (int fd, __u8 fid, __u32 nsid, __u32 cdw11, bool save, __u32 data_len, void *data, __u32 *result) - - Helper function for **nvme_set_features\(\)** - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u8 fid`` - Feature identifier - -``__u32 nsid`` - Namespace ID, if applicable - -``__u32 cdw11`` - Value to set the feature to - -``bool save`` - Save value across power states - -``__u32 data_len`` - Length of feature data, if applicable, in bytes - -``void *data`` - User address of feature data, if applicable - -``__u32 *result`` - The command completion result from CQE dword0 - - -.. c:function:: int nvme_set_features_simple (int fd, __u8 fid, __u32 nsid, __u32 cdw11, bool save, __u32 *result) - - Helper functionn for **nvme_set_features\(\)** - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u8 fid`` - Feature identifier - -``__u32 nsid`` - Namespace ID, if applicable - -``__u32 cdw11`` - Value to set the feature to - -``bool save`` - Save value across power states - -``__u32 *result`` - The command completion result from CQE dword0 - - -.. c:function:: int nvme_set_features_arbitration (int fd, __u8 ab, __u8 lpw, __u8 mpw, __u8 hpw, bool save, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u8 ab`` - -``__u8 lpw`` - -``__u8 mpw`` - -``__u8 hpw`` - -``bool save`` - Save value across power states - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_set_features_power_mgmt (int fd, __u8 ps, __u8 wh, bool save, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u8 ps`` - -``__u8 wh`` - -``bool save`` - Save value across power states - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_set_features_lba_range (int fd, __u32 nsid, __u32 nr_ranges, bool save, struct nvme_lba_range_type *data, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Namespace ID - -``__u32 nr_ranges`` - Number of ranges in **data** - -``bool save`` - Save value across power states - -``struct nvme_lba_range_type *data`` - User address of feature data - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_set_features_temp_thresh (int fd, __u16 tmpth, __u8 tmpsel, enum nvme_feat_tmpthresh_thsel thsel, bool save, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u16 tmpth`` - -``__u8 tmpsel`` - -``enum nvme_feat_tmpthresh_thsel thsel`` - -``bool save`` - Save value across power states - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_set_features_err_recovery (int fd, __u32 nsid, __u16 tler, bool dulbe, bool save, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Namespace ID - -``__u16 tler`` - Time-limited error recovery value - -``bool dulbe`` - -``bool save`` - Save value across power states - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_set_features_volatile_wc (int fd, bool wce, bool save, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``bool wce`` - Write cache enable - -``bool save`` - Save value across power states - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_set_features_irq_coalesce (int fd, __u8 thr, __u8 time, bool save, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u8 thr`` - -``__u8 time`` - -``bool save`` - Save value across power states - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_set_features_irq_config (int fd, __u16 iv, bool cd, bool save, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u16 iv`` - -``bool cd`` - -``bool save`` - Save value across power states - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_set_features_write_atomic (int fd, bool dn, bool save, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``bool dn`` - -``bool save`` - Save value across power states - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_set_features_async_event (int fd, __u32 events, bool save, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 events`` - Events to enable - -``bool save`` - Save value across power states - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_set_features_auto_pst (int fd, bool apste, bool save, struct nvme_feat_auto_pst *apst, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``bool apste`` - -``bool save`` - Save value across power states - -``struct nvme_feat_auto_pst *apst`` - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_set_features_timestamp (int fd, bool save, __u64 timestamp) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``bool save`` - Save value across power states - -``__u64 timestamp`` - The current timestamp value to assign to this this feature - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_set_features_hctm (int fd, __u16 tmt2, __u16 tmt1, bool save, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u16 tmt2`` - -``__u16 tmt1`` - -``bool save`` - Save value across power states - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_set_features_nopsc (int fd, bool noppme, bool save, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``bool noppme`` - -``bool save`` - Save value across power states - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_set_features_rrl (int fd, __u8 rrl, __u16 nvmsetid, bool save, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u8 rrl`` - Read recovery level setting - -``__u16 nvmsetid`` - NVM set id - -``bool save`` - Save value across power states - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_set_features_plm_config (int fd, bool enable, __u16 nvmsetid, bool save, struct nvme_plm_config *data, __u32*result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``bool enable`` - -``__u16 nvmsetid`` - -``bool save`` - Save value across power states - -``struct nvme_plm_config *data`` - -``__u32*result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_set_features_plm_window (int fd, enum nvme_feat_plm_window_select sel, __u16 nvmsetid, bool save, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_feat_plm_window_select sel`` - -``__u16 nvmsetid`` - -``bool save`` - Save value across power states - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_set_features_lba_sts_interval (int fd, __u16 lsiri, __u16 lsipi, bool save, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u16 lsiri`` - -``__u16 lsipi`` - -``bool save`` - Save value across power states - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_set_features_host_behavior (int fd, bool save, struct nvme_feat_host_behavior *data) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``bool save`` - Save value across power states - -``struct nvme_feat_host_behavior *data`` - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_set_features_sanitize (int fd, bool nodrm, bool save, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``bool nodrm`` - -``bool save`` - Save value across power states - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_set_features_endurance_evt_cfg (int fd, __u16 endgid, __u8 egwarn, bool save, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u16 endgid`` - -``__u8 egwarn`` - Flags to enable warning, see :c:type:`enum nvme_eg_critical_warning_flags ` - -``bool save`` - Save value across power states - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_set_features_sw_progress (int fd, __u8 pbslc, bool save, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u8 pbslc`` - -``bool save`` - Save value across power states - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_set_features_host_id (int fd, bool exhid, bool save, __u8 *hostid) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``bool exhid`` - -``bool save`` - Save value across power states - -``__u8 *hostid`` - Host ID to set - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_set_features_resv_mask (int fd, __u32 mask, bool save, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 mask`` - -``bool save`` - Save value across power states - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_set_features_resv_persist (int fd, bool ptpl, bool save, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``bool ptpl`` - -``bool save`` - Save value across power states - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_set_features_write_protect (int fd, enum nvme_feat_nswpcfg_state state, bool save, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_feat_nswpcfg_state state`` - -``bool save`` - Save value across power states - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - - - -.. c:type:: struct nvme_get_features_args - - Arguments for the NVMe Admin Get Feature command - -**Definition** - -:: - - 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; - }; - -**Members** - -``result`` - The command completion result from CQE dword0 - -``data`` - User address of feature data, if applicable - -``args_size`` - Size of :c:type:`struct nvme_get_features_args ` - -``fd`` - File descriptor of nvme device - -``timeout`` - Timeout in ms - -``nsid`` - Namespace ID, if applicable - -``sel`` - Select which type of attribute to return, - see :c:type:`enum nvme_get_features_sel ` - -``cdw11`` - Feature specific command dword11 field - -``data_len`` - Length of feature data, if applicable, in bytes - -``fid`` - Feature identifier, see :c:type:`enum nvme_features_id ` - -``uuidx`` - UUID Index for differentiating vendor specific encoding - - - -.. c:function:: int nvme_get_features (struct nvme_get_features_args *args) - - Retrieve a feature attribute - -**Parameters** - -``struct nvme_get_features_args *args`` - :c:type:`struct nvme_get_features_args ` argument structure - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_features_data (int fd, enum nvme_features_id fid, __u32 nsid, __u32 data_len, void *data, __u32 *result) - - Helper function for **nvme_get_features\(\)** - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_features_id fid`` - Feature identifier - -``__u32 nsid`` - Namespace ID, if applicable - -``__u32 data_len`` - Length of feature data, if applicable, in bytes - -``void *data`` - User address of feature data, if applicable - -``__u32 *result`` - The command completion result from CQE dword0 - - -.. c:function:: int nvme_get_features_simple (int fd, enum nvme_features_id fid, __u32 nsid, __u32 *result) - - Helper function for **nvme_get_features\(\)** - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_features_id fid`` - Feature identifier - -``__u32 nsid`` - Namespace ID, if applicable - -``__u32 *result`` - The command completion result from CQE dword0 - - -.. c:function:: int nvme_get_features_arbitration (int fd, enum nvme_get_features_sel sel, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_features_power_mgmt (int fd, enum nvme_get_features_sel sel, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_features_lba_range (int fd, enum nvme_get_features_sel sel, struct nvme_lba_range_type *data, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``struct nvme_lba_range_type *data`` - User address of feature data, if applicable - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_features_temp_thresh (int fd, enum nvme_get_features_sel sel, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_features_err_recovery (int fd, enum nvme_get_features_sel sel, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_features_volatile_wc (int fd, enum nvme_get_features_sel sel, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_features_num_queues (int fd, enum nvme_get_features_sel sel, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_features_irq_coalesce (int fd, enum nvme_get_features_sel sel, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_features_irq_config (int fd, enum nvme_get_features_sel sel, __u16 iv, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``__u16 iv`` - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_features_write_atomic (int fd, enum nvme_get_features_sel sel, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_features_async_event (int fd, enum nvme_get_features_sel sel, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_features_auto_pst (int fd, enum nvme_get_features_sel sel, struct nvme_feat_auto_pst *apst, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``struct nvme_feat_auto_pst *apst`` - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_features_host_mem_buf (int fd, enum nvme_get_features_sel sel, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_features_timestamp (int fd, enum nvme_get_features_sel sel, struct nvme_timestamp *ts) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``struct nvme_timestamp *ts`` - Current timestamp - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_features_kato (int fd, enum nvme_get_features_sel sel, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_features_hctm (int fd, enum nvme_get_features_sel sel, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_features_nopsc (int fd, enum nvme_get_features_sel sel, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_features_rrl (int fd, enum nvme_get_features_sel sel, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_features_plm_config (int fd, enum nvme_get_features_sel sel, __u16 nvmsetid, struct nvme_plm_config *data, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``__u16 nvmsetid`` - NVM set id - -``struct nvme_plm_config *data`` - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_features_plm_window (int fd, enum nvme_get_features_sel sel, __u16 nvmsetid, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``__u16 nvmsetid`` - NVM set id - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_features_lba_sts_interval (int fd, enum nvme_get_features_sel sel, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_features_host_behavior (int fd, enum nvme_get_features_sel sel, struct nvme_feat_host_behavior *data, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``struct nvme_feat_host_behavior *data`` - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_features_sanitize (int fd, enum nvme_get_features_sel sel, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_features_endurance_event_cfg (int fd, enum nvme_get_features_sel sel, __u16 endgid, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``__u16 endgid`` - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_features_sw_progress (int fd, enum nvme_get_features_sel sel, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_features_host_id (int fd, enum nvme_get_features_sel sel, bool exhid, __u32 len, __u8 *hostid) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``bool exhid`` - -``__u32 len`` - Length of **hostid** - -``__u8 *hostid`` - Buffer for returned host ID - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_features_resv_mask (int fd, enum nvme_get_features_sel sel, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_features_resv_persist (int fd, enum nvme_get_features_sel sel, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_features_write_protect (int fd, __u32 nsid, enum nvme_get_features_sel sel, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Namespace ID - -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_features_iocs_profile (int fd, enum nvme_get_features_sel sel, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``enum nvme_get_features_sel sel`` - Select which type of attribute to return, see :c:type:`enum nvme_get_features_sel ` - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - - - -.. c:type:: struct nvme_format_nvm_args - - Arguments for the Format Nvme Namespace command - -**Definition** - -:: - - 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; - }; - -**Members** - -``result`` - The command completion result from CQE dword0 - -``args_size`` - Size of :c:type:`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 - - - -.. c:function:: int nvme_format_nvm (struct nvme_format_nvm_args *args) - - Format nvme namespace(s) - -**Parameters** - -``struct nvme_format_nvm_args *args`` - :c:type:`struct nvme_format_nvme_args ` argument structure - -**Description** - -The Format NVM command low level formats the NVM media. This command is used -by the host to change the LBA data size and/or metadata size. A low level -format may destroy all data and metadata associated with all namespaces or -only the specific namespace associated with the command - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - - - -.. c:type:: struct nvme_ns_mgmt_args - - Arguments for NVMe Namespace Management command - -**Definition** - -:: - - 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; - }; - -**Members** - -``result`` - NVMe command result - -``ns`` - Namespace identication descriptors - -``args_size`` - Size of :c:type:`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 - - - -.. c:function:: int nvme_ns_mgmt (struct nvme_ns_mgmt_args *args) - - Issue a Namespace management command - -**Parameters** - -``struct nvme_ns_mgmt_args *args`` - :c:type:`struct nvme_ns_mgmt_args ` Argument structure - - -.. c:function:: int nvme_ns_mgmt_create (int fd, struct nvme_id_ns *ns, __u32 *nsid, __u32 timeout, __u8 csi) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``struct nvme_id_ns *ns`` - Namespace identification that defines ns creation parameters - -``__u32 *nsid`` - On success, set to the namespace id that was created - -``__u32 timeout`` - Overide the default timeout to this value in milliseconds; - set to 0 to use the system default. - -``__u8 csi`` - Command Set Identifier - -**Description** - -On successful creation, the namespace exists in the subsystem, but is not -attached to any controller. Use the nvme_ns_attach_ctrls() to assign the -namespace to one or more controllers. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_ns_mgmt_delete (int fd, __u32 nsid) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Namespace identifier to delete - -**Description** - -It is recommended that a namespace being deleted is not attached to any -controller. Use the nvme_ns_detach_ctrls() first if the namespace is still -attached. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - - - -.. c:type:: struct nvme_ns_attach_args - - Arguments for Nvme Namespace Management command - -**Definition** - -:: - - 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; - }; - -**Members** - -``result`` - NVMe command result - -``ctrlist`` - Controller list to modify attachment state of nsid - -``args_size`` - Size of :c:type:`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 :c:type:`enum nvme_ns_attach_sel ` - - - -.. c:function:: int nvme_ns_attach (struct nvme_ns_attach_args *args) - - Attach or detach namespace to controller(s) - -**Parameters** - -``struct nvme_ns_attach_args *args`` - :c:type:`struct nvme_ns_attach_args ` Argument structure - - -.. c:function:: int nvme_ns_attach_ctrls (int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Namespace ID to attach - -``struct nvme_ctrl_list *ctrlist`` - Controller list to modify attachment state of nsid - - -.. c:function:: int nvme_ns_detach_ctrls (int fd, __u32 nsid, struct nvme_ctrl_list *ctrlist) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Namespace ID to detach - -``struct nvme_ctrl_list *ctrlist`` - Controller list to modify attachment state of nsid - - - - -.. c:type:: struct nvme_fw_download_args - - Arguments for the NVMe Firmware Download command - -**Definition** - -:: - - struct nvme_fw_download_args { - __u32 *result; - void *data; - int args_size; - int fd; - __u32 timeout; - __u32 offset; - __u32 data_len; - }; - -**Members** - -``result`` - The command completion result from CQE dword0 - -``data`` - Userspace address of the firmware data - -``args_size`` - Size of :c:type:`struct nvme_fw_download_args ` - -``fd`` - File descriptor of nvme device - -``timeout`` - Timeout in ms - -``offset`` - Offset in the firmware data - -``data_len`` - Length of data in this command in bytes - - - -.. c:function:: int nvme_fw_download (struct nvme_fw_download_args *args) - - Download part or all of a firmware image to the controller - -**Parameters** - -``struct nvme_fw_download_args *args`` - :c:type:`struct nvme_fw_download_args ` argument structure - -**Description** - -The Firmware Image Download command downloads all or a portion of an image -for a future update to the controller. The Firmware Image Download command -downloads a new image (in whole or in part) to the controller. - -The image may be constructed of multiple pieces that are individually -downloaded with separate Firmware Image Download commands. Each Firmware -Image Download command includes a Dword Offset and Number of Dwords that -specify a dword range. - -The new firmware image is not activated as part of the Firmware Image -Download command. Use the nvme_fw_commit() to activate a newly downloaded -image. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - - - -.. c:type:: struct nvme_fw_commit_args - - Arguments for the NVMe Firmware Commit command - -**Definition** - -:: - - struct nvme_fw_commit_args { - __u32 *result; - int args_size; - int fd; - __u32 timeout; - enum nvme_fw_commit_ca action; - __u8 slot; - bool bpid; - }; - -**Members** - -``result`` - The command completion result from CQE dword0 - -``args_size`` - Size of :c:type:`struct nvme_fw_commit_args ` - -``fd`` - File descriptor of nvme device - -``timeout`` - Timeout in ms - -``action`` - Action to use for the firmware image, see :c:type:`enum nvme_fw_commit_ca ` - -``slot`` - Firmware slot to commit the downloaded image - -``bpid`` - Set to true to select the boot partition id - - - -.. c:function:: int nvme_fw_commit (struct nvme_fw_commit_args *args) - - Commit firmware using the specified action - -**Parameters** - -``struct nvme_fw_commit_args *args`` - :c:type:`struct nvme_fw_commit_args ` argument structure - -**Description** - -The Firmware Commit command modifies the firmware image or Boot Partitions. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. The command -status response may specify additional reset actions required to complete -the commit process. - - - - -.. c:type:: struct nvme_security_send_args - - Arguments for the NVMe Security Send command - -**Definition** - -:: - - 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; - }; - -**Members** - -``result`` - The command completion result from CQE dword0 - -``data`` - Security data payload to send - -``args_size`` - Size of :c:type:`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 - - - -.. c:function:: int nvme_security_send (struct nvme_security_send_args *args) - - -**Parameters** - -``struct nvme_security_send_args *args`` - :c:type:`struct nvme_security_send ` argument structure - -**Description** - -The Security Send command transfers security protocol data to the -controller. The data structure transferred to the controller as part of this -command contains security protocol specific commands to be performed by the -controller. The data structure transferred may also contain data or -parameters associated with the security protocol commands. - -The security data is protocol specific and is not defined by the NVMe -specification. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - - - -.. c:type:: struct nvme_security_receive_args - - Arguments for the NVMe Security Receive command - -**Definition** - -:: - - 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; - }; - -**Members** - -``result`` - The command completion result from CQE dword0 - -``data`` - Security data payload to send - -``args_size`` - Size of :c:type:`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 - - - -.. c:function:: int nvme_security_receive (struct nvme_security_receive_args *args) - - -**Parameters** - -``struct nvme_security_receive_args *args`` - :c:type:`struct nvme_security_recevice ` argument structure - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - - - -.. c:type:: struct nvme_get_lba_status_args - - Arguments for the NVMe Get LBA Status command - -**Definition** - -:: - - 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; - }; - -**Members** - -``slba`` - Starting logical block address to check statuses - -``result`` - The command completion result from CQE dword0 - -``lbas`` - Data payload to return status descriptors - -``args_size`` - Size of :c:type:`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 :c:type:`enum nvme_lba_status_atype ` - -``rl`` - Range length from slba to perform the action - - - -.. c:function:: int nvme_get_lba_status (struct nvme_get_lba_status_args *args) - - Retrieve information on possibly unrecoverable LBAs - -**Parameters** - -``struct nvme_get_lba_status_args *args`` - :c:type:`struct nvme_get_lba_status_args ` argument structure - -**Description** - -The Get LBA Status command requests information about Potentially -Unrecoverable LBAs. Refer to the specification for action type descriptions. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - - - -.. c:type:: struct nvme_directive_send_args - - Arguments for the NVMe Directive Send command - -**Definition** - -:: - - 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; - }; - -**Members** - -``result`` - If successful, the CQE dword0 value - -``data`` - Data payload to to be send - -``args_size`` - Size of :c:type:`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 :c:type:`enum nvme_directive_send_doper ` - -``dtype`` - Directive type, see :c:type:`enum nvme_directive_dtype ` - -``cdw12`` - Directive specific command dword12 - -``data_len`` - Length of data payload in bytes - -``dspec`` - Directive specific field - - - -.. c:function:: int nvme_directive_send (struct nvme_directive_send_args *args) - - Send directive command - -**Parameters** - -``struct nvme_directive_send_args *args`` - :c:type:`struct nvme_directive_send_args ` argument structure - -**Description** - -Directives is a mechanism to enable host and NVM subsystem or controller -information exchange. The Directive Send command transfers data related to a -specific Directive Type from the host to the controller. - -See the NVMe specification for more information. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_directive_send_id_endir (int fd, __u32 nsid, bool endir, enum nvme_directive_dtype dtype, struct nvme_id_directives *id) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - -``bool endir`` - -``enum nvme_directive_dtype dtype`` - -``struct nvme_id_directives *id`` - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_directive_send_stream_release_identifier (int fd, __u32 nsid, __u16 stream_id) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Namespace ID - -``__u16 stream_id`` - Stream identifier - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_directive_send_stream_release_resource (int fd, __u32 nsid) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Namespace ID - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - - - -.. c:type:: struct nvme_directive_recv_args - - Arguments for the NVMe Directive Receive command - -**Definition** - -:: - - 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; - }; - -**Members** - -``result`` - If successful, the CQE dword0 value - -``data`` - Usespace address of data payload - -``args_size`` - Size of :c:type:`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 :c:type:`enum nvme_directive_send_doper ` - -``dtype`` - Directive type, see :c:type:`enum nvme_directive_dtype ` - -``cdw12`` - Directive specific command dword12 - -``data_len`` - Length of data payload in bytes - -``dspec`` - Directive specific field - - - -.. c:function:: int nvme_directive_recv (struct nvme_directive_recv_args *args) - - Receive directive specific data - -**Parameters** - -``struct nvme_directive_recv_args *args`` - :c:type:`struct nvme_directive_recv_args ` argument structure - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_directive_recv_identify_parameters (int fd, __u32 nsid, struct nvme_id_directives *id) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Namespace ID - -``struct nvme_id_directives *id`` - Identify parameters buffer - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_directive_recv_stream_parameters (int fd, __u32 nsid, struct nvme_streams_directive_params *parms) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Namespace ID - -``struct nvme_streams_directive_params *parms`` - Streams directive parameters buffer - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_directive_recv_stream_status (int fd, __u32 nsid, unsigned nr_entries, struct nvme_streams_directive_status *id) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Namespace ID - -``unsigned nr_entries`` - Number of streams to receive - -``struct nvme_streams_directive_status *id`` - Stream status buffer - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_directive_recv_stream_allocate (int fd, __u32 nsid, __u16 nsr, __u32 *result) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Namespace ID - -``__u16 nsr`` - -``__u32 *result`` - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - - - -.. c:type:: struct nvme_capacity_mgmt_args - - Arguments for the NVMe Capacity Management command - -**Definition** - -:: - - struct nvme_capacity_mgmt_args { - __u32 *result; - int args_size; - int fd; - __u32 timeout; - __u32 cdw11; - __u32 cdw12; - __u16 element_id; - __u8 op; - }; - -**Members** - -``result`` - If successful, the CQE dword0 value - -``args_size`` - Size of :c:type:`struct nvme_capacity_mgmt_args ` - -``fd`` - File descriptor of nvme device - -``timeout`` - Timeout in ms - -``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 - -``element_id`` - Value specific to the value of the Operation field - -``op`` - Operation to be performed by the controller - - - -.. c:function:: int nvme_capacity_mgmt (struct nvme_capacity_mgmt_args *args) - - -**Parameters** - -``struct nvme_capacity_mgmt_args *args`` - :c:type:`struct nvme_capacity_mgmt_args ` argument structure - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - - - -.. c:type:: struct nvme_lockdown_args - - Arguments for the NVME Lockdown command - -**Definition** - -:: - - struct nvme_lockdown_args { - __u32 *result; - int args_size; - int fd; - __u32 timeout; - __u8 scp; - __u8 prhbt; - __u8 ifc; - __u8 ofi; - __u8 uuidx; - }; - -**Members** - -``result`` - The command completion result from CQE dword0 - -``args_size`` - Size of :c:type:`struct nvme_lockdown_args ` - -``fd`` - File descriptor of nvme device - -``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 - - - -.. c:function:: int nvme_lockdown (struct nvme_lockdown_args *args) - - Issue lockdown command - -**Parameters** - -``struct nvme_lockdown_args *args`` - :c:type:`struct nvme_lockdown_args ` argument structure - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - - - -.. c:type:: struct nvme_set_property_args - - Arguments for NVMe Set Property command - -**Definition** - -:: - - struct nvme_set_property_args { - __u64 value; - __u32 *result; - int args_size; - int fd; - __u32 timeout; - int offset; - }; - -**Members** - -``value`` - The value to set the property - -``result`` - The command completion result from CQE dword0 - -``args_size`` - Size of :c:type:`struct nvme_set_property_args ` - -``fd`` - File descriptor of nvme device - -``timeout`` - Timeout in ms - -``offset`` - Property offset from the base to set - - - -.. c:function:: int nvme_set_property (struct nvme_set_property_args *args) - - Set controller property - -**Parameters** - -``struct nvme_set_property_args *args`` - :c:type:`struct nvme_set_property_args ` argument structure - -**Description** - -This is an NVMe-over-Fabrics specific command, not applicable to PCIe. These -properties align to the PCI MMIO controller registers. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - - - -.. c:type:: struct nvme_get_property_args - - Arguments for NVMe Get Property command - -**Definition** - -:: - - struct nvme_get_property_args { - __u64 *value; - int args_size; - int fd; - __u32 timeout; - int offset; - }; - -**Members** - -``value`` - Where the property's value will be stored on success - -``args_size`` - Size of :c:type:`struct nvme_get_property_args ` - -``fd`` - File descriptor of nvme device - -``timeout`` - Timeout in ms - -``offset`` - Property offset from the base to retrieve - - - -.. c:function:: int nvme_get_property (struct nvme_get_property_args *args) - - Get a controller property - -**Parameters** - -``struct nvme_get_property_args *args`` - :c:type:`struct nvme_get_propert_args ` argument structure - -**Description** - -This is an NVMe-over-Fabrics specific command, not applicable to PCIe. These -properties align to the PCI MMIO controller registers. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - - - -.. c:type:: struct nvme_sanitize_nvm_args - - Arguments for the NVMe Sanitize NVM command - -**Definition** - -:: - - 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; - }; - -**Members** - -``result`` - The command completion result from CQE dword0 - -``args_size`` - Size of :c:type:`struct nvme_sanitize_nvm_args ` - -``fd`` - File descriptor of nvme device - -``timeout`` - Timeout in ms - -``sanact`` - Sanitize action, see :c:type:`enum nvme_sanitize_sanact ` - -``ovrpat`` - Overwrite pattern - -``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 - - - -.. c:function:: int nvme_sanitize_nvm (struct nvme_sanitize_nvm_args *args) - - Start a sanitize operation - -**Parameters** - -``struct nvme_sanitize_nvm_args *args`` - :c:type:`struct nvme_sanitize_nvm_args ` argument structure - -**Description** - -A sanitize operation alters all user data in the NVM subsystem such that -recovery of any previous user data from any cache, the non-volatile media, -or any Controller Memory Buffer is not possible. - -The Sanitize command starts a sanitize operation or to recover from a -previously failed sanitize operation. The sanitize operation types that may -be supported are Block Erase, Crypto Erase, and Overwrite. All sanitize -operations are processed in the background, i.e., completion of the sanitize -command does not indicate completion of the sanitize operation. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - - - -.. c:type:: struct nvme_dev_self_test_args - - Arguments for the NVMe Device Self Test command - -**Definition** - -:: - - struct nvme_dev_self_test_args { - __u32 *result; - int args_size; - int fd; - __u32 timeout; - __u32 nsid; - enum nvme_dst_stc stc; - }; - -**Members** - -``result`` - The command completion result from CQE dword0 - -``args_size`` - Size of :c:type:`struct nvme_dev_self_test_args ` - -``fd`` - File descriptor of nvme device - -``timeout`` - Timeout in ms - -``nsid`` - Namespace ID to test - -``stc`` - Self test code, see :c:type:`enum nvme_dst_stc ` - - - -.. c:function:: int nvme_dev_self_test (struct nvme_dev_self_test_args *args) - - Start or abort a self test - -**Parameters** - -``struct nvme_dev_self_test_args *args`` - :c:type:`struct nvme_dev_self_test ` argument structure - -**Description** - -The Device Self-test command starts a device self-test operation or abort a -device self-test operation. A device self-test operation is a diagnostic -testing sequence that tests the integrity and functionality of the -controller and may include testing of the media associated with namespaces. -The controller may return a response to this command immediately while -running the self-test in the background. - -Set the 'nsid' field to 0 to not include namepsaces in the test. Set to -0xffffffff to test all namespaces. All other values tests a specific -namespace, if present. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - - - -.. c:type:: struct nvme_virtual_mgmt_args - - Arguments for the NVMe Virtualization resource management command - -**Definition** - -:: - - 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; - }; - -**Members** - -``result`` - If successful, the CQE dword0 - -``args_size`` - Size of :c:type:`struct nvme_virtual_mgmt_args ` - -``fd`` - File descriptor of nvme device - -``timeout`` - Timeout in ms - -``act`` - Virtual resource action, see :c:type:`enum nvme_virt_mgmt_act ` - -``rt`` - Resource type to modify, see :c:type:`enum nvme_virt_mgmt_rt ` - -``cntlid`` - Controller id for which resources are bing modified - -``nr`` - Number of resources being allocated or assigned - - - -.. c:function:: int nvme_virtual_mgmt (struct nvme_virtual_mgmt_args *args) - - Virtualization resource management - -**Parameters** - -``struct nvme_virtual_mgmt_args *args`` - :c:type:`struct nvme_virtual_mgmt_args ` argument structure - -**Description** - -The Virtualization Management command is supported by primary controllers -that support the Virtualization Enhancements capability. This command is -used for several functions: - - - Modifying Flexible Resource allocation for the primary controller - - Assigning Flexible Resources for secondary controllers - - Setting the Online and Offline state for secondary controllers - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_flush (int fd, __u32 nsid) - - Send an nvme flush command - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Namespace identifier - -**Description** - -The Flush command requests that the contents of volatile write cache be made -non-volatile. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - - - -.. c:type:: struct nvme_io_args - - Arguments for NVMe I/O commands - -**Definition** - -:: - - 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; - __u8 dsm; - __u8 dspec; - }; - -**Members** - -``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 :c:type:`struct nvme_io_args ` - -``fd`` - File descriptor of nvme device - -``timeout`` - Timeout in ms - -``nsid`` - Namespace ID - -``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. - -``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 :c:type:`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. - -``dsm`` - Data set management attributes, see :c:type:`enum nvme_io_dsm_flags ` - -``dspec`` - Directive specific value - - - -.. c:function:: int nvme_io (struct nvme_io_args *args, __u8 opcode) - - Submit an nvme user I/O command - -**Parameters** - -``struct nvme_io_args *args`` - :c:type:`struct nvme_io_args ` argument structure - -``__u8 opcode`` - Opcode to execute - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_read (struct nvme_io_args *args) - - Submit an nvme user read command - -**Parameters** - -``struct nvme_io_args *args`` - :c:type:`struct nvme_io_args ` argument structure - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_write (struct nvme_io_args *args) - - Submit an nvme user write command - -**Parameters** - -``struct nvme_io_args *args`` - :c:type:`struct nvme_io_args ` argument structure - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_compare (struct nvme_io_args *args) - - Submit an nvme user compare command - -**Parameters** - -``struct nvme_io_args *args`` - :c:type:`struct nvme_io_args ` argument structure - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_write_zeros (struct nvme_io_args *args) - - Submit an nvme write zeroes command - -**Parameters** - -``struct nvme_io_args *args`` - :c:type:`struct nvme_io_args ` argument structure - -**Description** - -The Write Zeroes command sets a range of logical blocks to zero. After -successful completion of this command, the value returned by subsequent -reads of logical blocks in this range shall be all bytes cleared to 0h until -a write occurs to this LBA range. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_write_uncorrectable (struct nvme_io_args *args) - - Submit an nvme write uncorrectable command - -**Parameters** - -``struct nvme_io_args *args`` - :c:type:`struct nvme_io_args ` argument structure - -**Description** - -The Write Uncorrectable command marks a range of logical blocks as invalid. -When the specified logical block(s) are read after this operation, a failure -is returned with Unrecovered Read Error status. To clear the invalid logical -block status, a write operation on those logical blocks is required. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_verify (struct nvme_io_args *args) - - Send an nvme verify command - -**Parameters** - -``struct nvme_io_args *args`` - :c:type:`struct nvme_io_args ` argument structure - -**Description** - -The Verify command verifies integrity of stored information by reading data -and metadata, if applicable, for the LBAs indicated without transferring any -data or metadata to the host. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - - - -.. c:type:: struct nvme_dsm_args - - Arguments for the NVMe Dataset Management command - -**Definition** - -:: - - 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; - }; - -**Members** - -``result`` - The command completion result from CQE dword0 - -``dsm`` - The data set management attributes - -``args_size`` - Size of :c:type:`struct nvme_dsm_args ` - -``fd`` - File descriptor of nvme device - -``timeout`` - Timeout in ms - -``nsid`` - Namespace identifier - -``attrs`` - DSM attributes, see :c:type:`enum nvme_dsm_attributes ` - -``nr_ranges`` - Number of block ranges in the data set management attributes - - - -.. c:function:: int nvme_dsm (struct nvme_dsm_args *args) - - Send an nvme data set management command - -**Parameters** - -``struct nvme_dsm_args *args`` - :c:type:`struct nvme_dsm_args ` argument structure - -**Description** - -The Dataset Management command is used by the host to indicate attributes -for ranges of logical blocks. This includes attributes like frequency that -data is read or written, access size, and other information that may be used -to optimize performance and reliability, and may be used to -deallocate/unmap/trim those logical blocks. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - - - -.. c:type:: struct nvme_copy_args - - Arguments for the NVMe Copy command - -**Definition** - -:: - - 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; - }; - -**Members** - -``sdlba`` - Start destination LBA - -``result`` - The command completion result from CQE dword0 - -``copy`` - Range descriptior - -``args_size`` - Size of :c:type:`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 - - - -.. c:function:: int nvme_copy (struct nvme_copy_args *args) - - -**Parameters** - -``struct nvme_copy_args *args`` - :c:type:`struct nvme_copy_args ` argument structure - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - - - -.. c:type:: struct nvme_resv_acquire_args - - Arguments for the NVMe Reservation Acquire Comand - -**Definition** - -:: - - 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; - }; - -**Members** - -``crkey`` - The current reservation key associated with the host - -``nrkey`` - The reservation key to be unregistered from the namespace if - the action is preempt - -``result`` - The command completion result from CQE dword0 - -``args_size`` - Size of :c:type:`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 :c:type:`enum nvme_resv_rtype ` - -``racqa`` - The action that is performed by the command, see :c:type:`enum nvme_resv_racqa ` - -``iekey`` - Set to ignore the existing key - - - -.. c:function:: int nvme_resv_acquire (struct nvme_resv_acquire_args *args) - - Send an nvme reservation acquire - -**Parameters** - -``struct nvme_resv_acquire_args *args`` - :c:type:`struct nvme_resv_acquire ` argument structure - -**Description** - -The Reservation Acquire command acquires a reservation on a namespace, -preempt a reservation held on a namespace, and abort a reservation held on a -namespace. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - - - -.. c:type:: struct nvme_resv_register_args - - Arguments for the NVMe Reservation Register command - -**Definition** - -:: - - 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; - }; - -**Members** - -``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 :c:type:`struct nvme_resv_register_args ` - -``fd`` - File descriptor of nvme device - -``timeout`` - Timeout in ms - -``nsid`` - Namespace identifier - -``rrega`` - The registration action, see :c:type:`enum nvme_resv_rrega ` - -``cptpl`` - Change persist through power loss, see :c:type:`enum nvme_resv_cptpl ` - -``iekey`` - Set to ignore the existing key - - - -.. c:function:: int nvme_resv_register (struct nvme_resv_register_args *args) - - Send an nvme reservation register - -**Parameters** - -``struct nvme_resv_register_args *args`` - :c:type:`struct nvme_resv_register_args ` argument structure - -**Description** - -The Reservation Register command registers, unregisters, or replaces a -reservation key. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - - - -.. c:type:: struct nvme_resv_release_args - - Arguments for the NVMe Reservation Release Command - -**Definition** - -:: - - 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; - }; - -**Members** - -``crkey`` - The current reservation key to release - -``result`` - The command completion result from CQE dword0 - -``args_size`` - Size of :c:type:`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 :c:type:`enum nvme_resv_rtype ` - -``rrela`` - Reservation releast action, see :c:type:`enum nvme_resv_rrela ` - -``iekey`` - Set to ignore the existing key - - - -.. c:function:: int nvme_resv_release (struct nvme_resv_release_args *args) - - Send an nvme reservation release - -**Parameters** - -``struct nvme_resv_release_args *args`` - :c:type:`struct nvme_resv_release_args ` argument structure - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - - - -.. c:type:: struct nvme_resv_report_args - - Arguments for the NVMe Reservation Report command - -**Definition** - -:: - - 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; - }; - -**Members** - -``result`` - The command completion result from CQE dword0 - -``report`` - The user space destination address to store the reservation - report - -``args_size`` - Size of :c:type:`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 - - - -.. c:function:: int nvme_resv_report (struct nvme_resv_report_args *args) - - Send an nvme reservation report - -**Parameters** - -``struct nvme_resv_report_args *args`` - struct nvme_resv_report_args argument structure - -**Description** - -Returns a Reservation Status data structure to memory that describes the -registration and reservation status of a namespace. See the defintion for -the returned structure, :c:type:`struct nvme_reservation_status `, for more details. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - - - -.. c:type:: struct nvme_zns_mgmt_send_args - - Arguments for the NVMe ZNS Management Send command - -**Definition** - -:: - - 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; - }; - -**Members** - -``slba`` - Starting logical block address - -``result`` - The command completion result from CQE dword0 - -``data`` - Userspace address of the data - -``args_size`` - Size of :c:type:`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 - - - -.. c:function:: int nvme_zns_mgmt_send (struct nvme_zns_mgmt_send_args *args) - - -**Parameters** - -``struct nvme_zns_mgmt_send_args *args`` - :c:type:`struct nvme_zns_mgmt_send_args ` argument structure - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - - - -.. c:type:: struct nvme_zns_mgmt_recv_args - - Arguments for the NVMe ZNS Management Receive command - -**Definition** - -:: - - 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; - }; - -**Members** - -``slba`` - Starting logical block address - -``result`` - The command completion result from CQE dword0 - -``data`` - Userspace address of the data - -``args_size`` - Size of :c:type:`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 - - - -.. c:function:: int nvme_zns_mgmt_recv (struct nvme_zns_mgmt_recv_args *args) - - -**Parameters** - -``struct nvme_zns_mgmt_recv_args *args`` - :c:type:`struct nvme_zns_mgmt_recv_args ` argument structure - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_zns_report_zones (int fd, __u32 nsid, __u64 slba, enum nvme_zns_report_options opts, bool extended, bool partial, __u32 data_len, void *data, __u32 timeout, __u32 *result) - - Return the list of zones - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Namespace ID - -``__u64 slba`` - Starting LBA - -``enum nvme_zns_report_options opts`` - Reporting options - -``bool extended`` - Extended report - -``bool partial`` - Partial report requested - -``__u32 data_len`` - Length of the data buffer - -``void *data`` - Userspace address of the report zones data - -``__u32 timeout`` - timeout in ms - -``__u32 *result`` - The command completion result from CQE dword0 - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - - - -.. c:type:: struct nvme_zns_append_args - - Arguments for the NVMe ZNS Append command - -**Definition** - -:: - - 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; - }; - -**Members** - -``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 :c:type:`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 - - - -.. c:function:: int nvme_zns_append (struct nvme_zns_append_args *args) - - Append data to a zone - -**Parameters** - -``struct nvme_zns_append_args *args`` - :c:type:`struct nvme_zns_append_args ` argument structure - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. _linux.h: - -**linux.h** - - -linux-specific utility functions - -.. c:function:: int nvme_fw_download_seq (int fd, __u32 size, __u32 xfer, __u32 offset, void *buf) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 size`` - Total size of the firmware image to transfer - -``__u32 xfer`` - Maximum size to send with each partial transfer - -``__u32 offset`` - Starting offset to send with this firmware downlaod - -``void *buf`` - Address of buffer containing all or part of the firmware image. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_ctrl_telemetry (int fd, bool rae, struct nvme_telemetry_log **log) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``bool rae`` - Retain asynchronous events - -``struct nvme_telemetry_log **log`` - On success, set to the value of the allocated and retreived log. - -**Description** - -The total size allocated can be calculated as: - (:c:type:`struct nvme_telemetry_log `.dalb3 + 1) * ``NVME_LOG_TELEM_BLOCK_SIZE``. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_host_telemetry (int fd, struct nvme_telemetry_log **log) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``struct nvme_telemetry_log **log`` - On success, set to the value of the allocated and retreived log. - -**Description** - -The total size allocated can be calculated as: - (:c:type:`struct nvme_telemetry_log `.dalb3 + 1) * ``NVME_LOG_TELEM_BLOCK_SIZE``. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_new_host_telemetry (int fd, struct nvme_telemetry_log **log) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``struct nvme_telemetry_log **log`` - On success, set to the value of the allocated and retreived log. - -**Description** - -The total size allocated can be calculated as: - (:c:type:`struct nvme_telemetry_log `.dalb3 + 1) * ``NVME_LOG_TELEM_BLOCK_SIZE``. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_log_page (int fd, __u32 nsid, __u8 log_id, bool rae, __u32 xfer_len, __u32 data_len, void *data) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Namespace Identifier, if applicable. - -``__u8 log_id`` - Log Identifier, see :c:type:`enum nvme_cmd_get_log_lid `. - -``bool rae`` - Retain asynchronous events - -``__u32 xfer_len`` - Max log transfer size per request to split the total. - -``__u32 data_len`` - Total length of the log to transfer. - -``void *data`` - User address of at least :c:type:`data_len` to store the log. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_log_page_padded (int fd, __u32 nsid, __u8 log_id, bool rae, __u32 data_len, void *data) - - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Namespace Identifier, if applicable. - -``__u8 log_id`` - Log Identifier, see :c:type:`enum nvme_cmd_get_log_lid `. - -``bool rae`` - Retain asynchronous events - -``__u32 data_len`` - Total length of the log to transfer. - -``void *data`` - User address of at least :c:type:`data_len` to store the log. - -**Description** - -Calls nvme_get_log_page() with a default 4k transfer length, as that is -guarnateed by the protocol to be a safe transfer size. - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_ana_log_len (int fd, size_t *analen) - - Retreive size of the current ANA log - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``size_t *analen`` - Pointer to where the length will be set on success - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_logical_block_size (int fd, __u32 nsid, int *blksize) - - Retrieve block size - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Namespace id - -``int *blksize`` - Pointer to where the block size will be set on success - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_get_lba_status_log (int fd, bool rae, struct nvme_lba_status_log **log) - - Retreive the LBA Status log page - -**Parameters** - -``int fd`` - File descriptor of the nvme device - -``bool rae`` - Retain asynchronous events - -``struct nvme_lba_status_log **log`` - On success, set to the value of the allocated and retreived log. - - -.. c:function:: int nvme_namespace_attach_ctrls (int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist) - - Attach namespace to controller(s) - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Namespace ID to attach - -``__u16 num_ctrls`` - Number of controllers in ctrlist - -``__u16 *ctrlist`` - List of controller IDs to perform the attach action - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_namespace_detach_ctrls (int fd, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist) - - Detach namespace from controller(s) - -**Parameters** - -``int fd`` - File descriptor of nvme device - -``__u32 nsid`` - Namespace ID to detach - -``__u16 num_ctrls`` - Number of controllers in ctrlist - -``__u16 *ctrlist`` - List of controller IDs to perform the detach action - -**Return** - -The nvme command status if a response was received (see -:c:type:`enum nvme_status_field `) or -1 with errno set otherwise. - - -.. c:function:: int nvme_open (const char *name) - - Open an nvme controller or namespace device - -**Parameters** - -``const char *name`` - The basename of the device to open - -**Description** - -This will look for the handle in /dev/ and validate the name and filetype -match linux conventions. - -**Return** - -A file descriptor for the device on a successful open, or -1 with -errno set otherwise. - - - - -.. c:type:: enum nvme_hmac_alg - - HMAC algorithm - -**Constants** - -``NVME_HMAC_ALG_NONE`` - No HMAC algorithm - -``NVME_HMAC_ALG_SHA2_256`` - SHA2-256 - -``NVME_HMAC_ALG_SHA2_384`` - SHA2-384 - -``NVME_HMAC_ALG_SHA2_512`` - SHA2-512 - - -.. c:function:: int nvme_gen_dhchap_key (char *hostnqn, enum nvme_hmac_alg hmac, unsigned int key_len, unsigned char *secret, unsigned char *key) - - DH-HMAC-CHAP key generation - -**Parameters** - -``char *hostnqn`` - Host NVMe Qualified Name - -``enum nvme_hmac_alg hmac`` - HMAC algorithm - -``unsigned int key_len`` - Output key lenght - -``unsigned char *secret`` - Secret to used for digest - -``unsigned char *key`` - Generated DH-HMAC-CHAP key - -**Return** - -If key generation was successful the function returns 0 or --1 with errno set otherwise. - - -.. _log.h: - -**log.h** - - -logging functions - -.. c:function:: void nvme_init_logging (nvme_root_t r, int lvl, bool log_pid, bool log_tstamp) - - initialize logging - -**Parameters** - -``nvme_root_t r`` - nvme_root_t context - -``int lvl`` - logging level to set - -``bool log_pid`` - boolean to enable logging of the PID - -``bool log_tstamp`` - boolean to enable logging of the timestamp - -**Description** - -Sets the default logging variables for the library. - - -.. _tree.h: - -**tree.h** - - -libnvme tree object interface - -.. c:function:: nvme_root_t nvme_create_root (FILE *fp, int log_level) - - Initialize root object - -**Parameters** - -``FILE *fp`` - filedescriptor for logging messages - -``int log_level`` - logging level to use - -**Return** - -initialized nvme_root_t object - - -.. c:function:: void nvme_free_tree (nvme_root_t r) - - Free root object - -**Parameters** - -``nvme_root_t r`` - nvme_root_t object - -**Description** - -Free an nvme_root_t object and all attached objects - - -.. c:function:: nvme_host_t nvme_first_host (nvme_root_t r) - - Start host iterator - -**Parameters** - -``nvme_root_t r`` - nvme_root_t object - -**Return** - -first nvme_host_t object in an iterator - - -.. c:function:: nvme_host_t nvme_next_host (nvme_root_t r, nvme_host_t h) - - Next host iterator - -**Parameters** - -``nvme_root_t r`` - nvme_root_t object - -``nvme_host_t h`` - previous nvme_host_t iterator - -**Return** - -next nvme_host_t object in an iterator - - -.. c:function:: nvme_root_t nvme_host_get_root (nvme_host_t h) - - Returns nvme_root_t object - -**Parameters** - -``nvme_host_t h`` - host - -**Return** - -nvme_root_t object from **h** - - -.. c:function:: nvme_host_t nvme_lookup_host (nvme_root_t r, const char *hostnqn, const char *hostid) - - Lookup nvme_host_t object - -**Parameters** - -``nvme_root_t r`` - nvme_root_t object - -``const char *hostnqn`` - Host NQN - -``const char *hostid`` - Host ID - -**Description** - -Lookup a nvme_host_t object based on **hostnqn** and **hostid** -or create one if not found. - -**Return** - -nvme_host_t object - - -.. c:function:: const char * nvme_host_get_hostnqn (nvme_host_t h) - - Returns the host NQN - -**Parameters** - -``nvme_host_t h`` - host - -**Return** - -NVMe host NQN - - -.. c:function:: const char * nvme_host_get_hostid (nvme_host_t h) - - Returns the host ID - -**Parameters** - -``nvme_host_t h`` - host - -**Return** - -NVMe Host ID - - -.. c:function:: const char * nvme_host_get_dhchap_key (nvme_host_t h) - - return host key - -**Parameters** - -``nvme_host_t h`` - Host for which the key should be returned - -**Return** - -DH-HMAC-CHAP host key or NULL if not set - - -.. c:function:: void nvme_host_set_dhchap_key (nvme_host_t h, const char *key) - - set host key - -**Parameters** - -``nvme_host_t h`` - Host for which the key should be set - -``const char *key`` - DH-HMAC-CHAP Key to set or NULL to clear existing key - - -.. c:function:: nvme_host_t nvme_default_host (nvme_root_t r) - - Initializes the default host - -**Parameters** - -``nvme_root_t r`` - nvme_root_t object - -**Description** - -Initializes the default host object based on the values in -/etc/nvme/hostnqn and /etc/nvme/hostid and attaches it to **r**. - -**Return** - -nvme_host_t object - - -.. c:function:: nvme_subsystem_t nvme_first_subsystem (nvme_host_t h) - - Start subsystem iterator - -**Parameters** - -``nvme_host_t h`` - nvme_host_t object - -**Return** - -first nvme_subsystem_t object in an iterator - - -.. c:function:: nvme_subsystem_t nvme_next_subsystem (nvme_host_t h, nvme_subsystem_t s) - - Next subsystem iterator - -**Parameters** - -``nvme_host_t h`` - nvme_host_t object - -``nvme_subsystem_t s`` - previous nvme_subsystem_t iterator - -**Return** - -next nvme_subsystem_t object in an iterator - - -.. c:function:: nvme_subsystem_t nvme_lookup_subsystem (struct nvme_host *h, const char *name, const char *subsysnqn) - - Lookup nvme_subsystem_t object - -**Parameters** - -``struct nvme_host *h`` - nvme_host_t object - -``const char *name`` - Name of the subsystem (may be NULL) - -``const char *subsysnqn`` - Subsystem NQN - -**Description** - -Lookup a nvme_subsystem_t object in **h** base on **name** (if present) -and **subsystemnqn** or create one if not found. - -**Return** - -nvme_subsystme_t object - - -.. c:function:: void nvme_free_subsystem (struct nvme_subsystem *s) - - Free a subsystem - -**Parameters** - -``struct nvme_subsystem *s`` - subsystem - -**Description** - -Frees **s** and all related objects. - - -.. c:function:: nvme_host_t nvme_subsystem_get_host (nvme_subsystem_t s) - - Returns nvme_host_t object - -**Parameters** - -``nvme_subsystem_t s`` - subsystem - -**Return** - -nvme_host_t object from **s** - - -.. c:function:: nvme_ns_t nvme_ctrl_first_ns (nvme_ctrl_t c) - - Start namespace iterator - -**Parameters** - -``nvme_ctrl_t c`` - nvme_ctrl_t object - -**Return** - -first nvme_ns_t object of an **c** iterator - - -.. c:function:: nvme_ns_t nvme_ctrl_next_ns (nvme_ctrl_t c, nvme_ns_t n) - - Next namespace iterator - -**Parameters** - -``nvme_ctrl_t c`` - nvme_ctrl_t object - -``nvme_ns_t n`` - previous nvme_ns_t iterator - -**Return** - -next nvme_ns_t object of an **c** iterator - - -.. c:function:: nvme_path_t nvme_ctrl_first_path (nvme_ctrl_t c) - - Start path iterator - -**Parameters** - -``nvme_ctrl_t c`` - nvme_ctrl_t object - -**Return** - -First nvme_path_t object of an **c** iterator - - -.. c:function:: nvme_path_t nvme_ctrl_next_path (nvme_ctrl_t c, nvme_path_t p) - - Next path iterator - -**Parameters** - -``nvme_ctrl_t c`` - nvme_ctrl_t object - -``nvme_path_t p`` - previous nvme_path_t object of an **c** iterator - - -.. c:function:: nvme_ctrl_t nvme_subsystem_first_ctrl (nvme_subsystem_t s) - - First ctrl iterator - -**Parameters** - -``nvme_subsystem_t s`` - nvme_subsystem_t object - -**Return** - -First nvme_ctrl_t object of an **s** iterator - - -.. c:function:: nvme_ctrl_t nvme_subsystem_next_ctrl (nvme_subsystem_t s, nvme_ctrl_t c) - - Next ctrl iterator - -**Parameters** - -``nvme_subsystem_t s`` - nvme_subsystem_t object - -``nvme_ctrl_t c`` - previous nvme_ctrl_t object of an **s** iterator - -**Return** - -next nvme_ctrl_t object of an **s** iterator - - -.. c:function:: 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) - - Lookup nvme_ctrl_t object - -**Parameters** - -``nvme_subsystem_t s`` - nvme_subsystem_t object - -``const char *transport`` - transport name - -``const char *traddr`` - transport address - -``const char *host_traddr`` - host transport address - -``const char *host_iface`` - host interface name - -``const char *trsvcid`` - transport service identifier - -**Description** - -Lookup a nvme_ctrl_t object in **s** based on **transport**, **traddr**, -**host_traddr**, **host_iface**, and **trsvcid**. **transport** must be specified, -other fields may be required depending on the transport. A new -object is created if none is found. - -**Return** - -nvme_ctrl_t object - - -.. c:function:: nvme_ctrl_t nvme_create_ctrl (nvme_root_t r, const char *subsysnqn, const char *transport, const char *traddr, const char *host_traddr, const char *host_iface, const char *trsvcid) - - Allocate an unconnected NVMe controller - -**Parameters** - -``nvme_root_t r`` - NVMe root element - -``const char *subsysnqn`` - Subsystem NQN - -``const char *transport`` - Transport type - -``const char *traddr`` - Transport address - -``const char *host_traddr`` - Host transport address - -``const char *host_iface`` - Host interface name - -``const char *trsvcid`` - Transport service ID - -**Description** - -Creates an unconnected nvme_ctrl_t object to be used for -nvme_add_ctrl(). - -**Return** - -nvme_ctrl_t object - - -.. c:function:: nvme_ns_t nvme_subsystem_first_ns (nvme_subsystem_t s) - - Start namespace iterator - -**Parameters** - -``nvme_subsystem_t s`` - nvme_subsystem_t object - -**Return** - -First nvme_ns_t object of an **s** iterator - - -.. c:function:: nvme_ns_t nvme_subsystem_next_ns (nvme_subsystem_t s, nvme_ns_t n) - - Next namespace iterator - -**Parameters** - -``nvme_subsystem_t s`` - nvme_subsystem_t object - -``nvme_ns_t n`` - previous nvme_ns_t iterator - -**Return** - -Next nvme_ns_t object of an **s** iterator - - -.. c:function:: nvme_for_each_host_safe (r, h, _h) - - Traverse host list - -**Parameters** - -``r`` - nvme_root_t object - -``h`` - nvme_host_t object - -``_h`` - temporary nvme_host_t object - - -.. c:function:: nvme_for_each_host (r, h) - - Traverse host list - -**Parameters** - -``r`` - nvme_root_t object - -``h`` - nvme_host_t object - - -.. c:function:: nvme_for_each_subsystem_safe (h, s, _s) - - Traverse subsystems - -**Parameters** - -``h`` - nvme_host_t object - -``s`` - nvme_subsystem_t object - -``_s`` - temporary nvme_subsystem_t object - - -.. c:function:: nvme_for_each_subsystem (h, s) - - Traverse subsystems - -**Parameters** - -``h`` - nvme_host_t object - -``s`` - nvme_subsystem_t object - - -.. c:function:: nvme_subsystem_for_each_ctrl_safe (s, c, _c) - - Traverse controllers - -**Parameters** - -``s`` - nvme_subsystem_t object - -``c`` - nvme_ctrl_t object - -``_c`` - temporary nvme_ctrl_t object - - -.. c:function:: nvme_subsystem_for_each_ctrl (s, c) - - traverse controllers - -**Parameters** - -``s`` - nvme_subsystem_t object - -``c`` - nvme_ctrl_t object - - -.. c:function:: nvme_ctrl_for_each_ns_safe (c, n, _n) - - traverse namespaces - -**Parameters** - -``c`` - nvme_ctrl_t object - -``n`` - nvme_ns_t object - -``_n`` - temporary nvme_ns_t object - - -.. c:function:: nvme_ctrl_for_each_ns (c, n) - - traverse namespaces - -**Parameters** - -``c`` - nvme_ctrl_t object - -``n`` - nvme_ns_t object - - -.. c:function:: nvme_ctrl_for_each_path_safe (c, p, _p) - - Traverse paths - -**Parameters** - -``c`` - nvme_ctrl_t object - -``p`` - nvme_path_t object - -``_p`` - temporary nvme_path_t object - - -.. c:function:: nvme_ctrl_for_each_path (c, p) - - Traverse paths - -**Parameters** - -``c`` - nvme_ctrl_t object - -``p`` - nvme_path_t object - - -.. c:function:: nvme_subsystem_for_each_ns_safe (s, n, _n) - - Traverse namespaces - -**Parameters** - -``s`` - nvme_subsystem_t object - -``n`` - nvme_ns_t object - -``_n`` - temporary nvme_ns_t object - - -.. c:function:: nvme_subsystem_for_each_ns (s, n) - - Traverse namespaces - -**Parameters** - -``s`` - nvme_subsystem_t object - -``n`` - nvme_ns_t object - - -.. c:function:: int nvme_ns_get_fd (nvme_ns_t n) - - Get associated filedescriptor - -**Parameters** - -``nvme_ns_t n`` - nvme_ns_t object - -**Return** - -Filedescriptor associated with **n** or -1 - - -.. c:function:: int nvme_ns_get_nsid (nvme_ns_t n) - - NSID of an nvme_ns_t object - -**Parameters** - -``nvme_ns_t n`` - nvme_ns_t object - -**Return** - -NSID of **n** - - -.. c:function:: int nvme_ns_get_lba_size (nvme_ns_t n) - - LBA size of an nvme_ns_t object - -**Parameters** - -``nvme_ns_t n`` - nvme_ns_t object - -**Return** - -LBA size of **n** - - -.. c:function:: int nvme_ns_get_meta_size (nvme_ns_t n) - - Metadata size of an nvme_ns_t object - -**Parameters** - -``nvme_ns_t n`` - nvme_ns_t object - -**Return** - -Metadata size of **n** - - -.. c:function:: uint64_t nvme_ns_get_lba_count (nvme_ns_t n) - - LBA count of an nvme_ns_t object - -**Parameters** - -``nvme_ns_t n`` - nvme_ns_t object - -**Return** - -LBA count of **n** - - -.. c:function:: uint64_t nvme_ns_get_lba_util (nvme_ns_t n) - - LBA utilisation of an nvme_ns_t object - -**Parameters** - -``nvme_ns_t n`` - nvme_ns_t object - -**Return** - -LBA utilisation of **n** - - -.. c:function:: enum nvme_csi nvme_ns_get_csi (nvme_ns_t n) - - Command set identifier of an nvme_ns_t object - -**Parameters** - -``nvme_ns_t n`` - nvme_ns_t object - -**Return** - -The namespace's command set identifier in use - - -.. c:function:: const uint8_t * nvme_ns_get_eui64 (nvme_ns_t n) - - 64-bit eui of an nvme_ns_t object - -**Parameters** - -``nvme_ns_t n`` - nvme_ns_t object - -**Description** - -Returns a pointer to the 64-bit eui - - -.. c:function:: const uint8_t * nvme_ns_get_nguid (nvme_ns_t n) - - 128-bit nguid of an nvme_ns_t object - -**Parameters** - -``nvme_ns_t n`` - nvme_ns_t object - -**Description** - -Returns a pointer to the 128-bit nguid - - -.. c:function:: void nvme_ns_get_uuid (nvme_ns_t n, uuid_t out) - - UUID of an nvme_ns_t object - -**Parameters** - -``nvme_ns_t n`` - nvme_ns_t object - -``uuid_t out`` - buffer for the UUID - -**Description** - -Copies the namespace's uuid into **out** - - -.. c:function:: const char * nvme_ns_get_sysfs_dir (nvme_ns_t n) - - sysfs directory of an nvme_ns_t object - -**Parameters** - -``nvme_ns_t n`` - nvme_ns_t object - -**Return** - -sysfs directory name of **n** - - -.. c:function:: const char * nvme_ns_get_name (nvme_ns_t n) - - sysfs name of an nvme_ns_t object - -**Parameters** - -``nvme_ns_t n`` - nvme_ns_t object - -**Return** - -sysfs name of **n** - - -.. c:function:: const char * nvme_ns_get_generic_name (nvme_ns_t n) - - Returns name of generic namesapce chardev. - -**Parameters** - -``nvme_ns_t n`` - Namespace instance - -**Return** - -Name of generic namespace chardev - - -.. c:function:: const char * nvme_ns_get_firmware (nvme_ns_t n) - - Firmware string of an nvme_ns_t object - -**Parameters** - -``nvme_ns_t n`` - nvme_ns_t object - -**Return** - -Firmware string of **n** - - -.. c:function:: const char * nvme_ns_get_serial (nvme_ns_t n) - - Serial number of an nvme_ns_t object - -**Parameters** - -``nvme_ns_t n`` - nvme_ns_t object - -**Return** - -Serial number string of **n** - - -.. c:function:: const char * nvme_ns_get_model (nvme_ns_t n) - - Model of an nvme_ns_t object - -**Parameters** - -``nvme_ns_t n`` - nvme_ns_t object - -**Return** - -Model string of **n** - - -.. c:function:: nvme_subsystem_t nvme_ns_get_subsystem (nvme_ns_t n) - - nvme_subsystem_t of an nvme_ns_t object - -**Parameters** - -``nvme_ns_t n`` - nvme_ns_t object - -**Return** - -nvme_subsystem_t object of **n** - - -.. c:function:: nvme_ctrl_t nvme_ns_get_ctrl (nvme_ns_t n) - - nvme_ctrl_t of an nvme_ns_t object - -**Parameters** - -``nvme_ns_t n`` - nvme_ns_t object - -**Description** - -nvme_ctrl_t object may be NULL for a multipathed namespace - -**Return** - -nvme_ctrl_t object of **n** if present - - -.. c:function:: void nvme_free_ns (struct nvme_ns *n) - - free an nvme_ns_t object - -**Parameters** - -``struct nvme_ns *n`` - nvme_ns_t object - - -.. c:function:: int nvme_ns_read (nvme_ns_t n, void *buf, off_t offset, size_t count) - - Read from a namespace - -**Parameters** - -``nvme_ns_t n`` - nvme_ns_t object - -``void *buf`` - buffer into which the data will be transferred - -``off_t offset`` - LBA offset of **n** - -``size_t count`` - Number of sectors in **buf** - -**Return** - -Number of sectors read or -1 on error. - - -.. c:function:: int nvme_ns_write (nvme_ns_t n, void *buf, off_t offset, size_t count) - - Write to a namespace - -**Parameters** - -``nvme_ns_t n`` - nvme_ns_t object - -``void *buf`` - buffer with data to be written - -``off_t offset`` - LBA offset of **n** - -``size_t count`` - Number of sectors in **buf** - -**Return** - -Number of sectors written or -1 on error - - -.. c:function:: int nvme_ns_verify (nvme_ns_t n, off_t offset, size_t count) - - Verify data on a namespace - -**Parameters** - -``nvme_ns_t n`` - nvme_ns_t object - -``off_t offset`` - LBA offset of **n** - -``size_t count`` - Number of sectors to be verified - -**Return** - -Number of sectors verified - - -.. c:function:: int nvme_ns_compare (nvme_ns_t n, void *buf, off_t offset, size_t count) - - Compare data on a namespace - -**Parameters** - -``nvme_ns_t n`` - nvme_ns_t object - -``void *buf`` - buffer with data to be compared - -``off_t offset`` - LBA offset of **n** - -``size_t count`` - Number of sectors in **buf** - -**Return** - -Number of sectors compared - - -.. c:function:: int nvme_ns_write_zeros (nvme_ns_t n, off_t offset, size_t count) - - Write zeros to a namespace - -**Parameters** - -``nvme_ns_t n`` - nvme_ns_t object - -``off_t offset`` - LBA offset in **n** - -``size_t count`` - Number of sectors to be written - -**Return** - -Number of sectors written - - -.. c:function:: int nvme_ns_write_uncorrectable (nvme_ns_t n, off_t offset, size_t count) - - Issus a 'write uncorrectable' command - -**Parameters** - -``nvme_ns_t n`` - nvme_ns_t object - -``off_t offset`` - LBA offset in **n** - -``size_t count`` - Number of sectors to be written - -**Return** - -Number of sectors written - - -.. c:function:: int nvme_ns_flush (nvme_ns_t n) - - Flush data to a namespace - -**Parameters** - -``nvme_ns_t n`` - nvme_ns_t object - -**Return** - -0 on success, -1 on error. - - -.. c:function:: int nvme_ns_identify (nvme_ns_t n, struct nvme_id_ns *ns) - - Issue an 'identify namespace' command - -**Parameters** - -``nvme_ns_t n`` - nvme_ns_t object - -``struct nvme_id_ns *ns`` - nvme_id_ns buffer - -**Description** - -Writes the data returned by the 'identify namespace' command -into **ns**. - -**Return** - -0 on success, -1 on error. - - -.. c:function:: int nvme_ns_identify_descs (nvme_ns_t n, struct nvme_ns_id_desc *descs) - - Issue an 'identify descriptors' command - -**Parameters** - -``nvme_ns_t n`` - nvme_ns_t object - -``struct nvme_ns_id_desc *descs`` - list of identify descriptors - -**Description** - -Writes the data returned by the 'identify descriptors' command -into **descs**. - -**Return** - -0 on success, -1 on error. - - -.. c:function:: const char * nvme_path_get_name (nvme_path_t p) - - sysfs name of an nvme_path_t object - -**Parameters** - -``nvme_path_t p`` - nvme_path_t object - -**Return** - -sysfs name of **p** - - -.. c:function:: const char * nvme_path_get_sysfs_dir (nvme_path_t p) - - sysfs directory of an nvme_path_t object - -**Parameters** - -``nvme_path_t p`` - nvme_path_t object - -**Return** - -sysfs directory of **p** - - -.. c:function:: const char * nvme_path_get_ana_state (nvme_path_t p) - - ANA state of an nvme_path_t object - -**Parameters** - -``nvme_path_t p`` - nvme_path_t object - -**Return** - -ANA (Asynchronous Namespace Access) state of **p** - - -.. c:function:: nvme_ctrl_t nvme_path_get_ctrl (nvme_path_t p) - - parent controller of an nvme_path_t object - -**Parameters** - -``nvme_path_t p`` - nvme_path_t object - -**Return** - -parent controller if present - - -.. c:function:: nvme_ns_t nvme_path_get_ns (nvme_path_t p) - - parent namespace of an nvme_path_t object - -**Parameters** - -``nvme_path_t p`` - nvme_path_t object - -**Return** - -parent namespace if present - - -.. c:function:: int nvme_ctrl_get_fd (nvme_ctrl_t c) - - Get associated filedescriptor - -**Parameters** - -``nvme_ctrl_t c`` - nvme_ctrl_t object - -**Return** - -Filedescriptor associated with **c** or -1 - - -.. c:function:: const char * nvme_ctrl_get_name (nvme_ctrl_t c) - - sysfs name of an nvme_ctrl_t object - -**Parameters** - -``nvme_ctrl_t c`` - nvme_ctrl_t object - -**Return** - -sysfs name of **c** - - -.. c:function:: const char * nvme_ctrl_get_sysfs_dir (nvme_ctrl_t c) - - sysfs directory of an nvme_ctrl_t object - -**Parameters** - -``nvme_ctrl_t c`` - nvme_ctrl_t object - -**Return** - -sysfs directory name of **c** - - -.. c:function:: const char * nvme_ctrl_get_address (nvme_ctrl_t c) - - Address string of an nvme_ctrl_t - -**Parameters** - -``nvme_ctrl_t c`` - nvme_ctrl_t object - -**Return** - -NVMe-over-Fabrics address string of **c** - - -.. c:function:: const char * nvme_ctrl_get_firmware (nvme_ctrl_t c) - - Firmware string of an nvme_ctrl_t object - -**Parameters** - -``nvme_ctrl_t c`` - nvme_ctrl_t object - -**Return** - -Firmware string of **c** - - -.. c:function:: const char * nvme_ctrl_get_model (nvme_ctrl_t c) - - Model of an nvme_ctrl_t object - -**Parameters** - -``nvme_ctrl_t c`` - nvme_ctrl_t object - -**Return** - -Model string of **c** - - -.. c:function:: const char * nvme_ctrl_get_state (nvme_ctrl_t c) - - Running state of an nvme_ctrl_t object - -**Parameters** - -``nvme_ctrl_t c`` - nvme_ctrl_t object - -**Return** - -string indicating the running state of **c** - - -.. c:function:: const char * nvme_ctrl_get_numa_node (nvme_ctrl_t c) - - NUMA node of an nvme_ctrl_t object - -**Parameters** - -``nvme_ctrl_t c`` - nvme_ctrl_t object - -**Return** - -string indicating the NUMA node - - -.. c:function:: const char * nvme_ctrl_get_queue_count (nvme_ctrl_t c) - - Queue count of an nvme_ctrl_t object - -**Parameters** - -``nvme_ctrl_t c`` - nvme_ctrl_t object - -**Return** - -Queue count of **c** - - -.. c:function:: const char * nvme_ctrl_get_serial (nvme_ctrl_t c) - - Serial number of an nvme_ctrl_t object - -**Parameters** - -``nvme_ctrl_t c`` - nvme_ctrl_t object - -**Return** - -Serial number string of **c** - - -.. c:function:: const char * nvme_ctrl_get_sqsize (nvme_ctrl_t c) - - SQ size of an nvme_ctrl_t object - -**Parameters** - -``nvme_ctrl_t c`` - nvme_ctrl_t object - -**Return** - -SQ size (as string) of **c** - - -.. c:function:: const char * nvme_ctrl_get_transport (nvme_ctrl_t c) - - Transport type of an nvme_ctrl_t object - -**Parameters** - -``nvme_ctrl_t c`` - nvme_ctrl_t object - -**Return** - -Transport type of **c** - - -.. c:function:: const char * nvme_ctrl_get_subsysnqn (nvme_ctrl_t c) - - Subsystem NQN of an nvme_ctrl_t object - -**Parameters** - -``nvme_ctrl_t c`` - nvme_ctrl_t object - -**Return** - -Subsystem NQN of **c** - - -.. c:function:: nvme_subsystem_t nvme_ctrl_get_subsystem (nvme_ctrl_t c) - - Parent subsystem of an nvme_ctrl_t object - -**Parameters** - -``nvme_ctrl_t c`` - nvme_ctrl_t object - -**Return** - -Parent nvme_subsystem_t object - - -.. c:function:: const char * nvme_ctrl_get_traddr (nvme_ctrl_t c) - - Transport address of an nvme_ctrl_t object - -**Parameters** - -``nvme_ctrl_t c`` - nvme_ctrl_t object - -**Return** - -Transport address of **c** - - -.. c:function:: const char * nvme_ctrl_get_trsvcid (nvme_ctrl_t c) - - Transport service identifier of an nvme_ctrl_t object - -**Parameters** - -``nvme_ctrl_t c`` - nvme_ctrl_t object - -**Return** - -Transport service identifier of **c** (if present) - - -.. c:function:: const char * nvme_ctrl_get_host_traddr (nvme_ctrl_t c) - - Host transport address of an nvme_ctrl_t object - -**Parameters** - -``nvme_ctrl_t c`` - nvme_ctrl_t object - -**Return** - -Host transport address of **c** (if present) - - -.. c:function:: const char * nvme_ctrl_get_host_iface (nvme_ctrl_t c) - - Host interface name of an nvme_ctrl_t object - -**Parameters** - -``nvme_ctrl_t c`` - nvme_ctrl_t object - -**Return** - -Host interface name of **c** (if present) - - -.. c:function:: const char * nvme_ctrl_get_dhchap_key (nvme_ctrl_t c) - - return controller key - -**Parameters** - -``nvme_ctrl_t c`` - controller for which the key should be returned - -**Return** - -DH-HMAC-CHAP controller key or NULL if not set - - -.. c:function:: void nvme_ctrl_set_dhchap_key (nvme_ctrl_t c, const char *key) - - set controller key - -**Parameters** - -``nvme_ctrl_t c`` - Controller for which the key should be set - -``const char *key`` - DH-HMAC-CHAP Key to set or NULL to clear existing key - - -.. c:function:: struct nvme_fabrics_config * nvme_ctrl_get_config (nvme_ctrl_t c) - - Fabrics configuration of an nvme_ctrl_t object - -**Parameters** - -``nvme_ctrl_t c`` - nvme_ctrl_t object - -**Return** - -Fabrics configuration of **c** - - -.. c:function:: void nvme_ctrl_set_discovered (nvme_ctrl_t c, bool discovered) - - Set the 'discovered' flag - -**Parameters** - -``nvme_ctrl_t c`` - nvme_ctrl_t object - -``bool discovered`` - value of the 'discovered' flag - -**Description** - -Set the 'discovered' flag of **c** to **discovered** - - -.. c:function:: bool nvme_ctrl_is_discovered (nvme_ctrl_t c) - - Returns the value of the 'discovered' flag - -**Parameters** - -``nvme_ctrl_t c`` - nvme_ctrl_t object - -**Return** - -Value of the 'discovered' flag of **c** - - -.. c:function:: void nvme_ctrl_set_persistent (nvme_ctrl_t c, bool persistent) - - Set the 'persistent' flag - -**Parameters** - -``nvme_ctrl_t c`` - nvme_ctrl_t object - -``bool persistent`` - value of the 'persistent' flag - -**Description** - -Set the 'persistent' flag of **c** to **persistent** - - -.. c:function:: bool nvme_ctrl_is_persistent (nvme_ctrl_t c) - - Returns the value of the 'persistent' flag - -**Parameters** - -``nvme_ctrl_t c`` - nvme_ctrl_t object - -**Return** - -Value of the 'persistent' flag of **c** - - -.. c:function:: void nvme_ctrl_set_discovery_ctrl (nvme_ctrl_t c, bool discovery) - - Set the 'discovery_ctrl' flag - -**Parameters** - -``nvme_ctrl_t c`` - Controller to be modified - -``bool discovery`` - value of the discovery_ctrl flag - -**Description** - -Sets the 'discovery_ctrl' flag in **c** to specify whether -**c** connects to a discovery subsystem. - - -.. c:function:: bool nvme_ctrl_is_discovery_ctrl (nvme_ctrl_t c) - - Check the 'discovery_ctrl' flag - -**Parameters** - -``nvme_ctrl_t c`` - Controller to be checked - -**Description** - -Returns the value of the 'discovery_ctrl' flag which specifies whether -**c** connects to a discovery subsystem. - -**Return** - -value of the 'discover_ctrl' flag - - -.. c:function:: int nvme_ctrl_identify (nvme_ctrl_t c, struct nvme_id_ctrl *id) - - Issues an 'identify controller' command - -**Parameters** - -``nvme_ctrl_t c`` - nvme_ctrl_t object - -``struct nvme_id_ctrl *id`` - identify controller data structure - -**Description** - -Issues an 'identify controller' command to **c** and copies the -data into **id**. - -**Return** - -0 on success or -1 on failure. - - -.. c:function:: int nvme_disconnect_ctrl (nvme_ctrl_t c) - - Disconnect a controller - -**Parameters** - -``nvme_ctrl_t c`` - nvme_ctrl_t object - -**Description** - -Issues a 'disconnect' fabrics command to **c** - -**Return** - -0 on success, -1 on failure. - - -.. c:function:: nvme_ctrl_t nvme_scan_ctrl (nvme_root_t r, const char *name) - - Scan on a controller - -**Parameters** - -``nvme_root_t r`` - nvme_root_t object - -``const char *name`` - name of the controller - -**Description** - -Scans a controller with sysfs name **name** and add it to **r**. - -**Return** - -nvme_ctrl_t object - - -.. c:function:: void nvme_rescan_ctrl (nvme_ctrl_t c) - - Rescan an existing nvme_ctrl_t object - -**Parameters** - -``nvme_ctrl_t c`` - nvme_ctrl_t object - - -.. c:function:: int nvme_init_ctrl (nvme_host_t h, nvme_ctrl_t c, int instance) - - Initialize nvme_ctrl_t object for an existing nvme controller. - -**Parameters** - -``nvme_host_t h`` - nvme_host_t object - -``nvme_ctrl_t c`` - nvme_ctrl_t object - -``int instance`` - Instance number (e.g. 1 for nvme1) - -**Return** - -The ioctl() return code. Typically 0 on success. - - -.. c:function:: void nvme_free_ctrl (struct nvme_ctrl *c) - - -**Parameters** - -``struct nvme_ctrl *c`` - - -.. c:function:: void nvme_unlink_ctrl (struct nvme_ctrl *c) - - -**Parameters** - -``struct nvme_ctrl *c`` - - -.. c:function:: const char * nvme_subsystem_get_nqn (nvme_subsystem_t s) - - -**Parameters** - -``nvme_subsystem_t s`` - - -.. c:function:: const char * nvme_subsystem_get_sysfs_dir (nvme_subsystem_t s) - - sysfs directory of an nvme_subsystem_t object - -**Parameters** - -``nvme_subsystem_t s`` - nvme_subsystem_t object - -**Return** - -sysfs directory name of **s** - - -.. c:function:: const char * nvme_subsystem_get_name (nvme_subsystem_t s) - - sysfs name of an nvme_subsystem_t object - -**Parameters** - -``nvme_subsystem_t s`` - nvme_subsystem_t object - -**Return** - -sysfs name of **s** - - -.. c:function:: const char * nvme_subsystem_get_type (nvme_subsystem_t s) - - Returns the type of a subsystem - -**Parameters** - -``nvme_subsystem_t s`` - Subsystem - -**Description** - -Returns the subsystem type of **s**. - -**Return** - -'nvm' or 'discovery' - - -.. c:function:: int nvme_scan_topology (nvme_root_t r, nvme_scan_filter_t f) - - Scan NVMe topology and apply filter - -**Parameters** - -``nvme_root_t r`` - nvme_root_t object - -``nvme_scan_filter_t f`` - filter to apply - -**Description** - -Scans the NVMe topology and filters out the resulting elements -by applying **f**. - -**Return** - -Number of elements scanned - - -.. c:function:: const char * nvme_host_get_hostnqn (nvme_host_t h) - - Host NQN of an nvme_host_t object - -**Parameters** - -``nvme_host_t h`` - nvme_host_t object - -**Return** - -Host NQN of **h** - - -.. c:function:: const char * nvme_host_get_hostid (nvme_host_t h) - - Host ID of an nvme_host_t object - -**Parameters** - -``nvme_host_t h`` - nvme_host_t object - -**Return** - -Host ID of **h** - - -.. c:function:: void nvme_free_host (nvme_host_t h) - - Free nvme_host_t object - -**Parameters** - -``nvme_host_t h`` - nvme_host_t object - - -.. c:function:: nvme_root_t nvme_scan (const char *config_file) - - Scan NVMe topology - -**Parameters** - -``const char *config_file`` - configuration file - -**Return** - -nvme_root_t object of found elements - - -.. c:function:: void nvme_read_config (nvme_root_t r, const char *config_file) - - Read NVMe json configuration file - -**Parameters** - -``nvme_root_t r`` - nvme_root_t object - -``const char *config_file`` - json configuration file - -**Description** - -Read in the contents of **config_file** and merge them with -the elements in **r**. - - -.. c:function:: void nvme_refresh_topology (nvme_root_t r) - - refresh nvme_root_t object contents - -**Parameters** - -``nvme_root_t r`` - nvme_root_t object - -**Description** - -Removes all elements in **r** and rescans the existing topology. - - -.. c:function:: int nvme_update_config (nvme_root_t r) - - Update JSON configuration - -**Parameters** - -``nvme_root_t r`` - nvme_root_t object - -**Description** - -Updates the JSON configuration file with the contents of **r**. - -**Return** - -0 on success, -1 on failure. - - -.. c:function:: int nvme_dump_config (nvme_root_t r) - - Print the JSON configuration - -**Parameters** - -``nvme_root_t r`` - nvme_root_t object - -**Description** - -Prints the current contents of the JSON configuration -file to stdout. - -**Return** - -0 on success, -1 on failure. - - -.. c:function:: char * nvme_get_attr (const char *d, const char *attr) - - Read sysfs attribute - -**Parameters** - -``const char *d`` - sysfs directory - -``const char *attr`` - sysfs attribute name - -**Return** - -string with the contents of **attr** - - -.. c:function:: char * nvme_get_subsys_attr (nvme_subsystem_t s, const char *attr) - - Read subsystem sysfs attribute - -**Parameters** - -``nvme_subsystem_t s`` - nvme_subsystem_t object - -``const char *attr`` - sysfs attribute name - -**Return** - -string with the contents of **attr** - - -.. c:function:: char * nvme_get_ctrl_attr (nvme_ctrl_t c, const char *attr) - - Read controller sysfs attribute - -**Parameters** - -``nvme_ctrl_t c`` - nvme_ctrl_t object - -``const char *attr`` - sysfs attribute name - -**Return** - -string with the contents of **attr** - - -.. c:function:: char * nvme_get_ns_attr (nvme_ns_t n, const char *attr) - - Read namespace sysfs attribute - -**Parameters** - -``nvme_ns_t n`` - nvme_ns_t object - -``const char *attr`` - sysfs attribute name - -**Return** - -string with the contents of **attr** - - -.. c:function:: nvme_ns_t nvme_subsystem_lookup_namespace (struct nvme_subsystem *s, __u32 nsid) - - lookup namespace by NSID - -**Parameters** - -``struct nvme_subsystem *s`` - nvme_subsystem_t object - -``__u32 nsid`` - namespace id - -**Return** - -nvme_ns_t of the namespace with id **nsid** in subsystem **s** - - -.. c:function:: char * nvme_get_path_attr (nvme_path_t p, const char *attr) - - Read path sysfs attribute - -**Parameters** - -``nvme_path_t p`` - nvme_path_t object - -``const char *attr`` - sysfs attribute name - -**Return** - -string with the contents of **attr** - - -.. c:function:: nvme_ns_t nvme_scan_namespace (const char *name) - - scan namespace based on sysfs name - -**Parameters** - -``const char *name`` - sysfs name of the namespace to scan - -**Return** - -nvme_ns_t object or NULL if not found. - - -.. _types.h: - -**types.h** - - -NVMe standard definitions - -.. c:function:: NVME_GET (value, name) - - extract field from complex value - -**Parameters** - -``value`` - The original value of a complex field - -``name`` - The name of the sub-field within an nvme value - -**Description** - -By convention, this library defines _SHIFT and _MASK such that mask can be -applied after the shift to isolate a specific set of bits that decode to a -sub-field. - -**Return** - -The 'name' field from 'value' - - -.. c:function:: NVME_SET (value, name) - - set field into complex value - -**Parameters** - -``value`` - The value to be set in its completed position - -``name`` - The name of the sub-field within an nvme value - -**Return** - -The - - - - -.. c:type:: enum nvme_constants - - A place to stash various constant nvme values - -**Constants** - -``NVME_NSID_ALL`` - A broadcast value that is used to specify all - namespaces - -``NVME_NSID_NONE`` - The invalid namespace id, for when the nsid - 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_NVMSETID_NONE`` - Use to omit a nvmsetid command parameter - -``NVME_DOMID_NONE`` - Use to omit a domid 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 - log pages log. - -``NVME_ID_NVMSET_LIST_MAX`` - The largest possible nvmset index in identify - nvmeset - -``NVME_ID_UUID_LIST_MAX`` - The largest possible uuid index in identify - uuid list - -``NVME_ID_CTRL_LIST_MAX`` - The largest possible controller index in - identify controller list - -``NVME_ID_NS_LIST_MAX`` - The largest possible namespace index in - identify namespace list - -``NVME_ID_SECONDARY_CTRL_MAX`` - The largest possible secondary controller index - 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 - index in the endurance group list - -``NVME_ID_ND_DESCRIPTOR_MAX`` - The largest possible namespace granularity - index in the namespace granularity descriptor - list - -``NVME_FEAT_LBA_RANGE_MAX`` - The largest possible LBA range index in feature - lba range type - -``NVME_LOG_ST_MAX_RESULTS`` - The largest possible self test result index in the - device self test log - -``NVME_LOG_TELEM_BLOCK_SIZE`` - Specification defined size of Telemetry Data Blocks - -``NVME_LOG_FID_SUPPORTED_EFFECTS_MAX`` - The largest possible FID index in the - feature identifiers effects log. - -``NVME_DSM_MAX_RANGES`` - The largest possible range index in a data-set - 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 - -``NVME_ZNS_CHANGED_ZONES_MAX`` - Max number of zones in the changed zones log - page - - - - -.. c:type:: enum nvme_csi - - Defined command set indicators - -**Constants** - -``NVME_CSI_NVM`` - NVM Command Set Indicator - -``NVME_CSI_ZNS`` - Zoned Namespace Command Set - - - - -.. c:type:: enum nvme_register_offsets - - controller registers for all transports. This is the layout of BAR0/1 for PCIe, and properties for fabrics. - -**Constants** - -``NVME_REG_CAP`` - Controller Capabilities - -``NVME_REG_VS`` - Version - -``NVME_REG_INTMS`` - Interrupt Mask Set - -``NVME_REG_INTMC`` - Interrupt Mask Clear - -``NVME_REG_CC`` - Controller Configuration - -``NVME_REG_CSTS`` - Controller Status - -``NVME_REG_NSSR`` - NVM Subsystem Reset - -``NVME_REG_AQA`` - Admin Queue Attributes - -``NVME_REG_ASQ`` - Admin SQ Base Address - -``NVME_REG_ACQ`` - Admin CQ Base Address - -``NVME_REG_CMBLOC`` - Controller Memory Buffer Location - -``NVME_REG_CMBSZ`` - Controller Memory Buffer Size - -``NVME_REG_BPINFO`` - Boot Partition Information - -``NVME_REG_BPRSEL`` - Boot Partition Read Select - -``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_PMRCAP`` - Persistent Memory Capabilities - -``NVME_REG_PMRCTL`` - Persistent Memory Region Control - -``NVME_REG_PMRSTS`` - Persistent Memory Region Status - -``NVME_REG_PMREBS`` - Persistent Memory Region Elasticity Buffer Size - -``NVME_REG_PMRSWTP`` - Memory Region Sustained Write Throughput - -``NVME_REG_PMRMSCL`` - Persistent Memory Region Controller Memory Space Control Lower - -``NVME_REG_PMRMSCU`` - Persistent Memory Region Controller Memory Space Control Upper - - -.. c:function:: bool nvme_is_64bit_reg (__u32 offset) - - Checks if offset of the controller register is a know 64bit value. - -**Parameters** - -``__u32 offset`` - Offset of controller register field in bytes - -**Description** - -This function does not care about transport so that the offset is not going -to be checked inside of this function for the unsupported fields in a -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. - - -.. c:function:: __u64 nvme_cmb_size (__u32 cmbsz) - - Calculate size of the controller memory buffer - -**Parameters** - -``__u32 cmbsz`` - Value from controller register ``NVME_REG_CMBSZ`` - -**Description** - -Returns size of controller memory buffer in bytes - - -.. c:function:: __u64 nvme_pmr_size (__u32 pmrebs) - - Calculate size of persistent memory region elasticity buffer - -**Parameters** - -``__u32 pmrebs`` - Value from controller register ``NVME_REG_PMREBS`` - -**Description** - -Returns size of controller persistent memory buffer in bytes - - -.. c:function:: __u64 nvme_pmr_throughput (__u32 pmrswtp) - - Calculate throughput of persistent memory buffer - -**Parameters** - -``__u32 pmrswtp`` - Value from controller register ``NVME_REG_PMRSWTP`` - -**Description** - -Returns throughput of controller persistent memory buffer in bytes/second - - - - -.. c:type:: enum nvme_psd_flags - - Possible flag values in nvme power state descriptor - -**Constants** - -``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. - -``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. - - - - -.. c:type:: enum nvme_psd_ps - - Known values for :c:type:`struct nvme_psd ` ``ips`` and ``aps``. Use with nvme_psd_power_scale() to extract the power scale field to match this enum. - -**Constants** - -``NVME_PSD_PS_100_MICRO_WATT`` - 0.0001 watt scale - -``NVME_PSD_PS_10_MILLI_WATT`` - 0.01 watt scale - - -.. c:function:: unsigned int nvme_psd_power_scale (__u8 ps) - - power scale occupies the upper 3 bits - -**Parameters** - -``__u8 ps`` - power scale value - - - - -.. c:type:: enum nvme_psd_workload - - Specifies a workload hint in the Power Management Feature (see :c:type:`struct nvme_psd `.apw) to inform the NVM subsystem or indicate the conditions for the active power level. - -**Constants** - -``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. - -``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 - NVM subsystem are idle. The submission queue(s) - should be sufficiently large allowing the host to - ensure there are multiple commands pending at all - times during the workload. - - - - -.. c:type:: struct nvme_id_psd - - -**Definition** - -:: - - struct nvme_id_psd { - __le16 mp; - __u8 rsvd2; - __u8 flags; - __le32 enlat; - __le32 exlat; - __u8 rrt; - __u8 rrl; - __u8 rwt; - __u8 rwl; - __le16 idlp; - __u8 ips; - __u8 rsvd19; - __le16 actp; - __u8 apws; - __u8 rsvd23[9]; - }; - -**Members** - -``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 :c:type:`enum nvme_psd_flags `). A value of 0 indicates - Maximum Power is not reported. - -``rsvd2`` - Reserved - -``flags`` - Additional decoding flags, see :c:type:`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. - -``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. - -``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. - -``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 - -``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 - -``idlp`` - Idle Power indicates the typical power consumed by the NVM - subsystem over 30 seconds in this power state when idle. - -``ips`` - Idle Power Scale indicates the scale for :c:type:`struct nvme_id_psd `.idlp, - see :c:type:`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. - -``apws`` - Bits 7-6: Active Power Scale(APS) indicates the scale for the :c:type:`struct - nvme_id_psd `.actp, see :c:type:`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 :c:type:`enum nvme_psd_workload ` for decoding this field. - -``rsvd23`` - Reserved - - - - - -.. c:type:: struct nvme_id_ctrl - - Identify Controller data structure - -**Definition** - -:: - - struct nvme_id_ctrl { - __le16 vid; - __le16 ssvid; - char sn[20]; - char mn[40]; - char fr[8]; - __u8 rab; - __u8 ieee[3]; - __u8 cmic; - __u8 mdts; - __le16 cntlid; - __le32 ver; - __le32 rtd3r; - __le32 rtd3e; - __le32 oaes; - __le32 ctratt; - __le16 rrls; - __u8 rsvd102[9]; - __u8 cntrltype; - __u8 fguid[16]; - __le16 crdt1; - __le16 crdt2; - __le16 crdt3; - __u8 rsvd134[119]; - __u8 nvmsr; - __u8 vwci; - __u8 mec; - __le16 oacs; - __u8 acl; - __u8 aerl; - __u8 frmw; - __u8 lpa; - __u8 elpe; - __u8 npss; - __u8 avscc; - __u8 apsta; - __le16 wctemp; - __le16 cctemp; - __le16 mtfa; - __le32 hmpre; - __le32 hmmin; - __u8 tnvmcap[16]; - __u8 unvmcap[16]; - __le32 rpmbs; - __le16 edstt; - __u8 dsto; - __u8 fwug; - __le16 kas; - __le16 hctma; - __le16 mntmt; - __le16 mxtmt; - __le32 sanicap; - __le32 hmminds; - __le16 hmmaxd; - __le16 nsetidmax; - __le16 endgidmax; - __u8 anatt; - __u8 anacap; - __le32 anagrpmax; - __le32 nanagrpid; - __le32 pels; - __le16 domainid; - __u8 rsvd358[10]; - __u8 megcap[16]; - __u8 rsvd384[128]; - __u8 sqes; - __u8 cqes; - __le16 maxcmd; - __le32 nn; - __le16 oncs; - __le16 fuses; - __u8 fna; - __u8 vwc; - __le16 awun; - __le16 awupf; - __u8 icsvscc; - __u8 nwpc; - __le16 acwu; - __le16 ocfs; - __le32 sgls; - __le32 mnan; - __u8 maxdna[16]; - __le32 maxcna; - __u8 rsvd564[204]; - char subnqn[NVME_NQN_LENGTH]; - __u8 rsvd1024[768]; - __le32 ioccsz; - __le32 iorcsz; - __le16 icdoff; - __u8 fcatt; - __u8 msdbd; - __le16 ofcs; - __u8 rsvd1806[242]; - struct nvme_id_psd psd[32]; - __u8 vs[1024]; - }; - -**Members** - -``vid`` - PCI Vendor ID, the company vendor identifier that is assigned by - 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 - -``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 :c:type:`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 - -``cntlid`` - Controller ID, the NVM subsystem unique controller identifier - associated with the controller. - -``ver`` - Version, this field contains the value reported in the Version - register, or property (see :c:type:`enum nvme_registers ` ``NVME_REG_VS``). - -``rtd3r`` - RTD3 Resume Latency, the expected latency in microseconds to resume - from Runtime D3 - -``rtd3e`` - RTD3 Exit Latency, the typical latency in microseconds to enter - 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 - -``cntrltype`` - Controller Type, see :c:type:`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 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 - -``rsvd134`` - Reserved - -``nvmsr`` - NVM Subsystem Report, see :c:type:`enum nvme_id_ctrl_nvmsr ` - -``vwci`` - VPD Write Cycle Information, see :c:type:`enum nvme_id_ctrl_vwci ` - -``mec`` - Management Endpoint Capabilities, see :c:type:`enum nvme_id_ctrl_mec ` - -``oacs`` - Optional Admin Command Support,the optional Admin commands and - features supported by the controller, see :c:type:`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. - -``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. - -``frmw`` - Firmware Updates indicates capabilities regarding firmware - updates. See :c:type:`enum nvme_id_ctrl_frmw `. - -``lpa`` - Log Page Attributes, see :c:type:`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. - -``npss`` - Number of Power States Supported, the number of NVM Express - power states supported by the controller, indicating the number - of valid entries in :c:type:`struct nvme_id_ctrl `.psd. This is a 0's - based value. - -``avscc`` - Admin Vendor Specific Command Configuration, see - :c:type:`enum nvme_id_ctrl_avscc `. - -``apsta`` - Autonomous Power State Transition Attributes, see - :c:type:`enum nvme_id_ctrl_apsta `. - -``wctemp`` - Warning Composite Temperature Threshold indicates - the minimum Composite Temperature field value (see :c:type:`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 :c:type:`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. - -``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. - -``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. - -``tnvmcap`` - Total NVM Capacity, the total NVM capacity in the NVM subsystem. - 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 - :c:type:`enum nvme_id_ctrl_rpmbs `. - -``edstt`` - Extended Device Self-test Time, if Device Self-test command is - supported (see :c:type:`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 :c:type:`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 - -``kas`` - Keep Alive Support indicates the granularity of the Keep Alive - Timer in 100 millisecond units. - -``hctma`` - Host Controlled Thermal Management Attributes, see - :c:type:`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``. - -``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``. - -``sanicap`` - Sanitize Capabilities, see :c:type:`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. - -``hmmaxd`` - Host Memory Maximum Descriptors Entries indicates the number of - 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. - -``endgidmax`` - Endurance Group Identifier Maximum, defines the maximum value of - 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. - -``anacap`` - Asymmetric Namespace Access Capabilities, see - :c:type:`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. - -``nanagrpid`` - Number of ANA Group Identifiers indicates the number of ANA - groups supported by this controller. - -``pels`` - Persistent Event Log Size indicates the maximum reportable size - for the Persistent Event Log. - -``domainid`` - Domain Identifier indicates the identifier of the domain - that contains this controller. - -``rsvd358`` - Reserved - -``megcap`` - Max Endurance Group Capacity indicates the maximum capacity - of a single Endurance Group. - -``rsvd384`` - Reserved - -``sqes`` - Submission Queue Entry Size, see :c:type:`enum nvme_id_ctrl_sqes `. - -``cqes`` - Completion Queue Entry Size, see :c:type:`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. - -``nn`` - Number of Namespaces indicates the maximum value of a valid - nsid for the NVM subsystem. If the MNAN (:c:type:`struct nvme_id_ctrl `.mnan - field is cleared to 0h, then this field also indicates the - maximum number of namespaces supported by the NVM subsystem. - -``oncs`` - Optional NVM Command Support, see :c:type:`enum nvme_id_ctrl_oncs `. - -``fuses`` - Fused Operation Support, see :c:type:`enum nvme_id_ctrl_fuses `. - -``fna`` - Format NVM Attributes, see :c:type:`enum nvme_id_ctrl_fna `. - -``vwc`` - Volatile Write Cache, see :c:type:`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. - -``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. - -``icsvscc`` - NVM Vendor Specific Command Configuration, see - :c:type:`enum nvme_id_ctrl_nvscc `. - -``nwpc`` - Namespace Write Protection Capabilities, see - :c:type:`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. - -``ocfs`` - Optional Copy Formats Supported, each bit n means controller - supports Copy Format n. - -``sgls`` - SGL Support, see :c:type:`enum nvme_id_ctrl_sgls ` - -``mnan`` - Maximum Number of Allowed Namespaces indicates the maximum - 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. - -``maxcna`` - Maximum I/O Controller Namespace Attachments indicates the - 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. - -``iorcsz`` - I/O Queue Response Capsule Supported Size, defines the maximum - 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. - -``fcatt`` - Fabrics Controller Attributes, see :c:type:`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. - -``ofcs`` - Optional Fabric Commands Support, see :c:type:`enum nvme_id_ctrl_ofcs `. - -``rsvd1806`` - Reserved - -``psd`` - Power State Descriptors, see :c:type:`struct nvme_id_psd `. - -``vs`` - Vendor Specific - - - - - -.. c:type:: enum nvme_id_ctrl_cmic - - Controller Multipath IO and Namespace Sharing Capabilities of the controller and NVM subsystem. - -**Constants** - -``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. - - - - -.. c:type:: enum nvme_id_ctrl_oaes - - Optional Asynchronous Events Supported - -**Constants** - -``NVME_CTRL_OAES_NA`` - Namespace Attribute Notices event supported - -``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 - -``NVME_CTRL_OAES_LBAS`` - LBA Status Information Notices event supported - -``NVME_CTRL_OAES_EGE`` - Endurance Group Events Aggregate Log Change - 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 - - - - -.. c:type:: enum nvme_id_ctrl_ctratt - - Controller attributes - -**Constants** - -``NVME_CTRL_CTRATT_128_ID`` - 128-bit Host Identifier supported - -``NVME_CTRL_CTRATT_NON_OP_PSP`` - Non-Operational Poser State Permissive Mode - 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 - -``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_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 - - - - -.. c:type:: enum nvme_id_ctrl_cntrltype - - Controller types - -**Constants** - -``NVME_CTRL_CNTRLTYPE_IO`` - NVM I/O controller - -``NVME_CTRL_CNTRLTYPE_DISCOVERY`` - Discovery controller - -``NVME_CTRL_CNTRLTYPE_ADMIN`` - Admin controller - - - - -.. c:type:: enum nvme_id_ctrl_nvmsr - - This field reports information associated with the NVM Subsystem, see :c:type:`struct nvme_id_ctrl `.nvmsr. - -**Constants** - -``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. - -``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. - - - - -.. c:type:: 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 :c:type:`struct nvme_id_ctrl `.vwci. - -**Constants** - -``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. - -``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. - - - - -.. c:type:: enum nvme_id_ctrl_mec - - Flags indicatings the capabilities of the Management Endpoint in the Controller, :c:type:`struct nvme_id_ctrl `.mec. - -**Constants** - -``NVME_CTRL_MEC_SMBUSME`` - If set, then the NVM Subsystem contains a Management - Endpoint on an SMBus/I2C port. - -``NVME_CTRL_MEC_PCIEME`` - If set, then the NVM Subsystem contains a Management - Endpoint on a PCIe port. - - - - -.. c:type:: enum nvme_id_ctrl_oacs - - Flags indicating the optional Admin commands and features supported by the controller, see :c:type:`struct nvme_id_ctrl `.oacs. - -**Constants** - -``NVME_CTRL_OACS_SECURITY`` - If set, then the controller supports the - Security Send and Security Receive commands. - -``NVME_CTRL_OACS_FORMAT`` - If set then the controller supports the Format - NVM command. - -``NVME_CTRL_OACS_FW`` - If set, then the controller supports the - Firmware Commit and Firmware Image Download commands. - -``NVME_CTRL_OACS_NS_MGMT`` - If set, then the controller supports the - Namespace Management capability - -``NVME_CTRL_OACS_SELF_TEST`` - If set, then the controller supports the Device - 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. - -``NVME_CTRL_OACS_VIRT_MGMT`` - If set, then the controller supports the - Virtualization Management command. - -``NVME_CTRL_OACS_DBBUF_CFG`` - If set, then the controller supports the - Doorbell Buffer Config command. - -``NVME_CTRL_OACS_LBA_STATUS`` - If set, then the controller supports the Get LBA - Status capability. - - - - -.. c:type:: enum nvme_id_ctrl_frmw - - Flags and values indicates capabilities regarding firmware updates from :c:type:`struct nvme_id_ctrl `.frmw. - -**Constants** - -``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. - -``NVME_CTRL_FRMW_FW_ACT_NO_RESET`` - If set, the controller supports firmware - activation without a reset. - - - - -.. c:type:: enum nvme_id_ctrl_lpa - - Flags indicating optional attributes for log pages that are accessed via the Get Log Page command. - -**Constants** - -``NVME_CTRL_LPA_SMART_PER_NS`` - -``NVME_CTRL_LPA_CMD_EFFECTS`` - -``NVME_CTRL_LPA_EXTENDED`` - -``NVME_CTRL_LPA_TELEMETRY`` - -``NVME_CTRL_LPA_PERSETENT_EVENT`` - - - - -.. c:type:: enum nvme_id_ctrl_avscc - - Flags indicating the configuration settings for Admin Vendor Specific command handling. - -**Constants** - -``NVME_CTRL_AVSCC_AVS`` - If set, all Admin Vendor Specific Commands use the - optional vendor specific command format with NDT and - NDM fields. - - - - -.. c:type:: enum nvme_id_ctrl_apsta - - Flags indicating the attributes of the autonomous power state transition feature. - -**Constants** - -``NVME_CTRL_APSTA_APST`` - If set, then the controller supports autonomous power - state transitions. - - - - -.. c:type:: enum nvme_id_ctrl_rpmbs - - This field indicates if the controller supports one or more Replay Protected Memory Blocks, from :c:type:`struct nvme_id_ctrl `.rpmbs. - -**Constants** - -``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_ACCESS_SIZE`` - Mask to get the value of Access Size - - - - -.. c:type:: enum nvme_id_ctrl_dsto - - Flags indicating the optional Device Self-test command or operation behaviors supported by the controller or NVM subsystem. - -**Constants** - -``NVME_CTRL_DSTO_ONE_DST`` - If set, then the NVM subsystem supports only one - device self-test operation in progress at a time. - - - - -.. c:type:: enum nvme_id_ctrl_hctm - - Flags indicate the attributes of the host controlled thermal management feature - -**Constants** - -``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``. - - - - -.. c:type:: enum nvme_id_ctrl_sanicap - - Indicates attributes for sanitize operations. - -**Constants** - -``NVME_CTRL_SANICAP_CES`` - Crypto Erase Support. If set, then the - 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. - -``NVME_CTRL_SANICAP_OWS`` - Overwrite Support. If set, then the controller - 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. - -``NVME_CTRL_SANICAP_NODMMAS`` - No-Deallocate Modifies Media After Sanitize, - mask to extract value. - - - - -.. c:type:: enum nvme_id_ctrl_anacap - - This field indicates the capabilities associated with Asymmetric Namespace Access Reporting. - -**Constants** - -``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. - -``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. - -``NVME_CTRL_ANACAP_GRPID_NO_CHG`` - If set, then the ANAGRPID field in the - Identify Namespace data structure - (:c:type:`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. - - - - -.. c:type:: enum nvme_id_ctrl_sqes - - Defines the required and maximum Submission Queue entry size when using the NVM Command Set. - -**Constants** - -``NVME_CTRL_SQES_MIN`` - Mask to get the value of the required Submission Queue - 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. - - - - -.. c:type:: enum nvme_id_ctrl_cqes - - Defines the required and maximum Completion Queue entry size when using the NVM Command Set. - -**Constants** - -``NVME_CTRL_CQES_MIN`` - Mask to get the value of the required Completion Queue - 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. - - - - -.. c:type:: enum nvme_id_ctrl_oncs - - This field indicates the optional NVM commands and features supported by the controller. - -**Constants** - -``NVME_CTRL_ONCS_COMPARE`` - If set, then the controller supports - the Compare command. - -``NVME_CTRL_ONCS_WRITE_UNCORRECTABLE`` - If set, then the controller supports - the Write Uncorrectable command. - -``NVME_CTRL_ONCS_DSM`` - If set, then the controller supports - the Dataset Management command. - -``NVME_CTRL_ONCS_WRITE_ZEROES`` - If set, then the controller supports - 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. - -``NVME_CTRL_ONCS_RESERVATIONS`` - If set, then the controller supports - reservations. - -``NVME_CTRL_ONCS_TIMESTAMP`` - If set, then the controller supports - the Timestamp feature. - -``NVME_CTRL_ONCS_VERIFY`` - If set, then the controller supports - the Verify command. - - - - -.. c:type:: enum nvme_id_ctrl_fuses - - This field indicates the fused operations that the controller supports. - -**Constants** - -``NVME_CTRL_FUSES_COMPARE_AND_WRITE`` - If set, then the controller supports the - Compare and Write fused operation. - - - - -.. c:type:: enum nvme_id_ctrl_fna - - This field indicates attributes for the Format NVM command. - -**Constants** - -``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. - -``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. - - - - -.. c:type:: enum nvme_id_ctrl_vwc - - -**Constants** - -``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``. - -``NVME_CTRL_VWC_FLUSH`` - Mask to get the value of the flush command behavior. - - - - -.. c:type:: enum nvme_id_ctrl_nvscc - - This field indicates the configuration settings for NVM Vendor Specific command handling. - -**Constants** - -``NVME_CTRL_NVSCC_FMT`` - If set, all NVM Vendor Specific Commands use the - format format with NDT and NDM fields. - - - - -.. c:type:: enum nvme_id_ctrl_nwpc - - This field indicates the optional namespace write protection capabilities supported by the controller. - -**Constants** - -``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. - -``NVME_CTRL_NWPC_WRITE_PROTECT_POWER_CYCLE`` - If set, then the controller - 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. - - - - -.. c:type:: enum nvme_id_ctrl_sgls - - This field indicates if SGLs are supported for the NVM Command Set and the particular SGL types supported. - -**Constants** - -``NVME_CTRL_SGLS_SUPPORTED`` - -``NVME_CTRL_SGLS_KEYED`` - -``NVME_CTRL_SGLS_BIT_BUCKET`` - -``NVME_CTRL_SGLS_MPTR_BYTE_ALIGNED`` - -``NVME_CTRL_SGLS_OVERSIZE`` - -``NVME_CTRL_SGLS_MPTR_SGL`` - -``NVME_CTRL_SGLS_OFFSET`` - -``NVME_CTRL_SGLS_TPORT`` - - - - -.. c:type:: enum nvme_id_ctrl_fcatt - - This field indicates attributes of the controller that are specific to NVMe over Fabrics. - -**Constants** - -``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. - - - - -.. c:type:: enum nvme_id_ctrl_ofcs - - Indicate whether the controller supports optional fabric commands. - -**Constants** - -``NVME_CTRL_OFCS_DISCONNECT`` - If set, then the controller supports the - Disconnect command and deletion of individual - I/O Queues. - - - - -.. c:type:: struct nvme_lbaf - - LBA Format Data Structure - -**Definition** - -:: - - struct nvme_lbaf { - __le16 ms; - __u8 ds; - __u8 rp; - }; - -**Members** - -``ms`` - Metadata Size indicates the number of metadata bytes provided per LBA - based on the LBA Data Size indicated. - -``ds`` - LBA Data Size indicates the LBA data size supported, reported as a - power of two. - -``rp`` - Relative Performance, see :c:type:`enum nvme_lbaf_rp `. - - - - - -.. c:type:: enum nvme_lbaf_rp - - This field indicates the relative performance of the LBA format indicated relative to other LBA formats supported by the controller. - -**Constants** - -``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 - - - - -.. c:type:: struct nvme_id_ns - - Identify Namespace data structure - -**Definition** - -:: - - struct nvme_id_ns { - __le64 nsze; - __le64 ncap; - __le64 nuse; - __u8 nsfeat; - __u8 nlbaf; - __u8 flbas; - __u8 mc; - __u8 dpc; - __u8 dps; - __u8 nmic; - __u8 rescap; - __u8 fpi; - __u8 dlfeat; - __le16 nawun; - __le16 nawupf; - __le16 nacwu; - __le16 nabsn; - __le16 nabo; - __le16 nabspf; - __le16 noiob; - __u8 nvmcap[16]; - __le16 npwg; - __le16 npwa; - __le16 npdg; - __le16 npda; - __le16 nows; - __le16 mssrl; - __le32 mcl; - __u8 msrc; - __u8 rsvd81[11]; - __le32 anagrpid; - __u8 rsvd96[3]; - __u8 nsattr; - __le16 nvmsetid; - __le16 endgid; - __u8 nguid[16]; - __u8 eui64[8]; - struct nvme_lbaf lbaf[64]; - __u8 vs[3712]; - }; - -**Members** - -``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. - -``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. - -``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. - -``nsfeat`` - Namespace Features, see :c:type:`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 :c:type:`struct nvme_id_ns `.lbaf. - -``flbas`` - Formatted LBA Size, see :c:type:`enum nvme_id_ns_flbas `. - -``mc`` - Metadata Capabilities, see :c:type:`enum nvme_id_ns_mc `. - -``dpc`` - End-to-end Data Protection Capabilities, see - :c:type:`enum nvme_id_ns_dpc `. - -``dps`` - End-to-end Data Protection Type Settings, see - :c:type:`enum nvme_id_ns_dps `. - -``nmic`` - Namespace Multi-path I/O and Namespace Sharing Capabilities, see - :c:type:`enum nvme_id_ns_nmic `. - -``rescap`` - Reservation Capabilities, see :c:type:`enum nvme_id_ns_rescap `. - -``fpi`` - Format Progress Indicator, see :c:type:`enum nvme_nd_ns_fpi `. - -``dlfeat`` - Deallocate Logical Block Features, see :c:type:`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. - -``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. - -``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. - -``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. - -``nabo`` - Namespace Atomic Boundary Offset indicates the LBA on this - 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. - -``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. - -``nvmcap`` - NVM Capacity indicates the total size of the NVM allocated to - 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. - -``npwa`` - Namespace Preferred Write Alignment indicates the recommended - 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. - -``npda`` - Namespace Preferred Deallocate Alignment indicates the - 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. - -``mssrl`` - -``mcl`` - -``msrc`` - -``rsvd81`` - Reserved - -``anagrpid`` - ANA Group Identifier indicates the ANA Group Identifier of the - ANA group of which the namespace is a member. - -``rsvd96`` - Reserved - -``nsattr`` - Namespace Attributes, see :c:type:`enum nvme_id_ns_attr `. - -``nvmsetid`` - NVM Set Identifier indicates the NVM Set with which this - namespace is associated. - -``endgid`` - Endurance Group Identifier indicates the Endurance Group with - 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 - -``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 - remains fixed throughout the life of the namespace and is - preserved across namespace and controller operations - -``lbaf`` - LBA Format, see :c:type:`struct nvme_lbaf `. - -``vs`` - Vendor Specific - - - - - -.. c:type:: enum nvme_id_nsfeat - - This field defines features of the namespace. - -**Constants** - -``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. - -``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. - -``NVME_NS_FEAT_DULBE`` - If set, indicates that the controller supports the - 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. - -``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 - - - - -.. c:type:: enum nvme_id_ns_flbas - - This field indicates the LBA data size & metadata size combination that the namespace has been formatted with - -**Constants** - -``NVME_NS_FLBAS_LOWER_MASK`` - Mask to get the index of one of the supported - LBA Formats's least significant - 4bits indicated in - :c:type:`struct nvme_id_ns `.lbaf. - -``NVME_NS_FLBAS_META_EXT`` - Applicable only if format contains metadata. If - this bit is set, indicates that the metadata is - transferred at the end of the data LBA, creating an - 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 - the supported LBA Formats's most significant - 2bits indicated in - :c:type:`struct nvme_id_ns `.lbaf. - - - - -.. c:type:: enum nvme_id_ns_mc - - This field indicates the capabilities for metadata. - -**Constants** - -``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. - -``NVME_NS_MC_SEPARATE`` - If set, indicates that the namespace supports the - metadata being transferred as part of an extended data LBA. - - - - -.. c:type:: enum nvme_id_ns_dpc - - This field indicates the capabilities for the end-to-end data protection feature. - -**Constants** - -``NVME_NS_DPC_PI_TYPE1`` - If set, indicates that the namespace supports - Protection Information Type 1. - -``NVME_NS_DPC_PI_TYPE2`` - If set, indicates that the namespace supports - Protection Information Type 2. - -``NVME_NS_DPC_PI_TYPE3`` - If set, indicates that the namespace supports - 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. - -``NVME_NS_DPC_PI_LAST`` - If set, indicates that the namespace supports - protection information transferred as the last eight - bytes of metadata. - - - - -.. c:type:: enum nvme_id_ns_dps - - This field indicates the Type settings for the end-to-end data protection feature. - -**Constants** - -``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. - - - - -.. c:type:: enum nvme_id_ns_nmic - - This field specifies multi-path I/O and namespace sharing capabilities of the namespace. - -**Constants** - -``NVME_NS_NMIC_SHARED`` - If set, then the namespace may be attached to two or - more controllers in the NVM subsystem concurrently - - - - -.. c:type:: enum nvme_id_ns_rescap - - This field indicates the reservation capabilities of the namespace. - -**Constants** - -``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. - -``NVME_NS_RESCAP_WERO`` - If set, indicates that the namespace supports the - Write Exclusive - Registrants Only reservation type. - -``NVME_NS_RESCAP_EARO`` - If set, indicates that the namespace supports the - Exclusive Access - Registrants Only reservation type. - -``NVME_NS_RESCAP_WEAR`` - If set, indicates that the namespace supports the - Write Exclusive - All Registrants reservation type. - -``NVME_NS_RESCAP_EAAR`` - If set, indicates that the namespace supports the - 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. - - - - -.. c:type:: 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. - -**Constants** - -``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. - - - - -.. c:type:: enum nvme_id_ns_dlfeat - - This field indicates information about features that affect deallocating logical blocks for this namespace. - -**Constants** - -``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_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 - - - - -.. c:type:: enum nvme_id_ns_attr - - Specifies attributes of the namespace. - -**Constants** - -``NVME_NS_NSATTR_WRITE_PROTECTED`` - If set, then the namespace is currently - write protected and all write access to the - namespace shall fail. - - - - -.. c:type:: struct nvme_ns_id_desc - - -**Definition** - -:: - - struct nvme_ns_id_desc { - __u8 nidt; - __u8 nidl; - __le16 rsvd; - __u8 nid[]; - }; - -**Members** - -``nidt`` - Namespace Identifier Type, see :c:type:`enum nvme_ns_id_desc_nidt ` - -``nidl`` - Namespace Identifier Length contains the length in bytes of the - :c:type:`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 :c:type:`struct nvme_id_ns `.nidl. - - - - - -.. c:type:: enum nvme_ns_id_desc_nidt - - Known namespace identifier types - -**Constants** - -``NVME_NIDT_EUI64`` - IEEE Extended Unique Identifier, the NID field contains a - 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. - -``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. - - - - -.. c:type:: struct nvme_nvmset_attr - - NVM Set Attributes Entry - -**Definition** - -:: - - struct nvme_nvmset_attr { - __le16 nvmsetid; - __le16 endgid; - __u8 rsvd4[4]; - __le32 rr4kt; - __le32 ows; - __u8 tnvmsetcap[16]; - __u8 unvmsetcap[16]; - __u8 rsvd48[80]; - }; - -**Members** - -``nvmsetid`` - NVM Set Identifier - -``endgid`` - Endurance Group Identifier - -``rsvd4`` - Reserved - -``rr4kt`` - Random 4 KiB Read Typical indicates the typical - time to complete a 4 KiB random read in 100 nanosecond units - when the NVM Set is in a Predictable Latency Mode Deterministic - Window and there is 1 outstanding command per NVM Set. - -``ows`` - Optimal Write Size - -``tnvmsetcap`` - Total NVM Set Capacity - -``unvmsetcap`` - Unallocated NVM Set Capacity - -``rsvd48`` - Reserved - - - - - -.. c:type:: struct nvme_id_nvmset_list - - -**Definition** - -:: - - struct nvme_id_nvmset_list { - __u8 nid; - __u8 rsvd1[127]; - struct nvme_nvmset_attr ent[NVME_ID_NVMSET_LIST_MAX]; - }; - -**Members** - -``nid`` - Nvmset id - -``rsvd1`` - Reserved - -``ent`` - nvmset id list - - - - - -.. c:type:: struct nvme_id_independent_id_ns - - -**Definition** - -:: - - struct nvme_id_independent_id_ns { - __u8 nsfeat; - __u8 nmic; - __u8 rescap; - __u8 fpi; - __le32 anagrpid; - __u8 nsattr; - __u8 rsvd9; - __le16 nvmsetid; - __le16 endgid; - __u8 nstat; - __u8 rsvd15[4081]; - }; - -**Members** - -``nsfeat`` - -``nmic`` - -``rescap`` - -``fpi`` - -``anagrpid`` - -``nsattr`` - -``rsvd9`` - -``nvmsetid`` - -``endgid`` - -``nstat`` - -``rsvd15`` - - - - - -.. c:type:: struct nvme_id_ns_granularity_desc - - -**Definition** - -:: - - struct nvme_id_ns_granularity_desc { - __le64 nszegran; - __le64 ncapgran; - }; - -**Members** - -``nszegran`` - -``ncapgran`` - - - - - -.. c:type:: struct nvme_id_ns_granularity_list - - -**Definition** - -:: - - struct nvme_id_ns_granularity_list { - __le32 attributes; - __u8 num_descriptors; - __u8 rsvd5[27]; - struct nvme_id_ns_granularity_desc entry[NVME_ID_ND_DESCRIPTOR_MAX]; - __u8 rsvd288[3808]; - }; - -**Members** - -``attributes`` - -``num_descriptors`` - -``rsvd5`` - -``entry`` - -``rsvd288`` - - - - - -.. c:type:: struct nvme_id_uuid_list_entry - - -**Definition** - -:: - - struct nvme_id_uuid_list_entry { - __u8 header; - __u8 rsvd1[15]; - __u8 uuid[16]; - }; - -**Members** - -``header`` - -``rsvd1`` - -``uuid`` - - - - - -.. c:type:: enum nvme_id_uuid - - -**Constants** - -``NVME_ID_UUID_HDR_ASSOCIATION_MASK`` - -``NVME_ID_UUID_ASSOCIATION_NONE`` - -``NVME_ID_UUID_ASSOCIATION_VENDOR`` - -``NVME_ID_UUID_ASSOCIATION_SUBSYSTEM_VENDOR`` - - - - -.. c:type:: struct nvme_id_uuid_list - - -**Definition** - -:: - - struct nvme_id_uuid_list { - __u8 rsvd0[32]; - struct nvme_id_uuid_list_entry entry[NVME_ID_UUID_LIST_MAX]; - }; - -**Members** - -``rsvd0`` - -``entry`` - - - - - -.. c:type:: struct nvme_ctrl_list - - -**Definition** - -:: - - struct nvme_ctrl_list { - __le16 num; - __le16 identifier[NVME_ID_CTRL_LIST_MAX]; - }; - -**Members** - -``num`` - -``identifier`` - - - - - -.. c:type:: struct nvme_ns_list - - -**Definition** - -:: - - struct nvme_ns_list { - __le32 ns[NVME_ID_NS_LIST_MAX]; - }; - -**Members** - -``ns`` - - - - - -.. c:type:: struct nvme_id_ctrl_nvm - - -**Definition** - -:: - - struct nvme_id_ctrl_nvm { - __u8 vsl; - __u8 wzsl; - __u8 wusl; - __u8 dmrl; - __u32 dmrsl; - __u64 dmsl; - __u8 rsvd16[4080]; - }; - -**Members** - -``vsl`` - -``wzsl`` - -``wusl`` - -``dmrl`` - -``dmrsl`` - -``dmsl`` - -``rsvd16`` - - - - - -.. c:type:: struct nvme_zns_lbafe - - -**Definition** - -:: - - struct nvme_zns_lbafe { - __le64 zsze; - __u8 zdes; - __u8 rsvd9[7]; - }; - -**Members** - -``zsze`` - -``zdes`` - -``rsvd9`` - - - - - -.. c:type:: struct nvme_zns_id_ns - - Zoned Namespace Command Set Specific Identify Namespace Data Structure - -**Definition** - -:: - - struct nvme_zns_id_ns { - __le16 zoc; - __le16 ozcs; - __le32 mar; - __le32 mor; - __le32 rrl; - __le32 frl; - __le32 rrl1; - __le32 rrl2; - __le32 rrl3; - __le32 frl1; - __le32 frl2; - __le32 frl3; - __le32 numzrwa; - __le16 zrwafg; - __le16 zrwasz; - __u8 zrwacap; - __u8 rsvd53[2763]; - struct nvme_zns_lbafe lbafe[64]; - __u8 vs[256]; - }; - -**Members** - -``zoc`` - Zone Operation Characteristics - -``ozcs`` - Optional Zoned Command Support - -``mar`` - Maximum Active Resources - -``mor`` - Maximum Open Resources - -``rrl`` - Reset Recommended Limit - -``frl`` - Finish Recommended Limit - -``rrl1`` - Reset Recommended Limit 1 - -``rrl2`` - Reset Recommended Limit 2 - -``rrl3`` - Reset Recommended Limit 3 - -``frl1`` - Finish Recommended Limit 1 - -``frl2`` - Finish Recommended Limit 2 - -``frl3`` - Finish Recommended Limit 3 - -``numzrwa`` - Number of ZRWA Resources - -``zrwafg`` - ZRWA Flush Granularity - -``zrwasz`` - ZRWA Size - -``zrwacap`` - ZRWA Capability - -``rsvd53`` - Reserved - -``lbafe`` - LBA Format Extension - -``vs`` - Vendor Specific - - - - - -.. c:type:: struct nvme_zns_id_ctrl - - -**Definition** - -:: - - struct nvme_zns_id_ctrl { - __u8 zasl; - __u8 rsvd1[4095]; - }; - -**Members** - -``zasl`` - -``rsvd1`` - Reserved - - - - - -.. c:type:: struct nvme_primary_ctrl_cap - - -**Definition** - -:: - - struct nvme_primary_ctrl_cap { - __le16 cntlid; - __le16 portid; - __u8 crt; - __u8 rsvd5[27]; - __le32 vqfrt; - __le32 vqrfa; - __le16 vqrfap; - __le16 vqprt; - __le16 vqfrsm; - __le16 vqgran; - __u8 rsvd48[16]; - __le32 vifrt; - __le32 virfa; - __le16 virfap; - __le16 viprt; - __le16 vifrsm; - __le16 vigran; - __u8 rsvd80[4016]; - }; - -**Members** - -``cntlid`` - -``portid`` - -``crt`` - -``rsvd5`` - -``vqfrt`` - -``vqrfa`` - -``vqrfap`` - -``vqprt`` - -``vqfrsm`` - -``vqgran`` - -``rsvd48`` - -``vifrt`` - -``virfa`` - -``virfap`` - -``viprt`` - -``vifrsm`` - -``vigran`` - -``rsvd80`` - - - - - -.. c:type:: struct nvme_secondary_ctrl - - -**Definition** - -:: - - struct nvme_secondary_ctrl { - __le16 scid; - __le16 pcid; - __u8 scs; - __u8 rsvd5[3]; - __le16 vfn; - __le16 nvq; - __le16 nvi; - __u8 rsvd14[18]; - }; - -**Members** - -``scid`` - -``pcid`` - -``scs`` - -``rsvd5`` - -``vfn`` - -``nvq`` - -``nvi`` - -``rsvd14`` - - - - - -.. c:type:: struct nvme_secondary_ctrl_list - - -**Definition** - -:: - - struct nvme_secondary_ctrl_list { - __u8 num; - __u8 rsvd[31]; - struct nvme_secondary_ctrl sc_entry[NVME_ID_SECONDARY_CTRL_MAX]; - }; - -**Members** - -``num`` - -``rsvd`` - -``sc_entry`` - - - - - -.. c:type:: struct nvme_id_iocs - - NVMe Identify IO Command Set data structure - -**Definition** - -:: - - struct nvme_id_iocs { - __u64 iocsc[512]; - }; - -**Members** - -``iocsc`` - List of supported IO Command Set Combination vectors - - - - - -.. c:type:: struct nvme_id_domain_attr - - Domain Attributes Entry - -**Definition** - -:: - - struct nvme_id_domain_attr { - __le16 dom_id; - __u8 rsvd2[14]; - __u8 dom_cap[16]; - __u8 unalloc_dom_cap[16]; - __u8 max_egrp_dom_cap[16]; - __u8 rsvd64[64]; - }; - -**Members** - -``dom_id`` - -``rsvd2`` - -``dom_cap`` - -``unalloc_dom_cap`` - -``max_egrp_dom_cap`` - -``rsvd64`` - - - - - -.. c:type:: struct nvme_id_domain_list - - -**Definition** - -:: - - struct nvme_id_domain_list { - __u8 num; - __u8 rsvd[127]; - struct nvme_id_domain_attr domain_attr[NVME_ID_DOMAIN_LIST_MAX]; - }; - -**Members** - -``num`` - Number of domain attributes - -``rsvd`` - Reserved - -``domain_attr`` - List of domain attributes - - - - - -.. c:type:: struct nvme_id_endurance_group_list - - -**Definition** - -:: - - struct nvme_id_endurance_group_list { - __le16 num; - __le16 identifier[NVME_ID_ENDURANCE_GROUP_LIST_MAX]; - }; - -**Members** - -``num`` - -``identifier`` - - - - - -.. c:type:: struct nvme_supported_log_pages - - -**Definition** - -:: - - struct nvme_supported_log_pages { - __le32 lid_support[NVME_LOG_SUPPORTED_LOG_PAGES_MAX]; - }; - -**Members** - -``lid_support`` - - -**Description** - -Supported Log Pages (Log Identifier 00h) - - - - -.. c:type:: struct nvme_error_log_page - - Error Information Log Entry (Log Identifier 01h) - -**Definition** - -:: - - struct nvme_error_log_page { - __le64 error_count; - __le16 sqid; - __le16 cmdid; - __le16 status_field; - __le16 parm_error_location; - __le64 lba; - __le32 nsid; - __u8 vs; - __u8 trtype; - __u8 rsvd[2]; - __le64 cs; - __le16 trtype_spec_info; - __u8 rsvd2[22]; - }; - -**Members** - -``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. - -``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``. - -``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``. - -``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. - -``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. - Bits 7-0: Byte in command that contained the error. - Valid values are 0 to 63. - -``lba`` - LBA: This field indicates the first LBA that experienced - the error condition, if applicable. - -``nsid`` - Namespace: This field indicates the NSID of the namespace - 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``. - -``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 :c:type:`enum nvme_trtype `. - -``rsvd`` - Reserved - -``cs`` - Command Specific Information: This field contains command - specific information. If used, the command definition - specifies the information returned. - -``trtype_spec_info`` - -``rsvd2`` - - - - - -.. c:type:: enum nvme_err_pel - - -**Constants** - -``NVME_ERR_PEL_BYTE_MASK`` - -``NVME_ERR_PEL_BIT_MASK`` - - - - -.. c:type:: struct nvme_smart_log - - SMART / Health Information Log (Log Identifier 02h) - -**Definition** - -:: - - struct nvme_smart_log { - __u8 critical_warning; - __u8 temperature[2]; - __u8 avail_spare; - __u8 spare_thresh; - __u8 percent_used; - __u8 endu_grp_crit_warn_sumry; - __u8 rsvd7[25]; - __u8 data_units_read[16]; - __u8 data_units_written[16]; - __u8 host_reads[16]; - __u8 host_writes[16]; - __u8 ctrl_busy_time[16]; - __u8 power_cycles[16]; - __u8 power_on_hours[16]; - __u8 unsafe_shutdowns[16]; - __u8 media_errors[16]; - __u8 num_err_log_entries[16]; - __le32 warning_temp_time; - __le32 critical_comp_time; - __le16 temp_sensor[8]; - __le32 thm_temp1_trans_count; - __le32 thm_temp2_trans_count; - __le32 thm_temp1_total_time; - __le32 thm_temp2_total_time; - __u8 rsvd232[280]; - }; - -**Members** - -``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 :c:type:`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. - -``avail_spare`` - Available Spare: Contains a normalized percentage (0% - 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. - -``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). - -``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 :c:type:`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. - -``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. - -``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. - -``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. - -``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. - -``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. - -``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. - -``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. - -``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``. - -``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. - -``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. - -``thm_temp2_total_time`` - Total Time For Thermal Management Temperature 2 - -``rsvd232`` - Reserved - - - - - -.. c:type:: enum nvme_smart_crit - - Critical Warning - -**Constants** - -``NVME_SMART_CRIT_SPARE`` - If set, then the available spare capacity has fallen - 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. - -``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. - -``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. - -``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. - -``NVME_SMART_CRIT_PMR_RO`` - If set, then the Persistent Memory Region has become - read-only or unreliable. - - - - -.. c:type:: enum nvme_smart_egcw - - Endurance Group Critical Warning Summary - -**Constants** - -``NVME_SMART_EGCW_SPARE`` - If set, then the available spare capacity of one or - 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. - - - - -.. c:type:: struct nvme_firmware_slot - - -**Definition** - -:: - - struct nvme_firmware_slot { - __u8 afi; - __u8 rsvd1[7]; - char frs[7][8]; - __u8 rsvd2[448]; - }; - -**Members** - -``afi`` - -``rsvd1`` - -``frs`` - -``rsvd2`` - - - - - -.. c:type:: struct nvme_cmd_effects_log - - -**Definition** - -:: - - struct nvme_cmd_effects_log { - __le32 acs[256]; - __le32 iocs[256]; - __u8 rsvd[2048]; - }; - -**Members** - -``acs`` - -``iocs`` - -``rsvd`` - - - - - -.. c:type:: enum nvme_cmd_effects - - -**Constants** - -``NVME_CMD_EFFECTS_CSUPP`` - -``NVME_CMD_EFFECTS_LBCC`` - -``NVME_CMD_EFFECTS_NCC`` - -``NVME_CMD_EFFECTS_NIC`` - -``NVME_CMD_EFFECTS_CCC`` - -``NVME_CMD_EFFECTS_CSE_MASK`` - -``NVME_CMD_EFFECTS_UUID_SEL`` - - - - -.. c:type:: struct nvme_st_result - - Self-test Result - -**Definition** - -:: - - struct nvme_st_result { - __u8 dsts; - __u8 seg; - __u8 vdi; - __u8 rsvd; - __le64 poh; - __le32 nsid; - __le64 flba; - __u8 sct; - __u8 sc; - __u8 vs[2]; - }; - -**Members** - -``dsts`` - Device Self-test Status: Indicates the device self-test code and the - status of the operation (see :c:type:`enum nvme_status_result ` and :c:type:`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. - -``vdi`` - Valid Diagnostic Information: Indicates the diagnostic failure - information that is reported. See :c:type:`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. - -``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. - -``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. - -``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 :c:type:`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. - -``vs`` - Vendor Specific. - - - - - -.. c:type:: enum nvme_status_result - - Result of the device self-test operation - -**Constants** - -``NVME_ST_RESULT_NO_ERR`` - Operation completed without error. - -``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. - -``NVME_ST_RESULT_ABORTED_FORMAT`` - Operation was aborted due to the processing - 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. - -``NVME_ST_RESULT_UNKNOWN_SEG_FAIL`` - Operation completed with a segment that failed - 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. - -``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 :c:type:`struct nvme_st_result `.dsts field. - - - - -.. c:type:: enum nvme_st_code - - Self-test Code value - -**Constants** - -``NVME_ST_CODE_RESERVED`` - Reserved. - -``NVME_ST_CODE_SHORT`` - Short device self-test operation. - -``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 - :c:type:`struct nvme_st_result `.dsts field. - - - - -.. c:type:: enum nvme_st_curr_op - - Current Device Self-Test Operation - -**Constants** - -``NVME_ST_CURR_OP_NOT_RUNNING`` - No device self-test operation in progress. - -``NVME_ST_CURR_OP_SHORT`` - Short device self-test operation in progress. - -``NVME_ST_CURR_OP_EXTENDED`` - Extended device self-test operation in progress. - -``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 - :c:type:`struct nvme_self_test_log `.current_operation field. - -``NVME_ST_CURR_OP_CMPL_MASK`` - Mask to get the current operation completion value - from the :c:type:`struct nvme_self_test_log `.completion field. - - - - -.. c:type:: enum nvme_st_valid_diag_info - - Valid Diagnostic Information - -**Constants** - -``NVME_ST_VALID_DIAG_INFO_NSID`` - NSID Valid: if set, then the contents of - 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. - -``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. - - - - -.. c:type:: struct nvme_self_test_log - - Device Self-test (Log Identifier 06h) - -**Definition** - -:: - - struct nvme_self_test_log { - __u8 current_operation; - __u8 completion; - __u8 rsvd[2]; - struct nvme_st_result result[NVME_LOG_ST_MAX_RESULTS]; - }; - -**Members** - -``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 :c:type:`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. - -``rsvd`` - Reserved - -``result`` - Self-test Result Data Structures, see :c:type:`struct nvme_st_result `. - - - - - -.. c:type:: enum nvme_cmd_get_log_telemetry_host_lsp - - -**Constants** - -``NVME_LOG_TELEM_HOST_LSP_RETAIN`` - -``NVME_LOG_TELEM_HOST_LSP_CREATE`` - - - - -.. c:type:: struct nvme_telemetry_log - - Retrieve internal data specific to the manufacturer. - -**Definition** - -:: - - struct nvme_telemetry_log { - __u8 lpi; - __u8 rsvd1[4]; - __u8 ieee[3]; - __le16 dalb1; - __le16 dalb2; - __le16 dalb3; - __u8 rsvd14[2]; - __le32 dalb4; - __u8 rsvd20[362]; - __u8 ctrlavail; - __u8 ctrldgn; - __u8 rsnident[128]; - __u8 data_area[]; - }; - -**Members** - -``lpi`` - Log Identifier, either ``NVME_LOG_LID_TELEMETRY_HOST`` or - ``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. - -``dalb1`` - Telemetry Controller-Initiated Data Area 1 Last Block is - 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. - -``dalb3`` - Telemetry Controller-Initiated Data Area 1 Last Block is - 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. - -``rsvd20`` - Reserved - -``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. - -``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. - -``data_area`` - Telemetry data blocks, vendor specific information data. - - -**Description** - -This log consists of a header describing the log and zero or more Telemetry -Data Blocks. All Telemetry Data Blocks are ``NVME_LOG_TELEM_BLOCK_SIZE``, 512 -bytes, in size. This log captures the controller’s internal state. - - - - -.. c:type:: struct nvme_endurance_group_log - - -**Definition** - -:: - - struct nvme_endurance_group_log { - __u8 critical_warning; - __u8 rsvd1[2]; - __u8 avl_spare; - __u8 avl_spare_threshold; - __u8 percent_used; - __u8 rsvd6[26]; - __u8 endurance_estimate[16]; - __u8 data_units_read[16]; - __u8 data_units_written[16]; - __u8 media_units_written[16]; - __u8 host_read_cmds[16]; - __u8 host_write_cmds[16]; - __u8 media_data_integrity_err[16]; - __u8 num_err_info_log_entries[16]; - __u8 rsvd160[352]; - }; - -**Members** - -``critical_warning`` - -``rsvd1`` - -``avl_spare`` - -``avl_spare_threshold`` - -``percent_used`` - -``rsvd6`` - -``endurance_estimate`` - -``data_units_read`` - -``data_units_written`` - -``media_units_written`` - -``host_read_cmds`` - -``host_write_cmds`` - -``media_data_integrity_err`` - -``num_err_info_log_entries`` - -``rsvd160`` - - - - - -.. c:type:: enum nvme_eg_critical_warning_flags - - -**Constants** - -``NVME_EG_CRITICAL_WARNING_SPARE`` - -``NVME_EG_CRITICAL_WARNING_DEGRADED`` - -``NVME_EG_CRITICAL_WARNING_READ_ONLY`` - - - - -.. c:type:: struct nvme_aggregate_endurance_group_event - - -**Definition** - -:: - - struct nvme_aggregate_endurance_group_event { - __le64 num_entries; - __le16 entries[]; - }; - -**Members** - -``num_entries`` - Number or entries - -``entries`` - List of entries - - - - - -.. c:type:: struct nvme_nvmset_predictable_lat_log - - -**Definition** - -:: - - struct nvme_nvmset_predictable_lat_log { - __u8 status; - __u8 rsvd1; - __le16 event_type; - __u8 rsvd4[28]; - __le64 dtwin_rt; - __le64 dtwin_wt; - __le64 dtwin_tmax; - __le64 ndwin_tmin_hi; - __le64 ndwin_tmin_lo; - __u8 rsvd72[56]; - __le64 dtwin_re; - __le64 dtwin_we; - __le64 dtwin_te; - __u8 rsvd152[360]; - }; - -**Members** - -``status`` - -``rsvd1`` - -``event_type`` - -``rsvd4`` - -``dtwin_rt`` - -``dtwin_wt`` - -``dtwin_tmax`` - -``ndwin_tmin_hi`` - -``ndwin_tmin_lo`` - -``rsvd72`` - -``dtwin_re`` - -``dtwin_we`` - -``dtwin_te`` - -``rsvd152`` - - - - - -.. c:type:: enum nvme_nvmeset_pl_status - - -**Constants** - -``NVME_NVMSET_PL_STATUS_DISABLED`` - -``NVME_NVMSET_PL_STATUS_DTWIN`` - -``NVME_NVMSET_PL_STATUS_NDWIN`` - - - - -.. c:type:: enum nvme_nvmset_pl_events - - -**Constants** - -``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`` - - - - -.. c:type:: struct nvme_aggregate_predictable_lat_event - - -**Definition** - -:: - - struct nvme_aggregate_predictable_lat_event { - __le64 num_entries; - __le16 entries[]; - }; - -**Members** - -``num_entries`` - Number of entries - -``entries`` - Entry list - - - - - -.. c:type:: struct nvme_ana_group_desc - - -**Definition** - -:: - - struct nvme_ana_group_desc { - __le32 grpid; - __le32 nnsids; - __le64 chgcnt; - __u8 state; - __u8 rsvd17[15]; - __le32 nsids[]; - }; - -**Members** - -``grpid`` - ANA group id - -``nnsids`` - Number of namespaces in **nsids** - -``chgcnt`` - Change counter - -``state`` - ANA state - -``rsvd17`` - Reserved - -``nsids`` - List of namespaces - - - - - -.. c:type:: enum nvme_ana_state - - -**Constants** - -``NVME_ANA_STATE_OPTIMIZED`` - -``NVME_ANA_STATE_NONOPTIMIZED`` - -``NVME_ANA_STATE_INACCESSIBLE`` - -``NVME_ANA_STATE_PERSISTENT_LOSS`` - -``NVME_ANA_STATE_CHANGE`` - - - - -.. c:type:: struct nvme_ana_log - - -**Definition** - -:: - - struct nvme_ana_log { - __le64 chgcnt; - __le16 ngrps; - __u8 rsvd10[6]; - struct nvme_ana_group_desc descs[]; - }; - -**Members** - -``chgcnt`` - -``ngrps`` - -``rsvd10`` - -``descs`` - - - - - -.. c:type:: struct nvme_persistent_event_log - - -**Definition** - -:: - - struct nvme_persistent_event_log { - __u8 lid; - __u8 rsvd1[3]; - __le32 tnev; - __le64 tll; - __u8 rv; - __u8 rsvd17; - __le16 lhl; - __le64 ts; - __u8 poh[16]; - __le64 pcc; - __le16 vid; - __le16 ssvid; - char sn[20]; - char mn[40]; - char subnqn[NVME_NQN_LENGTH]; - __le16 gen_number; - __le32 rci; - __u8 rsvd378[102]; - __u8 seb[32]; - }; - -**Members** - -``lid`` - -``rsvd1`` - -``tnev`` - -``tll`` - -``rv`` - -``rsvd17`` - -``lhl`` - -``ts`` - -``poh`` - -``pcc`` - -``vid`` - -``ssvid`` - -``sn`` - -``mn`` - -``subnqn`` - -``gen_number`` - -``rci`` - -``rsvd378`` - -``seb`` - - - - - -.. c:type:: struct nvme_persistent_event_entry - - -**Definition** - -:: - - struct nvme_persistent_event_entry { - __u8 etype; - __u8 etype_rev; - __u8 ehl; - __u8 rsvd3; - __le16 cntlid; - __le64 ets; - __u8 rsvd14[6]; - __le16 vsil; - __le16 el; - }; - -**Members** - -``etype`` - -``etype_rev`` - -``ehl`` - -``rsvd3`` - -``cntlid`` - -``ets`` - -``rsvd14`` - -``vsil`` - -``el`` - - - - - -.. c:type:: enum nvme_persistent_event_types - - -**Constants** - -``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`` - - - - -.. c:type:: struct nvme_fw_commit_event - - -**Definition** - -:: - - 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; - }; - -**Members** - -``old_fw_rev`` - -``new_fw_rev`` - -``fw_commit_action`` - -``fw_slot`` - -``sct_fw`` - -``sc_fw`` - -``vndr_assign_fw_commit_rc`` - - - - - -.. c:type:: struct nvme_time_stamp_change_event - - -**Definition** - -:: - - struct nvme_time_stamp_change_event { - __le64 previous_timestamp; - __le64 ml_secs_since_reset; - }; - -**Members** - -``previous_timestamp`` - -``ml_secs_since_reset`` - - - - - -.. c:type:: struct nvme_power_on_reset_info_list - - -**Definition** - -:: - - 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; - }; - -**Members** - -``cid`` - -``fw_act`` - -``op_in_prog`` - -``rsvd4`` - -``ctrl_power_cycle`` - -``power_on_ml_seconds`` - -``ctrl_time_stamp`` - - - - - -.. c:type:: struct nvme_nss_hw_err_event - - -**Definition** - -:: - - struct nvme_nss_hw_err_event { - __le16 nss_hw_err_event_code; - __u8 rsvd2[2]; - __u8 *add_hw_err_info; - }; - -**Members** - -``nss_hw_err_event_code`` - -``rsvd2`` - -``add_hw_err_info`` - - - - - -.. c:type:: struct nvme_change_ns_event - - -**Definition** - -:: - - struct nvme_change_ns_event { - __le32 nsmgt_cdw10; - __u8 rsvd4[4]; - __le64 nsze; - __u8 rsvd16[8]; - __le64 nscap; - __u8 flbas; - __u8 dps; - __u8 nmic; - __u8 rsvd35; - __le32 ana_grp_id; - __le16 nvmset_id; - __le16 rsvd42; - __le32 nsid; - }; - -**Members** - -``nsmgt_cdw10`` - -``rsvd4`` - -``nsze`` - -``rsvd16`` - -``nscap`` - -``flbas`` - -``dps`` - -``nmic`` - -``rsvd35`` - -``ana_grp_id`` - -``nvmset_id`` - -``rsvd42`` - -``nsid`` - - - - - -.. c:type:: struct nvme_format_nvm_start_event - - -**Definition** - -:: - - struct nvme_format_nvm_start_event { - __le32 nsid; - __u8 fna; - __u8 rsvd5[3]; - __le32 format_nvm_cdw10; - }; - -**Members** - -``nsid`` - -``fna`` - -``rsvd5`` - -``format_nvm_cdw10`` - - - - - -.. c:type:: struct nvme_format_nvm_compln_event - - -**Definition** - -:: - - struct nvme_format_nvm_compln_event { - __le32 nsid; - __u8 smallest_fpi; - __u8 format_nvm_status; - __le16 compln_info; - __le32 status_field; - }; - -**Members** - -``nsid`` - -``smallest_fpi`` - -``format_nvm_status`` - -``compln_info`` - -``status_field`` - - - - - -.. c:type:: struct nvme_sanitize_start_event - - -**Definition** - -:: - - struct nvme_sanitize_start_event { - __le32 sani_cap; - __le32 sani_cdw10; - __le32 sani_cdw11; - }; - -**Members** - -``sani_cap`` - -``sani_cdw10`` - -``sani_cdw11`` - - - - - -.. c:type:: struct nvme_sanitize_compln_event - - -**Definition** - -:: - - struct nvme_sanitize_compln_event { - __le16 sani_prog; - __le16 sani_status; - __le16 cmpln_info; - __u8 rsvd6[2]; - }; - -**Members** - -``sani_prog`` - -``sani_status`` - -``cmpln_info`` - -``rsvd6`` - - - - - -.. c:type:: struct nvme_set_feature_event - - -**Definition** - -:: - - struct nvme_set_feature_event { - __le32 layout; - __le32 cdw_mem[0]; - }; - -**Members** - -``layout`` - -``cdw_mem`` - - - - - -.. c:type:: struct nvme_thermal_exc_event - - -**Definition** - -:: - - struct nvme_thermal_exc_event { - __u8 over_temp; - __u8 threshold; - }; - -**Members** - -``over_temp`` - -``threshold`` - - - - - -.. c:type:: struct nvme_lba_rd - - -**Definition** - -:: - - struct nvme_lba_rd { - __le64 rslba; - __le32 rnlb; - __u8 rsvd12[4]; - }; - -**Members** - -``rslba`` - -``rnlb`` - -``rsvd12`` - - - - - -.. c:type:: struct nvme_lbas_ns_element - - -**Definition** - -:: - - struct nvme_lbas_ns_element { - __le32 neid; - __le32 nlrd; - __u8 ratype; - __u8 rsvd8[7]; - struct nvme_lba_rd lba_rd[]; - }; - -**Members** - -``neid`` - -``nlrd`` - -``ratype`` - -``rsvd8`` - -``lba_rd`` - - - - - -.. c:type:: enum nvme_lba_status_atype - - -**Constants** - -``NVME_LBA_STATUS_ATYPE_SCAN_UNTRACKED`` - -``NVME_LBA_STATUS_ATYPE_SCAN_TRACKED`` - - - - -.. c:type:: struct nvme_lba_status_log - - -**Definition** - -:: - - struct nvme_lba_status_log { - __le32 lslplen; - __le32 nlslne; - __le32 estulb; - __u8 rsvd12[2]; - __le16 lsgc; - struct nvme_lbas_ns_element elements[]; - }; - -**Members** - -``lslplen`` - -``nlslne`` - -``estulb`` - -``rsvd12`` - -``lsgc`` - -``elements`` - - - - - -.. c:type:: struct nvme_eg_event_aggregate_log - - -**Definition** - -:: - - struct nvme_eg_event_aggregate_log { - __le64 nr_entries; - __le16 egids[]; - }; - -**Members** - -``nr_entries`` - -``egids`` - - - - - -.. c:type:: enum nvme_fid_supported_effects - - -**Constants** - -``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`` - -**Description** - -FID Supported and Effects Data Structure definitions - - - - -.. c:type:: struct nvme_fid_supported_effects_log - - -**Definition** - -:: - - struct nvme_fid_supported_effects_log { - __le32 fid_support[NVME_LOG_FID_SUPPORTED_EFFECTS_MAX]; - }; - -**Members** - -``fid_support`` - - -**Description** - -Feature Identifiers Supported and Effects (Log Identifier 12h) - - - - -.. c:type:: struct nvme_boot_partition - - -**Definition** - -:: - - struct nvme_boot_partition { - __u8 lid; - __u8 rsvd1[3]; - __le32 bpinfo; - __u8 rsvd8[8]; - __u8 boot_partition_data[]; - }; - -**Members** - -``lid`` - -``rsvd1`` - -``bpinfo`` - -``rsvd8`` - -``boot_partition_data`` - - - - - -.. c:type:: struct nvme_media_unit_stat_desc - - -**Definition** - -:: - - struct nvme_media_unit_stat_desc { - __le16 muid; - __le16 domainid; - __le16 endgid; - __le16 nvmsetid; - __le16 cap_adj_fctr; - __u8 avl_spare; - __u8 percent_used; - __u8 mucs; - __u8 cio; - }; - -**Members** - -``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 - -``percent_used`` - Percentage Used - -``mucs`` - Number of Channels attached to media units - -``cio`` - Channel Identifiers Offset - - - - - -.. c:type:: struct nvme_media_unit_stat_log - - -**Definition** - -:: - - struct nvme_media_unit_stat_log { - __le16 nmu; - __le16 cchans; - __le16 sel_config; - __u8 rsvd6[10]; - struct nvme_media_unit_stat_desc mus_desc[]; - }; - -**Members** - -``nmu`` - Number unit status descriptor - -``cchans`` - Number of Channels - -``sel_config`` - Selected Configuration - -``rsvd6`` - Reserved - -``mus_desc`` - Media unit statistic descriptors - - - - - -.. c:type:: struct nvme_resv_notification_log - - -**Definition** - -:: - - struct nvme_resv_notification_log { - __le64 lpc; - __u8 rnlpt; - __u8 nalp; - __u8 rsvd9[2]; - __le32 nsid; - __u8 rsvd16[48]; - }; - -**Members** - -``lpc`` - -``rnlpt`` - See :c:type:`enum nvme_resv_notify_rnlpt `. - -``nalp`` - -``rsvd9`` - -``nsid`` - -``rsvd16`` - - - - - -.. c:type:: enum nvme_resv_notify_rnlpt - - -**Constants** - -``NVME_RESV_NOTIFY_RNLPT_EMPTY`` - -``NVME_RESV_NOTIFY_RNLPT_REGISTRATION_PREEMPTED`` - -``NVME_RESV_NOTIFY_RNLPT_RESERVATION_RELEASED`` - -``NVME_RESV_NOTIFY_RNLPT_RESERVATION_PREEMPTED`` - - - - -.. c:type:: struct nvme_sanitize_log_page - - Sanitize Status (Log Identifier 81h) - -**Definition** - -:: - - struct nvme_sanitize_log_page { - __le16 sprog; - __le16 sstat; - __le32 scdw10; - __le32 eto; - __le32 etbe; - __le32 etce; - __le32 etond; - __le32 etbend; - __le32 etcend; - __u8 rsvd32[480]; - }; - -**Members** - -``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``. - -``sstat`` - Sanitize Status (SSTAT): indicates the status associated with - the most recent sanitize operation. See :c:type:`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. - -``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. - -``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. - -``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. - -``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. - -``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. - -``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 - - - - - -.. c:type:: enum nvme_sanitize_sstat - - Sanitize Status (SSTAT) - -**Constants** - -``NVME_SANITIZE_SSTAT_STATUS_SHIFT`` - Shift amount to get the status value of - the most recent sanitize operation from - the :c:type:`struct nvme_sanitize_log_page `.sstat - field. - -``NVME_SANITIZE_SSTAT_STATUS_MASK`` - Mask to get the status value of the most - recent sanitize operation. - -``NVME_SANITIZE_SSTAT_STATUS_NEVER_SANITIZED`` - The NVM subsystem has never been - sanitized. - -``NVME_SANITIZE_SSTAT_STATUS_COMPLETE_SUCCESS`` - The most recent sanitize operation - 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. - -``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. - -``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. - -``NVME_SANITIZE_SSTAT_COMPLETED_PASSES_MASK`` - Mask to get the number of completed - passes. - -``NVME_SANITIZE_SSTAT_GLOBAL_DATA_ERASED_SHIFT`` - Shift amount to get the Global - Data Erased value from the - :c:type:`struct nvme_sanitize_log_page `.sstat field. - -``NVME_SANITIZE_SSTAT_GLOBAL_DATA_ERASED_MASK`` - Mask to get the Global Data Erased - 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. - - - - -.. c:type:: struct nvme_zns_changed_zone_log - - ZNS Changed Zone List log - -**Definition** - -:: - - struct nvme_zns_changed_zone_log { - __le16 nrzid; - __u8 rsvd2[6]; - __le64 zid[NVME_ZNS_CHANGED_ZONES_MAX]; - }; - -**Members** - -``nrzid`` - -``rsvd2`` - -``zid`` - - - - - -.. c:type:: enum nvme_zns_zt - - -**Constants** - -``NVME_ZONE_TYPE_SEQWRITE_REQ`` - - - - -.. c:type:: enum nvme_zns_za - - -**Constants** - -``NVME_ZNS_ZA_ZFC`` - -``NVME_ZNS_ZA_FZR`` - -``NVME_ZNS_ZA_RZR`` - -``NVME_ZNS_ZA_ZRWAV`` - -``NVME_ZNS_ZA_ZDEV`` - - - - -.. c:type:: enum nvme_zns_zs - - -**Constants** - -``NVME_ZNS_ZS_EMPTY`` - -``NVME_ZNS_ZS_IMPL_OPEN`` - -``NVME_ZNS_ZS_EXPL_OPEN`` - -``NVME_ZNS_ZS_CLOSED`` - -``NVME_ZNS_ZS_READ_ONLY`` - -``NVME_ZNS_ZS_FULL`` - -``NVME_ZNS_ZS_OFFLINE`` - - - - -.. c:type:: struct nvme_zns_desc - - -**Definition** - -:: - - struct nvme_zns_desc { - __u8 zt; - __u8 zs; - __u8 za; - __u8 zai; - __u8 rsvd4[4]; - __le64 zcap; - __le64 zslba; - __le64 wp; - __u8 rsvd32[32]; - }; - -**Members** - -``zt`` - -``zs`` - -``za`` - -``zai`` - -``rsvd4`` - -``zcap`` - -``zslba`` - -``wp`` - -``rsvd32`` - - - - - -.. c:type:: struct nvme_zone_report - - -**Definition** - -:: - - struct nvme_zone_report { - __le64 nr_zones; - __u8 rsvd8[56]; - struct nvme_zns_desc entries[]; - }; - -**Members** - -``nr_zones`` - Number of descriptors in **entries** - -``rsvd8`` - Reserved - -``entries`` - Zoned namespace descriptors - - - - - -.. c:type:: struct nvme_lba_status_desc - - -**Definition** - -:: - - struct nvme_lba_status_desc { - __le64 dslba; - __le32 nlb; - __u8 rsvd12; - __u8 status; - __u8 rsvd14[2]; - }; - -**Members** - -``dslba`` - -``nlb`` - -``rsvd12`` - -``status`` - -``rsvd14`` - - - - - -.. c:type:: struct nvme_lba_status - - -**Definition** - -:: - - struct nvme_lba_status { - __le32 nlsd; - __u8 cmpc; - __u8 rsvd5[3]; - struct nvme_lba_status_desc descs[]; - }; - -**Members** - -``nlsd`` - -``cmpc`` - -``rsvd5`` - -``descs`` - - - - - -.. c:type:: struct nvme_feat_auto_pst - - -**Definition** - -:: - - struct nvme_feat_auto_pst { - __le64 apst_entry[32]; - }; - -**Members** - -``apst_entry`` - See :c:type:`enum nvme_apst_entry ` - - - - - -.. c:type:: enum nvme_apst_entry - - -**Constants** - -``NVME_APST_ENTRY_ITPS_SHIFT`` - -``NVME_APST_ENTRY_ITPT_SHIFT`` - -``NVME_APST_ENTRY_ITPS_MASK`` - -``NVME_APST_ENTRY_ITPT_MASK`` - - - - -.. c:type:: struct nvme_metadata_element_desc - - Metadata Element Descriptor - -**Definition** - -:: - - struct nvme_metadata_element_desc { - __u8 type; - __u8 rev; - __u16 len; - __u8 val[0]; - }; - -**Members** - -``type`` - Element Type (ET) - -``rev`` - Element Revision (ER) - -``len`` - Element Length (ELEN) - -``val`` - Element Value (EVAL), UTF-8 string - - - - - -.. c:type:: struct nvme_host_metadata - - Host Metadata Data Structure - -**Definition** - -:: - - struct nvme_host_metadata { - __u8 ndesc; - __u8 rsvd1; - union { - struct nvme_metadata_element_desc descs[0]; - __u8 descs_buf[4094]; - }; - }; - -**Members** - -``ndesc`` - Number of metadata element descriptors - -``rsvd1`` - Reserved - -``{unnamed_union}`` - anonymous - -``descs`` - Metadata element descriptors - -``descs_buf`` - Metadata element descriptor buffer - - - - - -.. c:type:: enum nvme_ctrl_metadata_type - - Controller Metadata Element Types - -**Constants** - -``NVME_CTRL_METADATA_OS_CTRL_NAME`` - Name of the controller in - the operating system. - -``NVME_CTRL_METADATA_OS_DRIVER_NAME`` - Name of the driver in the - operating system. - -``NVME_CTRL_METADATA_OS_DRIVER_VER`` - Version of the driver in - the operating system. - -``NVME_CTRL_METADATA_PRE_BOOT_CTRL_NAME`` - Name of the controller in - the pre-boot environment. - -``NVME_CTRL_METADATA_PRE_BOOT_DRIVER_NAME`` - Name of the driver in the - pre-boot environment. - -``NVME_CTRL_METADATA_PRE_BOOT_DRIVER_VER`` - Version of the driver in the - 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_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_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. - -``NVME_CTRL_METADATA_HOST_DET_FAIL_REC`` - Failure record. - - - - -.. c:type:: enum nvme_ns_metadata_type - - Namespace Metadata Element Types - -**Constants** - -``NVME_NS_METADATA_OS_NS_NAME`` - Name of the namespace in the the - operating system - -``NVME_NS_METADATA_PRE_BOOT_NS_NAME`` - Name of the namespace in the pre-boot - environment. - -``NVME_NS_METADATA_OS_NS_QUAL_1`` - First qualifier of the Operating System - Namespace Name. - -``NVME_NS_METADATA_OS_NS_QUAL_2`` - Second qualifier of the Operating System - Namespace Name. - - - - -.. c:type:: struct nvme_timestamp - - -**Definition** - -:: - - struct nvme_timestamp { - __u8 timestamp[6]; - __u8 attr; - __u8 rsvd; - }; - -**Members** - -``timestamp`` - -``attr`` - -``rsvd`` - - - - - -.. c:type:: struct nvme_lba_range_type_entry - - -**Definition** - -:: - - struct nvme_lba_range_type_entry { - __u8 type; - __u8 attributes; - __u8 rsvd2[14]; - __u64 slba; - __u64 nlb; - __u8 guid[16]; - __u8 rsvd48[16]; - }; - -**Members** - -``type`` - -``attributes`` - -``rsvd2`` - -``slba`` - -``nlb`` - -``guid`` - -``rsvd48`` - - - - - -.. c:type:: enum nvme_lbart - - -**Constants** - -``NVME_LBART_TYPE_GP`` - -``NVME_LBART_TYPE_FS`` - -``NVME_LBART_TYPE_RAID`` - -``NVME_LBART_TYPE_CACHE`` - -``NVME_LBART_TYPE_SWAP`` - -``NVME_LBART_ATTRIB_TEMP`` - -``NVME_LBART_ATTRIB_HIDE`` - - - - -.. c:type:: struct nvme_lba_range_type - - -**Definition** - -:: - - struct nvme_lba_range_type { - struct nvme_lba_range_type_entry entry[NVME_FEAT_LBA_RANGE_MAX]; - }; - -**Members** - -``entry`` - - - - - -.. c:type:: struct nvme_plm_config - - -**Definition** - -:: - - struct nvme_plm_config { - __le16 ee; - __u8 rsvd2[30]; - __le64 dtwinrt; - __le64 dtwinwt; - __le64 dtwintt; - __u8 rsvd56[456]; - }; - -**Members** - -``ee`` - -``rsvd2`` - -``dtwinrt`` - -``dtwinwt`` - -``dtwintt`` - -``rsvd56`` - - - - - -.. c:type:: struct nvme_feat_host_behavior - - -**Definition** - -:: - - struct nvme_feat_host_behavior { - __u8 acre; - __u8 rsvd1[511]; - }; - -**Members** - -``acre`` - -``rsvd1`` - - - - - -.. c:type:: enum (anonymous) - - -**Constants** - -``NVME_ENABLE_ACRE`` - - - - -.. c:type:: struct nvme_dsm_range - - -**Definition** - -:: - - struct nvme_dsm_range { - __le32 cattr; - __le32 nlb; - __le64 slba; - }; - -**Members** - -``cattr`` - -``nlb`` - -``slba`` - - - - - -.. c:type:: struct nvme_copy_range - - -**Definition** - -:: - - struct nvme_copy_range { - __u8 rsvd0[8]; - __le64 slba; - __le16 nlb; - __u8 rsvd18[6]; - __le32 eilbrt; - __le16 elbatm; - __le16 elbat; - }; - -**Members** - -``rsvd0`` - -``slba`` - -``nlb`` - -``rsvd18`` - -``eilbrt`` - -``elbatm`` - -``elbat`` - - - - - -.. c:type:: struct nvme_registered_ctrl - - -**Definition** - -:: - - struct nvme_registered_ctrl { - __le16 cntlid; - __u8 rcsts; - __u8 rsvd3[5]; - __le64 hostid; - __le64 rkey; - }; - -**Members** - -``cntlid`` - -``rcsts`` - -``rsvd3`` - -``hostid`` - -``rkey`` - - - - - -.. c:type:: struct nvme_registered_ctrl_ext - - -**Definition** - -:: - - struct nvme_registered_ctrl_ext { - __le16 cntlid; - __u8 rcsts; - __u8 rsvd3[5]; - __le64 rkey; - __u8 hostid[16]; - __u8 rsvd32[32]; - }; - -**Members** - -``cntlid`` - -``rcsts`` - -``rsvd3`` - -``rkey`` - -``hostid`` - -``rsvd32`` - - - - - -.. c:type:: struct nvme_resv_status - - -**Definition** - -:: - - struct nvme_resv_status { - __le32 gen; - __u8 rtype; - __u8 regctl[2]; - __u8 rsvd7[2]; - __u8 ptpls; - __u8 rsvd10[14]; - union { - struct { - __u8 rsvd24[40]; - struct nvme_registered_ctrl_ext regctl_eds[0]; - }; - struct nvme_registered_ctrl regctl_ds[0]; - }; - }; - -**Members** - -``gen`` - -``rtype`` - -``regctl`` - -``rsvd7`` - -``ptpls`` - -``rsvd10`` - -``{unnamed_union}`` - anonymous - -``{unnamed_struct}`` - anonymous - -``rsvd24`` - -``regctl_eds`` - -``regctl_ds`` - - - - - -.. c:type:: struct nvme_streams_directive_params - - -**Definition** - -:: - - struct nvme_streams_directive_params { - __le16 msl; - __le16 nssa; - __le16 nsso; - __u8 nssc; - __u8 rsvd[9]; - __le32 sws; - __le16 sgs; - __le16 nsa; - __le16 nso; - __u8 rsvd2[6]; - }; - -**Members** - -``msl`` - -``nssa`` - -``nsso`` - -``nssc`` - -``rsvd`` - -``sws`` - -``sgs`` - -``nsa`` - -``nso`` - -``rsvd2`` - - - - - -.. c:type:: struct nvme_streams_directive_status - - -**Definition** - -:: - - struct nvme_streams_directive_status { - __le16 osc; - __le16 sid[]; - }; - -**Members** - -``osc`` - -``sid`` - - - - - -.. c:type:: struct nvme_id_directives - - -**Definition** - -:: - - struct nvme_id_directives { - __u8 supported[32]; - __u8 enabled[32]; - __u8 rsvd64[4032]; - }; - -**Members** - -``supported`` - -``enabled`` - -``rsvd64`` - - - - - -.. c:type:: enum (anonymous) - - -**Constants** - -``NVME_ID_DIR_ID_BIT`` - Identify directive is supported - -``NVME_ID_DIR_SD_BIT`` - Streams directive is supported - - - - -.. c:type:: struct nvme_host_mem_buf_attrs - - -**Definition** - -:: - - struct nvme_host_mem_buf_attrs { - __le32 hsize; - __le32 hmdlal; - __le32 hmdlau; - __le32 hmdlec; - __u8 rsvd16[4080]; - }; - -**Members** - -``hsize`` - -``hmdlal`` - -``hmdlau`` - -``hmdlec`` - -``rsvd16`` - - - - - -.. c:type:: enum nvme_ae_type - - -**Constants** - -``NVME_AER_ERROR`` - -``NVME_AER_SMART`` - -``NVME_AER_NOTICE`` - -``NVME_AER_CSS`` - -``NVME_AER_VS`` - - - - -.. c:type:: enum nvme_ae_info_error - - -**Constants** - -``NVME_AER_ERROR_INVALID_DB_REG`` - -``NVME_AER_ERROR_INVALID_DB_VAL`` - -``NVME_AER_ERROR_DIAG_FAILURE`` - -``NVME_AER_ERROR_PERSISTENT_INTERNAL_ERROR`` - -``NVME_AER_ERROR_TRANSIENT_INTERNAL_ERROR`` - -``NVME_AER_ERROR_FW_IMAGE_LOAD_ERROR`` - - - - -.. c:type:: enum nvme_ae_info_smart - - -**Constants** - -``NVME_AER_SMART_SUBSYSTEM_RELIABILITY`` - -``NVME_AER_SMART_TEMPERATURE_THRESHOLD`` - -``NVME_AER_SMART_SPARE_THRESHOLD`` - - - - -.. c:type:: enum nvme_ae_info_css_nvm - - -**Constants** - -``NVME_AER_CSS_NVM_RESERVATION`` - -``NVME_AER_CSS_NVM_SANITIZE_COMPLETED`` - -``NVME_AER_CSS_NVM_UNEXPECTED_SANITIZE_DEALLOC`` - - - - -.. c:type:: enum nvme_ae_info_notice - - -**Constants** - -``NVME_AER_NOTICE_NS_CHANGED`` - -``NVME_AER_NOTICE_FW_ACT_STARTING`` - -``NVME_AER_NOTICE_TELEMETRY`` - -``NVME_AER_NOTICE_ANA`` - -``NVME_AER_NOTICE_PL_EVENT`` - -``NVME_AER_NOTICE_LBA_STATUS_ALERT`` - -``NVME_AER_NOTICE_EG_EVENT`` - -``NVME_AER_NOTICE_DISC_CHANGED`` - - - - -.. c:type:: enum nvme_subsys_type - - Type of the NVM subsystem. - -**Constants** - -``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). - -``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. - -``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. - - - - -.. c:type:: enum nvmf_disc_eflags - - Discovery Log Page entry flags. - -**Constants** - -``NVMF_DISC_EFLAGS_NONE`` - Indicates that none of the DUPRETINFO or EPCSD - 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. - -``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. - - - - -.. c:type:: struct nvmf_disc_log_entry - - Discovery Log Page entry - -**Definition** - -:: - - struct nvmf_disc_log_entry { - __u8 trtype; - __u8 adrfam; - __u8 subtype; - __u8 treq; - __le16 portid; - __le16 cntlid; - __le16 asqsz; - __le16 eflags; - __u8 rsvd12[20]; - char trsvcid[NVMF_TRSVCID_SIZE]; - __u8 rsvd64[192]; - char subnqn[NVME_NQN_LENGTH]; - char traddr[NVMF_TRADDR_SIZE]; - union tsas { - char common[NVMF_TSAS_SIZE]; - struct rdma { - __u8 qptype; - __u8 prtype; - __u8 cms; - __u8 rsvd3[5]; - __u16 pkey; - __u8 rsvd10[246]; - } rdma; - struct tcp { - __u8 sectype; - } tcp; - } tsas; - }; - -**Members** - -``trtype`` - Transport Type (TRTYPE): Specifies the NVMe Transport type. - See :c:type:`enum nvmf_trtype `. - -``adrfam`` - Address Family (ADRFAM): Specifies the address family. - See :c:type:`enum nvmf_addr_family `. - -``subtype`` - Subsystem Type (SUBTYPE): Specifies the type of the NVM subsystem - that is indicated in this entry. See :c:type:`enum nvme_subsys_type `. - -``treq`` - Transport Requirements (TREQ): Indicates requirements for the NVMe - Transport. See :c:type:`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). - -``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. - -``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. - -``eflags`` - Entry Flags (EFLAGS): Indicates additional information related to - the current entry. See :c:type:`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. - -``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). - -``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. - -``tsas`` - Transport specific attribute settings - - - - - -.. c:type:: enum nvmf_trtype - - Transport Type codes for Discovery Log Page entry TRTYPE field - -**Constants** - -``NVMF_TRTYPE_UNSPECIFIED`` - Not indicated - -``NVMF_TRTYPE_RDMA`` - RDMA - -``NVMF_TRTYPE_FC`` - Fibre Channel - -``NVMF_TRTYPE_TCP`` - TCP - -``NVMF_TRTYPE_LOOP`` - Intra-host Transport (i.e., loopback), reserved - for host usage. - -``NVMF_TRTYPE_MAX`` - Maximum value for :c:type:`enum nvmf_trtype ` - - - - -.. c:type:: enum nvmf_addr_family - - Address Family codes for Discovery Log Page entry ADRFAM field - -**Constants** - -``NVMF_ADDR_FAMILY_PCI`` - PCIe - -``NVMF_ADDR_FAMILY_IP4`` - AF_INET: IPv4 address family. - -``NVMF_ADDR_FAMILY_IP6`` - AF_INET6: IPv6 address family. - -``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. - - - - -.. c:type:: enum nvmf_treq - - Transport Requirements codes for Discovery Log Page entry TREQ field - -**Constants** - -``NVMF_TREQ_NOT_SPECIFIED`` - Not specified - -``NVMF_TREQ_REQUIRED`` - Required - -``NVMF_TREQ_NOT_REQUIRED`` - Not Required - -``NVMF_TREQ_DISABLE_SQFLOW`` - SQ flow control disable supported - - - - -.. c:type:: enum nvmf_rdma_qptype - - RDMA QP Service Type codes for Discovery Log Page entry TSAS RDMA_QPTYPE field - -**Constants** - -``NVMF_RDMA_QPTYPE_CONNECTED`` - Reliable Connected - -``NVMF_RDMA_QPTYPE_DATAGRAM`` - Reliable Datagram - - - - -.. c:type:: enum nvmf_rdma_prtype - - RDMA Provider Type codes for Discovery Log Page entry TSAS RDMA_PRTYPE field - -**Constants** - -``NVMF_RDMA_PRTYPE_NOT_SPECIFIED`` - No Provider Specified - -``NVMF_RDMA_PRTYPE_IB`` - InfiniBand - -``NVMF_RDMA_PRTYPE_ROCE`` - InfiniBand RoCE - -``NVMF_RDMA_PRTYPE_ROCEV2`` - InfiniBand RoCEV2 - -``NVMF_RDMA_PRTYPE_IWARP`` - iWARP - - - - -.. c:type:: enum nvmf_rdma_cms - - RDMA Connection Management Service Type codes for Discovery Log Page entry TSAS RDMA_CMS field - -**Constants** - -``NVMF_RDMA_CMS_RDMA_CM`` - Sockets based endpoint addressing - - - - -.. c:type:: enum nvmf_tcp_sectype - - Transport Specific Address Subtype Definition for NVMe/TCP Transport - -**Constants** - -``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. - - - - -.. c:type:: struct nvmf_discovery_log - - Discovery Log Page (Log Identifier 70h) - -**Definition** - -:: - - struct nvmf_discovery_log { - __le64 genctr; - __le64 numrec; - __le16 recfmt; - __u8 rsvd14[1006]; - struct nvmf_disc_log_entry entries[]; - }; - -**Members** - -``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). - -``numrec`` - Number of Records (NUMREC): Indicates the number of records - 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. - -``rsvd14`` - Reserved - -``entries`` - Discovery Log Page Entries - see :c:type:`struct nvmf_disc_log_entry `. - - - - - -.. c:type:: struct nvmf_connect_data - - Data payload for the 'connect' command - -**Definition** - -:: - - struct nvmf_connect_data { - __u8 hostid[16]; - __le16 cntlid; - char rsvd4[238]; - char subsysnqn[NVME_NQN_LENGTH]; - char hostnqn[NVME_NQN_LENGTH]; - char rsvd5[256]; - }; - -**Members** - -``hostid`` - Host ID of the connecting host - -``cntlid`` - Requested controller ID - -``rsvd4`` - Reserved - -``subsysnqn`` - Subsystem NQN to connect to - -``hostnqn`` - Host NQN of the connecting host - -``rsvd5`` - Reserved - - - - - -.. c:type:: struct nvme_mi_read_nvm_ss_info - - -**Definition** - -:: - - struct nvme_mi_read_nvm_ss_info { - __u8 nump; - __u8 mjr; - __u8 mnr; - __u8 rsvd3[29]; - }; - -**Members** - -``nump`` - -``mjr`` - -``mnr`` - -``rsvd3`` - - - - - -.. c:type:: struct nvme_mi_port_pcie - - -**Definition** - -:: - - struct nvme_mi_port_pcie { - __u8 mps; - __u8 sls; - __u8 cls; - __u8 mlw; - __u8 nlw; - __u8 pn; - __u8 rsvd14[18]; - }; - -**Members** - -``mps`` - -``sls`` - -``cls`` - -``mlw`` - -``nlw`` - -``pn`` - -``rsvd14`` - - - - - -.. c:type:: struct nvme_mi_port_smb - - -**Definition** - -:: - - struct nvme_mi_port_smb { - __u8 vpd_addr; - __u8 mvpd_freq; - __u8 mme_addr; - __u8 mme_freq; - __u8 nvmebm; - __u8 rsvd13[19]; - }; - -**Members** - -``vpd_addr`` - -``mvpd_freq`` - -``mme_addr`` - -``mme_freq`` - -``nvmebm`` - -``rsvd13`` - - - - - -.. c:type:: struct nvme_mi_read_port_info - - -**Definition** - -:: - - struct nvme_mi_read_port_info { - __u8 portt; - __u8 rsvd1; - __le16 mmctptus; - __le32 meb; - union { - struct nvme_mi_port_pcie pcie; - struct nvme_mi_port_smb smb; - }; - }; - -**Members** - -``portt`` - -``rsvd1`` - -``mmctptus`` - -``meb`` - -``{unnamed_union}`` - anonymous - -``pcie`` - -``smb`` - - - - - -.. c:type:: struct nvme_mi_read_ctrl_info - - -**Definition** - -:: - - struct nvme_mi_read_ctrl_info { - __u8 portid; - __u8 rsvd1[4]; - __u8 prii; - __le16 pri; - __le16 vid; - __le16 did; - __le16 ssvid; - __le16 ssid; - __u8 rsvd16[16]; - }; - -**Members** - -``portid`` - -``rsvd1`` - -``prii`` - -``pri`` - -``vid`` - -``did`` - -``ssvid`` - -``ssid`` - -``rsvd16`` - - - - - -.. c:type:: struct nvme_mi_osc - - -**Definition** - -:: - - struct nvme_mi_osc { - __u8 type; - __u8 opc; - }; - -**Members** - -``type`` - -``opc`` - - - - - -.. c:type:: struct nvme_mi_read_sc_list - - -**Definition** - -:: - - struct nvme_mi_read_sc_list { - __le16 numcmd; - struct nvme_mi_osc cmds[]; - }; - -**Members** - -``numcmd`` - -``cmds`` - - - - - -.. c:type:: struct nvme_mi_nvm_ss_health_status - - -**Definition** - -:: - - struct nvme_mi_nvm_ss_health_status { - __u8 nss; - __u8 sw; - __u8 ctemp; - __u8 pdlu; - __le16 ccs; - __u8 rsvd8[2]; - }; - -**Members** - -``nss`` - -``sw`` - -``ctemp`` - -``pdlu`` - -``ccs`` - -``rsvd8`` - - - - - -.. c:type:: enum nvme_mi_css - - -**Constants** - -``NVME_MI_CCS_RDY`` - -``NVME_MI_CSS_CFS`` - -``NVME_MI_CSS_SHST`` - -``NVME_MI_CSS_NSSRO`` - -``NVME_MI_CSS_CECO`` - -``NVME_MI_CSS_NAC`` - -``NVME_MI_CSS_FA`` - -``NVME_MI_CSS_CSTS`` - -``NVME_MI_CSS_CTEMP`` - -``NVME_MI_CSS_PDLU`` - -``NVME_MI_CSS_SPARE`` - -``NVME_MI_CSS_CCWARN`` - - - - -.. c:type:: struct nvme_mi_ctrl_health_status - - -**Definition** - -:: - - struct nvme_mi_ctrl_health_status { - __le16 ctlid; - __le16 csts; - __le16 ctemp; - __u8 pdlu; - __u8 spare; - __u8 cwarn; - __u8 rsvd9[7]; - }; - -**Members** - -``ctlid`` - -``csts`` - -``ctemp`` - -``pdlu`` - -``spare`` - -``cwarn`` - -``rsvd9`` - - - - - -.. c:type:: enum nvme_mi_csts - - -**Constants** - -``NVME_MI_CSTS_RDY`` - -``NVME_MI_CSTS_CFS`` - -``NVME_MI_CSTS_SHST`` - -``NVME_MI_CSTS_NSSRO`` - -``NVME_MI_CSTS_CECO`` - -``NVME_MI_CSTS_NAC`` - -``NVME_MI_CSTS_FA`` - - - - -.. c:type:: enum nvme_mi_cwarn - - -**Constants** - -``NVME_MI_CWARN_ST`` - -``NVME_MI_CWARN_TAUT`` - -``NVME_MI_CWARN_RD`` - -``NVME_MI_CWARN_RO`` - -``NVME_MI_CWARN_VMBF`` - - - - -.. c:type:: struct nvme_mi_vpd_mra - - -**Definition** - -:: - - struct nvme_mi_vpd_mra { - __u8 nmravn; - __u8 ff; - __u8 rsvd7[6]; - __u8 i18vpwr; - __u8 m18vpwr; - __u8 i33vpwr; - __u8 m33vpwr; - __u8 rsvd17; - __u8 m33vapsr; - __u8 i5vapsr; - __u8 m5vapsr; - __u8 i12vapsr; - __u8 m12vapsr; - __u8 mtl; - __u8 tnvmcap[16]; - __u8 rsvd37[27]; - }; - -**Members** - -``nmravn`` - -``ff`` - -``rsvd7`` - -``i18vpwr`` - -``m18vpwr`` - -``i33vpwr`` - -``m33vpwr`` - -``rsvd17`` - -``m33vapsr`` - -``i5vapsr`` - -``m5vapsr`` - -``i12vapsr`` - -``m12vapsr`` - -``mtl`` - -``tnvmcap`` - -``rsvd37`` - - - - - -.. c:type:: struct nvme_mi_vpd_ppmra - - -**Definition** - -:: - - struct nvme_mi_vpd_ppmra { - __u8 nppmravn; - __u8 pn; - __u8 ppi; - __u8 ls; - __u8 mlw; - __u8 mctp; - __u8 refccap; - __u8 pi; - __u8 rsvd13[3]; - }; - -**Members** - -``nppmravn`` - -``pn`` - -``ppi`` - -``ls`` - -``mlw`` - -``mctp`` - -``refccap`` - -``pi`` - -``rsvd13`` - - - - - -.. c:type:: struct nvme_mi_vpd_telem - - -**Definition** - -:: - - struct nvme_mi_vpd_telem { - __u8 type; - __u8 rev; - __u8 len; - __u8 data[0]; - }; - -**Members** - -``type`` - -``rev`` - -``len`` - -``data`` - - - - - -.. c:type:: enum nvme_mi_elem - - -**Constants** - -``NVME_MI_ELEM_EED`` - -``NVME_MI_ELEM_USCE`` - -``NVME_MI_ELEM_ECED`` - -``NVME_MI_ELEM_LED`` - -``NVME_MI_ELEM_SMBMED`` - -``NVME_MI_ELEM_PCIESED`` - -``NVME_MI_ELEM_NVMED`` - - - - -.. c:type:: struct nvme_mi_vpd_tra - - -**Definition** - -:: - - struct nvme_mi_vpd_tra { - __u8 vn; - __u8 rsvd6; - __u8 ec; - struct nvme_mi_vpd_telem elems[0]; - }; - -**Members** - -``vn`` - -``rsvd6`` - -``ec`` - -``elems`` - - - - - -.. c:type:: struct nvme_mi_vpd_mr_common - - -**Definition** - -:: - - struct nvme_mi_vpd_mr_common { - __u8 type; - __u8 rf; - __u8 rlen; - __u8 rchksum; - __u8 hchksum; - union { - struct nvme_mi_vpd_mra nmra; - struct nvme_mi_vpd_ppmra ppmra; - struct nvme_mi_vpd_tra tmra; - }; - }; - -**Members** - -``type`` - -``rf`` - -``rlen`` - -``rchksum`` - -``hchksum`` - -``{unnamed_union}`` - anonymous - -``nmra`` - -``ppmra`` - -``tmra`` - - - - - -.. c:type:: struct nvme_mi_vpd_hdr - - -**Definition** - -:: - - struct nvme_mi_vpd_hdr { - __u8 ipmiver; - __u8 iuaoff; - __u8 ciaoff; - __u8 biaoff; - __u8 piaoff; - __u8 mrioff; - __u8 rsvd6; - __u8 chchk; - __u8 vpd[]; - }; - -**Members** - -``ipmiver`` - -``iuaoff`` - -``ciaoff`` - -``biaoff`` - -``piaoff`` - -``mrioff`` - -``rsvd6`` - -``chchk`` - -``vpd`` - - - - - -.. c:type:: enum nvme_status_field - - Defines all parts of the nvme status field: status code, status code type, and additional flags. - -**Constants** - -``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_SC_MASK`` - Mask to get the value of the status code. - -``NVME_SC_SUCCESS`` - Successful Completion: The command - completed without error. - -``NVME_SC_INVALID_OPCODE`` - Invalid Command Opcode: A reserved coded - 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. - -``NVME_SC_CMDID_CONFLICT`` - Command ID Conflict: The command - 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. - -``NVME_SC_POWER_LOSS`` - Commands Aborted due to Power Loss - 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. - -``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. - -``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. - -``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. - -``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. - -``NVME_SC_INVALID_NS`` - Invalid Namespace or Format: The - 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. - -``NVME_SC_SGL_INVALID_LAST`` - Invalid SGL Segment Descriptor: The - 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. - -``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. - -``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. - -``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. - -``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. - -``NVME_SC_AWU_EXCEEDED`` - Atomic Write Unit Exceeded: The length - 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. - -``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. - -``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. - -``NVME_SC_KAT_EXPIRED`` - Keep Alive Timer Expired: The Keep Alive - Timer expired. - -``NVME_SC_KAT_INVALID`` - Keep Alive Timeout Invalid: The Keep - 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. - -``NVME_SC_SANITIZE_FAILED`` - Sanitize Failed: The most recent sanitize - 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. - -``NVME_SC_SGL_INVALID_GRANULARITY`` - SGL Data Block Granularity Invalid: The - 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. - -``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. - -``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. - -``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. - -``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. - -``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. - -``NVME_SC_LBA_RANGE`` - LBA Out of Range: The command references - 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. - -``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. - -``NVME_SC_RESERVATION_CONFLICT`` - Reservation Conflict: The command was - 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. - -``NVME_SC_CQ_INVALID`` - Completion Queue Invalid: The Completion - 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 - part of the command. An invalid queue - identifier is one that is currently in - 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. - -``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. - -``NVME_SC_ABORT_MISSING`` - Abort Command is missing: The abort - command is missing. - -``NVME_SC_ASYNC_LIMIT`` - Asynchronous Event Request Limit - 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. - -``NVME_SC_FIRMWARE_IMAGE`` - Invalid Firmware Image: The firmware - 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. - -``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. - -``NVME_SC_INVALID_FORMAT`` - Invalid Format: The LBA Format specified - 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. - -``NVME_SC_INVALID_QUEUE`` - Invalid Queue Deletion: Invalid I/O - Completion Queue specified to delete. - -``NVME_SC_FEATURE_NOT_SAVEABLE`` - Feature Identifier Not Saveable: The - 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. - -``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. - -``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. - -``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. - -``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. - -``NVME_SC_FW_ACTIVATE_PROHIBITED`` - Firmware Activation Prohibited: The image - 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. - -``NVME_SC_NS_INSUFFICIENT_CAP`` - Namespace Insufficient Capacity: Creating - 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. - -``NVME_SC_NS_ALREADY_ATTACHED`` - Namespace Already Attached: The - 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. - -``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. - -``NVME_SC_THIN_PROV_NOT_SUPP`` - Thin Provisioning Not Supported: Thin - provisioning is not supported by the - controller. - -``NVME_SC_CTRL_LIST_INVALID`` - Controller List Invalid: The controller - 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. - -``NVME_SC_BP_WRITE_PROHIBITED`` - Boot Partition Write Prohibited: The - 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 - -``NVME_SC_ANA_GROUP_ID_INVALID`` - ANA Group Identifier Invalid: The specified - 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. - -``NVME_SC_INSUFFICIENT_CAP`` - Insufficient Capacity: Requested operation - 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. - -``NVME_SC_PROHIBIT_CMD_EXEC_NOT_SUPPORTED`` - Prohibition of Command Execution - 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 - -``NVME_SC_INVALID_IOCS`` - Invalid I/O Command Set - -``NVME_SC_ID_UNAVAILABLE`` - Identifier Unavailable - -``NVME_SC_BAD_ATTRIBUTES`` - Conflicting Dataset Management Attributes - -``NVME_SC_INVALID_PI`` - Invalid Protection Information - -``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. - -``NVME_SC_CONNECT_CTRL_BUSY`` - Controller Busy: The controller is - already associated with a host. - -``NVME_SC_CONNECT_INVALID_PARAM`` - Connect Invalid Parameters: One or more - of the command parameters. - -``NVME_SC_CONNECT_RESTART_DISC`` - Connect Restart Discovery: The NVM - 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 - -``NVME_SC_DISCONNECT_INVALID_QTYPE`` - Invalid Queue Type: The command was sent - on the wrong queue type. - -``NVME_SC_DISCOVERY_RESTART`` - Discover Restart: The snapshot of the - 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. - -``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. - -``NVME_SC_ZNS_ZRWA_RESOURCES_UNAVAILABLE`` - ZRWA Resources Unavailable: - No ZRWAs are available. - -``NVME_SC_ZNS_BOUNDARY_ERROR`` - Zone Boundary Error: The command specifies - logical blocks in more than one zone. - -``NVME_SC_ZNS_FULL`` - Zone Is Full: The accessed zone is in the - ZSF:Full state. - -``NVME_SC_ZNS_READ_ONLY`` - Zone Is Read Only: The accessed zone is - in the ZSRO:Read Only state. - -``NVME_SC_ZNS_OFFLINE`` - Zone Is Offline: The accessed zone is - in the ZSO:Offline state. - -``NVME_SC_ZNS_INVALID_WRITE`` - Zone Invalid Write: The write to a zone - 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. - -``NVME_SC_ZNS_INVAL_TRANSITION`` - Invalid Zone State Transition: The request - is not a valid zone state transition. - -``NVME_SC_WRITE_FAULT`` - Write Fault: The write data could not be - committed to the media. - -``NVME_SC_READ_ERROR`` - Unrecovered Read Error: The read data - 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. - -``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. - -``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. - -``NVME_SC_COMPARE_FAILED`` - Compare Failure: The command failed due - 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. - -``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. - -``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. - -``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. - -``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. - -``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. - -``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. - -``NVME_SC_CTRL_PATH_ERROR`` - Controller Pathing Error: A pathing error - was detected by the controller. - -``NVME_SC_HOST_PATH_ERROR`` - Host Pathing Error: A pathing error was - detected by the host. - -``NVME_SC_CMD_ABORTED_BY_HOST`` - Command Aborted By Host: The command was - aborted as a result of host action. - -``NVME_SC_CRD`` - Mask to get value of Command Retry Delay - 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. - -``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. - - -.. c:function:: __u16 nvme_status_code_type (__u16 status_field) - - Returns the NVMe Status Code Type - -**Parameters** - -``__u16 status_field`` - The NVMe Completion Queue Entry's Status Field - -**Description** - -See :c:type:`enum nvme_status_field ` - - -.. c:function:: __u16 nvme_status_code (__u16 status_field) - - Returns the NVMe Status Code - -**Parameters** - -``__u16 status_field`` - The NVMe Completion Queue Entry's Status Field - -**Description** - -See :c:type:`enum nvme_status_field ` - - - - -.. c:type:: enum nvme_admin_opcode - - Known NVMe admin opcodes - -**Constants** - -``nvme_admin_delete_sq`` - -``nvme_admin_create_sq`` - -``nvme_admin_get_log_page`` - -``nvme_admin_delete_cq`` - -``nvme_admin_create_cq`` - -``nvme_admin_identify`` - -``nvme_admin_abort_cmd`` - -``nvme_admin_set_features`` - -``nvme_admin_get_features`` - -``nvme_admin_async_event`` - -``nvme_admin_ns_mgmt`` - -``nvme_admin_fw_commit`` - -``nvme_admin_fw_activate`` - -``nvme_admin_fw_download`` - -``nvme_admin_dev_self_test`` - -``nvme_admin_ns_attach`` - -``nvme_admin_keep_alive`` - -``nvme_admin_directive_send`` - -``nvme_admin_directive_recv`` - -``nvme_admin_virtual_mgmt`` - -``nvme_admin_nvme_mi_send`` - -``nvme_admin_nvme_mi_recv`` - -``nvme_admin_capacity_mgmt`` - -``nvme_admin_lockdown`` - -``nvme_admin_dbbuf`` - -``nvme_admin_fabrics`` - -``nvme_admin_format_nvm`` - -``nvme_admin_security_send`` - -``nvme_admin_security_recv`` - -``nvme_admin_sanitize_nvm`` - -``nvme_admin_get_lba_status`` - - - - -.. c:type:: enum nvme_identify_cns - - -**Constants** - -``NVME_IDENTIFY_CNS_NS`` - -``NVME_IDENTIFY_CNS_CTRL`` - -``NVME_IDENTIFY_CNS_NS_ACTIVE_LIST`` - -``NVME_IDENTIFY_CNS_NS_DESC_LIST`` - -``NVME_IDENTIFY_CNS_NVMSET_LIST`` - -``NVME_IDENTIFY_CNS_CSI_NS`` - -``NVME_IDENTIFY_CNS_CSI_CTRL`` - -``NVME_IDENTIFY_CNS_CSI_NS_ACTIVE_LIST`` - -``NVME_IDENTIFY_CNS_CSI_INDEPENDENT_ID_NS`` - -``NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST`` - -``NVME_IDENTIFY_CNS_ALLOCATED_NS`` - -``NVME_IDENTIFY_CNS_NS_CTRL_LIST`` - -``NVME_IDENTIFY_CNS_CTRL_LIST`` - -``NVME_IDENTIFY_CNS_PRIMARY_CTRL_CAP`` - -``NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST`` - -``NVME_IDENTIFY_CNS_NS_GRANULARITY`` - -``NVME_IDENTIFY_CNS_UUID_LIST`` - -``NVME_IDENTIFY_CNS_DOMAIN_LIST`` - -``NVME_IDENTIFY_CNS_ENDURANCE_GROUP_ID`` - -``NVME_IDENTIFY_CNS_CSS_ALLOCATED_NS_LIST`` - -``NVME_IDENTIFY_CNS_COMMAND_SET_STRUCTURE`` - Base Specification 2.0a section 5.17.2.21 - - - - -.. c:type:: enum nvme_cmd_get_log_lid - - -**Constants** - -``NVME_LOG_LID_SUPPORTED_LOG_PAGES`` - -``NVME_LOG_LID_ERROR`` - -``NVME_LOG_LID_SMART`` - -``NVME_LOG_LID_FW_SLOT`` - -``NVME_LOG_LID_CHANGED_NS`` - -``NVME_LOG_LID_CMD_EFFECTS`` - -``NVME_LOG_LID_DEVICE_SELF_TEST`` - -``NVME_LOG_LID_TELEMETRY_HOST`` - -``NVME_LOG_LID_TELEMETRY_CTRL`` - -``NVME_LOG_LID_ENDURANCE_GROUP`` - -``NVME_LOG_LID_PREDICTABLE_LAT_NVMSET`` - -``NVME_LOG_LID_PREDICTABLE_LAT_AGG`` - -``NVME_LOG_LID_ANA`` - -``NVME_LOG_LID_PERSISTENT_EVENT`` - -``NVME_LOG_LID_LBA_STATUS`` - -``NVME_LOG_LID_ENDURANCE_GRP_EVT`` - -``NVME_LOG_LID_MEDIA_UNIT_STATUS`` - -``NVME_LOG_LID_FID_SUPPORTED_EFFECTS`` - -``NVME_LOG_LID_BOOT_PARTITION`` - -``NVME_LOG_LID_DISCOVER`` - -``NVME_LOG_LID_RESERVATION`` - -``NVME_LOG_LID_SANITIZE`` - -``NVME_LOG_LID_ZNS_CHANGED_ZONES`` - - - - -.. c:type:: enum nvme_features_id - - -**Constants** - -``NVME_FEAT_FID_ARBITRATION`` - -``NVME_FEAT_FID_POWER_MGMT`` - -``NVME_FEAT_FID_LBA_RANGE`` - -``NVME_FEAT_FID_TEMP_THRESH`` - -``NVME_FEAT_FID_ERR_RECOVERY`` - -``NVME_FEAT_FID_VOLATILE_WC`` - -``NVME_FEAT_FID_NUM_QUEUES`` - -``NVME_FEAT_FID_IRQ_COALESCE`` - -``NVME_FEAT_FID_IRQ_CONFIG`` - -``NVME_FEAT_FID_WRITE_ATOMIC`` - -``NVME_FEAT_FID_ASYNC_EVENT`` - -``NVME_FEAT_FID_AUTO_PST`` - -``NVME_FEAT_FID_HOST_MEM_BUF`` - -``NVME_FEAT_FID_TIMESTAMP`` - -``NVME_FEAT_FID_KATO`` - -``NVME_FEAT_FID_HCTM`` - -``NVME_FEAT_FID_NOPSC`` - -``NVME_FEAT_FID_RRL`` - -``NVME_FEAT_FID_PLM_CONFIG`` - -``NVME_FEAT_FID_PLM_WINDOW`` - -``NVME_FEAT_FID_LBA_STS_INTERVAL`` - -``NVME_FEAT_FID_HOST_BEHAVIOR`` - -``NVME_FEAT_FID_SANITIZE`` - -``NVME_FEAT_FID_ENDURANCE_EVT_CFG`` - -``NVME_FEAT_FID_IOCS_PROFILE`` - -``NVME_FEAT_FID_SPINUP_CONTROL`` - -``NVME_FEAT_FID_CTRL_METADATA`` - Controller Metadata - -``NVME_FEAT_FID_NS_METADATA`` - Namespace Metadata - -``NVME_FEAT_FID_SW_PROGRESS`` - -``NVME_FEAT_FID_HOST_ID`` - -``NVME_FEAT_FID_RESV_MASK`` - -``NVME_FEAT_FID_RESV_PERSIST`` - -``NVME_FEAT_FID_WRITE_PROTECT`` - - - - -.. c:type:: enum nvme_feat - - -**Constants** - -``NVME_FEAT_ARBITRATION_BURST_SHIFT`` - -``NVME_FEAT_ARBITRATION_BURST_MASK`` - -``NVME_FEAT_ARBITRATION_LPW_SHIFT`` - -``NVME_FEAT_ARBITRATION_LPW_MASK`` - -``NVME_FEAT_ARBITRATION_MPW_SHIFT`` - -``NVME_FEAT_ARBITRATION_MPW_MASK`` - -``NVME_FEAT_ARBITRATION_HPW_SHIFT`` - -``NVME_FEAT_ARBITRATION_HPW_MASK`` - -``NVME_FEAT_PWRMGMT_PS_SHIFT`` - -``NVME_FEAT_PWRMGMT_PS_MASK`` - -``NVME_FEAT_PWRMGMT_WH_SHIFT`` - -``NVME_FEAT_PWRMGMT_WH_MASK`` - -``NVME_FEAT_LBAR_NR_SHIFT`` - -``NVME_FEAT_LBAR_NR_MASK`` - -``NVME_FEAT_TT_TMPTH_SHIFT`` - -``NVME_FEAT_TT_TMPTH_MASK`` - -``NVME_FEAT_TT_TMPSEL_SHIFT`` - -``NVME_FEAT_TT_TMPSEL_MASK`` - -``NVME_FEAT_TT_THSEL_SHIFT`` - -``NVME_FEAT_TT_THSEL_MASK`` - -``NVME_FEAT_ERROR_RECOVERY_TLER_SHIFT`` - -``NVME_FEAT_ERROR_RECOVERY_TLER_MASK`` - -``NVME_FEAT_ERROR_RECOVERY_DULBE_SHIFT`` - -``NVME_FEAT_ERROR_RECOVERY_DULBE_MASK`` - -``NVME_FEAT_VWC_WCE_SHIFT`` - -``NVME_FEAT_VWC_WCE_MASK`` - -``NVME_FEAT_NRQS_NSQR_SHIFT`` - -``NVME_FEAT_NRQS_NSQR_MASK`` - -``NVME_FEAT_NRQS_NCQR_SHIFT`` - -``NVME_FEAT_NRQS_NCQR_MASK`` - -``NVME_FEAT_IRQC_THR_SHIFT`` - -``NVME_FEAT_IRQC_THR_MASK`` - -``NVME_FEAT_IRQC_TIME_SHIFT`` - -``NVME_FEAT_IRQC_TIME_MASK`` - -``NVME_FEAT_ICFG_IV_SHIFT`` - -``NVME_FEAT_ICFG_IV_MASK`` - -``NVME_FEAT_ICFG_CD_SHIFT`` - -``NVME_FEAT_ICFG_CD_MASK`` - -``NVME_FEAT_WA_DN_SHIFT`` - -``NVME_FEAT_WA_DN_MASK`` - -``NVME_FEAT_AE_SMART_SHIFT`` - -``NVME_FEAT_AE_SMART_MASK`` - -``NVME_FEAT_AE_NAN_SHIFT`` - -``NVME_FEAT_AE_NAN_MASK`` - -``NVME_FEAT_AE_FW_SHIFT`` - -``NVME_FEAT_AE_FW_MASK`` - -``NVME_FEAT_AE_TELEM_SHIFT`` - -``NVME_FEAT_AE_TELEM_MASK`` - -``NVME_FEAT_AE_ANA_SHIFT`` - -``NVME_FEAT_AE_ANA_MASK`` - -``NVME_FEAT_AE_PLA_SHIFT`` - -``NVME_FEAT_AE_PLA_MASK`` - -``NVME_FEAT_AE_LBAS_SHIFT`` - -``NVME_FEAT_AE_LBAS_MASK`` - -``NVME_FEAT_AE_EGA_SHIFT`` - -``NVME_FEAT_AE_EGA_MASK`` - -``NVME_FEAT_APST_APSTE_SHIFT`` - -``NVME_FEAT_APST_APSTE_MASK`` - -``NVME_FEAT_HMEM_EHM_SHIFT`` - -``NVME_FEAT_HMEM_EHM_MASK`` - -``NVME_FEAT_HCTM_TMT2_SHIFT`` - -``NVME_FEAT_HCTM_TMT2_MASK`` - -``NVME_FEAT_HCTM_TMT1_SHIFT`` - -``NVME_FEAT_HCTM_TMT1_MASK`` - -``NVME_FEAT_NOPS_NOPPME_SHIFT`` - -``NVME_FEAT_NOPS_NOPPME_MASK`` - -``NVME_FEAT_RRL_RRL_SHIFT`` - -``NVME_FEAT_RRL_RRL_MASK`` - -``NVME_FEAT_PLM_PLME_SHIFT`` - -``NVME_FEAT_PLM_PLME_MASK`` - -``NVME_FEAT_PLMW_WS_SHIFT`` - -``NVME_FEAT_PLMW_WS_MASK`` - -``NVME_FEAT_LBAS_LSIRI_SHIFT`` - -``NVME_FEAT_LBAS_LSIRI_MASK`` - -``NVME_FEAT_LBAS_LSIPI_SHIFT`` - -``NVME_FEAT_LBAS_LSIPI_MASK`` - -``NVME_FEAT_SC_NODRM_SHIFT`` - -``NVME_FEAT_SC_NODRM_MASK`` - -``NVME_FEAT_EG_ENDGID_SHIFT`` - -``NVME_FEAT_EG_ENDGID_MASK`` - -``NVME_FEAT_EG_EGCW_SHIFT`` - -``NVME_FEAT_EG_EGCW_MASK`` - -``NVME_FEAT_SPM_PBSLC_SHIFT`` - -``NVME_FEAT_SPM_PBSLC_MASK`` - -``NVME_FEAT_HOSTID_EXHID_SHIFT`` - -``NVME_FEAT_HOSTID_EXHID_MASK`` - -``NVME_FEAT_RM_REGPRE_SHIFT`` - -``NVME_FEAT_RM_REGPRE_MASK`` - -``NVME_FEAT_RM_RESREL_SHIFT`` - -``NVME_FEAT_RM_RESREL_MASK`` - -``NVME_FEAT_RM_RESPRE_SHIFT`` - -``NVME_FEAT_RM_RESPRE_MASK`` - -``NVME_FEAT_RP_PTPL_SHIFT`` - -``NVME_FEAT_RP_PTPL_MASK`` - -``NVME_FEAT_WP_WPS_SHIFT`` - -``NVME_FEAT_WP_WPS_MASK`` - -``NVME_FEAT_IOCSP_IOCSCI_SHIFT`` - -``NVME_FEAT_IOCSP_IOCSCI_MASK`` - - - - -.. c:type:: enum nvme_get_features_sel - - -**Constants** - -``NVME_GET_FEATURES_SEL_CURRENT`` - -``NVME_GET_FEATURES_SEL_DEFAULT`` - -``NVME_GET_FEATURES_SEL_SAVED`` - -``NVME_GET_FEATURES_SEL_SUPPORTED`` - - - - -.. c:type:: enum nvme_cmd_format_mset - - Format NVM - Metadata Settings - -**Constants** - -``NVME_FORMAT_MSET_SEPARATE`` - indicates that the metadata is transferred - as part of a separate buffer. - -``NVME_FORMAT_MSET_EXTENDED`` - indicates that the metadata is transferred - as part of an extended data LBA. - - - - -.. c:type:: enum nvme_cmd_format_pi - - Format NVM - Protection Information - -**Constants** - -``NVME_FORMAT_PI_DISABLE`` - Protection information is not enabled. - -``NVME_FORMAT_PI_TYPE1`` - Protection information is enabled, Type 1. - -``NVME_FORMAT_PI_TYPE2`` - Protection information is enabled, Type 2. - -``NVME_FORMAT_PI_TYPE3`` - Protection information is enabled, Type 3. - - - - -.. c:type:: enum nvme_cmd_format_pil - - Format NVM - Protection Information Location - -**Constants** - -``NVME_FORMAT_PIL_LAST`` - Protection information is transferred as the last - bytes of metadata. - -``NVME_FORMAT_PIL_FIRST`` - Protection information is transferred as the first - bytes of metadata. - - - - -.. c:type:: enum nvme_cmd_format_ses - - Format NVM - Secure Erase Settings - -**Constants** - -``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. - -``NVME_FORMAT_SES_CRYPTO_ERASE`` - Cryptographic Erase: All user data shall - be erased cryptographically. This is - accomplished by deleting the encryption key. - - - - -.. c:type:: enum nvme_ns_mgmt_sel - - -**Constants** - -``NVME_NS_MGMT_SEL_CREATE`` - -``NVME_NS_MGMT_SEL_DELETE`` - - - - -.. c:type:: enum nvme_ns_attach_sel - - -**Constants** - -``NVME_NS_ATTACH_SEL_CTRL_ATTACH`` - -``NVME_NS_ATTACH_SEL_CTRL_DEATTACH`` - - - - -.. c:type:: enum nvme_fw_commit_ca - - -**Constants** - -``NVME_FW_COMMIT_CA_REPLACE`` - -``NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE`` - -``NVME_FW_COMMIT_CA_SET_ACTIVE`` - -``NVME_FW_COMMIT_CA_REPLACE_AND_ACTIVATE_IMMEDIATE`` - -``NVME_FW_COMMIT_CA_REPLACE_BOOT_PARTITION`` - -``NVME_FW_COMMIT_CA_ACTIVATE_BOOT_PARTITION`` - - - - -.. c:type:: enum nvme_directive_dtype - - -**Constants** - -``NVME_DIRECTIVE_DTYPE_IDENTIFY`` - -``NVME_DIRECTIVE_DTYPE_STREAMS`` - - - - -.. c:type:: enum nvme_directive_receive_doper - - -**Constants** - -``NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM`` - -``NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM`` - -``NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS`` - -``NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE`` - - - - -.. c:type:: enum nvme_directive_send_doper - - -**Constants** - -``NVME_DIRECTIVE_SEND_IDENTIFY_DOPER_ENDIR`` - -``NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_IDENTIFIER`` - -``NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE`` - - - - -.. c:type:: enum nvme_directive_send_identify_endir - - -**Constants** - -``NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_DISABLE`` - -``NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_ENABLE`` - - - - -.. c:type:: enum nvme_sanitize_sanact - - Sanitize Action - -**Constants** - -``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. - - - - -.. c:type:: enum nvme_dst_stc - - Action taken by the Device Self-test command - -**Constants** - -``NVME_DST_STC_SHORT`` - Start a short device self-test operation - -``NVME_DST_STC_LONG`` - Start an extended device self-test operation - -``NVME_DST_STC_VS`` - Start a vendor specific device self-test operation - -``NVME_DST_STC_ABORT`` - Abort device self-test operation - - - - -.. c:type:: enum nvme_virt_mgmt_act - - -**Constants** - -``NVME_VIRT_MGMT_ACT_PRIM_CTRL_FLEX_ALLOC`` - -``NVME_VIRT_MGMT_ACT_OFFLINE_SEC_CTRL`` - -``NVME_VIRT_MGMT_ACT_ASSIGN_SEC_CTRL`` - -``NVME_VIRT_MGMT_ACT_ONLINE_SEC_CTRL`` - - - - -.. c:type:: enum nvme_virt_mgmt_rt - - -**Constants** - -``NVME_VIRT_MGMT_RT_VQ_RESOURCE`` - -``NVME_VIRT_MGMT_RT_VI_RESOURCE`` - - - - -.. c:type:: enum nvme_ns_write_protect_cfg - - -**Constants** - -``NVME_NS_WP_CFG_NONE`` - -``NVME_NS_WP_CFG_PROTECT`` - -``NVME_NS_WP_CFG_PROTECT_POWER_CYCLE`` - -``NVME_NS_WP_CFG_PROTECT_PERMANENT`` - - - - -.. c:type:: enum nvme_log_ana_lsp - - -**Constants** - -``NVME_LOG_ANA_LSP_RGO_NAMESPACES`` - -``NVME_LOG_ANA_LSP_RGO_GROUPS_ONLY`` - - - - -.. c:type:: enum nvme_pevent_log_action - - -**Constants** - -``NVME_PEVENT_LOG_READ`` - -``NVME_PEVENT_LOG_EST_CTX_AND_READ`` - -``NVME_PEVENT_LOG_RELEASE_CTX`` - - - - -.. c:type:: enum nvme_feat_tmpthresh_thsel - - -**Constants** - -``NVME_FEATURE_TEMPTHRESH_THSEL_OVER`` - -``NVME_FEATURE_TEMPTHRESH_THSEL_UNDER`` - - - - -.. c:type:: enum nvme_features_async_event_config_flags - - -**Constants** - -``NVME_FEATURE_AENCFG_SMART_CRIT_SPARE`` - -``NVME_FEATURE_AENCFG_SMART_CRIT_TEMPERATURE`` - -``NVME_FEATURE_AENCFG_SMART_CRIT_DEGRADED`` - -``NVME_FEATURE_AENCFG_SMART_CRIT_READ_ONLY`` - -``NVME_FEATURE_AENCFG_SMART_CRIT_VOLATILE_BACKUP`` - -``NVME_FEATURE_AENCFG_SMART_CRIT_READ_ONLY_PMR`` - -``NVME_FEATURE_AENCFG_NOTICE_NAMESPACE_ATTRIBUTES`` - -``NVME_FEATURE_AENCFG_NOTICE_FIRMWARE_ACTIVATION`` - -``NVME_FEATURE_AENCFG_NOTICE_TELEMETRY_LOG`` - -``NVME_FEATURE_AENCFG_NOTICE_ANA_CHANGE`` - -``NVME_FEATURE_AENCFG_NOTICE_PL_EVENT`` - -``NVME_FEATURE_AENCFG_NOTICE_LBA_STATUS`` - -``NVME_FEATURE_AENCFG_NOTICE_EG_EVENT`` - -``NVME_FEATURE_AENCFG_NOTICE_DISCOVERY_CHANGE`` - - - - -.. c:type:: enum nvme_feat_plm_window_select - - -**Constants** - -``NVME_FEATURE_PLM_DTWIN`` - -``NVME_FEATURE_PLM_NDWIN`` - - - - -.. c:type:: enum nvme_feat_resv_notify_flags - - -**Constants** - -``NVME_FEAT_RESV_NOTIFY_REGPRE`` - -``NVME_FEAT_RESV_NOTIFY_RESREL`` - -``NVME_FEAT_RESV_NOTIFY_RESPRE`` - - - - -.. c:type:: enum nvme_feat_nswpcfg_state - - -**Constants** - -``NVME_FEAT_NS_NO_WRITE_PROTECT`` - -``NVME_FEAT_NS_WRITE_PROTECT`` - -``NVME_FEAT_NS_WRITE_PROTECT_PWR_CYCLE`` - -``NVME_FEAT_NS_WRITE_PROTECT_PERMANENT`` - - - - -.. c:type:: enum nvme_fctype - - -**Constants** - -``nvme_fabrics_type_property_set`` - -``nvme_fabrics_type_connect`` - -``nvme_fabrics_type_property_get`` - -``nvme_fabrics_type_auth_send`` - -``nvme_fabrics_type_auth_receive`` - -``nvme_fabrics_type_disconnect`` - - - - -.. c:type:: enum nvme_io_opcode - - -**Constants** - -``nvme_cmd_flush`` - -``nvme_cmd_write`` - -``nvme_cmd_read`` - -``nvme_cmd_write_uncor`` - -``nvme_cmd_compare`` - -``nvme_cmd_write_zeroes`` - -``nvme_cmd_dsm`` - -``nvme_cmd_verify`` - -``nvme_cmd_resv_register`` - -``nvme_cmd_resv_report`` - -``nvme_cmd_resv_acquire`` - -``nvme_cmd_resv_release`` - -``nvme_cmd_copy`` - -``nvme_zns_cmd_mgmt_send`` - -``nvme_zns_cmd_mgmt_recv`` - -``nvme_zns_cmd_append`` - - - - -.. c:type:: enum nvme_io_control_flags - - -**Constants** - -``NVME_IO_DTYPE_STREAMS`` - -``NVME_IO_DEAC`` - -``NVME_IO_ZNS_APPEND_PIREMAP`` - -``NVME_IO_PRINFO_PRCHK_REF`` - -``NVME_IO_PRINFO_PRCHK_APP`` - -``NVME_IO_PRINFO_PRCHK_GUARD`` - -``NVME_IO_PRINFO_PRACT`` - -``NVME_IO_FUA`` - -``NVME_IO_LR`` - - - - -.. c:type:: enum nvme_io_dsm_flags - - -**Constants** - -``NVME_IO_DSM_FREQ_UNSPEC`` - -``NVME_IO_DSM_FREQ_TYPICAL`` - -``NVME_IO_DSM_FREQ_RARE`` - -``NVME_IO_DSM_FREQ_READS`` - -``NVME_IO_DSM_FREQ_WRITES`` - -``NVME_IO_DSM_FREQ_RW`` - -``NVME_IO_DSM_FREQ_ONCE`` - -``NVME_IO_DSM_FREQ_PREFETCH`` - -``NVME_IO_DSM_FREQ_TEMP`` - -``NVME_IO_DSM_LATENCY_NONE`` - -``NVME_IO_DSM_LATENCY_IDLE`` - -``NVME_IO_DSM_LATENCY_NORM`` - -``NVME_IO_DSM_LATENCY_LOW`` - -``NVME_IO_DSM_SEQ_REQ`` - -``NVME_IO_DSM_COMPRESSED`` - - - - -.. c:type:: enum nvme_dsm_attributes - - -**Constants** - -``NVME_DSMGMT_IDR`` - -``NVME_DSMGMT_IDW`` - -``NVME_DSMGMT_AD`` - - - - -.. c:type:: enum nvme_resv_rtype - - -**Constants** - -``NVME_RESERVATION_RTYPE_WE`` - -``NVME_RESERVATION_RTYPE_EA`` - -``NVME_RESERVATION_RTYPE_WERO`` - -``NVME_RESERVATION_RTYPE_EARO`` - -``NVME_RESERVATION_RTYPE_WEAR`` - -``NVME_RESERVATION_RTYPE_EAAR`` - - - - -.. c:type:: enum nvme_resv_racqa - - -**Constants** - -``NVME_RESERVATION_RACQA_ACQUIRE`` - -``NVME_RESERVATION_RACQA_PREEMPT`` - -``NVME_RESERVATION_RACQA_PREEMPT_AND_ABORT`` - - - - -.. c:type:: enum nvme_resv_rrega - - -**Constants** - -``NVME_RESERVATION_RREGA_REGISTER_KEY`` - -``NVME_RESERVATION_RREGA_UNREGISTER_KEY`` - -``NVME_RESERVATION_RREGA_REPLACE_KEY`` - - - - -.. c:type:: enum nvme_resv_cptpl - - -**Constants** - -``NVME_RESERVATION_CPTPL_NO_CHANGE`` - -``NVME_RESERVATION_CPTPL_CLEAR`` - -``NVME_RESERVATION_CPTPL_PERSIST`` - - - - -.. c:type:: enum nvme_resv_rrela - - -**Constants** - -``NVME_RESERVATION_RRELA_RELEASE`` - -``NVME_RESERVATION_RRELA_CLEAR`` - - - - -.. c:type:: enum nvme_zns_send_action - - -**Constants** - -``NVME_ZNS_ZSA_CLOSE`` - -``NVME_ZNS_ZSA_FINISH`` - -``NVME_ZNS_ZSA_OPEN`` - -``NVME_ZNS_ZSA_RESET`` - -``NVME_ZNS_ZSA_OFFLINE`` - -``NVME_ZNS_ZSA_SET_DESC_EXT`` - -``NVME_ZNS_ZSA_ZRWA_FLUSH`` - - - - -.. c:type:: enum nvme_zns_recv_action - - -**Constants** - -``NVME_ZNS_ZRA_REPORT_ZONES`` - -``NVME_ZNS_ZRA_EXTENDED_REPORT_ZONES`` - - - - -.. c:type:: enum nvme_zns_report_options - - -**Constants** - -``NVME_ZNS_ZRAS_REPORT_ALL`` - -``NVME_ZNS_ZRAS_REPORT_EMPTY`` - -``NVME_ZNS_ZRAS_REPORT_IMPL_OPENED`` - -``NVME_ZNS_ZRAS_REPORT_EXPL_OPENED`` - -``NVME_ZNS_ZRAS_REPORT_CLOSED`` - -``NVME_ZNS_ZRAS_REPORT_FULL`` - -``NVME_ZNS_ZRAS_REPORT_READ_ONLY`` - -``NVME_ZNS_ZRAS_REPORT_OFFLINE`` - - -.. _fabrics.h: - -**fabrics.h** - - -Fabrics-specific definitions. - - - -.. c:type:: struct nvme_fabrics_config - - Defines all linux nvme fabrics initiator options - -**Definition** - -:: - - struct nvme_fabrics_config { - char *host_traddr; - char *host_iface; - int queue_size; - int nr_io_queues; - int reconnect_delay; - int ctrl_loss_tmo; - int fast_io_fail_tmo; - int keep_alive_tmo; - int nr_write_queues; - int nr_poll_queues; - int tos; - bool duplicate_connect; - bool disable_sqflow; - bool hdr_digest; - bool data_digest; - bool tls; - }; - -**Members** - -``host_traddr`` - Host transport address - -``host_iface`` - Host interface name - -``queue_size`` - Number of IO queue entries - -``nr_io_queues`` - Number of controller IO queues to establish - -``reconnect_delay`` - Time between two consecutive reconnect attempts. - -``ctrl_loss_tmo`` - Override the default controller reconnect attempt timeout in seconds - -``fast_io_fail_tmo`` - Set the fast I/O fail timeout in seconds. - -``keep_alive_tmo`` - Override the default keep-alive-timeout to this value in seconds - -``nr_write_queues`` - Number of queues to use for exclusively for writing - -``nr_poll_queues`` - Number of queues to reserve for polling completions - -``tos`` - Type of service - -``duplicate_connect`` - Allow multiple connections to the same target - -``disable_sqflow`` - Disable controller sq flow control - -``hdr_digest`` - Generate/verify header digest (TCP) - -``data_digest`` - Generate/verify data digest (TCP) - -``tls`` - Start TLS on the connection (TCP) - - - -.. c:function:: const char * nvmf_trtype_str (__u8 trtype) - - Decode TRTYPE field - -**Parameters** - -``__u8 trtype`` - value to be decoded - -**Description** - -Decode the transport type field in the discovery -log page entry. - -**Return** - -decoded string - - -.. c:function:: const char * nvmf_adrfam_str (__u8 adrfam) - - Decode ADRFAM field - -**Parameters** - -``__u8 adrfam`` - value to be decoded - -**Description** - -Decode the address family field in the discovery -log page entry. - -**Return** - -decoded string - - -.. c:function:: const char * nvmf_subtype_str (__u8 subtype) - - Decode SUBTYPE field - -**Parameters** - -``__u8 subtype`` - value to be decoded - -**Description** - -Decode the subsystem type field in the discovery -log page entry. - -**Return** - -decoded string - - -.. c:function:: const char * nvmf_treq_str (__u8 treq) - - Decode TREQ field - -**Parameters** - -``__u8 treq`` - value to be decoded - -**Description** - -Decode the transport requirements field in the -discovery log page entry. - -**Return** - -decoded string - - -.. c:function:: const char * nvmf_eflags_str (__u16 eflags) - - Decode EFLAGS field - -**Parameters** - -``__u16 eflags`` - value to be decoded - -**Description** - -Decode the EFLAGS field in the discovery log page -entry. - -**Return** - -decoded string - - -.. c:function:: const char * nvmf_sectype_str (__u8 sectype) - - Decode SECTYPE field - -**Parameters** - -``__u8 sectype`` - value to be decoded - -**Description** - -Decode the SECTYPE field in the discovery log page -entry. - -**Return** - -decoded string - - -.. c:function:: const char * nvmf_prtype_str (__u8 prtype) - - Decode RDMA Provider type field - -**Parameters** - -``__u8 prtype`` - value to be decoded - -**Description** - -Decode the RDMA Provider type field in the discovery -log page entry. - -**Return** - -decoded string - - -.. c:function:: const char * nvmf_qptype_str (__u8 qptype) - - Decode RDMA QP Service type field - -**Parameters** - -``__u8 qptype`` - value to be decoded - -**Description** - -Decode the RDMA QP Service type field in the discovery log page -entry. - -**Return** - -decoded string - - -.. c:function:: const char * nvmf_cms_str (__u8 cms) - - Decode RDMA connection management service field - -**Parameters** - -``__u8 cms`` - value to be decoded - -**Description** - -Decode the RDMA connection management service field in the discovery -log page entry. - -**Return** - -decoded string - - -.. c:function:: void nvmf_default_config (struct nvme_fabrics_config *cfg) - - Default values for fabrics configuration - -**Parameters** - -``struct nvme_fabrics_config *cfg`` - config values to set - -**Description** - -Initializes **cfg** with default values. - - -.. c:function:: int nvmf_add_ctrl (nvme_host_t h, nvme_ctrl_t c, const struct nvme_fabrics_config *cfg) - - Connect a controller and update topology - -**Parameters** - -``nvme_host_t h`` - Host to which the controller should be attached - -``nvme_ctrl_t c`` - Controller to be connected - -``const struct nvme_fabrics_config *cfg`` - Default configuration for the controller - -**Description** - -Issues a 'connect' command to the NVMe-oF controller and inserts **c** -into the topology using **h** as parent. -**c** must be initialized and not connected to the topology. - -**Return** - -0 on success; on failure errno is set and -1 is returned. - - -.. c:function:: int nvmf_get_discovery_log (nvme_ctrl_t c, struct nvmf_discovery_log **logp, int max_retries) - - Return the discovery log page - -**Parameters** - -``nvme_ctrl_t c`` - Discover controller to use - -``struct nvmf_discovery_log **logp`` - Pointer to the log page to be returned - -``int max_retries`` - maximum number of log page entries to be returned - -**Return** - -0 on success; on failure -1 is returned and errno is set - - -.. c:function:: char * nvmf_hostnqn_generate () - - Generate a machine specific host nqn - -**Parameters** - -**Return** - -An nvm namespace qualified name string based on the machine -identifier, or NULL if not successful. - - -.. c:function:: char * nvmf_hostnqn_from_file () - - Reads the host nvm qualified name from the config default location in /etc/nvme/ - -**Parameters** - -**Return** - -The host nqn, or NULL if unsuccessful. If found, the caller -is responsible to free the string. - - -.. c:function:: char * nvmf_hostid_from_file () - - Reads the host identifier from the config default location in /etc/nvme/. - -**Parameters** - -**Return** - -The host identifier, or NULL if unsuccessful. If found, the caller - is responsible to free the string. - - -.. c:function:: nvme_ctrl_t nvmf_connect_disc_entry (nvme_host_t h, struct nvmf_disc_log_entry *e, const struct nvme_fabrics_config *defcfg, bool *discover) - - Connect controller based on the discovery log page entry - -**Parameters** - -``nvme_host_t h`` - Host to which the controller should be connected - -``struct nvmf_disc_log_entry *e`` - Discovery log page entry - -``const struct nvme_fabrics_config *defcfg`` - Default configurationn to be used for the new controller - -``bool *discover`` - Set to 'true' if the new controller is a discovery controller - -**Return** - -Pointer to the new controller - - -.. c:function:: void nvme_chomp (char *s, int l) - - Strip trailing white space - -**Parameters** - -``char *s`` - String to strip - -``int l`` - Maximum length of string - - -.. _util.h: - -**util.h** - - -libnvme utility functions - - - -.. c:type:: enum nvme_connect_err - - nvme connect error codes - -**Constants** - -``ENVME_CONNECT_RESOLVE`` - failed to resolve host - -``ENVME_CONNECT_ADDRFAM`` - unrecognized address family - -``ENVME_CONNECT_TRADDR`` - failed to get traddr - -``ENVME_CONNECT_TARG`` - need a transport (-t) argument - -``ENVME_CONNECT_AARG`` - need a address (-a) argument - -``ENVME_CONNECT_OPEN`` - failed to open nvme-fabrics device - -``ENVME_CONNECT_WRITE`` - failed to write to nvme-fabrics device - -``ENVME_CONNECT_READ`` - failed to read from nvme-fabrics device - -``ENVME_CONNECT_PARSE`` - failed to parse ctrl info - -``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 - - -.. c:function:: __u8 nvme_status_to_errno (int status, bool fabrics) - - Converts nvme return status to errno - -**Parameters** - -``int status`` - Return status from an nvme passthrough commmand - -``bool fabrics`` - Set to true if :c:type:`status` is to a fabrics target. - -**Return** - -An errno representing the nvme status if it is an nvme status field, -or unchanged status is < 0 since errno is already set. - - -.. c:function:: const char * nvme_status_to_string (int status, bool fabrics) - - Returns string describing nvme return status. - -**Parameters** - -``int status`` - Return status from an nvme passthrough commmand - -``bool fabrics`` - Set to true if :c:type:`status` is to a fabrics target. - -**Return** - -String representation of the nvme status if it is an nvme status field, -or a standard errno string if status is < 0. - - -.. c:function:: const char * nvme_errno_to_string (int err) - - Returns string describing nvme connect failures - -**Parameters** - -``int err`` - Returned error code from nvme_add_ctrl() - -**Return** - -String representation of the nvme connect error codes - - -.. c:function:: void nvme_init_id_ns (struct nvme_id_ns *ns, __u64 nsze, __u64 ncap, __u8 flbas, __u8 dps, __u8 nmic, __u32 anagrpid, __u16 nvmsetid) - - Initialize an Identify Namepsace structure for creation. - -**Parameters** - -``struct nvme_id_ns *ns`` - Address of the Identify Namespace structure to initialize - -``__u64 nsze`` - Namespace size - -``__u64 ncap`` - namespace capacity - -``__u8 flbas`` - formatted logical block size settings - -``__u8 dps`` - Data protection settings - -``__u8 nmic`` - Namespace sharing capabilities - -``__u32 anagrpid`` - ANA group identifier - -``__u16 nvmsetid`` - NVM Set identifer - -**Description** - -This is intended to be used with a namespace management "create", see -nvme_ns_mgmt_create(). - - -.. c:function:: void nvme_init_ctrl_list (struct nvme_ctrl_list *cntlist, __u16 num_ctrls, __u16 *ctrlist) - - Initialize an nvme_ctrl_list structure from an array. - -**Parameters** - -``struct nvme_ctrl_list *cntlist`` - The controller list structure to initialize - -``__u16 num_ctrls`` - The number of controllers in the array, :c:type:`ctrlist`. - -``__u16 *ctrlist`` - An array of controller identifiers in CPU native endian. - -**Description** - -This is intended to be used with any command that takes a controller list -argument. See nvme_ns_attach_ctrls() and nvme_ns_detach(). - - -.. c:function:: void nvme_init_dsm_range (struct nvme_dsm_range *dsm, __u32 *ctx_attrs, __u32 *llbas, __u64 *slbas, __u16 nr_ranges) - - Constructs a data set range structure - -**Parameters** - -``struct nvme_dsm_range *dsm`` - DSM range array - -``__u32 *ctx_attrs`` - Array of context attributes - -``__u32 *llbas`` - Array of length in logical blocks - -``__u64 *slbas`` - Array of starting logical blocks - -``__u16 nr_ranges`` - The size of the dsm arrays - -**Description** - -Each array must be the same size of size 'nr_ranges'. This is intended to be -used with constructing a payload for nvme_dsm(). - -**Return** - -The nvme command status if a response was received or -errno -otherwise. - - -.. c:function:: void nvme_init_copy_range (struct nvme_copy_range *copy, __u16 *nlbs, __u64 *slbas, __u32 *eilbrts, __u32 *elbatms, __u32 *elbats, __u16 nr) - - Constructs a copy range structure - -**Parameters** - -``struct nvme_copy_range *copy`` - Copy range array - -``__u16 *nlbs`` - Number of logical blocks - -``__u64 *slbas`` - Starting LBA - -``__u32 *eilbrts`` - Expected initial logical block reference tag - -``__u32 *elbatms`` - Expected logical block application tag mask - -``__u32 *elbats`` - Expected logical block application tag - -``__u16 nr`` - Number of descriptors to construct - - -.. c:function:: int nvme_get_feature_length (int fid, __u32 cdw11, __u32 *len) - - Retreive the command payload length for a specific feature identifier - -**Parameters** - -``int fid`` - Feature identifier, see :c:type:`enum nvme_features_id `. - -``__u32 cdw11`` - The cdw11 value may affect the transfer (only known fid is - ``NVME_FEAT_FID_HOST_ID``) - -``__u32 *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 -recognize :c:type:`fid`. - - -.. c:function:: int nvme_get_directive_receive_length (enum nvme_directive_dtype dtype, enum nvme_directive_receive_doper doper, __u32 *len) - - -**Parameters** - -``enum nvme_directive_dtype dtype`` - Directive type, see :c:type:`enum nvme_directive_dtype ` - -``enum nvme_directive_receive_doper doper`` - Directive receive operation, see :c:type:`enum nvme_directive_receive_doper ` - -``__u32 *len`` - On success, set to this directives payload length in bytes. - -**Return** - -0 on success, -1 with errno set to EINVAL if the function did not -recognize :c:type:`dtype` or :c:type:`doper`. - - diff --git a/doc/list-man-pages.sh b/doc/list-man-pages.sh new file mode 100755 index 0000000000..fef237cb47 --- /dev/null +++ b/doc/list-man-pages.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +file=$1 + +for func in $(sed -n 's/ \* \([a-z_]*\)() -.*/\1/p' $file); do + echo ${func} +done + +for struct in $(sed -n 's/ \* struct \([a-z_]*\) -.*/\1/p' $file); do + echo ${struct} +done + +for enum in $(sed -n 's/ \* enum \([a-z_]*\) -.*/\1/p' $file); do + echo ${enum} +done diff --git a/doc/meson.build b/doc/meson.build index 1bb3444fdc..0936d558fe 100644 --- a/doc/meson.build +++ b/doc/meson.build @@ -2,36 +2,107 @@ # # This file is part of libnvme. # Copyright (c) 2022 Dell Inc. +# Copyright (c) 2022 SUSE LLC # # Authors: Martin Belanger +# Authors: Daniel Wagner # -# Requires python3-sphinx and python3-sphinx-rtd-theme +api_files = [ + 'filters.h', + 'ioctl.h', + 'linux.h', + 'log.h', + 'tree.h', + 'types.h', + 'fabrics.h', + 'util.h' +] sphinx_sources = [ 'conf.py', - 'libnvme.rst', - 'index.rst' + 'index.rst', + 'config-schema.json' ] -man_pages = [ - 'libnvme.1' -] +want_docs = get_option('docs') +want_docs_build = get_option('docs-build') +if want_docs != 'false' + kernel_doc = find_program('kernel-doc') -mandir1 = join_paths(get_option('mandir'), 'man1') + if want_docs == 'all' or want_docs == 'man' + mandir = join_paths(get_option('mandir'), 'man2') + list_man_pages = find_program('list-man-pages.sh') + if want_docs_build + foreach apif : api_files + afile = files('../src/nvme/' + apif) + c = run_command(list_man_pages, afile) + man_pages = c.stdout().split() + foreach page : man_pages + custom_target( + page.underscorify() + '_man', + input: afile, + output: page + '.2', + capture: true, + command: [kernel_doc, + '-module', 'libnvme', + '-man', + '-function', + page, + afile], + install: true, + install_dir: mandir) + endforeach + endforeach + else + if want_docs == 'all' or want_docs == 'man' + install_subdir('man', install_dir: mandir) + endif + endif + endif -if get_option('man') + if want_docs == 'all' or want_docs == 'html' + htmldir = join_paths(get_option('htmldir'), 'nvme') sphinx_build = find_program('sphinx-build-3', 'sphinx-build') - - custom_target( - 'man', + if sphinx_build.found() and want_docs_build + cat = find_program('cat') + rsts = [] + foreach apif : api_files + afile = files('../src/nvme/' + apif) + rst = custom_target( + apif.underscorify() + '_rst', + input: afile, + output: '@BASENAME@._rst', + capture: true, + command: [kernel_doc, + '-rst', + '@INPUT@']) + rsts += rst + endforeach + libnvme = custom_target( + 'libnvme', + command: [ cat, '@INPUT@' ], + capture: true, + input: rsts, + output: 'libnvme.rst') + static_sources = [] + foreach file : sphinx_sources + static_sources += configure_file(input: file, output: file, copy: true) + endforeach + custom_target( + 'generate_doc_html', + input: [static_sources, libnvme], + output: 'html', command: [sphinx_build, - '-b', 'man', - meson.current_source_dir(), - meson.current_build_dir()], - input: sphinx_sources, - output: man_pages, + '-b', 'html', + '@OUTDIR@', + '@OUTDIR@' + '/html'], install: true, - install_dir: mandir1, - ) + install_dir: htmldir) + else + if want_docs == 'all' or want_docs == 'html' + install_subdir('html', install_dir: htmldir) + endif + endif + endif endif diff --git a/doc/regen-man.sh b/doc/regen-man.sh deleted file mode 100755 index 94b60a1673..0000000000 --- a/doc/regen-man.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash - -API_FILES="src/nvme/filters.h src/nvme/ioctl.h src/nvme/linux.h src/nvme/log.h src/nvme/tree.h src/nvme/types.h src/nvme/fabrics.h src/nvme/util.h" -MAN=doc/man - -for file in $API_FILES ; do - for func in $(sed -n 's/ \* \([a-z_]*\)() -.*/\1/p' $file); do - echo "Updating ${func}.2" - ./doc/kernel-doc -man -function $func $file > ${MAN}/${func}.2 - done - for struct in $(sed -n 's/ \* struct \([a-z_]*\) -.*/\1/p' $file); do - echo "Updating ${struct}.2" - ./doc/kernel-doc -man -function $struct $file > ${MAN}/${struct}.2 - done - for enum in $(sed -n 's/ \* enum \([a-z_]*\) -.*/\1/p' $file); do - echo "Updating ${enum}.2" - ./doc/kernel-doc -man -function $enum $file > ${MAN}/${enum}.2 - done -done diff --git a/doc/regen-rst.sh b/doc/regen-rst.sh deleted file mode 100755 index 25be581bd0..0000000000 --- a/doc/regen-rst.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -API_FILES="filters.h ioctl.h linux.h log.h tree.h types.h fabrics.h util.h" -DOC_ROOT=doc - -rm ${DOC_ROOT}/libnvme.rst -for file in $API_FILES ; do - ./doc/kernel-doc -rst src/nvme/$file >> ${DOC_ROOT}/libnvme.rst -done diff --git a/doc/update-docs.sh b/doc/update-docs.sh new file mode 100755 index 0000000000..5cb1ddc35f --- /dev/null +++ b/doc/update-docs.sh @@ -0,0 +1,17 @@ +#!/bin/sh -x + +DESTDIR=$(pwd) + +BUILDDIR="$(mktemp -d)" +trap 'rm -rf -- $BUILDDIR' EXIT + +meson $BUILDDIR -Ddocs=all -Ddocs-build=true +ninja -C $BUILDDIR + +rm -rf $DESTDIR/doc/man +rm -rf $DESTDIR/doc/html +mkdir $DESTDIR/doc/man + +cp -R $BUILDDIR/doc/html $DESTDIR/doc/ +find $BUILDDIR/doc -maxdepth 1 -name '*.2' -exec cp {} $DESTDIR/doc/man \; + diff --git a/meson_options.txt b/meson_options.txt index cff41d480b..f1bca656f0 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,7 +1,9 @@ # -*- mode: meson -*- - option('pkgconfiglibdir', type : 'string', value : '', description : 'directory for standard pkg-config files') +option('htmldir', type : 'string', value : '', description : 'directory for HTML documentation') + +option('docs', type : 'combo', choices : ['false', 'html', 'man', 'all'], description : 'install documentation') +option('docs-build', type : 'boolean', value : 'false', description : 'build documentation') -option('man', type : 'boolean', value : false, description : 'build and install man pages (requires sphinx-build)') option('python', type : 'combo', choices : ['auto', 'true', 'false'], description : 'Generate libnvme python bindings') option('openssl', type : 'feature', value: 'auto', description : 'OpenSSL support') From 02c81daa0c738f96b5a234adcfde307258a03b74 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Fri, 4 Feb 2022 12:45:19 +0100 Subject: [PATCH 0451/1564] doc: Fix sphinx setup sphinx warns about cyclic refernce. Do not include the index into the index file. Also add the build dir and index.rst to the ignore list. This avoids another type of warnings. Signed-off-by: Daniel Wagner --- doc/conf.py | 2 +- doc/index.rst | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/conf.py b/doc/conf.py index 8e10c92b33..422386a5b0 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -40,7 +40,7 @@ # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] +exclude_patterns = ['html', 'man', 'index.rst', 'Thumbs.db', '.DS_Store'] # -- Options for HTML output ------------------------------------------------- diff --git a/doc/index.rst b/doc/index.rst index 716808a9f0..639b3d5ba3 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -10,7 +10,6 @@ Welcome to libnvme's documentation! :maxdepth: 2 :caption: Contents: - index libnvme From 2595b3b2795a4b9ae367fa2cebf32c982ec00a3c Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Fri, 4 Feb 2022 12:48:45 +0100 Subject: [PATCH 0452/1564] doc: Regenerate all documentation Signed-off-by: Daniel Wagner --- doc/html/.buildinfo | 4 + doc/html/.doctrees/environment.pickle | Bin 0 -> 833103 bytes doc/html/.doctrees/libnvme.doctree | Bin 0 -> 3501997 bytes doc/html/_sources/libnvme.rst.txt | 18498 ++++++++++++++++ doc/html/_static/basic.css | 906 + doc/html/_static/css/badge_only.css | 1 + .../_static/css/fonts/Roboto-Slab-Bold.woff | Bin 0 -> 87624 bytes .../_static/css/fonts/Roboto-Slab-Bold.woff2 | Bin 0 -> 67312 bytes .../css/fonts/Roboto-Slab-Regular.woff | Bin 0 -> 86288 bytes .../css/fonts/Roboto-Slab-Regular.woff2 | Bin 0 -> 66444 bytes .../_static/css/fonts/fontawesome-webfont.eot | Bin 0 -> 165742 bytes .../_static/css/fonts/fontawesome-webfont.svg | 2671 +++ .../_static/css/fonts/fontawesome-webfont.ttf | Bin 0 -> 165548 bytes .../css/fonts/fontawesome-webfont.woff | Bin 0 -> 98024 bytes .../css/fonts/fontawesome-webfont.woff2 | Bin 0 -> 77160 bytes .../_static/css/fonts/lato-bold-italic.woff | Bin 0 -> 323344 bytes .../_static/css/fonts/lato-bold-italic.woff2 | Bin 0 -> 193308 bytes doc/html/_static/css/fonts/lato-bold.woff | Bin 0 -> 309728 bytes doc/html/_static/css/fonts/lato-bold.woff2 | Bin 0 -> 184912 bytes .../_static/css/fonts/lato-normal-italic.woff | Bin 0 -> 328412 bytes .../css/fonts/lato-normal-italic.woff2 | Bin 0 -> 195704 bytes doc/html/_static/css/fonts/lato-normal.woff | Bin 0 -> 309192 bytes doc/html/_static/css/fonts/lato-normal.woff2 | Bin 0 -> 182708 bytes doc/html/_static/css/theme.css | 4 + doc/html/_static/doctools.js | 326 + doc/html/_static/documentation_options.js | 12 + doc/html/_static/file.png | Bin 0 -> 286 bytes doc/html/_static/jquery-3.5.1.js | 10872 +++++++++ doc/html/_static/jquery.js | 2 + doc/html/_static/js/badge_only.js | 1 + .../_static/js/html5shiv-printshiv.min.js | 4 + doc/html/_static/js/html5shiv.min.js | 4 + doc/html/_static/js/theme.js | 1 + doc/html/_static/language_data.js | 297 + doc/html/_static/minus.png | Bin 0 -> 90 bytes doc/html/_static/plus.png | Bin 0 -> 90 bytes doc/html/_static/pygments.css | 74 + doc/html/_static/searchtools.js | 529 + doc/html/_static/underscore-1.13.1.js | 2042 ++ doc/html/_static/underscore.js | 6 + doc/html/genindex.html | 1373 ++ doc/html/libnvme.html | 14713 ++++++++++++ doc/html/objects.inv | Bin 0 -> 9675 bytes doc/html/search.html | 111 + doc/html/searchindex.js | 1 + doc/man/__nvme_get_log_page.2 | 27 - doc/man/enum .2 | 678 - doc/man/enum nvme_cmd_format_mset.2 | 18 - doc/man/enum nvme_cmd_format_ses.2 | 24 - doc/man/enum nvme_feat_tmpthresh_thsel.2 | 18 - doc/man/enum nvme_id_ctrl_cmic.2 | 30 - doc/man/enum nvme_id_ctrl_ctratt.2 | 66 - doc/man/enum nvme_id_ctrl_oaes.2 | 42 - doc/man/enum nvme_psd_ps.2 | 18 - doc/man/enum nvme_subsys_type.2 | 18 - doc/man/is_64bit_reg.2 | 16 - doc/man/libnvme.2 | 2 - ...vme_admin_opcode.2 => nvme_admin_opcode.2} | 45 +- doc/man/nvme_admin_passthru.2 | 44 +- doc/man/nvme_admin_passthru64.2 | 71 - ..._info_css_nvm.2 => nvme_ae_info_css_nvm.2} | 5 +- ...e_ae_info_error.2 => nvme_ae_info_error.2} | 8 +- ...ae_info_notice.2 => nvme_ae_info_notice.2} | 10 +- ...e_ae_info_smart.2 => nvme_ae_info_smart.2} | 5 +- .../{enum nvme_ae_type.2 => nvme_ae_type.2} | 7 +- ...=> nvme_aggregate_endurance_group_event.2} | 6 +- ...=> nvme_aggregate_predictable_lat_event.2} | 6 +- ...ana_group_desc.2 => nvme_ana_group_desc.2} | 14 +- .../{struct nvme_ana_log.2 => nvme_ana_log.2} | 6 +- doc/man/nvme_ana_state.2 | 31 + doc/man/nvme_apst_entry.2 | 26 + doc/man/nvme_boot_partition.2 | 26 + doc/man/nvme_cap_config_desc.2 | 0 doc/man/nvme_capacity_mgmt.2 | 12 + doc/man/nvme_capacity_mgmt_args.2 | 45 + doc/man/nvme_change_ns_event.2 | 50 + doc/man/nvme_channel_config_desc.2 | 24 + doc/man/nvme_chomp.2 | 12 + doc/man/nvme_cmb_size.2 | 11 + doc/man/nvme_cmd_effects.2 | 41 + ...d_effects_log.2 => nvme_cmd_effects_log.2} | 7 +- doc/man/nvme_cmd_format_mset.2 | 20 + ...e_cmd_format_pi.2 => nvme_cmd_format_pi.2} | 12 +- doc/man/nvme_cmd_format_pil.2 | 20 + doc/man/nvme_cmd_format_ses.2 | 33 + ...d_get_log_lid.2 => nvme_cmd_get_log_lid.2} | 46 +- doc/man/nvme_cmd_get_log_telemetry_host_lsp.2 | 16 + doc/man/nvme_compare.2 | 52 +- doc/man/nvme_connect_err.2 | 78 + ...enum nvme_constants.2 => nvme_constants.2} | 85 +- doc/man/nvme_copy.2 | 12 + doc/man/nvme_copy_args.2 | 83 + doc/man/nvme_copy_range.2 | 32 + doc/man/nvme_create_ctrl.2 | 32 + doc/man/nvme_create_root.2 | 14 + doc/man/nvme_csi.2 | 18 + doc/man/nvme_ctrl_disconnect.2 | 8 - doc/man/nvme_ctrl_first_ns.2 | 9 +- doc/man/nvme_ctrl_first_path.2 | 9 +- doc/man/nvme_ctrl_for_each_ns.2 | 12 +- doc/man/nvme_ctrl_for_each_ns_safe.2 | 16 +- doc/man/nvme_ctrl_for_each_path.2 | 12 +- doc/man/nvme_ctrl_for_each_path_safe.2 | 16 +- doc/man/nvme_ctrl_get_address.2 | 10 +- doc/man/nvme_ctrl_get_config.2 | 11 + doc/man/nvme_ctrl_get_dhchap_key.2 | 11 + doc/man/nvme_ctrl_get_fd.2 | 9 +- doc/man/nvme_ctrl_get_firmware.2 | 9 +- doc/man/nvme_ctrl_get_host_iface.2 | 11 + doc/man/nvme_ctrl_get_host_traddr.2 | 11 + doc/man/nvme_ctrl_get_model.2 | 9 +- doc/man/nvme_ctrl_get_name.2 | 9 +- doc/man/nvme_ctrl_get_numa_node.2 | 9 +- doc/man/nvme_ctrl_get_queue_count.2 | 9 +- doc/man/nvme_ctrl_get_serial.2 | 9 +- doc/man/nvme_ctrl_get_sqsize.2 | 9 +- doc/man/nvme_ctrl_get_state.2 | 9 +- doc/man/nvme_ctrl_get_subsysnqn.2 | 9 +- doc/man/nvme_ctrl_get_subsystem.2 | 9 +- doc/man/nvme_ctrl_get_sysfs_dir.2 | 9 +- doc/man/nvme_ctrl_get_traddr.2 | 11 + doc/man/nvme_ctrl_get_transport.2 | 9 +- doc/man/nvme_ctrl_get_trsvcid.2 | 11 + doc/man/nvme_ctrl_identify.2 | 16 +- doc/man/nvme_ctrl_is_discovered.2 | 11 + doc/man/nvme_ctrl_is_discovery_ctrl.2 | 14 + doc/man/nvme_ctrl_is_persistent.2 | 11 + ...ruct nvme_ctrl_list.2 => nvme_ctrl_list.2} | 6 +- doc/man/nvme_ctrl_metadata_type.2 | 108 + doc/man/nvme_ctrl_next_ns.2 | 13 +- doc/man/nvme_ctrl_next_path.2 | 11 +- doc/man/nvme_ctrl_reset.2 | 6 +- doc/man/nvme_ctrl_set_dhchap_key.2 | 12 + doc/man/nvme_ctrl_set_discovered.2 | 14 + doc/man/nvme_ctrl_set_discovery_ctrl.2 | 15 + doc/man/nvme_ctrl_set_persistent.2 | 14 + doc/man/nvme_ctrls_filter.2 | 4 +- doc/man/nvme_default_host.2 | 14 + doc/man/nvme_dev_self_test.2 | 30 +- doc/man/nvme_dev_self_test_args.2 | 35 + ...rective_dtype.2 => nvme_directive_dtype.2} | 4 +- ...doper.2 => nvme_directive_receive_doper.2} | 6 +- doc/man/nvme_directive_recv.2 | 36 +- doc/man/nvme_directive_recv_args.2 | 55 + .../nvme_directive_recv_identify_parameters.2 | 14 +- doc/man/nvme_directive_recv_stream_allocate.2 | 16 +- .../nvme_directive_recv_stream_parameters.2 | 14 +- doc/man/nvme_directive_recv_stream_status.2 | 18 +- doc/man/nvme_directive_send.2 | 40 +- doc/man/nvme_directive_send_args.2 | 55 + ...nd_doper.2 => nvme_directive_send_doper.2} | 5 +- doc/man/nvme_directive_send_id_endir.2 | 20 +- ...2 => nvme_directive_send_identify_endir.2} | 4 +- ...directive_send_stream_release_identifier.2 | 14 +- ...e_directive_send_stream_release_resource.2 | 10 +- doc/man/nvme_directive_types.2 | 18 + doc/man/nvme_disconnect_ctrl.2 | 13 + doc/man/nvme_dsm.2 | 25 +- doc/man/nvme_dsm_args.2 | 43 + ...dsm_attributes.2 => nvme_dsm_attributes.2} | 5 +- ...ruct nvme_dsm_range.2 => nvme_dsm_range.2} | 5 +- .../{enum nvme_dst_stc.2 => nvme_dst_stc.2} | 12 +- doc/man/nvme_dump_config.2 | 14 + ...ags.2 => nvme_eg_critical_warning_flags.2} | 5 +- ...te_log.2 => nvme_eg_event_aggregate_log.2} | 4 +- doc/man/nvme_end_grp_chan_desc.2 | 20 + doc/man/nvme_end_grp_config_desc.2 | 46 + ...group_log.2 => nvme_endurance_group_log.2} | 17 +- doc/man/nvme_err_pel.2 | 16 + doc/man/nvme_errno_to_string.2 | 11 + doc/man/nvme_error_log_page.2 | 107 + doc/man/nvme_fabrics_config.2 | 75 + doc/man/{enum nvme_fctype.2 => nvme_fctype.2} | 8 +- doc/man/nvme_feat.2 | 496 + ...e_feat_auto_pst.2 => nvme_feat_auto_pst.2} | 4 +- ...t_behavior.2 => nvme_feat_host_behavior.2} | 6 +- ...pcfg_state.2 => nvme_feat_nswpcfg_state.2} | 6 +- ...select.2 => nvme_feat_plm_window_select.2} | 4 +- doc/man/nvme_feat_resv_notify_flags.2 | 21 + doc/man/nvme_feat_tmpthresh_thsel.2 | 16 + ... nvme_features_async_event_config_flags.2} | 16 +- ... nvme_features_id.2 => nvme_features_id.2} | 63 +- doc/man/nvme_fid_supported_effects.2 | 78 + doc/man/nvme_fid_supported_effects_log.2 | 16 + doc/man/nvme_firmware_slot.2 | 23 + doc/man/nvme_first_host.2 | 11 + doc/man/nvme_first_subsystem.2 | 11 +- doc/man/nvme_flush.2 | 14 +- doc/man/nvme_for_each_host.2 | 12 + doc/man/nvme_for_each_host_safe.2 | 15 + doc/man/nvme_for_each_subsystem.2 | 14 +- doc/man/nvme_for_each_subsystem_safe.2 | 18 +- doc/man/nvme_format_nvm.2 | 42 +- doc/man/nvme_format_nvm_args.2 | 52 + doc/man/nvme_format_nvm_compln_event.2 | 26 + doc/man/nvme_format_nvm_start_event.2 | 23 + doc/man/nvme_free_ctrl.2 | 5 +- doc/man/nvme_free_host.2 | 9 + doc/man/nvme_free_ns.2 | 9 + doc/man/nvme_free_subsystem.2 | 11 + doc/man/nvme_free_tree.2 | 10 +- doc/man/nvme_fw_commit.2 | 27 +- doc/man/nvme_fw_commit_args.2 | 39 + ...vme_fw_commit_ca.2 => nvme_fw_commit_ca.2} | 8 +- doc/man/nvme_fw_commit_event.2 | 32 + doc/man/nvme_fw_download.2 | 27 +- doc/man/nvme_fw_download_args.2 | 39 + doc/man/nvme_fw_download_seq.2 | 24 +- doc/man/nvme_gen_dhchap_key.2 | 24 + doc/man/nvme_get_ana_log_len.2 | 9 +- doc/man/nvme_get_attr.2 | 14 + doc/man/nvme_get_ctrl_attr.2 | 13 +- doc/man/nvme_get_ctrl_telemetry.2 | 24 +- doc/man/nvme_get_directive_receive_length.2 | 14 +- doc/man/nvme_get_feature_length.2 | 17 +- doc/man/nvme_get_features.2 | 36 +- doc/man/nvme_get_features_arbitration.2 | 12 +- doc/man/nvme_get_features_args.2 | 56 + doc/man/nvme_get_features_async_event.2 | 12 +- doc/man/nvme_get_features_auto_pst.2 | 15 +- doc/man/nvme_get_features_data.2 | 24 + .../nvme_get_features_endurance_event_cfg.2 | 15 +- doc/man/nvme_get_features_err_recovery.2 | 12 +- doc/man/nvme_get_features_hctm.2 | 12 +- doc/man/nvme_get_features_host_behavior.2 | 15 +- doc/man/nvme_get_features_host_id.2 | 21 +- doc/man/nvme_get_features_host_mem_buf.2 | 12 +- doc/man/nvme_get_features_iocs_profile.2 | 18 + doc/man/nvme_get_features_irq_coalesce.2 | 12 +- doc/man/nvme_get_features_irq_config.2 | 15 +- doc/man/nvme_get_features_kato.2 | 12 +- doc/man/nvme_get_features_lba_range.2 | 16 +- doc/man/nvme_get_features_lba_sts_interval.2 | 12 +- doc/man/nvme_get_features_nopsc.2 | 12 +- doc/man/nvme_get_features_num_queues.2 | 12 +- doc/man/nvme_get_features_plm_config.2 | 19 +- doc/man/nvme_get_features_plm_window.2 | 16 +- doc/man/nvme_get_features_power_mgmt.2 | 12 +- doc/man/nvme_get_features_resv_mask.2 | 12 +- doc/man/nvme_get_features_resv_persist.2 | 12 +- doc/man/nvme_get_features_rrl.2 | 12 +- doc/man/nvme_get_features_sanitize.2 | 12 +- ...features_sel.2 => nvme_get_features_sel.2} | 10 +- doc/man/nvme_get_features_simple.2 | 18 + doc/man/nvme_get_features_sw_progress.2 | 12 +- doc/man/nvme_get_features_temp_thresh.2 | 12 +- doc/man/nvme_get_features_timestamp.2 | 14 +- doc/man/nvme_get_features_volatile_wc.2 | 12 +- doc/man/nvme_get_features_write_atomic.2 | 12 +- doc/man/nvme_get_features_write_protect.2 | 14 +- doc/man/nvme_get_host_telemetry.2 | 20 +- doc/man/nvme_get_lba_status.2 | 31 +- doc/man/nvme_get_lba_status_args.2 | 52 + doc/man/nvme_get_lba_status_log.2 | 15 + doc/man/nvme_get_log.2 | 39 +- doc/man/nvme_get_log_ana.2 | 20 +- doc/man/nvme_get_log_ana_groups.2 | 14 +- doc/man/nvme_get_log_args.2 | 74 + doc/man/nvme_get_log_boot_partition.2 | 25 + doc/man/nvme_get_log_changed_ns_list.2 | 22 +- doc/man/nvme_get_log_cmd_effects.2 | 21 +- doc/man/nvme_get_log_create_telemetry_host.2 | 12 +- doc/man/nvme_get_log_device_self_test.2 | 14 +- doc/man/nvme_get_log_discovery.2 | 16 +- doc/man/nvme_get_log_endurance_group.2 | 12 +- doc/man/nvme_get_log_endurance_grp_evt.2 | 18 +- doc/man/nvme_get_log_error.2 | 24 +- doc/man/nvme_get_log_fid_supported_effects.2 | 18 + doc/man/nvme_get_log_fw_slot.2 | 22 +- doc/man/nvme_get_log_lba_status.2 | 18 +- doc/man/nvme_get_log_media_unit_stat.2 | 18 + doc/man/nvme_get_log_page.2 | 33 +- doc/man/nvme_get_log_page_padded.2 | 30 + doc/man/nvme_get_log_persistent_event.2 | 18 + doc/man/nvme_get_log_predictable_lat_event.2 | 15 +- doc/man/nvme_get_log_predictable_lat_nvmset.2 | 17 +- doc/man/nvme_get_log_reservation.2 | 10 +- doc/man/nvme_get_log_sanitize.2 | 16 +- doc/man/nvme_get_log_smart.2 | 30 +- .../nvme_get_log_support_cap_config_list.2 | 18 + doc/man/nvme_get_log_supported_log_pages.2 | 18 + doc/man/nvme_get_log_telemetry_ctrl.2 | 12 +- doc/man/nvme_get_log_telemetry_host.2 | 14 +- doc/man/nvme_get_log_zns_changed_zones.2 | 23 + doc/man/nvme_get_logical_block_size.2 | 18 + doc/man/nvme_get_new_host_telemetry.2 | 20 +- doc/man/nvme_get_ns_attr.2 | 13 +- doc/man/nvme_get_nsid.2 | 15 +- doc/man/nvme_get_path_attr.2 | 13 +- doc/man/nvme_get_property.2 | 18 +- doc/man/nvme_get_property_args.2 | 31 + doc/man/nvme_get_subsys_attr.2 | 13 +- doc/man/nvme_hmac_alg.2 | 30 + doc/man/nvme_host_behavior_support.2 | 11 + doc/man/nvme_host_get_dhchap_key.2 | 11 + doc/man/nvme_host_get_hostid.2 | 11 + doc/man/nvme_host_get_hostnqn.2 | 11 + doc/man/nvme_host_get_root.2 | 11 + doc/man/nvme_host_mem_buf_attrs.2 | 26 + doc/man/nvme_host_metadata.2 | 33 + doc/man/nvme_host_set_dhchap_key.2 | 12 + .../{struct nvme_id_ctrl.2 => nvme_id_ctrl.2} | 91 +- ...id_ctrl_anacap.2 => nvme_id_ctrl_anacap.2} | 2 +- ...e_id_ctrl_apsta.2 => nvme_id_ctrl_apsta.2} | 2 +- ...e_id_ctrl_avscc.2 => nvme_id_ctrl_avscc.2} | 2 +- doc/man/nvme_id_ctrl_cmic.2 | 43 + ...l_cntrltype.2 => nvme_id_ctrl_cntrltype.2} | 10 +- doc/man/nvme_id_ctrl_cqes.2 | 20 + doc/man/nvme_id_ctrl_ctratt.2 | 104 + ...vme_id_ctrl_dsto.2 => nvme_id_ctrl_dsto.2} | 2 +- ...e_id_ctrl_fcatt.2 => nvme_id_ctrl_fcatt.2} | 2 +- ... nvme_id_ctrl_fna.2 => nvme_id_ctrl_fna.2} | 2 +- ...vme_id_ctrl_frmw.2 => nvme_id_ctrl_frmw.2} | 2 +- ...e_id_ctrl_fuses.2 => nvme_id_ctrl_fuses.2} | 2 +- ...vme_id_ctrl_hctm.2 => nvme_id_ctrl_hctm.2} | 2 +- ... nvme_id_ctrl_lpa.2 => nvme_id_ctrl_lpa.2} | 7 +- ... nvme_id_ctrl_mec.2 => nvme_id_ctrl_mec.2} | 2 +- doc/man/nvme_id_ctrl_nvm.2 | 32 + ...e_id_ctrl_nvmsr.2 => nvme_id_ctrl_nvmsr.2} | 2 +- ...e_id_ctrl_nvscc.2 => nvme_id_ctrl_nvscc.2} | 2 +- ...vme_id_ctrl_nwpc.2 => nvme_id_ctrl_nwpc.2} | 2 +- ...vme_id_ctrl_oacs.2 => nvme_id_ctrl_oacs.2} | 2 +- doc/man/nvme_id_ctrl_oaes.2 | 62 + ...vme_id_ctrl_ofcs.2 => nvme_id_ctrl_ofcs.2} | 2 +- ...vme_id_ctrl_oncs.2 => nvme_id_ctrl_oncs.2} | 2 +- ...e_id_ctrl_rpmbs.2 => nvme_id_ctrl_rpmbs.2} | 2 +- ..._ctrl_sanicap.2 => nvme_id_ctrl_sanicap.2} | 2 +- ...vme_id_ctrl_sgls.2 => nvme_id_ctrl_sgls.2} | 10 +- ...vme_id_ctrl_sqes.2 => nvme_id_ctrl_sqes.2} | 2 +- ... nvme_id_ctrl_vwc.2 => nvme_id_ctrl_vwc.2} | 2 +- ...vme_id_ctrl_vwci.2 => nvme_id_ctrl_vwci.2} | 2 +- ...e_id_directives.2 => nvme_id_directives.2} | 5 +- doc/man/nvme_id_domain_attr.2 | 29 + doc/man/nvme_id_domain_list.2 | 23 + doc/man/nvme_id_endurance_group_list.2 | 17 + doc/man/nvme_id_independent_id_ns.2 | 44 + doc/man/nvme_id_iocs.2 | 15 + doc/man/{struct nvme_id_ns.2 => nvme_id_ns.2} | 50 +- ...um nvme_id_ns_attr.2 => nvme_id_ns_attr.2} | 2 +- ...vme_id_ns_dlfeat.2 => nvme_id_ns_dlfeat.2} | 2 +- ...enum nvme_id_ns_dpc.2 => nvme_id_ns_dpc.2} | 2 +- ...enum nvme_id_ns_dps.2 => nvme_id_ns_dps.2} | 2 +- ... nvme_id_ns_flbas.2 => nvme_id_ns_flbas.2} | 17 +- doc/man/nvme_id_ns_granularity_desc.2 | 17 + ...y_list.2 => nvme_id_ns_granularity_list.2} | 9 +- .../{enum nvme_id_ns_mc.2 => nvme_id_ns_mc.2} | 2 +- ...um nvme_id_ns_nmic.2 => nvme_id_ns_nmic.2} | 2 +- ...vme_id_ns_rescap.2 => nvme_id_ns_rescap.2} | 2 +- ...enum nvme_id_nsfeat.2 => nvme_id_nsfeat.2} | 15 +- ...id_nvmset_list.2 => nvme_id_nvmset_list.2} | 10 +- .../{struct nvme_id_psd.2 => nvme_id_psd.2} | 14 +- doc/man/nvme_id_uuid.2 | 26 + ...vme_id_uuid_list.2 => nvme_id_uuid_list.2} | 4 +- ...list_entry.2 => nvme_id_uuid_list_entry.2} | 5 +- doc/man/nvme_identify.2 | 30 +- doc/man/nvme_identify_active_ns_list.2 | 14 +- doc/man/nvme_identify_active_ns_list_csi.2 | 28 + doc/man/nvme_identify_allocated_ns.2 | 12 +- doc/man/nvme_identify_allocated_ns_list.2 | 14 +- doc/man/nvme_identify_allocated_ns_list_csi.2 | 28 + doc/man/nvme_identify_args.2 | 55 + ...vme_identify_cns.2 => nvme_identify_cns.2} | 66 +- doc/man/nvme_identify_ctrl.2 | 13 +- doc/man/nvme_identify_ctrl_csi.2 | 18 + doc/man/nvme_identify_ctrl_list.2 | 18 +- doc/man/nvme_identify_domain_list.2 | 25 + doc/man/nvme_identify_endurance_group_list.2 | 18 + .../nvme_identify_independent_identify_ns.2 | 19 + doc/man/nvme_identify_iocs.2 | 21 + ...me_identify_iocs_ns_csi_user_data_format.2 | 28 + doc/man/nvme_identify_ns.2 | 12 +- doc/man/nvme_identify_ns_csi.2 | 24 + .../nvme_identify_ns_csi_user_data_format.2 | 27 + doc/man/nvme_identify_ns_descs.2 | 12 +- doc/man/nvme_identify_ns_granularity.2 | 14 +- doc/man/nvme_identify_nsid_ctrl_list.2 | 19 +- doc/man/nvme_identify_nvmset_list.2 | 18 +- doc/man/nvme_identify_primary_ctrl.2 | 19 +- doc/man/nvme_identify_secondary_ctrl_list.2 | 19 +- doc/man/nvme_identify_uuid.2 | 14 +- doc/man/nvme_init_copy_range.2 | 27 + doc/man/nvme_init_ctrl.2 | 17 + doc/man/nvme_init_ctrl_list.2 | 18 + doc/man/nvme_init_dsm_range.2 | 27 + doc/man/nvme_init_id_ns.2 | 33 + doc/man/nvme_init_logging.2 | 20 + doc/man/nvme_io.2 | 15 + doc/man/nvme_io_args.2 | 91 + ...ontrol_flags.2 => nvme_io_control_flags.2} | 15 +- ...vme_io_dsm_flags.2 => nvme_io_dsm_flags.2} | 17 +- ...enum nvme_io_opcode.2 => nvme_io_opcode.2} | 34 +- doc/man/nvme_io_passthru.2 | 44 +- doc/man/nvme_io_passthru64.2 | 71 - ...lba_range_type.2 => nvme_lba_range_type.2} | 3 +- ...pe_entry.2 => nvme_lba_range_type_entry.2} | 9 +- .../{struct nvme_lba_rd.2 => nvme_lba_rd.2} | 5 +- ...ct nvme_lba_status.2 => nvme_lba_status.2} | 6 +- ...status_atype.2 => nvme_lba_status_atype.2} | 4 +- ...a_status_desc.2 => nvme_lba_status_desc.2} | 7 +- ...lba_status_log.2 => nvme_lba_status_log.2} | 8 +- doc/man/{struct nvme_lbaf.2 => nvme_lbaf.2} | 2 +- .../{enum nvme_lbaf_rp.2 => nvme_lbaf_rp.2} | 2 +- doc/man/nvme_lbart.2 | 41 + ...as_ns_element.2 => nvme_lbas_ns_element.2} | 9 +- doc/man/nvme_lockdown.2 | 12 + doc/man/nvme_lockdown_args.2 | 47 + doc/man/nvme_log_ana_lsp.2 | 16 + doc/man/nvme_lookup_ctrl.2 | 35 + doc/man/nvme_lookup_host.2 | 20 + doc/man/nvme_lookup_subsystem.2 | 20 + doc/man/nvme_media_unit_config_desc.2 | 24 + doc/man/nvme_media_unit_stat_desc.2 | 47 + doc/man/nvme_media_unit_stat_log.2 | 31 + doc/man/nvme_metadata_element_desc.2 | 27 + doc/man/nvme_mi_css.2 | 66 + doc/man/nvme_mi_csts.2 | 41 + doc/man/nvme_mi_ctrl_health_status.2 | 32 + doc/man/nvme_mi_cwarn.2 | 31 + doc/man/nvme_mi_elem.2 | 41 + ...tatus.2 => nvme_mi_nvm_ss_health_status.2} | 8 +- .../{struct nvme_mi_osc.2 => nvme_mi_osc.2} | 6 +- ...vme_mi_port_pcie.2 => nvme_mi_port_pcie.2} | 9 +- ... nvme_mi_port_smb.2 => nvme_mi_port_smb.2} | 8 +- ...d_ctrl_info.2 => nvme_mi_read_ctrl_info.2} | 13 +- ...m_ss_info.2 => nvme_mi_read_nvm_ss_info.2} | 6 +- ...d_port_info.2 => nvme_mi_read_port_info.2} | 8 +- ..._read_sc_list.2 => nvme_mi_read_sc_list.2} | 4 +- ...ct nvme_mi_vpd_hdr.2 => nvme_mi_vpd_hdr.2} | 11 +- ...pd_mr_common.2 => nvme_mi_vpd_mr_common.2} | 12 +- ...ct nvme_mi_vpd_mra.2 => nvme_mi_vpd_mra.2} | 20 +- ...vme_mi_vpd_ppmra.2 => nvme_mi_vpd_ppmra.2} | 11 +- ...vme_mi_vpd_telem.2 => nvme_mi_vpd_telem.2} | 6 +- ...ct nvme_mi_vpd_tra.2 => nvme_mi_vpd_tra.2} | 6 +- doc/man/nvme_namespace_attach_ctrls.2 | 14 +- doc/man/nvme_namespace_detach_ctrls.2 | 14 +- doc/man/nvme_namespace_filter.2 | 4 +- ...enum nvme_nd_ns_fpi.2 => nvme_nd_ns_fpi.2} | 2 +- doc/man/nvme_next_host.2 | 14 + doc/man/nvme_next_subsystem.2 | 15 +- doc/man/nvme_ns_attach.2 | 17 +- doc/man/nvme_ns_attach_args.2 | 39 + doc/man/nvme_ns_attach_ctrls.2 | 8 +- ...e_ns_attach_sel.2 => nvme_ns_attach_sel.2} | 6 +- doc/man/nvme_ns_compare.2 | 21 +- doc/man/nvme_ns_detach_ctrls.2 | 15 + doc/man/nvme_ns_dettach_ctrls.2 | 15 - doc/man/nvme_ns_flush.2 | 9 +- doc/man/nvme_ns_get_csi.2 | 11 + doc/man/nvme_ns_get_ctrl.2 | 11 +- doc/man/nvme_ns_get_fd.2 | 9 +- doc/man/nvme_ns_get_firmware.2 | 11 + doc/man/nvme_ns_get_generic_name.2 | 11 + doc/man/nvme_ns_get_lba_count.2 | 9 +- doc/man/nvme_ns_get_lba_size.2 | 9 +- doc/man/nvme_ns_get_lba_util.2 | 9 +- doc/man/nvme_ns_get_meta_size.2 | 11 + doc/man/nvme_ns_get_model.2 | 11 + doc/man/nvme_ns_get_name.2 | 9 +- doc/man/nvme_ns_get_nguid.2 | 11 + doc/man/nvme_ns_get_nsid.2 | 9 +- doc/man/nvme_ns_get_serial.2 | 11 + doc/man/nvme_ns_get_subsystem.2 | 9 +- doc/man/nvme_ns_get_sysfs_dir.2 | 9 +- doc/man/nvme_ns_get_uuid.2 | 14 + ...ct nvme_ns_id_desc.2 => nvme_ns_id_desc.2} | 6 +- ..._id_desc_nidt.2 => nvme_ns_id_desc_nidt.2} | 8 +- doc/man/nvme_ns_identify.2 | 16 +- doc/man/nvme_ns_identify_descs.2 | 17 + .../{struct nvme_ns_list.2 => nvme_ns_list.2} | 3 +- doc/man/nvme_ns_metadata_type.2 | 34 + doc/man/nvme_ns_mgmt.2 | 25 +- doc/man/nvme_ns_mgmt_args.2 | 43 + doc/man/nvme_ns_mgmt_create.2 | 19 +- doc/man/nvme_ns_mgmt_delete.2 | 10 +- ... nvme_ns_mgmt_sel.2 => nvme_ns_mgmt_sel.2} | 4 +- doc/man/nvme_ns_read.2 | 21 +- doc/man/nvme_ns_rescan.2 | 6 +- doc/man/nvme_ns_verify.2 | 17 +- doc/man/nvme_ns_write.2 | 21 +- doc/man/nvme_ns_write_protect_cfg.2 | 26 + doc/man/nvme_ns_write_uncorrectable.2 | 17 +- doc/man/nvme_ns_write_zeros.2 | 17 +- doc/man/nvme_nss_hw_err_event.2 | 20 + doc/man/nvme_nvm_id_ns.2 | 31 + doc/man/nvme_nvm_identify_ctrl.2 | 15 + doc/man/nvme_nvmeset_pl_status.2 | 21 + doc/man/nvme_nvmset_attr.2 | 46 + doc/man/nvme_nvmset_pl_events.2 | 31 + ...og.2 => nvme_nvmset_predictable_lat_log.2} | 20 +- doc/man/nvme_open.2 | 4 +- ...vme_passthru_cmd.2 => nvme_passthru_cmd.2} | 2 +- doc/man/nvme_path_get_ana_state.2 | 9 +- doc/man/nvme_path_get_ctrl.2 | 11 + doc/man/nvme_path_get_name.2 | 9 +- doc/man/nvme_path_get_ns.2 | 9 +- doc/man/nvme_path_get_sysfs_dir.2 | 9 +- doc/man/nvme_paths_filter.2 | 4 +- doc/man/nvme_persistent_event_entry.2 | 38 + doc/man/nvme_persistent_event_log.2 | 68 + doc/man/nvme_persistent_event_types.2 | 71 + doc/man/nvme_pevent_log_action.2 | 21 + ...ct nvme_plm_config.2 => nvme_plm_config.2} | 10 +- doc/man/nvme_pmr_size.2 | 11 + doc/man/nvme_pmr_throughput.2 | 11 + doc/man/nvme_power_on_reset_info_list.2 | 32 + ...ary_ctrl_cap.2 => nvme_primary_ctrl_cap.2} | 20 +- ...enum nvme_psd_flags.2 => nvme_psd_flags.2} | 2 +- doc/man/nvme_psd_power_scale.2 | 8 +- doc/man/nvme_psd_ps.2 | 18 + ...vme_psd_workload.2 => nvme_psd_workload.2} | 2 +- doc/man/nvme_read.2 | 55 +- doc/man/nvme_read_config.2 | 17 + doc/man/nvme_refresh_topology.2 | 10 +- ...me_registers.2 => nvme_register_offsets.2} | 18 +- ...gistered_ctrl.2 => nvme_registered_ctrl.2} | 7 +- ..._ctrl_ext.2 => nvme_registered_ctrl_ext.2} | 12 +- doc/man/nvme_rescan_ctrl.2 | 9 + doc/man/nvme_resv_acquire.2 | 37 +- doc/man/nvme_resv_acquire_args.2 | 52 + ..._reservation_cptpl.2 => nvme_resv_cptpl.2} | 9 +- ...ion_log.2 => nvme_resv_notification_log.2} | 9 +- doc/man/nvme_resv_notify_rnlpt.2 | 26 + ..._reservation_racqa.2 => nvme_resv_racqa.2} | 9 +- doc/man/nvme_resv_register.2 | 35 +- doc/man/nvme_resv_register_args.2 | 52 + doc/man/nvme_resv_release.2 | 27 +- doc/man/nvme_resv_release_args.2 | 47 + doc/man/nvme_resv_report.2 | 24 +- doc/man/nvme_resv_report_args.2 | 44 + ..._reservation_rrega.2 => nvme_resv_rrega.2} | 9 +- ..._reservation_rrela.2 => nvme_resv_rrela.2} | 8 +- ..._reservation_rtype.2 => nvme_resv_rtype.2} | 12 +- ...eservation_status.2 => nvme_resv_status.2} | 17 +- doc/man/nvme_sanitize_compln_event.2 | 23 + doc/man/nvme_sanitize_log_page.2 | 106 + doc/man/nvme_sanitize_nvm.2 | 40 +- doc/man/nvme_sanitize_nvm_args.2 | 51 + ...nitize_sanact.2 => nvme_sanitize_sanact.2} | 12 +- doc/man/nvme_sanitize_sstat.2 | 105 + doc/man/nvme_sanitize_start_event.2 | 20 + doc/man/nvme_scan.2 | 9 +- doc/man/nvme_scan_ctrl.2 | 14 +- doc/man/nvme_scan_ctrl_namespace_paths.2 | 7 +- doc/man/nvme_scan_ctrl_namespaces.2 | 7 +- doc/man/nvme_scan_ctrls.2 | 8 + doc/man/nvme_scan_namespace.2 | 11 + doc/man/nvme_scan_subsystem_namespaces.2 | 7 +- doc/man/nvme_scan_subsystems.2 | 4 +- doc/man/nvme_scan_topology.2 | 17 + ...secondary_ctrl.2 => nvme_secondary_ctrl.2} | 10 +- ...ctrl_list.2 => nvme_secondary_ctrl_list.2} | 7 +- doc/man/nvme_security_receive.2 | 39 +- doc/man/nvme_security_receive_args.2 | 59 + doc/man/nvme_security_send.2 | 41 +- doc/man/nvme_security_send_args.2 | 59 + doc/man/nvme_self_test_log.2 | 43 + doc/man/nvme_set_attr.2 | 16 - doc/man/nvme_set_feature_event.2 | 17 + doc/man/nvme_set_features.2 | 42 +- doc/man/nvme_set_features_arbitration.2 | 24 +- doc/man/nvme_set_features_args.2 | 63 + doc/man/nvme_set_features_async_event.2 | 16 +- doc/man/nvme_set_features_auto_pst.2 | 18 +- doc/man/nvme_set_features_data.2 | 30 + doc/man/nvme_set_features_endurance_evt_cfg.2 | 17 +- doc/man/nvme_set_features_err_recovery.2 | 23 +- doc/man/nvme_set_features_hctm.2 | 18 +- doc/man/nvme_set_features_host_behavior.2 | 13 +- doc/man/nvme_set_features_host_id.2 | 17 +- doc/man/nvme_set_features_irq_coalesce.2 | 18 +- doc/man/nvme_set_features_irq_config.2 | 18 +- doc/man/nvme_set_features_lba_range.2 | 24 +- doc/man/nvme_set_features_lba_sts_interval.2 | 18 +- doc/man/nvme_set_features_nopsc.2 | 20 +- doc/man/nvme_set_features_plm_config.2 | 21 +- doc/man/nvme_set_features_plm_window.2 | 18 +- doc/man/nvme_set_features_power_mgmt.2 | 18 +- doc/man/nvme_set_features_resv_mask.2 | 15 +- doc/man/nvme_set_features_resv_persist.2 | 15 +- doc/man/nvme_set_features_rrl.2 | 20 +- doc/man/nvme_set_features_sanitize.2 | 15 +- doc/man/nvme_set_features_simple.2 | 24 + doc/man/nvme_set_features_sw_progress.2 | 15 +- doc/man/nvme_set_features_temp_thresh.2 | 21 +- doc/man/nvme_set_features_timestamp.2 | 12 +- doc/man/nvme_set_features_volatile_wc.2 | 16 +- doc/man/nvme_set_features_write_atomic.2 | 15 +- doc/man/nvme_set_features_write_protect.2 | 15 +- doc/man/nvme_set_property.2 | 18 +- doc/man/nvme_set_property_args.2 | 35 + doc/man/nvme_setup_ctrl_list.2 | 15 - doc/man/nvme_setup_dsm_range.2 | 26 - doc/man/nvme_setup_id_ns.2 | 30 - doc/man/nvme_smart_crit.2 | 54 + doc/man/nvme_smart_egcw.2 | 31 + doc/man/nvme_smart_log.2 | 235 + doc/man/nvme_st_code.2 | 37 + doc/man/nvme_st_curr_op.2 | 50 + doc/man/nvme_st_result.2 | 77 + doc/man/nvme_st_valid_diag_info.2 | 34 + doc/man/nvme_status_code.2 | 11 + doc/man/nvme_status_code_type.2 | 11 + doc/man/nvme_status_field.2 | 1088 + doc/man/nvme_status_result.2 | 87 + doc/man/nvme_status_to_errno.2 | 13 +- doc/man/nvme_status_to_string.2 | 15 + ...rams.2 => nvme_streams_directive_params.2} | 12 +- ...atus.2 => nvme_streams_directive_status.2} | 4 +- doc/man/nvme_submit_admin_passthru.2 | 12 +- doc/man/nvme_submit_admin_passthru64.2 | 20 - doc/man/nvme_submit_io_passthru.2 | 12 +- doc/man/nvme_submit_io_passthru64.2 | 20 - doc/man/nvme_subsys_filter.2 | 4 +- doc/man/nvme_subsys_type.2 | 37 + doc/man/nvme_subsystem_first_ctrl.2 | 9 +- doc/man/nvme_subsystem_first_ns.2 | 9 +- doc/man/nvme_subsystem_for_each_ctrl.2 | 12 +- doc/man/nvme_subsystem_for_each_ctrl_safe.2 | 16 +- doc/man/nvme_subsystem_for_each_ns.2 | 12 +- doc/man/nvme_subsystem_for_each_ns_safe.2 | 16 +- doc/man/nvme_subsystem_get_host.2 | 11 + doc/man/nvme_subsystem_get_name.2 | 9 +- doc/man/nvme_subsystem_get_nqn.2 | 4 +- doc/man/nvme_subsystem_get_sysfs_dir.2 | 9 +- doc/man/nvme_subsystem_get_type.2 | 13 + doc/man/nvme_subsystem_lookup_namespace.2 | 14 + doc/man/nvme_subsystem_next_ctrl.2 | 13 +- doc/man/nvme_subsystem_next_ns.2 | 13 +- doc/man/nvme_subsystem_reset.2 | 4 +- doc/man/nvme_supported_cap_config_list_log.2 | 22 + doc/man/nvme_supported_log_pages.2 | 16 + doc/man/nvme_telemetry_log.2 | 82 + doc/man/nvme_thermal_exc_event.2 | 17 + doc/man/nvme_time_stamp_change_event.2 | 17 + ...ruct nvme_timestamp.2 => nvme_timestamp.2} | 7 +- doc/man/nvme_unlink_ctrl.2 | 5 +- doc/man/nvme_update_config.2 | 13 + doc/man/nvme_verify.2 | 39 +- ...e_virt_mgmt_act.2 => nvme_virt_mgmt_act.2} | 6 +- ...vme_virt_mgmt_rt.2 => nvme_virt_mgmt_rt.2} | 4 +- doc/man/nvme_virtual_mgmt.2 | 27 +- doc/man/nvme_virtual_mgmt_args.2 | 43 + doc/man/nvme_write.2 | 58 +- doc/man/nvme_write_uncorrectable.2 | 30 +- doc/man/nvme_write_zeros.2 | 47 +- doc/man/nvme_zns_append.2 | 12 + doc/man/nvme_zns_append_args.2 | 70 + doc/man/nvme_zns_changed_zone_log.2 | 20 + doc/man/nvme_zns_desc.2 | 38 + doc/man/nvme_zns_id_ctrl.2 | 18 + doc/man/nvme_zns_id_ns.2 | 87 + doc/man/nvme_zns_identify_ctrl.2 | 15 + doc/man/nvme_zns_identify_ns.2 | 18 + doc/man/nvme_zns_lbafe.2 | 20 + doc/man/nvme_zns_mgmt_recv.2 | 12 + doc/man/nvme_zns_mgmt_recv_args.2 | 55 + doc/man/nvme_zns_mgmt_send.2 | 12 + doc/man/nvme_zns_mgmt_send_args.2 | 55 + doc/man/nvme_zns_recv_action.2 | 16 + doc/man/nvme_zns_report_options.2 | 46 + doc/man/nvme_zns_report_zones.2 | 39 + doc/man/nvme_zns_send_action.2 | 41 + doc/man/nvme_zns_za.2 | 31 + doc/man/nvme_zns_zs.2 | 41 + doc/man/nvme_zns_zt.2 | 11 + doc/man/nvme_zone_report.2 | 23 + doc/man/nvmf_add_ctrl.2 | 22 +- doc/man/nvmf_addr_family.2 | 43 + doc/man/nvmf_adrfam_str.2 | 13 +- doc/man/nvmf_cms_str.2 | 15 +- doc/man/nvmf_connect_data.2 | 35 + doc/man/nvmf_connect_disc_entry.2 | 21 +- doc/man/nvmf_default_config.2 | 11 + doc/man/nvmf_disc_eflags.2 | 39 + doc/man/nvmf_disc_log_entry.2 | 122 + doc/man/nvmf_discovery_log.2 | 38 + doc/man/nvmf_eflags_str.2 | 14 + doc/man/nvmf_get_discovery_log.2 | 18 +- doc/man/nvmf_hostid_from_file.2 | 7 +- doc/man/nvmf_hostnqn_from_file.2 | 7 +- doc/man/nvmf_hostnqn_generate.2 | 7 +- doc/man/nvmf_prtype_str.2 | 13 +- doc/man/nvmf_qptype_str.2 | 13 +- doc/man/nvmf_rdma_cms.2 | 12 + doc/man/nvmf_rdma_prtype.2 | 36 + doc/man/nvmf_rdma_qptype.2 | 18 + doc/man/nvmf_sectype_str.2 | 13 +- doc/man/nvmf_subtype_str.2 | 13 +- doc/man/nvmf_tcp_sectype.2 | 26 + doc/man/nvmf_treq.2 | 30 + doc/man/nvmf_treq_str.2 | 13 +- doc/man/nvmf_trtype.2 | 43 + doc/man/nvmf_trtype_str.2 | 13 +- doc/man/struct nvme_error_log_page.2 | 37 - doc/man/struct nvme_fabrics_config.2 | 51 - doc/man/struct nvme_firmware_slot.2 | 19 - doc/man/struct nvme_frs.2 | 13 - doc/man/struct nvme_id_ns_granularity_desc.2 | 15 - doc/man/struct nvme_mi_ctrl_heal_status.2 | 25 - doc/man/struct nvme_nvmset_attr.2 | 37 - doc/man/struct nvme_passthru_cmd64.2 | 87 - doc/man/struct nvme_persistent_event_log.2 | 43 - doc/man/struct nvme_sanitize_log_page.2 | 31 - doc/man/struct nvme_self_test_log.2 | 19 - doc/man/struct nvme_smart_log.2 | 61 - doc/man/struct nvme_st_result.2 | 31 - doc/man/struct nvme_telemetry_log.2 | 33 - doc/man/struct nvmf_connect_data.2 | 26 - doc/man/struct nvmf_disc_log_entry.2 | 63 - doc/man/struct nvmf_discovery_log.2 | 21 - 710 files changed, 64399 insertions(+), 4508 deletions(-) create mode 100644 doc/html/.buildinfo create mode 100644 doc/html/.doctrees/environment.pickle create mode 100644 doc/html/.doctrees/libnvme.doctree create mode 100644 doc/html/_sources/libnvme.rst.txt create mode 100644 doc/html/_static/basic.css create mode 100644 doc/html/_static/css/badge_only.css create mode 100644 doc/html/_static/css/fonts/Roboto-Slab-Bold.woff create mode 100644 doc/html/_static/css/fonts/Roboto-Slab-Bold.woff2 create mode 100644 doc/html/_static/css/fonts/Roboto-Slab-Regular.woff create mode 100644 doc/html/_static/css/fonts/Roboto-Slab-Regular.woff2 create mode 100644 doc/html/_static/css/fonts/fontawesome-webfont.eot create mode 100644 doc/html/_static/css/fonts/fontawesome-webfont.svg create mode 100644 doc/html/_static/css/fonts/fontawesome-webfont.ttf create mode 100644 doc/html/_static/css/fonts/fontawesome-webfont.woff create mode 100644 doc/html/_static/css/fonts/fontawesome-webfont.woff2 create mode 100644 doc/html/_static/css/fonts/lato-bold-italic.woff create mode 100644 doc/html/_static/css/fonts/lato-bold-italic.woff2 create mode 100644 doc/html/_static/css/fonts/lato-bold.woff create mode 100644 doc/html/_static/css/fonts/lato-bold.woff2 create mode 100644 doc/html/_static/css/fonts/lato-normal-italic.woff create mode 100644 doc/html/_static/css/fonts/lato-normal-italic.woff2 create mode 100644 doc/html/_static/css/fonts/lato-normal.woff create mode 100644 doc/html/_static/css/fonts/lato-normal.woff2 create mode 100644 doc/html/_static/css/theme.css create mode 100644 doc/html/_static/doctools.js create mode 100644 doc/html/_static/documentation_options.js create mode 100644 doc/html/_static/file.png create mode 100644 doc/html/_static/jquery-3.5.1.js create mode 100644 doc/html/_static/jquery.js create mode 100644 doc/html/_static/js/badge_only.js create mode 100644 doc/html/_static/js/html5shiv-printshiv.min.js create mode 100644 doc/html/_static/js/html5shiv.min.js create mode 100644 doc/html/_static/js/theme.js create mode 100644 doc/html/_static/language_data.js create mode 100644 doc/html/_static/minus.png create mode 100644 doc/html/_static/plus.png create mode 100644 doc/html/_static/pygments.css create mode 100644 doc/html/_static/searchtools.js create mode 100644 doc/html/_static/underscore-1.13.1.js create mode 100644 doc/html/_static/underscore.js create mode 100644 doc/html/genindex.html create mode 100644 doc/html/libnvme.html create mode 100644 doc/html/objects.inv create mode 100644 doc/html/search.html create mode 100644 doc/html/searchindex.js delete mode 100644 doc/man/__nvme_get_log_page.2 delete mode 100644 doc/man/enum .2 delete mode 100644 doc/man/enum nvme_cmd_format_mset.2 delete mode 100644 doc/man/enum nvme_cmd_format_ses.2 delete mode 100644 doc/man/enum nvme_feat_tmpthresh_thsel.2 delete mode 100644 doc/man/enum nvme_id_ctrl_cmic.2 delete mode 100644 doc/man/enum nvme_id_ctrl_ctratt.2 delete mode 100644 doc/man/enum nvme_id_ctrl_oaes.2 delete mode 100644 doc/man/enum nvme_psd_ps.2 delete mode 100644 doc/man/enum nvme_subsys_type.2 delete mode 100644 doc/man/is_64bit_reg.2 delete mode 100644 doc/man/libnvme.2 rename doc/man/{enum nvme_admin_opcode.2 => nvme_admin_opcode.2} (79%) delete mode 100644 doc/man/nvme_admin_passthru64.2 rename doc/man/{enum nvme_ae_info_css_nvm.2 => nvme_ae_info_css_nvm.2} (73%) rename doc/man/{enum nvme_ae_info_error.2 => nvme_ae_info_error.2} (77%) rename doc/man/{enum nvme_ae_info_notice.2 => nvme_ae_info_notice.2} (76%) rename doc/man/{enum nvme_ae_info_smart.2 => nvme_ae_info_smart.2} (73%) rename doc/man/{enum nvme_ae_type.2 => nvme_ae_type.2} (68%) rename doc/man/{struct nvme_aggregate_endurance_group_event.2 => nvme_aggregate_endurance_group_event.2} (55%) rename doc/man/{struct nvme_aggregate_predictable_lat_event.2 => nvme_aggregate_predictable_lat_event.2} (56%) rename doc/man/{struct nvme_ana_group_desc.2 => nvme_ana_group_desc.2} (50%) rename doc/man/{struct nvme_ana_log.2 => nvme_ana_log.2} (63%) create mode 100644 doc/man/nvme_ana_state.2 create mode 100644 doc/man/nvme_apst_entry.2 create mode 100644 doc/man/nvme_boot_partition.2 create mode 100644 doc/man/nvme_cap_config_desc.2 create mode 100644 doc/man/nvme_capacity_mgmt.2 create mode 100644 doc/man/nvme_capacity_mgmt_args.2 create mode 100644 doc/man/nvme_change_ns_event.2 create mode 100644 doc/man/nvme_channel_config_desc.2 create mode 100644 doc/man/nvme_chomp.2 create mode 100644 doc/man/nvme_cmb_size.2 create mode 100644 doc/man/nvme_cmd_effects.2 rename doc/man/{struct nvme_cmd_effects_log.2 => nvme_cmd_effects_log.2} (54%) create mode 100644 doc/man/nvme_cmd_format_mset.2 rename doc/man/{enum nvme_cmd_format_pi.2 => nvme_cmd_format_pi.2} (53%) create mode 100644 doc/man/nvme_cmd_format_pil.2 create mode 100644 doc/man/nvme_cmd_format_ses.2 rename doc/man/{enum nvme_cmd_get_log_lid.2 => nvme_cmd_get_log_lid.2} (74%) create mode 100644 doc/man/nvme_cmd_get_log_telemetry_host_lsp.2 create mode 100644 doc/man/nvme_connect_err.2 rename doc/man/{enum nvme_constants.2 => nvme_constants.2} (53%) create mode 100644 doc/man/nvme_copy.2 create mode 100644 doc/man/nvme_copy_args.2 create mode 100644 doc/man/nvme_copy_range.2 create mode 100644 doc/man/nvme_create_ctrl.2 create mode 100644 doc/man/nvme_create_root.2 create mode 100644 doc/man/nvme_csi.2 delete mode 100644 doc/man/nvme_ctrl_disconnect.2 create mode 100644 doc/man/nvme_ctrl_get_config.2 create mode 100644 doc/man/nvme_ctrl_get_dhchap_key.2 create mode 100644 doc/man/nvme_ctrl_get_host_iface.2 create mode 100644 doc/man/nvme_ctrl_get_host_traddr.2 create mode 100644 doc/man/nvme_ctrl_get_traddr.2 create mode 100644 doc/man/nvme_ctrl_get_trsvcid.2 create mode 100644 doc/man/nvme_ctrl_is_discovered.2 create mode 100644 doc/man/nvme_ctrl_is_discovery_ctrl.2 create mode 100644 doc/man/nvme_ctrl_is_persistent.2 rename doc/man/{struct nvme_ctrl_list.2 => nvme_ctrl_list.2} (54%) create mode 100644 doc/man/nvme_ctrl_metadata_type.2 create mode 100644 doc/man/nvme_ctrl_set_dhchap_key.2 create mode 100644 doc/man/nvme_ctrl_set_discovered.2 create mode 100644 doc/man/nvme_ctrl_set_discovery_ctrl.2 create mode 100644 doc/man/nvme_ctrl_set_persistent.2 create mode 100644 doc/man/nvme_default_host.2 create mode 100644 doc/man/nvme_dev_self_test_args.2 rename doc/man/{enum nvme_directive_dtype.2 => nvme_directive_dtype.2} (68%) rename doc/man/{enum nvme_directive_receive_doper.2 => nvme_directive_receive_doper.2} (77%) create mode 100644 doc/man/nvme_directive_recv_args.2 create mode 100644 doc/man/nvme_directive_send_args.2 rename doc/man/{enum nvme_directive_send_doper.2 => nvme_directive_send_doper.2} (76%) rename doc/man/{enum nvme_directive_send_identify_endir.2 => nvme_directive_send_identify_endir.2} (71%) create mode 100644 doc/man/nvme_directive_types.2 create mode 100644 doc/man/nvme_disconnect_ctrl.2 create mode 100644 doc/man/nvme_dsm_args.2 rename doc/man/{enum nvme_dsm_attributes.2 => nvme_dsm_attributes.2} (66%) rename doc/man/{struct nvme_dsm_range.2 => nvme_dsm_range.2} (61%) rename doc/man/{enum nvme_dst_stc.2 => nvme_dst_stc.2} (50%) create mode 100644 doc/man/nvme_dump_config.2 rename doc/man/{enum nvme_eg_critical_warning_flags.2 => nvme_eg_critical_warning_flags.2} (72%) rename doc/man/{struct nvme_eg_event_aggregate_log.2 => nvme_eg_event_aggregate_log.2} (60%) create mode 100644 doc/man/nvme_end_grp_chan_desc.2 create mode 100644 doc/man/nvme_end_grp_config_desc.2 rename doc/man/{struct nvme_endurance_group_log.2 => nvme_endurance_group_log.2} (60%) create mode 100644 doc/man/nvme_err_pel.2 create mode 100644 doc/man/nvme_errno_to_string.2 create mode 100644 doc/man/nvme_error_log_page.2 create mode 100644 doc/man/nvme_fabrics_config.2 rename doc/man/{enum nvme_fctype.2 => nvme_fctype.2} (76%) create mode 100644 doc/man/nvme_feat.2 rename doc/man/{struct nvme_feat_auto_pst.2 => nvme_feat_auto_pst.2} (53%) rename doc/man/{struct nvme_feat_host_behavior.2 => nvme_feat_host_behavior.2} (51%) rename doc/man/{enum nvme_feat_nswpcfg_state.2 => nvme_feat_nswpcfg_state.2} (74%) rename doc/man/{enum nvme_feat_plm_window_select.2 => nvme_feat_plm_window_select.2} (66%) create mode 100644 doc/man/nvme_feat_resv_notify_flags.2 create mode 100644 doc/man/nvme_feat_tmpthresh_thsel.2 rename doc/man/{enum nvme_features_async_event_config_flags.2 => nvme_features_async_event_config_flags.2} (82%) rename doc/man/{enum nvme_features_id.2 => nvme_features_id.2} (77%) create mode 100644 doc/man/nvme_fid_supported_effects.2 create mode 100644 doc/man/nvme_fid_supported_effects_log.2 create mode 100644 doc/man/nvme_firmware_slot.2 create mode 100644 doc/man/nvme_first_host.2 create mode 100644 doc/man/nvme_for_each_host.2 create mode 100644 doc/man/nvme_for_each_host_safe.2 create mode 100644 doc/man/nvme_format_nvm_args.2 create mode 100644 doc/man/nvme_format_nvm_compln_event.2 create mode 100644 doc/man/nvme_format_nvm_start_event.2 create mode 100644 doc/man/nvme_free_host.2 create mode 100644 doc/man/nvme_free_ns.2 create mode 100644 doc/man/nvme_free_subsystem.2 create mode 100644 doc/man/nvme_fw_commit_args.2 rename doc/man/{enum nvme_fw_commit_ca.2 => nvme_fw_commit_ca.2} (78%) create mode 100644 doc/man/nvme_fw_commit_event.2 create mode 100644 doc/man/nvme_fw_download_args.2 create mode 100644 doc/man/nvme_gen_dhchap_key.2 create mode 100644 doc/man/nvme_get_attr.2 create mode 100644 doc/man/nvme_get_features_args.2 create mode 100644 doc/man/nvme_get_features_data.2 create mode 100644 doc/man/nvme_get_features_iocs_profile.2 rename doc/man/{enum nvme_get_features_sel.2 => nvme_get_features_sel.2} (67%) create mode 100644 doc/man/nvme_get_features_simple.2 create mode 100644 doc/man/nvme_get_lba_status_args.2 create mode 100644 doc/man/nvme_get_lba_status_log.2 create mode 100644 doc/man/nvme_get_log_args.2 create mode 100644 doc/man/nvme_get_log_boot_partition.2 create mode 100644 doc/man/nvme_get_log_fid_supported_effects.2 create mode 100644 doc/man/nvme_get_log_media_unit_stat.2 create mode 100644 doc/man/nvme_get_log_page_padded.2 create mode 100644 doc/man/nvme_get_log_persistent_event.2 create mode 100644 doc/man/nvme_get_log_support_cap_config_list.2 create mode 100644 doc/man/nvme_get_log_supported_log_pages.2 create mode 100644 doc/man/nvme_get_log_zns_changed_zones.2 create mode 100644 doc/man/nvme_get_logical_block_size.2 create mode 100644 doc/man/nvme_get_property_args.2 create mode 100644 doc/man/nvme_hmac_alg.2 create mode 100644 doc/man/nvme_host_behavior_support.2 create mode 100644 doc/man/nvme_host_get_dhchap_key.2 create mode 100644 doc/man/nvme_host_get_hostid.2 create mode 100644 doc/man/nvme_host_get_hostnqn.2 create mode 100644 doc/man/nvme_host_get_root.2 create mode 100644 doc/man/nvme_host_mem_buf_attrs.2 create mode 100644 doc/man/nvme_host_metadata.2 create mode 100644 doc/man/nvme_host_set_dhchap_key.2 rename doc/man/{struct nvme_id_ctrl.2 => nvme_id_ctrl.2} (86%) rename doc/man/{enum nvme_id_ctrl_anacap.2 => nvme_id_ctrl_anacap.2} (94%) rename doc/man/{enum nvme_id_ctrl_apsta.2 => nvme_id_ctrl_apsta.2} (78%) rename doc/man/{enum nvme_id_ctrl_avscc.2 => nvme_id_ctrl_avscc.2} (80%) create mode 100644 doc/man/nvme_id_ctrl_cmic.2 rename doc/man/{enum nvme_id_ctrl_cntrltype.2 => nvme_id_ctrl_cntrltype.2} (62%) create mode 100644 doc/man/nvme_id_ctrl_cqes.2 create mode 100644 doc/man/nvme_id_ctrl_ctratt.2 rename doc/man/{enum nvme_id_ctrl_dsto.2 => nvme_id_ctrl_dsto.2} (82%) rename doc/man/{enum nvme_id_ctrl_fcatt.2 => nvme_id_ctrl_fcatt.2} (81%) rename doc/man/{enum nvme_id_ctrl_fna.2 => nvme_id_ctrl_fna.2} (92%) rename doc/man/{enum nvme_id_ctrl_frmw.2 => nvme_id_ctrl_frmw.2} (88%) rename doc/man/{enum nvme_id_ctrl_fuses.2 => nvme_id_ctrl_fuses.2} (79%) rename doc/man/{enum nvme_id_ctrl_hctm.2 => nvme_id_ctrl_hctm.2} (83%) rename doc/man/{enum nvme_id_ctrl_lpa.2 => nvme_id_ctrl_lpa.2} (77%) rename doc/man/{enum nvme_id_ctrl_mec.2 => nvme_id_ctrl_mec.2} (85%) create mode 100644 doc/man/nvme_id_ctrl_nvm.2 rename doc/man/{enum nvme_id_ctrl_nvmsr.2 => nvme_id_ctrl_nvmsr.2} (87%) rename doc/man/{enum nvme_id_ctrl_nvscc.2 => nvme_id_ctrl_nvscc.2} (79%) rename doc/man/{enum nvme_id_ctrl_nwpc.2 => nvme_id_ctrl_nwpc.2} (91%) rename doc/man/{enum nvme_id_ctrl_oacs.2 => nvme_id_ctrl_oacs.2} (95%) create mode 100644 doc/man/nvme_id_ctrl_oaes.2 rename doc/man/{enum nvme_id_ctrl_ofcs.2 => nvme_id_ctrl_ofcs.2} (79%) rename doc/man/{enum nvme_id_ctrl_oncs.2 => nvme_id_ctrl_oncs.2} (94%) rename doc/man/{enum nvme_id_ctrl_rpmbs.2 => nvme_id_ctrl_rpmbs.2} (89%) rename doc/man/{enum nvme_id_ctrl_sanicap.2 => nvme_id_ctrl_sanicap.2} (92%) rename doc/man/{enum nvme_id_ctrl_sgls.2 => nvme_id_ctrl_sgls.2} (78%) rename doc/man/{enum nvme_id_ctrl_sqes.2 => nvme_id_ctrl_sqes.2} (85%) rename doc/man/{enum nvme_id_ctrl_vwc.2 => nvme_id_ctrl_vwc.2} (86%) rename doc/man/{enum nvme_id_ctrl_vwci.2 => nvme_id_ctrl_vwci.2} (92%) rename doc/man/{struct nvme_id_directives.2 => nvme_id_directives.2} (61%) create mode 100644 doc/man/nvme_id_domain_attr.2 create mode 100644 doc/man/nvme_id_domain_list.2 create mode 100644 doc/man/nvme_id_endurance_group_list.2 create mode 100644 doc/man/nvme_id_independent_id_ns.2 create mode 100644 doc/man/nvme_id_iocs.2 rename doc/man/{struct nvme_id_ns.2 => nvme_id_ns.2} (81%) rename doc/man/{enum nvme_id_ns_attr.2 => nvme_id_ns_attr.2} (79%) rename doc/man/{enum nvme_id_ns_dlfeat.2 => nvme_id_ns_dlfeat.2} (93%) rename doc/man/{enum nvme_id_ns_dpc.2 => nvme_id_ns_dpc.2} (92%) rename doc/man/{enum nvme_id_ns_dps.2 => nvme_id_ns_dps.2} (91%) rename doc/man/{enum nvme_id_ns_flbas.2 => nvme_id_ns_flbas.2} (66%) create mode 100644 doc/man/nvme_id_ns_granularity_desc.2 rename doc/man/{struct nvme_id_ns_granularity_list.2 => nvme_id_ns_granularity_list.2} (60%) rename doc/man/{enum nvme_id_ns_mc.2 => nvme_id_ns_mc.2} (86%) rename doc/man/{enum nvme_id_ns_nmic.2 => nvme_id_ns_nmic.2} (80%) rename doc/man/{enum nvme_id_ns_rescap.2 => nvme_id_ns_rescap.2} (94%) rename doc/man/{enum nvme_id_nsfeat.2 => nvme_id_nsfeat.2} (74%) rename doc/man/{struct nvme_id_nvmset_list.2 => nvme_id_nvmset_list.2} (55%) rename doc/man/{struct nvme_id_psd.2 => nvme_id_psd.2} (89%) create mode 100644 doc/man/nvme_id_uuid.2 rename doc/man/{struct nvme_id_uuid_list.2 => nvme_id_uuid_list.2} (66%) rename doc/man/{struct nvme_id_uuid_list_entry.2 => nvme_id_uuid_list_entry.2} (61%) create mode 100644 doc/man/nvme_identify_active_ns_list_csi.2 create mode 100644 doc/man/nvme_identify_allocated_ns_list_csi.2 create mode 100644 doc/man/nvme_identify_args.2 rename doc/man/{enum nvme_identify_cns.2 => nvme_identify_cns.2} (53%) create mode 100644 doc/man/nvme_identify_ctrl_csi.2 create mode 100644 doc/man/nvme_identify_domain_list.2 create mode 100644 doc/man/nvme_identify_endurance_group_list.2 create mode 100644 doc/man/nvme_identify_independent_identify_ns.2 create mode 100644 doc/man/nvme_identify_iocs.2 create mode 100644 doc/man/nvme_identify_iocs_ns_csi_user_data_format.2 create mode 100644 doc/man/nvme_identify_ns_csi.2 create mode 100644 doc/man/nvme_identify_ns_csi_user_data_format.2 create mode 100644 doc/man/nvme_init_copy_range.2 create mode 100644 doc/man/nvme_init_ctrl.2 create mode 100644 doc/man/nvme_init_ctrl_list.2 create mode 100644 doc/man/nvme_init_dsm_range.2 create mode 100644 doc/man/nvme_init_id_ns.2 create mode 100644 doc/man/nvme_init_logging.2 create mode 100644 doc/man/nvme_io.2 create mode 100644 doc/man/nvme_io_args.2 rename doc/man/{enum nvme_io_control_flags.2 => nvme_io_control_flags.2} (73%) rename doc/man/{enum nvme_io_dsm_flags.2 => nvme_io_dsm_flags.2} (77%) rename doc/man/{enum nvme_io_opcode.2 => nvme_io_opcode.2} (71%) delete mode 100644 doc/man/nvme_io_passthru64.2 rename doc/man/{struct nvme_lba_range_type.2 => nvme_lba_range_type.2} (66%) rename doc/man/{struct nvme_lba_range_type_entry.2 => nvme_lba_range_type_entry.2} (62%) rename doc/man/{struct nvme_lba_rd.2 => nvme_lba_rd.2} (60%) rename doc/man/{struct nvme_lba_status.2 => nvme_lba_status.2} (63%) rename doc/man/{enum nvme_lba_status_atype.2 => nvme_lba_status_atype.2} (70%) rename doc/man/{struct nvme_lba_status_desc.2 => nvme_lba_status_desc.2} (61%) rename doc/man/{struct nvme_lba_status_log.2 => nvme_lba_status_log.2} (63%) rename doc/man/{struct nvme_lbaf.2 => nvme_lbaf.2} (85%) rename doc/man/{enum nvme_lbaf_rp.2 => nvme_lbaf_rp.2} (89%) create mode 100644 doc/man/nvme_lbart.2 rename doc/man/{struct nvme_lbas_ns_element.2 => nvme_lbas_ns_element.2} (57%) create mode 100644 doc/man/nvme_lockdown.2 create mode 100644 doc/man/nvme_lockdown_args.2 create mode 100644 doc/man/nvme_log_ana_lsp.2 create mode 100644 doc/man/nvme_lookup_ctrl.2 create mode 100644 doc/man/nvme_lookup_host.2 create mode 100644 doc/man/nvme_lookup_subsystem.2 create mode 100644 doc/man/nvme_media_unit_config_desc.2 create mode 100644 doc/man/nvme_media_unit_stat_desc.2 create mode 100644 doc/man/nvme_media_unit_stat_log.2 create mode 100644 doc/man/nvme_metadata_element_desc.2 create mode 100644 doc/man/nvme_mi_css.2 create mode 100644 doc/man/nvme_mi_csts.2 create mode 100644 doc/man/nvme_mi_ctrl_health_status.2 create mode 100644 doc/man/nvme_mi_cwarn.2 create mode 100644 doc/man/nvme_mi_elem.2 rename doc/man/{struct nvme_mi_nvm_ss_health_status.2 => nvme_mi_nvm_ss_health_status.2} (62%) rename doc/man/{struct nvme_mi_osc.2 => nvme_mi_osc.2} (50%) rename doc/man/{struct nvme_mi_port_pcie.2 => nvme_mi_port_pcie.2} (62%) rename doc/man/{struct nvme_mi_port_smb.2 => nvme_mi_port_smb.2} (60%) rename doc/man/{struct nvme_mi_read_ctrl_info.2 => nvme_mi_read_ctrl_info.2} (57%) rename doc/man/{struct nvme_mi_read_nvm_ss_info.2 => nvme_mi_read_nvm_ss_info.2} (61%) rename doc/man/{struct nvme_mi_read_port_info.2 => nvme_mi_read_port_info.2} (72%) rename doc/man/{struct nvme_mi_read_sc_list.2 => nvme_mi_read_sc_list.2} (62%) rename doc/man/{struct nvme_mi_vpd_hdr.2 => nvme_mi_vpd_hdr.2} (61%) rename doc/man/{struct nvme_mi_vpd_mr_common.2 => nvme_mi_vpd_mr_common.2} (64%) rename doc/man/{struct nvme_mi_vpd_mra.2 => nvme_mi_vpd_mra.2} (59%) rename doc/man/{struct nvme_mi_vpd_ppmra.2 => nvme_mi_vpd_ppmra.2} (62%) rename doc/man/{struct nvme_mi_vpd_telem.2 => nvme_mi_vpd_telem.2} (61%) rename doc/man/{struct nvme_mi_vpd_tra.2 => nvme_mi_vpd_tra.2} (63%) rename doc/man/{enum nvme_nd_ns_fpi.2 => nvme_nd_ns_fpi.2} (85%) create mode 100644 doc/man/nvme_next_host.2 create mode 100644 doc/man/nvme_ns_attach_args.2 rename doc/man/{enum nvme_ns_attach_sel.2 => nvme_ns_attach_sel.2} (53%) create mode 100644 doc/man/nvme_ns_detach_ctrls.2 delete mode 100644 doc/man/nvme_ns_dettach_ctrls.2 create mode 100644 doc/man/nvme_ns_get_csi.2 create mode 100644 doc/man/nvme_ns_get_firmware.2 create mode 100644 doc/man/nvme_ns_get_generic_name.2 create mode 100644 doc/man/nvme_ns_get_meta_size.2 create mode 100644 doc/man/nvme_ns_get_model.2 create mode 100644 doc/man/nvme_ns_get_nguid.2 create mode 100644 doc/man/nvme_ns_get_serial.2 create mode 100644 doc/man/nvme_ns_get_uuid.2 rename doc/man/{struct nvme_ns_id_desc.2 => nvme_ns_id_desc.2} (82%) rename doc/man/{enum nvme_ns_id_desc_nidt.2 => nvme_ns_id_desc_nidt.2} (76%) create mode 100644 doc/man/nvme_ns_identify_descs.2 rename doc/man/{struct nvme_ns_list.2 => nvme_ns_list.2} (62%) create mode 100644 doc/man/nvme_ns_metadata_type.2 create mode 100644 doc/man/nvme_ns_mgmt_args.2 rename doc/man/{enum nvme_ns_mgmt_sel.2 => nvme_ns_mgmt_sel.2} (66%) create mode 100644 doc/man/nvme_ns_write_protect_cfg.2 create mode 100644 doc/man/nvme_nss_hw_err_event.2 create mode 100644 doc/man/nvme_nvm_id_ns.2 create mode 100644 doc/man/nvme_nvm_identify_ctrl.2 create mode 100644 doc/man/nvme_nvmeset_pl_status.2 create mode 100644 doc/man/nvme_nvmset_attr.2 create mode 100644 doc/man/nvme_nvmset_pl_events.2 rename doc/man/{struct nvme_nvmset_predictable_lat_log.2 => nvme_nvmset_predictable_lat_log.2} (55%) rename doc/man/{struct nvme_passthru_cmd.2 => nvme_passthru_cmd.2} (95%) create mode 100644 doc/man/nvme_path_get_ctrl.2 create mode 100644 doc/man/nvme_persistent_event_entry.2 create mode 100644 doc/man/nvme_persistent_event_log.2 create mode 100644 doc/man/nvme_persistent_event_types.2 create mode 100644 doc/man/nvme_pevent_log_action.2 rename doc/man/{struct nvme_plm_config.2 => nvme_plm_config.2} (56%) create mode 100644 doc/man/nvme_pmr_size.2 create mode 100644 doc/man/nvme_pmr_throughput.2 create mode 100644 doc/man/nvme_power_on_reset_info_list.2 rename doc/man/{struct nvme_primary_ctrl_cap.2 => nvme_primary_ctrl_cap.2} (63%) rename doc/man/{enum nvme_psd_flags.2 => nvme_psd_flags.2} (90%) create mode 100644 doc/man/nvme_psd_ps.2 rename doc/man/{enum nvme_psd_workload.2 => nvme_psd_workload.2} (92%) create mode 100644 doc/man/nvme_read_config.2 rename doc/man/{enum nvme_registers.2 => nvme_register_offsets.2} (80%) rename doc/man/{struct nvme_registered_ctrl.2 => nvme_registered_ctrl.2} (61%) rename doc/man/{struct nvme_registered_ctrl_ext.2 => nvme_registered_ctrl_ext.2} (51%) create mode 100644 doc/man/nvme_rescan_ctrl.2 create mode 100644 doc/man/nvme_resv_acquire_args.2 rename doc/man/{enum nvme_reservation_cptpl.2 => nvme_resv_cptpl.2} (60%) rename doc/man/{struct nvme_resv_notification_log.2 => nvme_resv_notification_log.2} (57%) create mode 100644 doc/man/nvme_resv_notify_rnlpt.2 rename doc/man/{enum nvme_reservation_racqa.2 => nvme_resv_racqa.2} (61%) create mode 100644 doc/man/nvme_resv_register_args.2 create mode 100644 doc/man/nvme_resv_release_args.2 create mode 100644 doc/man/nvme_resv_report_args.2 rename doc/man/{enum nvme_reservation_rrega.2 => nvme_resv_rrega.2} (62%) rename doc/man/{enum nvme_reservation_rrela.2 => nvme_resv_rrela.2} (53%) rename doc/man/{enum nvme_reservation_rtype.2 => nvme_resv_rtype.2} (67%) rename doc/man/{struct nvme_reservation_status.2 => nvme_resv_status.2} (62%) create mode 100644 doc/man/nvme_sanitize_compln_event.2 create mode 100644 doc/man/nvme_sanitize_log_page.2 create mode 100644 doc/man/nvme_sanitize_nvm_args.2 rename doc/man/{enum nvme_sanitize_sanact.2 => nvme_sanitize_sanact.2} (64%) create mode 100644 doc/man/nvme_sanitize_sstat.2 create mode 100644 doc/man/nvme_sanitize_start_event.2 create mode 100644 doc/man/nvme_scan_ctrls.2 create mode 100644 doc/man/nvme_scan_namespace.2 create mode 100644 doc/man/nvme_scan_topology.2 rename doc/man/{struct nvme_secondary_ctrl.2 => nvme_secondary_ctrl.2} (63%) rename doc/man/{struct nvme_secondary_ctrl_list.2 => nvme_secondary_ctrl_list.2} (56%) create mode 100644 doc/man/nvme_security_receive_args.2 create mode 100644 doc/man/nvme_security_send_args.2 create mode 100644 doc/man/nvme_self_test_log.2 delete mode 100644 doc/man/nvme_set_attr.2 create mode 100644 doc/man/nvme_set_feature_event.2 create mode 100644 doc/man/nvme_set_features_args.2 create mode 100644 doc/man/nvme_set_features_data.2 create mode 100644 doc/man/nvme_set_features_simple.2 create mode 100644 doc/man/nvme_set_property_args.2 delete mode 100644 doc/man/nvme_setup_ctrl_list.2 delete mode 100644 doc/man/nvme_setup_dsm_range.2 delete mode 100644 doc/man/nvme_setup_id_ns.2 create mode 100644 doc/man/nvme_smart_crit.2 create mode 100644 doc/man/nvme_smart_egcw.2 create mode 100644 doc/man/nvme_smart_log.2 create mode 100644 doc/man/nvme_st_code.2 create mode 100644 doc/man/nvme_st_curr_op.2 create mode 100644 doc/man/nvme_st_result.2 create mode 100644 doc/man/nvme_st_valid_diag_info.2 create mode 100644 doc/man/nvme_status_code.2 create mode 100644 doc/man/nvme_status_code_type.2 create mode 100644 doc/man/nvme_status_field.2 create mode 100644 doc/man/nvme_status_result.2 create mode 100644 doc/man/nvme_status_to_string.2 rename doc/man/{struct nvme_streams_directive_params.2 => nvme_streams_directive_params.2} (63%) rename doc/man/{struct nvme_streams_directive_status.2 => nvme_streams_directive_status.2} (61%) delete mode 100644 doc/man/nvme_submit_admin_passthru64.2 delete mode 100644 doc/man/nvme_submit_io_passthru64.2 create mode 100644 doc/man/nvme_subsys_type.2 create mode 100644 doc/man/nvme_subsystem_get_host.2 create mode 100644 doc/man/nvme_subsystem_get_type.2 create mode 100644 doc/man/nvme_subsystem_lookup_namespace.2 create mode 100644 doc/man/nvme_supported_cap_config_list_log.2 create mode 100644 doc/man/nvme_supported_log_pages.2 create mode 100644 doc/man/nvme_telemetry_log.2 create mode 100644 doc/man/nvme_thermal_exc_event.2 create mode 100644 doc/man/nvme_time_stamp_change_event.2 rename doc/man/{struct nvme_timestamp.2 => nvme_timestamp.2} (51%) create mode 100644 doc/man/nvme_update_config.2 rename doc/man/{enum nvme_virt_mgmt_act.2 => nvme_virt_mgmt_act.2} (76%) rename doc/man/{enum nvme_virt_mgmt_rt.2 => nvme_virt_mgmt_rt.2} (68%) create mode 100644 doc/man/nvme_virtual_mgmt_args.2 create mode 100644 doc/man/nvme_zns_append.2 create mode 100644 doc/man/nvme_zns_append_args.2 create mode 100644 doc/man/nvme_zns_changed_zone_log.2 create mode 100644 doc/man/nvme_zns_desc.2 create mode 100644 doc/man/nvme_zns_id_ctrl.2 create mode 100644 doc/man/nvme_zns_id_ns.2 create mode 100644 doc/man/nvme_zns_identify_ctrl.2 create mode 100644 doc/man/nvme_zns_identify_ns.2 create mode 100644 doc/man/nvme_zns_lbafe.2 create mode 100644 doc/man/nvme_zns_mgmt_recv.2 create mode 100644 doc/man/nvme_zns_mgmt_recv_args.2 create mode 100644 doc/man/nvme_zns_mgmt_send.2 create mode 100644 doc/man/nvme_zns_mgmt_send_args.2 create mode 100644 doc/man/nvme_zns_recv_action.2 create mode 100644 doc/man/nvme_zns_report_options.2 create mode 100644 doc/man/nvme_zns_report_zones.2 create mode 100644 doc/man/nvme_zns_send_action.2 create mode 100644 doc/man/nvme_zns_za.2 create mode 100644 doc/man/nvme_zns_zs.2 create mode 100644 doc/man/nvme_zns_zt.2 create mode 100644 doc/man/nvme_zone_report.2 create mode 100644 doc/man/nvmf_addr_family.2 create mode 100644 doc/man/nvmf_connect_data.2 create mode 100644 doc/man/nvmf_default_config.2 create mode 100644 doc/man/nvmf_disc_eflags.2 create mode 100644 doc/man/nvmf_disc_log_entry.2 create mode 100644 doc/man/nvmf_discovery_log.2 create mode 100644 doc/man/nvmf_eflags_str.2 create mode 100644 doc/man/nvmf_rdma_cms.2 create mode 100644 doc/man/nvmf_rdma_prtype.2 create mode 100644 doc/man/nvmf_rdma_qptype.2 create mode 100644 doc/man/nvmf_tcp_sectype.2 create mode 100644 doc/man/nvmf_treq.2 create mode 100644 doc/man/nvmf_trtype.2 delete mode 100644 doc/man/struct nvme_error_log_page.2 delete mode 100644 doc/man/struct nvme_fabrics_config.2 delete mode 100644 doc/man/struct nvme_firmware_slot.2 delete mode 100644 doc/man/struct nvme_frs.2 delete mode 100644 doc/man/struct nvme_id_ns_granularity_desc.2 delete mode 100644 doc/man/struct nvme_mi_ctrl_heal_status.2 delete mode 100644 doc/man/struct nvme_nvmset_attr.2 delete mode 100644 doc/man/struct nvme_passthru_cmd64.2 delete mode 100644 doc/man/struct nvme_persistent_event_log.2 delete mode 100644 doc/man/struct nvme_sanitize_log_page.2 delete mode 100644 doc/man/struct nvme_self_test_log.2 delete mode 100644 doc/man/struct nvme_smart_log.2 delete mode 100644 doc/man/struct nvme_st_result.2 delete mode 100644 doc/man/struct nvme_telemetry_log.2 delete mode 100644 doc/man/struct nvmf_connect_data.2 delete mode 100644 doc/man/struct nvmf_disc_log_entry.2 delete mode 100644 doc/man/struct nvmf_discovery_log.2 diff --git a/doc/html/.buildinfo b/doc/html/.buildinfo new file mode 100644 index 0000000000..87f3cf16ef --- /dev/null +++ b/doc/html/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: d4b1279bd20667a658a462887c1b9569 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/doc/html/.doctrees/environment.pickle b/doc/html/.doctrees/environment.pickle new file mode 100644 index 0000000000000000000000000000000000000000..741425e2847b93a539b22ed9c29bae65829ff5de GIT binary patch literal 833103 zcmeEv37lL-wf-ctBonglBq4+#5Wpk^B0CynHz6RPA`&ily6;SPr?>RIJ(Gk*0YOF^ zK^%B0C;}=jPf;I=ilCqZ`hO@Yq7P7?pyE>$7eGM8|2cJ+uCBXu-EA_H9Q--yrKT@0Fkh>bOIq0&Y0P|mJzvb8zaO5WGfk?rfJ!HZKSd9YNJ%e|F6odKcc*4pmNBD+-fMWI%kxMt5;b? z^^r!8Udyl=3w&xokxZrBpC1@$OtXO5?|Y6jzi^QBRtB|NEuYnN0M_W%HKWduXkjWl{QmFl)yejo>*&N}#@gAaQ3vh`Zt$Sr$) zUC-nIgIYIo6?m{cxsR6}y}1v+Ubk7Rm9^rkN^Rh^BaJB~RX4Pn0?#;-o8OpJ(~6p^ z!*6sRv}(;rW4fW0szue%bfu~qIRrFCaXuSS8#A@7nPNSw;n&a(!@Q!=g&hZNl+-ey z&6l&<)>Snf(Dt5{tC#xpRoOmxz3TWgl{1Y>O&ie~GqHxE8>*4dI6pO&eFzCYFT%K*t@tNdysrCRP9YDCo=)2rJCa6ITxZd(zasmBxvbQ(6C(~4E4 z4<5FxLZ`yRPhmgD8iOHZmQ`v-RhRTi-q2Q7 z)y!sf0D!8E=~}hkr?fzyZax|RG}G8e1@8H#>6LmdqbYj5zdyfqq_JD3QY^wyU_+y^ z+iA6|R@1V_=V5TbpgLou(Peh>%$lYfwR*;=!`H0q^v1Muy#&Kj>95pED)!}y#w6Wr z3q*RR`D)odIL4tERD|(%Vt!y1`>5Mc`>_8epN0RjkEUcQS#4!sv69&g^*7{oBVQiC zZ|aSnLA6+i2Z!It&4X_3gsC~Q@m(Xi-E)g_r^AcJENe_F+&JzS$?c7W7UUMP7mZ0U zJ8%|^<%wf8OY2Z*cfBOqA~x1TBTxKwCV!;yNfP>!FbV#S#jBb2E%@m))eKASS{XVSx)sKK-RNI= z_(~o0idlBA+;X$*)U4L8){BNxtAK>8=U=F1vw)?{h6)VT8cc$mrh`nbG;7Vo0;Ni} z4t;`;>3p$=QOlQLkW`Fv#n6(wd@e7*V2ChN!M!;>-{1mmq#s+1KdhZ73EXAMpP)ud?Ee6ccM_aOTSMk)8v zY}Pes3t)CB{Y4di+v?8gRp>RfwhhEtQuCnlCRSm1vY|e;3^oQ75HnIE8#m$u%rrma z^!!Ee4SX>b^ko&5hElH;Z77q=d83-oY~D69%nD7n-YfZmGV0DvX5G21AA{%yG<-x> zr^lTAw*2N;$^aAqyi&4S6;%8B2@G-W_}mF5^ckQiataja1N#8u+pax}eXebRPPEmD zHSTt^Yru4}`(}z!)D@V@`TlM8N4w!i85mDBL${xDN?pfa89?)Gx28j%8e8fx5S^Z$ z&3&e*Y6*>XJSZ`R#&`R^^$#57T(*Pg#j0Zc5YpqMB3Ax!`^1O2oj_o_x0QvU{7m5nJp0ZnpEqCv zgLYt_?Z(PmW*pQe`_KerKL?C54U{AM#{Wgmt$GJ%g5aWPkpn0Vt)}A6e*X znq#`nq9%%J1*el`)7clf!*Yk4zi4)wO)**uHO$^HDj93|cAAZv$nj%fQ`Y=+it1o+ z;CU|Qe;+h~0<#xQwWZ$Xvga(R*5}GlK8y3C!>naK4by-yOVMEF%f);dn&m_Rqgi1p z2OzMIXRt$+rrtq9zHNQcUQ_J_&fety}%wlzhYI(G+sII{TPXS(+-wuVzFLcWLz6fK)vioL6=rwZZjArv+Gv}^YGx-hq)tiN19J^RPJc=#fseiW_go(fyS(< zHuW;Um}fQ(Bvz?cvp`hA@G&A_nhN%<4r8%Tg;@?JhJ9>S0viZDTPdqWXcEP5e?5oQ zGIcphF`r=yh*dSeL-SeHfJuSiH^UH^YjJ&BpRB?bMjCUFpaNq8Wn8T(l|IJf8UN>> zifiaf^Ygh3K=X5j^-^QveP6a7z@(4-AYgyQE85$#%K03SD7FgpaHz|<=1npy)71SlH^2ph;P*T z!fcKKYLY_>tTP&iY2ozMR({^H=|D$;Mwe{fC&Jj0fqw16|D<{ zYmN)kDx%S|iTA`+%dE;)f3c@*vYS@y=9iq7XKkB5Yxa)nK`YdKrtbRs@nl)7s zz-o%YoGWODkQLZnyTp177}`j}v4&Qz*sf0QW%G&5Uu9+)cpUl*HQT(hX4fjHUf@G( zpa26gas|+Q%-d@ml{1X0e&p)anQVDgLC#7k*7Vn`2HUx^ zR4T5_ATTIw^%!Fj*rM1W)9s(K)F+tW#>8`1fLS|t{}IiE?^Mp_b#Ozsp`C{B--d-Y z*@c{jK$Rfzu%uzvJs4P@*XM_bpW9U48X7Pta%j3|+MlD(fcnDzVygW`9Zlk}S$ekp zA=vJU!t?=@XU1}o^Ho#v7-|hZMgC!ySzwnbqDHeF33TOmKk-c)HZ0qC?5QU#JNkrE zk3D6>x?_(&{)`jOJoB|9<}c4{RyCa;@YB^2=%x+FZanEt$DRcBHf&f|%$ttCS!XJ` z_FG}544?sPOs-~u*TN?zYn)+zYa0fWCCzW_W?79@SdfcKv=27)0Kct+;W9>4Ht?sI zKVTXL_Q_216Nu5kXk~iWVz7(NFHp~zuS($bfLbipOJ$1~TX3<+R?yluU*6p;Z&a#9 zZBT<4gX!y{UuDwqxn==T-!nW`o1C?uSOz18<6@3kjeUjo1L!a?2=>)<^D79Yu9nqY#@2u`Jzq0}~>AB$Y${+fC+)cT|a^SEccC(FKM9MExB=D3{`3n)q*PBVimQV0rmnKo_(>f`772J z&3+TrO!AtHE>t-C6>RYXAC4>uTR*q@Oj}3uD^i59mZd2+ax8*%Jln70&QQ z>iP-x(4U6Yn#0N*H;eGYlDZkJr8!73U;(cxHG446(P7*cHPbNLw5G5pj1^O1&Vo6a zFZWk4u)x@yJ!u_O;9)E({0b^G_B^euErTc3mT|OnS*3rO6LFk&YF^K1MesPF+jVE! z&bEKVJxyoYU%AG<{e|Z=b6_`nq%ql!LYPB$p4~th9!@jVd=chW-I{O$ zu!SvmY~QduHIqXw*qC&{F)J@#e&G3*=AFihl(ix35%{{RUWO2Xsg>uj?~wF4+`#cj z5f^LPa+F&*gXtt~1vU;L2g7hY;29YupH(1Y$|yhloUQ+7WAGC!wbyquGm1%oH*4Eq zz-O6g8~gT)E#zV z4bNf)JiB2oeihIW@GbD3`T!uUYz9AX7?>2QWUOX>!3Gir`0ej@hmdH#sz3;>tYTmk zBEOl<5T(;|_7m-8MsO80AocPVFjVLpXBA^x)sB)`4&po*_%I1s{J37uT0t}nA@@4p zuu#Ap=PghHRuGuN#=`y+LAL|mxy`S$+8~B(kX|&pwem`sZced<&0c z-(jbT-J3;9`7&^nT1hDa0Rdyt>=>@!bTHiJXwN<3G{RvtBe^5omou8bVEL?5Z9n&9 z5Lxp{7dH!HG#iHoOiPT3z)Wp|;kw@`W`_SZHQSosY>PcPcn>Cpp1~Ff`ts$~xqRKo z7n@bM&T`r{>&$ZM*k3ejEo=S|kYeUtf>wZ)7jR<@nD)Ryn%xAW%C*V?ky!R23rDX3 zbHJt!b8J{y4{xpcB^pNCEwXv`7N8%kD=DTenrVH(0?aIYY}J@*ePJ@4Mt2!}@Il+b z;=dDphI+lPG0kN2Z0QFk$@&Q}>lwedJ~4G9xJiv3pnI_R1OC9g#&pX;cTC%))2(GS zdpRyQIoFFJ_{L-~on}n@YFs3-t@$dDDu}RjBMTqr4qAVBy)oC)J{XjOt~Y}yBg2i^EuVvX4Z&$x{jeSZ zC}?9cbO^?>kS?xhOlK|<*g-2C-u`yMHc(dgO!&rs|M)sb?lOVPUJv!W&mnl}% z&58yBC@NrhGM^c}pVcq}RzpdBH7syq4UR8t zY)q~7XSg=@wcCK;k_rx428iaWyk_*9E!m62&=S^bX=!@C+!BY#RT|S_a51H%Y{iv0 z>@}o%dcCjp(^)nF)U{&284VbQ*q;guJ7m|kcDoT!$-kQ z1!+=@TxV|UaATSsLI&|cOfmOJV=Akl*s=C{V=~xu*VsXAoXNmY#cUV>fGU2OKtBi8RCNAZOqtoj3*FKXUm9tWHkOm)TNrcBF6vv{?8E z{9#{AgQx`34z)O>ZqrAuhN2~4c-Y}q(Ho&?qswZa)#+jV<-lVdi|SQhRYp|~MwAu6 zg;8_ezqh6iS+OtB4U;oDi2MW50_IitENlHNP@{-`%F*S@GFJJufSXk=d=W~ZMlqMt zMhc&Y_w_!tF@>XWIHWuCjFkcNLaz&8z$$gOsZ8M2WC%$&-yr{BKI0}>Go56pz)K+3 zUichqT5n7#R=_A?%++~F_Om*yQgCuH!SB{rhm~P7n&mvQg}U%x&>}qL*Wn+)Sh&Z0 z`%Uwo`^$vc~n-Kwc0fQTa32q=#vyG_En00`cUFa#mzccds85&<|xY4U{<7-9X8Td(a7_wh4 z{1M(4o<$smKeNAo!4DYRX~&*<)+x<(84Gn|ipfjNwVHXD1!At-qFKeo6Aa<$eTBa| z?M#Puj^~iukKdSLhM~^_QVS!}UL=N|H(kyApeBCBwK@q}WnVkZ_2Pq{S=B&Om=7@3 z`eE}kr(8Gq?SQe+-3c=3Eo%J+Uuia9>C8NOEzU58JOyxoA;5ydFddW)xS9`k{pI1t zWR~lIiU(c~Rv?4|!De{f4VDQ^8N9$LiW3pI!xWY?WBu@4Kw=4H0leH;Scre2&BE^R zVz{t~{awudE`h(S1=Ndi>dyoVlE-m}y@(B2y|xrPR`}{f@EAZPu%#ZW9}DJm1w8}H zq^jNr&(wtiuv(dKbt4YfN^K)lJ{?|`nqAq0g--zm?2NUI5R1{WSkx(H{Yc@TFqqUv z4^AntD#P$wlhs;H-F8~l)N7y&q3vc`oH!E~fU}lKz+e6w6kr6W@Ep8aKe_Nc{4-p50saC$QE_8)ZpB^2 z9$>0>0=%;Nz6)M9rrG+{oQH)Td|tEY@mOgq{24B6!$!ZR@q&K`ub9_AypnUiMCzzD`&$2C7W5ndKfZoXfS@7r|q zxKw@TG@o%3KI3`#N5MaBHA|p68)&v$z}DJJs&!%%YEX+)l)UJ0q6R6hLLKU2p+Wf9 zrLg$9e>p<)nfo(?H4>}pqLL3_gI*e`@DBWjQ$x4mdrl2KBoD>bILYW9VEm93CQw<@ zJqhTZM?s{ddyvk1)2>}x_dF6X;THz$9#++*d**k^>Yf+yr#aoT1Z(=JK>a*auBm)7mW9;|qY!c$_6#|V7WWbTF!6m@zYHQg zY{oYMcVp!h;`AVv|6{8+o8iP7+qhwrZCg&P}VOD$s=Akv$1RVdK0)tqQTgQ;dK%J!( z4iwFh_&&67r{E$!+bbI+mLrpev1w(0kR zZ8`#L`gr`USp3&FyfGaljcF>D(Mheo%xKz676v6B02i{7GLR>OKt1*C z7+8B5gZ6R!DBEs(vUo~2czGr%J=?kp&Fhg91N6v|Eqd0qWXr0$)NBJAlyU)bSdvp| z*U3Xk!397mHQ7H)izXK!Q5WDNAYacp;MQ>D0>Gk!tP8Lkv&(G!CdB>=zk>`CqW>TR z?*u#3=#Sf|)HtC3HwM^(*SDA@H~nXIU3TdSY*ETC-Ge1LyEL^2-uux1RxJJm+Z$6S zwk(C|mjb5Q;W5Rf|GT%+|E8@ZGnuHFTnwTmGwGSw?5TIjOxii&?tEc#+;GE1AyQHu zq&KE_NMkxzz;tzZOmWSmoujPl zunVNFWJ;J)?rr2*ycn|_og8_yTn*TFqZhK<&t&Ig+G*{LE*y{}9=WC;fX8%92K*W) zmFoj~Kxr8v{!)>O4$fippb8tx?B_moZRjVz3DBB3%(ozJcUJAE{h#!c0Z)2ol25wC zBtrE*JZ?kH;{I^^u>&3%w-ixAy0srjHX;41ytw(SW(pZ37I*|Lrh;gR(;x)r6)EP>PW2@16b zwvxi3Vgal30gDE1x%#ib-sx{oPn|WP#h|)lFs!nRT>cH4l!|x!50>O;%yE<8y>|>o z1mn+Ryg@C%rlmmrT>y1TdZ3P$2DJoBay@lg1W<7~uesHms1OSnd+nJ`AV>6UkgKCl zcuh`Jh^SCs@V3*yz|eAZOyIPA*If!KCf7Hj=F;+}gYe-h( zMpk65#s#xr^NQ@%_>mPZkbB1Thz5=&8p!6=Ye-h(!Cph1qHge1`TT`t2x)gS%5|P0$JFa%Ee4IB2Bz7FoE+2aR2tM*1W>){fqGFI)MEmu8R>yq1XqpA zjj4YMpys6q>S$?DOR*$3&=;o%>O5&sczrt$YOnM_y+ayQp8#sV^g!Jr4eFf&sFmq~ z`nEKvPY9q6Ne|R-r9nL?fI1>QP?OPENST@63!q+?9;gGPK~2SyoJu$$Jy08@L9G%% ztxpeBQ5w|g0;o5p2kL5RP+J60Z%Gf-?b4v$FM!&V9;hElgStZil}QiO3(}w-6+q=9 zfQp;nyvTpY7lawTRU7U1;_iQv-S1Tc;d=VOl;liF&SNLZIm~`9&;7v87;k1h$Bwnr zZm%7a$sQCAj4jkr+wD~iFsp;@qD!o@E4uWb*rXKgzZOe!4Evw*VEm&?-k=_q2K9LX z)WqEYq)*68=%KKno|gvo69LrZ2%zG!A#(?7>uxWiK}ntkIt!%gmFve~9*ajUQRjUa#>ZE86Qdeq=@VYW&EG_IiyUS$MOwuw^`~QP`70d%X%fL2!xodf_I!u{5t}uNS*sWhaQ({Ni|K)SN*dI6 z1W>P}2dW#JmNLjs3!u8Dr)H4%kp|U^B{`KaB|T6lOM^N<05vl`P&sK(8w61E(*yM$ zX;38r)ROc--7XF4Y5~;p2%zF-H(S@7nzwu9D|EG&*NLyLaAIe^9P(~o-dy~f$RqP zuW=zO+UvED_Ij--OvUx$>F~!|X`Y3hQkadOM!E-RyoJ|;wl{=6ord;$(O$3K=3Jt= zrPLGig=w$X=HhHfbmbp z@dmZ8G^oi~lFJaPrw8g}X;23Upe{%cR6!cl1_9J1>49oUgDMN4-jyDx&q;&2MgVnH zdY~Sb2K7Y&)cex|^;c<7j|iYXm>#IPGiCME3j(N{(gSsON0P4>4K;0t^>Z1avyVC>p3u#dI3821}9;gY}v{WAP zQv#^(rUz;-X;9r*l2ZvkNDtKU(xCPgK>Z{=P&sK(Ckvn+j{quea`OWIUN0`knQpU4 z@-~ZKgJdbg**m?LZ8@TyUeSWL$>#Tk+37`>dWFpI+nM6*(T)+iuB&502mZ%aE()(q z?C5BW+U;IX1{l|M6ARA+nBl?;@OKkzn0yBQwU$@zf|mtW*%f12I$M^gbzw=46P5A3 zPmDN@VLD|a<6V1q>tG%R7GaoB^h$w%4T;z^+(RMG| z?!^LD#48d^aii^C<7`_BnX7SOu4ud0IGb0r-D~{JE86ZgE@Va9y%u5;whV1|We;=> zR`S^qRqulo?v=PRD%yf2w@yh{d(qWi_LA_4IHFF5KUREhJ-*)=cM*-kyrQeU=xVR# zOxk5;Rtn+U*d}h&QgJQ`$mw`%yHp%j*_DcOH#RAiGkq(Trvy-I(*w1)G^lPY$%*gC^gx{;4Qf9D)VlOQ4M>AJMF4eT zdZ31-L2VX5ZAcH)XQV-0C4f33Jx~uxgSuS+b#{87o|OjmLjlxz>4BOxS5{B`O#qcm z57Z&jpypvoPEQrm1NA0pP=^Vis_B6mk_Pow0n}i6p#DP|)CB^l3)2JjHEB>c3ZO1c z57cAQpzaYsU6~%Je@TP-r2y)^>4Dk{o0ejp6R;$w5=J6`iksRz*WT`>Z_^E}q|`KB zGbp_|$@JzAgIFcgn+wP7g08PCs1*La>mG4$|GjUHVdZ(Rx|K;)8U|ej=*i#fi(j+Qv}vbiZE;ic}nVq6~q{J2xHhK zyL~LKUbfpe6rdyA9-`)uf6+r63{bI8w5ogeF#@czOW%JHo0QV`AHb5FzW=#A7=Opm z8`PuHpuQ}CdMW~_xM3~piq@=FHuC-36ty;>`&y#&981)r8?}1Iu>MYE-v>PN3$3HVUl39rx@m6n)|2`^B$?YN&Lc12!Vxe4 zHjNaH!r?;xIrf5}_QRYOL?1|KIX|hiz;kTfVe;C9Y&`VG!JgZBm`ZivQR-jt618?8Qux1|A{OH;j|n_ z`TIKorvxb66IzwO+X-NmUE2S0Y*I@5Z^n|G_W!&*7=P~R4eC?UpoRrdUycAOt`lG# z+hsceWq%id*l`49`3(@M=e#0=l-LTPpfJfGy}U7iubbU2cqMdbP1`+lfg$n04i5~8 z2i9aEaY0mJxWg2iJ218G=%FN;LucVkM&*S{ByX z$kR^J(|#KW*HI|^v?pRi#HOz>R;(ov8zMFsW(j@A>BP|>Hg65EkZ*5CY*=L%vAGVL zl;RKFj|2L({SOAplJ(xC1VK>aBKsJO&ti9l>18E8-gR-+X2 zI_*VZ#{ndjK=gMIFHsvhYTbLilc-I&eIvBq17N)H~AyH6#t{ zEdr=_M*tO<-s~yR8!m1`49DJhmsnuo{UBk_xlh5H#QK<4rQk|1`AZnQmO3bSvr`6d z%#4pWz`7;~=j6cKi2KB5os2>WTmZb-3 z4mK^-Q-2dc?Hd79T!v%b8EogEvurM6Hi?ja1#L^U8>@!Cvfgr`^(~01$3^0`6Z^v&~Wf#B6OIz*J zuq4NCzAO*MpWk?cdXF@yk^t)K>4Cak8r0PSsQV&-ipy_=1uERvP9%rzno6AH{67${ zV-Wa>PvIL1-%#!iah%Xe#bF|C#78e-cLK`CHg{YC_|C>hzZ*bo{?Lw(vdS(#+Pzpd ziu4D8Wf@r0XGKu}$}*b)Vkg6Sdt?* z^OwMTAI2qs@n>A#p#C5Y>LCHtlJr2$z^0{o>RAEQ@(7^flAGNHax++hWAbT@Gx6}> zfgoGYSx@0V3jdAI@LysvrOBX!KdB#ai&ArTy2x%z4jD@ zp*iyy&EeI%l2NNX6-kijbP7%L>Ml8!^PK>5c~U!;!z#O2&V)T=gA`8-wtFMi^aka(L3LwEj(VMy9;lO~LG34iIwu0CxGZNci{x8JDd}3KQqI~u$EN&5b`mqh z8IUoN9a^@cWh=NqK-fJ=%T^n6>7MGDSOkuEY3jUmA+yZh2HCM72~yKZdd9Z*PV?!| zQ#F9+oZpU~vdS)c`eAHRY7Ol&EXgs!sZ0IosQ|{Go_d4&hBT;~1yHlo1NAFuP~Q?j zEldwoH#RLLzTXI-mPP;-movLIK_~+?wOlW%wY;$n97pdbq1a%A*x-I3UQcaAvBAV# z5`l%$$?D-bSeSUzV$0*kWBoY2;j+C+n)ZR3tNC zws2XG1dUU#=MSV~o<10$d_UaIJh93y^YjyJQp$C?3rlk5sbf!g@3Sx>fblm^-k@HR z2K7GzsGbO*;+m(qt!og#i!yqi{HP=^a+m>PB?CnUYK$AGFguiKx6BURpe!q@E=8#y z?ww5$dS6pFQiZL2V**W}jZI$JFpVy)TrZ6jdji^1aYP>okqI(-etp zvCM%nU4s?y(p9|=#&km0e`i%g4VXLuM`pR_mH&C*(*hXem)mh{R@ud|Pr)XoIQD8R z$#LwT%7gLe*xsNvOM^O90QK|qKwTvbsv>}TDm_r2mj?Ad0o4Dc2kK#IPLs&L;#)KQIbOXgk(uyqf&BXg{>i_9IoOqR?o#F8ADy8z$&1WW}m{$$P@)LGJ? z4i!LMk{&2S8r0bWsCPvG6_=tcYmMTnEqB*ZL>E*-qGaV75HXPzis({AmlDZMvJv+p z9^#c98w(3TPq)j$-(kG+9Gh3JC~Sh4VV3hp<2s&6uyQ*(C)U3=fZzPO9W7;*U9|Lj z*rZg9@$*=cqoqgepuR7FdR=;;reo7mJ@sb+)CuW~=rYk|qRT{=I|?T^spNX3lD*CMQ}O-u=KERj za${jOemb}LsrDdu(;iM^yu;#0TidJyUp>gtg?$PzZaX7B7p{$` z#MYLDB-MmcBj*R$&R4bLVXU%?hn;~N62QB}{qDJyA+s*J=u;@hbh5T1hovGI$H04x5N@*u)(mXQDhrd3GYolh}b@ zGd)y~=UjnPOx?Q$=z1Xxp~UPyvj;Pv8w|CN?bv>aPN*OVR^%ur#Q-Sd#0hcclmF zENM`O3ZSk^50oJd>TChj`y+sg>pdMH1dJ;g9go|B9aH2&E$Zy(7%oWdLG8?!4Sox1 z`@O$6g0MYlA#I_eEmXVsT^`ad)O8a(CUoF`KdJ+Cq5KFHP3G6OR>r>U+Ph8Qp#=lI+o--gv_hpy^k*?fbsXGyg|Jv4eBugR6adW zi?C^_p8BT%s*)b4qoqMD#gd%(>gj|z%8V3Shz z@?%(%Gfn>|55}Kac!PRU8q|FPsAnU9iffweEFmieG+QaD`LewQ(YtRcF(N`@#ET$X zvQA{3#<+EojS6+ck)(+wMs$PL3A8|z4dHbrX&5Fk$7T|(3f|F338sN|jn4k{7Xpms za63A|D!b^!!TZS4iG^5_qZ4n(_dbCN0gOML@CJ33G^j%bP?x6%YO6G;vjtG^i2y1t z$60O-ev9M4wwF3wHkQ%g?x0G&N@QnAXTk?7jew9H)xzh2(-I~vVeaBfn7yEW25MD^ z1oF;2KS^lG(r3vs4B@dam{feUy`!GSAM?33z=VFH9rIz8UCihE*rZe-pd1+AB2%x?d z0aRRCW8QYS9n#V1?2^S0ycsSe9>V!=5UZn1_z6$MhKSAhBsO&0;SRm+Fbu7k&LZ}v zf=}2aaOVyTcZ!E}6{doMQ*}Haa3yG(Li^)n1a{L|Q#DFF+a3DO$Nh_&X}^&1 zWN(G-XqW`;aVOC60D>lN}LY0^ibVj#s$sF{|vd$8~H{${xQBOLF%3Zh0{NR@fWV zwbG!r3821}9;h!%gSuV-_1y@d;yQ|E&Y8_zv|6oFBQGjRFX~4iR7aEW?3=g>ag{N| zRT`7)Wj#Mo*0SLaz!MnDlyVJ{xQ$w#`8=KjpEBm{jCtaV(Joj^`0(Qpfg5vYCNqjhBni~uTG4y%{c8r>6;=+$Ufflxh7 zIdNFxuse{$3aR*Ej>Dkz!qH7HB&s{!sIHmS$*ieJLlb1Vy`Ddi4$pm005^GeJD$rb zyLj#c*rZfg^s`u!qm*k7@aMS#7=NDY4eI}-LH$1g)M4p?>cOU^dg_k?sAJLtb$~Re zDOi#d-*FK@#pSu?MjAU-+drh}#R@UqM49de5GyfV$~N^`Zd{71xO3r;mB6w9UdkPI z9y4S`^l685yWn7iN%1ll*820c(vVuyY*p>(mINtO4_Jaxi4(pdz~+6X9e-k#UHs_^ zY*LC96tN^{fWI#f#-BfVgSu53)Vl>xkE93c0clXT37{T}04gq3F%R^ysY)iNmIojm z4z>VW#|?VRoRZ-pB*Q%g;&s#t?>JF#j)HSLFgQn)WxP=qb1y|xNjq94NwR{?kH(_r zuL7*z{q4vKtL!2xdmJcBRywgHM^-d^@3W{Wfbl0Q-k^?@2DO&}YIAy^&XWf9S^?CS z2%zGU6*CFcAuFY?BY9jV3Sh8 znGaz}j_*u(wLjkx!1(hWZ%~g)gZhd9YEpWjUX}*+m;h>81W9M_-8MEkO%9I=kiO2B_eFw6mP7vdeOw zj!jBg&O@;zXE`sB2jg!!y+Ik$pw1FNT@nFQTq9*(1LHX5HBB`%uuny;q#3nsO0Ghd zsv}WL^==R{St_zrJDsI!Dh(mvHq&ZL%OR^0o#S!I`{`ZhKxWvM=mB{@s= ztUMThOXUsfchaC96hJ*60aRQ|wYbHdYK}HCQIH*#sEK+7q)R4>Ow<@RQDOF>9J-d@ z-`TWCp^u8`sr2{j8b)tCX9#V&wl`f1o^KdoCAMj(v#6CxQti(55i>{{U4s=k(v&+; zX`q>kTY#4l4pVLGw-e+ICUW$kzytL)-!hp&|7ZA-Bv$J=hj_uDaX8D_-a@C3dp z{&^1moGO6v=WX7g&XERnv;gW;>4CaX8q|3LsN2&6b)z(>cL<=q6aiFP43|zjPnzN0 z1Jd=h-;~Tr$()qTX>GeX5pDg+@W*<;9^dyi-%rK&)0^*S!OM+>+4yOs%{yZy(;*C3 zCC6g4_h^x05%NfZ9X73Y8pq=60c7y#c8&$B>~bt##3rQz!oR?hoMZ8hRq)=&u@J!c zI~Lxc=3&!Pp#CXWQkYHp=FT5M#gF@hwwnTs<{R6wLRQ(u3LnQNr3l!)Sd!y9D^|mMA66)U z@n?nJp#CKd>X!njRq27+3!9eesR>w;>#4O7K*i-cd$;5+RBKu`pE1y=gJT9=JW3&NsVS5mmmh9^T}y z<7BD*r~o5cZpVFCWf%7u!X~9G`X(&NS@dtqgYoA+-k?4x4e9~`)c4W@b+AWj5r5U#PHXit(?;rtH>nWzs@pRq=L#N{BmwomQ=fS6}mj)nD7%9@4v zVeaM7d^1cY0%gr!G_skIY^euza$XU8?dHN7*hb_ zPvyNq9V88E0hZ+ai<{E}b%r#kwF0Qy(gS5kgL<<7>a*#A8j%LIRRHy05kSRtdS)`` z-`-ZOmQ`|bl5}yt4k9HNhg_Vo=HdukyAa}xGgD(gTu=dRp%nFMLhIX|LQ}%l8(Q3E zcbk)M8ZBje$N8p|cuk4dpuCQNOdMF@I?7DYA#LWV&Bm>7`n3S+KGM!NWtCmN=?mDT z)H2f(Sdw!CKf1=>HxhQbJ>wl)8Yj7D-wB{6Uv1|Uu*xo{V8X$& z{QGHvD{aP_J_}X?7=Ne08`M&1P~BLPX)N%pTPyYl6(+HYRvKuffmRxZ3yX2{b72WvaDo2V zxmFt989)So(9Wq~m0eE7H?c{np#CSYB*))RJ_O$TI28gIf2YD5)X$|seOmyvF+EWK zmIn1J0n}OPf!Yh3mJ(klmgK~DPI{n@l?Jts0P6e*pyGNuOIw2a{Qm!{q7BlvpF|y= zJP4Q^9&&id;UR|y>`@GdC$ZQ*ZTq2ZKbNr6DtDTrV#SrpahqB-5Wok2-Ok}*m0b?c zt=Oa#V;;tm9AiFkExh+}cmy#14v#meZ%Tu@O#rnfJy1_dgZj1r>ag@cbz##|;`^-t z>X`IEy-FI?WGu;zspBGmitF&So^{Zl&nkMoTCLO!Evs19RMSSFBsT(W03nmpLrxDl zJ>>L&`WKv@FlSVnu_{lMJ?>Acd_#aKe5oDRW0hT8?+R>EiYyedBxjeuFAv6_>v@B^ zRT|X01yGNq2kHT7P`3%79*Y1fE`w>kWwWnRF_fxWGxA2hf>)_|i=0lVjBrBbQy^WU zE<|03x)617Qy19;l`ci8AMTyb8~Scj+A6-w9MN=LN5_N?{BKvh-z$t;U}n#|c#vbb z6Fj-K3yBs#m4(gC0f*JP_dRP)q7FmI@$X*+u*zwZ+uUx?D!ZJ4JzgX040K{i4$PNvlZv;?r z-KP01nJ(G9o~aCKwQb}vB^m7f9thS^yu5OxTU&jyF+1~cxH5NR9r`=_14xBTx6yy^>W@|dzi`HNz&cK`QHZ29}4+5wo(*w0q z8q_o_$@SE_2%zFpomaKQbge{QC8JiAOr_kPA5e;Uo%S#$x`*);5VNNOAj(6OhbRwG zp72*_g`qs=_KoJ24MEqZNq*p`0z#7sk)M+Stmxa?ksnssMSd>BCZ%{r9!qj2{b6}9 z{^Z9S)W@Yky-NV~XnLT&D-G&X0;neZ= z!b3^Glmtvkz+fJQ&{`PovWR)Bpr{9xa>dB^=QB)Qr^#7_OYHfKoa6#FPX!piN;}TN zD!Vw#o`=hFmToM`ah3sm@3V?0fbr)n-k^?_2DP^Us+1n6^QA$p6F}(^K*i-O^I8Ko zDlALow`;U0mE@w-g&V#0N53SvxuSDa$jbHr zt9Nlbvcf96$jXT3e1t|R;zl+Z(ALH%7C)K3La zQzC$hOIBLX#@t@kl}t`855Pe&+bd;_E(1t(U1<&o*wHGypF-itZ}w zlu6S*lZG~VjD;)8!bHS&XW;ZTY6=_g!6hPgb9;k*iC|v;ct@J>BUK-Rj0;ums02P<`?$HvZt7-`q-XeRuouVFRX<>)^$VoP3-8{G*b8n{KGyeyaKNp zX4t68lm!bKsTnIR!5QeyuuXq(RNZk{m0)C_PZ8OM^OC0CibQ7U?LFP7xA(Cp`G{$k<#c$myMS1*pj zA@0uxc+Lx3z4#R_H=b2?x$y@cCF{n|!jhaDzvO6m?-K(T!1z1w-k?sE2DMrMwLCpg z6=_g!6hN&=57hglLFodhRq28HoHVHG1W;?!1NE>ps4ohjj!X~KpQS-PB7j<#9;kWP zv{Yp8c>&ak5kSRVS22$);8z+HJzuI8X$N4Ux%8)jXgygA#rC|NEQ;-o<>TNfwr8bV zEr11RD+}KNLWnk{+n3*tC=*`!@m9Y3YGFNE*~kEXfV@H$?yy*Sj{i z?X-B;YOODC)aX>e)|-w*I~>9NI}hYbE;eo38ROe_WS3l$bg?I@eYDKqZkaz~_Dqs; z>MT}=NKoTJP$d#n`_muB!i>t1pxO&cWM32op(qGzPZUG|;~xd_2K6;*P&W#o%ISf6LK@UP0w^OrP_IaX`d0;om=P;o;u=AE1^p_yuBNUJHO zff604l4$b7bs%1f%ur;8A~UXoSteF-3%lp!pkq^F9-ES6WM<+}j^xxXFhg!+#Po;d zkrOA<+9)%A7SrD!z#WV2+(=g0sTE4bSzRSjAlYwPw!bkmbu#q0r5=~|H&ypY>RN6&e!s1-t7wPIeNhKJNE zY+|4>2AeE&d#w2;Hbyd(xxs_NEITC3BD>!yC>%L{-0wz!BXDy&_nTFAx!(_BlT!ZM z=ddK_Dh(bB?|s~F0gS)%+I#>Yp-t<6Kq(Pk~fEtMaDz5u&UPa!LKdjYY5k$*W2DREY^1qY38sWnrVDi7o z|K5rGZ@P+{og^iHM%0d56-q2r(q$C28hPKNo=4oBtrz=R7Hr97CYO1*AoRfwJB2P{ zXmICnnQsUn?{~FxnOS9*%luPpQpyp$8%uIN*E?Ph?|ocm0gS)P><#KAX;6;~psq*{ z)M9K}s;B-XfNG=%>TqdLdtymWeAlK2>P^z1jut?DAU#mqq(Qw^0QHdwpyImB9xK*^ zl_DI4R@9WC40+5+dd#PwY)731K7JO% zJ|4g^e%g-Nv&t@J|0`@#imyI^B{^z%;&JfahuI5Y{F%Kss8^&x{YC(_Aw5uwv1zHE znusO2o;o8vP_L5)wWk2;>P!|o_uYKlBuXgO=nieyMrmkGD3=_3IZm=N`!T+ z5!Q&Yxg^u}Iw7T-Rt?&%8jJx!bs6~*IV0qZ1mBiR%M9$+pu#H?J31PpcKNFkKp_9r z&KY5qUCzi2*rXK2z648h6nnqp;k}PDB7pICM!Z4YEe+}>0o2O$K>bo0)V%_zL(&8F zPiat3380Qh57aVjT53#nU`cLFy)FW%xE_+nA)2O#RPN6YP(VM)fd0uKUhs*RWO7YShmgKsLdzpvvB>SNNN zt`I=YNDtJ#(x5&mfSQ*cs9#8f`i=lPZ3AUJ*dW^>sW}gNAB(LsL|v zQp!{MQleJ|8~_3)Z-=~{vF7b0PolGBBGE*m15dT11%n;2V6Y;9V=Qe)qFH4ZiOxzB zo;P4gjzoV~9*jSU_6Bu{G^m^a>Idn8`iL~B%LPzBNe|S0(x7e;Ks_D-R9wF5k!`Q) z+sYY58`R2l!&Rbm_17R@qN_w##~NLYm=hDUu`u-ca6L@l(7E807DH(<5NqbSX>O^r9rMS0(aEam) z#T{!DH}QyUw+gx=IE(wb2^|wU@V`PG3^`oXS{O8!WDCbN4f~1kvT$%9OQp{OPN4+;sCyu?@v2)XUPKekFh^r3Y#O zHZ9dtuLz*@^gtaY4Qer#125C!_fpV{v6F4)Gwt$-7kQemL8}H z*tAqnJtcse69H6Q<}u$Lt<7bO5|NH1cM2{6!FtYXA{|6Jb|C49k&KYw3G5}~VBV1O zq}%Ax@7IMj~vv&t^Y|7K|-do-5h zDF2i4VEie+H>j=Bpw1CM{VqLFACd-jp#bVn>4Caa8q`MwP|u|Y>TzjMcL|_gjsPmI zbF{$i9F;3oopu%`n#a<43VBDc`+E^Yzg!ofu=PeUHW(r7EhIBe?5Bew0@k^`ozmC` zqxXRFsM2wSf$Y(9z{l=+%3q0+zp`s3HcS9BBOJCl_$^T|ja~$PvLf zPtaL`cLk8gkGFF~SY?+Z@^@@f$`ScFmgF3f%iaL*w*zF{Q}Z`Gjj)P;o`XN93Sj&l z5pPhtW7ATg{vm)GP7l;k(xCRhl3Y(+ogS#Or9r(;0Cin@pe~dKb*=#Fh6teIdPg4T zqF0M0xH*c>MTg0qXgvR8AYM-zNZC%_fn|#4Z!9cC6O#)*k77BLiIyasPE@%^E319Q z;Ek!Y9~ER4BQt}%9_L(=QOk)J*Bfd1rDIeSlrT-gY#*M%g1;?{#xcRooe8ninYyy7 zp$23C1~}C2{R@=G2_~*tAqn{aXNaeR`mdlm@jImgK~DV|t*@ zlLqx#0n{z&fx1i@R7L>x$q1lQa<_-_=M8EaHZ29} zSpn2V>491;4Qdva~fWUgiT6$C11gkoC9#)sqo&%RT9AXyGq`mo|6Xk zr~oRP9;o@)v{X;MD1a)Y2kH=MP>Zl6C%$TWpxz=4>M#M+U<6QcU8OzUu2Qa|8%m#+ zQwQ^v8m%@Zx!Ux0kTCg4cI^bI-uP)~$1Q!OH@x?BaM|#U`bg%S~94BMB2W!h0W% zCxG$ic;28Ml?HXU0BTZtpk9^+^_T!^S_DvWnTy9wX}Vg@8~N>+Q|>KsI`lunZi)FI zTt}r)iVSL?C9t}kXaJo~m;!w+pQ4}6j+E|lC0oP8yFEucZNs;>;S*aN6KrwUivGb(M}2O@xqOIP=H2iml9wq8@q8BNg!4JFe*K)f}{VB5nWWlu{^sombIcoBR9;;rF% z>sVOmhRxU60XoB|{b8yRg_Y#lU_IKvkXkE~U(zmvg!~fnOD-BIyaKV{#;EPe{eA$K zJh+`-!YaG`k}0Rj`XzrBi0$=Q(lfdC>%@SSPI7$gp9mV z%Y#@Iz)FVNF*weeJ{TEiOC9J z{28k^s1v0@trS3wqz5V^4eAX7s1KzF>Rr;H1_V$ajQ}bxWA!+?Yp9ktG|ZDV%)1_l zvU=N>2$c0xAYr1c6qg<2aoI2z#c)SRmGz-2Y(R!1(p977O4jBPQlX=@-LA&?!(%91 zOW|4y*Y2=z?QH>s<<@rOmsNI=->0xisTJ+-Vo8qto_eM~`4zzUlV5L8-Pp7gsHX)` zXQl^gxiqL=EXnoMThjw|qBN*|1yD)^P;trcd={=9;1d$m+JOJou=DUfsvh{$=+TW@ z9d1H1N5xG&))|6@Ti}()RkAsFIEVK^5SSB2f53C!)jEg#hwUHn|0$xt^Bd z(Mcv<4DmwdS&BOzP4_OtcxAIm?lwaIiR#R%CdZ7O(AQ-t0jF(Vm_Rv0g^pC`oIi$; zoB8#Cng4fT=8LD4vbwGbe)b*$ratlzs&%)y_cPEUS%iqg z10Yz>aqLz~D|Sh(Bqnl4=wrdoPVCRpZqIhdtO&af!$cfrG9KfkkhW%CH_brkP(x>b zYg2;OcdrWUlJi9nToUI;hL%)UStn7o-=i`XL^T;rx>D5W=wZIJ1X9w_Lc_KjU_oh>Z|F2IzbxLegdd(qz7t18q_HQsPCi)>Rr;H zHVdHsUwWYaQyNr50QJKNpyEbG7rJ7Fik>f3i*zeSqBk}?2BP(}#pIp)aH3AQdz+_3 zp?wGP&R-7gIgocga#5%wns=tdoI=kq^3Kyd$zbR3Bz_jaY4&XANwCT;Ph#$yWIc(O z1%h=M*7Wft1Tg-dgg2-|r9myklAI?ooF1sNr9mAjfVw(8P!~#rI#&R7T?9~Z`LTJn ztdKd-mp5vvk*{E^i@rtvKrMEUk>sX5+crM>OK9;*{tymu(U@=c@M|4O%skha!NAOLWZBDO*B1#XePmyHy8h)iY6^^C(D{cnkaB)X;5>qBuBEZOb^tXr9mAkfO>Cwpe~RG z^)><2NCZ%ENw&wjsiBpsijjkJGIO+Un&f`u4}*M(W)saOnoTr2HJZI^(XSfAdP}fBGeW@uy$jpk9&&^|%1)fb>A^flW*G)V~B!2SorC zm+6>CfwzPcwOS1>yvbAswc0kKI!RKUBS64Jb;b(Sxo$$ogbw_Vj_0$F=M%Dx!fdFZ zTrr3M(jkB1;`gX+`aLYbcwXL)^RUV;&ZA3P^0#71j`Ms|9*jTd@dkCBG^il~)cxs! z`l>Xj4+^0EI|8VCL6fS#0TY zHvEmYpt&>cAC0|aI%-Vk#{nkugYB3OtL$PrGu|p2vv^*x-{)dYpT#u+j6c)y2DL^S z)Eq3y(XYPrK)p#C)N2G#xd@=*G98bs_;S6ZY^iH?&HwyhI>9o+>55xGyhL<}=+H72 zEo0F#7Ens>iQqn-RP#M~x)NY9KiiJzu*xo?^BHVXYH{X$Sd!xuFUo`QCpzAs9+C!i zy8!By^g#VZ8q^O3P+jNvQ$j&(PEW-pIv&ed`PvpGQ&EeWo}t9}L=)qufq;qX5Y_S4 z@P)Aw6`<9tW~4_xNqwwHZ`aD$*)70k-rJ7qu*xo~a}qWwMRitUNsj7_$b)eVctO1S z!y8my8q|6L)Q8dob(J)zk^t(X5kSSIIvz0{lj@ZF^8>VamE_{pr$D?!bcpB>(V>{m zn271DITRGUqmg19zBMsF$hSmiZ_(LXczp*)0&feTHa}^{NLghUBYg^+lwzdc#gZJD zGu{U8eO4I-F#e3x8&o$oEd}an0o2*)f!a?RR4g#^5AFCDtL)-mw_%e~ROc!z$+3#(B~sD}hl9p^&N z`7l*MY)((br8*w@?5e)4oKdtv4X&Y~Q{L^Q-vlnv?FIP~)1iyTP$vnXu1^otur#Q= z0P4mFpyD!}MebAH)w)qpsyfk}L<2e>2jLRUA(}%phiFb}G$+j2r?Z*n@7GjA;WWOZ zq7vjiU8-qKoVNLRHeEg+{)pRME0gcm09rI>TARz~S!EZS{UtUj#b&>QB{??x#!c|v zCmJPy@n^H%peA6`QlOp^K)oeBQ2R)O>c)~>Pi;yM)ElHh9Uy?pL;w|+VtcHc<|?|O zl(dr4SMR52Vv-4lMG&y3ouPG8S~u;ZofP6}QgoG4gewMiE&f#qu$lX}<6o?@i+_Cr zo0OtD4J^sAioeN&@#kOOpdOS4^=SdrOX-1nMjF(A3!wfT0aRS7<8hUekuPbwp_Zz| zbCTpalg}fb*x{xmq5KKjHBPm6Zl{q5$f;^gvxH z4Js#qx*-CnxP)iEd--%Tq{9=}Ns{Y)3rzOfy} zVU=AJ=NH(d6vg>AmgFeTfeO6$SyL0h_){EjP#xH`6sRW!P;1fy^(tvlU09Oqsly_G zN`d0!GDe9gPLdR79SD{v4rPZ?b{J)crIsDGYf+rn2G~li9mQdlT@+_KHYvp>&c~9R z;eJ3Kj6cQk26dw}sEY+q52Xj{o6?{@DuDWN1W<7)&H{H7r(CJ(bfiI|8SqblWQpSt z$03eG9EUg#EUI}=gfQp1KNestx3%Lqtg?&a%s*e2wB7lm^aXfAlt<{PY#Yr-XvlZk@42Kwww_>N{V@f_wASq|p zisB3gn98f#F&tLe#c;leO-e;^K7b`TGVyPDF#Zh38`LAxpuQ}C>Q?<}m(W9DLA@vq z>SqF|-6DXB%Wyo7ajzCjaAOS};||V7qM@9*AYLLmM0AMgP$*|igmMx)#(gp@1?ZZQ z&jzF!yCXD(<3PjiZ>Axgi0RTNH{Y+v_r1;cQ}O*ycx7~$vnOV-1(z1=61dZtL*YUHe!=fzQaQ~P}fR>G6Yb6N)ObRr9oXUfO;-HP>)N4x=R4{as*H*d1*uWa<(!=;pim8 z(VczdrTLh5+BZS_CTQQpXz!aKFU|21<*$!jj{f4@rvE5klNkI2uz-Fk314f+;8|rC zgFgnFlw$CEV@Zy||ED|{e+KUjN|6S2tN`kZ>4CaL8dOFA^_BEMeOwyUD$503kb(DE@Q-+G>?*!P* zAGYIQtg?%PO~}Y{u%`thz7cEsiT!)f4yca+zTa~g^6UbH#lNDfY!(=y7h-%-_ zQPT9{AJGXQg{(9LP)X2)~M3bZ-x5GAP7l;%Y+6cuzY{?16#-OSvh8v6 zo357gMt-|SJUdCAeED<(|{& ztVV8vmxYh*34i1c`}NpNs%y9u;f(VpPg~vm8A_JsSle>!b6VGRXlxknwIaY?{-YiD zVwGLoD=Tfh-+(1K?)3$EF#g=j8`KrjpmGAJJJSR8X=zaJ7C_w{0aRR?vyVHbsFkzz znp)0iiZ-Z~4JFe*K#V6z#&bW&*|7w~c!=?UspBl)Scz8<<7rYe`K+?BBE2wsQ4&i$ z>;c;`K%2uhhIKB&2y6T=d4D^A=ggSi=Eho9*+ow~G$5T)v8CS%q^p88eU`ihF#hz^ z8`N@XP+eG((+CimCN86#gQkC-LfY=14VnzOOGpF=zxq;UdGQee$MCp@rbQjx27gM5iA z(<(fz!c%mR^N|7-6Vb2XdY}Kw?3Do~bDwtfi&b{fuWw_MQuOQ7SdwEpv-;t^5B(Cr z_|q?MP`{N1^`HQ1L3*I3VAE1P^?L!-9uYvrWjedNnGQ=mVJ@EcV-U+}bi(G75moPl zko`&|ZS9wM_66Az%ORFSEQeT5ax6zo94JhM#s5%xNyr=M*0$y-y0=5Q)D>F zEQ)C$UGka8XCj}8e5T}lCL!xrmJoIWAsqh;^ScEY%rn|CLRQ(u2v5Q$rQ)3{u_VU` zN94gc*1PbGo#?)za2LERc!SDIgIX_u`cQhHu95~-5a*scJPnuNy>l zlB7DH0s#}%A*w@Eho}xw9Sm1`>Vh!AuiFA_W`8@X!z#O|&QsW=6xI1ImgK0;K{m<39p-TmZk> z-j0^C$}U>^c5G6L0cu#1BU^ux2jfpmy+Pe94eBxh)N|>9`j#}Pj|-q)P7l=6(x4s? zKy~CnoIYNKFqRzg#pTK#VZnSQqa#)B&llVJr8q1+2-FK z-Kf(feTidecbZ5>4 zRugqyN5_N?{7*cr*d4)Bxf9^vTWl+`*sz4weLju%Fn(2yU_jiBfG4#l=hvC@*>FMak9iw;SsM}cq^L^hLEvFW_ra7zYQnzPfi&E6&K&s9J306icc1a>AZfK3L(_V0F=p^iyLvLpd zV+5u!rIF7nWps_5!JVM?pV-w#sgp*}0I50zl~;f6P!M@v7{Mj) zYhz&{#IiT$f_NHhoJ|j2WZbXwxb8EvWp%xut_QVQp1v*D!)S>j6Xf_ z2K6~m@4)9pZ}`KYv@ zlH`KQk9Y|OTTycLKo^Br%XTPW>lAh7Q-VRY5KGzZ!)pF3*bfKH`Rjx^FRoy-x-LsF zyC`c3{))fNS%TfMrjMg2Vo7RA#mr8C6>LkQ8KYM8Pa&d{bt5p&stdag<{#Q!7GNZAYBkvI&@QX& zve@TJTkO|kNzP(_N*;{A$KVa>Vrfw43!rXK57aHvpe_|aeJKK{xDKVmZL%73D2dxF zvGN`h+s1znh}F?2{Dh~7Wnz6y`644L3i7PTD`_x^l!8%+SQ59{wYkmL1B~S7+Ho6J z*~M*M#3rTU(!aox9Je{41n+&K5ds*0ZsQGV5jHIa>YoCr_343ntu&~mSd#0hH%0&z zm)p!^5#;_MC0iLP7b|KurEvK<@NABOZw;599q`!SXdSKo14JrZK2v;H3YaGuFwgTc z4kmGApGNcXLdR^~9uxlT^c3@PZ~aoTM5K zp0LjB8h@JjodFu)H-ZKbH8HE}(!}>;i&C2S6Ihbd#1DnQVr!$gns_18!~>e46#G;~ zH&mkz>3gZ1{Pie2o-0#5EYkgkQ!bxi3-|%84Eu5ql4w|ga z%o=|>_^E)|zj9V<2vXF+tgcH3?^BW0!QEJr)4{LC_dekW5sR&flF`B0Jdi>IX>f}1 zh}Xd5IU}W22OkpfR?varGwvzElTm=ESBVS@OwgFu{BX#9lV6`U_q>K&JTo!^EFaVNh+ri5U(>+ zf|V0(VWBN7^2wUZAtAXi7yj&j$rw2(p3*#h?sAAJD)HdF!c;i*Th;qu-~LJ*1fl!A z+t%}*iU~HHxK9M2>?P>v5Lc0z8z`C47>^8q^^Is9FS2 zar4MmdO1;WJ&2~3lo}lIrRtiJ&uV2O-=EjWt4j2+A8nqa&2x0ma3H53 za__|s!|Zchb7(?LzSlArA?4*y^tJ`q!OyfKdaSaG=zR&Bl%g*;U`dWC{97K3Khg6B z^;2n3Ull-gZvl`#>{IBWu%KR&2KBfAYPSfW;?kD`CFl!W+*hgBGIUc!qU2>RNSnwD z-TdkkEnFHoup2YZcuq5zya`^0v50;SF$jdsS6RdyM}jo74=F5P$~%Cpnep3B9xIpOWK%}!kNt{1I*@UT@~`nVxN0 znS9+~OG+(`^FCg3$GBe{U_uXS$9!027xVcVHYpXo_$Zd-n9n5LpZN%2{F#q8s3)XB z-6MdSmL8}MY+9xsB8%jJ7b zu9x-vKv~O<#M$yQrCfvEoklIM1u+y#4fIM4OoDkj*48l(39gz=49p))Xb;Jv0RD1( zJKD)AyJ+W|rODLMSdyci_sWCur=8xQwn~FKM*#IedZ4bC26dqT>Y?;NeN7tFhXhbR zjsPky7v4L73#-LqC8N@v?8)BA{sc(bQFpvAOq(=llLl?l2sGNn#JreTn3UASHfeO0 zb=`SXn9wd=}j z6E--8QM=v~)R|4=PvcI7vEt_?{8pIpqQ+%)T^e^IwkV}>S7Av`nZ$M;qUE24v*rJs7y$VZm+V_qSSZpnnjP}KgNmACncf-Ru zHML+V>g!ZBF~n!J0nNdJ&7Qg_6;}x?0W~`R$ql+|U-Pw*`rO0LKz|IA@%+ zYTrcx&s`E^U_W;p?aMzcY2PHZ?}5CKN&6*Not2wL!T0s@Sg>nx58T+Xe7+&Om8ZzuN*H{9Zu_ z_Jc=Lzh>mD<#9>>CaHhl%}bf|Z<6{qV5&OvYWykSD+A{K?}WK8DqvRErGUSOElMfi zPh&|=0sk-r7F!R+RlsIMX)s?i>S{5~WQWJ#;hb^Os(*hL@Z3FfTLVD$b4Sy^X6ToH zT2jABs^9kVu*_Inp`Kjo+&(7aO-x;8i?{8JfZWGNayG-;;*rb$+ z{vRyKnds$P;k}QOC4lj_58j}bVAE2dUJ*d8hyW_CiSA|Q3+_kEk^xK7fUN;pI&+Yp zHST@(q~2h{gxGB}?(COZSON#S;<5G2!g6Y8b-;}OS*uQT1)5o1mrC3st$p5zB{?ix zLtsfZ?le@((=i{(9`kVt2$R&$B6g1QVvp05cP0AluYTShFy)_aqkdRjm-@LETa+R{ zH)Bao{X7@~OH%5`v?Q5I2~LTn`xFzsSLKHwPEtUmfI5cj;EVe4pC1HF`WMEjZLSdvmeGnx0r_>Zz(t5xW7r$m*|ULaCZLZpO(mC&966Tf?2 zYub;v_|NLPl#nW|gpS3M91F^Yz><^_GVc>Kl~BE$snp=+IYaF$5+h1f8Epa4k}@J? z6s(LY0SaJo8)d}mx|Gouuth1C?0s00Q$}A2fh8$rv>RhYgIX=$zl|c&Nk*ja1!R1 zWk$f`o-A~|{kX1G0jZpo$xO+@Lz0F~Qo}CeWlL**NoJk9rlm87#%j`vf6!}bz&sxk z=DFx^vbru6dp@=(Me){QNsi(Tgur6!oVdy6)0y_kRH|v6?o@?`a>hrijx7f~?=?c- z+s_+K$C`;1_>`n%lT@;A=Y>m3Hc2Jxo|w)o8h={$qJWwHv@p{}Ez9b(ahUFOb!~ui$TU+IJtU z=@Ui}vDjKDuJ$z#DPa1jrVZqEL#w5vepkWMIRm9t{k}Tj!A}%~U_W>?^=qCd((<^Z zf0NX|$M8}n{TrZvuj}ZT(1HIIHbLHBn7rbEIqOWY@u!K83Qz(U3raxb!K|)J6JLZa zO7Y-LSd!Dk?+k&(R!DI*F=t+DT2WK=w0Q7U@NmvJX;sAU33%=iK?e47M^nTc54N6` z^l*}T_(opHq=y6aaA@`GKT(}oHU6~khXQ8)1H#M~wJ)pd(!Nh%i&EP6>sXT0zE6d~ zVr!we+IJp{^;*QRTB)UVs@^m3Y|b!gRldIucf)oZ#l z+snFnnx3wevnhoj*2B{|1Ep2@o)YljdkR9ZA3U1!HA4_Bk4x$|N%eaUFJ)4{Nvhv~ zsp`zD@uz^#4w(Dr2y>!!3%;A><9nvo+=UEN)G zcGxZc7QKv|a!A9q@Nna!35v&iyCkEXVbZOYN(Bj9hZX z$R+o~k}HL^)mye4@$k*1P_Jnhag$O!;B>@q{7C#*c11k}IAs z=u~1=xtNc!(3ygTRXmy!P5D(A%EswyppNK@6=*v5 zNcH&DZNQ`CJ8&>r^&sqZLv!4c(m7qoES4hA4dl7t-+nP1Thy)OYjPKg&EC}P$8a&h zqJbsFd^ew~l^U_SmI2kQuP$dlP1U9Ll$iz7O^Bo`&$W>M6;Bl41828}OS<*Rpbe1&50>gxD!TQwV zZlzvo_PUOWjJ1_jZH?Ur7r|1AUd>f`j)t$-tNrNd#g63Dr)VNfKYE%K)-quyph~Yy z*a0XhWx_hIfZr{dFvS@A(bHz5O5R32T`_8Hc1FF<+o+0S)GMLcDpU91>&L3T!c z)!V466{9ZB&Zz(KHtIITs5fP2)IwD4)%$*<81>fdjM~@RsHG?=QNp{kGwNh-qYhMz zdVh9C)x3>5MKS6lBN#RA5&1i_HH$z%yiNw$ zUcm~1mARkA$*l}1+{lMK$Cd{M4qd88gM1uzAv!))HMb<(s)^>d43$E^#JRUD~q zxhip3XdmC|QLFu&keeL6{(xQG3m92hEoj~1mA-ECm-ueULoLCQmY`L&CDimSuhR0G zT(P;PQETRla5wwvNJt@uuDf zic$AuXVe|uMtw#x>W?EBHEvFducnzSb#sMoyO!(1$p-aOw;j(K40>e$KcHsg@MxHc z`r&h8%BsG&xb;Ejz>4L`)YxF`Rb2Di`8d>Z#5>0Ld6@Jh-<_J$bgtH%lp`;Da&qis z<$UE;{<%uW_t0Z>d;Iq|hkJbCp!km!*5bdzU*(&}T!xZT{Pzm{-IB*tjIqamW}{B` zHtHzFsPnTkYTDbV=O{*9G=fp#qME5@ryHXhSUR>oy*rO{kV^d{%tBoXH5;Rv7}Z!- zU^;iBIb)NsN#E#Rr4^=j_xdIWPqzoTS5{bauir$KUaM<9g_4qc{inY%cK2#F>V9vd z?of={;yk<0SH4hc)VQ8(H@1!f$LEdGnq2f|;K#fcdJjK-+zM(pdb8-wqBomYefSR+ zmpHik!a?4Q71q4j(@>?CH#-m|C2!XDHzsu)+Sw^)qpIFUovavj&Im@0>&^J7vgpkq znUHJcC*#$yLG#S#L7he)7Jb+p_hB1l!9YAjVbzq!l)#z&9fx@Cy>C@5fI}3HHfN#- zFK1S!ZWf_)hzDLcQzUWvX7k>#x&&9M#ZBNDGFs3ReBz${UD28NRF^g}F~|4p+cT=K zbd0dxGiVIT3TtD~8&IX!81%g;DUCs2_iFgvGGVD0V;_T>jk?p@sGAg{UZ0&&|L1Mg zFBPLM&CaOZQMFg~%|}V8`re+MQBU$VYA?m8%d<1;rQSw8RWa%V*%|dJZ=;HeQCE#% z)VRr(UDK%pk!*pCOOc6Z=;S>jQVJHMy>WX>I}uGYqB%yP2NWJ6r(;nf>Gm+m-#UvxHuu-fb&&h4vL?# zYVH+rtUSV4`6j5=I985h>IF#p9TjSa-Z@XXk*ol4zm5lpb&=@ z)}o z7&UH;(my>0ZoSHNy7_LelN?D9!jqyp0Pv%;DqB^}e6}B;^!iL%2z7ty# zq;YjhF81uj*zwCoKR)JGhksnWjGTh4A0NmHYhlg83w#p__bSf%bS!Dfawx{w!y2S^}OtiI@#N({S>2KJc3ceT^NQF2=)eD;+YECwrq|?_#kpCn`9?nOz1&p{%eL zg_UpmvR}B!iZUf>=FGa=oXNIecHzWy0lNxJHn5006$Bq1OZ&D z4KKKSHhQwu$Q7rc$+mK5m*TxsL8sTADOa=HXJZb*l0yj3os03%_Qq-q3ep}YSH-Zo z0HjSd&9n!ea0j@d(6G&eS9Iz$s6vh_S=PMV(Ti?Yx_J zsHN($>p;ksah1*Iu~*8C<9I0h?B~gj*s?`qOMML?`%H9Moe?rqf7icx!HXVmY!jrxXS)IQl6wKb~tYEyquj5=@x zqsGlU@k`Tp^nJm&4WT?R#*#-S9^ysXP~4M8h_j07<*`JHtG^@qk4)_-_Opd zk9iw)sbbVmvoq>eZ=Ir<^ELe?Mp)JAJlg+2vGX>TK9RYy1FrDL)Nxx-?vvYxnlQ zbujcbgS^+y{oRMJ#L?cSXZA#4f7L_D@>l+KAn)L*m9l7nNl_VI}5A!rDmM6@!-ME1x?5<}iNge{>$Yd-Z=Yc|jBwc;p0;81eB zh~TTx6g;UY2GvV8X0p%oVZT>tGpVOV$c)Z~Uqj6j+ebfNcDU1jQP-}I zepq46w=cQa*SFuJ`1aGVq-FG@7-Jv(n2p-s+o-KkQVKYpo1IZ7dmHsQ#i$pJVAQxn zGJf5BIwYHOTY7z|VZEd4R9AqXtlAEhkxS0rR{bK>wP%S)Xo96JnX;CXV{^E!^x)f+1NB=*BGNcwF zv$7gNPI+_DGf`3^$odergbI=QMfYX4D6!L<=&bE@OZB)iaom-Od>SbIprbEOoQ5_L zIcYfr%^7ggMvbiP3#Gdb9ynnDC$X{`C;caC^ooz(fszs@-8h6Tp*V@31;~~sradT9 z(ww2BuR@dXq@+!5w13(Bd0WiG|FS%DolmN6RC0>(t$%hnn6IZPg6dWahg+26n7MP1 z__L`)(bE85#=@FMS@L>ck8%%|mpsbjv7{vppcrFM1DK6Ez}u*;QBpGMh!Kn$Hx2Me zwr(+5Dij@^esRv35cRQ>i&s{Mxy>zDe>@Hv#pdehM)7aM+&;_?$VVS1ugwm(aelxA zn|lhahdFwfN}I-E2mJqpenUJ7{#iY_|NFD>_oe;cx53}H>;Jw3{Bu=xNBpa8s#s6i zY$iGIpeM=4N`g&$GvSY{UdlaFz(cF;amuj{FFY|QPGN<$IORN4={54rqofoP-0E+P zJx(zj^Mj6c6LVH;%(Fi6{EgCf>GlJPdrD!j%SFWlO8&$hi#8CtA7_%t7rH# z>*PBJr$dH`e)tAlx#6ZCI$#Lo9zYHi0@;(5KXY{cmr>5vCQw*ejk5Q6gD+)2q!7_Q zSkf}IRBZ{BtlWi-;?kr^lJ$>d$L~ngZ_I4r zy4(-u5|p_GdouKP2UUN7x($8OmKE0g#`c%^`i(y+e&a|iX&G57#@LggW}^=AHfl$d zl$_cB8^Ne?^NxJIq!d@T@?AV$$n1{eSbwOoK7Py5W9t*4Ie2=s$dLXF$yXz7REK6C z=AYo8fX`Br)UuDPtj3YALycasbp<6QI+_{6mQb-Zp9bm2){%{1rajQ%rQ@;DWzZTt z*(k=>Y>~t;C(dkCI*Q(7Snn}jS5hNv*Nqs%MA(-)2>Z*_dFT-~E3A2sAEHVx?{OVU zO5Woke`D+sw%Mq^dmHr=#i#{u1S2hBzw(7rqsEP}mnjo!JbjHFK8D%jCa^=qa@#_i z@N{gEDE)~t*s4{^mP4;1x5wIBJILS;N|#!!&B|(Qc^Yc;V#`BOQew;J3}H*CSeu_F z(x2&P$?V8W;R5dQg1WPyNqF*747i5~xaSHnMQ7sgOhWj1#g7a-A8Jo*zsSMeKc{{~ z54%}m&5>M=D!m-Zc_=A4lCSt1lSa6jcQYGxv$s+2Q;fQO1f#|cyLmTHb|XcvHdnmb ze?e1-UM>8cotv#!+f4QrE$z1RjZUlCChLLZ6`;7m%YJ*Po=2MX_+vAvsYOsz#bR6D z1{kYp7Z#xJia)0wls5=&v;*t5<_oc7UAfQwofCDn6|1XCIbXngYmMPUWWTx5trmCN zo#{fjf7dYv{NtceGApc&k{|UZ-%;}4l>zB5 zv7}`lNHNAfN;Vty1aG63p`yCn`qWmz_~-yp4L1V$}WF8TB@Aqh78U z^^fd~y3X6EcPmEyUv@_Q%-g6hC`K)O^YFbdOggC0F6FzWTucYem2}W{&=idEoW7qi zPI9m@)G(`xHtHF*vmUu^Ci#W%2bjc~%IK(>n6qO`S62XWd7T!u(UL(iX9q*MxnE5& zXD8yexnEZ?XO}G8pZir6I%j830&U|M`R%$JxxhDbx?Ljeb?Kl&niY8o}E$m zdmHsb#i(PlGiqm4?bZAKt{C;?5sVr)38bEF6;G0ZTPT9uX+Hk8^OK=HcxHlTeY`4t zq&_5?tg>N;Q;}LV`<%u;tZB zES|Rq2lv65JNi-cbRp`@qm=zY@k|-1yN%QI$LFNCL38lrq?nzC?%+F7Jy%F6Iuidn z8^1SE-m4xKY-zz;9IX8;>Ou5TB`d7Cke{GRuekQ}C@Hy+c^lw&%hCeH7`x*z8}(0b zqwZ9US~P-DVS?>)vz;sD3sdY2*<2@I#uZ$~FFUiao-eeU8>)+dNzz|f9kjuZ&MbM# z8P7SDNnE-ixkcko=wFWj@#Obg;P`rEl#thdu ztr-a2amMe+VcX{h;r@&R_fA1^^ZPrXhVizCa?#qrH^1{AwToxwR~p?7`OXB4C=P;= zMRo8&++QX2d<+zVG0L%6_Bi;Fg!VW}fj`go&1_Pt?ctW$-slMldrJGuj*h!R>A1g# zF>BHWZouIzE34%r7F-68yz&vh#&=6&-KAL4l8;br36;|3`Mrcr8XdM9$ZUNil$qfP zWk;yeetshoibP@?cfMfE45yt?9^vT3hYTPTR#qdF)4d7hFqD)C<+(%H5{gjxDb)#~ z)F$$|PGy}nkywqSG6Jc*1gbTX%5n(9g3iCs;V9+Bj*k4K0i?ppYNYZm)aVtZyaFX9 zQhDzXwuB-Tp36x{rC#brR#Dah1sMB$6zVmy%I3r>A9nQQQwFdKE32`}Z&9NctK5c? z606)dge{q{3Wh3$W)Ct3mPyaeFjhIUpY%8j{^`4BWJwPaFGn6R`gIzAg~kx6Xmg^X z2OQo1%mGxy%4$?}^jmzXXgNwsRCFBvz7E?vBo6P#L{AHUJODpVRc#4HMcSyT*R8}u z$H%@+V{9fm3EDzrqRokkp62NNQv;ZYmDQN&Le%IL6jf1DVxrd%VM{0`+MZ1+CPS@4 zrxL><+sy~nEBA!z@;l^V315W4K4;1&y&-0%-U3Y_EhryS7-yz7(M0kFN9Ug&Kt!yp zMnpeCjb21_JxWSMbmtJZgd!q-cW**OrC#O8BjyMd`5s=f-f_mOdk4Q<(tOauh$FMb zI5IohHZYs)5BI9@PmlTXUqicyth8x|M~+rZmulbbAc^w_5Ed(|5!Qik^(CxrP*NhS zL-2RY7*4e%6T)gt_U6o7dL*os)nvcHG0-j|VMW4Pi~j8>2T8nn0AaDR8eyG_8oeT{ z97;-r^_n4U2}M|B?N4v+@RhVk#JSQ<4wJN*;1yWIJNF|Ra;&+tBpXj?6KV^ln?UG8 zttOm-I`t%*xF;2A%6EQYqfgYwwV(c#wFrsDHsTn(BA2eynwj71xo*{ffV77V3I0C~ z|6kvmupe-Ak%MuspzN=2MP-FG`o9fTdeQ&KP*S4*KlvMDUpH?y>RxZ7zNr}Xw-JmQ zcPlDc>Csu+DR*+k3f|CR{;spTerzrT(z;_ROy%3MV;X)KKksecjw({0KlN>NKP9hH z^&ZAQda1;HtAX!8}?}57Z9ID3%Xj6}X-sR}{-yA?ftgJ>tccDfv61o{BB@()O z2wOst5Lt`{2XEHbNiD^gkUyK&-4rKnK0umw>iMNr`|C z$KNeOFx8e&1jLWxN}`|+#6bDEvKDqz9fbWqsO3mMk$xEcJkinRe>Z@BSXqsJUXB{Q z;-8nGq(ncj9>SJT^g~vj)tkjqWS?wNw99IK1XK2=EBm9Ga(z49K$oruEby`S^oqYMP#c@o2}@| z)*m@&VBw?bsdnliQLL;+NxQ$pmy#Y*C~0pjxemI3VRxcxODIYr3&rq|#mGjsO+mhE zn6~bp%1Rcr46`TbKxhh)h&Cr8TIuNgI}IQrR#qdTnl}-xLP;q$T0Mjhqp$H?E4b~gI@!_9K3#9&`MF5%D2pXilkUn2Jz92PEvMq*x4 z1`id+-z@9sO!z<}q>vUi%jIBO85V)EPKgZulzNPnHO|ovi}2vtV70YSoDFAmRM6@4 z%Cc`g`I;ksIhe*$`qmRxSPP~WztcCE`kfL?t;Uj;gpy*6ed~$YsQtW++6pD52yabx zMm@vZsK+WsotvFeXL}oUs$$e@MlfpJO*-2qVarp4T@C?+akz@3O zeqt~jgW*-xUGXDKJ-Esd^;MnQsGTKOfOhLPYG+B$ZPYOsPS&<>v^t8xuow%FGXk8A z`{7nub2u2j$PvJtG$^Y}6CXgkNr8KaFkbQv)$p2LyWsSfXW)}Tm>71koH*P}|W_@RlC zlB@oKzcKbm%WTxgy^VUKV${#FGwM6uMtxE->c2-YYTTeEJq5hbtheUQ?$1pm$9FH( zXpCxNR5P!-U4J5S2bRp-apZj4MoUR(VZL@$V$AWy9N)Z|IN?1wQNM{!c>m53!mJ(? zd9uP<SS-D9;X=f_Uw#0+uNv96{9ZC&ZyUW z8`V^d`oIWAjT;W{L?*m*>q_lrCnowrCi*@OwHia>7!q$9A@PX0qnPN6i9RC<4!OSY zV-6R2;h=Df71qM7-=j*eMBleiQVO@8@E&`(r5Ixmx6DRui>keh`d`JUW3w~rU~i*# zKuPIKJ!J%=#*J)tqmfOoQE0Z?r9wA9QHu-vg6?v8Ce*I6bC0mF4{podVjliiUD{6| zZG)+!O(CH)qW6s3T^>f>Gln`3qsp4YbDAeReCE3bg*vRT7V2DxD!rnLDoRQY{0@I( z?4gd?sE>FXb+Ka953@7sc5kDuR*brH1f#|cb<$l6K3{`t%HL;>sWY zl|LIjq_Lj|aJQoeUqgvkyC#H{)p&QG%YAuw5lTwDdjS4!$>^)LggOr(Jrk)?EH%1u z;ivP2{^1vX9tKtFNhom}6k9pqcNED+XOu|)z*R57p}Jp%ZN(BaaD^T_@F?vP;f{}) z*^+8jHlaJVl?}7y`49(1e}TFSeakZ|toe%;s`QG}{{tl@fAJ1~W9)Id*{Dmsjp`^y zT`_`DmR1-z`HR#TdIwGaI!Ps`fJK9>u6#Mlfnzm&Wf7Y2~|9xye#D-kr8PgqjX_wqX3* zWA}nuHg+}Lzs2C+Klj5=2xbkL91_)M%3*KMu0D9lym`_QlyWR$Twx$*f865$iHY`b zbozTJEozA&R#s!hmwFS>Q&Cc~r96Z!p%O#8u$Vd}pm>Kho<)~E3pJstBMU7DwqIY} zjs2wGe8frhhbs%!9XMl$40* z${}nCOGM0pV~V;QuM=@3sE1!VbTw3Iq?C*(WxTLcxwz=JFpWEEKAOfhS2?=zApcg%7k+N@?Wlb7l9|rkd&b2h?(8nN6K#yl1`s=IHcK z8bCm-tVTe`yw8__c0);tfS!!MuY*(ru64K{IJVlt9}mEfQ&n3+5fGpCN(m^=dd<$P z*U3=Tk%b})CHdx)pgGuj{wV`kh?Uh?=t9)!6$VvNQevSu3}H(s7J4L`drw&?Uo5su zow>4{byJOm-U<~RIVf^a!aeC}E*H96kTi0W8GIYAm$VmA)+W7lnnE zVM)tKOtmEx3oWB5>D9ebuaqk^dkx&wXC~8y^TEtT@MC6484hIaR+^0sTynr^pH)`U zd4 z*2U3SwiI+T)N`buNI?k&eZkS~ZyZ2DtgJ>s^FH89LI15#&>}2p8I7s7grXoNC)91{ z8=Y3O9mitXve5QW)sclF3neVHt)u7PK7fT-S&fBG^Jbw#QBn$oo;!ps8L?2OHv#LV z8><^JBa~@o`Xx}+k%b})B`ow}N6-K902X3pH5PggYV;b8y$U5I7P@i>TQX&#ZmB*; zSV%fF%z3rBp3#;{uE12f?U+<&$#HIC<|hqsT89rh`Y|0>L$ipCwW%|fvX#|A1-}_U zOIKl8jh6lw|LR3ccc7$1OAicTODI}W64fw7gIyeRgp)Saxw3ylJx89|)Okjm`t3VP zNOO=v#Pd)q9A1(S-0JpE>z~qDIJ?C z2b}^H9XTj+P%=7urla4_-_w0`A}gzL&?z8)7_EDd!7u z;y&9cvwNVfBMn6wN@(b}j;_Dw02*RtH5xkbL%uY$4N6KhbO`=#8Iq~CWJE*7DcCO6 z%AH+W8#6)FwK?7)rmDOlyEo$_NhF*k{5)Hj_2wO6sp$;6~ zI_GGppV6ysv`I64YwL6qvS<0u1Y{Wx!U?&-7gt>fb?Zqx@%m>>j(XlE%&+rd=R$9vxC&u6IO%KzZna_hEW3LH!>E&x3q807IUwIpKt76ojM=)yKOD~l<(?YXRu1wC6 z$apTeq%)!S9)LFoudJSh9eIfR*ZE00<@`juQs}_O&E(6b-K>8d<7EFOReZ@{FZWMq zDybs*HpX~!<~Yl5=75tM>E_ITIGE#P%B|YXnXIfvtxx{2FSYKCk`lF^h`(FL_^K^g z1=p2Mp*dY@m*&dM>s(+mJ&+haxLyTy>q$E?xCSPV!F6?4{0vhM%7LzS&8Tz0=`86T zTx;)SZbI!7)or$f20qMiQwgQFD$3Mj>?+3llI?fJpW>j?=TU0c!)8`kA51Y+Kec0QmOBAC%J%Ul=hRxD$uu3OKD&72LXZK`|x#(|(?^`!Q#TvU% z401Q2AeSy6yus0#Cn?=&kt{2#vE75H(TnYVhLRH7{ofF_WE9D^O6^Xi(=E-JGk@kH zv&<|QK9XJX5pQmZk!*})F_hoTB3VK`MmIcUB)bT@oGmfXqtvcPvaGPi?I)p1FK%Cn zk`lL1`5R-8WX(oRcpLQ$#i+&zMum-JNu`^=Y>Z@wk7Ud31 zON?e?G`smlvr9#a4p)5|d&-c(?9C2F-9Xu04`x|mjo#;d)R*4>TcP(ASkf}(rWj)n zX3a+J?rqe3l$3nV$`OnjH<;b6?{lQIY;-vTHa`s?&>jkvYwSibpxtBx+JhY(`h%46 zw1AeC)flgV8odJA(@|0)m(CEjgbHY-o6;*q$jDa8b7c#`oJ`8juRzjzsJYaaL#29> zN{nJ-6g%gm*fG`)Zo>kZN>L1!({3@=qCr^Pz}7NWAA*0)Y{?F$NHxo=2*a)VUFRU` z>!{Pv<78G?^BUKqN-wYRE|iqK#@+tL*yCigQFnS9b)#a`JtG)3Zk)_l{jxDpqfsh! zMKd#h)|l~~8Qz)Q57lbyTQNf3WFzE1IlA(ayp`+?{vk9l`$VtV1gyyl0gG6N2 z&V}>l4U?XX8{+1jwP7Z}bvw!`-UW?(9ZxAScAIdq@o^4{{v~x6dTh)JYyRRqROuBP z7f@327a#IB#vU7+jk?0ysPh%0t{%atabshC1aG?(-PpW&Qeue(ZR&dYQC8l47V6a4 zv0`An$p*%scJ$-FQl`@aV^&rpx(86B7t#FyB_*Q!#}KxJ4U8*|N*rkqn2H)hQ5R)r)GNG=Dk?_3aRj5r9sKYNUb$U@o5tfZ&3TYsfbD6)hCXkH8Z~z4IP@_M zeTF$~Wof$d%N(kVaKsAD&AEM{;{YgVKs}7Q;Q!O`|MfjcD~aSV3#BA-e5<3&?@XCm z8z-@{8d3ikHF^>Cbtoy>^7A2V2{lgQxtCs}R%x6a2}rb(a0K*QsMAP5%ds084_i}0 z@6C^Ze(mV=yAL2BR#qdRl~?-`&=QoC2G-s|)xzPjIC8w>4wR(c{{%P|0YOeBDm|fjHk`SOYL0avhn%owNT%Y zk0Kw*9B{sa10FYkk62lakG_f;z4++EC@JyLH-@k!6d&;uuP7fS%OuPoW_Q)7?@`Up zn|oJ4u<3Q@@9Z7b{C%kENJWu~T{R&gQ{0M==V(O3iMSbtgz+_u0@qzBjig_Qt|~q@;Ao5%EWBc zcfF1Jv|`jeO| z@heBaZ&7B{R&}tl8Zqww314DdijopB9)!PJ#_Osrp@L+-+njI^J9@xO?J;i{Vn^GN zP|uNqf)Caot`u~Hquak?00ptK8U;spbAAmlaMKD*@O z>x;uoT9}tSY0K9~I86TnsL@C^n>yLRU{LDCuW|I^nE{N#%4&@ACDiD}C?7yc$(FAV zVM{1R;R}v2^Y`#1lgk#&+hQL6S2ecV6~0rUW>z_Kv@{2Iuj6Hmy!Q5^;$hP zA;@L$|MkZBW0;ADJsq5TCFOs8;(-;`96-+70XzjIrBL(&e`D+u4`!oY;ce7}V${VW z7!_vXpOES(Kdv7WvuPBc8MT$4TAeY2x8Ur*^yn@wP4HMaXMYV;a- ze;Oqvw)^1_wuB0I`BZqXRm^u`lX?tz2ka6Ze#y-*pi(2L7_%a#UFr{`c-KxUcR4!p z*9VXaE31*p9@qMk$~=^mNaZp3yJZZm+7gOX_!zp_tG6PhNV5{=lP`v+l*d7pMoQVd zDCIy$H~z^0N?~O+N~xkouQ=rtl$0o?IfN~tC}mr=l^hpc<-6UvvSU-~+s^aNW_QMM z{2iO;Km~ge%lLH!9>J(_lXZNB9y?-y9eomA)__rU zfHUXsgL*dhL;Wzg*>_pKaYC4h>Y!@~=E|uj(T8PpIm1TxVfQ*1`k_HSj1|^=*g>E4 z^&H;X(RGD)U3^tMwBb;W z>#$2)NyX^6%rkTW(i6&(?v0;0{Go%E_ZsB5SYgd^E&G(O4UA8zr$M`j z&d%T24Rh>!a^*q2YZPh56Sz9^SZ%=*agVVp`{n9KDJKg?XG!(Q$? zv!Kyorydx4;*d8wo$6rvLkIanR#@|em!e9qL0ktVCAV{fzcF@SXg2CI-bTGuG3tvW z7&Wdh>}Mcb`R-I4#$`W@yA5jD*q`DYT7V2BYsH}kau3FVoIF{&(e~zU{DIup9n}2P zLC%X6)|}T?pZ0ZLzgPUkp;*!~kW-AYJ1?_Q2Y4H`ElNrr^{5ey8rOO4#0PSPd?OCt z*tSIKy*Aq5?RaPlo-S_IL;KBT)m(DVfw3BfT{UOlgYhIsuRnwGqPDS%mDOnRRjAP` zrZ1wT#6Yhb!j@1ArkAXG-l-?%o_^wUtOu&>yaB9S1if=+VLe}HH#cx_yTG55Y1TjC z4Pi(0r(JJ>-(kb?8v#zg_Kt_=SZxyCH#qQ4Dc@e;)hgjWe7RN$N+Ok`JR=K~mk&bu zZU@Tqf}-SU5!juF7a4au)*8KXPf?=_N{wDUsnFwJmsDu=eT$6s`EeO3oaH6ewN;6S&<3Nm|Z4_Ca}DL**2U7DEw<)VxrQ`0cLBBZhl#7^?bPMHo$WE&IIu1LBONc!FjNs%5^LsFs%>L zXFY<6$;s+NP@gl4c>jiW-*=P8K=t+y>(HlK?UBrn9bGr4blu;>>l5dF1Nu)^R&%1e zeg+bTN%th`$G#bw(7_~1SU@mv0ZCA68bQpNcpA zJPRcy`e_bfOIZ48)!UJNf+TUqqn~r21w{H;4#7mwZ9YNiXAyLk(gY4ujWsnS|4cjj z{Hq4=4=bzj&-JL$EBtvEN=p25^ANU#;vb$$M*itewVS=ksa6kXk<0)#zY*0&34(5g zc3^DVF$kJ7LC|98GMzQuRv;SsnxpH#VE_%WvKkF-{aIfcx=*2@9k8Tj6sFn|iiUU& zvehZ(%C-Dt@EqiFfRy$qnuFZcf%ZMhmltS9%O>-!LWr>y9N+z^omnoh>}vAdhQUm2+ABc zO~>>8$SrG{?Xzpme9;=EjyO;CT0oW76!j73I{<%6`S=3xI6k6+F2WA*C78=+Q>%+Q z-FC0gO{U^5hY2{Ap0!QIU1o=PsRQC~gF@Vf&)~oT_^|ccT8SfLywZ;GeGZJLJSOCX zTrx|=G3E;OO2GcFc(64*vJIFQ z?UyCt7J?J*?sk~V9WZyv5N5euUlW>cA8UtsfCJ_;g2JS2w${prM)^cL%A*}9&kBl? z5^a9EQwZKSpJB)ObO+8>mN;9mnl5yGzQB(2c@CVf$Pj0{1(U&{aZcKCmK-=Q4vLdH z&SIzA3=MPI4zufkc}0dWrwZMAXqXq+VZO!z^Xi~5d2Uj~2c3MQQpjWS-kbp$G2q)^ zNBU+5($5D)N=GaCMm__e@3#YeuLJ1Mf&!%-w6i+==<}0ynAbR9F5Ex6n6Hol%rDwu z-sFJ!s0?8?8{tFS@7Q5}%K>x$pfG7PRPJ@cx7wfEao*{`c}7s2G`1}_g2zICu%rCF z1LaFILrRAc9j2gpgb=qO4?={Sw!&L{HJwvy%jvNjjk^Zijz8&#+p{}>fFr^ zbD0C?6&b?pOxA+O?+4mpu5`e>F(^#hYRiQTlD5a#aUSKs`GcT1X{&9P!#mEC?J!Sr zz`Q#sOn$UdZ6aT`a_q=+M$fkce69oFpMwJA^I`}v*A6~1Dccbi9SC<=88VXHN=z>_ z?2I#V9ro-9I}U^g21Ur1F~KOa(J7bm!6%8%w_|*@1LLv-Le^p$*}=(?WoWMUx*Ty7 zeW@Mgn;a;g926zr7Q|{YR}UTsyw48t3J1g&2Zbm#)?6`staGg$<0l*#8yR8@-c)b4 zWBh^xDN%P>cd)Q`5~Jko*l#X)hVvm^=B8XTPwzVSZY4)sI_)Heo&x=h3el}54DD#4FN z7yD}#qp;`M0YAq9_+voROQ-8u#SM4bQU26{^70H&uEQn^S$O-h_mSD> z_jZ)`I8c5mBa|7%fd90k{D%YO&w`@lJrnB^P-5>4-!r$m-Z}tZ0*`D1@M9hqGA!Un z|FzncdcM6j*`VTB*fw(0U1kTniv#TGLBaAtTc-qPRTc%@@b$XV4s|~V)VBnMx+{xr zDb$QS=}~sPPjKMYCa_0tz9-o+KFxvghe0u>Ifr7ip070Amrjff^|^Ma zXE>n#K2xaK#DGOR)CmXF?GFmcz`KiaC}dW8kZmZGAnDMAd$qE`+_7U`?ZEulpqLYO z>a|+UcDDqh@8)E#m7jF1WgNLVzuJ!XRSvvQ35u8Z+)}&UY^PYmJDxY$pJR+a}*F!J-D5Rw_-yG6!q0IPw7Cay#~SJFssT6g$769zFoBK5Mm0#Y&-@pQx2` zwR}d*{c$_&k2zrP7Zf%>cMI#C;jZO)C~2+a5hJV{?O1PcV0~#&tbD>sRBDQBVG<9s7?R*k2VCJI|QH=@UsZJe$SA_t>HS)&ccxL80<7 zE<(j_8+=^!4?D)cIWXQF6eAz`A;wICt0kYej^Y==BiktcyFoGXb+WBeyMx#0!5UfC zKeGY6iyiPI9f1E36fj>Ws{zhv73F?*$on`TA9YyB;K~9SPq_^4gPvdqe7FPfL{Pvy zrCMGCDVus7E=CIGMm4%W6y<@8)`w(Bt7gO-i`7-nfRf_#Y`^6MRtk2pM} zN8+Rmjr;B2e- z^LE77I}l$O6fsX}pfkb^zCDEh`oxD%gEqhyhE{kt9OUmaL~7ZfXx zrm#AB+7Z^JW^m~L;v20){DttyHpE|YL`Y}Lvr-b&OtKk|vP0e30d?n~PAD(D7VTK3>2M|Iw8`kO_*$e%L9qQ>0s22x?%H!lZOoQcfJqVT=L1(m$ zJ#Pn`a{&HmP{4eCTLqj6W3}vf8xFj81;xurTEYuEo642RjH>vRcF5;CAaD7EkS>^4 zF=pl(r5a=PiUv#i~Z z+3|kVf%gSL@vh(l`!w8ubIC-T#_d1ZxZxY@$gguCzc?sz9&ACrc{ZkfumTUv_IHJkvwmww z`)dc<9|uLtL&_9w2gkuys3TVE-|RsD;sE-LBSSi09#G=0cs?~&%&luSV0Bd%3kVl| z!8+hy0FP_~{x<~$%u`hecwO)seWV@WP7Z)qWd$(!6$|^=0j_WW{7hB=gU`?(ZU=a% z1K`(!0^}zRV-wA0jnq@^Adh!|yfY}s2 z^yLnuxu8gSh2{a^fRpq_41r#62YImrWG5&{K5l_sG5KP?n-^0%8FBBs?1V7Z zhLFF=qdaE7k z*Bnrn9v#xF@)g#&u#c_l3*UNwWJmb}2g(&eQS!kV`cpVX29_;i%N;<(BL_>ru><~< z1Msmy0rUG{0I(w*9MRSM)sF802fmjE#n+#0?pJ8|w!82q>o|KpJhF|mr-MS}p+l=y zPqLrkVeV{)xuXN-`k*kmgTWO|d`Im>X(~TmX|}_|eT*IM-VV4|1%=CFB^Egdq+)8_ zig?5hdzc;XAr8D>42qZgnPR8T8Q6+(WZHd-9p#f9C~psnlK0g@vjqukbTr{%o^FS^ z$^rB4pfLGR95&J7ZXVc5n$ansIXl*~99Wkg6EZ;J({2h@ScjOwNVQ?dTXW!D85A#1 zC$Xs*zGf|a8$Q>L^JNa4&kTx_@9yYy+ogOR@`IH&9Ewz#F5$u#_(OQmGj`AyIY7U1 zRzPP})9h?K{`8)C8^{Ls`sOIq#t%5{Zde*oR|A;Ig`D2*V&PN&Vlr2 zL6P!kF-g4Ca}&KXJMuMyiv7AB?pGaf?+FSw*(1ycu2yauF+TjE9pU#K2$w!Fq?_fP zG+*Ky?AURjp>h7&j`MB@&fPM^$qqP;Kjc7p=~yT)+hyJs^YFjw zKewDW?|}0*oV%g=5d3QfM2~B){nzY3zv2M;y`Vso{ZJKHG?#}9Tk${) zxX{XVRPV@me_+S^Uk<$g3W}Fs0a>r)aEV~9RjAkpDI){@l^y8+IDqc@|3ZgDrJMlT zsZWG&zz^7Q{@H=^xS%-so(aIo8ZfKXY?|-Ivrxi`gjM{uLZ@*4^SF?nmCr&zGcI(x!RxeUM_6?rd|FV1e8UJL#KX`-H`|xlA+B{mJToXnzC;Be zPPdA=dOL&g{vtcf3mq_PL1CuhF2ZcJG6DK_JJ7c}fPO4HpzNXsYqK3WuK%zd=m#A@ ze;5>K%075xlojKM9_4d(gr9LBygw*H(lxtTbj`2YVSd>GbLo>px)Hv*K4lBowPl;g2l8xU#wp3T@Z_eFyxV zmD~~kwR8W;F7VG))m`!D)Pw7*%itgDtIOHX-Pq6F;pbT!dK1+>;2)!vTrqOV{jlVj z@FT%>7W{KnHHUvaqW{-h0R34T)U4yeT&{QMkwEHc{&W4EmDG_ zdJG7`8;(WU+)hE&KGir%;#mduVq_!@L3hS!HGa z7yh-X`bYNjPx#lT-2y*Y2i>CIE*4?QPp7KqT1sVKqMCZMMk%(r6h|ahr5|PCtZPG;aY^Zlz z=YQe=B4TB=o_-l>^dh1)C@B%qJBP4E(9gI;#G}7_v0iDw#hy+k8Zr925>TZsgU*e< z&jI+E%EuRgN8?)#vr>fBQkC-BT%i#>3HB*F%xfJm-xL%k&&Mj1Z*Y`%*inAlfpW{I(%@yhW{WGQO6;uo(3SWLJG{Fb@SYtM9v_q8 zy{u_Pc1pF-Q2*Bs^*#sGN1qU~Ci^`zxzqwLa}162Av@B4IglO{6e-^hfE<({ZB;_! z-1bXWm$EfHvib8T1;xo1j}x51o9^y*pvxUV&&U>NC;Y8okF^6mzyY)v6e#y8aO7Bh zvJR(8hi9TE+EE_uK>5m`D0%+`l=*HqUx2CX@Hn4g$N6*z&WnTM=_Bsof!UeBy}%ClH4eC63ksJX8?C@i$83PT61*m1wvf&2SGaq}+R zKWG;&lr0304c~7^`d$apUj{|WCxVM`lwPM>2;F5rX-9aC1L0qTBIMq6x&jMzSrm~$ zO@7gi^Ckz*t)CWhJj1 z{@afApAM`i1jWi5Fgu&8TW@uz;B=U&Tz4vipnsb$TL`Zle-jjH zGR4@;;Yo>^z&zg$^VJTRTbvj&@aJi7#0dGrc4ea14WA9Z)DHAb4xsx710C=!E5p^JIJ3oKz4$H;-ydmTt$nGsUR z zP*Sp`HH0laKh2ircC8TG7%DmJ$0NIi3gdU$7$i7XrHS>x#L zD+W*xE2~k@b*RycdfthW67}3Xge{?{2d4?kaOcSct~H9>lR5X?3UwU0$GBZ~u5i!d zq&H+wK3{Wm_$Le?A68Z)pQT^*C7*j0@_7W7v}~PJZ3#s_{D@9GO*S%5=FGDUDmXIF zoMxT{$-&CTY6>^p+Qre;PaZ%!tgJ>mFZ8CJV^LCyd0sk%EumVGsHvXxmIY%?h2x${M}L3O0PbOBHSYNcYV;a!U5t_v_gpiCEupw4 z8E^69x+D2yPCnN`9UGf;B%g7}CuEv=asTjoV@-u4pU*iud}9Flu(BHY`~x+5k29ORbtC7y{P@@;=+>VkG>HKjBTSAdea!Ee%v!odd){{yPk*oq_9n7F3OmgoAN1Z`RNn||&7qQc=9ekz&g z`FsO@s#;m*<6cAPeMs@&929W<06Jo2H99)x>%Mff3?(HxIv#(wWPVgzLeUYQX@}cs z**!Vd72J`CX69EK-QjrX8Bm|b=BxA2%4$6M-1|6szH4}@2}jJ}ruXy{_sM6lkDz2z zEnGBjo}@|P8d#L95K62rJZjy~XYlG`cLIj0uHSAs$E(YCbB6PFfEADpvR)G*mo#tA zI1`FXmpyC-ZoZTTurkcFu%m*KlAr&szcKbJ2+T%( z*xRU!6r+BWol&=Y8+Dap)LkPORkD9GuWK9dgwW_WP_e1s zmc4BZjjEIbc`~ybv=I$Y%PZaS=ebTwp!D_zdbDa zmBYXO_n@$d71qL{eQ)&*ix#7#6c)AccT4(1F~;uV%|<=b+o+X_QPbHORrNONbj7Hb zk6_feVG*A4RLJ-Oqe=w$0}%NAub8>2!C#$X9EFYp>?hC!Y#jITBkB zTr4VXUF5?BE!qfh5XbkkZ9U&}w4UvPwjMl~2iAEs8x1_y8AtUwxFf8+HqLh7WwfU8 z%WMue|Lxz*;w%Y_Z-=X!I7^bGz{%~*&LqOdO9dorLy(~G$Z|naX#{A`1q?m*-vVQ= zRI&fSUmso0`czn)TUlAPT(zxa3>Fnj<$$XwX1%7RC}*Q(_SDF#x(&=dO3RVP&cZDb z(+r_Hq&?m9Pe;hLoQ7QbEEp@SrF))yn{T>jZL-bT$RM%_GuQRC*Iwt_&ulq*a%>-I}aV&Z9L!SG8aZ-v@4 zMgw}HY4Z%iRW}eKyGOlsb*qK0MJ?{6UR<6uuc}qi*fTC$;0fEtZed&xZ+E<3bCBhs zgB&j_tU2C=xBEKY-zm&}0G6~kUd0%@<24)g7;mGNqNEfJ96W+iu&6xTcH}y5vK?hHl z8-_gij_%fy&mNo07j;+<7>dy2fENzjRR_F7rFvJsL<9Ji>0n~446*VEJ0WNiaArPFLl{50G3k^~ zR{{ZvEo1FsIr~ZP>!A#{kE8#-g)*GBV2hR22yVigOHM{fiQp;sf*^>2#RI@y;aBm8k18YNkdr+2<@0mcq(!N{Y^;&pr^N~l$Ns@k@4xMvZ(CDml zt?-FeHO{ifz*SYqyLMs4sv4)N#!AyGvDw0MZ6c4?dD^%!R@Gdos`N;3 zi{(0{?vT}GpLc6H#_3nmoPj>?#tLgmgHNJLuLR_qQBq18eCV6-yCo~C7-P?hnvMFt zw^5%{jJi5IqyFY?)Q=UTK9!wO%TTpf_5D*Z>bmTVI@a5$N28?Frf$m4sI$C{da`2F zSF$temEK0>6{Bv?&Zzf#8}%B+s5?e5YTP*qejFytBeL_&YLyNiac1rmF_$>X%H*Fw zwHn7;F_&nJHHOJ0ZpYWtciXjG(sI);-48s*-r%yh(CDh_V^Yz7KjJuJ>Y#VQEp7Db z?3ma%w9aa1?W(T;9T9pu_fTm+AEzVQ#|l4k_~Ne*8Y{5E+E`)vw|s-m2bI8J3QJnX z3W_oIv4YvCCRIyXfweyY1cr1+TSeW6bW6y3|{Be0YJJ78-}OH_L@OW6a6g@~30FNko}`Rt5(oVQWiprllNli3+{nzvDhDn`{uFlyX^Az$y$bL-94+Bh;y7kcwSi@L#P zl;rv})N49kkp~rVWH|Q75bson!)oNFn||tmL&F95hB!9#x+llH;(d&%ZPY@Pl&bHe*%|dr zZ=()WjJhT}qnh4Eou(M|+3bvZv$s)Q#i-AZVAQzDF1(_m#4epIm*Akjb}3gYH72`L zaWQFnPM?^TAsI*yS|b-Cf>EAvDiJJCA_;?*Pi$Fy!SYa)8x*Sz{g(>Huq!gz7-rpE|>|{3Ti{3`PUoq;>*%|dKZ==4V z81?rNjOxcu{eR6YZcbDo4(e<;cf-{4pEa*Hv$QaUTV3FU2Kdv;nZ?Pk>GLIp3LIEp zX*TdN7J(AUUr@=+w&FL4tIGJ7-pu?$tA*0ld%%xXd-&sC_;Klmy_v!g|9wxn3&1@t7@|5-@{LUKNs_Okr%>(S`U*PBZ z>R;g}_)T#-V-@|Vz`3x}D3;DiK`h2g4e=U1v$Nrmo&Z;hahTXqAZ{Exv zOtzKpPIb)cc1qOAA{%rKxW9XV23dq?*pu1N=}mOjT2$%%q($(rQEA#gT-qWGqC_L_^iW3c(9~ z0aAK5hN98I*8^=S?|(#sA$?BDE@x#YOIJ5#}AsP+x0G|~GQ`VHWt7NNVSb+xMsUC0q# zoEuXhpc(qT$w0x4CQ+hMX-%zmrJirEWx$ns*IJV-OLX!mFnx8W1UI=Ag;tZbk5R!J zijX&Gb(Nch{pr10zFq069okS=vNX}F^zU9zqb99?qYTl(xj97-^;qasly51xS&<@o zly<{fx2{QRH$sl+I*7KxJn7#C`&OtGqL(204^i|>oW$ze@QQu4SC|Tsw;V>_g5#G~ z34S#2u=vCsXe7A5`W{O$*PD19=6an{J6Fti^SN@fUC*n;sJ+QjjJ)Y61yi%o0V2om zHRyGZ(||e3l6Uf!1uyP@Hf%LY8x<`}lOwtmMk+Szc?fn5EUYn-BuX?MOuqdUVI(R={2bE=Se4?K#QbZ504I<&F4NZ>d z;_)1YO||Bv9vX?Uk1RmSFJs?6d8~Yq?UJvYJSF8gzX-LRUaQq?V@QHlwDOQlQFIA@ zag-qXd3_0KxQU~w<{m_S5gCV$4!AkB1FJfi4AH^sT)d;aCfBJoRV|{<6)B>J`!6BE zGfWu3nOe8-UlwVicVD^waOj&WmCKmjQojFkT9>jU(RU!xS1e6epdWThwQ{ao(gMRh z6{V^;(ad{!im45Yt4g4>R;rh}5PwWHHT9yGJIj!FtR&Vul|NdsoeFztHFR3LRum>$ zX^T(@OsPG!MJUolFZayio3+}dVx`c{Pt;(xHxFYk7CPsdwe&94yyo2_%iDt74wBPPlFfpur z5w%ZHVWO3LMuDj2|Pf=M{Qk02I zqAEr-(YA~6iSTFZnhnkKt8G`4C%UQsfob6m zXjwSMCQ?Kb&lk%w%2yOomn=dw@OCagW}^&6jnNt$jSyYDoe*7}3d|m zH9(~D?TJdaZEAd?25jO)Gw+c^wAEY#Bdq#l-PR*5(nK%kA|i>b3uA~$^&@4k1_3TE$}+K?=s(0{S)S-NSUueY$6o>ezoy`0 zwIoh78?3IhR|DzgYmnViKeW+mS)S-Nvi7e4+=p)?<%6@^9~Lph==nQxI%H=3=ET1g_lB9NIN(Z;@p zF`~)PHd{3~e3vej<&ohy`8q7kDa zcOmi?11EIWUadw6e+=ZNnqTJZ(NCBd~pXniyA1X~}8U>SK zcub^-CLSNkGKys)K9og>hW3A)$>K zN!1A?Zd55Q*3nWShn6Btt#;KaQMGU(qJ@uM z;5Bd_e!eiJe+5a0Btmqg>qNPL0!3OU%Ab?6d>qz)KTe#gLub(v6e+WwVu|4xphuP> zdU)Ny%s-@M8ntG=sDBZWM^c4|9zL5Xi6~!1%w|dwq&%+|cv@)I*|KqU8LX%mDnfMd zdPxNo3q-x7&q-O4Q7iOt$sMc-Xc)dkKRc(25na5m!6|Fp*OX6LqbsBbxd#Bo8fco>*@-Vnzn}QIR9scnhRbidCZSsSwe^ zZR&5nG*_Uo$sk9xahs@=#U?65wD8!G3c%v39JH;9y52{`juvU6_lazdR*{4(PAQKo z=WC^WrzF;JRkTe_2Pc!YzQxI#kM?*oIPYe!txcI6-rn7mc3TWGq|_V(5XmdX)r zYTcsLz`8{tqU8wXOR#sP3+G_50BkLTbhJwC2WVfxR*<}n$FB;qq{gl967lPxV&qMH zt+Tm^aYcw&>+C8*-oSI!W^u8gUa1d}t9BP6Z{chQ>lX5`eQ~WN;t_nVixFL%&xw#? zpx|>NLv(Qe2wNM@Mn|i+UZH_V5Dk2nhj^|SAa;3($E0L`Z2&~FkgA67q4^Op;>W}~ zks_M=YKMyT5*lj_&CsIUHKMyTrEVjsMh=%05Bx^;?QF;1ZR4Jk< z`7V--#TGF-#g`EcyuHE_!~Swa{lkd%s*4d_yuA`3#T?Pvhz!xezs+=|-RqH(O5&awq8-XexK_FqzNEtrrg0L8fULEiVEXh++jx!D)?XD}e zo2n}k5xFEm%JT@6KZQNf%{F){w$f6uT*OocNuqC8_O)Qao4!YF+vI!khlWyk?VVPU zg7d^fQtpx5KX=sG`mK^z;XQZqE;R9#;ryqM26^)zKsZFwfZ36MwTL)q;HeRD8`U)lZX%vJW@<-#T@|pml5M7Rfy=}Jy8-- z3=ut1k|5=I9pTDCmbftwZA2aEVni3OBO;_&BkG9A5FLs=EP~Z4NwX&vBf1oOP-u`n zC_{Ag?P-@-HJKJ_ikd=LvKZ0Sw~05u$;vO2(Z&u)InS0EPpRum}u>{5Gg+cWfTMD7D5GyHg02j zz=ue%ni7-3MzgR}tDMMG?9{c&!bB_g*)SGTD?|8fd}JswRnHe-hdTR0C798N^EX5k zA|8=aBDdAZ6{lboc`J8zNsSWvxh+|UXyNUeT~G$KGYLo7D9A;-mPLpL?tysbJ=ccq z42lBbfg}l1KFO@MOR%R2eki3yd{h?CN!eu1qSA&HbVvzGVZnywRDhIDa_yyajD^LU z8{#=B%h{aK5OyvDZsF^Q4ACLR?ai}cucpC#@#SjGRDzV}jFRfNHUq&Z21%Pf9Ao?G zqmo1)Z(GGuIp3=pKe1?AvIx48B?B@2$@m7GcuJ-n~5noI>0HKMOjA)sPMuKD0H?bqyQIKfkEtKUqLjBhW?*VA44hPB#U!RtkSLT1P#DPDo~UTS?W!)KhJ&Rd z$Ud570<1-pD3xhZ*d{1VSSRXQ*GE+GnM1=DHhes>$i*&ARBL1)Or@VuREbe5QJAiV zK-X4QM@ngg*5Q|q(0nLoMgWCn4F_ilW|SnzyZI+ip0crtJ|GgFNRc9Xc+`+cz{DNw ze%2LHK9d?W>4EJu4qcdh$anN54O1}F3o@qrHCF*jET|ufjc7p?hBC8JX%N| zmUxCVlHmn*?xUhdL>2}~qK~u@@YeM;`W%7MMuZg6!)Y~n8*Ig{ zXuGI{|0FU*2WctwCak?uKq>XiM2H4jPa^zMw5atY#E2%+VvuVUB}zS^1S!vF16WwE zMK)s2C3$Kn2j9prDJ04zPf0mGw+m0$B#L6J$S{b67M4N)o&`&jdT2JNmm71;fR#9J)1hIjaN3}_OqI?)pUXmc?rGRum9iM33^l;H->B2j|%aeXmr|rHv0T8mrYzy!Q1|!NJ;K z>){~V(s2#ZrhIt-0KG?1rF}6jMf50ru-ooT7qq?1S|3crh$f|Vu?&gPEUk4(qC_K) zLDP1_#42St1Yf}^Vo-ymOW(kZbgHi}Y12pZ)-L;~B+;kTsqth3txmZV(Ib5~_O|5s zChOcF!$~EHKB-q#a6rOOgVNNIen13?HpROBSwVxoT3?drqt^9>6m_a~eL(x)-1715(vm}r%Jx`^Tw*di|B%968Mi4NZCSgkf1uyD$B z01(>SsvSf_lLvGP45@6jU++J^LMjJMFeVjclz8=mW`1d zWz*-REVsMYs8t$gyX=-ENO?6wjZRc|Fd}YAJpoTbt)}z7Y9@|3WJ?M`v|Osu9HsI8 zMI{Xh1<}8BL4w$%4KEK zc|IP;h5%dQ)PPEi$Hik(lGi@#bu80kQXpzyks^BdS3n8I*#`hL!dMZ(h`lmuf3$LYCryJ^Wjv#F}RNY}^Km zO*b)GSlF)7Wn#i?=_gmzimNXmA)T_*d-`coZu%# zf>=QN9%R$03bpTX0iuC^fzE1Y-^a&}(gk;EeC#OQY`9xJJSL@S+bhGRC9b+>&q;aO z?#uj~bxXU4r;f5f1ya4KeFmPAvefRzfIh>Xlk&928f#ke%Y{!8jRqe(N_QstArqE1 zi;qcZYI_;(V>dc@sFc(aMC{4R;4@M#ZGSLmD1#|->y_G&cuLBq zkp(=h%k?kfKlVy^L`q4P=8B}*5KHlyqnvD~T8`Ei-`U4aY0#KN%pvz5k~gO91n{ve zlw5sM8&4mT(i|u3(!p=nlAXA)H+@FR$!{&zl**)U<&Q~e8Lb#(CH;z`#fPLMe=isd zUjy$x%5JS=39XxC1K1YuAaQ zL?_SYz{_!M61zeH4grCCVMq%Q**RT|=;Cab2uUm?*e-cO%B1l_`hN0esm-SXq&(*^ zmO0TrgXnANQ&KYNqy3wJ($6RCg{srO7xh2Tnuxigr2U09nw zHI&4SdFV4(`ZTpyluVymO4{FvCD~I_l4DJtX`?}bReDZJCnI+0nnS#-gM2QLuaNII zL?NPw_ii}$N4naOXc4`eiVz)1-ks=3?+Z!4qnKBuiu5*+dNFaES*k&_9Qc;nEoLc8 zCD*YDhE59$98g#iAvjbWT9emxXf2qZVhAtkpEF4BdrJ)xvj!GfVwsrP5cl0cYQBFT zS*kJp!s)#@sT|S9akAUT(wohUbxuWy4$ek+fNzU0_)A=&sH5ZwDZ~3GyNwLrOI|5@ zS^AWeu@-@PZ|z@`kdo0S|&K*ym;b;^HYO$=M0l(7+jA{nE*M1$OeB zl;`aO-dso)*eLBIc|yu0wG3r?(5{+tOqkYH`jC`N^4HxQTmyg|ypo@UP@~Mw^GIGS zyezy}5h9v+t*2MRX*HH27njGO1ku2={a7P7AAmhD-89WNy3{%{GI7R{y8w9ux3RBP z?MuQ&B0)58KG7&j>63y_401#p=e*Kn4!b7Xr3}lF8?aqf%L9v3KdrJvFTe94KMB_i zOyVS#YDao`QraiQjZ_25khk!YTOlsM=vckJP5rcDZpJQ7baMs(VZ7Ho*MjXj>E&uk zvlN+6O@`>12y66RS}{^{hlgVpYLfbL*Bw|#g(7j@o6I-;YFzk(ZOQ? z6u=M0;<4m=2|tlOvy@XSPWUA(2hT_;K04_yVd0-w>-u7JViF|!_~=9v(<6T|k}!)B zofaE0k1n?Zt41bBH1f8Yo{HJO;3w@(!aFH4L<{fxc;+}(70we+;RRI&Z6e;W$P%r5 zeGk9*pxHqG1KkG+T@Ne8S;{tHqL=%LMyHdTT9d;NMQ`$HPf~=4p2V|rs1V)jYQ(oo zK8KJYT6jBw4RUY?a}IhgenB{FMpq_k)htSM^7@bjaS4B|VNfdS!y-$xChJVZIcGLI zMGxs11c^SrYAqGB+L-P}6AEQXqLI%CVlzojem5W%T&qbLGXAS3lvZWJO|)`V z#H~doRl($v7L{9h8wY>ST6M1Pm{nb(jhjV@T|9a*-sUL{3`E;8$`O5ht(Q?wa{?lQ zu}TxoydLP)pd<(vUyzCr9lY-;cX#TUF46Z)fyAkf+B<2|7P1y+e-vND0$i4Zd7! zuwqV0JS4UySxWpO{PZ+ZMXs`Qg158${01I5<~;fO5|Z}LO*w(3`WGe`wvM;-v4l0IbL5ToVi{BqW>8s ziAIiwt#%c{IWA)!p z%op54-%NDymfgQ9h?EzttN)mk<#S7{-LmSIZ{bPNi@Mash%WBgh#GObI+~Px3(-!E zazr1mRXm`TeH#Kx)N1;al;mH8ow%wO6%?*sEn1Cu&fUAUdQy2+4(P zY}Gb3Mf8k>D%rhlT#V@AdF(u#f0t~lNcuvWPvTEV8D8g5hGi_+B#P9F#5W+%9p%~d zgrhurPRjFdDD)Q~kpa{uX%OE~ksvyFTqPtheB>Ji6ZnGLr~uKB%=Ylr`^wi7?VfLM zVc%9OTV{LXawT;wF)vG=lCsFl$y1CN^{gAWT@@iZFup3ok%x-eJiZbSNC`w+&f&Jv zTsdE_)Yue%^09=)(o<4)$K-ANxYwi*U-g9VDy=5c{7vm5Y+hd7QVbMtlAhYiwp4JW zEPqPMVm1R7TH$*OoO=>WdHmRaL`rdMyM-2=1z=$sQ@X@eL=kfu`g`b0cAPpOk!dwRU>?XL5^tSeF~)5Va2UN zg)TJU)|7Ix04dLTMLh1*Cyc&CdQM97F&8{#SeOYK5;5k|q#T-9m^e^VDn&H$3>mzw zsjP|;BbonS*tP7&QAANIU^~G?ynZ0du!xn9h>#FMvP2Ne(ad-zJ*|0V9>|WAMK+F* zTCkw`0T2RKzzSA;1Ut5T3Fp?WTXj!$kJ;Gjx#yg&_v2P|m70j7y}X5RJMOxKt$iyn zq@sROAY!Igli^&>0ZZ#MDR<3JdH_qRIxhnfjjn5OU2I?=Mw}ynAxBXh4uy@qM7x6| zMeVUd80hmA>#?GRI4K{-vU2A_ZgWE+iHTS`R)guw_2po(33Jz!Y&KTQX5yy0Alx-R zDq*&(3kh(T9~L^PG8Fs(Abv_Eak07xyHpYjaVWm{4ualT#204b>bxr@2HK>>Vii(4 zrI^i^N)YK#7%DxaASo1KfVqdOMSL)wP3C=HyLdCPbyOA2vZ|kkL{psJBaS5;+Gueo zVWgzv691ZimBC8-h-v~SnO#AGMFwijgg@v!kI18!H~4+?q|03Zd; zH*sgkJ(`@5mT%5VT#Y}h*qA0qo-*6wPj=#Kna?Y+WA7=nQtQpc)*Q@prpsa^W;s|O zNJD$7jKBnMB6HD8xmwDV2J0^mAW2i(l#C2lT$F<5!RdpMnx2$ez*0?yKVA?2i&fqH z>9^uZKek)uwccVc!MLv;z<_-)FVKJm1Zil$gHMex)bJbot>1|j;%M2CYm(xHO!QVO zJ7g!mmYr-T2bYx{Zzi_p5lW_B^n**ccHvx$sXq+wB{6_Px8us5jbA$$($N@6i#XUV*7)Kzd}?2Dm9!Z3!AMPa)ui^-T|;lnIpqxY zVf6a^FNfZv{>~7bd(uU>BPY0~sr7*YET zJmz=lf=Ee6($jLvXd`Jg5F_pzUUi2A=5fT$UpibMp7xQjVVbzxtmd6fYt~1W5K_@P z28g&d%M`Ra=FP;`-c6{oZ+SM_@5t$8eG>ynL02h4?vxXI8x>~bK_;%H^8E@k#dwe@ zTl8EhWTqGoF~{rO+V|wd48}uDTue5X1(A}L-05(H(`03syqwN>Q?->FhLDDoJacHF zu9jzXXl{5w4|{mIfzRs}b_NhzQge!RhLMa$dg$685Q6wp=hQ*gLpHCJ_|L>lOpUd= z7JIlB>kJ@v47d8Tdgv+K89{t~ySmtV==Syu=wYkt?-q6j5L^9maNzY&bqoS`m|BS^ zr52vHcwa~^Yi`=6rL6>!isl&npy~Jn$G03aGcm;zHw`CCXQq7o@J`7eiuec8Y)>rz#&J2>1Kttf7UsP!a~)-kyZ{BR!0s=`A~TnDalB| zIW=*@T=s&y#L`x#4@hd-uZ}D1Bb1iT3E0|bun|W`dFFS;3W#eXZItJ%#EpAHbl=); zCEGNY<;9%V&PE@Cp-4wZc^QE=pnHRo_3b5$l;RE|2?tJOl8Vz6vJi#PW)$gYFCWfL zL*8kN?~>Dcz6>C?_8aNcwdD463fA5;=#WZUfGx6>R1%0(G)43^xBxS+^18rSiWDf) z(J`%aJ`8YA+Oy83GS(k1>wTt815K+(ywi;PaX0PQ7hkwh!y0zmJYy zw#_Mysol@vB6!(WUwm@3Z{EZ<-pV8HSJ=fldA<+3t^`-F?;IU{wGHsscHzh++)P$$U7P;A4J)+(nBf-`QTZ_4m-No;LTl>uR>V zI>+5{I47rV-WxpK;4Ig92-wADb#>i-i-`RIbo0(&K74VFWhVtpV5uHAr`k%++vfP= zAiZl}we?RT|G54c|LR}x=XHD2j$XITT_lZ$0O7rUl%A@m^^br(^u*@vPeVFBIH3Ex z(>>WvhMRHK)_>r~Ua_;!0^-31uJCI+Vf@o+QNZfIf?)H(#r3Yjh>n8vy4^Q#4VSBB zPUDcUF?Da+`d6^)-+~05Bycf=coO9(f73Si&^^fY@aKqx6o&M}qY7!)oZ`F2-8>of zF`95H;{Ga|!lRmwF&9n-dC;Fv z_~stQZCn3~Bx~+J!F}m+B9kz-3Txh9ZDzO!5Bsu%{9wPC;dRYD9Q?Z;$nu^%o#9x# NFqy-i4GGNX{69|~6D;lOf3v2r)+40|+EUAs`~Y%w(n~-Iv+y?je96pdv1f z>$o94+;|}Fd@70yKE?I9E05=b_;Ba(xhv{Z`Ks!y_jcWT>fY%N`YAu-%yd`PspWsp zsdMi+r>>dv>K%8OwFCawTG*JZ*2XVeF*rOtJ~3QrOtDrhwGK`>1V>1yCHqEHriOB1L0Cb8NYO_vZCH-PET#A?%diL zBn)n?4^CFCcfh;_eSOxrzCN-JXy-PX^@;JV9$|F}8V+C0-c-2^9b|Q0QJubSnw(vo zQ=MClsz*(28LaLOZmI4G9E;%JKJafp_;CliRF?wL5ecG$2MwJscF<>fT=lT( z;_9Ji?*z=s2m4npo2(2qH-ir=;G3b!@a8R-Zzj)OHC;WSx@)7gFG~U*2ZDov0336; z0t&cdKkc$;xK;2PIGz?<8_`<&e#Mh&V~**)TUuCe6t&Vv$;_N3^%9h6_2KMOl`aw zv8_eDLlfhTW(2sK8fsDmfV6LTsq*~}t-X>`H&eeby&QtKGE;P}WK?)>BYN{CmCLtH z)Q2}WFP}{4y%PvGAfVq}yfJXwvg6&_@e*)ix&urB)3X#4VY-K+ZXLIo!sR<|R%Duo z-;#~LFsJcZ+uGZH0o(S@TW`V`W0J!1}ESUwu?kED zqcs>-Jx}eIi!$3QEWgjY4-b8EGvaf1>t~HmpLq^38+7QulCJzr+Ci;Zm$bX`9x(e8 zfWzzUc$fpad($GTuWAE10u2Rz+6u&31$wtp*8G{&_6KdEzt$$YkgmUK6PT^*4y|1$ zE91j3er~=DrWMc8Ftg$O_pikuOyNM$dz2M~YHl69()t z4r<)h1~(5whVVl`n3{jG+d-z*0!XqqPgd$DP#@7=Qs^!crQXf4wH{C|I;a>my_<+*Y^}N=QK=y-e(4(_!X!)j!XTm z9!Hk~+^c{n4;82bq~!6-1au}}-3454@>Q2XA22Y$&t(Gxsypo5nm1a5>2q+@3s8KU zvm$FQOm?AnhBb|EN1;*tZ(-7^F=~Nl)F$KO0DKaucXgn32&GJugUxD#&$su|`L<7z zn`>8+n)Fs<^FeEcO?rK4fn0jhvM*=Zb2FLV>ZO)FKP!&^3j>h75PELgEC^X~{7uV5 ziSeGoge3m4?FZ8_Bw0b9&LeC5O!mH7Da!H`6dbAKX9mI=YaUP3~6umebqY> z!=xG6A$jG@`mi-Ckf`2m3A1`44mZ6nsjGfYk3U@M886zA8G6`!F5aC;Md@dJ7$=sG zu@-BS(CUx0zHIgx_j8hGuJDsMv3Ux|_>jxQqFnB|foqe;*jXH@mpAyir=H+U@=3{F zBI(=+!m^Ui_)st_UTkcOkAUAGne4S6VCoqE3H}eVM|Pz2Gsi-h8RKls4Z)L)R*)&i zC&C{ZIc=%pvl-FxlYt>U#OYko=xv9R_#97qI$wMtBc0C|wcKRhl34X}DPz1V*MJv& zGqyn1$c!!7ts!4L29~L8F&>9s;|a7hioc3KXmT*)yh{z^|9~%5b{IF1rwRX;813TA z;FCluxI4)F5`3t#!T1XJHPw5<`JWY_Q$Uz}lE&qyfbmP9QR*FW3xB%{+#26te|stX zHq&(P6ChH9FgxA*WFVX--TSzJ&SXY=d6|(s-HYD=Hk&ZS_c`UW=9c6n`K_>mCd<1w zOlq^dy**oImgNmK>!X1z&nKCAmgh?=k>&a9oyzj&>|{DJn|SeA-Ym;Rz5f7dmbaJX zV;kc~bEdI$mghT$&+^(SOqQ4UCJEppK;5>57e50Z#*pS`d5l?)RhD-$qkNT5nvN$@ zS(bMWCzg+~7Awv2F6Jc9T;UogHc#OWWO-L`ZSok~#*upSe4#AwN)R@)EN=-&@Upx_ zKT2eIMKE(CXJc*%#97{LjOg4fPwOqq@;<;w&&cwW++=DJ&hnnXHQ+_x&+^*Gmh9H@ zvb?|Gl<%@U80Wn#?+@^0!7Oh-$nyTAWln7=ndKP)I?Ds4lExLw@_qttRaqYW)`=|d z|ANS1miLQ5I8B!KKLR?FQKq+8 zn(3Wn`3huuOk*z7+p|5G=~OS1q`$>|l}z@|<-o~L#OE-i`N@ze#*uo{eW7IU?I3Js$=)WA z0LdOdUM8}=A~E+#M$1xjOg5KPwOqq_8w%UXJmUyZZbs)XL}=D177(3Y_ENA z$!;w#+v|fiy=)K0dN12M0=_Jm?M0C7EzvSdXM09~&h|j5q;bWvy+w0Ownx8pBHKFv zL;d7%2*?{S#lqf?P>Bg?CVoH>HU!I9j@E=m=cjMp}>3G z%^2gNdEYZE6Xkt<(!6iX@)gMYn8sY*w}=aCI`hjR>TmI1CbPe*Ik56G^RpS!{Opgh z&t-r6=Lfp#-stX|fhlr^|4KLi73muo{WB84*Al5L0lbY9%g^OXYzOkG4|8quQTrfA z>P@JH@~Mx2u$kpk*MbDdr?SSQL`GF43g6<)%#DILqxuOWIya-zVHP*=+io{7Yi|22 zEU>`eG^$2%HT?9$PJMc|klL@c8`Dfia;RLC%xJ>N;j0)&`CNW-*gp1Tx0aV2J`LLR zl0%pfyyWm)__APf*bB+wCM~mca%cqTXyRdofBUpd#{qy}LA9 zYO*)Ilj|aUdUG2?nxB+1*1M#1Wm$N*Y}J3_szIz0)%?6~_cZp+T-*Ld(pmq(cpzie z{TxT?4Y-AJ!7qWZndO4-1__W0hKHO)R(KB?A5uLkw z(D4;FQ0sOBmzHb5TmST=x*MKb@jgnz@_9^i86&cCRk`6Io6BDZwNH2Xd|4Y`pAP`` z)4ZOI6I-nJS$ieYYl=6q_xO0(JJdn(pA=xmXB?W zpJtiH+$w8fDu620bjc_GeSfR%^CV=~fTI4uOt0JcglH8*n!j*j3~~#n{c;2AJ~blGr-eCLgm2j?|kd3a#IoAgo{#n>y~a79_y> zjTvnc3$`KwcqM0HZUDqt=9?JNxoND9u(*MDb-RJP$~EAnv2*lfpiW-vzmh}9XPHJa zl2_%RWX2U<+pgyt@IdS*ukAxlc58VL@pp$dz2p@JelL051->kpysm}GWPz4hI(an$ zbn*&HC5yAL=yEAKt$6rCe5S>Y0kM~j}m%PFueSYp> zbH06@@>x?(68QUv4KeB7-eFRk?w#n_Qa0W59^qpLc8_B>)A9LK_Lq2`#?hBe1~<0n zbM2~7VneMqqoHC?@6QR#SC3~4h%b;*o`#4i`r!U#%S0*VI%!IIp5-f$QZkLXl+t?= z&j&qu4UmXD@!+17n(RXru4C}I%pgOWpMNseyZm!m31qm(s|ymSRk>(>YPXBWp_2Fh zR^qdyW1i1gn=z|i%aMBXW1%GP1t4r@N#0hFkbX$dA|a9UT}4L7lJ2*02J<e6*eQwL=%X&(G zJOJ2R=s-H+Ep*nvmjxF(r@%sIt(IAOp<@K-g$^i{G_Ke}XB^_D7CQ7>Cl)$Q5NYs| zc^lcK9A3P!$vma63+T*3=QM9|;1)W2=%@51&1Kg&FL64jvX|s6ctcnnv#fbhnA9$7 z@Vemkd(=uin}3V5BX{~tTJ^TDs>Z4}g-NYdXL?qZU926Me6;IUNa?Ls2d1CWd!%KT zXlLaup+EsIYc0AuJ2O{wVaWv+W?w~!6kV8o(K6A(3@)^mWuxD-d<7O}Ok-|gwtprd z(og+El>Mz7iev}*C5L)G>3WzU&0mQz=KkHR#1`(tq+q;bcI8OD5x>w%Y!47tFdI!h zZvQpJ307jc!$u-AolpA9VBgQ#%4eoptZWf>JSUfTx00Jo4Z@4C*~-YSEW*y`l;;;= zPgQD&7GYaBvAnO9*bXeh8eE%v940x^vap{5VFh7-6tc)sUc~dS;7rT)ym)zZGb1{8 z{iQ=IZs48WZs5b^8YsK|`V7-t#`;USs@%ws&E>DZ+Gn(UzO41v=WO<1vJP+k^(pwW z;QDJltiL|3WtLul839#Qhy+rhq;bX8Uw?$Ssr48A)`|7kqaZT4{+hKbGjV&vl39QK zg~L^f&aA&Sdij3A_18Y2j@CJM{k30MZL?BY6ehJRm8Y_rmso!-cXkw5fAxn|HC7!J zCbd@Cf-R7(?_w@sZ0(AbjA|1@%~4awDD!Ul>Ork}M2Q87;Ck>LD71@@Y3$5}eUo{B%X zNA{X5qrW}FSOfZ&U0mao7Pmubu`akCud)(9`eHr2Kh zhSb)`tFT{`1&lqVYy;*!?v$yzQ98U&rddRJ@KwJEFRg(8O_h+*< zR+*S;ZXPq{0tZx}f+8nR?78ZR`Zf4Joj4;WCWpe`1wgLXF!67&XQ}jl#KU?b)!9%P z+XA&9+q>nQ1-4tx(?qF0IS(i#eR3xOo#~U$_VnDjwQ$&u8&H)eQKL*%5$J^yj!+iK z3@${p8A`H@dHuKbl7Ru$IR^%MHbT`Os+$yHZ-t#ml}faBXf0N=Svyb}pBhsI{c01N z6-y&}63yc7gA)d#!SP{^X>fR~HlE^3e0IV>kIn#~@Fe732`zh^mPC|1e7@90W3JLH z6^x_8PByvs5&`KE*q(yUb6{9Kj99?gP!P#D+jFrl>EM8M^<(U3?Pj>`hEv43F5`Q! z_*Aku@rBUOnu$=N3+nEi`0NB#&MDd9 zE^~3(*TpHp=d_|wUBNiIH@*lyl?CcjhMx^oJOY$CuNj0f8b!?}P?S2$m9!1l$?XwI zCXT*#NN)yl95GG`Sc3>X0ch;tk}Ens6iMB9bP!38Bluw-2&@|zpri{%`Ew@Vl8C9v z$%%TiGQ5@+x=@04I2xI#!?-^-h66a!M!l7-YoqhdSidYf{rvMzTdK$B_()&y&Q>tf zpWlUwss22NM5a*j9?~?~fm41nJ@p*|Qg2+o7F>5LvBW3B595cnvG@t4y+P(eC!B!< zo4CZE1sy@-Plt`PI6@0Q8KyTlQqBwRXECDcx?6zQ#Q9Ce9p#4!i7FOPZ z0X2`q^ac#dNHG{tdOjGAZ3Dxxg~0$a7%<#`&TwEjHU);435?cYc!_}21H%nq^!3D2 z2n-o^XMiD#+JWI#v_Fb(2`g{GfSSK0OmD!Tj1+?brDuWR^nn5MlnnrJKGar+;Q(Ko z;FGvY115(F`)29^+hu{`84`T;bgwiA%&IC z3Vfom@+kqShn1IuPwpm`e5|Y~>k@&X*99zah;@%>>FEuzrAZ-?m(qLeGdh(hUE zh&o|l0I`#aCVYHb5J@ogD3J_`{(`>IqYVkARDvDLA&-0(;MU{7l@IA(zB4W(hV5+d>;_BLBAj{cxl!L z#~U~V!Pi@xRW@neJuQU+&2i`!1)5#W(1T5;!1H*48#H*16_9%1c@4OspIGw2b7;T= z1}8x}2Z@bnJG`S0D{LWw+MX4rH;_<6Kbzwzq=uyk(hUrb{ zl|karqx7uMub}nD%A+Cf$#i_>(O73mJ?O%vOKqe!#AhJza0}l|fe0q}x1cjr@aGU! zD)P4qtk#i#tANyt{7qo>&BT%)`Ns+DHV6>WIwahU#z*nT!irlYpw@SV=?xN;fnp?} z^Z*iIdPpN-WkDo>2nGrFqcc1ttV|){0fE&T3EvTrdPuk#tiF#}iXnlsI|~UctwX{i zXnYj^F08mk0&4y1Fug&7GEj^Jlpa7r`-6;?@Fb(qm;fReB<#I=5(&qokgzX&AIPK3 zQ?0!Oq#hF90#+|1mSRZY?9M_0OY4x(kH$yw^049-38-~nnBE{k87M{qN)I5R{VB#u zSfCd|0{;+W13JSS6VgvHHVUlPW5U@2QV$8YfYoOZOEDyHc4r}hrFBTyipEEAC9Jqb z0&2Y_OmC2&3=|^)r3a9(s(p4?RS*dvf*BL8LuYtMSd|(Rt`}IXk?=eLsfUEy!0M}s zr5F-8yR(qM(mEvEjK)Xt8^elQB%szehUpCwl!0O-p!5I|j%!E4aRre8A{Zom44vU2 z;kXnM?iN_Bk?;`#sfUDjfYo;rOEDyHc4r}hrFBTS4~>uFd&7!bB%sz`57QeYChYKLUxCg&A7f6Q(yXQ%(`X45eqm>|A)0PMbjiV&_$w(Zo3Jz?dAZ z;AUWaa^9>~%$|%Tjp)>;o))cp+QxI&MMuM@wfelPfF}op|`L z^tj1OEMI}+CQM`QxJkCN+<}wJuvIk>u;g}-r5$~51nRaC_V%_*q~8c|d_6;&f8?ay zmTVyB9XYwwI?@EdZ8nRa1z#3Ca&jkF)6gVfdG101sh1kx2T|FDSn^ZjzyHG|OO=&7z#wm+)RDs^t3a-v$0UbIRx|M_azf!4 zhTq@IZjX|5{Dgw4aFKCf1aYK1oPS`1i$doPj9lnqAv`d05#!Dx;kba|-#+089T;&D zNv3_icK(48q(3rXjdx%~4H~(k{R1N?eLhJ~4&0B;fsq?P6WwRo10ydJ_(4C4c!_}2 z8*jf2ez;!w;qT$V$gSuo*drP?(mr-T3*Qo^H;)~ZGsHMT>4>B4bztPv*p^zQ%;64< zd{$toM#`rIq#jc42TSiJmi(DH^FWAJJM(*+NyZPLk+5$wte}lDYWM9hy@|3iL>y(5 zo)zV89~k)yIzvUAJ23L7z-S%t{}qsW0slT2{Rpw-2V8grMB5;wc3{|dF9O5f@FS3N zS}>sIdxq%^7?hD>Frf4tFsQ>GsU0`4g`gt`Mvg;gXfQAbMjkIPT7%(O0jURuAAr&Q z#1a5Qa_?1!-R7zE5i)8AhK*=HY{CpHZ^3|?pB1JzU{FSi!GO~9!O*_dBI76o`wl~$ z9^&^}jG;3e7}8rUCIm)nFkB)a^}z6BFnTMo6aqtr-5FrWqIO`o9_@#1nPKHE7*O-) zhUpC$l#yaEp!6&-Jcb8GZb3gOoMassxmDm3jg_|wNIk6l4197kvE*Z={CN*;T6qBu zQFo)KV0&lSM2jf2@2)VtL6mZZ7*Qxa3sKwoz{vgR8$H@E2Sy$c_&_7*I|5Pn@E)XLJrDq{$`yCkBdyxfA-hq*Q zfh>^Rndgan2}nKg`~uvtkXZ7;6Fdl_aT26+kmyI-VP9xiVG9Y=wl7R?AfXHsLjt8| zL87|{MmC@;^bC}7U}U4fY(0LQEgt$i+y3;kBK7dC>16}6#9 zEw_Z}P3VAF#z{vFit99g`Cm{7A|2weyYGTQcyyy^!HbF$| zkZ>~^4;w+lid!V0);EUf4HA@rVkDsS01~=(VB}-y3=awE10#0}tky{Qh=9~X!XLou zJBg(j64*l^8AxDh9TM(C<6$FcSaFL4)cWgTdV>UIpcn}#J%EI+9T@o?I>SRk`oPE| z0;@F=ej_0Dknq1?^)HB}7!ue+AQ?ztX&n+4?oCKo06zjrk3|A%-4muaNKgifk$}Li)hSR)N(T2}1%>hlCBYW`Wt8iKiG8*i#@G zP+(~t6s|_=qxh<@<^~E%?JL3z1`EnUDHfFY02sP!bJsVa+WVNbNhq3O)}$gEZw8 zG15qU7Sc{tcQ9gJdM^%Ddgq=_Ru{tefke(cz1l@U>Y=I!Q8kZv@=>*>tT)Wdm+}G}mX@HOqWFlgjTTE} z;NmcY!IJWY7)vBR3rposAuV5-aSn;RS?CnfY3MUGZ1Ja%&JZ|94_T)QNIh^ZL~xx* zJo(@Xo*hb_(c-;hfOdM(gGd?T9PBou3#0g%Ve2jI7NF@Dg&7R&l$XS?BhNb6<@0s+ zFw#<0LUd}&SgpBP-QH}D9j&HQNh4F^LwL*%3g8@K%F6Q8`~f9AP=cqWDrVEF-v3;U z%?GWgyZW!Z8u+`~#=lg7$enY#Fx1kF z8Y)nD_BDvX>|;{TZ95+{1ps`dWkRQJSTsv|PU>xzvA{Vgt~Ga1O4Ukg@bOY^w8sOp1USL6>>-NBINAFAREcSUH|%n%~3oakHyYBdK`FSXraC-~fqe)N0N z_OCMrRe8XCnMh@&o4(J9l{tJ7Czf}(5}T+a zp+-@!LMD3@QQO6SmyFU8oHl%v7IUQDnYNs&0`Y-xdcm*a5HA5?1*^EGiWh$f!Vje( zLX*=ArUx5aaKHGY0GT3jI*l_oH%{WhtLHJIb1S=QyS_7FokJYP2>n;mj4S14T+We}1?O`>SV3@}j4Xw)I7J%E#*7;|>v$|G zv9TD7w=tq~v8eTSSTySqGnlFzEH#*ZfN3TJk*a}mh|K0PGslPcgespgt2pmVVGL5~ zoXyO<1Jo~qZ;KtE-mnKQI9{Tq@+YWWp`;b(Q5qHvMyppX-vSRWFsFw{7gStwVrpv@ zE}4d^Qs#yX)76Ty**+QnHv|#%djNlAC$V0y^UmpP*b7bju4WBA2Du#O3(phkC^%)l z$v_n=H2iyLU7ZG}-?-D@X4&Gryjx%2QwHl$;{l3pF{RG_j27wViHRMK4-dNZ}6wOngVbVJZRcCFrd;-cp`RsZL|WH@-&9(waF&bshEJiTw~&i-;%x;lv^NR-4Wd zBC~eItI%jDI1$#@K29KI`@;<8ae}fdiTKnpIPa|51`@xA@mbE z!5}ec;4M3i$~gZt^l<{Y3|!7djGOxdl!2}hd*zS9r6o+2RiaC9KzXua}X?g6($ z^8I9S6d<#9#iQsAs8tcx*W!qj-5O>vI8t_raYW(~N8DkxGY19|sU9F_<0L*P8XS#A zYL(GpL`=N`rHV|bxVh;O^DzRR#JZq}bXs$3|D8uT2@E!C-6n_hU z6wcii^Tzb_^_@#Sy}bhL&#)ck__>NE<@5g$_!6()_=$kd`228Q%^U1kY%i{D4mPJ6 zSYl-m2PnE8F4{KOfIo&RwM(H)Q!f;E?O_T+Hi&bx8tGJdSO23E29{#wFL)QRt=6nY za1kON=fkV(Ag=XoaOI&2XD{3~u%@h9&XY5c0j~XP3JZz#dTUh~>zUDd=lv}b_Ho59 zeWy8lXxQEb7}CjNk*f{nG5mhk)V-S~R2}++Y3j)n6`$O2B+eS>ba;N>-#RRe6x(|x z#7sbQ$5uPuqgrMmQTlSb#q>TY@FHnn{URw%R`w0jg$KYg5!WRdjjJUKy&N(%*7YA$ zZIgc2_0{QjC_av*_RQ~iaMt_%Snv0hNBe)Q^#AZ#Rwj5>`DDkLKg>CYWznS*wc)4_ z|2E(GwNuRZ<}*X%?mneYvfqMTxPP9v?CTB4?*3t&Rp3qDSvag^Po(^dnbR#3Jug}= zev@~hWi0R}k891n$=jRlG%DF}5BKt@`db;_+Hs4<^Ozft`Bw}h3~ByLJI+S?((XdM zH0htfhBU0V>RywXM>Lq86#)DTnAl{ze|#>H${uY`b7J{N+ghvxXYTvQw{U`a*eSu; zvnBuj@j1#$=h$7mp_BSiZz7|D&VUKAQ-3zno9tfwk?c7imz(erj?{Y+Tj=H7CqP)i z_aCX3bE6;uUe0As_=&f2carWhxO|VZlZT5I>-=r*s59#lb+cV6`+S&dfQOB0V8*cN zA=s$;-_$2(h?@BawCB$muUh7Cq-9al1HuZT=G)+GAxLJCsxpuq$(hB2M2mGG(f4X; zjIg(Ct>VP<5K-bg0ui04N(L5unYwbd8CmpS$)V*bavL^qq-8;JE(q%$NX{fxWgr>n z%;G_!#X6A8#!bM+zv_>qd#~h#^AJ(OI|32Cevv}t*kguWigUDf|sth8hb7t`n(PEPjQIXIPNgsRNq=dhE2VCmHf7RWuf<@h)u+CTn z|M=lVwK8L@;Bp6M902jkqdNqaNzPTg5n~)_S+LYWSogqEBUNQ!c`0WW4;C%ffkoe% zVFqj!nB<&(6DOW`uoB-%l&tI!N8@W7LO7wHiZ%u z3K&xeGwJ&^e#nXEQKH0m5+y1r4Lmv#&I3G3 zwAd6%-1-2=lJxpu87H1ci4xyQlyoXRd9vJy(>T(yC^-v+bq^&cld7_@WP~$|M~N1j zLW#{!Xe>!5C{0d0j}j%mlPFOIuVy}$yj*U?4IF7%l)Mszbq^&kB2{H5c{gVkj}k35 zg%VwROwTy!J3BtgiRV$G#CH-U$8{(#`7gN<_j06VQSxmN);*MbjZ~GP*PWqu+WfED*aaBV>+?HE8(z4zDogl1x-Ttkls;t|8jx&qLq896*lDrpKKjcV$n1s%Ma*grbUo|#k z=bFB%KQ-UKLy#*Gy_~i{2-tjnlWfnM^aEj!2;COW`^|!Z&2TW5|sqeZxdvA@-m zebgC<0w$}Y&H_4fu4jdJLgBGK>U^m6f!RlEK|{Np4+4UK{r0G{fYdv5xDrvdhllW}tX=UcG#ZXNhxN6GN=VuMFoQWnsO(B2KHXCeg=)&Wdyx1&lrIuTotM!8 zQgeX8Kh|8EFc%@@o@ri~5y`1j zXO$1MC(PQ7H^X8sjkPEqMVsN2a#&Lf0a9~on883mStN!4iAMfIM+FmYFwh~rM;v*La@#a-`+#Ss8*aA`~q z4#DZ_;mUZk1}AvyIYGCKOwj*?o^U}oyKb$kDCmC{n5~2U2LY)U^y4w;za^ghpfBQV zHWBB)v^KXaT7g>60+h%ZMjG(hF1Onjp7*?&7;1O@oT3VU28j zNu4vo3?{xxb8&o0yd=JUjS&^!V}tSKE2GBfgmiqM(P2}YMtL3a z6pON*meW!8bdQJ8Iw;{8*2zYh6xtkSFi}>zi=#~9MN#%kdg&2+Rd`+oE@s4jF8ZM@ z%IWuB&lgy&qkN5k)Qj@D809O8r&yHjM#glMJ>BD*&^jp38P>^0nG||$n88F@=`M~k zi5ErLuhpfad|Wunz{N!QF7!iNl+*kAJ}R(UNBKhnQZLHqW0c=dJjJ4HHzKB^?CBnV z6Rm^Nn_-=7lu4nlgc(efmG0swllZJCpJj4vvw;rM?DduLt#DBpTmcIgltuVO)T|GV zH%8zg*>D7x2REy=hJA7he{Z?GS!u9v*t1->!lE@f~4%ERe{U_kyxfual!tHh>+V7IE^K;pyw>HifD7?WoqfG&p@z;3-0bqsi3s);N z{_(izHuavzS%9Usu3Enmx^@M+KoV*mtIZdXdg$7U=$cJD`RH0x);k7Z0x7O7vL!ZIHbf0qMrz~g`Hu~|ySrUo->n!T)e-!U{BE#ETT7m0 z%$Hzk3!&k`u-a$pHMXGMfKk(o=;lsOJ3bRqULA-ux*m%QU|Zzz-P2}!YPNsJXqoIR z+}-)Ui&(EQ-Q;%kh3Y2W-TA&GrzaWyPR8&eUF0@~fBSS1b$5QkG{1w4V+XO}@;gX; z9XhEUH?kgra+w~IQ`zDhE+%|si+ck;G~oN1fX>W)lf0V$tZdOF(lkO z{h|%JclsZlz`fk~jYERhJAJlP@BAGT@glwRR}BC5?41eI{N7o|-ic1{R%MHHKxLg9 z)v}#?lbJ?fpu{0HaZ#Rkkf${dwujbhmBut)k3P^^LigmenPk*^YUI^PKPazGdf6Hm zt@CYxiwqr1m5Z!A%2h~*jZ#?^(l_O|VlUAz-bjHf=2sn_?6&S88Qo^cAA~;IGSLCF z%f&SnPO*#yYASH8xtaatvZx(>eBx6oSRf16>m7O+y4kwmBZK}n($mUihXmNu1NGZYD zBOPCrpsK8Njy*WH%MvVmtJ0e2w{Yrztqo}R0MOp76uI6EyRBJ~N!sDJB!2JU#PaS| zViOa(9?)F`R4(Z+&P~hAH%U!C#c9IF=Mx;MKauQQuZ#>&j1AVtr(>+W)0zh#G%ug5 zOt;rV|1=0Ic+fgka^V7y03{dlC!s{$g(4C90cUJ(gv1r7f5nK-J$|kAcJU5WL;ow& zK*qsqC3?nv4j-ht$yW8Te8>tev^?Ml@gTo1M_Lw|2Z6AH(0l+qUIdAIk-oB_c@1Y9 zk3=O_ei6XwjObh>YP}s2MHc~_$260HN7X<%JZ5wG7XdJ{dp={*`Vf`mH0E0^EoesYg`V zmjc`bL;;iOdEDy+bjF`oc#FHo_)>rmIUkrb)`Er}%iR^W%e*`Lpn%kScXkz`>JH+` ze|Hu-?XP1PBC~eIUq_>(_^V-kZ5JSAzZ7OL@4=K^NyPilJD_{{_0LKCdz3E{r@>Fo zu2W8nV|edsPs%3-i`<(6;K)*LYRzsD`6YTyb(cV5Zaqy1`nAAo`rZD|1*9H=u0aGn zq`a1Un?T1apZ6R|2$~N+LW6_p^rY;ZFoQvmvP+C05|0SN;XQq)z!_%8hJJ=p=577D zr{%q=cPS%_onG{p!cHo|Ok$-^;2({ZBL$=$R-T7gSxh|nqs^+qZ|cD_W@;|SY<&=) zf_{qPlft&yk%4i7gRhi&gejJIeHUrAmkpfmn{ z5wGSy-wN?>g>Fh=A+aLwSiSRG9TH@3h2G9YyvSRjTNr*nOX}XXhCsdZm*8xHPVd%R zp>#lV$5lJlqgpe5E5wx?PrVM>o2_YuKHS*pMbmY?EqmOX*;@8o`Hndn*2 zE5+~Res38Iyp!WvbMNHT-m7GXQFw8W?Xqe5TkLl>&!ENG{3Xl^hJR@=n<34A{l-~m zU%&n1Rya@h{ti?)Kb(n8#=FFbNM#SKkKx4f53IFV2h7}ei6?P_dDtnz+4Cd+F7Y5` zrF)l{xb6_s-N4Pp!3yUW%T0JXN9sK`EmYzBUqD#FcN(eJZ9O0XUbkgT@`?9s=ac3# zuw2Pm$%93Ubzm`jAn z5{TSPipn5z4`&n)5iQn1L{Q!Q>zsHVAWD2k0Ag-V6bvf(sx(mD{O58T{)Zzi3z1)f zux>%*C#0whBD?l72?-AoE!IIKSlj#nPB;$`CA=d5f%)E6)DFx#f_Lew z8W7ekfb^51GJtI2jN$>J#d-j-alk@G^hYus-ogpz0iuL=3Ltbjqi_U)a`$?k)No1K z@Eo}f&*n(W0^}MH)-8Z+BSmEZxrsB12Z$Ey0mQ}u0m9svc{?YZ2Z$2hL4b6saOh{` zHhhXBEenv(fv|1?4*IMT8h z`6&qN7DgT*MP(S7-N($eJVvzG6h>@1!WJ>#lM~NlM2YVtMmkl*e1+VIqd3yC7&#h* zbqga)NKqL^)^kSj7|~)=7_m2h5=Ol1J}GCth!f9aM2YVtMmkl({8G6Q4UV)dMlJ(k z-NMKODJsLrG-ni#5iK@_5qobaVZ^&ElrZuZPCSnhC4R;jN#C*AnWfFg<#v38BP|P) zPk^v)!Q@U-R0fmpaz^nm(PAA;T(xrj{K)`vr#}mXb*s~#Op3}n{Rn3ik3=oj0VP?dTzCBBhsn<0F7yPAuXqqjogoKXg%fXV8NvVhJU(0P@2)Zno`qwIW;aYi|8mp!8_AoWfSz6Mcs z2l3>e8Vnsi)-eo`xz6x)G#bt*hxN6mLrB>#g&E9AKxJ1F@&4(X)EQ+G{~qOw#2Mx7 zQMmk<=nmBn5<7XV!_>=nf$`?3v4GSA!s`(T4=Lkwj~eF|CD#_@(pZb)p5+9A`S2su zyG^epHRpsG3Y?B!M8RU>$sY~^ zCCRl30V;=tQ_yTU797^r4hE#^@nHso1Z9;N2_!xX3EeGRK7h_}7%>y{RyRiMz5y9Cs3*756R{ zE`J?*!Uf%IskN@6px-DkTL=9$0#YyNZ^59yl6dli&etZ_n)6>;8{#|A$S8hqST`GP zQtVw}1`}>&gE-tIJ}cbaDO~oHom0JkHQQlzDjd(d`Y|{zU@^~`68*inVUv%Yb1LW$ov&deABxq zdw?jA^O%f&u7K2w?`;_09f_wcWZ5skSH3Xnl&nYTbuV5RiH?eh0>QE%D^XI9(yr-s95#h1EU22(63a z3&T3uD3e0xhZ#(imG0swlXy{-p#*tPs#tsJ!sVBtAKIeq75}CvUm>tsNBL3#sTbvU zW0dQ}Q!L7M<7GO^p6>B0(Yh#pc~~bKWm4#dFoTJ*(p?;75-*B!CkvOq7yZx{Wv}=* zMfnba)jG=W7La;Teji5pcH$`(Wji6KqwMJ(e*vwF;?IS3vQZ|5J{@K-QC7N(qfFvO zQEs1-%NH*HDf*!;%HG^YQGQ5ZwT|+S1*Be--;Ys#ka&tk*-p#pD0{lcJN8qQcYq&( zq{2p-6#9$6h!Yl&Y^A$6$|PPClu4oE!VIP_E8WFWCh?*ucd~H#h3JR2D5v-HT_mtt_vH%& zq+XQo!YH3hJjJ4HHz1~??CBoY(Yh#}4C`d0ObU&K8BCOw?&2tu_^c?OW!6KFW#RId zqt6r~(wi!6T1x}`D+Nx{pm?c()C0xG5EL&ao_tW0tvs&nE6Z;E5Z{i@isIYC_E~_D zakqpS48W8h!~i4lSpeJah08yO{!w7^H(go>5|F+iaE1obX9T1kkUoJx`Xuq>1F1+A za&1o$7He<(AUY(9zaO^40)~vZKg?hNqwEy}hQwz9=5L{J`3^^03~`%2t#1iSI|6Ya zZ8Q1EUj;7pu=FX!(w~SYA4>&GkZU*<x#J z8M7hGV1T6T76XaIX94MNrEvKqx=mrKeJiTgXiisy5RV7Q0 zYXeJiTQ9^fMrTFw3&Yk~jFD;Ag&7RSlo!MpBk@6u&EP8ZaN%-y#UJ|)vn;UG`jvxK^#EbRjPzJSi`C;BqL#9lb;3YWj2Xo>KdmMzzH zP0g*rn}^1R{aVc%JFJg80nzHXXu$C!7*B79Yw|Yl)wXVRW{r;a67Fo3*Bw_{-0YVn z%b7|e&TL>wC)-7C^xlEt_xBWb`$lgcA=9`&_))#N_p3PIq2t@il$$Ed>8RxPX*dB@-xsEYHaoHyjOQFv$v3* z$rxUwhn&XnZ_gf*FwO5F-@qPX!^PDpPe(-7Lr^Z$LvkuoOuCrx6)EZg9~$tD3+T*L zcQ3EzKPyu36)CR67YW{j96Y(Ow^Q8>`_UxSr)BN6f zANEdkdbcW4qysAJ+^ClA+-2*OAL-Ygu1#zPH@H)p3X+bMvU1;@0n2r^0w>`bJxv!w@eV)?VBTC6+znOj<5 zDJPhZl@gpi(D9`O<|r$jV-F4VSpufKQ28mG0eqqI6O<~VLggDdvAn~T*u;zu-2jth z7XwvW#EjIqAYW~FX|UfVd(;4@4Iiava-`lV&_dM{wt%pLN2^oS6Mh379I7YePDP0t z3Ppl+4QFd^ki@mhU&@HiJ#nq|b|DYcDt`mhK*m{XC3?mk51*a78CP|)eAMEF*$$`r zuOu?>l$-H>jJ+0Wj9>)-+~urp$sqCTl`j(40GyOvR9r8S{bJ>{2{TsYRw{p- zKqyW8@jIY!qN$=7-+*pY{Uw;4TW1r9UM6sye&zZS0jUR~A0ddYSB~3WR|wpSeu&~* z!kSw6keY7^GZ^?Ni^T9D@dzIr+tYQ*&!pY5E~P73r+hhorfH8h=?ro{jjAc+q|(bI zPChH}kjBZU1f(8Leu_A`n|SgEo7H71l`prapUSdZKg189ui)aKuzeO?WZbvI37t^CZ5t5*q%l^5o7 z5ZDK-0|+d_ABB^(hj}w{-V7a%?I@S?Z-$N(dV8^e&g4Kp=hgh@n<4(q&=XQvNUX>^ zR;zrSLxSwh(CJLXi@X^+h2i(pq;BtQ$b2*OOPnvz>D_uWln!X_sA|V3RBOg>h7P5t z{fRdvsaHaa^edqRP1$!r$?Dq)k?uVZ-8=LTQmEXeV(Ir;7w+R1Do?n|zOnd6_Edp4 zEZ5;smOXj$_Yhxendm{#BjR^*ud<8<-pO&Txp#7Vw)axXti9I-nI!!!?kk&M(3{d_rwk!)=WOB;qQyFd1S^!^$qDE2p@eq?ALcqmAwB{H zsJ|h%;j0{JS$y0J!n%ZyFOr@zeEf>DiN}W)>)|6*p!`uzIFAn{yi@p~OBg$Yj{{dT zlQ3_?ejI68d>jnIx`dBKq^ArYPvC6g@u9_f_^@Hfs84QQGZw}VCR+`iCbs(%uSh#;t zIkCK}m00;9pN}%4a}W7wy3jKR1FDf3$Fu!X$j*!c6LL#NInuJDz_UPD zmqvjq=_!Nb4V+Cp9JN@77QYs`9s~T3k|V$yxQ6%&`AH9CSh|V3owB8PnvLnh&GZ`b7YM>krv$@P;v=6~! zG-e-UK4aDq<*Q&nmfFs0cc!|noAG7vZNVeTzr_viS7@oBBg#jdH??I9P9_hItHa4~ z&M@bEvXI&iAMrtJ!8kaaj6brs?0P-RKb-t~G-O}R8aSzI4ksJCtLpS6?(#dx_$v_k^SshLm(3yidfAEeNJl2Pkoewe&Cx`8_hm!@Q-g&|Q zMO1Ahp8WHIp;N~?h9NT7879zZIGh~T*PaR?W#ce|Isd2ZN+RBWC4k5Hy~D{Qe!cQV z;&Afzs8N0cx6TKkKBo^DZ;u+~pT@TJa7ZU$Mn(s>Hd6N#epX<=IX)~P^-wTtM~KJW z#FIZ91gei~69QBg+wlWvHXH^HYip4}s(w4nV344!5+i}cXCa}xHOl{j&Ttqo`){qc zXe4-4V7bP?{|ZPw49rFhJVHGA7|5(au9eUH-dYmx`$UTS-tZ$dzngiR)Y~)6VB)SU z5yzdxXT`mXHOh}ePq?6)O|{ll6!gan%+^6aRzT_neI5qApLp_v&X*zAn)6>;8{&;< zWE5`*>t?$-DRx$v!Gv4cAPzT)&kA>UYLt(m6B3c8eVNuv6zK_p#X8cL2uQt1_h6*A z5>I}lQ?;t?j*Yg@t>*FdXd2u!8`j9im(+P~n8CzXX)ca0iI>E;y&!7Y8s)d36VmZb z?^?K3V6l$xTLq+Ed>3GRZzi5X@wK}wQt|aPkMBm)qWEKBjcj~Lox8#eCca8@aePU9 zR(!iwqx^pKg9>qChpO!f)Q2AsSgm9H9RaBqo9|fveI1~WfCunawlt)@BJh$%IWQl`vO%UcQI@8y#%CQl=s3YFC?B~ zQMUUp(^2+xkNeTOC|(}c$wrwJ>I*ZNC@bB?Q6}-CD0i|(`3CeuTVGD^NZcr}TKDC% z1*Be-_rWNiK|IBxY$xP&ls(p6>C@Xk8S)F|3n~GAVRpn88F@ z=`M~ki5Eq=lQqgehJI*^a(X-9-2$t1ls_UM^`d+bM)^+SDHdhBe=!|pPxtsfv@VM8 z4eMm1ObUHH%wVFdbQedN#EYWb$r|OqLqD`dIlZIr5rNe@%D)kidQm0 zNg5PK2}nIqEJjc)A)b6tlr1u@?JLV}{Scpl&WhsG!uDB!k#VPl84SRbAH)D7@mT=d z?lsCQ=pO|pf8V8bAOUHsz!@4yLjqC{NJk)$HWN=ikct!>*Y*@)vG&GSqeG(js<0gv zFl59PVFm*jWv>`8Bt8o;e+xCr--s?#7~=MQTHg|uZWj1SW9bb7QV&bLh^5yOPd=6k zRvXu*738v3$9JN8qWA-0Yb>J3lsm!<22sjtF``I(7NQ>08s+z*uk_rOTci9wfpavB zz9As>V00A1=qtpN52K>R#r?@$ zhpv@~t`mtTA6?~3jB5kS3$VV3H>1Cz_?clFEyl>ei^2>BW6Bp|jFEVUv3$OnUWR@( zny=uJa~b-zVPk0*;8g-Tvzy>pfQh|m*wrY1QMe{}^48j=E22%+S|e&ynvG~`5_XUd zN2(%Zqh~M*7UhQS)Lxc*^(wzi`8l0c$!#fWby_k2c^U)iZE;Orh+a?w>t2iuryg~RA2aqA=@bt#{M)Bf>}D>J)>YU2{;&r7gAEbaAJSNn z^#_#8^oN`R6bnwY(clYEEChl;vQ2>7ML=g}xV5~R|13bk7ob>-G4jTZWRG0M^hm$9 zg0wXGa)$(20g8Sm;zhdVQ4Ig~>6&|}n#;|>=2TeIr_%s>*wP3l zkmW0*ZM9}Ks?_V_6PQv(6U}O+zOB}%tZ+kCOF*n;`vH}8ZdA*5?y{xH4_BtsnIfF% zOu^e!6^i{c3zL^EMbSDpr!2WEMv;{*xsv3t4K=GI`BQV6utgk-w@{$;!8mpzudBL) zVmal=W6MMb%ud}Aa3?B(e5GY9Q2Kyt&6PgbHv=E(`Um-R{jJRJ?E;gg_m@&HOL>Vu zx%y&;G`|u8XQ{1(&{{nsM7TTd&G9JAX$m0acE+5H;sO6gq%uf+h!e{nBGqEu8PD9} z0iWRn^N~`5vj;W4c)(kfmCmsT=k`zrXc43${<$^L5?(YY|xdOH}3PWIox zG?M{F)j&BgW^?%``Hkk43YbjKI=(KTGyYuXt=b;rGyT7IJ}^nE1r256zYW`E zUabC7K9YlGABw?w&dIBt}iMGp+nG@mRs-iIzzeI<~CTQ?JYmI+*@ z-<*@Vz`;>HeG|YLR1DmuZ)M)GuY20jJv!|>a)GNp-%^Ffec23ZwxGWh zYEp@$^(mobSl}Oxk^up!hmsA5l8cEaA0?~G6dEU!;R?=j%+?3-mFOq9|0isl#T6O0 zEzDqWrFpdayS2e=Tia?;tR#Q1$4&K=kaR(^ZgG0e&;_^ zSV*k7J62%)za0`}?{|K{M7+rRod+0xKP~FseuTjLo%3;?K&N->{Z2Zdxg)9_6`$U>vMO0Ay9JCyK_paZ6PTg5ss*$Cc; zPs(i=<4DV*qYlElf{q$#DMQCgIg5C7Xt5qTY!I+iH2slGfp6l3^XO2*JB1Eg!+PfE z_>kO&4{)Sq(Qy|D>k2yFM_S6z@t>SUJUX;k4;?lL8HL1u$O-4sp@er39i6J$xx+f~ z?D!YX+_LD{5!&qvI{sJy9fxqn^XSlGljyLwR&iy-mvO>*bSU97Mn~e3Mq%O+*lP7; zxe=#vq-Ei876|JKJWeJpWrN2EXAut%E!M$<$}ie`DD_{-$)(AO=K-R`cM>3-DkA=J zxe+&Tq-6o}N)Xl+fV_yblmX=3oJBl9wAd6t>=l*-5bxefdI0xPPCO3~CBBmY=~M~v z|B@SVFGpGyAm0XIT>;3~NJ|+&e$QFN14N5W0mR;ZNdWP#yd;3kK21D%EAgEKNT)K8 zNN&Wz9BEmAECyj+0m%NOr3@e^a2D|Z(PC2ou_*`v#Jeq%0J5GF&yOHVd?x|YsjA^s zxe*nPv@Aek5Y`od43d^IfV_aShzE!kn*xZvbCUq#U9?F6ndZdv08!#Q36M_J41cfO zh<9t~@vfBBx&X;anp;QdA=|Mv8xL zC84B9z3}5Xb@|u*Pasm6tIy`d@~&25<>zvq&WO%Em!tJ|u?*G=A7PrvIFqA<&p3wM zy^)>i@z0gpay3U|VA()g%D__REaJhU#L7pmYZ%eFBbV0Op;308 zm}w?s)KU$ULt!?Tf1a4x-k8srb)NVD*c{`XC&sO&-g)A^;oE}eiJy);)%Vp>L+6Qw zwZHWUA*8m0NBm(38EA7S{wREKx_6-@^aWN?b%&bmBP`R$*>eW zRSd1`Q^ojOXHFHPMQWv$bE+7K0w$|d#R58W!seOYS%Js;RI&3x#;M}4UG`M5fYdwi zH-M;mn0WFJ{DqDS>llW}TxZzz$pq0J_z?=N2^lFnFU(*L@hQ8Ki1&}rq)ru+_@60X zBu*7?k4oWv=nmBn68m$l!|3tUGJ)~te6WDj1Hupj;c()~2SV=IUu{7yjkPFVhc?6c z;IO9lgb%5CVwk}|Kv^V)0EtHkaOZ=!N2TyB=n_2~(vcRfQuwgIeslg;K5TJ5MxDw5V6TM+=EfPr8ZD9t31Z9;N2_!xX3Eiy}ej_@=VZdyywcetU z;3k3P8UwErka`%XAqJ+2Cm#cumB6*~ncrJW;`gJeQG7>OLmPKe?>%7#6L)2aIPN4q zEACya6#jMegbTXaF>75#LI0+}Y#sEk3P`=6k7CfjNIdyL=Zk@B&G|2_4e`ThWE4LX z*3E{S6#Ge-!Gv4cAPzT)&kA>UDuwr)nT|A5DSTHT3Zz9Qy=@eA~;CmaPnt96Vo6Oei_p28S6i6=kC>5`Oohi3a1R`+-st&8GUhIO)0 zCWT%WW-w7!x{ISs;zd#JWTo&s&<|}rby2)Ftdos0DfIX-gXzmk zcX5a6wg?|BkrVx?dPHEFx8sNVuaFPba z=LDo4D6U6P+(SJ1peS4FTiaKb-TEQ^Av!CH9}L@P0Y=6>5N0p{Q+^NwjKpUFY`a$q z-|=hNYcpZJE=eFER;Z1>aG>j$% zq#lf3jxZV}o_rV;E%~kOD$3@7)I#S(@r%RuSRj!x*M}Jlkd)nGAd&biApNaW3cnrQ zrZCmM71er|2B&ulJf%@}n}F0q)vFLyZzG<3RF$mttqm;6ZM_iRgU*WLPlm0t7$ei} z4l@{xDKCgIM&g4Q(64fsce4491i%#26#-4rBRzGriILp!F6m zIX9Xg0#t#Vn|1*nAfPi_%3cRBu{Q?0O5x8dRF=DUhIPW3D&c;e8Rv(Wjnl}T&83Ejn)MpLPU7TD^nMIG!SC+I$q?9S2O(Er%UA31%D&<2OA=; zKculD>klZG=?^(|BW`!m;Oj=bGvGi2xZ4DDWsH@9#iO^QvMeydZ5#|g9B7O#=U&amlrxK~` zNap#RSpG<+7VAz-=H9SB#0lnIuLNfg8vG6WCvpvVC-VH0l1!+wn?uH|laf0@qiUqH zUC4F4_^&X=7Cb3=3y#e@XsMx-k_VhQUTf9{o0VuVvO`ZqL!PPfmPcayM*K2tFp6)m z*0BBBb0%g*Cfm6cRerHm+1a0SCem1_&qU(TlMFzyGm&qD*43Fv`mG~pB5y~FR34vw zCi0y?)Ha}`{DjMu+XQsRpKtf(LFPfCs@Eo)6ZL3f zM3s;nu3TChs<0IidmK9EoX#4wNeQggQW$zC&n5Tfst|Z|7%n*8)Uuc!Y-z^Y7(9^4qnYOE~?ZgqS{FNoD<>luBN9Xh*v#YzB1ZY zYgVI5y*`e`Ynwe2&1$8-t=6d6z;sNWi_Qt?E;xUIKMF_Z{l3{{mmvpHIy=;?kFqO} zJ@g915tLqh9AuXgPFUu;<3NTuk(U-oK!@_Z%in9X*)mbS^bzrr<5`xGO-=X=m21r{ zITog3lwNJ{-}krLKDWT5Iq`X*Y1{C~C%RWNr1@(M&Z6$EF>Yq`%UEN)fkm6RPay^41v7fJVJF2KE^@&%_tNw*}W2 zAA%7szEDdItuYSt))?N5n^D&x=4x>{w>Zyi}>?6?tp5?W=<1|mP`jLGy;WCsDAncY9?O>>X!DkE|( z;8z)o!)BRP#vuYyZN2?`m!I{&&MZ_bF zei@61-w>&65i#c}jEDH}X|cjZ#9o|W-t|gw_6*A}B7VU+#LIg9MFbP7?B?VO$CwzZGa#ME)YG zy;igOK45ZcbAh9=QZFOWcgY|WTSjbx*3~kCe(T6G;v%#tw2ZhIhyo_7luAHnrtdF% zGu&gljJV9XfL}&j5jM*#BQ6z?ddrBfA*kxavz?a_uSBDx_~l`J?J|Oty&=qCmJ!OX zB;a$F5hQ*>AbzIHh&#~q;45Nm^U5wH z4xoj^)=G0TRvk{QBNpm)g!#JkGGd8c8W>S#6|pRW%QW%K3O3)iC+f&HKE0w~*b2O+ z*z2je{^pk#3oR2ZFCGvtFAlSe1(p|FYi@b5AQ83n>Vo^Wzm@vbf{@l0$AXS+X#k(# z_A{jUYYWa6x3<_jFQhZx619=hHe;o6Hj&C!8qeg!@+%E3R=Co*gcHmMLJ7{Eg!z@m z8OloMSba|#bwEPW%qx9gFE`@(9I3bPY3*FEj0{hV4c5k|+O)JD$VP8nJYX0Nv4U6QU*$RIW%T-`RiV07|CbM+Mu@! zSmmvIaU}QFy>sE)g6rPz!b}{`*HT04-ebrIiS_Jw)f6cjmfiq&_hQTPN%e zm1rcnYs;*L%dpyUKK?l>2+4-Eo}G@ozURMc`yQJ3Gi##rSI!#Qcto#}(a*_%6M=_Ue7*DFp&)1&yru-109 zOe#Mq%wSf_%DN=KsT@Q7d;6_@F%N z4HWW;911Q+tD|^ZSXYYzQnVRnFep$qiBUk}5d}C?r3cP5dS?3E8TRhxGI|Pq!bXu_D@3t@K<{sgGAim*6f$=q4ku0Tgz_ zH>c|34Vr*y*$aCVaWYn)N0$zcPF0W@_L;)}rp8Am>dmQf*i+vFzeQt%lil-8<7OD<))wCtSc)FOcIZ&zapg?0 zm}r$0z}T8QirX3DSAKlTKA=089`)3QVS{^ZK%80$q4@2fT3{9!gv;t65;M?uD5rXDs!keJ@aBz`KY62%*>!7Oqz7R-M@W7b<^oM)KTqj{-p zY}X5B^k_0hdcizb_os^AL*kb}Am|ZU+``{Rpl$U^nSK*5m)BKB=)A_ncwe7#UZ3gE z@hIA(;N0WrQvG@yhCjeonVTNbpwpE(>w&+duL+XYC{rbe4j zgb&nBeZzyzLHr9>)i|VXZq%-*m=8vV@i(>jY1YOn6H~-lfh>#;&uzA&-Vh{_@DIt| zw?mCu1pk~2OfmIeP%>%=2J*z8(D-C!s5Vj?0>PSYO*A!C8@}v`Jy$)^0QmoZLv7Ea z(eT;;JoKZ%_&0zC-C_Rfp~NjFTD$c1ZKz-Z-DpSjD;%QdX`&RIUlq^;pORso@-hLP zf%C3AxoZu=Pk){;Fre@YOMY04n`xc|y-Psqt^5~)Q{uN1PyUmj<%OJJ`cFYFYjym2bP2pF z4_jk1KQiT>FoStEpsY@g_5Ron81oN*lK6j9o=Q9+I(}dPM>g|lh>knr>0elV!g3OD zGB`X8!G{IwMAWPgjyFc|!4W_TxmdK!Hxe1F`~)4NW`o%%Ak}exCa_;WBl?km)I-Xi zh?M_U_UAq$I+mUh6?22ZODSH5npv9&HIIfZv#24n{v2j7s8JpeqlUyIYSa^@(;+^>U~h)A(;qEH)YWi_&rTR%v9uu31_P)=(Ps)!J6mm1s5%U20@;Nb ze-0LqdZ^kPQMEtupF{SnwZxyZY^>L(n$=zKiGBe#y)Ndre5l*3kC=Q%H_Ge%Jx`dSQW4b2X9@GN1-cM zwm;63_^cj#g&TrD?B1jKJ)`QENJHGCK$l{1f8V-vlFnV!16PJOH3jtAoaj<2ql8V zlMj~DaLF)Zw~*yHZy!}aoO4DoHUQtFWLfgTx(bA0Gx!|=OgTnM@L1^_f`QJpEE8CwYNqknvfKtKmFa|otsp@%PbRN75(GLl0 zm3k)9k%vM0vEW>b^hVA3iClkN*!3nkT`3^-kbW2%uie160WFN; zv%~t?_>yu@4l|g6PuU@kFNx2JFKmjy=W7sPH_qwB2!wYTofw^*9IXxETUj>Ru*6jo zm~dZ$&d^I-Bud45OklGf*=hn(FW!e^yeq_$AMeKr%r?On(K;kthsHkoYVlKvhb5w%R@ky6!H)!_HO?1BkbxPZS{LP-`hf+#;}DBjU{hQV$VJ z5D{-Ao_s{~rY5IM>kTaA3=SI~LqA0EN5VE(Y>)vT3NsjNC|kwYAn{q)fch?wm-r9b z0VU2cY6A!C^{7{#HC3xuhAEXEj3x)`&Dzk^=wLlM^_=t6#t?Q4*^80Spyxa2HHDsq zDSc8nx?kWYjiYY~NIe|&A&%}Po_rjwF6SSEsp@D zh%rXuvoLnXzyQ6p0c4$jKJ4l}b9}gR8O}d$OA>6tn4E;oM7U!JHx~^<9zF`2i15+u zSfyE=81Cs|@daa&md&7QuL~@y<`7j1OMAoj!bfI%2uM9F^&^%R5Klgq)|U5(!P87c zI7}@^Uq$gzVLL6RmZOoqVFrUKNwrA_^P|8%AVgZx!PYg$-Dy|Hs~&z{yn=`{OKO z8}@w*a3L(o7#PAD0YPMuumm9iBil@8rjzN*WM=H12?PNFSwve!1W{B(#9b6|Ma2~r zQQY3s2P)!IL;-neeZt8bliDIMh?$kdEG z7t+)f*`xwK9ff|El{5?PjjzFwf_sT*egj=c91C zm_uQ^$GO+KGJCfGq-Yq4Pfog(QD~4)NqRRGjdS}QoLJu3Lag)N1MrILR4$+`*B9JR zu6w`2wS{-@m$;%<;!Dygt*?QwiJj8A8YEb!v^0FLwohrLxaC)zeqOg6VKFlKQSe2Y zeeLeTy@FEF>jioYr+i`i$C#%O}`>;_;) zL?f83!Fk5Q!3k1hl_vkbusKyI^PGsH)}~=Df_V|u@oySVnna_D>ED@6CzVLQ*cdvR zNWYY^TMChW5mSHlAkxXj%c*(5mTb*{+{}{v&j1lo-yO4T_3QzX9@q-l!y@7Z{JgSl zhJnPN5h0%6pP55zn|F5~D__O{d;ZRJ#4o@zJme7#+xrlOVNIc9M60O|H zD=?TiPwfz8PBnzd!~v=rC5~l_$CrpiGB^b#-Zilp4n;Na+|)9eceWUkXuHNh*8DS1 zG4CarO*5<&9|5`&3+eMwGh4INsi*ep&=fsJ=08MFW%&d6Px5?z1aEB50i%cUIby2h zZ~K2F!q=Fl`iqEi3KK{1&0O=&I{uw?e<@(Wooy!TopsL{B*eY5?ghrb4t`;o%0arh z9RW7^O#J(j0Z14bYmWEpIG*^io4K;-P+pL}i*Gv{sY|ed4Jr`6}93uNionLg0P9jK>I)f#6bC3zzKw=_~R)~Nv}Vm1EJ3_qP>Ao z*>0<6LH>l2vFxg<-aKo)$^=6T zS5Zyr%O#f?8>j_=1`W*@BVoN%RPy|YqE=M$WJJ|cs^gDJhRzm9ABKu)z4B{N=`6o0 z++MxKpvGPiuAov9gkCPIG4a5^ZC%|)b6G|2i0K1Tq?6J-7Gu(CAN zJ{(a_4Yj9PL#-8LJrc>r;v7pa$<$egSzjMSPLJ!IckFTV7tTBWRlV>_?=cHcKe?|@ z1W55%!i)$xW&s{o9B}ei>6gLX#pc)Pe(jygTc+^39p7}*6zY}Fg$=33c5D#^eb(O3 z2+6OSL9i}1*9$@o@CCeUPG0~AWlDG`G5D$Tuk`K6K6wahtkxK6!Ru)$oQ;R0Wz4)j zVB9qgWt;Z5#dk3Hwr7cspbhSv|D2uD9A>=CP`ZHs*39P6G>E*i2b39MmNQ<`yM90;*tI&^4QBM&cdqH!kA3!EIV zKiUO(ffFLisbTDud^6YZ0z5C!i$1cpIZh0tJz2a!Zjcbi3k)$HPwCl%O#PM9vje=q ztFU{c(Wiod`MR!j-W4^Be+{vOyCH(rx}i53pdJ-zQl>!gv3e;^t3yF&{G&q>))g9 zQ836yJFeV&5A>w(Fh%|B0H>5;2VRu!aTCr~VF7{FF*r!=+NJah;bZSoiGCRaZ$$rx08|1o1q~(EOjF5J5aOZpmG$aA`cZQ)<7lro`zF6;e2lv!Y2%uZ3{aG zG2#p4MBf0qgljfWDlJYhb&C_rn_7r<7Gz=`w8q#jMJlP`x2J9Y$sK5}Vzj8d~!18P-e17qf_> zR@8q0Q8k_FtYq%!2vizgUK?(&?gG@bI_+(0+DN#9^0v?-+S?=^y^TXLObCw0;Z7=cl~|1{WTCNR z=_44FT#xM(C@ERKYE#pIaYKaJBw((KC~5&FN5HhHj(@DIu;Cha(v9dfOV@E&=b6!Qbh$1u;_U>XQ}L z<#0q&iT(;V#Nmr?#3>KB3p^1)tMvjFeyDW_x^<5jLe^zv2kb z0O3v2{ml`$NLsJuTl8)uy4J+#Yq-vHrqUK>GuNKl=Kx6lQ~-&y5NU7O;TAQyZ%Q1v za+hf_%{2cA4-aZ-iq9urT@b9JzOfRMj*kvmx4xHG@ z^V@PKl0q=gFFKuCj;4@5gk8t#peB;;NhWx|u0#>|E25JLKC3GxBolB?Gsy(*ZEwA{ zN5mr4a3#T_J#AkRJsZ;E_B+(c3g+S|v2QX({iz0=%Bwcj;J1tpC8-9FP|-O4_-Rfo z&#g(Z#+}|&gBLi#ynBS;@_~#`HTZ?law<~|c0R9j9a=))?Z6ea*rKFke7k_KMAmht zx;QM~89wFT1>-=ffqxu!k`A^Z1>!(+IHxQR8Y$L*CYW?Ej}y)VM+l!Va7v=KxLb+8 z*>5q|Y(DAWyaZE^aAJ8=3$e}u4+cuyavAH}`xChvv;X9du$OVq<~?xD zAG{aFHnC#TiyyNJ$Zv*U6Vne~i);3GOR1ssgTog)V`ET)`@)e}j3+D@XZX!Gz)+$>BJ^YH&9;yW_avsi6l1qy3EhgyVy=`rHm{Hm{zD|6aNh zZF+Btj`$y{D<(wzxu=~}&rbCJ?W95+Z0_OI zcZ|H-SKvvTJ(7P0@u{49bprUC@#`{$p+KjB?DalzK1lc2r`qtZG|? zsicl0DxGC)A1&#+BrUdoF+5$w_UY54#P+X1jbv=oy#J?=J9;G)3aCsGiOV9&sfffo zti9DLj_u!SY@imC8Z@*#zAdbmitXPLQPc|6y$exwGu82j>Ow(#>BCSltylgghAXH5oY2cfyd7>p7R-w6llYs2Eu7f?OWZ?+T`)q7H-{|_Fk9NJL(&|+ zkOYp=$oI9<{kJ7=jSnAFd=Ske`$cKY|K}05kRjZkMHIDgaSP(&C&CuqnE$>>#!!=4 zVl9K3zo1#N{Lf)+G-^ndr@|E!YJ}F&s3Gx)8jd44-92;YtVAdAXyY#4$B@yTvnTl$ zi#57DOJ!|#8icljI)Oo04MLkm6t%$iJ_K7A)$tEPm16#~7gegOEs%Gk#o*n(Va+t~ zNUgoX6%_D<1)_mR;tlZp^+J3>=w(wUqWWSu@*HtIIjk(r(-sS#@W1M;eApiClc|vS*7`Qk|8gW0rV!T^+N8R^q8h`A#f-_VM3a3DY@hhz__%5C2JC z*nWU_@OhE&Wg9!^Ygx4DDKYcb`r$HjF#25ll!pu6$2BSWeHMw6~i9nibajm*TjB!P)(oQQtSR(CI;9vIw3BbQbjMxqZJ4#x_A?GGeV;(tDtU*qYg8cv|oJWrk zK4J8D;!3#hiKk${!Zn?zV857P?(cD8d2FGCH954 zVU<+qr}*MuoPu6oM6<9P4s_0JUKUoi+v;03F6t=B4MVlOf_;F;Kq!+I$aUjz$fMN7UeuUOcU}x-zj( zV0#6+JS%41S!uWa#|RTju>B#Ts0FsKAlM$II{rbZ5}PXZtW;N9AfHwz;H?Aygk~Z& z!;o4pM3~}8e6gvrKs4}3yaArS-b9($JyCrD7!MP>cZ7A2SlAb|I854m&Bl%qy7s z_DX0~FtOjpQ6G)G@|oD8YrSKqUPxerHCYqI#9nNi%rmi<2K=I!*oz{{sR8pozL{&7 zSe}V}EBeS9wA^k!SxoG^4HDv**jpHnr}X%nnffcI#|N0$`?1@j(Wi=uEjl!=b7Qk~ z=dQ}c?&&hI{bS7`j)C2=$iV7?m6_MmI$2RI)L~rb9Fp}9j}_mDY07rPuNZplIP1zB zrq#70B(8aID)> z(Kx1TA5JV!7f7+jrCyHpU`{aaC?U9fMB_QuErpiGup2`}N%d1gU&OmK=Nuw%+S6W- zY8P?^Pm5P#K3CKVU?&}NT>!!oiKPO``T~F-NLJ6F?2xM`3S(ZQU+lVerVIn0+%EWP zPE#H-Qmlc@dNfQc(ej%s{tI?W;ASTWtB&Ye|BB-Ij#-7Yd*~tt=b*F0KyWx!!oQAi~bZp{3oZF z*ALPB>Tej)UVc@!+jOrDaBYA3xRCnJEo|1SibX8SRrQlj`&acLec74 zxV=`}<{zO7+sUfMSc|=LviMb{@u0ZH5?7b5L(=%w{o(0?U!_lz!ml2J8i_blIlnp= z3I$Xqe)XV;a>|}Ru{Knzm|tCJY@n8u8Z@+2J~OPB;#W_PC~8p~KSfl{r#gOWBSf4^ zABKu)z4BpHI?IQ`?bTg?8ruk0P)wQ7%SC*#r&uRlN&HE|77o992%U6Q3sN|txL~Z- z9K)kg$IM@N^1Ng5ZDQgujXL{;V+8xU#mx(%Xn1!|A-2&llFG2x!P;~Li8n`>L9$(M zh$w17;z5MO)xr#3YIUzDGpGqHvb5GR{~+2S%Wn_2UIT=h{=RSp1rVWSG(bo^0t83z zB9;0|_q3^AkLktdB%W;DBm67|SodPf1+YTvWbFmQ+P5PtDzWyBh@uwOet}r~3f1us zKb6=~scfaX+5-8n&}>=$%dln|hosg+;R*_e!UEAaB=H7^{(2K-R-Z@p<#2Rtz181r zjN&1}!cKCn!MGXv*|1Tx6(6={Xp32W_Zg!&;2yC5L5JGQGPzWPL#FOQSBs6TS>?M- zdG|ysTxec@^>}Say|dH2i&4E}8PBmg$6euCQQ8c5cbfy0*ROu9G%jnej;(_}wl$#0 zUKtN|>nO%X+Qw=^VM7knBXNjNq5%Ke`x&$3SIwZVUTlW9gK4-v!o#(%^u(^2BE*?p z{av2gtubeIxmV|5@0>Z<(=L70;XwtnI`M?|{_Lv`bz|h~7xnie`O`^#TGY=lXF)uy`1jc5(dbjf78e~F*SWD-x^q`$iwjpITq{ zb-eM$*4*X}t3NS;FT5Xno7JaHDAaR{^0##*3ZXs~O)NjCD<%-j+|vxPT)6Yt^`KbJ znZS2M;f`CB3ljBQN^6ZLsCO2O##0@SF-846GpD%WnU9_>}<<#OhsCp1Ivj^d_Ss#N^5 zJ8wV9wSjldAGo4byTDT*Y|6VpiZeFKnYr8RjOaXt?HSSDJO$Zq)5mmPg7m5W?mBZ% z=0PQS3gQvf`dN7`J5PaGwD~KR2*ZSJk^?iP!D z9nHssCWC!C1Jf3>%StRs71Ry zjW8RhI)2(MMCVH%hKgyu@*7ddDKB$EkTZ=nUYhz=z{=xcyAdTRjRb2kC2>{_cu0M??60vl9Poix|o7&Gt*h5mX zpNc4IVdJlejXQ)ry!8JZNRz?~zvB&}n41bUwf6Y~Xr3(pURW!QAX4eRa0P`Rp?x%h zNIW74r-EWyz{<@Xc@kS8u;Xk>wD|};PeqtQg6Hvwq851mj^Ozn)$tE3k=Y!eOUQxLt-;OA!CV^>uGg}Mc zbqIK93broGmeqy_fFiDqjYHbtlB@=a+^x}(;Z{BCOt8?2QuX2SWr8CXHG7vd>O%uE zQ_B9+k$tmpxZQUSZGA9FYi`wtTO)9F8Gx~e(G%7<>2~PJ$`JX3@poK?$Ptn}8qf^J;K;c2J5!?DtjC10;BR)cR$Ew*LGu+eP@Wzb+$o6d&@;r7Z zUJani@fjW%7M%}@dr~~+bNLqP+4$R%0ZQo5sTTGTPk1_{W?)0JZfb5vI>#yH;#qP& zLV7~##;hT?vzh2Hm%4G|DQm607XA-%3daErd+FK~Ufy&XSTgEd@1eS4LJkM_G?T-z z9S@IU_J+4uPrK}A-5Y4nI1ifNv2Ev>pW~RK{)`PyO_Q;4V0BQKR00*w#Z^rLSn7-} zCHDf z;wWdzZ>|duXC6|*vkURnx>tEEn`dXHT7Shdo_%-lw#BpKLddM7^6BtvBG2B1i}GEi zRGw!yK|||(*7~K_aH>Nbg@fIleIYMlTy{cN~`B1?o`F5>Md0VdH{xd9~pCSeOFH(+idH-LgVwPg@Gs`c05oT$7J zpxLM|$5%JP3ItBgjx<{pQvx1D%g8Q4Yg)=LFcBew#LpwlAepwGMHIClu?<4vC&CQg zlz^GBc2ILzd<6rOzo0STW!GUHG)zc=r@|E!OoXn{Fd^{>6CA^f2>@rhXZ6jZOhzmw z@mhf0gO4J+yVp%@F|4r_SSf245ZtzcdVvvGjX;}46t&>CJ;JSv>i9>XO608UN0sVo z3*_BsHF)uLSThYmQfsep1qDK3foKqtcmqOzy@?XLC!+ddK=NF-esWk@nxs#ND5oar z9j!^)x)k6O=Ec|Z^*B6lpbl4wE@|}F=(WeknkAdq5{^TxpLr>E*C5_vz64fwV@MQe zajnsMKS+Ztui_i7Gxa368DQr81@n$oZ@6wO>1vGOBY<|T^^Y}RHo%|7H37f|{JS;V zbbuNn0A6m5|0J(mcjldVB2FIzwJ{`NFtrRVjV~i7KY%}$;d{-|lFeqbwgSKG!|(0) z(FUHMEb=#(y@MC}o6Fv5-xV+-46v+{0e0gJFi?6|fHiIC7ktae_vF9h`!xlfoM1!y z08NAOc9JxhX)$|az}5H+F@kKz%PA~xUJn(D^GymtbR|>YUiwWP?b{J`K`v9>8L&G} zc4%;-hf?3#t@~q@_k9=L?42_7G=>e*ir*6+ehpcZ)9_-14iukFuG>N>56l4!0a} zyKfA;iF_a)f>AxutzPo-io?`gBYxsG~*YYp$H-*ZK)c9K7W zu*6RCKCBYoCsKT};V3gjd3_SiM{mc7_VUrP-NwV~i%zGUs=m5@oWVS%WRevRsMg`i zYuSu6Gb#HkmNC*Bfy>2yNw1yEnk%0Mza}!$vv5POzLXkbq_;CS)XzWjlxzWP6;6g5 zr!W`p8LI<7Tc z!>94i1MqagJJY90;hl5TNJON{dFLT06i}H$+Jh10RH$NKYtyxgdFR&~8>ls<1`REl z-w@VIu|8Kv6t!5N{Sj4HP#r((6C#wQ4@1SYUiodPbe7*5Zm;eF)Y$igD=02U=;b2b zjzbi9XA=KfVGD4{VT${5>fvbQPe`zA&98I zP#yo!Qi&9n3RkMDEs$^ZYQp3e@K0!dQS%0=wQ0D5!lbZ3G$u*B!KA<5LwU+xV!`&tZ%yq!h316UK;}v8!k2(?ow57d1=H7Y88*N?d-9S zA@BUfpkuxqU2iQyon2-7usILOVbP7K}s_C?jMV329#0* zDHu3P=yVM|qM1>m^sNLJVP9NH{r)O^mY81R`~5XczfI})uVd=3CjI^>?DyyZ>i7HV zWT%1p65zDp^)8rPQ|4LI#}X^bXWCAW!!tIQ!Lujl;FHGTe9pnA0?tu62X{o2Q%i}X z`DU)kIpA{+?nNJ!4giytbMQlhgt(l8A2S|L>GlsW^;b@}59AyigPk6YK2v9c?z2)tW2lbp?eJ?9+=$2X@)YSqHD|Oa-vz7Sj&sby4oC z3GCv%{k2heZ(MD(Bjw;s|8okga@u1OnBy&)Zr3dYj`@6pO>`xSnV%S)Z?LPbn2>M4 zJ{N~y5koR8N3dv5+gC)-mb91HA5`hs-}9{2Y^JC`<$zP!q#VqhAUF&wu0q4O zqDlbG$&5lJ=>{iI(Ky=pEKV#>kx8+}x88JvK~6C5DSY&14@z%gy?GBt-O|eUl)E&Ofq;m?f}-4QbS1wJu1A5apQXS3bCZlju{yqYmN*JL6o@RoUc;uNv@|| zna>9|LJLpEf2@t6QQDW5Fb|cRC#!a>v8+yNr6nj^42rY_T#~x3N=r-Vho_6Q1o|{7 zX$cL~NQAD+(-O{yLIIVD7+D%oPDL|Lvi4=GI4$8CV*|DJ)S#hd^|fKWR9eDS5k)QT za6Y2ya;oF!4nz3{(ubj9TCePv_s8`TB|;5;w9lwl+rYu1Ka_%{q;I-Fyg{kI-b8aA=Aim=_)=%n zfqE&h&j*H;rK!CqqMWkgnby>9avs_jmhyugJyPU06#tyY5zfxwo$j^K?(PV(@OZS9 zwIp;lh3zBRB!ObvH!EB#6||#Ow}R0jnymPwTd}b>1?+Y6gu` zMFe`s20g2y%`~}Tn0OC!`6g(r92I!x@-30tyfLDj8W7Ino4JO$v3b9oMqJZSW(VlImgjqBXlEZw=QGMD?gOjN55@6#Gk z+$DEvdPb4JWU5r=F<;%uFEZjCI#XZFUHaB_PC|F9pOouhI7g#eU~^fM(SQUR>wmCY zTAjZTo#MIACv+tW<@HB%pU>)w3EU_5G{b%F9z>j&OHK4Ownk4oqNHB`(|%~Pac1$) z2j9DxqJBb@vx6Z-PnvuX87fc3sc`4^k8nk+0_YPU zED=DLVwH5fe1MuAhnM>~6?wc!v6ivJ%=&|zcpfoA{DcuR(+&Xm)-p70#uMyMbDHo3 z`%?+_f1VS|+h2(F<9`QQEih`U4R?6~cc$NbdGt)b30JggFWC}=t(;zx;-!5#6}?`H zX4?;EM0?qG*>2MfH;{{S!AgGyL;@rY_&vAmYex-)A%f5kG^{V~1b)=PD> z#Lxd5eobWE`*8RATPZcfx?2~>>po|_V!7prJk5C&PLvcKu@!MJ>*1DWd8_RL9R*g=ll>!%#7;SNE-hLIOq%Jp4&PDOGu z#cVg3!v9q2xo$4c8E9lN62iDr)=@JO3cBQ)7 z0{I9UFw2*PHPa|1weoNUg;HUGXq1w8gHnIJi6&FL1=Sb$@mwJB*08c-B^Oant>l^j z4$T5-ig(d&aDl|pa5a~tbL_lXyh4I`??9&CJ1{dI23LHmi4>fUzv9cZxd*> zM*16YQ^SC`F&NXFWLks0R~T)M^g~8eV|b~^xRb9t-mhyRl&4E3P-v|&43|KF@CLjM z0pEIHo@C|dwVb;l^gHCcFxv{GEw2rY*CD5<@P>qAbfc{sB(j+l<(VbYJ_dW%mkDu-8Un^WVX;O^i`-@Tp^{9 z@Lyu;+q;ITO92x1CUfSy!A=8Ofs-LRhRFCA(U1}8Zw=yhQZ@NJ8|~i7L{D(o)Xt%~ z?a99Ry>UFBee-z0Jt~*zcM;{(4018w%r)6JeD=+==p$?7a|eaV%D&m)LOle;W#4QB z6(-X0*JJ9hoQ@yJzPS`TJQ{tfvTuqGjqBXlEZw=QX5Y+mb0OfRHA^9Pe0-?ZY>cfa z+#IlLG4aMNT{-85In(b-Ht9C@T!h#2IL(!NyQNJ&vF41<#2UB0PKQW-NWT^3Gu+cm_RMr2Vnj&F5GfIbd)od&dd{TP#UM9G z@a*RRQ`Da>!zpgkWe%PQK1}|G3NhpIDgifFGTM|R##}~41pK>Rd+kicY2lL# z=5KRidE*PQ&P)&e0axh8A3MvQ$qkFD4c;;8*t9q+;aEsV-x2sv`I^G&h&H2rC93vfS+%%uw-?^X)5&Y>l_eyjjSCUi zQE80!0(iP$wCU5NFxsy|jYR08oY6iT3I$ZAIOr=Q%BfxK)z*4^6*Jlw7#pbNh6W8S zqgI6VQZ&|hL{W<>xE4|MYO3R>3PM!1^kJx&)+>K2DxKwT3Ab0rN2sywa0NvG2)$gy z7kkQXn?f^0!Uu^T7PfF0?E#l83hZPik)`TMd@v1BE>ZPKG_&YmNh>bxC<5T8B8)D% zsyiZzS^#V#06!v(?&Z`g@l8_mN_Djb^6#Pzv-~?@%`{X=t$V{26jX%;qM=IS5vn+k z6bJPp#3#yCJ&w;25b|(UPllDHG5Yrr<sNX+O$6K3YFs#0uMc;b_ifuN2RNtR-)xMIjWkW)ykxK2tTbGBvb+oQ?UkvZOtu1)9M zfb#`9h&$CCbiIak@l!Xuq)45kBFd?u z_9niWYe*fQ)HxG3;?}M{gpES1W28CVz)=5PZgLQ7-V83o!!_dcs55(eYxmaSjY zx#}F`>6Xo@Xq?eAPAqS9A=X)@chD_jg0Y7)wKHRWal6qRt|h#e_T!3Lo1-LZ2*ra6eEh{QTh%Dk+{hjZ@O=nP@_#ml5qHRAjqNf7?hSTKU)di|f}R=3ynIig--5 z-dA4BCRLc>)L*fTRJj>^E@nkN!I>E#zY%^-BvsynYpdPDb^?h2| z8E4EpR>whhDi-+7W$#o)w0rV*fNS8XZ^wViXLze)*;L7UvB7VXRg3#!dpT=SB}zXT z3&v%EYyLE<`1^z{9IE7;4#q+c$JPR45-E~>A|FVTflG~Sbg}MFQL7>sXd6TAKu1$R+aRK- z1+)(#(AK3oexOyNHRK3Vsjjv_J_Bu+<-3P9(~u;!b`4ihkQ5e(h9rqcNaB1^9K4HA zo+u@945}ZbM2-t9OJniT5#`ia{1Iy`wkVOeA6M%iq={A#7L43j`T(UY?C-V`_LHM*d;Ht~2##IJ(oU16?xGs%IArHsA^PeRyPe-;3(a zk*qd6Apd}OWYY^<>zOTF9hqsbuFW%mJ_|jX<%{s2mN zCq3YOyb%}DE-C2c?3LPwlu;VGMTW@Ge`4v2SL1U;$Jn84r&%B^T2Q4pkfy{eN0|C{ zf1f(ig4sCQRK+K797n@PQx&#LH8i8B3cIF!stsfBD5^(jY_N`IMo|^-GVbQ7iuVMZ zqo|5^MwC-S;GKLk*H9HaRdFZ!$Qshzu0L5+#g_~c;;4#y7>}oP`@5O?E3@0f3nIqG zTfIvf^`Qahz}a2c?a}B{MO73X8rQk8S-Nvqr78;dWx|1s{#K(vR%}-!D?}-tt`MR0 z!Me)77Gb-YgSq-cdr>E`pdPFE3Ud|6>4b*CpPk@lieQX@=F< z#$`2>`*BrZ!gQWOJ#GF+JtNXae>yb0xNIm1-tE8?^>Z7Xf`;2TYH|=^g7PYqfh(s3 zq|9aXDq%YgqM~tu_v1OSJP@Q<<5n-*v5*tY$I*r0@{x^aJN6e^8pBTh?W?2lIxORg zS|Q6ME}#j*CdLKq3KD<|C>x#~HlRUGkAur~oSHmbq*w!&;DxKVaKd@W2;q|g899Rp z9?V%Ub>X&J9w9>fgb}i3$GSoQ#k{JtJq?SfW{WRwt6$(+&2y&DB-nb>OPNWL zx3v)K2ls|Flf%MEsbc=%sTa~{-)p{zPQcp=bFo(lkTOWaihqqIkCKfh1firbABx& z+RHi1cAH^p8g3}GQRs_nls5B-lEtbJUd@N)wQQ!DS={<7mNCtL?c8*j%}V|!_%)Gf z{v2+dpO#X2rg;lIrn?nvCANY8Tf>G$(+3M~V(CAj3DE}6Slu^=hCigoWW?YSlJ@{rsITbp)+X@1#VkY;u z#s+HpzyG&22Z$`C)j(hJtMT^1sAiTQ7;c^RHZ^Vka0TUU zp+&T}Nj!QR15Cx6TwhKemwO+i=z$&tI&YwUAzhj^(7^YW0>mM0_A3T`QvdM%l8@~XJC72`JwW}?dwk8FA&WNy#JcoE%L{SS9-#|>9LUsI@ zIJBZ!6lyBh*Othap{cU`{IG@^SESxxxPro!utYSjNPHQt_U-HI*f9aTju~0D3>oAF z^)c(VMHW5VvJw~&y%8-VK*a3Qv;_%EZ;G&n#L~49MJ+6S3$b(+)$wC#JKhEgDrG-w zJ@OBrzFGeMaQie8sByQ3D<~ugJ))67;>(b5OkbbbT1;XR5X?BXTm~55L_^8Z#S|^f zINyq}ibTZMBZ^vxxDOF=57qG_qEcFpRIE~6gQbVjL|Oieux1)dq}GGs3JOcY0?}9^ z@diu&dZCma&n=42q2>Y{Jd6E8SVdZjKNC?-EyeE#NN7IJ>>Spx*gT89)n(u#ixqPM zSMAASv3J3z2qeU@*t6%)Es4m#01XqJnSJ> zKQsX!4?BI9u0-tgPomlBAzd-y%pLbM!%lCo*0|8iMSqSH z%)3SiE+3zGF8X?*r7$5Y&Mc^5pv6}4hPNmTluKv*JaRJgJ5GLQgNdif0Dkm)JD*!1$w z^~9jh7x6sO&YWo8+@i%3M*M_$q=UHT@;uW1R5Wftc^M~`H?R;J&m+Bp5$)xXWV_9X z737i5Wgbz&BMITvd{|z~=8>2Q$X~IHM>-R_lUP&e<$;+q^V8thL>}o!xOiP4rB>#V zlz>6OBjKvW)h~@lx(<9NcqIBX89dV4L8KgH%Xy@CaG0^iPL+avLqs{XdHoM-8NP~n zq|X=|sHKZL&3rDbm*NrbiYRJDb$*60`vleTM|DC3k@R7xnAR)*0VMrcJIt$OIweY=Km96iI1*LR(>L) zsD+A$5EYM69X~3{!n;z1vY)jc`TAE-`=-G^#TZ1vQyK--xV6I-6bghM(I_DChyspZ zT6NLiJ<(7C81|Y(Tapm5cZ5|WBKC+VY9Zp6h=^UOjvo<~BDhkqN_Djb@*~kia5r&S zGmRxu>&4*;3QNKQ(O4q!221{W6Nvtvhnfp;@X_DCu!&Nb0r zKKk22A6Zc+X9qfI(ceoA65^u2moXksiT+;9)VD|ORTlmIHI7(l^r?#e79HyC-Fn2q zW=%NyyRRDnto4sIme=tm4ETycCJwwuF%H~WqiRGr?+o8|3OBJ~lPbfWZL-hXN_Dbs z`Jv;qQzPclI)*smCnrP_zly!k>g#4J=!r0YNmrsR^NtgO%g0YXI{m*wOJmr{KPh!!ybk+w zMXeA;Qh4`Z5H_*!?tg=EAiNth@H>It*`!7sbQW+b^U#rE4RnI1rfQsU9zH_&gyF;N zw?!9?CO0nP+RT$1%MbnEvu6o@8F)xyWmEyXjSyz48ju8e=1f<278JV zKF4Y3b3#0;aW5yDx3g&RgrPp&x6Y!eJ^t#1Cpnr&p#tkk{aAJ9T3$cFCZ$c|( zxsnu%m!7u!M|a)v4EKEADgWS#Rt5iaAZ(?8KgAh4UKzbekj{ucxwH=>+RHe}cAKeW zgMwG}ch{i@F%K%?ox~%m^|JC>Ht)nNJpC2Rc&E?9Ja6$%xM?tJ<@_%AHIa9E6t~Tv zky0!3PD;R_;GM8pu6}8}(^BxA;GO8xWbjVQK%@+rmGe#`9A>PZt$3&NBg(0;+3&3Y zz$)gQ-e_!~HYIMKc~e*~#XDUaQPhejKY=j2it6~|$ss~X`Y=>X>y>{1m4#k zh8lZoxPpoj3%y*x+cB{M??mFS5Vml5ry~pJm*Cpj@#e63(_brF+N{^$d>&j~R~v@^ zz-4*rg@5%Xdki6bu<4sm{vG;m0n2g4N}RbxHP!&AYpgm9L*`j0|@k zK3|6F3(R<4=Qk2omPpU@Bg(1O+ur~jn!eFTUKXtnX%v;9;cwHT1tq(xe zF1pMXPVcuyYyEJe?EoHng^T{0+05ZqV_;TBm;Pa6v0%SE$B1Vcm(|Al2l1isL)W~X zQ#1R3pFAl`kD!{}-Ei|qcQ-U^>G(2uhPlV}Z~sr)gVsqmuC*560se;odnUG;&Q}8LqUn!{scQEzs zZPV1H61agt+||DzBNxx&VgQXy0Naml5x^01puPk~ZSFOl_BF-^gsC;phyDkBWDTTlH=nGdqyIEWh)W)N zhVghxkN-PUf93S}z`GjPS`RuP8hxsghl&o3>)hBZ-MOnC9o@f>JTx>k(hotT0Z;zW zULE;ET&1chM9Y{w9!~z$WDyNTK7BHiLCjrr>%!CZ5(q!*DT8*ohh6RVdlTFDBoZB> zD^ViR`s)FRqfXJCperUM5^+y6iA05S$~DffLVrW(#MkL*N0oJLdKPHe5w_u(y)&7j z{){5d8mntY(Q-z+l8mAz6^%pDm7G|fxs_s#>%AF8*K>k-#|gpZgDRgnu5|ClzhYJ(qXE7F^M) z9bj7!me>LA2Xj`!dx{_Ca7z085T93c6epTDwP^8#(e4l67l1$bI~iJ7UxXG4OP@tt z>v`NSq@r=-OPv$T+gphBQjr3MEeLj z!9J^@4M-u6mqr*v68lF)6t#e{DFS0I)$s!(HAhJ5lv+*eoi9SeWcit4eKc@LnFZkr z3OGXVXyA}|1P;ys#aotFVrtQHw2XiZvz5{oB;;HeVGW6#v52A;a<)L^j8Yvxa>{at zqzYv}Yd!MoP~R+nbGUsP3DmeZhASu}2tA^aK;p}guzIH!eFBXsz~kSUX!{e6?u@Xd z#L>qiids0@8gcYts^iB|rSu@FYNfi`0{MMtv@HL2STl`4QtO-H3JQV30?`O0@dknZ zdJ|18`U9#jFyl!rdLpbWr4~IFQBJMiwgqr#a!02Ywf}Fzc{D2KKAEXS-EbGtZ1*M4TL`Y9AepGjji;X4V42G`6ObedKjRAaQ$n8Yji?6 zK8J|X6DA7|mU$;nrr#nF2}wJq+QUvg(xxpYBo)2n9pChryFEWztn!4U1HeW$=A7`^ zgcFipg3`t49FdT86yvXy^n}Bi`u1jPRU{-$$0Y{z)L%J0 zK9G=gk39 z@T4H!t1A(Auy=F{($93ogcKz1X(k0}uPAsGlaNws^|T{P>op)Pum3>ZxnNJ83Vf6) z>Q6-CY+@3T4x2E3Op=U>@8h~G0aw%Bz-%t~%dyv@qH+B0R-9O#Pn2Q}-RI3d$~eKi zw}jyG5tPq9dX{`VXbfw|$jP|QBnuG2g|KP;dURS>?dRk-7jZ|#>+oW(sKw7DWgi_0 z!V<~nLiW)UU>wLkiXQcy{G)?OmpJ^K!|BcAM~XEb2<9K9qP+JT z1~WIuZwC_!xf&#X zrm)4T&(&z4eMF?yUWaM}(hlbQ2xCa5bZJCU3mE$%F#3ftR4+1pLp+Yz2INQmPTo?|?o!YBNbsc$ajz-l{iyankBtGSY-gZbE!QNwunc z!gyzBzvKxHpD^c;tl03`83g*~X5-_HfeYD}D43VScMuF?(XFrp#FNp8gvjs_ZFej% zJ6R9oFjrTi9q{4NjKhh#Vglp9J*|{+DDktH;Z4}0z#({RbubQPrS<$z>-BR$*N%-W zAIMt76!kL>oJ|blaMI)h%0$Z5wiRdj1fX5W=vZ<9dW?$3g^;i2#PY#0Db|3%OF`Vg z3Fh4=1eXuGJOwc-v^0j@4u%@0_Y-tyI&(BjN6a}yEn|_6fNw4w?~K>y4z6g`xawUX zEHSQHpd-!$2^<|!)(ssx;v=L>9F~5>>CIzFiZxi;qBwIXXLSDH`sG*LLwTHuhfWx0 z7-Eo9S`4Ffo$e!)7H94zyp|Kq8(Xw^ z!g#me`dM7(Ov5F=>Yw6^i;dg3=JLrFw@}eIsNczn>WY4f(iVDmkidu2?qY!4(sg6Ic9^&}qpdBiv^~#SxrL+97aC>!}iW+-p zxPpp|3%y*x+i}1G6-eTD6t-}vz~kwS5X_DY_?yo6A@tWqYl|C0jj_584On9ss8)XG6D|F zHcnfRQ1Sf;Ye-bw7g5wg#R-Utd#R2e6=lcv)c|PUkZ*3MgleN zk#Gft1ffSX5=eX*5_ak9GaLd82;Jjw8l%SguZ?@!q=NR%8D+(QG3Jsve7|!7eniYx80!TmwdWWX=BSm#_xpR zETW;iqNFU}DO^-+gYE1HQn^g551qxxbv z@SM4y7gm;7`r{(XsipTR01M4Gng(AhdvP(}#oX<#FM>BG+0OuiF*_Cr#_V_^7`yPy z&xP=A4gH1>yf}VXzmr3+&KmWW7B~OQQ|uRRh}UTh_Ow@{7U?dVpND?S@^kPXi@P`5 zO>TFjOn)kGdQTq55I#r1gwNv`j_^Eg&hm(Is+p(r&0Lem!RK*YUciDA+nlsKj30I}V3>>Q>F@xTrIiqTzYWRHk*TNNdXEQ}NLk+CP9jw|uVPL(<>Xl_#FgEP_Uo$9gC zb!n-o)gOxAX2P>gE!StW=MqJ=O{PI(?sQmg?~XIh6`EqDIljuj)^LwT@? zhfWx5b`TI78OS9H=6k#`UW3<#I>1E`uKi=r61+K0 z2eX*=S1il?_?F)7=xvf&|L0$WUlTJw7GZGV8&YcJ%nv1CP-K4K?#~H@oXzhvWhc5K5cBkXMTJ(te4_uJ{3{a z;%3f6nB75j{5)JJr9=8KR7}sH`2(nQmVYnYULDz@#@-jMpm-OdmkW41a#+axAn_j+ zwpcwgKb}OJi70$r=EqYJ#*zf?;}JzI;M5Q}zZ1qPv|19#PbS$N)lQ7pmhQTl`5KQUiY> ztyBIIR65HK54TmrfEqeCTtUG==oAeD5?=;`m6-W)Hd;o&f!WJx3lb{Mjj)D9#j7HU zTBulxs5pb__)#(8%#U%@H_Kb$_Gu(g<3__36cU6U(MTZiWk{Hc%#XLB3FHW1l0*tw z5;sQZD}DXeh@zISbM*C_sE*&)Oy)=oMTdH496bwSv-J2~ zHLpaxGah(+bG>-~SaYawA;=Cghoqxi)qIhc>LiU0ktR2!a9u05s~3uA-Hm~c%RG)M z7pOBlg7OlsOE?F6NBMZn2bCA;N)(j5C^~l|*A)|TH@K&n+>PzPl65qv>-b`xhPPNx zyXwDYdp_hepfUj zD(m3qoLJu2Laa0WcCeRQP(OpK2G#H-dRR}p^9Q%nJju0#_st);qSlfy>3;I3Kv*K1 zS;!K(6eK{FNcp7UWQ3&nX5$+=ml%Uy-$Y-vydxvp%e2XMTRqJjJ6{Jry58KI5nsZx z3BlERT6ry-Wn+d+f5kGEZ6SDC%z}DCGoyTdD*T$rvR#Nvt<$8`$}F1_AXzq?XI=f$ zShiPz?*z+6pC*H4>jjZ24)lsz6V5@5)tklZxoaF|tZuDXwsRxOsjb#)tVQE0X4x(= zHc->8+h<-I)=RN$uZbvX#lbE`m|Z}1{Bf`leI|VvDyH?yZ$hQB{Kjy5^*Wy#dwsZq zigpRTT)^A=r~=DI;>Uz79F}ci$BngW3d0pRo{hyrKCRJOe?5aEad4ep4I@`sZD62T zZ?&?qk!-A48*VLuQW&J6OLD~=pYLs*O>XZNco5Zbk6eEi%_ugf-W7#5Jgq}NA7Mlp zSp9TFQ43I)BcMJhjObStG4={%=iCiw|l|yHUVkaCfoAbyn4r z7S!4tpOO;P+7c>EB&fA1Q{NtpS6NW&Djc!U=u;KcDmv8LyY+~J&6;pfYj3&dg16>1 zmaOO<7+F?p4EGK-TE&ZQcP^fdvWiv>ZJnVbQTl~_mQ)kn61PdhPmO`ul0s4M*mGLk zjqUD;cP;cjMF%}9JR~99@e1rssX?%lbtT#}yfHcmcAl=75Cr3%W`bbqtw)_e5xaD= zxeJx-X?sfOIha-Hl1x6E`XFv#TVCyi1tWdpOKkoms_J z-x*O(?fBc)-encXR_``8P)jwp&wMGYmx`@^KBA}<3VRE}?9)_dCC66(1C`G5ABWqk zx0}@1AA~EY0GH6q1-!kTFT_?!{GGxUPHa_QFi8suh@~D&d(>>+vFw#%o2&aMWpNq} z-H7PZsJw`5IBQ7P?f)C0s*HgCDWa(5_UqB@PYPAN5zvjas%lKP{-Rr(Z+sIub0hf2 z9{7B>C{YvE4_8pm6s?VRCW%L9ifCo-IP{E;7&f>{M;&Mn&qT~?5TGcDn3qP&_l$WG z1CUv0PyvweN>TfPcC0Uou&G4NJ`qJN)ZB=unL%~@gGEn~YzUZ6VJo?w);vE34VL9c zhc(i}38`~rxPn5U&^#J}B;FvtGiS7jhW-Dv7vSxj3yg3XB!ALp**EBc+u|DgzIZ?W+HZ}$qH;#|N zC3BED+!*d}*5M+<;icI~bAVVXcokNySI z2D-cL?BkhmMcwtQUt3K=!fM$%=xG-s;;eAuV7EGM(B4Q}T6Ju8(|vga$}l+@pG0x* z4V2?_w{Pn|F)i};I6VrylgICc3+naku>QlwR*cpU>vQv<+yErPG&_O~V&hLo_US7U z2kJ{2!ws55pj!a)yL3+w4}jN^ikx^v#l16=KK#pSepN{Nf27*5sB*Yyyc$)EeO80+?slRf%f8b@Lw_&$O zqfZqtTXbk#=f-B~&RzAeL61A7)rSYhAwj6W-n+CpGCs-?w0jl_TCPr2ruO_!4wVyM zq->$g(&i|n&3DkYY;B&u&EuY3;OnYCI)S9y{~d0RH&I90eDg;eX6s7C>V7zy)jd*I zOkj1nrx{jvk1)){D$>N5qpS3^V~Xn8mzFB802Mo87(B;tGE>w~_;RK&gzvGF2p~gJ zs*oZs-4cK`#3)z7{ti;nI6~LU8#|%Co-%LQ7-V%?10b zyE(x$a35d<1AKeDBJbmhT5<6t2Ka*@ERp0Y93?m%Bme^(Hw`#c@Owy+I0W6xDa|8D ziZuw@$aNO%vaG+jST98z-xN{QVuC)7Fnb%-@iRf8vo_L)p<-IE z{L`p(mVYYTULE13#(pAPLGe67FBkB3w4p#7llbd|EgY7yNAbXV(E+65acWWr+5)!G zp?4c@&B&m+(B+eVj8+k$*^X7IwjFJ6{v*N;k{$eEL{SS9pF~W2PuRiBDeqKn12xV2 zifDcECsFGxe>~hyjRk7tW8n%43qqf0ERcA_0>?Tp=-`66l}@JU=cAj=8omBfm+F8_ zi_JfPOVOfNl6_o!Z=;(vniAHe+AoB&jX{PznK7vVYV6q{qNs(lyAWsVQXT);vuBJ2 z72@IwYaR0$XrnCOJ=}JUJ!<%_;R*_SLdR(Ak$8hWf4vaj?BM~9LCwWj!}9>gg;gY$ z`RIspYTEsbHSJm~^BNw2=K&U>kEWal=r>4+;{oc7$5VKK8dKk%nWv5h4DbM-!!Zes zK2mME) zVuJcqv>X51aR}?>yx>C2HBxRuAoX_aC01WF8$3^h{#IRyBJ^L5j?mwwD<(wfxu=;3 z{Z^d-5VNM)zLys1X>&j6X_S@<_fo$pn1zqDeT^yVkGONHnTY$Gs@^wIV72waDKP;R zzh*Qk39tW>ipB*;|A!OH2YIAe<3w+G{aH>h?<66(e1zh|>kkSojbS&jJ30Yw;<5D| z-o>m+c`df(idw;gq}cjSAS^K?Sct8E8_WZ-b$+OIV(D8_!{gvGms665ixg|%vc4E9 z)dE_5b^G@5+yi)niw8^?HaiyfK4wM`7>bUX_i|0=qvmHPn0$y6%bQ$?^+(M&QBiZ$ zQ~AREqwA4Nxaad8xri%TwF|r!ge7)?gRn{j;#183E>0(}`J|F{5MHf2mDjSP;LOzOuUHlZe>aS6Rumi;J7zVI-vqxVM!~;`%kg(g zsgBCSltyjJeDh)(W zxV?HWNR8biTtP*jgkCP-?Y(v(3Qppu30pW(aJVnZUdTZR{1|wzd~;-I2vYV-PEc)8 ztV0u<8}dF5O(4Qh?n+Txi8dE6kI-1gyN`(|YI*;g=>4OF#@=}MrjEjDjxPLFw>s}d z#j^a|aBH-0sVQfLD=6QJR!94m#G`MysP^d{(Pp#aVh&MNy><-V?@+q1V}sb2V0#5V zJWE1tb^^<5BTOj4@|uXE7FfQGV7Y+m_=k#0*M>AYJeS6BCy70EUVZ;@oI@oeQ4qRwtifpgFpHVr#Y6guL zMGts;sUA5{t`1E{oj+OYJ-UDLywf^RAh6J*uK9ex%&5NVnh)^JT*Eu@ywkSmqtf0u zS?5nOgM>KVX%7Y&DIIfHrvA$5m;v7DhuAyO=u^cz6&)Jaxv^Qgb5}iovO7h#E*fr` zcODEEnWya}^HeBRm3ul-Q$z)U&Z&|E56FgFMea#d=!F(`<7EIH?9;q5(KZ7SFFAo} zs9|rh`lJc1c=)GtbtU4Tej3d`jp&LA{1f*y!#{1q0YPk|Oz6y0sHe^Us8_x;d0$Sw zs9+pEE_w-5)Xze33YM@?DHt$hi3)w-0yY5~?_o44VWHkhMdN6Nk8xu8AgdH>9O-4D z?&bvZP7;F4$19$Nx>0Cp42!S+lrAC2MQ~6D9-#L4c-jNLxj_4AybeF%idvz&Bo6Ao zKv-e`zQ94f4kQ2vRW|54EYuIE>2YxR8>c1@7b(`jWf~5}%HHCOYwmS#VOE7aWQ6bu zL&mw|yf7~a3`KKL)49g;9Mld}G|u3&II+CJg;-}-1;Zt7lZ_8Hvj%9G0hKq3e|G(H z7}o~gFNbnPt9FAUKv-focp7_76zWr)u!z&j>x5_~Y6&CS%S6d`8<$SQMT~N!_~N>+ z#XO>fi4wxAb*u7PHWS56ul|Za9Rs1Jhg1QSJ{CWDFkIEa+NvvMZt6C7r&eyo_Nk4BVJ8}y%9Ta8uBMBQ&} zpq689pZR`RFO?I0Uqn$Wy!;Tt>|Uzl4=;x(Ch5aaF|AkrC@P)hzX`Wj$5g1XkAy3z zps~=)1-!lcE-+Cf{_DaP4imK(u}X3=2h_xTc#)5IAqw0>rLKQxGwL^UYtp#rvQg{2 z*Wlk;F={)}7GoL|3IwQ>|JRBrYWe?{=>KPh&R#BRTUKc`(3kwGwaBNVnpwV6xOLjw z)U@rx6_mGy7SY}&@#t+FwqbyEJYIMyPGK!JiR@J2r8pfAVi0o}no`gW-UXvJK0)Y+ z2t!JSYHmbP3qp?|gbt!Q{vo6i%Oo|eR99OdUx+r#^3%hbY50*^r-myi_z4R{!;i!p z`1$LF7%I=9i!sz(poI^9FAu9o!S7~7Ihb2-TpKU4hyT$!=)bK=)*`6ZM8Wwe__gRP zE8^zto+j<>I5!wb#6`j1&bU4$3VuCP-=2r3j-Coc!GDWG7aD!4qToe`db_zEdazj& zj)IF%I6M|CKhfpqH@Zkw)tQA+#yg$z=QGT4 z2lTw8Cp0t4=l8*{iSf+e<5KH>DYbGuQwfmqOq^$3{nFx@KLOu~cqVnV?JnFle^t^Lr9<5l}O!jvr8!B2-e-N_7qNPC%Pw z`SD@RH1tTVW5N{_^n?YXp-18odLp>$uQ!3{)*x!`i*Ds%6)C#4B%+)eY5!u4v}=M| zHFzsWYjk9|RnPdK)+Oj8YeVg7>}m}wXSCB+k^2c3u^rpM=Uh@ zR0Xw)4)ykKJ>p=qCLGifw|FkCkM$0XEbXl|mr`D*2>;Bwp}n=t>a+{+fh=6r&Ibe4 z)w@T;_HO22uKv&#u|roB4mG2?#13}csiR>0e)qeGU8{$fl{ST(_?_>!bR}A$KNlTx z`kAhn5OU(4WJKV0ij?CQw^n64 zq_1l;YWo|%rsJ;v`X43`6jo4^Rm1P|0#!QVgI6L%V$xo4P@00x4M<`6>HOzlojMQ z53%h!NpADj7aj11x;^mbZv-Lvj`*K8{%3c1w%Fv+CvKCcMgwEt&APjf)i2%Y?iLo* zFDlCSL45?AyG*&lqI4D%3Mfo#kG&$wDQiA&jiUKqH!-h_UbHUgS~ebKuj$J0`lCY* z%7#Wq4i{e_pP?J3?(v~9{KN8*#sJ(PIIP* zasneS?&}jHBH&^notPEpV&Q!3=un;Bzb1aqmNZ9}WyhR$TsCk4yi{<178_kg8Uv5p z&@6K6Dufmga(jgSGNy5BL{SSNJ0U{eE%f&$eeIiM1cj2sS_Ua!Mw4Xu7sJ|Uq>w6~ z4_8n~5n4whg~TILL>$9S5<3F={>aiv442_xf&v+|{2bdL(6TO+DM00y5eAS@c`%}= z1(jV8D*s7!{DVoQ5SG-aQe6X^zoKoj{4Zh6G;Bz%KZPqO*a!Q8eldaybVX~2aNC7O{K$*a@RLwkFL=?5ak|9_& zp*nuBY+s_Z8bL~bH%_08nr3--xP{v3)VzJd6_nG3CecnO@gAoy831n|-x#WA1NBya zvoQ+SETG%*3=I5fd840q`ucr+Se5biiD&~cC}1*xHV!TIPL5DijtM736t&zu1KoTq z)$zMIM4rgDhl**v@&Qyh%NK{+tDR1b?G0B@P8WJbJDtRrIUQdAE;mZJo)B9m*jr`G z__gH5R&mDLSD^C3+Z#x+1(#nLp{8{CWf4U!m+y@(znJRyUB0QKrs~gyzZ!?W8+C&B zpN3nb9ZF5PDO^E0RJ1zUp(MV{q03-`ZeTaoD`%Pg->5g?HG%evf32-;VOuP&O(|@a z<;#B0A0D}2xQkvx&0_?Y2-pG!A74aUswDzsENCm!aPZ{_i%D#JA)=^-jc&xoXQ+-J z8v`rDYGfFE3-XSoPcxSB6#}JxB9y{}W*zfAOkWI>>|w@d55p6r&vq=8XWC1ie1vgN z3UToZroO#dnmXb_oTe`z-+3GIEX0y9JGgL5+Kk(M!kB{lQP=hMc0H2N!+sdB25udX z+>}NsfpM?wd^apA4%<<`C>u$RgMM5ec9wsm&5`9WoD5{+Ex6!r@%R!5I^c`$2S?xq zyLf*Stot)OU5Qi3;uY|Adv=Y8BLqrj(6;^U8g1)B8DmVs)sFCMeE`&i;s#w#+;WWsYW6_5f;HW1kW z*B;Y-f{h&l5NUSl}3kKKF-)WWp(jkrvA!VU2I5~ zNg&XWJy6%s5g3FS-4%rdwdDob`5 zsn_GWcfn}AzpO`=^);>%pTGrD+GZa-Vf z#Y-CXp@DMmLV3o!(?6hx1Mu!>!MnS{uaQf^og#`_-hDB8cRQ-%_wH8cT~|ltSnem| z(?d`*IFKA}m-Z<&YEHO<@~LQlv`my1Vyn4nN^Nxie!Vp}*+87z0oxzGt z-_pwZcOzYw@$f>lgP48SqbC%6d}f5cvIn0YQPlGB5$NOjRLAe*={}8>xBZ2T--l7( zEFTKDRr{S9+6Y%reiu4L`<=v>`F#eEgS9$%9WJ%4!G^BZS~1)|*c=%i8E<89buVQ0 zus(3B)E?BSXYCE7r&W((a!Y;}HZLWfN!dN^qbCeMOO;6wR#ESNr0TtIL2rL| zv2;wVsP*xVCwi=U8RGq+urg|_5?#Y9+ulY{cQRv@zaD=$qw3YXJJKFaCJ7c^2DzD= zyj?kOdyc*^S3jpTFR~j+@{TKa_b*DA86zO!H2D!9gmJVyla@bMK37+wgyWOehxGNR zbI&L0iU|qd+|x|Lx48CQ+EqOXBGZFiBawWmiO&b?o5|1f1K|O z$3gH=F%Ih?)jGq`1HUGo;WzeXuP7#o`RibfqAxzD5vasGT2j{b7Rub-4s$tDDlrHuxr%e{?d|yv{6Sduqy+5 z1OLzgp-faOODWtV+yWXG+*>OTG1d)Dh#ICe)z1xEQY9ZA6j9XLB%X>m-k<9DH;MBm z&7fkkcjnIaA=RWaHeP6KTz=5dweFdW$x_Ih)0z4!hrD4H5;luN&Ye%KgU$5T47jb$ z8T&JUL)3Q%DqA~yRHO%<6flRyv(9ywyw0n8OAyz)1p)K2>Mqiw^aU2zm{M%~ETI!K$&9eeKvvuV#+u zq&$Xui?2Z1!;QCaH7dto&MihzIO*m-NOhJIa%jhzX_pspo%UI-UA)uo;)+_4h@{}>=Rw%Sf}dN1 z1PFe{ED@Z5Xo}Z<%Bk%2T6944w~T0SKvcHd>W;9^(A^O~yPo|s^MI0Ys1RMPJC@h7 z!=cPf=C4?GrOo4dF`-u>X7!Rk3cn_XLtlx@?Z>3lP&jmV^?K)Qc-iv0NqwSo543<) z4v8qK-IY)O2&~88%_I0v`LfLFYIYdlRj9!BvT7hws4lNj`VNX?Ah?!u-H{d?odZu7 z*VoXeNePY~iW-SLj`HB>i=j|JWeN`*98pe%2hO%OI!thMrW+mY?(4&qebs}rU8XuA z#|>egVQiq5Xc{yWs(fWwFBPg>5K+_$Ri1~aI+g19LzSVEvC@a3Vp^|!1eMP6W#RVf zy(u*|4_8ph2tqFx@%G*ygJ#w#DH4COu!VCM$IQMywZKcylH0_t%sBr|Xa~^&%ra7& ziQNB|2$f|z(;Fj-TJEo*`>zoyd#~T{CBwNx@DTmU^B{G0d~|fAIR+=_YQqEBad3XF zAFf9$-Khbt&p3jL#DN#YGG{q-ggn|}c{7og$a%Cz=J<0jwd z!lux+TVhSVYhv@k*!(u&0(-^iY#Jx+-rC*pDFO*`vH9H@WTeFAcVX(=^Ybc;&C_s* zMxUzKe9@ua-mQBLHfzGM`Q4n@e7)I(t6ydwlPwt^rn4S!b?r8VXgrmv9Dncch=|K) ziuLsDY#h!CFCB)da=6(GXAPQ-I%Jcp^_Clkr<$5Y$hzS>e(Q+BFXo@A1F4hs$b=wj zA9k+tO&=fe`~TQ`6F9qyVh@-lEJ+ApKtR^R5=aI}SOhTw8bg2}n}&UHax-%$cMg-8 zaqdh)L{M;jIw}gNh`4W0TtEcbT%QYypooYf4|#|nA_C&R@l{pt=ho@2bMH*X@B85Q z3v*{~b)BxNe{c2g?sJwcM62K-aV~z)7Oaqq=bq+r@v~cTqlR9WsVEg$FwT8tM_+1g zucPMX7WuU2htE*Gh7pZt*g4Z&hW*${0ESBrn&RF-xB45yY) zb!oLOzR|4v4V+>=eoAq9pT}q2FI84L$8Nfg;Ujf2C+cNiD-j)MfU?erj*FlH1JS|H zz5;5aN_5WUjEqJ{Ol`c0Q5~f=biG}yH_;O~6JPs#7}HCb2bEA9>Jja=zVcE&#lcJ^ z;swhnj?*CCYDQ=$cW(BRFN1F@QXB)AWjR@EO;H@%I*J1?eWdn=^o9vV>Gw7?`PU#U z@Wij+kMfzV*PwhlV-PEQlP;Rb?HfA7*w#>V22O`V*H@!6egaQdbOwEz5IW;tv`DR? z%jt~!Kqz4{(HTDz$Qe3g*jpP;F`e;O=L0kMwVGf89L+70#Pr~*hEzQfy%@a zjVYc&$1o*k?aF6=mKwvB@FNvk6EdpotaJgBKvZ^xi1*Va1v-P&KcRdP8 z+>pXPehhEX#~ilp4&c2Av?9-H0|P@nHOOeQS?g^}R8nsel3n|uqf`rFC-By#1eF5> z?$J5v`2tZ7DytDHT~sCxl{q4}n0`|zZLQ3YL4RcV(dpXTJP=iVNxFamjP3WU6zaedb1sqlXx^w{pIAy6AaHQS=E?zFha&3WcN>cZk!>vWFFN3)k z%~uea=?OXq5ftuA8>?n#0y#6(UjQJmnR|C+=EEm7`kQuBk-m(51#FM6pF3KIdslk( zK-@nFuYy@sqqlzGOJQo}by{#GOKo(9ekTZsujz;T`w2d9A(64vm^CCwlO1*V+tv)lARWKyAdRpKs9ipI=eiob#tJ%31yd{;0exc^x09$l0c6 z@Hq-pCH(2<(o@2DP~m@7z|$M}YQ7y`l7jgY6F@k`fX7ephMy?OXio~d`xyO$EBY=@ z|4)Z6pN9zBcYlky!6CRYY}DNYq`-qW&K%NiwOq^WKnJ*XYY2glg&+epar`MhMIk}R zpEAg(#Gf+d{RP34@uzRXF%O+SY5Xa=+H2g=al?*fSS{NNw|llJa#kdj*&F49QSWq{x%1uR;gC z4xZkUVc-+ouVF+JJSk(E<4IpKL11tcp2-hkw^;!sA7BhC<3>qTMj(BLQ_JVd->1~N zn8vwLPB9-drMSF5E8#{}b(~{oxaLZYZEi5+K}!n}xe;)ULLp- zvGP+;)*-P18W>_lHLieIxt%I51Ir&dBYCiBwGJ%m-g-S(;4ZP>;Pc`}u9SBS7?*D; zw8a#ey8~BMzMI~bL}l)s%cncQwX5kZvGo2DhVhfk!%8Sy^_ceBSb3>{vV}mY z)qYTH8u}5&|n-Avy0Ikx*fQOxfC4XV2QwX&66w=hO)3voIpsJphE?`igtP-Pu)FTS8i(aSv>v{N4 z1p&7nu&yEioG&n217NK{)C0hK5ddRUCf*Um$W>kYn25C}zYNXI@=Mb7w4tX;UYssq zLa*!*ho01zg??#Bj@rqXm(_!=;beSeU#+(nUgQoJ_(M(}-tAilo(PVyQ?3$b;w<&L zheSKmZCr~^RG3LGbFA+POVf@qcU+U?JjVa=~6_p*24UDbWE1t zmae%)7ghV#bOD1dWuX{dq~4(`UanKJ^>H*`;UYq|K9M$7&8q}*W?uCH2)<48Te9`E z_rSYTL%vnN*s+-{J8sb{PNJi_E9-;x5g1n+_1XYXsUGnL0`Y12z0}9j@17(RIR;=ASGNIXhOfBjwqWa_7AR9^@r{O zpOg*3i(s;0sJeUFidwTD&SuqsPaN#+r`=%i_RnlZ|7fiw&spP36U?}VvDmhV--LXZ}mFnav}hXfhD{(L6l zRp|BonDYMOZOZ8NPvPtaojzIgdNH8UnS!0YV72VH+b+GnYjDi8Z%ub|05&Rx2b8xd z98lI$ZBy*Ww@}~qxrSut&m;HskE~i#8>y>Gc0nl^s9TuzO)3S4Oun@xE~ z%`-Jawh(1ZKQAWKFSG?K5bE619HFjW)ov~UwXw!A!KJ1nLh!~b4pW81#wFC83W-pj zcX%fw8mHAc10Ah?P$xKWl&?wL;b>U_A75asDdEzuB2gKC_Z3bpPh@DdE|^g+{WeZ9 zA1I}`yz}C@^iL@(onu`pq~O{VHTn=&RldPJpdKnZQv4LBmUpdI>s*_lMxWtS^UhVO zJ9h4_{(f(^Kc(gOTroGg-8Ia7kmp9XCQ%ul=WuFyrz^F=BnZ+SVSlBz00s7%Gz0gQ zoqki^8qH>ln|!s0qwQC@=`uw%8Xa>f@Os1IS_9( z`LOc{H^kU?14WEM2kfB!6PmmyPsA`tcR-d{vi{fNrM^WG_zRL3wS zX6?$KM5D9(_v!lD^&(aFv2+2G?N)Y$i1*jy1u~V?->!TSkg1b;gmLpP+6Lg}jn+*R z{w+Zy0e=(z%><%e_^-q8Z%Sq2;g9iSI`lCSYfnBG&CT*X)Ah7rr%LXgE?~m0>=B2Z z)MMDOPcE{j1q#g!1Ht+|%AuJ=JWHX?2`RJ^?KBSvsrMt%i>lWY%!jS_2~9@}JgG^v zBLt!znr=Wey@bld(X?ARiDvv|CO;BUYhS(`{gUOcOxN3@izhxBJ*Y74hiDb{Y}`O zqNr!!qu}Uat*7AxFr_!cUXiOPs@Bp#V>y}$^3HIAanZ8HOP3(Zd zUR9_D7aHR2?U+Cuq^k`K(=`77enVU%c`u?Q%P+$pm8YS%@PUpHGM~WbC{Xf*%%=o6 z!}E?G6UZ4nex0x8vxE#!$lO%GLXeA?Fhb_r4hb?s=DSS9s}M5(!<6?YfKx`ud=p1X zboyiwGR1&K#~nKsVzoLZWab6Q^PWa+aAm!>d$8F(&=30*LSkm;0x?sNZkwPvv4ue? zXimMq%~ZDwKQI){38@DpQuM6;3Q72luZ?!ze9m|STZob?-xHHGTib#aNE+^Gj-=T! zh7vXTa|tnl@PhHUkRASL4!kEA)Uu-D6Qa8@qH*$uGu)9k3)(}5V;4+{0LRn{h%tnPZC=SK=0l_umv?bIZL?5W=^X2p-v!sEXqz=$Rrw~^ zR1X!=HgDk6@~+itoof@c&AU0(ymOW6j-9)MPumoFKWgrB!saTj@;qVlsS57Cfm6%7 zTd55uNzkp}9M?r)GwR^9rDio7{xR&6zQ;YEkI8p9Q7>;?iKMv=lyyeZ%mocV(xe9S zfUKz!nMXNuqmdDlHGg4LN68vpZx`o{)eONz*!&vCcG{Q3!K}_3$Jy0r`?RL4Mou4j4TXAHG*adJY5kq^l3r}nwOzPYWZGH z&>ROs36m+Mv{WExmhj*A79&$k(DXYWnAw*F4b3OdN!w*I^eY9TUQYFPL{$%!iRV;P z%!`g;O3d1ozaEXw@(a`Twd+T!>;>rpCYP%03K8$G&kF<%sb8*qvF-?(kDwn^18_4$ z>m~~S#{?$pl=_DRqF(ragyFwJnH)Xj7Gqy@?PDU=p8RGsH_LBK*VBfbDtUdnfC;;@ zM;vxik74Hsn#Cc7QkYq`PtEL-&`aZeNXq;itEhkyo$Xp*6Lx+f@SDcYJpxe=J9i;= z?xHgBu0z7HXu~9;*1r5{^hlOJm9DqN5>@*5=>i5z%04lcNWH^Syj-Vr%vRS~Kt$-6 z=Yo`E?0k+u&WxRRdt;|Z$GpFcj%&pNQM_%^+XX{cK{jfu>od$m ztJyyYM~UeiQw>ic^}|(y_?uOjVZzxSHSUEQ$Le)BDAWsgRpO14GkWU-b+{zj5-tD9 zRdm4a!pLU%T>MdaqIeGP=F1jP!1Nz84Ue`ujaE93QwUNSHMD$ z9hfi*wlnQ68qg0kmBt{$`V3ztg@>amk-Hdf5M9ZBdDkEBc#i`|! zpjxd9a+GL!ic`$zot5J9j*ur>ZdX=1$3CZ}DHAF^1|VPm0z2cGhSG(@S2M0>=FB_= zurZ0se7r5EmiMtz8w~Q$3~-L-+`cI_Lg*V!a@hSLY&&zg=kg(#!-;yy#Y(CFE>PB4 z>i=elEu{Wq15uFnuM&-;Ia6cN@La#4=XLrVI{Xw)HScg$UG7T{MyAGRKyTy$!{R;Y2zNM>SS#lP?=qj6O{W zD>e&s>VCPL725)Y5+)NXHd7#HvNFH+)|XSvitX)uV5Z6zG_)kxH*J?;#pVe_z0~$^ z5LI)iOgy!nqPuhqQ)1Sxd`T%GOiEkX6(ZhGxfED2Qooz>MZk)| z9gr;(Z6HJz53O2-w@WR9cdzKXmipmNDK+oN_nf8A-_C7pH2z#x14)L|M-O^MB`BH6 zz4acUqAu`+COm2aQ4bZ5Au7&Ro`{lV+weXxy<^$e){gvqv^UGoOV`h$fGT%xx`07} zvO|mlQjaLWF1mP%X<0~S73N{^CN`B_!sJYpG4n?te7 z*dz50d+~Cel4^IO`3fTuQth6!u{8AFC6F^i?~~rp>yc`2DkIg92ZJ}QVP}iyi{LG4 z>M!<=KYgMJPbvZ323Ox1c+ho#Lrt$Z9FD@m_(CmvTj24h90!;3t!S=oj@DOM0_{Jg zIu5YE!-!@1Z}CUv`QsmWr$@-LzvFWhKzOq3pMsbpS@u_foWaJQ_-Z~&mhoiS7B_@g z2(kwgMwV@lPf61m46$2U_1MIkj)#{im z>k6ojUN}qI1NW=d2l~24@nY1FG25lUm=(p_rp=CN;joIT9e3uZ0&PVVO~#!yTAEaC z`45Ta3RK3K*nrBrY@P-?)fS>0$iKxjSidb;fd=EA=4h~;qS#PVFqguTNG}*qNZE0Z zrlaRkn{zp!2rIUR5skBAob8Skn_CeTj-N5BdF(qYpyj=c0VTxOB_t|KMSp@*%V#~c zS{KnM@pUbyn9nII#pRtEPkg;oS?L_RbG&^L9z7N;k^27uSARbBf2*pA=-AQEIkmjM zmD*tN2Grw->q4MzCkwhcv-IJ<3Y*Vwxw`NndV~}8l9H8(vEPBRifRAC#bxJ%1|Y_g z<4wShRSDCK8(ZfpjcAy}WWaWe>L?kY>+OQRp_gl>&tX{SFb^n6{wvk(wY>6De)6B` zMeCPMTMurZgZ~;^o)2B%Y(VtZ@Xv!2YA9m?mO<>*uxUp?Hv;6x!?zV#fPdih?L@6r z&H~_yQO!c&Mau(l#XQc3yvR5fpj6VvEq^)03~F%#{wSXkcpmaufPbL@$LgZR8Mg0M z%x&s7K^c2B3xM;8Frd{~fIfJ-IvYcuCWHkTK#SA@qnrg81fhhtj5l$f zViw@7&Ie}RU_nDupz*X_h6Q+wK-9~~ZLkTT>J3yTo{>wX_jL?YV%Dzw<7jl2e>7cR zyVjw~ekfhQxZIWfw@+>*hh~FI2t=Sb(F$oNO=lu+J}cz(qKAn%ey*K1bmq zlG^=u+F0sO|1OX-{pltUew&D}Z-5#9=t(ewsx|;GI0-L{!c^=SyvL;v@0o%dtKj7> zE9n(VZm2bBU3e)cu=tel?jRr; zqjwR=8BERMtNCn7m`@2GT);xGs+_Qt@FIru{h=)#} ztdwvupwThMj%Qdc+Y`6@PLKsb+OKD%4y+kug9qxX>Z2oTyBk9-dEq?@d11Cp+sR?( zwkW<%nCb274UbZ|dgDlhGq#o&hP1wqgsnfD5G+$)A@O$+HmdS&oKF*9U<=VAd7DiD zhobz{#kOFDG%@!ymnPmVjTbega~TeCkp<%tQ9Cr!Jols2EM3kZk~RJyBO1>dbFN5b zjmtselAC7rhXZW|@O+gqpd@R26N$=D@&isSpB~d{U2LOS<9j*9d`eO&F7NmFtnu~A zO6S;MjnocWR;b57JtVpYl-Zw1Oa%Nlfc{9;CRG{iS7LpE#-i zwDLueAuhb*z;*z3M~dDPoXUF6kfew??KHB7DdI=beX8B0ravK;9uxRar-&aBhoqn+gF5;0-5x2X} zpBt>(9JH7P{!WDjekjbZ?A7|RQK$Ej!FdQZOP$-u%^${(ZP}U?>UDd*y1T~?em*3A z`@IwXEq5B2x*tNNEEl-uRJRCk3{*+PU_`5?|O=?}JrXcn`Zcu9Y> zEm&bm&ppj8>34`gqqvq&%Pts?%7k6e8C=`smmjAvqVd%`XSG|s@6!e*+(Ofg&J|bi zs~ICoR`4SvDqF$7fm6$`QnXsPh={J>-_0rJwLEULT8EpB zRR?VxZ+;Cue;@Y%9zW^<9ph)Z9WSKdIq(2u1A+&B3r+Z|+=M@IqV0m`@1U$Ac)pKC zs$k_Qs;~?z+kAzYM)6qDY8_TKgyGvbnLdXu-h)%kqeQ9h93^%tp-|FTZRaV|@GDbU z^-EaW!?@b=qx=g=ROa88acX)0Dz&*d({wtcI+|(H_4Whk4#YE?6#JM5lw_Ke>h=Oy zUdqojF~femU|FW=0B9XvrU~b0UZ!bZ__kuEDZ|yp0B1VS`Usmuf9trU~UA0+q>3&PO=Rc%3C? zyzpq*l>#}leA^uyY#7lg&g6W>`M}H-!*1kjX}e4&=VpPZxBA`_VfJMzvyL-4_n^^P zes{XQHj_h@{c*a0$>b=zLckYS&fZ=>QvW68iy)J;-}2@DOcU}pC(wcu_9xM8u5dT2 zA;GiW+GveU*lbx;LM zaOG$NH=x0OwbgJhZ*MjR8yd3}V{iq)2;TYI7#g6%$h7YbL4upxR;-16XDnJ~1^OAN z?2Gw6SQ4c5kAWrt8GVyNX&`vyKP}G?c>y!K_^jVfKN!x0> z95VE!=>i60$|qusk@_->!9^o>>RG%$qHk!#?Vv2}a{xu21_niS^oT~0l`Jf3Rtl`w zDC!Z2dMH|eDC(v%aTM(wT>a2uyTM6H%pu{mXm^&MpRTV(0#)|a=>i4`$}TYyNWDWs zyd0nIb#tyQy1I^_cft`8VwJsS3u?Ynfaf3zR=n)N!!>sud2>aQAu(>L&q$}r3rgPYS=(wz=wi|@eN ztbQ)Mw+8>-QyU%~8>!pfz3ck14uIEV1hV`~_@g`@T$th-CmzTfdUL)O?Zx?g->$Y0v3iG#S-k^o!3wM%_p~&trx1YS zhD-02F?LS2oYf;4I|$MmWeHf*vf$(Mxr-RlIIG85?O45oJ3@z}p-j#O2iOXzsWIl1 z@Ox*Is4O=;#HriiF)(hO62JeL0Luqt8lNxQJ^78o>JEpkf+}v3uKM*an4#EIa;klj$up9{9SXY zVK@2@?g2c0)B`%kkC$~4f+sggkA<%9d1N8CDMB zjN`GQ)jF&s$kWA~Y91v@b>}E?S*1cBKAt2`&*Ey!_u{8j@Ndqk<^8MF%E{An8P!qp zRM*=NV3a(4BlCa~@>HpAFM#ExeDai;UBwHQk*7OBbMnYjoC2~mKMe_7eT-t4~ zwYE*38U+nSo?^8^`>K(rH$dzZc}kxqf;{~ysMNzk`8N2kbC~fuOGBRCB9JqwofmtH z)F~!U?{hvd6Y+3pygzN1Ay4lWhm&OI@XnxS&q)99D5UOzD8h}D z`WhjdzfOo*yYfGy(OLe-bbW1Jfhzk{x`4@FE4xC#`*|DOW#Eygr2a1Di-0McyL`D> zd;^IAd0u!eSypSV9qeh03=QHP4E5D;ivv%CZRQtd_=~N-VH<#3ELb@%s~o zQ8eM7EfDp>zXZd-IhBcrKlX-T-F#yr)}DMmnw#bOr0Z$JPL-UOE?~m0>=B2Z)MMB= zl60N%=EtI6RC+sH)>zjO6pk0TK{Hv$2t++79F0&olFG!PkRrsj6)7=mSKf!FXL)bB zz7`Tx*;=}QfrPS43<*+S28k)>&EJ6jQc&?$FxH=hlQ#)`qj7SPK-9y@%Md3QP?8d1geha!p z!^kahtjh>SUlo|IVRVx~)PvCp2&3z%OdLijM%;8aaUZ$tTK-eCJIjBPuCIl{@mSeA z(*+C^lwD#dkS`n*;^lbayj_-MUT_$uKG-`pQiJz)cdr~78XGRqEISttN)@Erd zAwUX>gQHUWADqG0EBkxHt56C>>;c7=3sKHWJmaE3eL z<`el)_ z(m58V(zX#39_OYRg8dIRt6Ag=;I|NU7s{=;fD`rd7L^!+*MqW(N#42Z>sNN=JHV%W z0cZe*Ak~it6v3;>1Q~EX!kNnhN2_(f*;w`J#`EUa(Dh&79>4=gJ)mO%?cv|cUN*=m zU^TvNP6Q-wXTO!Rg1=|yTNS*2H>Z~OzET@+3F__MjL9ZMQ9_H%B2klp!XuIv@ zH=wLyd$|&eRB9eo0yOP^nBgiKAn}o>*^KIF)?U}!wZFvWI=e6rD9PF@)$O&s@=|`* zo*A0s1V;Q%*8U6*GhS;pS^HB2awcnk5;)jwEt}%3{c7g}Gk*&^zH`%dnY8Vw zK-612pNcRWrZS1eb0QsY7S9PWYgc|T8V&CqPS@8io~g2LOBXPUXJuCi_(;~C)UQ&$ z2(tEz==_PD{Xyn_*=TKqHc_k9Eu3)~9PRIeSDfPMmXSK_tET&!@pk0_*lx|9YEfsP zJgqbwhG(EYk4|#ATq|6dNM0@QiB7J3Rv_x(;|#>dr{7<@oL6EXsj382v2;vBUmxuS*GxH(;s{G8{k`I7t0!s$R>Hti(5N`fw zQ3VW>WTLrzIfJ%`vE~YGve~MQ1*Q0YBk-$6;X?vZ4~1tV3Ll^{@m^}LAa_^pI)gs3 zytOo6?^}erf2S?5sH5utBVE9tPFX5O9jSMyizbJwIE-5y@G9bH>X0Aie~D|oN6(m8f>#R{6XPC)IP7u^2a%<74^V_Qzt zoB37Z1$P8x6?u*VFL*0B2zWu^a1hXgTahI)1TEyO<`JaTIs|PR1go)N-2EZ!29D+) z!bd?pq+>Mg?PqROHCuW_GfXL{iJ8J0XAI92o?RgjgPdAE5K3(@FNNL~mlZBHyMWPk zJ;UHEH))%sTo}pMa<$|m`5I2N-S%`LD680>4#pzwG@mL_yOJ|98Z|L}com~MN+0Ta zI}9Y~!yA|fl+cGtb$hL{yp&HLGJ|=%U>SY*LFhL<`VePiZvK&94&PR!4+n95a)s8~ zHhpLmG!%V^)e7yaMjt)~u~YOReVPdR@F`HKa}(wC;nN&uyhd&4!zToCCO`2iZ>2TG z^x+oYu|6;py|Dj#4hZ;wVzRM@KAa^G^%C==2(#%_CZ3p2z4lngFePT~%IBfcaP3;U zzIJg;mE9vF2H!TZujvwr@a$Fp0D z(AXEUgGZqcRAR0;5w(t@70ptC(VCfAA`tZeum%CJNEsdF2R)0;DDMBs);F)AQE(Gl zx*j&LREe|F1x#R7eZ_$#^%z)=)mstrZHZZ1@#eaKq4F{k8Dv`OgFS0YX}$#&AIqTU zwP=w-Po;^c4HZG_LV?>gw9XfZdeC|`LTfFRiT5r0my>=aE;R^jqolPyza0ISXV``tQpEIWyqC#v5=Q{WtzB zA;1#?cVLXX#9*-SnlM7(=MD)nLf{un#H$bj_b}!CF?q@efeWy=LZ?p_Ay5oxv~}Aa z2dmXFArQXm*y~e?5KxTv+{Ibn*kBJ{u{rP3mX}MiW!j|!T95g#>Kz+kj$E5}BB@Jb z%x{S|B()y%VV`Cbx78n3AtSr}cf(fg7Kt>c=hOY$*g}-r4*NUkbH9gcx9z?th+>^ z;M&xUYj5MK%D2rotA~niTzems*_-aqW|wYTmg@b;r)d^Hdh<)Z_)cN#fG1 zZ_2Is8Yk+dgevhS-vVV7^SlM#IhfpM%&bDuzBy1Ql~FsMI}cITdpqhZ(QWG*rwr z0y&czdZV|-onk8HPUizNEf3clcctwzRLlcsIm{I3z$TxvMU6DerIWw?bM8Q^sBroTgk#9$Y#18rpiNUQCsDA`BiRr zOZ85)vB~Umtqs-+`=@6Y_D_REyV=pcmhH;)IQ%QVVWK`bwu-LXr2V$=Rrf%1ID>y3 zzI>w2J=P{gC-kWml3X7`+;}XAo5@A;rB~QOlrMdcIA8iXTd+dDlzW=Xmu^`EPBA-L zBCue*^^35De~oJc{POE&Ml_!Jaj{xj^|8_MaA0{ydjKE#_RMsbo5!AYTnVR#vQi-H@h!% zFDYVRjH@c2M0yp8${>Fcrp5s56Q60_k>w5bEjOO@PFb^on@hjEs1+cu7pW|m%74d>) zIsW&;49Cmy;|kBM4D)xxw-s~zmtywqQmwV^9KTV}P&t0AR%lj zzXDWZvw~xDr|WAIXH?lc(gjSiSJ@Q;K9b`n^;auj1Ude5 zmMLa&&YsiXYZp~W-|{`K(X>5nT`=!`#KcmMcLWy#Fw8h%qfC_A!un1|q!)H-XqYxO??Z0t})MIa;sGmIO5hj)O zTk4SE@&aLFeVM>)-B^zjhjl2hczCTq)WgHa5D({3nK&MH7r228gqfa5)*<8ybV8P2p02q? z2vz$%=>i5J%0e+hNPQVX4h-nh87IL_e6@jrp&q(156%Xx9Bqj3k)&O3M87C-c=-$K zHySc-7WhCTo;G~c5# zabWCPe#}yvZ%`qSbdZ>NJ3(SP{P0)d%+44K399nO=>i54kCAm^NRWC5iFmoxHj*v6 zx{lDVx`d-qU0upYUFHQ3`QB*03V!51)qT^((t*l(0y(p!z6t_wkA}GmVDGh;srC#F zHsSJWy2Z4XHR`oqxZhg6w{u1R;7U7W)&_gM*LgNGD2MO01d$mys>16nSFNg#j`a6r zgSA!l=5VbC{@Bw~Z#LoTQ+LNHUTwPQ_(kfH)~34URI8d{3+lh){i(Il(OOT#Tv1x5 z$BqmQ3_vA^M}|+(c~&e>sS|M#q}n@M4C6UfnDCe>$AI1pi|W39=*YpI{oKD7y_uY)Zg1w{6M_u4U(irwIFG7;n2a&21SdO^sEmrA&#C39c&*mO zHo6h>P);$w(LpIL@9X%DnA<5Uonu|Hx!~H=CbW~es`9%WUalT0I-S0PQ_H(nt97nT zY(g96RP)YNsylYBm!Ko>22%}aqPQq<)fXHq9+#W&U!177OsljT^c|qA;s&F_ZqSWE z1MCKkjD*3a&^J=;Wv%hEoTWTuv|8u$#KxnWIMqC4lp zB5ed!BC^E~nXx_^5%FcbJ29%GyTf$7{Zpk$t+RJYg4%1imX!0)%(M~+wgf+hhzOA@B>_%Kj{akBpdv};o&``U>a6TN`S8aFL*$_LmJB&U}#O|;j zP)S2$YkZ(D}ejeZxNQ^=Z4z?y%PiL_H?wYY4OR zs7##6Np1VmF-(bByYeg0XrO%4^|dKFs_c8x1q_Fy>8me`W`g4^p z*4o)=i4x6_{)oUV*3={%>OVuT>_$7(8JpCOuts3{PyMhpv50#M+bJ zh2{dAo35t~J5}M3oOj2`iG|r7?>$b#V{lF4rcLko$em!LGu+nBD)9bX=7>k zKusWLrd;0#5ZEld8(Yqa62xwi=yAmEj}uN4pNsDC^3K6x*4rT*S-Lwe+pj0nQeW>v zv3Y064d5YtoWVtL~y*a0rPt|F)E~ZiT zXh%*lA1S4{yieoVqrWOEonzhdwBXtldvp+2Ro=Dxlc>zKFXhzouGMOtYZL6ziJWTQ zxk`1%&Yg@a3*g@i@_Hor@Dh23ye;K~5$YK2umvc92t!;ByMnOYm>2Wq5+Ez_!(puzhuYlcRN0Hu1xzMU*%bob&(;(;EK)zBe6j90tZUH^Dy8Ta z3D!-tu)I!SvQ8~uBM|k%|1%8#=ak9ohQqoY&4r7z)Ah7rr%K+ME?~m0>=B2Z)MMB= z4r|?>XMPN8p|B9HX+k_aF7SoM!=nOG4-daUJp7u<#JdC08D(vXNY+}IZ*&(SWJCBN zWwNN+>!k}AgeVKe2qE=l2w7(==kDki1rBe~V*N%v#TI zD?OYpU|^x_6T^ah;$RUk$Fq{{k|KKtXD8}|y<;P_!Jazo7#;4euO2OMBU$0ZO^bZH z6iMr8m=@I~Oo@F5fRHIUt%WIRc@j^Uh#usx_cw$m8HCbj3qfjPpG6o}B}_hT3(?B) zVKHHHlPy?*FyWr&2$P-T&{3wlmA*)P!FWn6bm9-VHpwS=Ze>K{EDC3Sl0^~1#3lR9 zA`ZLc3h?<2V@}B#oQFtMmW=x|r*GW;aD6))#R zy&O*^7UdLB7EOj`PiJ467wD8b0E9rNq{qpCRXL8Vk)ddm zvz$kfR_jnCVpT5U9>8NsJ)mPOc?*<@0n!KMCS1XZwhN>WgR&@)TJbZCMJmGOy;Nrz zTyEj)3WRG0=5PVyaTzLo= ze;?6W+a_0xf`%ejuv(#g)yS0>L+li}LZ2prTv-Atu~|j0k3NdSjMrZpa%HhV&X6mQ zfP>BMz9}YGdYli;ygXcR)YEnua-}8^^%5h$MVOsUW#WmE6l#Z(a5yPl zUz-r2%AT7pU=kwAt`P7Ma)s2Np?tCK$dxP552^vUwS#pNE!wXXn5^?+mkUI_@IQ{> zzf76DZpfAE&|El_l&+@@J5}=PbO94~Wsf-Qq#nawPOjMHb;p;*dYULz5nlU!7uG^y zAzbQ&c(_~O3yp_61)?4voKbNF(O8#zs^ojtm)JqM;!Z zwl?N-&@P2o|S8=h3xsI2-B+M%f+@3kuU!clP@2&1uKv*+|wNS zvRfKjMFK`#WWl&Z)V6u*)4s&DUp^UhH6t1)VmMbgB8IyZtvYlZZ(tUF*#A|4)Q=dm zN(h-BkfoHWPZmf<|C#Qm-n1JA#GstT@65i%Ry!_1}l z+}-*lDs$~@PA%_Rt=73VLC9pBYTmg@b;r)_l0%+42Ki-IFXU|DFS|OZg7=T))bid} zYUBKp;*Hs%1;-}U85(-ITrBL>PUY&zhw&s%)Ju$2Vx&$7Wfh5p0ugmRG(I4rWb=uD zjH(jDHJs7W7>cjQdLyGcn*G-G_L`^{_6_lK7~6L<4=6cWpj5ZlM9WM0*>7fqix(`* zevd=kz3ey6QM~N;o8jAv+3&yM?EJs9*0!_XMnOYmzp+}Oebutx--g(!>^FUyi0t=m zpi-}R%8wS@&SA!DrO>`C{E= zzjsAH#IxVKr+s9?zl%WB3;zb2Lil%}GV$=o?!MBskBPXjzX;9E@)xG-X~RyHJUCsz zBr23W;;@r?3_F+oJ}tbVsB{8jZbLe9=@Hp7lWfTFB``~L!lAb|T63@SV7Cy@ul6t| zeSSK6SAnU@#MFj|)|6)oT&?qDrwT+pxNU@RTSjH#aGNXjqnTgI3s_t8CORw2UzN7O zLXiv@OcyXvRJMwtNa`IF2`brA?&Ek=`YcGXw4>5PUP> zHe5Bw@zrXWRe^UE(Hn{I^@H$&imbmct7RkbY9x5$Qax*Z`-OdK_w1+lO@(RjoeF92P`KUvcYjMJI@HT0zPr1}4$0tk z(!uEhKh;uD(S;_pT+h@p0cCbCv4Oool*FHE{|iDbQGPis@=U4TV+b z0B&p@=L0) z3?^cVU>8a<$>ZbR;L*ZcBI>D4Xn-P$eoWIpd;H5%XhX zjOr*qrt9sR+B96Mn4qd(!YE$EJfeglQ_9=cY#6c| z1#%`~x22bTnBwyxKX*Pb3#G8l{330ap-Ao#hdTH@dIZaQZRRVWaWOm+vK0NH$cjzP zlM2(*mkCVQjMY&BQ7`<@!|*SrGV$>59Jkzz_bD+4gB~Loi+PkUEe2L)j!z3YHZbv@-!}sk6D3c1|S!r zrxZZEwWakWbr7!?cts=RwE|HOAv+;L&Z9DMgdB_rsqPbloOX*_Kjc@SpWuaLY5Odq zc0}XelP+KorTid96#1?UQAdYtc(^FaDB%x4OW#(-f@%+mat3QRq7N0;(koQ!dV=81 z0yk<1epw*uK`_H8T}x%+5R{xL(bh>st$q1j=oWbCS-Rd9T2$#f(gh5(lzn1ok$MNM zc)1R!^rz8s1qhx>|5MsTqSBud$eEe>ZV+(G3qDJwM>Yvu3aH%lJ_wOVwgoAe38T`t z!lx)8$f)$^LV@C(wF;H~9HzWKcb_sUeGlx8(CL#yr5D2)ZQ8cG!AjXC(=L_1d%$}3 z_BVTmR@XsyAb$`bC}9UH+NetnMF{Z|Z6PAWyTpX}3R|$k!7%P=ju795hlZNHx#V9|Y{7Wh*LI|(nZziy zt%8gAH19AY8fU;cGaUn7@(v>*92_favN+gdR)ERHj5#HA_c)2lviKk5)bjaat=2^} zN_T&jQ_M$7DK78Kc)I&7%1Y;0mmw**Hg(wR+gw$7y89dIp(48b$DCT;wOXxnZG!H8 zfK$yoSE=sUx#5)*`9qSB{{AW&_`AQD@$7ePE{F;ksfL2oy6CentV=K%JqS zE)exHl=Bg08&R2fhBC#D>KLZPtX=sWG#c(pO4rw>3aGMKx`4?{D!W3!7u~kYEU1QR z9i)B(<%@MkqAo^1sPvRuB3L)kvT}*QWF7uR0#Psg`(yYIQzoyQOZLu2bKyRubUkg@ zsgkFq3z)Dgd&FTU^%!=JMBUGDTtj_*a3INDvIo5BXrsSLoa*Qh9ETbm>94P@vz*43 zMI{V>aUNDc!601BgittN;06tawE|HO3eQIBK2DI zkOGIdT(KUcPU1R&H#9P?5r}%ocmX2gb5tgdjQOoZYRne~DOHPEyYt)8FYr3Fv^^F% zWX!GU0tPwCZZUF5eHn5NmcG!)=6JDtDT9n%mMmY+^e2y@Ycyo6WMOy4;{rEm$UG_# z^&qnlA@gf06Nk)RrYBf{!d_`(i45IcAZKRShXM#J zv*XCnX)p}~Q**^0GUUv0%me@`=WA@3O)932@N7^sgl_rbw+Y-F&1aHSKNF;edt z8tHA$H^7)+tqwkiqW`jdA^s@mK?;iz*B8 z{PoTS{<$=DGjDS?|!Q{@#6pZB~U6>h{xBW6c&q`^?nCEUn$< zv;6#Q;*E1xVGAqo)A>B@r)(k0^eq*0+c(;R6}WBgX^z|8F$NwrGP=C1KzPA;T*!`! zwBoppTBJ*J(uM#&75`mEG|qN&hC8F|#J;hQn?J^gP1YR6=?GibQ4H$)7m2 zd~RQ>bs>&Y-Wxu^On~`tDaGZzAWwP!Qd#L7JJV~zgvPnSNXe42`yXs(bV$*{Zz1M( zksGliC+f}9Dv`3gg0hO_T7i_k9lQgiY^o0rsM+nv1Q~8#%$dvMMyqwW*@${{>v;8B z==kF}^*nl%`i{}Fhrb=YY2-A;2cc|uGb{geo68Q(=+lqwgQMgF>u-4i( zVQLgK6eWbSyU@OBgz1wIJ4Kk%r->j;{|qX1f}or*{VRtVuQeOO^p65LlO#CCTkcFT zVY>DISs$3mTi9l{0f9ua&k&}w1)^SN^Eiar=2Rx0*-SB^I)*7RYgaxWjn49Y()G0~ zRI2Q}bODpcRCa}c_cH*6Q>UbUrt(EVm@XuW#HTBbi(@>fv5+I6A>0i zDpy2_)Oli8m?5D;32SZMhyKX&-n11KEM!70UBG}vSt|w$sYkG2uMhom0GPAGQ(w%~ zC+mVyGJ34+ILw`7CqwRpE~@Nrj$%r=j6j(yeIf(4H=q>?Y_dtJjSHdhO#&Zl6ka3{ z^-#DBQFsBBiFZy1meVe!ZZvpotE}}v{y}tJmVY2^nMEdVVV8=9S~%h z{RfzUSIO+($CUTS^(o8jpNbt8I(>3Zq!q&%ZQ8cG!Afr2` z{*~PWFhCXZ`+FAh`z58?&GQ3;I;yViT3H{(483{#T5GjXvJX=H-c%~g_uC0uv8>Ac zgPkpzf4F5p_V{#eSNik{+1y>sqt!b62v~z}aO!y!DfJzrXui)Hq{j*B z5aq9ayO*jZBu^- zWfj}h7qCcMO{hxnw)qt^#6^QA<`(u~R7bf5U2oS$H-wp(i8Xx=gSkKRfD&#&scx@* zmY4Fm1!g#p7cAozwuQKR+yYL^+;lFV4c}Je7S6gI{WVe-)i*zSs?16ZzZDd4^$@JDa{I;ri|U?o$IY!Xcc_l=sK)DdP~%!43+YJ~R1B4IDq&DD($-C3Nd zw=k*15Y<3g#cXzgA^IvbIADlkV}HO3Rf*VZIa8w%6Q{J_&Zv&2v~|6`#t8EW6KLjs zvG+3%C`oB6)$KLL@=|_En;FOA1=Pq_po8$eBg+h_?cm;*|DN z&Ie|?6ZV2nr|mK+?I#4HUiN4VVfGl6iD!>exoRE5l$fo zqsnfaE?{y*%B~Rb{*t(m(kAu4QN9RL+OQYdtZ*Rr_=@@{?v<}K*ADhHMurB5#+n)2 zEHyaVWD}9_mL6A_`o%ECI1l}xQjBg&X5B=|!@UJ2>*V2H0#Psg=VJJGr!w*I$KJrC zYabJ__T-Dv+$>*|uBQzdNhr%wsf$n2~p>w*z4y7k>#@6m>L z7ARfvM=>y}p%HJXGry=%!djc3 zhpx)@LNxJ-(fvtjpJ0VBU>%qdAx{gy;!d6a*0YWcOHR_o#!O;OEwgqf-F zky47wyD>gR^{}$iIo8dG3a(A1sCMV7%BQGyAyJuY_v6&^uGMOtYZED|!#UNwbCv3j zox58a>eSrj>8VpW8~F6pvI<`B<<#s4V9C^YK8Vy z%SrtTVyALa^l2h;Qjda4y_PD^Nj=74#%tFmC-sOx&g7&n1P2>ddWv&WoBYQ5z|3#L zE^s;s_<&*(Hzp^wkwDa2FTMd`wmy}KuNPCvCLP0+n6)e46^+jFUDEZnD?_U6j_Cqs zWvJ{50Uyapk@|lVgu)Z~lbVxyG5R5%lUgJ&S*HsQ6Nq}@e=~;vg;XXU{#e3E*FGlV z!hSlMo8_mb>uJMIl{_h3z=U1dBMv*M$FOrbspG>$QOi^&osTj_N^f7-Q}zg&G==HR zHRwwP9mx#S27wlXYXuI~pc)g1dZ2nMg6dUNCJw4S%X3h^*UWTLDsJt}--Qm!@^_}| zZ^1^DA5RxBU{iLA!A9yG*y82*?324aI(6OkHE6!VN94NeYtzQkF3B$lI(UMm@a0NT^gz5I|7=Sjs4JYeMIf?8tsRRm+Nqg$trkNdo!yI z_Ri=ZgjWl|ulP=Z+KQpEQFzTjJzF&dC&}SHY@i4jJ@$s|sjr9w>8%*0EdLJvC{JS* zW;@2w@8BIBxq0KK_#6cae%I{J1aZbowSOXzGu3<-U(IJP)m~F;5?uRN*L$ zGE0<3yQIV3L3a7ogU#-qMs09qy|??-Lxa$l&Rv}KjSbTEWAiQ@&kF2Ai+sB@M5Bcz zXi@F>2)JqkUe-I<#GADZp&M?iEfy}{Rl73%V9Qf<{M-sD=@&d2?eF;v>VdWp(H57B zX^SPcUSXEZqT9itIk zsnHo)=Qdm(-Xs8Uh^~O9CSzR*!7)UlvMl_CoLWB7sMWfFM+uI1a*FxDDaGYICQopj zqpWm}o#7fcK~r%5_JIeOrH6h+atOYwI^T5$+9dM>$$8S8ZehD4_b51!A9;Liv@U+d2{ei10-?#t1f_tCg)bj4t zYMpx%?AWZ|in~;$x?|_g@!7G`fn7CP@$Ke&a%S)Z*={5%!}WojTHf(WZ7_9*F$-5- zE*8(D(T=m(;6EY}Hi{#-n(>Wd5hvPiZ*(LmtJoWT7tmX^^QjV~6`Xz1Ac^U*VMcY7 z9@F)9A*XHHdI8RC**>3nKnXpjRJYgs%1in57&8Nk7c8U47C^*3dJN~S9zE6t-&Ul@ z-is@?eYDoL=`o|Aq3AKJR%l-}dhBY5oubF+(?rl?*Mmw8mU4RR1`ab`dp7jgmjrSq zWAlD*?K#Et*iW1f%?;vwcTkylDm%q{=@_QOtX=u<(daDy zUAn$DT|kw6G+n@?u9aOO;Qe$=VaqnDzfJif*s{H&c?m4e+hA|*@wHX;=5Vd2o-I9s z-F>@xSb&DQklEPmF$a5Z-frDPi@(i5$nQrYtmq7Zs2BDRW7s#QGV!o)=G$t9?C_7a z&iS5bRF?0Nu8R#RRbg_KWW>AD1q=d}y(P7#l?WAjL)uuP zLcb)CGZU##0~Bl$-*LA`A{9#aUctos-rZ2oddKS7=n#;e zS^eCeI=$MsHlU6{SweH7)H%T1jvj;eiQ|vTwB%=aqa(EBFYq}kKs+t^zXG2lE%|eS zoQch6`D#8(OY*ejlLagUxs3^hI0EoNUXvsdJJKx4h)UJi7v&bm;G* zy*{77KExIxa`H=Ja`G5kumU;BJI!%|moc$~o*X4nSvLMnoLWB7tJS)gN9oB+ImLYR zl;ZN9lcy(#m6gu1yQSMWq1HPhl&^n*oik0t;)TnDKF1lsQy~AXs`F-ZKjrxPnOSbY zrx4jUacX&|E49Hi0U8I+@?0F$At2XJcB{_RJihGfuuiveb>ic7D<|qDODj>aw}Y~Z zoJ=U{Snq<;_&u#61#)SFHGINIoMg7m6YcuGajPxhSU?tUMK z17DJdQ_+wXo&9^;v?S{V8yZ@XZViR~J}g3)ZYdD;Aa^rDZZj$qhulj#^`{w(I#*pixf{7VA}e4;9BaYS5V2SxsBZXVO(EX zQ+%q5?XVTw$=}krfjBZy|X%d|PoL`5kQ2_h_yBLelLs*l*Fu%CS{=V`>KHrRj|H@uwVD&ldHOqwF0QAa4JxrFTM<8baeZN=Hbe89Z%a<$k z!dw=2TbzdXjQiOz!jZR@w`Gd1KmMll{3+AnHwC{|`IQ^QlaH^15#&Z`H##HB?@C)@(LrYXC|$syLs=|F2dPJNa4DEmmoK-&o|l1H*t2kS?QnhJ z^7z1dD8Fzyd^wAuS;4ayAU%zhR6v?;YgItgp9Fr=XnIN@>Y?coMAPF`Cf?s1Z89>Q zdPy}jNsedclQ^9UxZ&}aOvvMdem~y^o}(j>Soc}P(jZD*{{1Oidu_ zMfFLVsZp7DRCn-CAr{OvF^jI`kCR2>pp*Ktpzp6D2XCF9VRDzv;d&3g zVb`wjX%WBw0a;&veSl}-b^JjK6aT%@BVPOuD8zqXf#o{>^8}(^{Qr#cpF?Hh@!wNs zyMcmK+@WF#`XI{}r|WOK0;>E=(gh4El$~N!kop8FVD+9t#X)IQfEET7J?Ie+6$cei zQ5RUQQBf0!dZ_ptqT*~S(-|tX?NU@2afgcY(Fa+6Ub_Ak6;%0i(*+DFl$~N!koq!I z9Hvq*m^cPt99th;IoiNky%`*sR1OTFgV~C;aL+6|ZooU{u#nQofaD5vkOIl3MzDaB zD+RvLIJsOP>fz*{h?C2xOdKZ*D!Re|rgAxloa@jrS$=KWB8wa{=jwC;gB)eK7&)ZA z3^{Q90Wu7Lnq_z-cQs8fYCR)E&1N<{v{csH=((?4RL@4s;I)f}8Ihv<`LeIWaQ~jG6Cdu!I8kpOR;9zQPlB?FhZhTnU#|xZ zaQKz&(cW}vt+_%GN?BedM4La&%#@-b5+AJFkx?BzSf}gl0zM6UPBSX1U&3I{V;)g* zm`*7#ADj4-=eH&x;2)-A+IsopVtXLR;i0O(wq38|J@Yriw-xt5PRH^8zqHoW9>{HR zn`6zc`D>%2BmFDJM%CeA;6F;gx1q^ThOodBm*J1{amQ;(h+LB_or#q_Q5Q{3;`NS3 zW1D7Eaj*(qU+tV<4o_Em8tIdGPveQT5xC89l->U|j25X0Y576F5fDn4OnVv!1#-rp zv%sHrPvZ{W(JIxyhA(e>O?bncKh04a#%VGGOTA8a2H;jm+Gz`kfswHu+>*{N1NRbE zh64HEFs4QqTUi=O9c2^s7!o`uxt{XtR@D*I6EoZJU;83 zUum1i=NVsC+2-*Xru=`-HV+E@C#j0ilWxT{0=H1*zXs^2@?rnxo9K6@^uUiLeBx~r zQLv2a_P2?U`Zo&H^Q%6$Av|)|-ETm>?l}3o?tYtoK6RQ83*=0vIos{ zb@wlfkvGzZ{mb)hKju#IVmf%N*-eaNrZ@R{e>$9Fls5gNMS|?EyBScRIGk4LOg3i9 z`z>wq_KfNEtmlzS)$CqfWUw_3A?WnUy6dhO&}fffr*2p+Gu3GO6!myE4go?`eX{Q{Qs*~l>w|s;7g81GhC9P+nOpAgck`V- zEz*)5Ig3g>LV9T_HcPMZyR`}(n&;C?OKc%p#Pjl%d zCUKyUluSQ3u?5^=NBTOPR`zpU3ZH(cGotZq6KAH&Hr3V@a@;*_<~k1?zbhc>jf~|b z7vNn;qOx?G$1;G_;an8mmBDuRmwPmmjNEGOD7NL~)gCJ`h@ zQ(a{sS;g7KgG8%!Akmv?bw|Q(tv!!Z&%;Ei?-(Z2?Qvo?^fc_{fO+qy?fPsQO1WGH zWz;U^>dMa!FRtL>k8o;v4{No~!)i;Bb}+ZU=nI^3-oHwD$Nt@1HA9>_;;uQ#_%3LP zx5@3el@o2ZCEgCoCb1=ci|Q(CiH~x2@i@_H9ZuZdM2!{qhj1qK7w#cEUerT6#>)(M z%RsR~jwf&H-15)ND9$&@%}7+{>YX{YysMR3`E8y1Fsh@ZqOP}#r8+=t+B~yFdm;0P zlBtbS-f;|PsWz{Z0Ta~ZPnMhU3Qn}$CVwg@o5Uu6Jk?c(!zO1Jk3*$aj>8KX)lnSk zdOIAN%MLUW&97m9@($)PC0JAsXb+3!rF?>$NiW0;mR<6*2xjCS!Hvlumo&-`g>Neo z+}mM3^l+^;MR4zXbbSD>9LxH~2Gxa?c-2prdc}rMc%C))tavYxq_;5F2Y8u`|prNwV7}pRW)oA$p;pvKor%w|?!#{);rD*tvh5md{AZHk*9lhLm z`X-jH<;zvd8L0L)j#^$@*UCWEZ;s|UrT3DWw%WiFxzI8T_NHN&C4fGN&VlHFM>N&GP<;s za{Cy5edCz78(Pm0g6mV@qzz{FkepzTV=YAc74Tj1(7K1ZkwXQh>aZUo5cR^o8;1S) zR3;vFZtJtIHTRXRe|{30m*uZW*UN^NDs@7-fC;avzc{?49>a@$Ka5F1i1#-4(zba7 z+g?svdJuaA9ilrrHN9kxV~+}~*AX8Uh~K4QsE3sKh?K3VOdKhd57uhvR4!*N&!3O($?^lz7FjHjISbMS43?DT zVl0vRGAzBwTq2HG0vuJio{q&3OgLPkk)2?^0v)6$98R>bQawrF4c*I}C=m6qvp-_z zSSl08PNiG-v_X~1ILr*7OR_vqTVgRoW~@vXFqlymi!np$%P_OZ^b z`})r3RP%sQsyhbE#P937TyDdAIMH@Na|I}?2%2-Sh!`X9rrOH7lrM9Z@fgu+9Y&Hn z`@YR7=TV}RcZ`xC^C#$81pA5pPj1BhoM^i+`4uReRG8dLwUxo-8O|~uCR(k7iC}Nv ztiLnkB@Yy(zGI+x$-%A-y3TXI?ew|JuHfv_&)ey92Yg#`r_T#8xA7yb zHMP@ceqqbbAYDrr-*baoeV)sfbE(WS0jS#7A&mY4dEz(we2)W)*NDw#AFN4n|4m^x zg3TDc5WV^pUG-FMUvKs?L1?JWKDeq6F;Z=_&%^L^wb_S0O~_`S-=Rf1CGGC!aB-yd z`R~b34wcOQCfYppTY;R}?DHbRf zRnw?UJf)i2#iL`G60>&Yd!W%-zFWG!wh2&WcS#p8NmFH4i1LzSt~cP4Q=dUUP1uWbGEv(UUOKOGec{M&+cXXwjeO@E5UPt^~fv6YpBQWBlR3_fgqZ@g& z0Z|!;flJZkEPr>prWONK&3C2?7z`+j#26s;Wf)i&n|;2BE>S25mi*Rf)bPI~aDaxv z)dEou21g+bK1*d1Fopv_tS{d7$&45*slO&2gQP!@?{KfA2j znk=9FeJ3Ltr{y`@9WB3fqG970WV6J_j<5opzQ9;ma^cQZBr40weuY!ZXJxfomo$x1 z^S5z|`QRzV<^3j4&3{T+=^VQW9j>XZAY{(%kePo(Uj2tSQ7_w9iJ5;ClvPaG7nu3W zKm#!I$=*Jo=N}*&WRTh9U(EE4hm2P1K}LrMGPoPS$FRLWms89`Mk($XGAi=|!_b6a zW`BA8=X0X%V&*_lRuMBBVv%YP>7pvjAaVj{9uE<%)(RM*{9w?i9kc?23WgvMkXC4m{t=0pH2?v4%KZhXs1gDw@iBdg5 zAc4v2gn;B5^7?<36KxkH{{zYW-Ul~d09S1Iq#uSzgND!NIIR;|0rhaGV2^ca>?dNdw1~=Y8;P#T^_cV#2JUwemYS zwmcseud`vZ%+~PFgE(w$$o1|6qoAR7A7Cycw6EIkga3xusoe+kiQ9dkb5-un`pvt# z+@=D3QHW?c8waWXmOwq9KX!@e0HIm#y%z#R|7hl#fr>!c_Q}w5YA{E4>P*cVMjpS~hpC@Mh{E+6K}F z8ecR7qF#4c19#-TR3_0K#_yk?1t_d|HY=|Bg-@+l32 z#;$605aa{KC+fXN|8z)@z4z$fOvJ0a_vr6Td4GO6W$!&|U@wJEpRD&D6$2V=-L}WU zYMB*R+wVP^*UE?w53Q+>bgx>uYP7K1VrOo*g_CY~v&G5$h6ks(u-9U^sdrecX;j!& zaZ>6jAw6EG8rwiEhvU8zoX5b+Aw3Gh~7cF?Vw2@`%xDJ;dnfzzk{w_!zeAUvi3h#3;oR zgqSrAy?TP@uQ%_)|A)QrfYYm}+7F}vA@m|8kV{XN5`xqadPfKyM8Mt6?z`E&Y-4wm z5Tq(aaDfjAQUnpjLQ_$S6hRR`sfG3Nw23Ekf>d}{8{F7h(zfq>OBIe)1St4Sdf+9%(c>`Gy?W%CruIh|kWyzcxqMcG`!4`YNft+gXA70#O85eKoxJg{6tMMr~0y5$R-A17P~ zg-um&i$<+vYNA1G|W z^)2;R7CTJ?sBQs}CKSSHd{8!fv155%42 zSH$aU+72uGfp`JkRb^c4u8QvaWG>z!qT6R6NwQZLR=_?$KF3Ik>f3iROdWun4FLJH zOv+nHbo)AFCd>af9*uzyhVs>T0SzA+H5)$Y9^lht(d}382#E<=bbBoxB8qOmWZ3C- z&AHC7>5THrMYn1_ahZVSzZDFcE4r;b(I9~*x=j@Yic7u}(QOJ*-d+2Qo9K2vj8c&F zW{Gaa1`Uo1X2gMN)h)WstX5Ha7qqtywf8S9zEgY?N^>*DwMuRm&|;YJ>nU#H^W5+e zCw*_Ze@IqTsBq4m=HZc{MI9rk*0&lrts_eZD_IMC3__RoUIE@cs43Uc^CLBK<(KAF zC_$4s40>wnUFd^MA(ZkiW=nY|nSu#Y9`!UU8Xq(0y6GZtu(26F;+rZPohj~h0iL&St5L1 z5IIjm%LJ@24=r0!!O>_@ZY^3?G3yJ>6*~XoPa|)q9z)|sKBjKmICM^7G>>V5M^JU8 zHNis@GJP`Tmd>HJFPb>~+c@C+{_Wk>D)nqD_{zpVGovSdL+I-iQ* znRa)B1CqewVykg>Le?**+|pT>ZoLzlRmTg~!IhZ5YS!Q<|K@jtk5ILto9V-pX|1Eq zM}@Oyk2)!>@-P)#uvO+chd%Os#4id=E3_1F^nZlwpya9Q?Q}NS1nEYdgunQ$_#E+w zlDR`Vue-Aq=tmsT!a!wAfq&wM@q5a&RxtiqIBPZ-e}fg~O@V7oCYAy;7^Pdj{yu|n z9R#DQw*@0hf8UOHObH<618M_gc_~+aCpLBAf@S*qeq!C@=F=$g?WF#WKQ%&suLzfFcr4f77gCsUy0q5cI~aDFr@q8t z+~V?HQ*Rc(&*ngH>it3dqIg_d)w_UU>WDU%0nE<9G7(iTqO7YnyJR`&qI)M@t1q1o@1p$4_OY4h9r#D%E#j!JgefqI?c|D&mM{wxHQ<=>6h#WX2a zp-H9E=1cZ-Otb3!y7)%y{6&2WDnr>oSBA8?xD?i(wIJ2p(n7ZN zI)oQYRDOrM4Ez&RLN<66OJFjHr!W4@$cAe5KQK(4R{tMp_1|KdaA%($$^r%l9~N1c zva&1OlD~^8tU3kdmlnO-8eLguSR;&D$*zl~?5s+hLPD`pdJjUxzz;LBa@?_opG;oR zw>zSs`!e{A!HJQ%A~FR!hhp&IHjfd#g4^y4QwMHW1Kf7TGGVyI?qBPE8Qjz7C#p`N-gcZFcUO)p$#>55^ zx-SFL_}%%x9TFumQ`rBTWFkQBWF$rbRgJ z1fvury;;YPiVYg<-DbprYMEYhyk3_pMWO5kcB3m*`bUO(D#Od*07Ba+@ri|zO5b4X zNVm9%(_OgqPrgyvF|YLq(uMSaAIGzI2x-o)*+}2uh`8~OuS6F=4_A7(%PReg`sAUb zu1fnzE1EzMA{O!Y4FA7(PDyU}%T6J^FIp-0_(&7$lyFYuAn3Es$WYjL(Hi4^rVt)P z`Z)U_(s8C>!a*eJY4#uz@c{(~1#%^5xoeI!`B4Vfrw&C;C=` zi7Qtx&Po)#36yEA;F&C(C4%Q!k?lmR{3`(~n^ED>SW#{*R;D;DBFI$ztB;o1)B|X= z$OqJomMu9;9|@_glvCp`Y`^_z7iNYkz!6IBR}?{2^AEhn5Me5R*5J7U`CMfM|8Xb?^X@s<(wB z>j2Tl#A8a9AMydUL9)D*dw_`8hJ_239U$6EEIXV7M6h$VJMMgU@z=xyM7IFbG*@}8 z`2dl2&@B%TLACt&(hd;K7i}jG5aCaaI6!o~aH&}4@&iOCQkZc%wLU;}EW=JS&9^$7 z8F7HfKWos`^Fu>61$qr#0zL$MaJdh-DQyrFYrM3Jq-6TO=S%{Qlhu~Ei>+is7Wnmpd-Am6#-Evv1!nq;-V>Q`Ia7Pbpti`PZN^(%2xQ|&wGYR_zI?LXsFq2XxuuOdWuH0RYm1Wx@bSJOrSkN-SmJbGWFIsM(?MXiV3~ zP!5V0(D0E_v*Cm80Y36PWw=~ynhP8q$RYC3(ShE0h|+2gn1Tt%0H~+g zV*s0mp(WX6OF^;B#fv5*Ud<$q`>H@uOv5JusPOGcfP)(f8!Jj{q5)>< z1URjL|o=L5o7B6v=LB8gaeFV>ld zl}}Oe6|i#61o6sj_@8+F!^L8~ru;jgfklFrG$-LN{#HU>lA zPFQE&(039Q9}O4jmaiID2-iW?Sk>F&k);|B5sxWRjpYMs!(@3WS2ZSJCcJiH zh1D$V<&_n9rA0x0ohXdlafFbobhE$7$coeKk3+NnQ-<2O*G_B$|U|#5c%2(wM!HCx{vSat8Cxf)7LXn>4Yx?i|+*+-g9w#@1hEM zxqEeUMnLQ*NNsu#NQ=}^fK$-hLemwHnc9<)gWIL3wj0CLY3nDTt>2Di!d-l`Xae+h ziD7A?%a4Qbv;3HNtqm%$%Jbs|G%93tY*e6oi;8f$n0O}I-)`H;_8*1>sP?y}g}%Os z5v^+fGvcNulTRkia%1o&jH_%ioV}Pq3-*Pp;{ob%?@ETL(-*!8ec=OGCfpYq{w9n& zAnq)`EnZ*Kc39a@#tZ0PAma+7+4;;7x_`gSg*V-e-wA{#AxW~Q6gHARK)%69is~#+ zFiahQJPiQ(s!U37VoW?sprT4FWunf10htl2rFb+3J{Zc6;{`N)WYlc zVuNVl1j5AC4JPQ97fcogkyR3&Kv;ocr#A=BIK$@h6A0~M9W*>R&_7(s=o1JVKpQ#Q zq(^o)>;%FV774r)2wM>?o^k?VGork^e;BtD2;YTK3X4ofN8tbhdHd8cul4-FeEJlC6;6115@c#_}+_DO;vQ!wEq0rfO{l7M(cfYUN^lVVv(jy3s00oSLQiE)8? zA$Gk&-e_L^e8Mz*jDU*W9wXSU24q-GThmLh97#aTM~NUxUJY;~n)1l(&roh@GF!Q| ztr|Qm@G#|=ZXfBme0-x13tT6ow256=_tRA2?pdm;v~c%~eCQ=w6C7P3(;IT}laJ7! zQ*P)%tZ>Eue+btl)^C>DSl6YW-6gIF8V*`180Jm9WRxuvtK z+}i9$MY}C2=X8Fh^Sbj}*lS^qy(L^Nhh6sNhp`uB>d^a1hh6p;&Jsnt!eN(-1;ESR zY~juc-dUGDFa{oc+NgMG_(->W5wD+c9Tf3Yy)8ajBHnw5$CQY8@&UDBw7irn;t>;O zxL}!xcdBT3xiB(o96QJ7CyBo%ig?e#I{jqjwPq1dJLr}o9xT25_|inY&xp2@A|C#9 zg&>tL1p%!SLx%b_vt@yb{yj@;(f>FK(Dg=dGmYmxHPNzZHB2sTKx!M_Dw7kVKp25?)cw8 z&{_UkyuN0Wh?RXMUO>}QGA&+0BdYp?P7j5+kbD#A6^|><<}{47IZ=H5tR* z;em|k6+68z!_;Z=0-CGES%he%a+yjwIOwba>een=c!uUMHPA`pqC17C4*yZnEj!76#LK``xsJH)Z zn1t~?iv*s8@qMDjQzVS<5ar#~)3`|(ufZqTazcpA7yy!8lIFuRj;>}-;eDEJ|J$aWeVZO|MzThV+&I-LENC8X2lKSLZjPa za^Y_28kRYEP15sfrfFQk?jpjf+OyCU^6TcUO;DP2gDqtEk%B=;>L@}1@O+NnY_wf5E z*EDRT>$+jHikVj$f}8L11Nb&&S}Sgz70wcI^9d+IUWY7)$v3giJed4}ijRhga%*8S zX+%u)8Yl7>A1H59&S{`X=k)^xrPSf}#j;+`*d0^*HdvdOwrI6)T{Pw8cPq**onPhF z$*+k++<}zRpP%2iQ_ku9O6PUww<&7hQT#BDpiFD+j>iaRW6&KB#X9rg(nrNd!$rE~ zt9$PuTnE)XRd0(&mb&+T;xQ%ao_s)Um@F^ls(Zw8F<+WyYPdn(A>K;_fk1tK#dq}jMRQK?wMyPvV5iS*dRj%%RmBNhEtF^lK zD8o)uSbuOf;)_nrgLLg?^F}U z%uHPQ-y!HM|7*OyhCac{z7a2=30oPLk9U`zDu{dN{`(B~F|tzTL$OSx!$w|Tsyl4N%*2&3oixONbZ?>)+!gb%Z`|f}! zw}~l)qTI?;1rS+xA7-0^38EbJG%LzY4*^C7ZaEf)@$AvCk)OW(L_k$r4Voj|i!cq# zaa7<|j@zXkd|1s$Z<=9}O~B1*L^LI0+{tLl1IX!=TbiL$Zf)ZR#ki%EW4fWFAzC9)uhh8?HSu?g|Wn z2bz1SaB0vew+?7}7VFV*Me(EGyT3{~ra>be*A1GLaQf)zl$hbaWb#F-rnJ8Dd_rbl zrQFh)Rc@WkswjlIvZDCW&+K0*$8=_;ep3dzwH07ao6Ur@} zTjkc~HhNQSTgo||U+KK={5D0qI)op_fs|>jW8PuHS>l*?w?K5-5VtSZm6Wit4HK?|%9X0OMI%eOI-htmF@R<5*zZmC>Bwfy+fl&dd@wv);g{?rKN>H* zr%!9;>VAfu=5|(bcBupx?l&e+M6}pa2vc5BIea*7euWn1c4jQ0a$4yOj*L12&bkVU_ ztq!)CaF&sNE)I{3!_?`l>p*AS7t2ICYebGx<8AB)nu#lKgSfN&-SPUGw!_Mv z5-*@TtBi}?S<(GoG8bbpWzH0OU-Wl(&*gL9r@%H=gU>XcA2C35vspZLQbj$@DpkaNFgJCQhPJE<%bdJE=6N-%Ih6bM5MfnqFlb(I z7s52GS5e_xy=vQZY*;ZxZ;)Y9O~A|vL<}V=)iG$wW8*p~w=^54+}dUhs#IrCj_Kx+ zj?2e5TBSNtMrji(cXplqse;30R8478{9^e`mOy+h<(AH@a_eMPMFE0?_|XUcCn(2s zW~Jl0GwbXW3#g3=4v$cErE~jWLT9=!>{lUZNKAb6wRdK(aP2aO-;majoYF)x4uaqu zLk;2*n*zPW^5@M<<6&u9^CE_+!&+?#D7yg5L}<-MYY?|U&{=+SyuN0ah?TuDUO@9w zGAEbL7@9{8SY~mgr@X6`$pTz^z*#8m3)WQBN!2SzZCW8G&Q~H00xW&z}czsRVVP)Tl7tq+3aj~(F z?!PZ{@fM-<-?pLYCWTd|50DLoojchE11AwfBWx@bSeCM0${E4MZ)cG99 zOqS1%M`PfFp==i~py4BF1ALlH=^q1;hbaBy;vpiXe-y(`FBEoghRx-aeo(Dg zCSchGZPfHP#hqc1z@zksi55?x^aqIY?qXuxDE%E_l!Bx;i_$MPXmC_8BMwxnZc3l{ z*iHNJ(*BOt%HoQ+{o%hTj{Mk-V_qwve=L1R#PMwTd~w`d+&0154JVNL$3!1tc-xdG zB#^Y9hyLXBTDy4-5c{7og^<|al}+q_*%VA5_Nk{?VxRbojnhI!UY}!4e)PumX=Y?( z^}mB%u#h*JeESw*8fNvW*e$ESV~yyr47A>N!sMEOn%9XyN~rzU(3D4V{flx-lU&NJ z<)DJp{?v_#wIba{(sB7%M^pR1lu_EmPILRKue^IOyUwTpgII7{rJ`$LiF+R5vYH(`}|J@PRsJQ^+1Enl$sHsLxbSg3ki zII;wb9}$l!5iH~bYJ+5XDOa!{76RddWrD@+VkmY53s}3^wM+g9@z+GbVrSTgd`fw( zS+LL!x}{(N)$-#@6D-!;SPK^TQzHb6^@U5EvuBT%3lDUI2#!Vea>gi zVli9``JeRZg)B%4&R^S_MB#3zpAoc@Fmi^e1Ax5%09`WZ;6dv(i!tk!UG*PK-Sdkf zyez*kUMJJYSfLBz1#~0Jy0aS@-9sZwZq?T%$KaDbx5A@kgF8!6lQC@VPcouct^F~E zsngo~LTi5n%S5_+qeYrWAnq)GI9^|a1gz`>@d6qNGA=d}(0v&a#_x?`FG8XuKniPV zA0$6!Bu0Vc2MkjOBnJRUzK>bATwG1Mm!n=Aq?dY@d6q`GHN!2 z(7lCFxLi!<4!kjJ{pki1^e25b5C*IT62nd}kPZ?sFqHH1H-^RD7`836kwf`flGQFnOPx@?A{Q{`= zMI!^PgTqCYW;*r0Fl}3_MAKiQpO`AZ-{DJKw;kCy?|@pa(kr+-~y&($26cgwoEDY-#5rQ!qi=p`K=?osG)D zC71M;(21JP9u1k8sT)_d*J58Sq>JVvuO>{xiVhXBRdkMO4rZ(_p||a@#7V%?7l=4Z z1fS2MDUT%l3gwn236)#hOm`MvhcgQGhVyD_pj^K2X8{_MLMOBvO z>tB+OWnJg^Gv$^}u5xRWI~m7Hy>V8*`MqS~Cd5jPPO)@fcZ!{DXaT;l3{R)(N@sWj zH08l}7Uh=CuySiN992Yiqny+EmCozV?~KTFsBrx?{eAQ9m(@mTiY!>T^>Z{8z%%Xc znhefwKQ2~BM z?kU_@xn2woLXi!x$~^HWrH!tjf(^FOycH%)(74L?5x*#CtAn@I7rgg=q&Gx*Vk}7SlK*YK(op+E+6lO^;$k-H8DBM&VlZaV7QMl%B!oF zq2aEBygYR!1TVz~cc*2tgB$m&7*$b9!{u>Plf~mwa6bmh++8*o&X&ke#b@L3=?-uQ z!_?^jCqf7K6qbo}fJQ5GPe9yR{QaHuQDpFy2{IOQfFG>_46&eytnW*y_keMvsBp!`va|~spcmdtVWYp|FhVK6r$6y}oV*%N6 zABbA^BU-lHFCHGA>)MN9r$(HRzi>Jtz zrxE4dCD*vgmaQ;CLDHKgTNWEMI3k$Q2C7xJY&o-9S%MFKi#IIx4Hj;fZ9?gm#<*7D z@<3WSG=A;PGL#jD#aF*kjNEnS%-GD59M+(w%|;K1IQ6xqfKNxeh<(E7qtIWRUTL@R z0g>@WQwT-I3R`6Sj47BPGEz^oBICvZD98j`wkB>ndo*Zc=2_gXd>K1eA!9Uq{4ik} z))}d&tsrT5w}RVHBMMWXU0;^FgX$|Lq(qukQOo^oqjGAJJYjdD!4i*#H* za?#@9_hghdvCcNGklUEDwN^%~P-$grH8kbrc2mkNom=JB<~FKqZAUq$^DCX#o!>RY zxYTe@!IDJ76Vujq+MEF|HkSOYRS<<;RysjNc~OPQFqMe`*9V{#oHt?c&Ob z@w+L^I2}>HQtU2urvptJntczw+_0xSFTcmYjX$hdsKyW6zF4IOmGYfx(5`%a4rU34+%%%r7L$;BCcz}d-*#S4GqCtPRu-*EpG2!RDnBO z?Zd-83;W@xk?tOGs|)@g99>y7RGF&QG+PUK#_R~!A)bMD{@t#uV*0TJBc$@}r804|>0vc~JA8fp# zdyBVlxjN|5B@lUtE?pWA5$V!J3_Cr^p5aWg%jwc6T{;SF9rOKJi7FH zqQz6_(rbwF?mRqhbm=gRUy$@>(WS)(4fbv`;y|_Prc1Y|=E%A`M*0d&=>`;23U;-U zq$M9|mygyrJH#$seD!UlZ)7L^MR@V^oP>999Z$2S@DxLm)%K7CitKslM^10G8@>RI z`aM$!Y1E}`8ugc^U;>RwJ(daCGp^m-2hC=Wmi^gGy0{4W8}_n7is)_s8-!_? zH>JX~yy@J!Az?{By+4DQGyy8>ZcZ%SX~u6&H04n?n^SIS%0{`htr}!gccdKCttB0o z4{S7>I!#7t6Fb#*SG6df;G8ZdiM~0z>a`&ded0GCaYyiDIE*rN_=Ti5Z_O9Z>LdF8 zAv%B{`pU;h5q%c5rX}V@6f<%a-D% zCX44exOd1`x6*USO8<$fba5s3=XgytRR0h+HI=@=sWj193$pAOD06FVXt6!fv=+Y~&BzOL!kVA|$k36b})FwhI_` zdX00bGi*9z{pGcOGyebcPuX9mV4y#Z?QK{aCbWIrB7rBgeS&E56rt@FqP)8f8aJWs z129TK(wil;6&p0zyUmCL)v8-)+p=0k=^q#zE`Gy)LrQ5w!&;@bchDl3dbrlw@GgS* zx4}ODHELqvD&9HVGE^B})H_mjE#dHhZzHE9xK7YYUV>heDy#j}6vAEkRcu-9kEURP ztVTV}%4%;b0fgl3EQu1fn>||kcQec4+G5gH#Nw0Y$|ew|VP%bq)GBMUYlDJSee^CE z=F0?#WJDY#mlLL=DUWj7fpSYzZpy7~%%Ge$k8(^mk#t->e9>~+1~N*U*j1grDW#F_ z#rlLG;|ubs5{HfhOmI( zSdK5H>PqMMqJ$iOh;mEkSh=-1j$Q$|m2yt!S30jdzlA*&=Ga@R)uJtYnIFcNC{u@x zOwxrP6V4K~g~A1pDZ+!$g##-IPZ)jxYtI|{eo94314p{$s|~Lcu7hfWs<%ZZOKtck z@t6{|K|Y{1be5NL)dphP3>Pd@8(uWa6SJ;y)Q0E8UlY}aD`6%6g7R9k+MpeDOSJ)( zTYh|LYQqj&YqbG?YJ}Rbvv8?);pJ+>uEHq7+u=@pCx)HgiGR@9QxF8^7^)4&+7#$@ zmOo)09}i1YxJNTg9aicZK-m#kCPG^_`cw725OkL3@%oxwAXau^ynyDNWL!Sp-CcG; zZ9w;jG2F*Er!~|Im*iTAWbQ{HddWR`D?q>9uV7S0v5}X>O-&xJ4I_W-sr%b)Hk_53 zpNl)=0qQ>RX@;rO2X25qa4VLH^nnN`uNpLV_r}DPKMrwc`D5|=nzqBrJ{m8e`+$s# z-3QS9EixBx5$gWukR%3m{}Ll9si%DlnJoWDJQ@QZ4CSx! z0vbLtYBqe(J;0~Q)cy2r3?}GT3T-M3I17f27=DMkz>ov#9%Gg9b+hGvYwC>Za~DuV!k8hI$KE zWZp&*_rk1J+WthETE_=#(q54ByJzBG^z|4~&*92QPiMjvnUae*!l@x`Ykf)rQ+p2d zBd538&1>L}%u-VbH@%-?lldPo1rx}8>S>nDUyp=Hk;)HQ%^ofJt68uijeiq%u|j?d z?AkRez@-TBKk*9wn?$#~o+uOM^QmAhpFghw(6Ah|-gLq$D*-YO5J8oY`}d+LkKuZP za!WH@%B>}!g5>_Ql;c9fsrHhN%Lh1`+`n5!X%oA$?zocK_h!HYAqp|4@xd01IX5U*9sJQ^#?t;NbjoEqfD0)O_i zJ%e&hqeZ%|8!f8~0EpX`dJ5rSM%|}U+avOJ)t>w~cBf2hMa^EqSt4pygCabT?2J|A zf#hT=EE*)rtp&--UTcWEGWH*QxGba|Lc>Kqq;9x4Oi5wjj%ixwQ+1^^t+NyId^zQo z&a-lB^BmQ*K1?~M^DCX#o!_QtTKDtAxQ8;WwKqN>oHegEeh#b3>y6J+VbLg&ZutV% zF9_E`0ZY}}!jL6k{hoMCiGU>^P#YA>OSu9Tu}%yZEEBL6iD_4E0L)t6u5t50@z+EF z>l3ga9a3Iv7O=E~ZYf~F7Q>G(O~Be>mKLz^r$z`^vxG}E0hbF{+X|zqg^JUe^>vwT z7!e zn)Ox|S9&wST8#AcFC<@dHO(!J%ToUhSLZ<@MOifDyAI=g(o7I_>`%X#b@$ z<{&x0aUg8H?F!nMi1OtPxfEAh>E0o}N=zU;})zr#;}F|z=&S8 z@NXHWP7B`yE&M8$3Ab=ecU2+8%uHPQDlLeFmBfEybN3c%eS(#p6fdBWAmd^q0o|7& zVf=1aZ3Bst04eO6OfnH9vlxlF9X?N)mg2dZUy&GEX|D1lZuGb1JS5$bXK+gHrU(O+A+}I)w8gm)NV>Cwbr^;!S)WHY3XbqX-CcX?K_p-%!<~=Xn1%9q%oE8?};Udd5=LSb%p}V{RH&iM@%8) zjK0Fwf4^-CCg{J^)2#kGJ%m5G;!+7>+*vQQBxU%^?*f5yHlJH&0? zM+4cSCx8&vqV`(h!^q|_W8!*r~D-WLm|z_ zW@JyH@4ygv5W0*CmxhpXYZGs^R<)6^|KP*uI_e=bjO0V=hLOXA6b8arSG}96E8SJ^ zO33pglv_H_%B{_FRDAs=<($s1bY6FUr-v3^YIOXXS*gCP@G(V}D!j__Wvceiw7WY3 zkY64bYxAEaWc-hmTRP*?ZFrPf1J^Hhjj2h>s(<&PKXE%^0;HQ}0%cn3$TL|uOB{JF z770rmXi}PEGb*}ZbIj8t;mq#I`9459NxEW%mI8og6Rv~0vZ}Y!!(hLlTXYis;y2?w z;t?g9vUFZ|4=WILIEsZ43iDv(b)fI$hj9XBS}PjgC7d-KjmKb(dDGrvDmogC(k=g# z!-a(FAR1M@EgD&;9IhfBQ-VnOfZ7mQUdlb?K@jhyN2U)%aL`%Hf+7W}H5) zPdR*@VW%nG#~gBsIOX6golQOD@GF}Fy$SXQ@z>&E=|c{`WSBbg#@7I4KgTj*c_a3= zPt}AmGZR<7;`XB5vwVX1kK0v>Y#_9(ZZWLvzZn7UExx8@;_~rcSe)fEz*Ke)bpI2E z`4+dYe$nmj(?Am6!f#*^mvur)7kdHu@o z8LyG9{BChmQ~4*I%168H7--lh*?c&AH$N38$K%tfIDuj6^xtnn|2+oFMEY-|uNa>J zacB8JyuPOCu(G}J0$PBSak2X^x}VQ*AM3waTU%(CNOtI}ARV$phqstMGOlJ+_jcGp zWcihGQg@JNo)8}#=K2m1Qj`#ZCafxf|Bar11TU+8@BrnszYXrM1U;FyE5 z&Lsmwoja1peAX=b#660Cy6dwxWz%p6pahS?Ch6{Y+`9AJ#V~a`&oj_@Zo@L+&XcIp zD;y-2GQh~6gv5xCvc{t^4UVBa9xtG~mW-O+wb1=18SZ0UE1>JY3Q@}*MCFMtrSi;ryrFE^k{?c+?Usprl$FB4*>Vq3} zmDVot<=$4HQ>97kaHY4>F(S^q)^k_;%veo~7Tb)9ID+8lL{Sq>DB{m%UcxQO;m|jo z5x|lh0XhF*QwZh!AF}2Acbb9;az6F6sGP5X1QU=Yv`UnE*SJ*9S4MvNa%!ZZS@kZ$ zG%V*+fm=EMolS<26`VDR0ke4mv@RwBE>ZH|i>5rrbQ$HAW=xe^+x|f%|6`P6x-F&S z^1+o>^3Rn~+Qe?j>HOGvXLcJAD_`MUqd-go2Zi87AW8lwz(pQ>Yy-X`%{$-8p?l47$3P+?c&=`j@w&2H+ zQKq$mXDi_>5j=keyp^88ps+F>Ys?#3_oJetv7+4Cq17I_P@6vc4?b#+q8>tbRr!#* zQRDDwId4B`GKvJw>5S?t#c5&O)MWl=PG51lHcwMN--c9NvHO*OZ@fkt=I6#uP33># zRG#SQg%@6ofvEfun-FI)>gVF4@c?x$Ze*A`UH+HQ<*&mskuKk8QTdAycb4B5udiu4 ztn3%!1$38}ak0BRy1z!|!h7?@_+5(rJ|syF0ELyb50K{>Nl`uhdkj+tAg=;IzAcjy zd^JX*1gfG+EM=n3e-D|-^4H_h82Df)zm6Bs@R3oo;e+l0KCt{LuB?hPO>EW(h^K4L zF_@sm)3t>GXMMCf!%nY{e(emK&X~VkJf+3ct)Pt@>BQrq8YZ6ZXpz7ZPj@0(JViX+ zfhg}Hd)&m+-@+&bNpF^TT5QnZs9;7Ms8-$L>FnxDsl5x@TZc!6TZMjC8Cu+4e2Mjz z)Ya%>nOcR^4qCn}y0_P)bc^{Vxe z2@2L3(D$4kZuj>AakS4ALUHs@Y;p8FQ!qgsrJiQRQQ~#z#Ws|?bIa(ki_9M7n3~BP zH!D|R?=7T}<|Z#EOv7?1l?p4DdT+uOxA@bsI|CGZX90gUpdsj5K7FTOTs2UBq>NfQhNBYUm6UTjztVZ#`7IC| znB(}s9=Sw%2S1EYQ>L|c%DaTKG3u1JV!e5t@<}R28Zy!?UnqQza2*s1RlO}HSwi7U z#A8Z?LivE&a9Li;6$**vWVm3NP}n2pV!4Yj8v?rm&O60l6NSP*z(%-Bd97I})DF6( zPzd`JKfW}f@NI9`LLvUt2%&Hj;ZjkE0j+E>Qq z3PK^e--+QqM)``Xq|OG1)B_hm^imG+HbZ{9FJV+hi2=iLQE{MZ@*7xT&f3Kb>k59d_&mzuRp#oTa7Tgm=aR)VcUH!_?`z|ADT1E0&3L z-9`(3k3-zzL$&exnzqBrJ{m8eyRM9j-F4CZEixBx5y9{0kR*oS_Yxy1s*nGaVd?;6 zg;hl(y(p9NRucUF1(^{as*Oiu;De$3HC{l&M@G$t54s2VG+FSQzO%suE%)mZ!S^Z zT?>ty;5QjYDM)&=1ixZ~21f-m;y|@buc`Gd$lFy5e%%AZBduZ&*1ouBV5o3max+Tp z^9s}|^_@n`Zk}(e^Eqms`$`48L+Ka6Hy_WE%cGSyZKdD72srDp!$F*m>};_PqXsgj0lKi_ALp+v!6X0weuIUH(?hoWRIp3 zuP02ysveaAtLp7hFIcSdr1#gzO?EFfkd0iReSnClMAEw#O?hZ}f^tifdCIMA=Afka zEajMPEa|v>P^2ZjyJeI%vCamlklPry{yJ4xnp=NOK9$uI|4F%}bF19i+(x@+2^Sbl9C1)g-I+(ph+8urs>gH4w^d-_w(Ugbk*_2y4^U|%i#Htd1-)1k7dXtYF z_hyfl{@owH_N8h?H`!j4X{|cK{=!+Jj!+PYZx%=v0x@HC;HkqYP1Z(59BeZ7>r(p( z*FjZ5)!XTfvDc-(hj>JZq9C2u)*H)9xrzcYm4yqIDGG~3vpb3ctU>JTn-7Y=CMpW6 zz)E{ad97Jd&@whZE`E7=&Lp!YjF#9H!iSUw*mK1&iL1+1E z@%ox=9#;01cmYi;$+&#LyW8l3q=4?9l)3PD$uYQ&GIdwe4V=Z9kAi8!#vN9O3wRm@ zD>Fn1p2_C}=c0y(Pq*<(tRrYfyldoe?jfQ6S@DqX69l3K~H#id$%$r64Ka z90;kAoHTDe>7(UfMurqsy?@-)WPe>}*mUHmz{QDEY#cO?dK%;LFuI@2u+yXa`gApy zU!0(M)In$?hj;N7`3>Vy-(!)$<5ABcT0DhET}qU9CxCI|Q8$1A7n0sA9<|t@!Qszz zZm3q>JnA;p6xeWkf6qwIS(O5XI-R0WwQa5J>5(*_sofTc)Bb_Zp}vGG5l4i*``j1H zc>+87F!Ud%m)adhfF1p!DTM6krfhcf|4hLIc9eRWWk)wEhenYYjhfCL4Vn0J;fvVQ z3hAQhgy#vhy-7z|+NEBKS8Vj1ms?4K(GkMN@VomY_8Cpxjz! zAjpBPOF5=nNIEVb&}a_y_cBVG*r}*xU>8+PoFSNFBNUKo@L1QYFaTcf{2~=BjUDNh zf0p}y3D-f^Rn^;qlXaH+yToHkm{<9L+5lQ!%4J@OSu997xTY0USdDRZOCG!f^^5aWmUZ?D?nOFR&5zOl};WEm+t}cw+gc6(+GOtq^ zc6x6^|`VnsSqI`FMBt-38(m-EYQlA3MvvdRv=a)sduHCj>7^HFp8%w|W<&DvCN= z5H~eh+%k;&u|E?1UYiVOspjY6!gzqX2b|9^b$Y-y&;!oKGLat8Xwvych&#(~h}YM& z9ai?*cmdr5WL)eXfbN&dTzJyM_`L(^K}ZtgNc6*uq^QpFMTV&ZkQM;QJu)e8r6bYb zgUn?4cjD0)_+Thc#|voq$f()yLH7WkMralRD*p|5gv10*<^LrfA}$yH$gtDPh3%YS z(@`9jQ~5NNzsepG2Kp_a&7tzwg{Md)@TmOtMSk?oo=GYu=w!^|8iNE$QBt&164BItBakt>G6E0Ol09zbJ8KA>*QI3!JB zT#xB#@1*KV>uJX)0e@GWn4bqUDB(dqoMot8SY~`n*6rB+2)W+ z+Q|^UWB~m=k>B#CFsh^Efs^8Wp-W^z)$EI%@?k~$=f_qa<_6R}QJi#&0j0#v_G!h#OntO}RXy6_6?S7mJ-S?w= z|B%WUTo8L&JXYbw*#`Q9!844=)mZx!!_*lJ_JzUVNf~)iiruu)TK%gKcb2~rudhJ? zR`#WM0gVC~7aIlW9#9~~Rv!uDr`N9}E_o|}6!x(`NLCSck(H>PF(xxi9grLVAXx#+ zglCMzuMerH5=)t=^UWYLSw15kje!t`GCf{ELr6x=h7h{95DJ%zE!F~h{eBR6NUuL2 z9wO@X`!MYEw&WmZX|`OiZ;!pg>_liIN5}Kjgoa(cYqvGd5%i>ItGT8Z*wv%*+Q z>WU-nBa4PxyLu|Uo!+A25E!K(>CMvXiwzp=-DbprYSpdRw^U22!%JERhXxjk_vj55 zl=>NzQtz18s?i@!tL2VoPo3XA8(c8l+mRs09~FIotEDpiCy1mUgTCbSSWA-yuHk*e z6hh_wNVf9+Ia4q}d8eLcmG@18Fu~1Ax8+1R)?z~z_GxBg+`c@9-LH^0n%aMaFb(VM zRP0t~xA*Z-fMa2=0iPNAF%d?Iu>J!y<&o*Xq1@7Bx^ipVH7KnAgK|u_kaS!=%F)95 z_hpn;Sf6U!L+-%PRMXhxur9#+}aFBh0!x9=X8Fh^Sbj}*id4Q!`%~3y+pnhvy30cRg`J19rQ!O zSz-s>35ulk$IG$Gy#DxkDm)r3(k)*S{W9S?D2b|iTR5^L(Wi*Vlt`lT0kuK0yp$`6 z5(|KE!7@qo1~Cvjk|?a%?3yLNM*KBV5`72kJ+4(=YnDW{gKjB_Lbd$((j?IdduvG) ze`6#0zMqO~&Qp-Q^Vuk|?_0nBhLgvWcsOc7aL? zqVI;_CE4b#W&O2L8>1?UqCYimYO;7-821G^bPVK*vu!e*#hIUrbK?Q(9&i@J)ad~y zLJwGsWgHy?q0LW)#Qi6I`qUfNaN-Slf&c6kj5ijJ7M`PfFp*$Hcpy4BF z1AL^~6)qPWL<3UA>+pz>RPp42~f#O0kMXH!aly{dD%{vSckt$AuQ3{gYEUBW{puyg4MjWVC-BQKY)qF9&Futd= zAX98i$rQ@8R*B*rw1QwN0Dtc4RFXvH%x<_k=zRJF7lJKd-P2k1J(a_QzKt@0?l`U; zGAs7dx1*rvqzV)7FojT<=wJ&IrCBD(1eE4MboQObS| z$~m21>Addz!kO&dGc`#yL{Qt7AHz(_v{t@;d*LjRuP+E{X9ySwK`pqF@Wiw&vHrYa z?;TXEG;X9@K6!sK;W|j(t9n~tPLYcgE!XK^{m$P-Jf?)amk+27oaLol@}8J5!v)L8 z`$I&dJLEmAYwR4K?=SwENZz-@YWzUuwPx~OJ5c03RLhSqjl92Jw4J=qgg-TcyuVqv zRQs=T^8OYIGfoeOW8Co0{+k$fdN?_8Xy#JC-fnH8st`xx(}-wTLKACkQP zD+Dh|2Y2!3xBA~1RZ)E8pW~(`i#=i7k3D(6-hL(-&N9u<#oL69JE9Wmo$dkaFif2u z&htw zi0rTf;ZoahWrVzSCa?9GRUz3Cj)WY@j^HmL{pLT45whwE?_iiZ%|8Ime~1h@NX@VA zN37R4#eX*S&KE*xSzd|P$22ciWzBYIWTVpW?YlG{B2MQQ zG3@koeuguwEhpEb)A*9)tvT63en1Ts3JM}b6vu_-L zhnz+&gAli!JsPwz^DmO^EALM%8)+hJ5@8x9+o`B6+3ubEXJW1aC;zu3!YE9Fm#mvV?o#?j(a`7xYKnL0#9(%Jua z3upCFl~aWWK~+XZWsj^p0VCj{=4>ij8a2wTMa?7_r1dIW{^IxT%P8kGa-{RRk>l)6 zVR`F};V}{6<5XQ~5#i>9{C^AI5W(X|0{}Md2*5bDjxBQu^X|vBJE*_%|vz8Y|K*UpSa@K=mve6b@9qEf`s+ z{?{QMQz9J52h;}0@=~sFKurGOf@Q+NPtAhMtkfLg;D_R`iNe7W*lGMod97JE&=lH^Y%-iRnxBiu;{ocf@MVUn(-qzeUEyIY6X^<#RuEo8R@%oy!!^%DvFQB`E zjEmhB(ES547oLJJes3!J2P8@Ml)?hj2gtt|Nl~5UZwylhAQu5Z-jGQNY7B`7`BhYj zrA*ZMx(6bB))xPXXln*O7|I&)0vbLtYBqe(J;0~Q3dPP4c}StyH69`=6gx5O^t#~^ zXV_e>P(&4q!=Q~E-qYI&HtbDB$6F-u6p9mx7Ee(qjwQ;wYm0GHC@zIj3XD-|h}eXTl0$-9bBNHA6L zZUYRC4E81{6(#Q~avxyC3cM1)@$c|lu`2=BKyPyTtlh~5-c@v!DTF)VE7@Ab$4$Wm zt%7=*)hgusLdA)O)~d)u?j}sbq6HPc z6)g%k1bFDM)Vkh;!ql38nrDb8N;He7(3Hn`{e*H$GhWKAC8UCy#cwIcbOTApHJFPb?3LR@xt-J zThCR!aEl?koxu;IpE7l5z$DpiSU5{$_6s)z?ic-A$ZqjUPT2=<43yX zv;8*{u7hm9s<#Cwi|xOYcuWb~FCS1FNXtvPY(Ft;h6|Rl{g;cDmkT7b*0B?P{(kY- zM7IBOShZiKyw=S2YX{wu?T00pA72{V{}a)6lI_Qz8o~CzEL^G`dpX=?1K8^jA}j!MSm+=?|?-rOg&KE)4Sw0-EuW381>|nfr#=neRH8~(rkCp$D*Oc>bV z5INxMo^Ch20b!uU6vEB&C)mQkJX0`17@(eJg@G9ncomfap8f36sGV5~qBbyJL{_!M zqp7>Y3DdAPKxM#c0|z%0IhNbjds&#Q6A+aX;gyI6U1-W9&d#LV(!`l^Yk94pXmBy* zm~J`gxP0uSMS}%0N}Jft<2_ud312gxfn4ESasEuMnkGT`tpgJGvxoKHIY(eaghzF||Km&yJ-`BXeCO?f}bFm)Ks+W=)> z!!i-dyU~)*%Mf&y{~}&r!ysT~e;O~KIZGLrkN3hN*8LJQx_^w}J|_8W-R6Ady?TKv zH~gd)H2E;o893{DA0;b^!tSUOcze>sxT(qd9pQd5_9D?1Hc8HM&dT)odQW>h(xC` zlA=VSlNqKCK<);BoFJ3(RuYL8L1u);7>~xl2SXW*7trvLQM2KL?g2hc7KyHbM}$P8 zYvUoJNOU#BPA@OM;0&9~MWU!kbi0Cqrj9-Cr(yR%?zKqZiA47kEuJD0eSs+NEDA%3cQcw}f%hj{nX=mts|sXjpD6xA zj}$h~tGBcqSn2BN?}3YFEiE#OExH-<;~^f2?WxwT(9us6Mv;JVg>o#zPG|E`XROWN zm^NX8uF~l9!7(a(&(tiFZzE9e(%Vz~!{Pz)m7SK(_K|k@4J2w9b6bad&Z_8t=<0-@ zWXX}9zRJL&5&IAQ!#((CD`$B_^KhkCyn?pZ+IMs=nKQ@!3J-4Wt@NvZ**)u$?!?n} z&lWA}={$4Kspsse5&ZvefTpLRklYi2gQ7z7KZ({?9ptMHDx7uesx2)?R{9o*o0QcE zUTP7%k}@j5_dSt%X#Q>q!%oBZ8KV1&F1%Y@m9#McR^0V=VSi8{X zSIA6x+{G?!Z7`S!oSZN$j`X&7b_!q&X9HasP^Xb+(XDoZEa?56EHbWOmP5@xgB#ymJU|twuNWU zdGyME?=})c;`)H|ECNU?y~6-$6=PXI(<;IyvUe>dKMLok2WK&f5{GPT>}266M_i zuX)@;*&Yn0@i)~v0+At`AlU0nkH!MiBQe1szV~W4?n%@IeY@%ox-aX|Lb2)U6kRzi za*-W$iY!XtqSfL8&W!nu-_8j1b~(VG#xQldZ(&UgXcpjV+OyFt-? zS%YrX)&{#s(VFwy`zphO?Hv{I@e<}rO_n4Y_Gw6hTB(6ip;ez@#Hw2LDTb-js=vUM z8kPyS>c)X^bsGn5Y>U4N!HShwyr!nbv6?T%3+NVq5>44Hj_%7^e7LPmkOHsoPc>N73 zu<|4E0(y3lak5c??#ocIm*j7NRu;fGqSC)`q&va`iN!{LwqU8a1WqDkn(L7O$+eIm zxz<=&Guj25T+hgbUPUrY9i03YaB>xv3FBmTVk$IXlFM1-+zp8lE75pF200kco$&%1 zIWlrKa?pJla*h+5LR^UI9@Wz+bT%=ZRED+_G6uN`ReP*wR|t+DTSZ(Pyg{TrWpVI(qWst_4%WoQfg72-EBm^$rARc+x3Zd|+D}YKLO@Kj8%N9n8b}J1b|RTHe{y)m0gSPTfAz z)4woVTjHRP9-M-u~blw38-vyq=Cw0v?@SjmiRk!)36o8)akr` zhR(YgmI-&>-D*q+Mk_jM&E@TsupeY8%lC;#XrS~b2yb4zfSwX$CfHEI>{%#<%h89( zkJn7K7z1GNUh^DrTXt>n!@A=CoC6M{D+%Zg^@w-Pz;)U-_3lwuF)zIBb{*opQ_V-6 z_B1!p{U?Tnj~0+8sy@3nm-IE0?JD6i@tJ^_^3ziEWxf$p2v1A>gMC`+VpA~TdOGzq zds=F(s%@9-Pv)T1Xqm-q>My1*;e>M?)i3BHQ_Bd`@R2DhE_>;GD}Hl#+ndi@FffAo z;h(3whX|~jK1KIAH052|`wHcjJ}xKSdZ%C2P+%LmOnyx>hs0C+GWsR3lg0E3_1*>k0F#r|aOoN>y*$ z;FDnF)KjPY#c#~jh)0y%sg%yk=O+5K19wvCaUkH{sU-S(`Qt*zBL~Gp<#=s|Ugvn^ z>Ef@6$0Pp=^M9Z68ap02{n!f3u;N8;?dIf%VU%@agpEui<$H(*63^ZZ{!=~!ISB;} z>yu7@hidPvipCax>e!=>QmL^pZTXFmcJXt*c)B|H2tQpR;C?Aou@j?#Binev6pl!H z2Op1a9}-f`2zhMmc!)^$nev;TCkmrT$nxML!%pY(pCX_7kU4R3%s=dLwxIU$(0Iv- z?F^SSVuN6IiD7d>SAgEVcN?6S#N)W)ejprD7blI#t;06V3L!-OgK0xHgLQzU~7Q)k=p9{_kSmI-e=j%z}a(4(2?c+@y!j<9Zd0omqcjPaMl zVOrRh7@Y)O`?6>lk4M6h+QEVT;YzloeOUa`QR!J+>C9#d2GkChmJE|6TTx(9teX2z zd$-NX1jVxboNP&tAmS@SL;VASOdZJv#MOnNB|XEH9b{h?K-#_5YS~QI;X^?3XV6B@ zOz)2`JDYJVA$np!|BXcg?>^h>M2n{kCa)3Y-JaIGGiP#V>*B$a8&?$Y#H2UtK3lOt zgCl}jxLj{J1ywQe7i@T@HA6eE8gWz$xHg>rdxY4$Vq-NB! z;cs1?+hrEO4&w{AFSb)RJ>blY{#k2U+d0=o^xxE7k}85o(5oZF+6!EjysHjB=p$5= zdMlAYEp304-`(v#CGh6MS*8%~Z&sNmu*-Ur+McFh0<}av%~DImTrIH!3v{~^4VulS zW_o?)vsF9)6~OZglU**qQbOH)4Q4u8Ou-Uce%h+odBgCBIJ@+9#+tlhnXdm zTbkfdZf&avUwL>D<(O_w>9~C4q`8N78Kq6^hNWYUn*Yu9**x;5!;esPr}@4cWGz_z z^A5@_oongVTOCyKebs`RTK!f3!S84fQ}v*m<^jso;Ufb3f@+TM5#g*pj_)YpL2!KK zbDBr=rL@h9RG^`@aYjEB(pByWQT;W_HJxr*akEP-;69y9Fb4yc>W{=Gi zDbrdZv$AlO2$|;rWlV&;iA}>BDYvBJq7kCp+L3aSX$r9kk-zv|awp0;jS=a*Zj7uh zF`}1V1l>_J;4pA9pC89NDAQVTa-otmx_zViE?XkVo!Ie;l%!fkC(Hk zhtPPD52+h3Q|(P|HJvWjqV(t__#6H!z#D(@t9vz7U0PVZG9lHsP;Ti|OSk;DUVfHv z9aLvjy=_~{`6VYfNyk)Ayg?kQdRrXoyXFds`d7b$u0=ei1dH+kwPCTml&cgHd$n-EvKOgr zC8l>rDTJN0-GS$s_-mq4I0fjW&6U@fQn>x0m0s~-XY+AsJRsK6QpMVwI`h<7ip_^%WOT#uW5rXekM2*HIboK4EE32EQYdlyFK|h-R85M) zqDu$5#QVyS(%n_n-S#P-Z36OLshGM2x}{hE?dk(0O~q^%PnRkt{&YnnRLq4CQB1|` zVdk^Ku+xP6REJt5RLsKrFIw8#Bx46x9C~`iOAIQ*9YZ~XBZ5&ESEZ1_@2o8D>7YeN z@xlvT9H)O@SG>sPK$9N+sB=j?E-f9tk74RahpPdq&ciZc>9FCqU2leBY(3-5&m;(ALdWde9mS6=KPby9fVB z0|Ez$w|huztX=Jwz{mEGEQyaIOJOpK>yg=v>?n+E%P@5?vOZvB8!QvXNb=<+6%*cq@ zm_hetnAuN{6H5IRut|G68;P8?s=N~5xd}2Q!Be11Og3@sxtWm}g`W>IOdb4e0{FQW z%Y^Zh_}VoURbnXhp7aI{5Y?Niq_iRp~k3Q(<%N<$b5sb297Vio@t2Wi#dsKn~{yN~#IXh*k zoWNm<*GwTiOtCrpFvY)2!GyyU)YI%?iVeyzgTs&`C`Js$h1OC}rn}-Gwfb?ydXtt3 zrV^&%BNbGz_DIFv4FQK$_cen6qgVoHT8OYpj!kThraZ=Xcgiiz_$s%SkPRN2IGA!w zx0rNXKIqZMCN`H*+QbI-;4;_jV-u}Z-RWZ!r^s5cj!pDZZs}Z0w_&xr`gDYv7_0x_ zccycwdeBXC7G>%XrAfyo&J)fOg^t42s5ONLacm+q7kLLKQd;LGD%4QxIOAO8;KUu2 zYdYbw#&!3F#vhz`f*-@X2wdccamGA@w~JN}L|7g;c0XQQIsiJ!Y@H8KiVTRXsv7Yavy) zK(`c9VRz&MBuz-YPCQ)-srXYvgw&5fM2gI_*G3Cu-bXP{7LtT^jKcJd3_C5PZXxoi z?`Vv(kovIAf!+rBqs}AoxU`V^Aj8xlqqYWA-G^nuWK_e2)bB&kS^m9veN7j@%03e> zpy?(Vmyh^D_i}|)bpHjJ3r{i|Cn5C>$dK$BflZu`l)o^tqiD-NGE5z$%mSpmF0<1d zA$9c=5E0YFea_TF z(BfNTnef;U6iHP8K^ueN{9p(<%MXm#)L;OsxnI11#(<27jRACDhJkSuGCCns5*&pM zi^(Q(gk6lxD10nnm^%2_5%BSDEEC2@q9mcBN-Slf&d-I+Wck_gXbgsCLnuq*1vG|a z)NBl4rYwfSQADv;^?{ zfrzI>)%Y!%^5~a0DYrEJqTE_`B&cevb|SH4qnk=PE*}ADRpV6|rA_Rn_GBY9Odvd+ z7r@1CglQYS372leG-LH4ZWtD2SEP=3<6r$wbs$wEx~2A`OdS#< zN#r8#5d*WEt~OF|rf z!r)?X*jMnw_yA>ED|r4#I7y$|YE3UdO(Z3XjH$bjv5QA0%7{iELGGJ5+1t zTCJn?ul_*r1o4;>B3nM7Hb|D2a*1qWHVzjoBeL%jgM?glnFW+(4f9Wnza|pdJHf`_ zcIA~Ovddo9>s)Bj4!R`|3+p;RzBC^8AENCf4~suhJgi!i+ZRiT&kmStQ%-~%))x?fM`!lPlYaBreet3Gjz^f>Mp zp~}9;Q013+bEBB-OTNsodAy3aT=Oqdod|6pshrrl)(7M}8I7R0o#Pp%4j}ggKprg{ zA;|Xfzav$5#?_)eODk@ro7Z` z2~pndmd$&qTgg5KrUm^SQN*82eQ@9~gAx`vJrWX3$?7|z65B!Ft~P}3VNjx!fPJeD zo+ln>m&ney7O&4VFI`}rX8#P-h(Q8>j*%EOP~6Edbq0#PVW9XlmI=>XiFB@tDzTIq z9`mn5X0rT$c+$eeHBwF6F52}y2x34^!C?2GVRs7k^ET~N!20hE^zm{YO+*LWq6hd<1 zP`0{rk|~&=?ody&>dy2KXk_4)P+}O*9t|7$>Fc4!37QYB5T;>ihYI|yBkf#7#8V>e zT!5xLLh@?LElo%&x3+nM(#|cEW4fuNa4m>UXN=sT$EO^(&JTpMM0UO)?VK(=2x%ua zIeE%XN?ZMn3OCeNPQ##@qnd$GcBY(My<#e%(PfS6?jB81b~fjSF@rL#6+2rBXNlN( z1K^efm5s5+ym542Dmoe}(k)-unNPS53OlOac976Yj^5pg?<_3p9kKKlE=^7$9#euy z`GDFGSzgK&c8Iw+T(C^o*-x~(BkaK1$*#HbdE&2$!p_04BiLJcty$R74wSG1)$-#@ z6Lzi;Z6}2t{HYPb&NAUr;iX*I`4EK}r%wYj2g1$=8FrcxILz7GjPv>W&)Xc(!p=SM zxU{hIIfki2j~xLpyA#WV>9K|jJKuz$v;6K*9*Hkph64q@jtXoFgWo!>ATLGiV}VwgIBJPH8$l5B+kZeeG|cfr!lTb7SDTG&}l zJVOD1FYK&=6|>VDPzot5+^R%*w_A>@u!H!MsSgeuW>CTcZ!$oxgdK_Ppl^3jLiaEz zy|sj${Vi|`3x0pocVMKgVF*?O#l8$vXP`J128wxDCOmT`N;IlFB$hH!=chtuvix1~ zXbglfl#}8G^t>jcW9j5tuOx`myY z)f|2Ag7(&-_Wp&%*N|;O={m-^R#|5$t+p7yd{xK&IIbz)3Lh5DTHqa|v1>hNMry*A zeQK&m!p)5zLChN!1mVQAw3=!&{f+;;Y8(8kQ_ z$Xxv!yKy07G=cqh!ZfT3QBhk}=;USt$jTd72_N*WEkR=jG)mRjDahoJwA)3yz%JElv_II(rvhV ztb?Qd;GARB*vonI}H7qK~rX z`-oo@m{w>h;OO6k>!2#8>TRc?=!dwbo=QxebSp~db$7M`WrH(M7^sZfcU$wr*n%>x z6^t{5vu1;F23D9iL>x#3M}twiJZ&+ z0JG0wnK04aaEbQY5OkJ*D_&niEMaB85ig*rY#Emic$c^;ORiN;blOw?sSTwB}2+Yl&wl0PrQ+b+BS~dP|jP*C5Kf-Ev$d zTEw4BeQ@9~gAx{)7zqhR8YR(6YzKY25-qxiL5Y%Rk7;X*ak>roDAAUjr{KoYzu9}R z1y_6n?oW7!GV-a$mjfB5&iK*=76FdiZv47iVBr#BC$ z3m6!Q(_T!y96sa)tXtMG(AU@A-zmnu_K`)ySx;9MRL|#j%mqDguJg@OS+cdOr_$S* z$@eh0|Fn18tW12zcKbQmlAe+7tTHszKOnB{k7NTQ-IbvwJ;Rk96sb9TboW}TW$CIq zdmJlR@@UC5Q|C!+8JBoaiWvKDzcc$AffAK}JyQtzv0=8#zl|xFpz>2svnoIF zB2FiZQX#RVCdZn5xu@&XOw_nM*+azSUg5xNvot5a3t<}8`l;Bh)<51a_dJ1!rvx&` zpec_Q@1We$w77C>8#t)spFugMn@Tz^9|>tC|412S)0F(nr~qiG@?u#PmXd!h<(5vk zbn8v|%~0|`P1T5QsZUU*4xOB&_MTV&Z$g=>D_sB;0 z?-m%pBa_h7mwWz5JVOD1FEIXuXwej2?uSHqw_A>@z=-&hsSgeuW>CTcPe(#>1V)MN zpl?@TME5W#Q3B)mNj+<~8Q>IF{63emuCS}(Qv8`)&s=LVOr3$^92h93VVUsEl_=V% z?vPl@M4fL3naT2&cr*q=7|J&B0(xGPQL`b0?k$AEQ6f)?oa8=g zj8vYxpocmA*pdx_mweu43L!~x30viP$P`Rad8nsZm1om1c#1L)%Y61|%*;&FDD*sq z{j!icnjL+TFbxYmRQPWlq32a1o)V$wWi;i{lYgb$()6TqYuUq~&@;K6SVz)LB^{TK zgS61|GZ|&mgq}^Q0BE6SBQ)hDd|S#bop9+kpWxhnYKG7=kE#*fQhQLQ&gLLV=-FF1 zOXTVcLeJ9z0z&ACPgI`LlhRtJQUQlri?8(LlxsTevc`3HkixzXR{r%XJs0!Ccpqh2 zD|+59oF$^?olqnZEazdJd0qQfDn1%4(k)-=`8?q|DD|j%+rgS8^*l;ErbOzI52y{3 z<)vJyhnSDU15Y*4YX+r|rMN=(M(1KuS73Q`Zc zUrpxXzeDPo4{cD3)N?eW5tP((1jEz;8s1)f6f=IE8fV5Be&pFfI zd)}EdwKP_Hno^e= zB>3H7Ij&F-#-B8OFmafqgbbY#l^m!?#&%G)3-zFQNJ{e;)bn-dk<1*0CBI)yxt3uV zl_;)ZkUELtd`J{uL7wo;l?d7>trEG6*7-ePnJm96u8j#HROJV820gDyt=S=j;%x|p z`5J(Fo(0WAP|qLYDk9YL41-QD<1TQPaSNfIDAe;h_{b>{dzGK2-RfDS(?kLf>Up1F zC@yeQrj&Oh5!1RUB?9$a1X&7<-YTf4=+NNkHW>%H)iBgUT;`cO*w<0*?W@e3*I7V% z$kVS5dA&eS3HstlZWhi{a+$|zX^dc=Jz#V>W7rlN0x-`mh6!PwFR@{sgA8K=%tN(i zVIJaoj$_3l%EO^1FY~xE&HRiQPY021N@`G_AV|X)52gG3gYld|=u?969EYU5y5!lE zSh_B$#M-i95aYR&5=@t{rQq@eNMk%BQp=WMJhxH`&=}8+vMa31Jain#PcpCnzp*^ zal_-Iu-}6ff8!9(I$gC3z>N|P8822=#V+$Q=?;{7bgW3R ze1vCTLUa(}QT?{5nuYKjMl@66OW8nuAz9AlB0R)w9A+#-cy<(ScMu*}K-q;?zODE) z5#hNMwg%fNsdXbfT7W`$pj*CvX$a40!gmtk!JnFe@QezPsw_~B@SIDEk^$MPmF((+3lWNlM7@ z1|!JTYk@MhgR)(O2gO5Dn!ga958A*ftoZ#}%FYpALkd=jVh0APlPJChiDFyi3C~=K zSdGeuiCjkOdbK@!^!ZXC6 z)62MTILo+&2u~E@ITL*3RENE~Pty>d3vDFu5T1((kEcv2Um*C$W=e@5Jl}*Y1x9Zb z!c%l;aCDoD1KnyE;h9u>A7fyof95eGm66JD0pKCO;oef$i|>@6E>>`};GHAs8$-6C zF+z79g^}fqUt44dpgRv4CPa5`Vxv3H8^#25hic8DJL`plrU>pZh^LK)iOj@|(9Y{P z5(`G7>!Gg@q+w`>Qhfe_c2@4LUA31$JIf;}uOPW0C6+EoDzUa+7=(7FP=aY!Nx|ir zkA`-Zky^G4+S!*{nCJ)b!KZ| z2Y+e?u#*Xqsv1xZ>})KEilsz%-==|`4H$H~B5<>_w;5+(XIEBGghx}VaF-DL?ywwJ zUxVCUD+Bbhl03x2d4T5{Tdl8t4$CDoMqgS3_87x`+>8JTL|n#ft~fiM^0hbtNJtz*qLY} zfd}lg5gt#OQZ^&_$7V{206RZ~ECohy6|hruXmE6!j04?j7}z0RY3m(2W@hJLM_*;Q zvr>R|$oEWK`g*~gl2_VX(anN)O701{O^p%2(+eZa8OOHR5CC{8h6#%l_pt$>;e2vhj1m?L4 zNqObT+bFSgc~XhB)x#jn^CL~xUm{PqVAgb~=dYl2 zmj5~4U$a5Q&b}09&?PacmmlzM0RRfH8!j)tepZeS6#olpivYitp8~R)>0LjZ`aHbub&kdgEl#|4K%Dr*@5=@_V(5f8Mnn_ni}a zrj1TbYttGnnNt{HV`+qzLOoMN8!G$qp`K}kM^ox@TM+#2upC#Y2jfqgKA1R6QbL9e zBPuyikBsf0Y&R*Pct}d~7t}M$22Nqg?^jd07>2n{?6X9?w=+ncMDZ&~6dy;PaH2>A zZ5oAoju%}LJ^NH#8xumP%Dgy(p4X(-><~inHiW`_4M07YgXR+cqoJNF<0|4Ep34|? zdKveCvy58^^+chbTfj$7iP)?BG!5#x(?$Xh>bZ;Xc*>OWeS&{%rj!WO^AKbyFnX(? zo}xp8quXR0=vKo}4{?V_R>TInduJDb9`fv~rLGs|nMGf%v4WF8o~^dadgo5gX3iYh zX6vj?tbRxOs*@z>FlW-|EmSUk>#eU?2s*cx4nqFS@C4{-~}dawxkFo?-}J&r`*eCrE^YW6a8 zk#uc>Gz|Dqid(>Ek7mV+MJRLu0Vd*v7}}B0tOWY`0Fv^`mHSa*=@3z3Z8b3n{TxmS zrky4Qm*+(q`q@fqX$>3OAWMV)L=W10(a(rgty~Q)4ts068AOP(8%Df1=W@HtlqODx_`^r4>(g@oaf8$M1p@oM=gzWNrW zZpc@B;OG04Xxiwq#|;mUrNyj?vzaWGgu`kHB-T@!`pwVEkMTA54MkdS*gPSGC5Fwl zz!F>Fcv12I_L!GKU!%06qeO{yQfTj7ZRGcfAAJkIua7)Kc znzY4&0S&$gK9Jj&*v`if$d?&TxK395|HvS90`eIM$Y-S!7VKMK?@A-I6dGKn-vj_3 z8eCQ|6>BLeb=;*0es@@oD>R7lCruwr9409t!#j*1SGT}qYzJk#&>)J3q$HuiFkcMU zS+2cZ@8H@c;GJKux5J|BneT4H!EW{Zk-uled5}}p$lo@h|}j|IzQ`P{fR#^)YjG}H>qtpX!0+D)*&?XvUvN5hF;8|(<|2( zoUyVH4UM9qH-L{EY*Rlz?8n1tZKE$F{x_KtNwNOo)K~jg5dVH4to#F1b;ySp<~0$>y3-&Mmf@#v&&# zzIjspg~{4Nt>W6fr24ixK^n$EDfKN5x_x7DVnI4xBf-)#A3^^Bp-&0=xfPP~DzbY~ zV(IWuVy%mV=;tAnU>e?$g3I$Djebs%T3W-#Y5>yUZ1gjy6rj=1ZrK$U`ZtFQd8;?qQQ z>o2fJ_`8x?H@c+-D0B-JcfNjU=+>^ncM{#gpUxGPu`>Z#>cUkgY#ug}k03ak?iJeF z4(=H0=&w{OL<8fxU%DHTKKVt$nGOaYnU9xAtVv=^DY`o!!njqg%7A4fM**Uz2vl z_0q+%b_S_aEPDmQ?BmE2E|xVN-8vqW78eBK{WTj@?CiWagD!_jz5IZ83jhUl3&np# z+QO@*p4;9Yz7{6Rt7%uF8o7o=)@C=3cabR8UIsp>2i>}y;RIFV{vw0a3CPzVATN|o zSg_HpTcr_Nif;W-w4nlkk8a&fcr>Lh_XC389hT#YZejdM(+3lWNlM6YQ$!`mGz#64 zu^p7{qFX2)l9EKX<`dP962%*kDE^8(;hAfUVV>pY z2+L&o1o2Nz8L6;j(Mu6jWvMuW4k4*EJA_cY4WTe!15nRo&^!e7OpU9EP){3!PTTG+ zXBp?LI?n;P6TTG>lK%y0rZ?RI51qv=5-8g7 z&Y9i4mAvQ;*(x7w3chK2?P#a-)aHdyVc49)8uu1v+L7j91P zP;a;FY0m~^h_KuPeB_jfy}fzUpq>xgNZ>&|2NE7nnNkiQ_{U~Si9kK?K$Zfdw+iYh zIy5-C&7=k0Y8dKitNk9Lj^X15I%ihqRtBntn{VXzc{}9w0zD<@izB&NI8VtJWjQT1 zR=#InbUOz|motWKp&)k5s<86@|O%_!uy6)YZm5NKNvVgl!rq-Z8SpV zuS#yf0a>scT^Ic(K^n$*DBb5DjOQ1GJ|!5>Pmq)sC67~L>AIv6Ys-c~jOPVPFzqTS zxI6*U7|)NSmMz10-lY_vF`l<&S6IVx*<*DAC=cREan{b1z9DDvA)W&$(X`cNj~gBzh5a6^_#1!Qu$!+& zCq-Is@bm~_iNUi2u%yMxOzbi*lb%AUN5_g3%SU*=K!^?^JgVO|RkIMDFB8p_oS={m z)EAQFTrR>x%*J8HGKA+;ktF1*%PgSm0wOxya!u@la$oD5gsj|N8Vq8b)BzY z8p89i@SQ|>@TX=VJWmLbsw_~B@H|Duj5DY;!t)q|PL~GWx4hltj5EUXZ)*b@;dwKz zmqvJAV~{#^vL%ES@_!;vxK7q|glDB8;rJ|HLHxt5gkfiwjWg&7-NLzD`1%{zcQ|k2_aPFOK}E0uSu=hA%x;>2!;6? zKzQx}%|i&!y>S&0;kk=JrOW48cD(Q%VHkSrM`n7`;^pPtl>l(QPsgbgN;6XLF)ZKT;i>IcK;C@2uB3wVbwI zY-b+*#$bo(0({=xH8~5P&Jr(QSBFN#8`;=Hc+z{O5z*EmbcwxnI5*r6HtbVRHxjP@ zY&7hTd|RFf;6m#gCM;{L&c=nN8O8)$h-%H^LhFP=2&Nrdh>DU<8x4{8OPD=`Dm6P) zx`w(7K^lgGD3vW7bX1Fj$HE%A?f~<5LQs8zP`Csy`UsNps+>ntV(BWU5^H@Q#EXuj z1k=8hg3Hq>jTap*wX}w9@|~bBPzum^(YdlKEWGH;lvvu}QmnUbXa!z$Gu0#7Q#Vkg zPIWK|FS=C-ODy>p@S?qh1c4WY=R6NAO7YZ#l(HdDIcagRVeuUmYK4wJ`-$!uN;GY9 z+2e)>$A*zPPo0c1H|Ba?(EAI?XwN-~5X|y7CQ+=U*v|?@r5|YKAngPlF zPKZ?5u^f_phKdKfb=Gc$J&|vvZ^c#D)BCjyQYV{k1ljZ& zw#~JkGFSQPj7v}*=6n_;%d~A#b9-#aqXf3B(`s?^! zjJJ=N^&c2?deO9rGgcO2)=|v*E$~sxG3&+Wnn>Vb)=LV8;xaj9&V3)jKQ?o21halW zWGFCtt1#=LLxUN?WE<#K!$S9G&3 zCYD@*bem$MjQG_u{+IqGfQ9?O2y@1=>3d zEbIV6bPx+u{kF-Pg@qkSG*c3jvVr&C*g0ELA?w|xE5u&}d)?<5w6KQ#jj`@9gT>I3Ci*cYgnaYnVq!p>#T z=^DXgXSXxXSlEr$1~e9Sb6hW7Ec+IN)G3xtgD|@mdBVlArek402c^Z=tHt|kHmKOy z`{E3`947Vh1KuqF6tJ*q%U`r3AP?eyqGMl^Mp-aGu@}J^^?+h8GrXaS-G5||I+3|G zMCP;72@Cd1l<~inHiW`_4PZXUg61L2=TmVN5%ZbLpwsKQ z?Va`9Ld++M`J4kja%#n138-oJ6u)RAfrt5AMtD4BO1YTeADby9g8A$SSqhBaD$J+o z(BSAc83(%6Fy=F{wm?|z?XQSeTKne|0H5`#i;9N0UbLr^z9DGj@}VC0sEB26s}9$E z@7SzJn{3P{(qsbu^CXNmXH44)L;(MJ)G#6bvl|=#dC4#);6GGr7XMi{5J*MvCr&$U zG)UvGPu{|zS+E#gp?;kp4Z}W^))w~Jt9hYfkqTW%zzQt?JIGc)u69XZ0s*azq`b1_ zCX`sZY^lWBs$viV+KLiPyG;r%Pm44Jw7k^P8a8%lR2tmesLB`pjJXQ4I9!x2+=e-T zQhK|n`RVrhd*vEKaOiu;B=RF7y+RVY%Y+?NCa!ZHg5eJ8E>XMd{s71amYEB{N8);kg&5W*5i!YRO#68I^;_zR_6&=>4G zhHnv~gIJd8w=?ThhqX7~Cw}xjxa6mZS(5gk6kOl9D(7-BEMjpHW-P<79x@9$vl6uH zq5PNP(?kqw7ufUsT1l-N!_oqJK)}6)*e*M zI73-uSi3Ojbj@RTXZJSF7}h7O4fN8}A2T!Kdg%h-#~7qe0dOw}vm=owTmWo3hBXhA z&hn9Xf6ay)J3AC-&?P>pmmlzML8E|Sq4*in77GS+brJZW9_Z>4h7(jp`T_>26Oj8t zK%OU^uwX-1H%KG26uSDZXhQ`6AG-QJ;n9>j;~fOQJ1oZ)y2ALArVl0#la!F*x`;}U zX%uuNV>>9@g|1LMBqa*E+S0$DW!BP}D7uL+cHC=ZXb8T}#{8Z9{>Al!LU19MU++Fp z@i*v=%o>3$i$8irBlZMzRS%d&+~ zR1}KZ8GPiFt-URG)1avRY$WiYsQn3#r%Vz15d7|FYuywPfug2EwgIEJ3W_Q^G&s6V z#({1%3`K2Hiy$1`Q5`IxP-{^r6wuWRKpjehL9%K1jPpz;arvib&ZN&>c!GE^aEZ}F z%9~*02Sf`A@X{GDf}C+`ivt08=@i3+MTNuI@Y2PGF#%qpTC?!d8gy{TDb$vJf@IT1 z%RV;KEk2cYEsn2(iRcp1H3VrGPomVcc+z-ZBl2jeGYh4<| zke;Ok)2@<&%kvqHA>AppY#E017Nr1PD}P;fg@qw4c|5UPqzx{`dJ}gmFr+o99?_m! zjUsi*ZAlo?+Co@j<-C9)T_@}=Fr@N{$AgbjytF-~Xvj-^_-G$WG;MC#)WKKdlN4#aQPU}eB}UCQz`_iYk78eWx%0D>UUZO1vHWX8=MbWUP>brfP0p-q zLzfZFlw2E<4b&HlwD>d;aybOn_9rN*bwe&% zK#zo6VA1C5mj=1~O88DfF8EV3AeY|=k!oLG4!Jx^#f&qWHRSRTgHG@5XE?i*afV!8 zu{NL~msjI@X~^Xt3{t0HbtHt@UyvtUuxdKwvg`@M@mao%_=j7{!p<%kXV9fAsh1z{ z?#8_UxuE!$r7ac=$Ym1vpdQF&3x*R^1$A=mQ@9!Asf`8}qRjR#%1KChzc%)BMuZ9Nuv%L=4 zC+nIwIMlTz3BjyfBb0z$K4$}`u+;afCnqxuqY}ku8Kh34_yi=1Pa{t_QH=3zp)Y}D zvi#DxHYS8nm5bvHI)tRw><~inHiW`_4L~$M0L?=X%@5-$B1H2&2Ay8U&2*M=3n7{) zMDrl{$SM7Lm7bCOn=pr94USkIj@4foM7)OM%f_1<@288XVmw<3P7s z0nzkyR{J>+4bU|iqLEFv6rzD9#t5QW?=${5wZ()0M6;G*!Xm_MHbm2A7!x2Gsp$&AsYPHUu5hox?i)0q|2K-5Ts#foP5*^eKU8W*{lA%-Btd zrOS*;taWJ+qN!4XX;(?X<@t<;XbzTIwhW>#PQDSL>OR?U>-3o~2 zda6gXr>><)o$_1~M00}>mRM{rKs37w31tusW)BadN%7MCl%gRoIhii z9ydHN3i~!#xi=2cyv|qSUleJ*QS*inmKZfZ0~QjZsST39V_$i>bJfohvk@I6QY;^$ z*@zGwglJU1ZE|KoG*gLYN+259Kz*@T&gDWh#QYm(EQ4rP6Fzhx8dx3KRaL&C_%sos zsleKPWhJ$4h(-(Okq`}Z%hxXrqUjL6lMoI5)C`Dbwh*cI_2m#vFBLP+Xx0!-g+ZtH z_C3xnWt<_JQ>_hXi01UTUK*k~nL+9lx{ii0`z-Q=3tdfzXub?eXZaQJ{+f*?cJ{J3 zgDz!Bz5IZ8H|_<92E`vQZLwfLG(Q9%)C1An&2WOMy#9be>ICEf1mt(56Bg`SF^@_k zv=pLwRioWfGyub!+a=-j0c7MT2*ThCmpGDw|7aSSAi6_F=AbB!@XGYu@0_^rN)x7=Hd^|*zt(sVhgrc&bd~d$1Zfzlp){R;kea^|`jj9wFC!_h z+W0mlmaaA`v9=f(L~54)9I-5`J>dbWk}6NlmawTvp$mY3_g_-OB-B@ zZ8=i28`UG)Q#(_n&RRbSso6saORTvUkeY`@2neJmF#UK?O^TalQksU`#D{A7DbcjO zWse&k8HN2Dtl%4mYR=@VaT-NhZ`hnIge8W}$AEpOaxNFEA!gt(V;NR+tw;QuZw3t_e@@`Nj1O~-1s0j0Bit9XCS4ih^& zHO`=GT2e1R;N2a30jojrD@j`{7+B3A;DdUwn!^}QP*}}D3{oc`PlAB_kaWU=jn(u@ zBP`-P9yPl22RlDlJ#J3rgYEF3b5^?-99hB{2H7FjE()@+hd=q*kGe=>q@7GVRXBb8$ zif=GTokVdeB#N&hPk81UW31*ruuPW!D6WkOAynnAID?+oq}J>ZLh&|)!h8*2HP3_Q zA*|+wxQd9?JjbBZ%ed2>W!yrnCW_U(2|jY_zh14UY1e5MJK016535;1FccTKDO1X# z1pnAfDG{vZOvqAT^j2XtMTZ7Qx5+rrt%k9hjceB#LqmN9q-ISDsS#xL;xr|XkzvEl zL1_-Aks#5+7-2Mf!{~9ws4XM}Fq+*B6Jj*yu`!xM4PydEL$zix8sgS6dK~5kTP+Gv zO&cxw)L&h6QNx}tY_=1mVRVMlasEMPP9*dxL1&IfQeJ)WTuLlmUsPhPLxbqd<&+ll;dGDDNcHo(lg{FC(T8!(JXpO?aHU594>p@@VF@K*I>oo zI5x9BUyXGr(t3ktLm@0NX#N3l#*2|Pu&cbxxf7)p9V1dKADP*o5FJEjRKIO%W+5|2 z5Y3c?qHLhPP%P(ikr`t44KtP@Gdl}+JID+yjO>Cc-(Gy0h|HV=OZpv^)Vh%wEkGeN z&@ErTG-T#X;X8@U;7`p!X3i5L)poudnK_?|8D}tSWabOH z+!WVKpGCf&LF&}EE`Tum2J(dKTTMr1eg;Zs`A_2gHTy~I?7eXYUBQxi`2p|l*9*uD zioZtMV!=RWUH~7+T3YODAN?)SOAIHdg6s1PQYRoUhJgINbi#s-%=||hp{2;o(x;jL z;3G2=1d}_xLA@ZQjJ71f?+(jxMP@Mmr0Ii+!z3kSc$*RA>Y+0k+dFb}_IXKYW zJG%hTY(N1tmbzY?<}?~bv4XP{G-a#p;H=BAcp9{8a^`-~vm>vqtE1X6IrH8Zog}Y? z*zdAAHP)@M>s7+{-#h`M*2xXFfDu519x+Ua2z`}}2)$?+6A&S)HH!$X7YfMY)g1=$ zw9zn;ztnjXM|r_$bVd6$f;0>hQHoobs4|xEWU&ujtia-K&s_6WPK$}~m*$=}ia+~? zTJ5yj{X+?;v=Wl?N~0T7V(HST5^F1$K~QN+N-*tMDY!fb)1cCFQcG*t*k)WB+%8};6re$+ePmZypwbbPSlZxHthd-`1*kNe>Jja!E{fDCDJFqR zy+T+bK2QLa-WC}_fJ(7x(!-Wge04gdZpc@BZ0RCOG;MU*O_+ zPXbROGxN|CM0*#ZD(?M%waHY&fH? zi0dJ{c-20s`Md9$)u>+3u34EPt#=@-A%wMjAf&isYf8JIJ9c)C(dWB~UsMz=+Exgl z-3ie_uvPWjjNj7FUcMUL z6luNDc(f4K@@SleJ?5q5(<$xfXq004(Emk*=wLLee%okdLH}11&6Gr>Y@oh~Ea!5e ze_}@!W-NpLA2b_Tvjeu9!2EvkX(IH071WG=rKHvk{c8a|@=_*j%zgdRp#MjO?F=GmUK&7ogF)&5 zDBplEdlh-Y07}!L|5eWrju&slihqhYqFb~D*J_txXIF?bXoy7W&#Zh<`Efc&rjj0N_LaM-U!O z!D$X9_}yVSuFyZmpEP|iahRlp4Esh@0)$&Z|1!3NvfZSF;vp$f(EkSbb!1KzM10BF zfk#Zw1bUJ6c9Gv;wn{AvuDtW>-CfI>HZF>F7Jp_so1wT$1gA4dokVa0B!ZKXC!7cz zjrAVF{gdf${#8&a%dd*}!#Ec^ab=uAJ6HCX?OYUZog3zhf$~{2r4@@E_ zfN*8RSW#4L#d$r3MU>Zn6el&-zA3yU%e_f?{J!7sIcv1SX4kjU^KsSns_pj-QfF-3 z3S;B9$P*qLV|?u89k5K6zZKWU_#9RFcbq|wFsXHTq-?mnsJX};4~l<+AwD*`CbYF3 zTB(i<4Yak%EYqfuu6*4y%^+G*(iG}E>kER|8h4Vg+u95|y%zqqGgcNJd5Io**%Ex@ zz}j9#s%b}FcCwMcJMyv%;qjEE)Q$xI*esmBGCoX0)#BB|>=^3qd&wnTRWD7w2QXMxvS#0xHXh{ahz#tya2jx}8OAq3(uO~SF2 z<6-1E@U4HB4BvyOVuv+ayelt(DRwCkkc@=Qq|Ou1QVX${-tgDHQb6rf?$Kgq7J4yL?KiKPuL#d=GERvb)O z_AFu#UI22BJuzk;vEWfW<>LGxuH ztmQ#-G4_}jG(VuUqk~3@<-_K`AVddYbJcGfl`Po&F`}6sIwEBQ^+jYkmkXN{E4naa z8Ejq^6N_B7n-#cSgyw_d(?r<(`>^jkMoFz3HrE1rWDyBA2EKl2u=z4)YuFrrY6fh+ zq7bQaSUGIIvLNErot9_N>AKSoogMTz!{$@04fI;y&*IbKdg%h}77S9S0DBLF+2+U- zF2FV&Hs24F&hmZY{WV1o?ChR#23=y6dieqG7L@?Za!RZyep6`+uR?!rd+6y{QG5_+ z)nS#sN@q2j*VEhClfiSd*y2D7}ALFxqLeGrf{r4ttH8}lbfBeWDYKSQ*k0)P*jpG9~yrPg~I z!S4>safQt>{-o)HiNho%WcXA>B?mT_u^p7{CM6UPNoh=B^B+QkGBFf)f&R>NH$!oi z2!6mIbrQi(ArX8BdBQW3i;?SaIfN+;I&HiAMHm>AYg3I=kDfE5r-JYJ zXPtxn{T%~c;(BvOb!0f}6-zF$&KjOGI51qv=5-8)kV zs0L(+0kb#w$ia@hT3yqy;e%`>@UY=S2#=?%7p4>ZW3yg}V8g$HECohy6*gRSXmE6! zNejAVM$HU8Y7`K#(g^}XT19|x;+Z4Qh)Y!l#Ac;3d?A2L?W5CbZ=d(g>XD^kB1T8Xu;4x+*@ zQ-Wz%Nx|hgl17DpEVZ&0j`62cNOngS|(tFXI3g?SU0hYhEAY&S~jkjMDg@N`NvZFQSXtSnM1HdPG!g522=)=DDyem2eOf?|#QLCH zzJ6&~-=o5J>WVD<)C{cew?dGrA(Uf%Pg61DjBL0^31`foWYFn4!XwU(Xq>UWx2z5H z3eI1fz7y9=V|{NhNS&hE;}B-AB2T!e)^x0IRS`X+?Ultp?pP`ALBX}!W!Tvj;taZM zCiU_I-re68us#(3Picz<1MAxgd>{*Wu@$Z#klQevpsKvn7^F@>J_P}}1@eRg^1uIz ztTaMPvA!9i4HW=w!YXhI%YHvmoXs$dN))FvNS#FSG$e|Xktdue#uyIzDp*Eb#EolX zLI_p4GR~mqHK{c_giyQnNlKf&~uQb!04@lgNhCfj&752pj!>Y zL6d9Ypq|0u>P)f4?3mjt5YmZzW!)nKoz>pKfk_vRZbV^09z(rA(C27m#*@uQf!ucn zx+@*knZ6v>^Vlacdc-dJ*WIB62w>Cm{Jda`7XdgaGfW64y~Ku-wl<6ja1zy;g_Aan z1Y;3P;?YkVjnet+oxO!-HQQOb>bg5Y8b*;Q3s@BC6Jrrj7822w3YhT|0FNT)^wEA(i%3l6PE@z@3_XE#=eMBfX156 zmt8qs9}gH^G?T+d9Q4WTffRft5iB!KBJUl)O=&?7 zlYb*AFE1_id15}G?JmWJhsl~a%hj$*^e`>`+@Gb^qIyNUY;}sX-l4LN5SBPp9uUS( z9vLYf+Ky5%=pptK$a@o_gNT~yx1E}zPaq#cG*N=4N#P9-zCyVNXQOb?GEm-rz8X12 zT5muO3Snarklom6UdlL|QjiWvDV7iMUP_1#2Bhk@4M-Nm`*ot3lAx3g)EAWHTrR{* zESkfNWf1RrA`>|fFYI>gE-7DAe3}UHz5um>wUyMmAzm$@M?$>NEnmMhi1$h1I|=dP zPoi?M$eDn_b)o7|G}uV)*_>kA3TJ-ZV0%7(B@`MZJO^0~bJYP6I z%U2iwxML**@nUCJi8JU@xYWxJc(?FZfOt{-Ytj}A2E_XT@IgHg@AeEQDCA}v2B{N} ze}{mahCJbb{I7?2r%NNW6yiNfw4nlk5AlAK@Muas{s@BK9hTz?@nZZ*(+3lWsg@(d z0TGoPh*!pTP__&4qIgJ365#qha_{zJL7Tg40u*yMw`=h;x8Gipwmm=*PTJ*tkf6YlB~S|3b6S9fsa}ai!b#B6A3(6d>O$|Tsfyq z!%GnSV>1m$VDUE~LxIs-1&bFQ8q5eL+d#J(hQ&9pMIwhg270T#pQ;oP@%1P~T+`MI zh95yg&sr=W2PfXF?Xh0~eR#MTHWo>=l7J@u4~!^h+}eUn0Jh%SFd=OHA2w`#gkem8 zt*O>5Y`so-uoMyNDCxA(5Q)F|=%F$LjR15Jq+y(zQrY6v<9*xl6hfa81o}iI<&|x} zK#8Txwo0t6ss<70uTX+%S4qL;xsFDlkC$4u41xY0r2q}B-7dSrLZE+2iKPuL#fDLe z)rpZ<>C?bk$*2CHdYtMJ?Wsp7Qm5RRgg`$jge9UF1q3=55(EMro{&87ImJ_NP|Aip z#Rs34xS)20R01`~9ydHV3VS-aOLQwZHD?y4aEgs{ZOc@=^!AyC%A z{_=9@Zj^3xph&TN=xaJ5ItYEKe%mC?g1$aVG*c3fvVr>Iv7F0=zKD4^%vc6}?Jj&S zmsw`TWLH}GPU6!<=<6L=|L>xt)(w4W0Sfwpg`BTn8uWFJ@STLd@TX=#Ul$0GYVThT zeO*Mwj5DG&^mRUiPVfKUb#^l241L{VZ9qd`x5f3+g|M3#q)s7h(G^6PU5`BBLRizG zulqsiEdNEkzh?7^o&9N?L6^FuUVgy4oBIOvh2pQ3wpcKruRnng>Vdxg!f=8rWWU59 zbpmp62*~H96Bg{3Oc%Wn7H-~>d~|2xEwP!GJM#QU3GlwgE>OHpNpLeCc0B||c zh6(^a^tA$Z%ua7mNJy!;UGuIeHI3EMcWcf$p z+L#bRRgQ===y^?Q%?=?HZ$l`|*8q(3Y0x|bx|E&xSDp4x(DKaM1f%L03eEQn;p#GO7KQ&i~;cFW8eVZNEv7hVdfGCKfN+rW@GBhFI$&qTqZ|hntR}UNa&R<7!CCi>1vdv2^8AiM55v zAbPYdC75=c6kMKSY4m6%siie+lkYE1rxc*kqy1%9ScCVYlvvu}QmnU@sHyRn;6rM` zSn{bKSw~YnqCM3^kvbK_B=o3X2us8O3h2?hV#Evdh&}mvKvIg+&ZhJZIgJk_T}p|j ztuK4r@Hkmc9DOh|A7-41;TTh2ov30;{pQEe?R+h6rAX_Iq3;M`i7|9Ku+$eaH)7X$ ziS;*>nsmr0u{NBx~{`C#NELUa&}RQ+~BQ$A8}LR0X5Jj%hyW2l&M2Db(y`x$h)inWTfA0KBh@*Haey#esY%z1IWbV>JY z2B}lhT^+*gbmR$_bej%Fegl-w@~_4FYf32C*{kCWx@ar)@&mrGCvxllDE<^_ivPiah>R(jO)iqjWyQ^&&u-)7Q2fzQeorcTWPnr>U!edi9zb* z$@L*mZjU_SiF=H(*dxI*S$=q28{>0S<*X48uZem4=f zZZ?hJup2>!0;9JIhb=lZm=R32fo?U7!?x8zV#D)h&KVk&0C^ zLgSu}IkN>d4)wIr2$jDgc@qa@!ESVA_%(twjG0opTg-I4@7S&OMPkWHqogY# zDX%2EF(sBR$ttnd!9kRCOG+^9Dk-=;0n#Yxa#G8dp``m$3eYI&KC&w;l=KKnENyTp z)|=^Dfs)RqdPIAwiz0POnMo*VuMn1qQxs6rx5XG2C~0(x^3c%~XPr*z8*&yO9leMW zOp`;)G7BiXfXMF`pC*D^ z?}x3yuawlf!7VMIM}k|huJiRv1Gm<{RD)aiQ!~J=O@v5Q7AOa|-Y3N{br_@&1~9DR%aV zID@W&Nxl4lclZ5JfOV>1D1HZNivc&PKearbvuGY5HK|Fi8m+&W)(# zfLk)QgRO{l;1E6qY}jf3{odiYz2wpe&h+yTw{#x z`~@tN<$sE6V?qd3c`?qQ=QXJ{JA_cY4WTe!0|?KumzkJY^3aO7`8!bf?wREU0cRPv z41-QD3xs;=jq+tii#)ta5CRy+hYm8NlmwJ7jGjt+%TN>&b&{vvD4F(+TKLAB;R_eA^;K z0R8DPOjx|wiH-hz$}lFNKU8ZL{aL%#S0++myJJ@)uu+AMtg#iz2NzNbVED zS{o$a$L{ii}h;hbX53x4TdnSL(92VD0W3UG?NS#Xd zZV+Z4LY{CXyXhG0(V%pe_s08cDo5Da?l^<4RZG46fOji%1q>F&|BtlAf`P%F2|lO? zgFTz!1O=^}&LDLHa!&}zlcf_DYz+1)X@r(yu-_7Gr~u$&us0GOO(~dPNASDDa$GT3 zj6Z4mVB#=I2^p@8sN`U@6*{?u*I&pyZIoWbZyeVj55>tAfF{{ z*?kHIgxRc$SlV->ySp-!bq@}S$3p>2u5@K!mu&yN$&ixwb{z>sRQ-=oObsl5Z|n!w z0Sx`s(At+l>IBvS5LkO6PdKpF4XBTbiSP>27>)8-pmdhE$9rm`0K55#ID?J?sS!I0 zP&`CIGtz0`#_36*xy+;Vd4yBqD&hz_kwK@oG#_>n=)&^|(entGfR7x!(yL=O?L5NO zHWGN}5w0OTp0d393c)`%%d5zFgaaW1fzexa9--*aU{)|02fEepd4!3z(6P8`I(KG& z$MDgG6A9~6ClU;Cy=M}Rq|XHyxy`z3TJlwqrX4n&@-0I9o78^@#S=AVpd)JXICK z65*-B*@7j61aYY;~K`YN5(Y+g@qXHQl=ZcYWt>>btWQ17gfY9*@ju(8d{ zr4d?+ZGJ)2sy{OJd1E`Ma3irAxfw=U{F=szY zo-0LQM>RD@*v>o{Va_F~`4ta}@^K46rrp+#U-0%P??E7Fh*f`E} zFkg-76luNDbEpuO7(E*UOJcC>kA3Fl(g8|8I#{GwKGbtOAvy^4sD9gI&4PN)B$_FK zdSnCj#bh~`3-u85ahS0T>KPPiLN2|`D#|V)@?3nH2=#Qs9-&W3tsCmm0(vCW1B*Lf zzci@lPT@QGJ$d+3GoYS(g-BI1D!<0|V=88xQ7tNI2=&~As|;lo^U|sV+XF`zH_2Dy+1Xr zO$%5ja|$DDDUGm*vovq|_vGy)+DL|ab|E~PQkUD2;CF}RxI#S`f70~9#9@*WGE9l6 zjWg(ZO=`^!Arx;zD9qOY)N>tZF5y2K>iJe&MO?;R%b?TCxT>>^TL|?; zp`N?JM^1^@tNb(#>iJ(A2|TFhmxRYtrj(x({9`kvM4+Czkfp%rt%7=r4h@cOlX0M1 z4MRPXYpeD1hI*?N_`bL*oO|-Io{cE1$784$?3qo2J)UfPjYpz61H1MQRpq~btO}OH->{tCUZVM3s7-%WOgawS_*)Y)BhA{yKqFS>s(1ww~D&jyq z`e~z4I)Cl5h0v^KlS5ZeHz!ELNDyTKiv;b}ys)w0g|01NQMPBUuJ^}ojO|D0)J38vj91(&Bx8Wq}2YH1BS!H#XYRrF@n8a##Zu-|9- zIvh`tI<>K+FJAkc5SCc+F5o3ogami2*@FM5Sl*V-AD6uwj7Kgkq^M`oL z5`Xar{SB0GI(nq=hNCA|d6C2QCwjQ%i+;vF#tHM6tuo-T_@7b=(3s-A2}b`7C6+e2 z6dN7`C12{Hwhtwr`kwkD)g#(d&rziHj*%CIu*5O)C16P%5-Hw!-!;Tk74i-rLtKdx zO`BQvxZwd&C@5h3hogy+Q77}&m_(7*8!c0Xu(61i_hYAd3G@I;K{{HbSU!k&6d^hY zBC3Ad49x-&D?~FTAfjxbzMw4UazR95DHmoe0}&S!X~F>!VGVBA?)kf77nukmehPM< zizumegNRx{j|35+TfTm2AmSH=?<9zbKQ#kHyi$l%Q%5<7_!TN5GdieqGmX-=2B8tCF+QI`7*VE6Z!J<>#4LeZWY8;-^(OD^b980`8XZIE4n{%&$ z_OjsWZb5vv|C^zzs=)t?LF%~uWN`c6rK-VOSczMJN7Ltgg|DGYmlOZE=?_a6 zh0&@Yn>@(Y?C>~r&K`{Td*8nGjA7pUFb|}VqxB;2UaD)oDHU_B^aHm1Q zZH7GIJo8_V4eu?D&{AypAkl^j0RA<=LkN$i6!NDN{BE`#S8N#LPntfMJj`5!40}XW zae`aLQM_`EP)z6kJD{i7z$t9y{6ujY!!RmQoWvk?62+O2C_aNc;Y2aU z*zlELnJm9Nu8j#HROQk*gPz-@*6a{M@iv6Qd<|g3cY)?1Z1|qIiii#0$)MBgg0n>! z7?f*MT|gT>2gU(F3}!G4S39aB!&z^476ed<3;L3CW_NF;uS;FdcmK3&`=m@fhB{@d zY+kQ;WVbRjG%zUc`d72TYENZoUhi;as;n4`!$mvP+bvrFY(Rzx%in;HT8<4rV>LJgxVyKnQUHg^Bl9kOz1VQcML<`y zg@zl0gG(*~x=k5aua1@y5a12J?vG?!MG7Fm>l!9RfG=Ppz*7uk0s>66W)WcG%ARXR zxrekhLl!xC5zv$BFHd$8YSrvO>B9F;1Zf!lrPR0Z?|8rV_%TAC63F*RB<0nednvJW z-C2pXE)GJz^C-cztEAxaOh`k%he<6h?Q z;aB*)+A$>FP`WU`SqMvnVG6+Z9zsIdML;i$c(`_ow|-429P$<)#QPm3nl`)aal-?o zu=B(55RNVei1#L6jn^sCdZXuUAuKU^{ufx{s~Rs@Uco-|a_Ji1AZ8~zSfp4!hPNpp zI*8$^e%oZt!tk~tnkm8XWCQiZWI30M;Suw3n6V7QTT}SZ!SG-eWmjMMD&o^b4DWo{ zC9I~T){Wt50X-7KgKqiyrD1qo!gmtG!=IXg;pIZ4nn}trygn*soKdYYydDOft`c16 z?03c)!#l&;fX497itD8@ywez@PRZ;N2(y!rCtNaXI)-;OD4peBiTBrRQL(dE#2Iu^ zOzPzayt{WTV0bA0v(gqGhWB3!_S^$Ls0Zx1m*E6e!@Y|^>ICFv5Rl)OP6(ol|Mg(c z6VeDR1$&+sZKwd?gFP=09!;stJxB1n!*X1~9*jR}`e5QPNeLMqji}^+JuB~D27}Z|6jwl^SOs~)GuIe{JzIli z#5LZyHYS8nl__xsJ+Dcv*&&4DZ3u<=8UT9^1hXaL~Dn9Zwu_xDm z7+no-h}B4goMRtmTvs-aQ148N)+x~Tyr2`7WU`nlo@u%b;@BB2c1w@*7+tBo$uJ?H zavd8`xyLXj04h{#7ElQo%#>~N8=zg8w`qERN`F|8*G%bjQSsLVX&4|O)G3c>sN|Ft zWUe>HG+waY%fBu@O)SWK14i<-N-ABDv1bjY?J+caq+cMT!}zVJ0`<@K#c`4y2nP`C z!ANy3N1u*N<}%H47tS;3ui!P`&YQ0+ zWU9EHVCf1&d{seI6U_xHO%mF!$e`2Kyxz&K`D@GBHx@_V4CJQl(-X2x9{p8kw{{YL zfV;+!S7#3QeyXDX(A@<;N!n^}e`Ro_YX1NSjo~+oHFx%R=|tEMr%>SkN-5^_W^;N2 zpZ1B5`$|6_t_+KVF2nG-=-v)l->i=AohF>HlMe6&*8pau;>@yHB%D-{I)7C}j~ZY% zIZ@@TbeC;wn_lUkCEi)C9Rb_f5wMgZDun+Ik$&jP>b49z9sYMZ9gSC3cWiH$ClQ-+ zQgMQnh9T!4QJi7zp|J|zEl0%F)Z5iV8Klm3^=`H<=K=Wk)1L_+lM%JTH`6ccxa3yS9_3UBx%v zJM9o*GzvD83#MfZWno~Q%dn3se4ND~bt36rh@{h`eS#Izy_;bnR39EeTUtxAiaLK2 zUAjhgsia<6hjR$a-z3^lmJcrT{ZV}jVc?YA+kLB6X&Hn2M4;us&Ztw(mm3Ld#b*{f!W#6$iP6a_*ZW8ho@#+ ziWAp;eVL%khL0PrR{C`dQ^}}W*6AA&TI-3>P@%Py>R} zUuz&wIKDnLel|suiMe4syI{t9z8!cg%eRf&*^G;ygORt2Gw5+4{lOj==)@5c4^H-MC%ODUnWB8iIXE3Y6=oC;h_vtCscn4Ry+`S!lAl`Eqv_1x7AdK zQQ61V#RH-d(Nskm8Wpo1 zh1Le`?V?JH>+#N!p^CVn*a0hMH8+(746+abvn?pE0!Gjj0%p5_iWjW`(-Hkk9N3R#sSo=FnWZixmsGH@d#QSR8{#)qi=i&_7 z?NTSU+tCiz?O{IpNKd^NJl88!QVTaaSFVBl>qh&xH}CAq1rD4s$R>sgiEU7goh03B z4+LyS$l;1fxPAFUh?4Td0`$|V-!n`IQ~!Z|Sm1ucNaDQol@O{mdstw_f@h^2%{hTl z`txbEe>Wosp{}Q?Q9z#;c#t~9G8Pk-pUc}=Q6w3}C>NFB^Q>FwIJg|Ng+S`)>Z1J4xU zg~9yy!s_CRACbAdYg#GJ*`Crc=$xH(pCnoFJW(b_4n38p9C_-XgYE)cED`(yYM`;^bYqBz!Hsgh?LE(ML`SSi0i z_9a0SQ5jDjU&5f%_IzI0Q=g$EjydEWc73eaaN(&)@>pVq3m36Yk6_sqdBm~^X3IbC z+71VW@YI<)fhl%&g>|2m0 zyeT-O>E@M70dHm<-L=4PR~1y8gt;PvPAANlorGx*upI?&IKUfNYJxoQi0S5m zuD-!}Szl#t1rc9Ssu&jFusA&{DEcd1y&Y4t8Gse*x9!A_0{88jFzYxZ>lqwIthuwN zV_9S&#-n34-apX}D~oJwbJcWY* z$;>qQM2K$jS}6RJyh8dj8K9#R+S(4SR7Zx0BgWf7J962dTA zx|<8%x0}~7EMB$jtn|(m<8b0|1y(;<{-HuF__Ou4X12EHrQN6e$k+XdIr<123A`&$ zM-d)RnVn}4{O;VE(LeSDs|?b6|L8|Lp#1 z?R}?JRq@j$sJr|r&FqVURAUR9Yq^WT8bW@B>Jo_E@@z@hsxB~0xSf8RUAer*FeX$k zsn%@evdmPb=8>Ndjmkt#5S#e}*FJX$+M2ZwUCFwYAPpBR2}R1|H&o6z&zRBJ-zjID zB|c3oXS@O9c2r4?l`{$#mBfwuLHwK!p3QO1a?l57D+Pec(^*(ucjcRC~SSb13}iO2l6Ru~iN~nrUQ>chgpPBH<4+ZtI{NQ-c%mNC#H9gLt3m{ShKV!NJRH&6~2zLzR z+hizyn$+4WowmV|S5X_aXGg`s@qwy1&wz)Y>@|X6(#_)J8?X~g_Bmh!nLgh)P&~CV z#86b7VHjYLI__Nw+?z{9gZFnfj%%#F%^|hUKMNEW-&G#(w{bpp`qVgscD~e)?R*pu z&WB~FSbKN@Fx|V46~6bSb3Q;^YU}3ysooo3*Fx81sFdFLx{hHT6)|6DkU9~wDn!iH z$P-QoyXreyW>f1+mkcP(<0 ziH6$yUGEbgMpn0a7Jipu6KBw^0fX*sDbxT;|w}IOTE}m zNAYD&U&pyaHDQK)jR0?M(erWS%GC~_yv(#ESFS$DP*dgE?HHtv%h$$*7xIK%zPzWV zo`eg3H3=#|6m$}ct$1&YL$NE<;|$uNTO%pkp(wu0q2h3G&BY|SUP`Xw#I7gfV$3?ZcgeHCl_=|M6xIBPD&_@2; zeJz+ndV4WJQz%AU$52|Ykr^I z8FWZojil_5K=EZEu~B=wD2a%W*h_s$*kR(5?*6#P!U0d84;L|jTto~!3;L@V5Hy7t z_ya>r6$8&ONSzqi6k^~hX8nmX`X8D`({uvK%44r#D&Y(Rk^OB#@Hl7<+E7-zu@D+SSq;4=|D|3e1v{SmZp-+KtS(MTZ(+?Fnmibd5kl&9y;bs2*^;M(^i^>&%H=&L;uim}CwK2Ee{UO3+DfRCC2>$t^ z-aQ4JyBGEj&vn;Ex7|*PbKS(phTqRru6Ax(#0Gbdn8T@;%fJiDcI)LBtQ#}LH+N4a zubJpf(K%ERXOjzCv(^2r*-S}9@6hBt6MCBa6UFV7l4rkV)m>wovmTT6i?>j5)W4{w zw(!>-GEqUOxzhXblGe-@tv1|P!p84%;oano-xm!Nu2QyUZ~U$^jO64`FFvW(?8a|Z zcjIT`z~3&E(}=SM6u&L+GA_fP&1+Jb7E_QXVr)LHH(?YgH3VU6v& z?-DK+yY7++$J>0TIO9W_RC;hlmnuLu4`S1hF!~pMBGQh!RbQh7?_2 zXq0og1!Q6u5N0g<>Yxk7a>Xei!`93eOY`%@r-=pREup4yzLH88kXJfEY$8?>0L^OR zKPTd#@Sxt}&;okod1>gDuU}d%_A|nF@eNNI zgD|@sdBSzkrk_~66O{FCbask&IVZzItn!->D$Xkry6d+1EJ!9|ZIy4ESo1c9#+r!WtR|@3sgIhQRD`X>Aax>aXNa)nkSCm}wyno1 zIk7LK&OBJh70q)r6x4iUIF@`NMs zldZL(j@4E-W9*uDf$g(=R@`1Ds&@lp&5SeXsFrqRM>YDQEUGufctR9N1T=kalbn2) za~X*kJPGU|W6$C?dj_5E=7;ERE_@}5ekJPPg;?+^)1%FLC2G;zO(gJMiCRoB6xZM> z=X~CaL`oH!3St`d|&9e>G=mwkTmX$0p=H)$%5scGwf*y*$IxcOrH*On5ZrF!s@y zgAHTC(HN?=vZFEDOOVTLk=#H2;?fk4#;DKCM1-r%S;P=8LE=71kcN-OP}c+%xEN-zy(NWtY9g+A#rS88bu zJHd`DTwP7{CLIwRew;Dj&^!1#+(wZ)OP-`NBHtCl60xqrBm7-L0&zw}jTrBY$W7RD zUbH+$X-P+m5^JL+ilP6J5>7{q6kcD%lykZ87ctVqjAiiG2ZdG+`~~UPfxkW=K23zb z4uPqDdnL7Q_)7~=@E3H;*DnqJTJsJKf8kHffWOukBGod#9RAu+5V-~=imJHPT$e$o zm-;iDMGJ8gVJzXVovaP?wBgToyTtX<@YjwEQm3YJB!t-qkSAPIX*&FMI4GUvhsFDA z)|uGZgX0Xk#v=9d13mzMq4=$(Ej;*ZsxHsMa*o8jDnn2mka?FZtgYaSAWCb)U=O+9 zb*DH#5JnivtK!-*3{oc$J_>=*FO?7CR~yvgSFZND;t?Y=dgbSU;#q!nyuT(8u(M~x z8FU~>z1V?(;vo4 z!<&gu6L-TojNyq&D!m)F@MiJ3^tt`@J+mI=Gp@>XdOV{nSBCZ&f4Hd@dG@K4k!R5)S1KL zYmoFGy1Ue?>Dz3bsbfX<53q%V-|QEs*c2(Aev@ym+jrLgzv{CY59r*lN1UeWaQUmt zndhvB9N#%RlF&ozci1>9d1(E+k$%968-ncH3_2ZT$2%R37mu3%(E1}*Yx<$}$KuN9 ziqXRiQm0VxS;$tuMxJoRhBA%$rV3FL>L2Xt?H1pFhR06u%RKsi?ODVcSUR^;@MDnWk{sac8}X$ z>(aN{_hnc}6(9FxkUCLyDn!+;$PW_J zx%z%l8Dl}&Zq`TfWh1vG@3voVBck@*_A42RssVTzgVY&-XTSiw7%HOcq-3$)Uw!LdDJ!M`_HPNoUsdH8)9_R-5S2B{N27vQoCdBX8?aI7HR90OSXHS z(GZmgxsOW~yoH>7h%m`{gm-2O>B>86mdLVQl`A;H4M{6Ff`4pQaH|yX1`)B|0p;@{ zVx+l)qtJ|SWcWx#A9n$Vq(Ry40uCeCj_@!ajpWyRo_Ss0RE49=E7^AhWp1b&lKFsp z5?RWsdCFVty_X0{INW->a9#ifrw=yYVwez1_#zw6xz8|?#d!KW zBh{M4b5`(uDrZA`_L2N}+Gz35W=h0l@F+%fq3BN|Iu8+~VMK>g$DU-~nCW8Y(RYO` zn#1}vL7_7DPc&rM^McBaOUmkdAr-zts8sUo``?h1cY^g@N-XVhDb@qwgk> zu1YWRGvCE4exF$3(Jo$&B6Sdvqyxq)3t^2NFn(Ovad_5fZMO2x7N>Y-8l_;+Gwk>0 zb|FLu9{^MRwtkL2{(b<_M9H-SDZG5fp^v-&i3(iD|L);sVsMu?7lLbV5RJ;bY*MVv zNBOnl(?q!TB3K4or=-T<+Aa3L1vcEDl&8X+b7o>2W>1k#99GwGri~`?n8BFO748!~ ztHM9Yr?D;prH)aou?^dC;+1yC2CBXVlb7$JwDZ?zi`ErT3qP@e+R#(*=YvLab5VW( z`vO4}Q5i9`^B8m*L%USiQy+jKFf_kRUiDvvv6v~Ic)>M|z+cRUEP(VD_hcX-;X!zD zwLTzRb%fX@++@uhpF>T=;tJuGxKTBla|46a+2CCPA^lC{32*SGH`TIojo?kWqs=X> z|H@jMUs!*DFkZ^G?0$lOY_?_O8pJKEUk;A`8TPOK2jV5apTAuFpg}#jvB4il4C3tT zWDo{ryZbr}+^;jlH+N6Bk-z?z$CnE`yETeCJ4r?F@8r%TbmDG$?Z!+u3!ij%xz|)h zS*kiT(piK(=)Bo~G zRoDypI-F0DIy;r5o$AFxSYtcYJ%t3ZQ!UHB-hTBQ>^d)8zD=n~hl>(x!zFqb_FhUj z9WqjQ!y)5+9Z~HBkyyR?E!BVeSoY%yHh-BCOWRzE4adE#zZqp^g4Sg@`)5DvzD4zc zcFn&j(t1b2J3?6ENVpkTSb?A7gf;IZrk$V@*oB(+6QYBK8r5$*vdpD|!P z;Zny~-Zekd+CZ<%{4sNOTrXX1IGsW2R2#kqVRka|gsTlrKVyMaaVCrVp*=ZVFsGW)=Zch_8=%#eT!c?KnZ$NWcN2UY8{trQ@c z`xr{A^8|M@NSy$<76RZ0Qt99w^EHa+QKZ&-<}Ul#1akgcP&CV*jQ7tt96R?|oIyKW z>cMt6iU)^7<`y~Db9&)@ZL=mZcTMU$TTVtv;TtWfw$RT0N!7QY=Q46)OGx7dEMC6D zu&9crHyET&G<^%A=~d(jr;~cllPg{8VKw^atNsw9aAon2J4F-Mx=a*a4@#{NXV6h7 z^=C&R+RR2_n6E{(GxzF$dF{-lYD(?Q6==U-(PlwjdCR%y>ebF%=?xT3=4#k{bTLtx z)AHr9>atMpAo$YIwuy%GcyLNVzVN9rn2FUwKGb=`J{Gs8lg-{?d&8Z+l1L)Y)Ss)z0n_!V)V6g=ggYgap5K<_#&YcJ>|YIxk$Fq12?q zMTxcH60M#6l@d;ej1=B*$ix;tux8*tZm`5%#HxUhov^bwFQVuEd^b2eA{X0>wiR|~2N9x! zwKLUkJF-lzOf_MC_ovQ}6AhKr&SVqyjjwVpw{}KMwPD7x+S#7M-%jlemOxJJY!~rq zV(sikSg`M=q}E+K(*k;A?F_o*>z7tLJ5Tsd*3R&!X4K9u5+YT=lphnigo+twH0#>g z1q?b}JG(^~IB-m8ENf@CSsT!`v)ki(>Dt*X3{q#a`)vrb8;~cw*=>65>{p<4mfs)m zui3<6XMY}N(3@DPmmlzf+8K(!PTImNqr_@wGP#pgk$COwFJOmQ?d)$1rB$`#PYhBg z0KNkO@Pbr2t#&50)_cjC+L`*;B>#MgyV2o`iGSSW7^+%e=N5@GXopKZ*bYbW;BcyT z_7VR;9#zj0-++_+E1&o&EJH_=fiRb&E)DCe59fwkXb{wM3Y#fI9np-`SC%U@l&FmVSH_$iO(IqeQ zxKF*UsSchMiRkJXRDdFny{(SNn`*^DAlv8O)^m@Xk;MExQ59TXUe%&^M{^7lR<-VB zSG7K87!#^mRBN`X6*8Gwf#(CzuuKOf3}zHyvF`#wUz3XI{nU8`X}F3-C{!NUp<4uf z#+=3v&eD3e_%v~8eK(BeUL}=YT3hIM%RPo>kHGsn!&$euNdWK2;u}Nz_73&W>kwbd zw6_{K;zB`xf5$+Vo)FU+jdSwvK#4JH?*y*quQb0bW3~WZLqsrd=;d9^bI7gT5p901*#~NFhXcOb1)Y9kM2rdcS~#B z&+ONVR+RO_8zvL#I1OKio%5H5DOb|IPVl>_t#xm`m27NazSgh3VN6K#2S=M3$;fb7 zL?zLJ9?3G^g0kH+c__YYB)8I}xGVK6?9JmJCE^kVWG zpm3JI9`CPlI(GJ7aR%*lsTbSnD89_;&3)}{^&goWQ1aT_nu3D6ykn3$E`Ju6cgPcV zdEs3*m9q+eHAyO;20Dr5S-dyKq1ctSID>ZRib%?KD2gw0=;rP1a&IOUX$RpZO@CW- zd}Sty6)ht`eASTN*@^EDpLJZd zGF$=yEa%E1BH>gpjf{k)K|VBEh=tP`R?zD#2B{MZFXK83dBU-QJrO%Ku75 z|H^@5ivFV|1k;EQ%n-soz`rrZ{XIa*L7aaPq~Yp6rPTjp?@Qq1DvHLrg@tg2JHX?T zB!mP4gwt>&h(Ydfh@#oa&TMubyF1IwZbDEL4@6`E(V!?I-XMr4eu$u`h#(%HpNfho zqJkpg^?4v5@UN=A-&7xOb|>)n!{1MKv#+YV>*(t0>Z)#&!@66tsI4o)b_vE?>4p^I zP5QCW=3i&rBK|OFV**V}mD`DHmY2O~HebWqB!X3yqaboGYY|{tGk@Qb;)~_SRLE)>5(WgVF{XcA9)nWLViSBLuhrMAkKj3R`y+WX z@6aYQ@b>d8fJ(8M(-Yv7&HS5XGp)n=AK~GyPMKLmOQ~LSReVIHptZ#63yW|z(rD62 zI4;G*87;v*n1%!E^4KUCziey-LLtnuJUdJ1vB&B$8?LPo9bge>wql?$2#;wsF^Gdc z!Ho8mU%wgspGlmy?D-L>O;C)0KT10#|KJtkPbePYQVmsBW=qMX5=&OCik{aHWJc5> z5h5F@*ZOKL@VYAaBqAUUSL@5`)iLnUR%!tP&WbvO-dZ&f7AizU*IKi)qu`xz4c6mP z$@*~L;8+#9uVf1``682%PRR4hjvpIZ3NO^dSm~1(Voz(N)<+MsiENFmSs7kd)2i}+ zjclVtCkQ1vt|KLSf>)w$^L2PeD6bYmc~wV3d4?BC;1&6^upfDr zadHjpcQJlF1OO>3Qau4qtw?KaYP@)BMS9^CdHxmo^9#D*`n~&U@7labg6~d_wU+eP zYlBspH(~#2KDW!b*l0r9EAp2x5-;QDUc}(rUSRhU7B-^*uFVnWWs`M4J#%Dww_cGi z3N+}g>R18}OYMCJI(@1{ydtmdXM1VEmgaCmm{dxZ^;owQzXD_kC7f3Q8aLc2{#LXA_P-Jae4xr@-c2A!}H<+ubmr99KDfj+;=3x*6o`0|2AoJ