summaryrefslogtreecommitdiffstats
path: root/nvme-lightnvm.h
diff options
context:
space:
mode:
Diffstat (limited to 'nvme-lightnvm.h')
-rw-r--r--nvme-lightnvm.h329
1 files changed, 329 insertions, 0 deletions
diff --git a/nvme-lightnvm.h b/nvme-lightnvm.h
new file mode 100644
index 0000000..19660b7
--- /dev/null
+++ b/nvme-lightnvm.h
@@ -0,0 +1,329 @@
+/*
+ * Copyright (C) 2016 CNEX Labs. All rights reserved.
+ *
+ * Author: Matias Bjoerling <matias@cnexlabs.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
+ * USA.
+ */
+
+#ifndef NVME_LIGHTNVM_H_
+#define NVME_LIGHTNVM_H_
+
+#include "linux/lightnvm.h"
+
+enum nvme_nvm_admin_opcode {
+ nvme_nvm_admin_identity = 0xe2,
+ nvme_nvm_admin_get_bb_tbl = 0xf2,
+ nvme_nvm_admin_set_bb_tbl = 0xf1,
+};
+
+struct nvme_nvm_identity {
+ __u8 opcode;
+ __u8 flags;
+ __le16 command_id;
+ __le32 nsid;
+ __le64 rsvd[2];
+ __le64 prp1;
+ __le64 prp2;
+ __le32 chnl_off;
+ __le32 rsvd11[5];
+};
+
+struct nvme_nvm_setbbtbl {
+ __u8 opcode;
+ __u8 flags;
+ __le16 rsvd1;
+ __le32 nsid;
+ __le32 cdw2;
+ __le32 cdw3;
+ __le64 metadata;
+ __u64 addr;
+ __le32 metadata_len;
+ __le32 data_len;
+ __le64 ppa;
+ __le16 nlb;
+ __u8 value;
+ __u8 rsvd2;
+ __le32 cdw14;
+ __le32 cdw15;
+ __le32 timeout_ms;
+ __le32 result;
+};
+
+struct nvme_nvm_getbbtbl {
+ __u8 opcode;
+ __u8 flags;
+ __le16 rsvd1;
+ __le32 nsid;
+ __le32 cdw2;
+ __le32 cdw3;
+ __u64 metadata;
+ __u64 addr;
+ __u32 metadata_len;
+ __u32 data_len;
+ __le64 ppa;
+ __le32 cdw12;
+ __le32 cdw13;
+ __le32 cdw14;
+ __le32 cdw15;
+ __le32 timeout_ms;
+ __le32 result;
+};
+
+struct nvme_nvm_command {
+ union {
+ struct nvme_nvm_identity identity;
+ struct nvme_nvm_getbbtbl get_bb;
+ };
+};
+
+struct nvme_nvm_completion {
+ __le64 result; /* Used by LightNVM to return ppa completions */
+ __le16 sq_head; /* how much of this queue may be reclaimed */
+ __le16 sq_id; /* submission queue that generated this entry */
+ __le16 command_id; /* of the command which completed */
+ __le16 status; /* did the command fail, and if so, why? */
+};
+
+#define NVME_NVM_LP_MLC_PAIRS 886
+struct nvme_nvm_lp_mlc {
+ __le16 num_pairs;
+ __u8 pairs[NVME_NVM_LP_MLC_PAIRS];
+};
+
+struct nvme_nvm_lp_tbl {
+ __u8 id[8];
+ struct nvme_nvm_lp_mlc mlc;
+};
+
+struct nvme_nvm_id12_group {
+ __u8 mtype;
+ __u8 fmtype;
+ __le16 res16;
+ __u8 num_ch;
+ __u8 num_lun;
+ __u8 num_pln;
+ __u8 rsvd1;
+ __le16 num_blk;
+ __le16 num_pg;
+ __le16 fpg_sz;
+ __le16 csecs;
+ __le16 sos;
+ __le16 rsvd2;
+ __le32 trdt;
+ __le32 trdm;
+ __le32 tprt;
+ __le32 tprm;
+ __le32 tbet;
+ __le32 tbem;
+ __le32 mpos;
+ __le32 mccap;
+ __le16 cpar;
+ __u8 reserved[10];
+ struct nvme_nvm_lp_tbl lptbl;
+} __attribute__((packed));
+
+struct nvme_nvm_addr_format {
+ __u8 ch_offset;
+ __u8 ch_len;
+ __u8 lun_offset;
+ __u8 lun_len;
+ __u8 pln_offset;
+ __u8 pln_len;
+ __u8 blk_offset;
+ __u8 blk_len;
+ __u8 pg_offset;
+ __u8 pg_len;
+ __u8 sect_offset;
+ __u8 sect_len;
+ __u8 res[4];
+} __attribute__((packed));
+
+enum {
+ LNVM_IDFY_CAP_BAD_BLK_TBL_MGMT = 0,
+ LNVM_IDFY_CAP_HYBRID_CMD_SUPP = 1,
+ LNVM_IDFY_CAP_VCOPY = 0,
+ LNVM_IDFY_CAP_MRESETS = 1,
+ LNVM_IDFY_DOM_HYBRID_MODE = 0,
+ LNVM_IDFY_DOM_ECC_MODE = 1,
+ LNVM_IDFY_GRP_MTYPE_NAND = 0,
+ LNVM_IDFY_GRP_FMTYPE_SLC = 0,
+ LNVM_IDFY_GRP_FMTYPE_MLC = 1,
+ LNVM_IDFY_GRP_FMTYPE_TLC = 2,
+ LNVM_IDFY_GRP_MPOS_SNGL_PLN_RD = 0,
+ LNVM_IDFY_GRP_MPOS_DUAL_PLN_RD = 1,
+ LNVM_IDFY_GRP_MPOS_QUAD_PLN_RD = 2,
+ LNVM_IDFY_GRP_MPOS_SNGL_PLN_PRG = 8,
+ LNVM_IDFY_GRP_MPOS_DUAL_PLN_PRG = 9,
+ LNVM_IDFY_GRP_MPOS_QUAD_PLN_PRG = 10,
+ LNVM_IDFY_GRP_MPOS_SNGL_PLN_ERS = 16,
+ LNVM_IDFY_GRP_MPOS_DUAL_PLN_ERS = 17,
+ LNVM_IDFY_GRP_MPOS_QUAD_PLN_ERS = 18,
+ LNVM_IDFY_GRP_MCCAP_SLC = 0,
+ LNVM_IDFY_GRP_MCCAP_CMD_SUSP = 1,
+ LNVM_IDFY_GRP_MCCAP_SCRAMBLE = 2,
+ LNVM_IDFY_GRP_MCCAP_ENCRYPT = 3,
+};
+
+struct nvme_nvm_id12 {
+ __u8 ver_id;
+ __u8 vmnt;
+ __u8 cgrps;
+ __u8 res;
+ __le32 cap;
+ __le32 dom;
+ struct nvme_nvm_addr_format ppaf;
+ __u8 resv[228];
+ struct nvme_nvm_id12_group groups[4];
+} __attribute__((packed));
+
+struct nvme_nvm_id20_addrf {
+ __u8 grp_len;
+ __u8 pu_len;
+ __u8 chk_len;
+ __u8 lba_len;
+ __u8 resv[4];
+} __attribute__((packed));
+
+struct nvme_nvm_id20 {
+ __u8 mjr;
+ __u8 mnr;
+ __u8 resv[6];
+
+ struct nvme_nvm_id20_addrf lbaf;
+
+ __le32 mccap;
+ __u8 resv2[12];
+
+ __u8 wit;
+ __u8 resv3[31];
+
+ /* Geometry */
+ __le16 num_grp;
+ __le16 num_pu;
+ __le32 num_chk;
+ __le32 clba;
+ __u8 resv4[52];
+
+ /* Write data requirements */
+ __le32 ws_min;
+ __le32 ws_opt;
+ __le32 mw_cunits;
+ __le32 maxoc;
+ __le32 maxocpu;
+ __u8 resv5[44];
+
+ /* Performance related metrics */
+ __le32 trdt;
+ __le32 trdm;
+ __le32 twrt;
+ __le32 twrm;
+ __le32 tcrst;
+ __le32 tcrsm;
+ __u8 resv6[40];
+
+ /* Reserved area */
+ __u8 resv7[2816];
+
+ /* Vendor specific */
+ __u8 vs[1024];
+} __attribute__((packed));
+
+struct nvme_nvm_id {
+ __u8 ver_id;
+ __u8 resv[4095];
+} __attribute__((packed));
+
+enum {
+ NVM_LID_CHUNK_INFO = 0xCA,
+};
+
+struct nvme_nvm_chunk_desc {
+ __u8 cs;
+ __u8 ct;
+ __u8 wli;
+ __u8 rsvd_7_3[5];
+ __u64 slba;
+ __u64 cnlb;
+ __u64 wp;
+};
+
+struct nvme_nvm_bb_tbl {
+ __u8 tblid[4];
+ __le16 verid;
+ __le16 revid;
+ __le32 rvsd1;
+ __le32 tblks;
+ __le32 tfact;
+ __le32 tgrown;
+ __le32 tdresv;
+ __le32 thresv;
+ __le32 rsvd2[8];
+ __u8 blk[0];
+};
+
+#define NVM_BLK_BITS (16)
+#define NVM_PG_BITS (16)
+#define NVM_SEC_BITS (8)
+#define NVM_PL_BITS (8)
+#define NVM_LUN_BITS (8)
+#define NVM_CH_BITS (7)
+
+struct ppa_addr {
+ /* Generic structure for all addresses */
+ union {
+ struct {
+ __u64 blk : NVM_BLK_BITS;
+ __u64 pg : NVM_PG_BITS;
+ __u64 sec : NVM_SEC_BITS;
+ __u64 pl : NVM_PL_BITS;
+ __u64 lun : NVM_LUN_BITS;
+ __u64 ch : NVM_CH_BITS;
+ __u64 reserved : 1;
+ } g;
+
+ __u64 ppa;
+ };
+};
+
+static inline struct ppa_addr generic_to_dev_addr(
+ struct nvme_nvm_addr_format *ppaf, struct ppa_addr r)
+{
+ struct ppa_addr l;
+
+ l.ppa = ((__u64)r.g.blk) << ppaf->blk_offset;
+ l.ppa |= ((__u64)r.g.pg) << ppaf->pg_offset;
+ l.ppa |= ((__u64)r.g.sec) << ppaf->sect_offset;
+ l.ppa |= ((__u64)r.g.pl) << ppaf->pln_offset;
+ l.ppa |= ((__u64)r.g.lun) << ppaf->lun_offset;
+ l.ppa |= ((__u64)r.g.ch) << ppaf->ch_offset;
+
+ return l;
+}
+
+int lnvm_get_identity(int fd, int nsid, struct nvme_nvm_id *nvm_id);
+
+int lnvm_do_init(char *, char *);
+int lnvm_do_list_devices(void);
+int lnvm_do_info(void);
+int lnvm_do_create_tgt(char *, char *, char *, int, int, int, int);
+int lnvm_do_remove_tgt(char *);
+int lnvm_do_factory_init(char *, int, int, int);
+int lnvm_do_id_ns(int, int, unsigned int);
+int lnvm_do_chunk_log(int, __u32, __u32, void *, unsigned int);
+int lnvm_do_get_bbtbl(int, int, int, int, unsigned int);
+int lnvm_do_set_bbtbl(int, int, int, int, int, int, __u8);
+
+#endif