1 // SPDX-License-Identifier: GPL-2.0
3 * nvme structure declarations and helper functions for the
10 #include <linux/nvme_ioctl.h>
14 * If the uapi headers installed on the system lacks nvme uring command
15 * support, use the local version to prevent compilation issues.
17 #ifndef CONFIG_NVME_URING_CMD
18 struct nvme_uring_cmd {
39 #define NVME_URING_CMD_IO _IOWR('N', 0x80, struct nvme_uring_cmd)
40 #define NVME_URING_CMD_IO_VEC _IOWR('N', 0x81, struct nvme_uring_cmd)
41 #endif /* CONFIG_NVME_URING_CMD */
43 #define NVME_DEFAULT_IOCTL_TIMEOUT 0
44 #define NVME_IDENTIFY_DATA_SIZE 4096
45 #define NVME_IDENTIFY_CSI_SHIFT 24
46 #define NVME_NQN_LENGTH 256
48 #define NVME_PI_APP_DISABLE 0xFFFF
49 #define NVME_PI_REF_DISABLE 0xFFFFFFFF
51 #define NVME_ZNS_ZRA_REPORT_ZONES 0
52 #define NVME_ZNS_ZRAS_FEAT_ERZ (1 << 16)
53 #define NVME_ZNS_ZSA_RESET 0x4
54 #define NVME_ZONE_TYPE_SEQWRITE_REQ 0x2
56 #define NVME_ATTRIBUTE_DEALLOCATE (1 << 2)
58 enum nvme_identify_cns {
59 NVME_IDENTIFY_CNS_NS = 0x00,
60 NVME_IDENTIFY_CNS_CTRL = 0x01,
61 NVME_IDENTIFY_CNS_CSI_NS = 0x05,
62 NVME_IDENTIFY_CNS_CSI_CTRL = 0x06,
71 enum nvme_admin_opcode {
72 nvme_admin_identify = 0x06,
76 nvme_cmd_write = 0x01,
79 nvme_cmd_io_mgmt_recv = 0x12,
80 nvme_zns_cmd_mgmt_send = 0x79,
81 nvme_zns_cmd_mgmt_recv = 0x7a,
85 NVME_ZNS_ZS_EMPTY = 0x1,
86 NVME_ZNS_ZS_IMPL_OPEN = 0x2,
87 NVME_ZNS_ZS_EXPL_OPEN = 0x3,
88 NVME_ZNS_ZS_CLOSED = 0x4,
89 NVME_ZNS_ZS_READ_ONLY = 0xd,
90 NVME_ZNS_ZS_FULL = 0xe,
91 NVME_ZNS_ZS_OFFLINE = 0xf,
94 enum nvme_id_ctrl_ctratt {
95 NVME_CTRL_CTRATT_ELBAS = 1 << 15,
99 NVME_ID_NS_NVM_STS_MASK = 0x7f,
100 NVME_ID_NS_NVM_GUARD_SHIFT = 7,
101 NVME_ID_NS_NVM_GUARD_MASK = 0x3,
105 NVME_NVM_NS_16B_GUARD = 0,
106 NVME_NVM_NS_32B_GUARD = 1,
107 NVME_NVM_NS_64B_GUARD = 2,
122 enum nvme_id_ns_dps {
123 NVME_NS_DPS_PI_NONE = 0,
124 NVME_NS_DPS_PI_TYPE1 = 1,
125 NVME_NS_DPS_PI_TYPE2 = 2,
126 NVME_NS_DPS_PI_TYPE3 = 3,
127 NVME_NS_DPS_PI_MASK = 7 << 0,
128 NVME_NS_DPS_PI_FIRST = 1 << 3,
131 enum nvme_io_control_flags {
132 NVME_IO_PRINFO_PRCHK_REF = 1U << 26,
133 NVME_IO_PRINFO_PRCHK_APP = 1U << 27,
134 NVME_IO_PRINFO_PRCHK_GUARD = 1U << 28,
135 NVME_IO_PRINFO_PRACT = 1U << 29,
138 struct nvme_pi_data {
151 /* 16 bit guard protection Information format */
152 struct nvme_16b_guard_pif {
158 /* 64 bit guard protection Information format */
159 struct nvme_64b_guard_pif {
203 struct nvme_lbaf lbaf[64];
225 struct nvme_id_ctrl {
309 char subnqn[NVME_NQN_LENGTH];
322 struct nvme_id_psd psd[32];
326 struct nvme_nvm_id_ns {
334 static inline int ilog2(uint32_t i)
345 struct nvme_zns_lbafe {
351 struct nvme_zns_id_ns {
369 struct nvme_zns_lbafe lbafe[64];
373 struct nvme_zns_desc {
385 struct nvme_zone_report {
388 struct nvme_zns_desc entries[];
391 struct nvme_fdp_ruh_status_desc {
399 struct nvme_fdp_ruh_status {
402 struct nvme_fdp_ruh_status_desc ruhss[];
405 struct nvme_dsm_range {
411 struct nvme_cmd_ext_io_opts {
417 int fio_nvme_iomgmt_ruhs(struct thread_data *td, struct fio_file *f,
418 struct nvme_fdp_ruh_status *ruhs, __u32 bytes);
420 int fio_nvme_get_info(struct fio_file *f, __u64 *nlba, __u32 pi_act,
421 struct nvme_data *data);
423 int fio_nvme_uring_cmd_prep(struct nvme_uring_cmd *cmd, struct io_u *io_u,
424 struct iovec *iov, struct nvme_dsm_range *dsm);
426 void fio_nvme_pi_fill(struct nvme_uring_cmd *cmd, struct io_u *io_u,
427 struct nvme_cmd_ext_io_opts *opts);
429 int fio_nvme_pi_verify(struct nvme_data *data, struct io_u *io_u);
431 int fio_nvme_get_zoned_model(struct thread_data *td, struct fio_file *f,
432 enum zbd_zoned_model *model);
434 int fio_nvme_report_zones(struct thread_data *td, struct fio_file *f,
435 uint64_t offset, struct zbd_zone *zbdz,
436 unsigned int nr_zones);
438 int fio_nvme_reset_wp(struct thread_data *td, struct fio_file *f,
439 uint64_t offset, uint64_t length);
441 int fio_nvme_get_max_open_zones(struct thread_data *td, struct fio_file *f,
442 unsigned int *max_open_zones);
444 static inline void put_unaligned_be48(__u64 val, __u8 *p)
454 static inline __u64 get_unaligned_be48(__u8 *p)
456 return (__u64)p[0] << 40 | (__u64)p[1] << 32 | (__u64)p[2] << 24 |
457 p[3] << 16 | p[4] << 8 | p[5];
460 static inline bool fio_nvme_pi_ref_escape(__u8 *reftag)
462 __u8 ref_esc[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
464 return memcmp(reftag, ref_esc, sizeof(ref_esc)) == 0;