1533affcbSRobert Mustacchi /* 2533affcbSRobert Mustacchi * This file and its contents are supplied under the terms of the 3533affcbSRobert Mustacchi * Common Development and Distribution License ("CDDL"), version 1.0. 4533affcbSRobert Mustacchi * You may only use this file in accordance with the terms of version 5533affcbSRobert Mustacchi * 1.0 of the CDDL. 6533affcbSRobert Mustacchi * 7533affcbSRobert Mustacchi * A full copy of the text of the CDDL should have accompanied this 8533affcbSRobert Mustacchi * source. A copy of the CDDL is also available via the Internet at 9533affcbSRobert Mustacchi * http://www.illumos.org/license/CDDL. 10533affcbSRobert Mustacchi */ 11533affcbSRobert Mustacchi 12533affcbSRobert Mustacchi /* 13533affcbSRobert Mustacchi * Copyright 2024 Oxide Computer Company 14533affcbSRobert Mustacchi */ 15533affcbSRobert Mustacchi 16533affcbSRobert Mustacchi #ifndef _LIBNVME_IMPL_H 17533affcbSRobert Mustacchi #define _LIBNVME_IMPL_H 18533affcbSRobert Mustacchi 19533affcbSRobert Mustacchi /* 20533affcbSRobert Mustacchi * Implementation structures and related for libnvme. 21533affcbSRobert Mustacchi */ 22533affcbSRobert Mustacchi 23533affcbSRobert Mustacchi #include <libnvme.h> 24533affcbSRobert Mustacchi #include <libdevinfo.h> 25533affcbSRobert Mustacchi #include <stdbool.h> 26533affcbSRobert Mustacchi #include <nvme_common.h> 27533affcbSRobert Mustacchi #include <synch.h> 28533affcbSRobert Mustacchi 29533affcbSRobert Mustacchi #ifdef __cplusplus 30533affcbSRobert Mustacchi extern "C" { 31533affcbSRobert Mustacchi #endif 32533affcbSRobert Mustacchi 33533affcbSRobert Mustacchi /* 34533affcbSRobert Mustacchi * Maximum size of an internal error message. 35533affcbSRobert Mustacchi */ 36533affcbSRobert Mustacchi #define NVME_ERR_LEN 1024 37533affcbSRobert Mustacchi 38533affcbSRobert Mustacchi typedef struct nvme_err_data { 39533affcbSRobert Mustacchi nvme_err_t ne_err; 40533affcbSRobert Mustacchi int32_t ne_syserr; 41533affcbSRobert Mustacchi char ne_errmsg[NVME_ERR_LEN]; 42533affcbSRobert Mustacchi size_t ne_errlen; 43533affcbSRobert Mustacchi uint32_t ne_ctrl_sct; 44533affcbSRobert Mustacchi uint32_t ne_ctrl_sc; 45533affcbSRobert Mustacchi } nvme_err_data_t; 46533affcbSRobert Mustacchi 47533affcbSRobert Mustacchi struct nvme { 48533affcbSRobert Mustacchi nvme_err_data_t nh_err; 49533affcbSRobert Mustacchi di_node_t nh_devinfo; 50533affcbSRobert Mustacchi }; 51533affcbSRobert Mustacchi 52533affcbSRobert Mustacchi struct nvme_ctrl_disc { 53533affcbSRobert Mustacchi di_node_t ncd_devi; 54533affcbSRobert Mustacchi di_minor_t ncd_minor; 55533affcbSRobert Mustacchi }; 56533affcbSRobert Mustacchi 57533affcbSRobert Mustacchi struct nvme_ctrl_iter { 58533affcbSRobert Mustacchi nvme_t *ni_nvme; 59533affcbSRobert Mustacchi bool ni_done; 60533affcbSRobert Mustacchi di_node_t ni_cur; 61533affcbSRobert Mustacchi nvme_ctrl_disc_t ni_disc; 62533affcbSRobert Mustacchi }; 63533affcbSRobert Mustacchi 64533affcbSRobert Mustacchi struct nvme_ctrl { 65533affcbSRobert Mustacchi nvme_t *nc_nvme; 66533affcbSRobert Mustacchi nvme_err_data_t nc_err; 67533affcbSRobert Mustacchi di_node_t nc_devi; 68533affcbSRobert Mustacchi di_minor_t nc_minor; 69533affcbSRobert Mustacchi char *nc_devi_path; 70533affcbSRobert Mustacchi int32_t nc_inst; 71533affcbSRobert Mustacchi int nc_fd; 72533affcbSRobert Mustacchi nvme_version_t nc_vers; 73533affcbSRobert Mustacchi nvme_identify_ctrl_t nc_info; 74533affcbSRobert Mustacchi const struct nvme_vsd *nc_vsd; 75533affcbSRobert Mustacchi }; 76533affcbSRobert Mustacchi 77533affcbSRobert Mustacchi struct nvme_ns_disc { 78533affcbSRobert Mustacchi uint32_t nnd_nsid; 79533affcbSRobert Mustacchi nvme_ns_disc_level_t nnd_level; 80533affcbSRobert Mustacchi nvme_ns_disc_flags_t nnd_flags; 81533affcbSRobert Mustacchi uint8_t nnd_eui64[8]; 82533affcbSRobert Mustacchi uint8_t nnd_nguid[16]; 83533affcbSRobert Mustacchi }; 84533affcbSRobert Mustacchi 85533affcbSRobert Mustacchi struct nvme_ns_iter { 86533affcbSRobert Mustacchi nvme_ctrl_t *nni_ctrl; 87533affcbSRobert Mustacchi nvme_ns_disc_level_t nni_level; 88533affcbSRobert Mustacchi bool nni_err; 89533affcbSRobert Mustacchi bool nni_done; 90533affcbSRobert Mustacchi size_t nni_cur_idx; 91533affcbSRobert Mustacchi nvme_ns_disc_t nni_disc; 92533affcbSRobert Mustacchi }; 93533affcbSRobert Mustacchi 94533affcbSRobert Mustacchi struct nvme_ns { 95533affcbSRobert Mustacchi nvme_ctrl_t *nn_ctrl; 96533affcbSRobert Mustacchi uint32_t nn_nsid; 97533affcbSRobert Mustacchi }; 98533affcbSRobert Mustacchi 99533affcbSRobert Mustacchi struct nvme_nvm_lba_fmt { 100533affcbSRobert Mustacchi uint32_t nnlf_id; 101533affcbSRobert Mustacchi uint32_t nnlf_ms; 102533affcbSRobert Mustacchi uint64_t nnlf_lbasz; 103533affcbSRobert Mustacchi uint32_t nnlf_rel; 104533affcbSRobert Mustacchi }; 105533affcbSRobert Mustacchi 106533affcbSRobert Mustacchi struct nvme_ctrl_info { 107533affcbSRobert Mustacchi nvme_info_err_t nci_err; 108533affcbSRobert Mustacchi int32_t nci_syserr; 109533affcbSRobert Mustacchi char nci_errmsg[NVME_ERR_LEN]; 110533affcbSRobert Mustacchi size_t nci_errlen; 111533affcbSRobert Mustacchi /* 112533affcbSRobert Mustacchi * The NVMe strings are generally ASCII strings that have trailing 113533affcbSRobert Mustacchi * spaces on them ala SCSI. We transform that into a C style string 114533affcbSRobert Mustacchi * without trailing padding. The +1 assumes we need to add a terminator. 115533affcbSRobert Mustacchi */ 116533affcbSRobert Mustacchi char nci_serial[NVME_SERIAL_SZ + 1]; 117533affcbSRobert Mustacchi char nci_model[NVME_MODEL_SZ + 1]; 118533affcbSRobert Mustacchi char nci_fwrev[NVME_FWVER_SZ + 1]; 119533affcbSRobert Mustacchi bool nci_lbaf_valid[NVME_MAX_LBAF]; 120533affcbSRobert Mustacchi nvme_nvm_lba_fmt_t nci_lbaf[NVME_MAX_LBAF]; 121533affcbSRobert Mustacchi /* 122533affcbSRobert Mustacchi * Only information below here should be persisted. That is, the above 123533affcbSRobert Mustacchi * information is meant to be specific to the library. 124533affcbSRobert Mustacchi */ 125533affcbSRobert Mustacchi nvme_version_t nci_vers; 126533affcbSRobert Mustacchi int32_t nci_inst; 127533affcbSRobert Mustacchi char nci_dev_path[PATH_MAX]; 128533affcbSRobert Mustacchi nvme_identify_ctrl_t nci_info; 129533affcbSRobert Mustacchi nvme_identify_nsid_t nci_ns; 130533affcbSRobert Mustacchi nvme_ctrl_transport_t nci_tport; 131533affcbSRobert Mustacchi uint16_t nci_vid; 132533affcbSRobert Mustacchi uint16_t nci_did; 133533affcbSRobert Mustacchi uint16_t nci_subvid; 134533affcbSRobert Mustacchi uint16_t nci_subsys; 135533affcbSRobert Mustacchi uint8_t nci_rev; 136533affcbSRobert Mustacchi uint32_t nci_mps_min; 137533affcbSRobert Mustacchi uint32_t nci_mps_max; 138533affcbSRobert Mustacchi uint32_t nci_nintrs; 139533affcbSRobert Mustacchi }; 140533affcbSRobert Mustacchi 141533affcbSRobert Mustacchi /* 142533affcbSRobert Mustacchi * Internal nvlist_t keys for control information. 143533affcbSRobert Mustacchi */ 144533affcbSRobert Mustacchi #define NVME_NVL_CI_VERS "version" 145533affcbSRobert Mustacchi #define NVME_NVL_CI_VERS_0 0 146533affcbSRobert Mustacchi #define NVME_NVL_CI_INST "inst" 147533affcbSRobert Mustacchi #define NVME_NVL_CI_MAJOR "nvme-major-version" 148533affcbSRobert Mustacchi #define NVME_NVL_CI_MINOR "nvme-minor-version" 149533affcbSRobert Mustacchi #define NVME_NVL_CI_DEV_PATH "dev-path" 150533affcbSRobert Mustacchi #define NVME_NVL_CI_ID_CTRL "identify-controller" 151533affcbSRobert Mustacchi #define NVME_NVL_CI_ID_NS "identify-namespace" 152533affcbSRobert Mustacchi #define NVME_NVL_CI_TPORT "transport" 153533affcbSRobert Mustacchi #define NVME_NVL_CI_PCI_VID "pci-vendor-id" 154533affcbSRobert Mustacchi #define NVME_NVL_CI_PCI_DID "pci-device-id" 155533affcbSRobert Mustacchi #define NVME_NVL_CI_PCI_SUBVID "pci-subsystem-vendor-id" 156533affcbSRobert Mustacchi #define NVME_NVL_CI_PCI_SUBSYS "pci-subsystem-id" 157533affcbSRobert Mustacchi #define NVME_NVL_CI_PCI_REV "pci-revision-id" 158533affcbSRobert Mustacchi #define NVME_NVL_CI_PCI_MPSMIN "pci-memory-page-size-min" 159533affcbSRobert Mustacchi #define NVME_NVL_CI_PCI_MPSMAX "pci-memory-page-size-max" 160533affcbSRobert Mustacchi #define NVME_NVL_CI_PCI_NINTRS "pci-num-interrupts" 161533affcbSRobert Mustacchi 162533affcbSRobert Mustacchi struct nvme_ns_info { 163533affcbSRobert Mustacchi nvme_info_err_t nni_err; 164533affcbSRobert Mustacchi int32_t nni_syserr; 165533affcbSRobert Mustacchi char nni_errmsg[NVME_ERR_LEN]; 166533affcbSRobert Mustacchi size_t nni_errlen; 167533affcbSRobert Mustacchi uint32_t nni_nsid; 168533affcbSRobert Mustacchi nvme_version_t nni_vers; 169533affcbSRobert Mustacchi nvme_ns_disc_level_t nni_level; 170533affcbSRobert Mustacchi nvme_ioctl_ns_info_t nni_info; 171533affcbSRobert Mustacchi bool nni_lbaf_valid[NVME_MAX_LBAF]; 172533affcbSRobert Mustacchi nvme_nvm_lba_fmt_t nni_lbaf[NVME_MAX_LBAF]; 173533affcbSRobert Mustacchi }; 174533affcbSRobert Mustacchi 175533affcbSRobert Mustacchi typedef enum { 176533affcbSRobert Mustacchi NVME_LOG_REQ_F_RAE = 1 << 0, 177533affcbSRobert Mustacchi NVME_LOG_REQ_F_BCAST_NS_OK = 1 << 1 178533affcbSRobert Mustacchi } nvme_log_req_flags_t; 179533affcbSRobert Mustacchi 180533affcbSRobert Mustacchi struct nvme_log_req { 181533affcbSRobert Mustacchi nvme_ctrl_t *nlr_ctrl; 182533affcbSRobert Mustacchi uint32_t nlr_need; 183533affcbSRobert Mustacchi uint32_t nlr_allow; 184533affcbSRobert Mustacchi nvme_csi_t nlr_csi; 185533affcbSRobert Mustacchi uint32_t nlr_lid; 186533affcbSRobert Mustacchi uint32_t nlr_lsp; 187533affcbSRobert Mustacchi uint32_t nlr_lsi; 188533affcbSRobert Mustacchi uint32_t nlr_nsid; 189533affcbSRobert Mustacchi nvme_log_req_flags_t nlr_flags; 190533affcbSRobert Mustacchi void *nlr_output; 191533affcbSRobert Mustacchi size_t nlr_output_len; 192533affcbSRobert Mustacchi uint64_t nlr_offset; 193533affcbSRobert Mustacchi }; 194533affcbSRobert Mustacchi 195533affcbSRobert Mustacchi /* 196533affcbSRobert Mustacchi * This structure is used internally to describe information about a given log 197533affcbSRobert Mustacchi * page. 198533affcbSRobert Mustacchi */ 199533affcbSRobert Mustacchi typedef enum { 200533affcbSRobert Mustacchi /* 201533affcbSRobert Mustacchi * This indicates that the log page is actually implemented. 202533affcbSRobert Mustacchi */ 203533affcbSRobert Mustacchi NVME_LOG_DISC_F_IMPL = 1 << 0 204533affcbSRobert Mustacchi } nvme_log_disc_flags_t; 205533affcbSRobert Mustacchi 206533affcbSRobert Mustacchi struct nvme_log_disc { 207533affcbSRobert Mustacchi const char *nld_short; 208533affcbSRobert Mustacchi const char *nld_desc; 209533affcbSRobert Mustacchi uint32_t nld_lid; 210533affcbSRobert Mustacchi nvme_csi_t nld_csi; 211533affcbSRobert Mustacchi nvme_log_disc_kind_t nld_kind; 212533affcbSRobert Mustacchi nvme_log_disc_source_t nld_srcs; 213533affcbSRobert Mustacchi nvme_log_disc_fields_t nld_fields; 214533affcbSRobert Mustacchi nvme_log_disc_scope_t nld_scope; 215533affcbSRobert Mustacchi nvme_log_disc_flags_t nld_flags; 216533affcbSRobert Mustacchi nvme_log_size_kind_t nld_size_kind; 217533affcbSRobert Mustacchi uint64_t nld_alloc_len; 218533affcbSRobert Mustacchi nvme_log_page_var_len_f nld_var_func; 219533affcbSRobert Mustacchi }; 220533affcbSRobert Mustacchi 221533affcbSRobert Mustacchi struct nvme_log_iter { 222533affcbSRobert Mustacchi nvme_ctrl_t *nli_ctrl; 223533affcbSRobert Mustacchi nvme_log_disc_scope_t nli_scope; 224533affcbSRobert Mustacchi bool nli_std_done; 225533affcbSRobert Mustacchi bool nli_vs_done; 226533affcbSRobert Mustacchi size_t nli_cur_idx; 227533affcbSRobert Mustacchi nvme_log_disc_t nli_nld; 228533affcbSRobert Mustacchi }; 229533affcbSRobert Mustacchi 230533affcbSRobert Mustacchi /* 231533affcbSRobert Mustacchi * Feature discovery and iteration. 232533affcbSRobert Mustacchi */ 233533affcbSRobert Mustacchi struct nvme_feat_disc { 234533affcbSRobert Mustacchi const char *nfd_short; 235533affcbSRobert Mustacchi const char *nfd_spec; 236533affcbSRobert Mustacchi uint32_t nfd_fid; 237533affcbSRobert Mustacchi nvme_feat_kind_t nfd_kind; 238533affcbSRobert Mustacchi nvme_feat_scope_t nfd_scope; 239533affcbSRobert Mustacchi nvme_feat_flags_t nfd_flags; 240533affcbSRobert Mustacchi nvme_feat_csi_t nfd_csi; 241533affcbSRobert Mustacchi nvme_get_feat_fields_t nfd_in_get; 242533affcbSRobert Mustacchi nvme_set_feat_fields_t nfd_in_set; 243533affcbSRobert Mustacchi nvme_feat_output_t nfd_out_get; 244533affcbSRobert Mustacchi nvme_feat_output_t nfd_out_set; 245533affcbSRobert Mustacchi uint64_t nfd_len; 246533affcbSRobert Mustacchi nvme_feat_impl_t nfd_impl; 247533affcbSRobert Mustacchi }; 248533affcbSRobert Mustacchi 249533affcbSRobert Mustacchi struct nvme_feat_iter { 250533affcbSRobert Mustacchi nvme_ctrl_t *nfi_ctrl; 251533affcbSRobert Mustacchi nvme_feat_scope_t nfi_scope; 252533affcbSRobert Mustacchi size_t nfi_cur_idx; 253533affcbSRobert Mustacchi nvme_feat_disc_t nfi_disc; 254533affcbSRobert Mustacchi }; 255533affcbSRobert Mustacchi 256533affcbSRobert Mustacchi struct nvme_get_feat_req { 257533affcbSRobert Mustacchi nvme_ctrl_t *gfr_ctrl; 258533affcbSRobert Mustacchi uint32_t gfr_need; 259533affcbSRobert Mustacchi uint32_t gfr_allow; 260533affcbSRobert Mustacchi nvme_feat_flags_t gfr_flags; 261533affcbSRobert Mustacchi uint32_t gfr_fid; 262533affcbSRobert Mustacchi uint32_t gfr_sel; 263533affcbSRobert Mustacchi uint32_t gfr_nsid; 264533affcbSRobert Mustacchi uint32_t gfr_cdw11; 265533affcbSRobert Mustacchi void *gfr_buf; 266533affcbSRobert Mustacchi size_t gfr_len; 267533affcbSRobert Mustacchi uint64_t gfr_targ_len; 268533affcbSRobert Mustacchi /* 269533affcbSRobert Mustacchi * The following are set on exec. 270533affcbSRobert Mustacchi */ 271533affcbSRobert Mustacchi bool gfr_results_valid; 272533affcbSRobert Mustacchi uint32_t gfr_cdw0; 273533affcbSRobert Mustacchi }; 274533affcbSRobert Mustacchi 275533affcbSRobert Mustacchi /* 276533affcbSRobert Mustacchi * Identify command request 277533affcbSRobert Mustacchi */ 278533affcbSRobert Mustacchi struct nvme_id_req { 279533affcbSRobert Mustacchi nvme_ctrl_t *nir_ctrl; 280533affcbSRobert Mustacchi const nvme_identify_info_t *nir_info; 281533affcbSRobert Mustacchi nvme_identify_req_field_t nir_need; 282533affcbSRobert Mustacchi nvme_identify_req_field_t nir_allow; 283533affcbSRobert Mustacchi uint32_t nir_nsid; 284533affcbSRobert Mustacchi uint32_t nir_ctrlid; 285533affcbSRobert Mustacchi void *nir_buf; 286533affcbSRobert Mustacchi }; 287533affcbSRobert Mustacchi 288533affcbSRobert Mustacchi /* 289533affcbSRobert Mustacchi * Vendor unique command support. 290533affcbSRobert Mustacchi */ 291533affcbSRobert Mustacchi struct nvme_vuc_disc { 292533affcbSRobert Mustacchi const char *nvd_short; 293533affcbSRobert Mustacchi const char *nvd_desc; 294533affcbSRobert Mustacchi uint8_t nvd_opc; 295533affcbSRobert Mustacchi nvme_vuc_disc_impact_t nvd_impact; 296533affcbSRobert Mustacchi nvme_vuc_disc_io_t nvd_dt; 297533affcbSRobert Mustacchi nvme_vuc_disc_lock_t nvd_lock; 298533affcbSRobert Mustacchi }; 299533affcbSRobert Mustacchi 300533affcbSRobert Mustacchi struct nvme_vuc_iter { 301533affcbSRobert Mustacchi nvme_ctrl_t *nvi_ctrl; 302533affcbSRobert Mustacchi size_t nvi_cur_idx; 303533affcbSRobert Mustacchi }; 304533affcbSRobert Mustacchi 305533affcbSRobert Mustacchi struct nvme_vuc_req { 306533affcbSRobert Mustacchi nvme_ctrl_t *nvr_ctrl; 307533affcbSRobert Mustacchi uint32_t nvr_need; 308533affcbSRobert Mustacchi uint32_t nvr_opcode; 309533affcbSRobert Mustacchi uint32_t nvr_timeout; 310533affcbSRobert Mustacchi uint32_t nvr_nsid; 311533affcbSRobert Mustacchi uint32_t nvr_cdw12; 312533affcbSRobert Mustacchi uint32_t nvr_cdw13; 313533affcbSRobert Mustacchi uint32_t nvr_cdw14; 314533affcbSRobert Mustacchi uint32_t nvr_cdw15; 315533affcbSRobert Mustacchi uint32_t nvr_impact; 316533affcbSRobert Mustacchi size_t nvr_outlen; 317533affcbSRobert Mustacchi size_t nvr_inlen; 318533affcbSRobert Mustacchi void *nvr_output; 319533affcbSRobert Mustacchi const void *nvr_input; 320533affcbSRobert Mustacchi /* 321533affcbSRobert Mustacchi * The following values are set on exec. 322533affcbSRobert Mustacchi */ 323533affcbSRobert Mustacchi bool nvr_results_valid; 324533affcbSRobert Mustacchi uint32_t nvr_cdw0; 325533affcbSRobert Mustacchi }; 326533affcbSRobert Mustacchi 327533affcbSRobert Mustacchi /* 328533affcbSRobert Mustacchi * If we ever support updating the boot partition ID, our expectation is that we 329533affcbSRobert Mustacchi * end up doing that through other library interfaces even if it uses the same 330533affcbSRobert Mustacchi * underlying ioctl. That ultimately will keep things simpler from a consumer 331533affcbSRobert Mustacchi * perspective. 332533affcbSRobert Mustacchi */ 333533affcbSRobert Mustacchi struct nvme_fw_commit_req { 334533affcbSRobert Mustacchi nvme_ctrl_t *fwc_ctrl; 335533affcbSRobert Mustacchi uint32_t fwc_need; 336533affcbSRobert Mustacchi uint32_t fwc_slot; 337533affcbSRobert Mustacchi uint32_t fwc_action; 338533affcbSRobert Mustacchi }; 339533affcbSRobert Mustacchi 340533affcbSRobert Mustacchi /* 341533affcbSRobert Mustacchi * Format request data. 342533affcbSRobert Mustacchi */ 343533affcbSRobert Mustacchi struct nvme_format_req { 344533affcbSRobert Mustacchi nvme_ctrl_t *nfr_ctrl; 345533affcbSRobert Mustacchi uint32_t nfr_need; 346533affcbSRobert Mustacchi bool nfr_ns; 347533affcbSRobert Mustacchi uint32_t nfr_lbaf; 348533affcbSRobert Mustacchi uint32_t nfr_ses; 349533affcbSRobert Mustacchi uint32_t nfr_nsid; 350533affcbSRobert Mustacchi }; 351533affcbSRobert Mustacchi 352533affcbSRobert Mustacchi /* 353533affcbSRobert Mustacchi * WDC e6 request. This was made an opaque request style structure to try to 354533affcbSRobert Mustacchi * safeguard us against future changes where something like the optional mode 355533affcbSRobert Mustacchi * byte was required (right now it's just always zero). 356533affcbSRobert Mustacchi */ 357533affcbSRobert Mustacchi struct nvme_wdc_e6_req { 358533affcbSRobert Mustacchi uint32_t wer_need; 359533affcbSRobert Mustacchi nvme_vuc_req_t *wer_vuc; 360533affcbSRobert Mustacchi }; 361533affcbSRobert Mustacchi 362533affcbSRobert Mustacchi /* 363533affcbSRobert Mustacchi * Common interfaces for operation success and failure. There are currently 364533affcbSRobert Mustacchi * errors that can exist on four different objects in the library and there is 365533affcbSRobert Mustacchi * one success() and error() function for each of them. See the theory statement 366533affcbSRobert Mustacchi * section on errors in libnvme.c for more information. Note, all namespace and 367533affcbSRobert Mustacchi * request structures set errors on the controller. 368533affcbSRobert Mustacchi * 369533affcbSRobert Mustacchi * The controller has an extra error path that is used for converting ioctls to 370533affcbSRobert Mustacchi * semantic errors. It takes care of translating the different kinds of kernel 371533affcbSRobert Mustacchi * errors to the library's errors. Our goal is to never programmatically leak 372533affcbSRobert Mustacchi * the kernel ioctls and their error codes as they do not promise stability 373533affcbSRobert Mustacchi * unlike our aspirations. It also doesn't allow for variable arguments and only 374533affcbSRobert Mustacchi * takes a single description. 375533affcbSRobert Mustacchi */ 376533affcbSRobert Mustacchi extern bool nvme_error(nvme_t *, nvme_err_t, int32_t, const char *, 377533affcbSRobert Mustacchi ...) __PRINTFLIKE(4); 378533affcbSRobert Mustacchi extern bool nvme_success(nvme_t *); 379533affcbSRobert Mustacchi 380533affcbSRobert Mustacchi extern bool nvme_ctrl_error(nvme_ctrl_t *, nvme_err_t, int32_t, const char *, 381533affcbSRobert Mustacchi ...) __PRINTFLIKE(4); 382533affcbSRobert Mustacchi extern bool nvme_ioctl_error(nvme_ctrl_t *, const nvme_ioctl_common_t *, 383533affcbSRobert Mustacchi const char *); 384533affcbSRobert Mustacchi extern bool nvme_ioctl_syserror(nvme_ctrl_t *, int, const char *); 385533affcbSRobert Mustacchi extern bool nvme_ctrl_success(nvme_ctrl_t *); 386533affcbSRobert Mustacchi 387533affcbSRobert Mustacchi extern bool nvme_info_error(nvme_ctrl_info_t *, nvme_info_err_t, int32_t, 388533affcbSRobert Mustacchi const char *, ...) __PRINTFLIKE(4); 389533affcbSRobert Mustacchi extern bool nvme_info_success(nvme_ctrl_info_t *); 390533affcbSRobert Mustacchi 391533affcbSRobert Mustacchi extern bool nvme_ns_info_error(nvme_ns_info_t *, nvme_info_err_t, int32_t, 392533affcbSRobert Mustacchi const char *, ...) __PRINTFLIKE(4); 393533affcbSRobert Mustacchi extern bool nvme_ns_info_success(nvme_ns_info_t *); 394533affcbSRobert Mustacchi 395533affcbSRobert Mustacchi /* 396533affcbSRobert Mustacchi * Common functions for preserving and restoring error data. This comes up when 397533affcbSRobert Mustacchi * utilizing callback functions for discovery where we call libnvme functions. 398533affcbSRobert Mustacchi */ 399533affcbSRobert Mustacchi extern void nvme_err_save(const nvme_t *, nvme_err_data_t *); 400533affcbSRobert Mustacchi extern void nvme_err_set(nvme_t *, const nvme_err_data_t *); 401533affcbSRobert Mustacchi extern void nvme_ctrl_err_save(const nvme_ctrl_t *, nvme_err_data_t *); 402533affcbSRobert Mustacchi extern void nvme_ctrl_err_set(nvme_ctrl_t *, const nvme_err_data_t *); 403533affcbSRobert Mustacchi 404533affcbSRobert Mustacchi /* 405533affcbSRobert Mustacchi * Common functions for issuing ioctls to a controller. 406533affcbSRobert Mustacchi */ 407533affcbSRobert Mustacchi extern bool nvme_ioc_ctrl_info(nvme_ctrl_t *, nvme_ioctl_ctrl_info_t *); 408533affcbSRobert Mustacchi extern bool nvme_ioc_ns_info(nvme_ctrl_t *, uint32_t, nvme_ioctl_ns_info_t *); 409533affcbSRobert Mustacchi 410533affcbSRobert Mustacchi /* 411533affcbSRobert Mustacchi * Common validation template functions. 412533affcbSRobert Mustacchi */ 413533affcbSRobert Mustacchi extern bool nvme_field_miss_err(nvme_ctrl_t *, const nvme_field_info_t *, 414533affcbSRobert Mustacchi size_t, nvme_err_t, const char *, uint32_t); 415533affcbSRobert Mustacchi 416533affcbSRobert Mustacchi typedef struct { 417533affcbSRobert Mustacchi const nvme_field_info_t *chk_fields; 418533affcbSRobert Mustacchi size_t chk_index; 419533affcbSRobert Mustacchi nvme_err_t chk_field_range; 420533affcbSRobert Mustacchi nvme_err_t chk_field_unsup; 421533affcbSRobert Mustacchi nvme_err_t chk_field_unuse; 422533affcbSRobert Mustacchi } nvme_field_check_t; 423533affcbSRobert Mustacchi 424533affcbSRobert Mustacchi extern bool nvme_field_check_one(nvme_ctrl_t *, uint64_t, const char *, 425533affcbSRobert Mustacchi const nvme_field_check_t *, uint32_t allow); 426533affcbSRobert Mustacchi 427533affcbSRobert Mustacchi /* 428533affcbSRobert Mustacchi * Misc. functions. 429533affcbSRobert Mustacchi */ 430533affcbSRobert Mustacchi extern const char *nvme_tporttostr(nvme_ctrl_transport_t); 431533affcbSRobert Mustacchi extern nvme_ns_disc_level_t nvme_ns_state_to_disc_level(nvme_ns_state_t); 432533affcbSRobert Mustacchi extern const char *nvme_nsleveltostr(nvme_ns_disc_level_t); 433533affcbSRobert Mustacchi 434533affcbSRobert Mustacchi /* 435533affcbSRobert Mustacchi * Version related information and functions. There are statically declared 436533affcbSRobert Mustacchi * version structures in the library for use for internal comparisons. Note, we 437533affcbSRobert Mustacchi * have attempted to avoid a general comparison function in the internal API so 438533affcbSRobert Mustacchi * that way it's always clear what we're comparing to a version and can't 439533affcbSRobert Mustacchi * reverse things. 440533affcbSRobert Mustacchi */ 441533affcbSRobert Mustacchi extern const nvme_version_t nvme_vers_1v0; 442533affcbSRobert Mustacchi extern const nvme_version_t nvme_vers_1v1; 443533affcbSRobert Mustacchi extern const nvme_version_t nvme_vers_1v2; 444533affcbSRobert Mustacchi extern const nvme_version_t nvme_vers_1v3; 445533affcbSRobert Mustacchi extern const nvme_version_t nvme_vers_1v4; 446533affcbSRobert Mustacchi extern const nvme_version_t nvme_vers_2v0; 447533affcbSRobert Mustacchi 448533affcbSRobert Mustacchi extern bool nvme_vers_ctrl_atleast(const nvme_ctrl_t *, const nvme_version_t *); 449533affcbSRobert Mustacchi extern bool nvme_vers_ctrl_info_atleast(const nvme_ctrl_info_t *, 450533affcbSRobert Mustacchi const nvme_version_t *); 451533affcbSRobert Mustacchi extern bool nvme_vers_ns_info_atleast(const nvme_ns_info_t *, 452533affcbSRobert Mustacchi const nvme_version_t *); 453533affcbSRobert Mustacchi 454533affcbSRobert Mustacchi /* 455533affcbSRobert Mustacchi * Vendor-specific information. 456533affcbSRobert Mustacchi */ 4577655c6d5SRobert Mustacchi typedef struct nvme_vsd_ident { 4587655c6d5SRobert Mustacchi const char *nvdi_human; 4597655c6d5SRobert Mustacchi bool nvdi_subsys; 4607655c6d5SRobert Mustacchi uint16_t nvdi_vid; 4617655c6d5SRobert Mustacchi uint16_t nvdi_did; 4627655c6d5SRobert Mustacchi uint16_t nvdi_svid; 4637655c6d5SRobert Mustacchi uint16_t nvdi_sdid; 4647655c6d5SRobert Mustacchi } nvme_vsd_ident_t; 4657655c6d5SRobert Mustacchi 466533affcbSRobert Mustacchi typedef struct nvme_vsd { 4677655c6d5SRobert Mustacchi const nvme_vsd_ident_t *nvd_ident; 4687655c6d5SRobert Mustacchi size_t nvd_nident; 4697655c6d5SRobert Mustacchi const nvme_log_page_info_t *const *nvd_logs; 470533affcbSRobert Mustacchi size_t nvd_nlogs; 471533affcbSRobert Mustacchi const nvme_vuc_disc_t *nvd_vuc; 472533affcbSRobert Mustacchi size_t nvd_nvuc; 473533affcbSRobert Mustacchi } nvme_vsd_t; 474533affcbSRobert Mustacchi 4757655c6d5SRobert Mustacchi extern const nvme_log_page_info_t ocp_log_smart; 4767655c6d5SRobert Mustacchi extern const nvme_log_page_info_t ocp_log_errrec; 4777655c6d5SRobert Mustacchi extern const nvme_log_page_info_t ocp_log_fwact; 4787655c6d5SRobert Mustacchi extern const nvme_log_page_info_t ocp_log_lat; 4797655c6d5SRobert Mustacchi extern const nvme_log_page_info_t ocp_log_devcap; 4807655c6d5SRobert Mustacchi extern const nvme_log_page_info_t ocp_log_unsup; 4817655c6d5SRobert Mustacchi 482533affcbSRobert Mustacchi extern const nvme_vsd_t wdc_sn840; 4837655c6d5SRobert Mustacchi extern const nvme_vsd_t wdc_sn65x; 4847655c6d5SRobert Mustacchi extern const nvme_vsd_t micron_7300; 4857655c6d5SRobert Mustacchi extern const nvme_vsd_t micron_74x0; 4867655c6d5SRobert Mustacchi extern const nvme_vsd_t micron_x500; 4877655c6d5SRobert Mustacchi extern const nvme_vsd_t intel_p5510; 4887655c6d5SRobert Mustacchi extern const nvme_vsd_t solidigm_p5x20; 4897655c6d5SRobert Mustacchi extern const nvme_vsd_t solidigm_ps10x0; 490*5b080c3aSRobert Mustacchi extern const nvme_vsd_t kioxia_cd8; 491533affcbSRobert Mustacchi 492533affcbSRobert Mustacchi extern void nvme_vendor_map_ctrl(nvme_ctrl_t *); 493533affcbSRobert Mustacchi extern bool nvme_vendor_vuc_supported(nvme_ctrl_t *, const char *); 494533affcbSRobert Mustacchi 495533affcbSRobert Mustacchi /* 496533affcbSRobert Mustacchi * Internal formatting functions that probably could be external. 497533affcbSRobert Mustacchi */ 498533affcbSRobert Mustacchi #define NVME_NGUID_NAMELEN 33 499533affcbSRobert Mustacchi #define NVME_EUI64_NAMELEN 17 500533affcbSRobert Mustacchi 501533affcbSRobert Mustacchi extern int nvme_format_nguid(const uint8_t [16], char *, size_t); 5022c6ce8c7SToomas Soome extern int nvme_format_eui64(const uint8_t [8], char *, size_t); 503533affcbSRobert Mustacchi 504533affcbSRobert Mustacchi #ifdef __cplusplus 505533affcbSRobert Mustacchi } 506533affcbSRobert Mustacchi #endif 507533affcbSRobert Mustacchi 508533affcbSRobert Mustacchi #endif /* _LIBNVME_IMPL_H */ 509