1
0
Fork 0
nvme-cli/nvme-lightnvm.h

330 lines
6.8 KiB
C
Raw Normal View History

/*
* 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