/* * nvmecmds.h * * Home page of code is: https://www.smartmontools.org * * Copyright (C) 2016-23 Christian Franke * * Original code from : * 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 #include #include // The code below was originally imported from include file from // Linux kernel sources. Types from were replaced. // Symbol names are unchanged but placed in a namespace to allow inclusion // of the original . namespace smartmontools { //////////////////////////////////////////////////////////////////////////// // BEGIN: From 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 //////////////////////////////////////////////////////////////////////////// // 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 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