Various fixes and support for newer nvme operations.
Signed-off-by: Keith Busch <kbusch@kernel.org>
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)
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,
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)
{
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);
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)
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,
* @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.
*/
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
* 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() -
/**
* 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
__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
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
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
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
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
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,
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:
* @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,
NVME_REG_PMRSTS = 0x0e08,
NVME_REG_PMREBS = 0x0e0c,
NVME_REG_PMRSWTP = 0x0e10,
- NVME_REG_PMRMSC = 0x0e14,
+ NVME_REG_PMRMSCL = 0x0e14,
+ NVME_REG_PMRMSCU = 0x0e18,
};
/**
case NVME_REG_ACQ:
case NVME_REG_BPMBL:
case NVME_REG_CMBMSC:
- case NVME_REG_PMRMSC:
return true;
default:
return false;
* 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.
__u8 vwc;
__le16 awun;
__le16 awupf;
- __u8 nvscc;
+ __u8 icsvscc;
__u8 nwpc;
__le16 acwu;
__u8 rsvd534[2];
__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;
/**
* struct nvme_ctrl_list -
- * @num;
+ * @num:
* @identifier:
*/
struct nvme_ctrl_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:
/**
* struct nvme_zns_id_ctrl -
- * @zamds:
+ * @zasl:
*/
struct nvme_zns_id_ctrl {
- __u8 zamds;
+ __u8 zasl;
__u8 rsvd1[4095];
};
} __attribute__((packed));
/**
- * enum -
+ * enum nvme_status_result -
* @NVME_ST_RESULT_NO_ERR:
* @NVME_ST_RESULT_ABORTED:
* @NVME_ST_RESULT_CLR:
};
/**
- * enum -
+ * enum nvme_st_code -
* @NVME_ST_CODE_NONE:
* @NVME_ST_CODE_SHORT:
* @NVME_ST_CODE_EXTENDED:
};
/**
- * 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:
NVME_ST_VALID_DIAG_INFO_SC = 1 << 3,
};
-
/**
* struct nvme_self_test_log -
* @current_operation:
__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;
/**
* struct nvme_persistent_event_log -
* @lid:
- * @ttl:
+ * @tnev:
+ * @tll:
* @rv:
- * @lht:
+ * @lhl:
* @ts:
* @poh:
* @pcc:
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;
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;
};
/**
/**
* 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[];
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,
};
/**
__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:
};
/**
- * struct nvme_resv_status -{
+ * struct nvme_resv_status -
* @gen:
* @rtype:
* @regctl:
};
/**
- * 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];
+
};
/**
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);
}
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)
{
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