summaryrefslogtreecommitdiffstats
path: root/nvmecmds.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 17:14:45 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 17:14:45 +0000
commit43e8530e93493bb978c446a2023134bdd4277e50 (patch)
treee8c0d3c0c394b17381f48fb2d288f166b4f22440 /nvmecmds.h
parentInitial commit. (diff)
downloadsmartmontools-43e8530e93493bb978c446a2023134bdd4277e50.tar.xz
smartmontools-43e8530e93493bb978c446a2023134bdd4277e50.zip
Adding upstream version 7.4.upstream/7.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'nvmecmds.h')
-rw-r--r--nvmecmds.h301
1 files changed, 301 insertions, 0 deletions
diff --git a/nvmecmds.h b/nvmecmds.h
new file mode 100644
index 0000000..452c297
--- /dev/null
+++ b/nvmecmds.h
@@ -0,0 +1,301 @@
+/*
+ * nvmecmds.h
+ *
+ * Home page of code is: https://www.smartmontools.org
+ *
+ * Copyright (C) 2016-23 Christian Franke
+ *
+ * Original code from <linux/nvme.h>:
+ * Copyright (C) 2011-2014 Intel Corporation
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef NVMECMDS_H
+#define NVMECMDS_H
+
+#define NVMECMDS_H_CVSID "$Id: nvmecmds.h 5471 2023-05-29 12:22:41Z chrfranke $"
+
+#include "static_assert.h"
+
+#include <errno.h>
+#include <stddef.h>
+#include <stdint.h>
+
+// The code below was originally imported from <linux/nvme.h> include file from
+// Linux kernel sources. Types from <linux/types.h> were replaced.
+// Symbol names are unchanged but placed in a namespace to allow inclusion
+// of the original <linux/nvme.h>.
+namespace smartmontools {
+
+////////////////////////////////////////////////////////////////////////////
+// BEGIN: From <linux/nvme.h>
+
+struct nvme_error_log_page {
+ uint64_t error_count;
+ unsigned short sqid;
+ unsigned short cmdid;
+ unsigned short status_field;
+ unsigned short parm_error_location;
+ uint64_t lba;
+ unsigned int nsid;
+ unsigned char vs;
+ unsigned char resv[35];
+};
+STATIC_ASSERT(sizeof(nvme_error_log_page) == 64);
+
+struct nvme_id_power_state {
+ unsigned short max_power; // centiwatts
+ unsigned char rsvd2;
+ unsigned char flags;
+ unsigned int entry_lat; // microseconds
+ unsigned int exit_lat; // microseconds
+ unsigned char read_tput;
+ unsigned char read_lat;
+ unsigned char write_tput;
+ unsigned char write_lat;
+ unsigned short idle_power;
+ unsigned char idle_scale;
+ unsigned char rsvd19;
+ unsigned short active_power;
+ unsigned char active_work_scale;
+ unsigned char rsvd23[9];
+};
+STATIC_ASSERT(sizeof(nvme_id_power_state) == 32);
+
+struct nvme_id_ctrl {
+ unsigned short vid;
+ unsigned short ssvid;
+ char sn[20];
+ char mn[40];
+ char fr[8];
+ unsigned char rab;
+ unsigned char ieee[3];
+ unsigned char cmic;
+ unsigned char mdts;
+ unsigned short cntlid;
+ unsigned int ver;
+ unsigned int rtd3r;
+ unsigned int rtd3e;
+ unsigned int oaes;
+ unsigned int ctratt;
+ unsigned char rsvd100[156];
+ unsigned short oacs;
+ unsigned char acl;
+ unsigned char aerl;
+ unsigned char frmw;
+ unsigned char lpa;
+ unsigned char elpe;
+ unsigned char npss;
+ unsigned char avscc;
+ unsigned char apsta;
+ unsigned short wctemp;
+ unsigned short cctemp;
+ unsigned short mtfa;
+ unsigned int hmpre;
+ unsigned int hmmin;
+ unsigned char tnvmcap[16];
+ unsigned char unvmcap[16];
+ unsigned int rpmbs;
+ unsigned short edstt;
+ unsigned char dsto;
+ unsigned char fwug;
+ unsigned short kas;
+ unsigned short hctma;
+ unsigned short mntmt;
+ unsigned short mxtmt;
+ unsigned int sanicap;
+ unsigned char rsvd332[180];
+ unsigned char sqes;
+ unsigned char cqes;
+ unsigned short maxcmd;
+ unsigned int nn;
+ unsigned short oncs;
+ unsigned short fuses;
+ unsigned char fna;
+ unsigned char vwc;
+ unsigned short awun;
+ unsigned short awupf;
+ unsigned char nvscc;
+ unsigned char rsvd531;
+ unsigned short acwu;
+ unsigned char rsvd534[2];
+ unsigned int sgls;
+ unsigned char rsvd540[228];
+ char subnqn[256];
+ unsigned char rsvd1024[768];
+ unsigned int ioccsz;
+ unsigned int iorcsz;
+ unsigned short icdoff;
+ unsigned char ctrattr;
+ unsigned char msdbd;
+ unsigned char rsvd1804[244];
+ struct nvme_id_power_state psd[32];
+ unsigned char vs[1024];
+};
+STATIC_ASSERT(sizeof(nvme_id_ctrl) == 4096);
+
+struct nvme_lbaf {
+ unsigned short ms;
+ unsigned char ds;
+ unsigned char rp;
+};
+STATIC_ASSERT(sizeof(nvme_lbaf) == 4);
+
+struct nvme_id_ns {
+ uint64_t nsze;
+ uint64_t ncap;
+ uint64_t nuse;
+ unsigned char nsfeat;
+ unsigned char nlbaf;
+ unsigned char flbas;
+ unsigned char mc;
+ unsigned char dpc;
+ unsigned char dps;
+ unsigned char nmic;
+ unsigned char rescap;
+ unsigned char fpi;
+ unsigned char rsvd33;
+ unsigned short nawun;
+ unsigned short nawupf;
+ unsigned short nacwu;
+ unsigned short nabsn;
+ unsigned short nabo;
+ unsigned short nabspf;
+ unsigned char rsvd46[2];
+ unsigned char nvmcap[16];
+ unsigned char rsvd64[40];
+ unsigned char nguid[16];
+ unsigned char eui64[8];
+ struct nvme_lbaf lbaf[16];
+ unsigned char rsvd192[192];
+ unsigned char vs[3712];
+};
+STATIC_ASSERT(sizeof(nvme_id_ns) == 4096);
+
+struct nvme_smart_log {
+ unsigned char critical_warning;
+ unsigned char temperature[2];
+ unsigned char avail_spare;
+ unsigned char spare_thresh;
+ unsigned char percent_used;
+ unsigned char rsvd6[26];
+ unsigned char data_units_read[16];
+ unsigned char data_units_written[16];
+ unsigned char host_reads[16];
+ unsigned char host_writes[16];
+ unsigned char ctrl_busy_time[16];
+ unsigned char power_cycles[16];
+ unsigned char power_on_hours[16];
+ unsigned char unsafe_shutdowns[16];
+ unsigned char media_errors[16];
+ unsigned char num_err_log_entries[16];
+ unsigned int warning_temp_time;
+ unsigned int critical_comp_time;
+ unsigned short temp_sensor[8];
+ unsigned int thm_temp1_trans_count;
+ unsigned int thm_temp2_trans_count;
+ unsigned int thm_temp1_total_time;
+ unsigned int thm_temp2_total_time;
+ unsigned char rsvd232[280];
+};
+STATIC_ASSERT(sizeof(nvme_smart_log) == 512);
+
+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_activate_fw = 0x10,
+//nvme_admin_download_fw = 0x11,
+ nvme_admin_dev_self_test = 0x14, // NVMe 1.3
+//nvme_admin_ns_attach = 0x15,
+//nvme_admin_format_nvm = 0x80,
+//nvme_admin_security_send = 0x81,
+//nvme_admin_security_recv = 0x82,
+};
+
+// END: From <linux/nvme.h>
+////////////////////////////////////////////////////////////////////////////
+
+// Figure 213 of NVM Express(TM) Base Specification, revision 2.0a, July 2021
+struct nvme_self_test_result {
+ uint8_t self_test_status;
+ uint8_t segment;
+ uint8_t valid;
+ uint8_t rsvd3;
+ uint8_t power_on_hours[8]; // unaligned LE 64
+ uint32_t nsid;
+ uint8_t lba[8]; // unaligned LE 64
+ uint8_t status_code_type;
+ uint8_t status_code;
+ uint8_t vendor_specific[2];
+};
+STATIC_ASSERT(sizeof(nvme_self_test_result) == 28);
+
+// Figure 212 of NVM Express(TM) Base Specification, revision 2.0a, July 2021
+struct nvme_self_test_log {
+ uint8_t current_operation;
+ uint8_t current_completion;
+ uint8_t rsvd2[2];
+ nvme_self_test_result results[20]; // [0] = newest
+};
+STATIC_ASSERT(sizeof(nvme_self_test_log) == 564);
+
+} // namespace smartmontools
+
+class nvme_device;
+
+// Print NVMe debug messages?
+extern unsigned char nvme_debugmode;
+
+// Read NVMe Identify Controller data structure.
+bool nvme_read_id_ctrl(nvme_device * device, smartmontools::nvme_id_ctrl & id_ctrl);
+
+// Read NVMe Identify Namespace data structure for namespace NSID.
+bool nvme_read_id_ns(nvme_device * device, unsigned nsid, smartmontools::nvme_id_ns & id_ns);
+
+// Read NVMe log page with identifier LID.
+unsigned nvme_read_log_page(nvme_device * device, unsigned nsid, unsigned char lid,
+ void * data, unsigned size, bool lpo_sup, unsigned offset = 0);
+
+// Read NVMe Error Information Log.
+unsigned nvme_read_error_log(nvme_device * device, smartmontools::nvme_error_log_page * error_log,
+ unsigned num_entries, bool lpo_sup);
+
+// Read NVMe SMART/Health Information log.
+bool nvme_read_smart_log(nvme_device * device, smartmontools::nvme_smart_log & smart_log);
+
+// Read NVMe Self-test Log.
+bool nvme_read_self_test_log(nvme_device * device, uint32_t nsid,
+ smartmontools::nvme_self_test_log & self_test_log);
+
+// Start Self-test
+bool nvme_self_test(nvme_device * device, uint8_t stc, uint32_t nsid);
+
+// Return true if NVMe status indicates an error.
+constexpr bool nvme_status_is_error(uint16_t status)
+ { return !!(status & 0x07ff); }
+
+// Return errno for NVMe status SCT/SC fields: 0, EINVAL or EIO.
+int nvme_status_to_errno(uint16_t status);
+
+// Return error message for NVMe status SCT/SC fields or nullptr if unknown.
+const char * nvme_status_to_str(uint16_t status);
+
+// Return error message for NVMe status SCT/SC fields or explanatory message if unknown.
+const char * nvme_status_to_info_str(char * buf, size_t bufsize, uint16_t status);
+
+// Version of above for fixed size buffers.
+template <size_t SIZE>
+inline const char * nvme_status_to_info_str(char (& buf)[SIZE], unsigned status)
+ { return nvme_status_to_info_str(buf, SIZE, status); }
+
+#endif // NVMECMDS_H