]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
Add open-channel 2.0 identify support
authorMatias Bjørling <mb@lightnvm.io>
Fri, 25 May 2018 07:04:34 +0000 (09:04 +0200)
committerMatias Bjørling <mb@lightnvm.io>
Fri, 25 May 2018 07:22:19 +0000 (09:22 +0200)
The 2.0 specification has been released. Update the lightnvm
submodule to understand the 2.0 geometry structure.

Signed-off-by: Matias Bjørling <mb@lightnvm.io>
nvme-lightnvm.c
nvme-lightnvm.h

index 12a0b01d8bf0f21706fd6758b034ed8a3ccf802a..465f4912147a2c285b212e75e623a84478800001 100644 (file)
@@ -239,7 +239,7 @@ int lnvm_do_factory_init(char *devname, int erase_only_marked,
        return ret;
 }
 
-static void show_lnvm_id_grp(struct nvme_nvm_id_group *grp, int human)
+static void show_lnvm_id_grp(struct nvme_nvm_id12_group *grp, int human)
 {
        uint32_t mpos = (uint32_t)le32_to_cpu(grp->mpos);
        uint32_t mccap = (uint32_t)le32_to_cpu(grp->mccap);
@@ -329,7 +329,7 @@ static void show_lnvm_ppaf(struct nvme_nvm_addr_format *ppaf)
                                        ppaf->sect_offset, ppaf->sect_len);
 }
 
-static void show_lnvm_id_ns(struct nvme_nvm_id *id, unsigned int flags)
+static void show_lnvm_id12_ns(struct nvme_nvm_id12 *id, unsigned int flags)
 {
        int i;
        int human = flags & HUMAN;
@@ -374,6 +374,66 @@ static void show_lnvm_id_ns(struct nvme_nvm_id *id, unsigned int flags)
        }
 }
 
+static void show_lnvm_id20_ns(struct nvme_nvm_id20 *id, unsigned int flags)
+{
+       int human = flags & HUMAN;
+       uint32_t mccap = (uint32_t) le32_to_cpu(id->mccap);
+
+       printf("ver_major     : %#x\n", id->mjr);
+       printf("ver_minor     : %#x\n", id->mnr);
+
+       printf("mccap         : %#x\n", mccap);
+       if (human) {
+               if (mccap & (1 << LNVM_IDFY_CAP_VCOPY))
+                       printf("           [0]: Vector copy support\n");
+               if (mccap & (1 << LNVM_IDFY_CAP_MRESETS))
+                       printf("           [1]: Multiple resets support\n");
+       }
+       printf("wit           : %d\n", id->wit);
+
+       printf("lba format\n");
+       printf(" grp len      : %d\n", id->lbaf.grp_len);
+       printf(" pu len       : %d\n", id->lbaf.pu_len);
+       printf(" chk len      : %d\n", id->lbaf.chk_len);
+       printf(" clba len     : %d\n", id->lbaf.lba_len);
+
+       printf("geometry\n");
+       printf(" num_grp      : %d\n", le16_to_cpu(id->num_grp));
+       printf(" num_pu       : %d\n", le16_to_cpu(id->num_pu));
+       printf(" num_chk      : %d\n", le32_to_cpu(id->num_chk));
+       printf(" clba         : %d\n", le32_to_cpu(id->clba));
+       printf("write req\n");
+       printf(" ws_min       : %d\n", le32_to_cpu(id->ws_min));
+       printf(" ws_opt       : %d\n", le32_to_cpu(id->ws_opt));
+       printf(" mw_cunits    : %d\n", le32_to_cpu(id->mw_cunits));
+       printf(" maxoc        : %d\n", le32_to_cpu(id->maxoc));
+       printf(" maxocpu      : %d\n", le32_to_cpu(id->maxocpu));
+       printf("perf metrics\n");
+       printf(" trdt (ns)    : %d\n", le32_to_cpu(id->trdt));
+       printf(" trdm (ns)    : %d\n", le32_to_cpu(id->trdm));
+       printf(" twrt (ns)    : %d\n", le32_to_cpu(id->twrt));
+       printf(" twrm (ns)    : %d\n", le32_to_cpu(id->twrm));
+       printf(" tcrst (ns)   : %d\n", le32_to_cpu(id->tcrst));
+       printf(" tcrsm (ns)   : %d\n", le32_to_cpu(id->tcrsm));
+}
+
+static void show_lnvm_id_ns(struct nvme_nvm_id *id, unsigned int flags)
+{
+       switch (id->ver_id) {
+               case 1:
+                       show_lnvm_id12_ns((struct nvme_nvm_id12 *)id,
+                                       flags);
+               break;
+               case 2:
+                       show_lnvm_id20_ns((struct nvme_nvm_id20 *)id,
+                                       flags);
+               break;
+               default:
+                       fprintf(stderr, "Version %d not supported.\n",
+                                       id->ver_id);
+       }
+}
+
 static int lnvm_get_identity(int fd, int nsid, struct nvme_nvm_id *nvm_id)
 {
        struct nvme_admin_cmd cmd = {
@@ -395,10 +455,8 @@ int lnvm_do_id_ns(int fd, int nsid, unsigned int flags)
        if (!err) {
                if (flags & RAW)
                        d_raw((unsigned char *)&nvm_id, sizeof(nvm_id));
-               else {
-                       printf("LightNVM Identify Geometry (%d):\n", nsid);
+               else
                        show_lnvm_id_ns(&nvm_id, flags);
-               }
        }
        else if (err > 0)
                fprintf(stderr, "NVMe Status:%s(%x) NSID:%d\n",
@@ -417,11 +475,11 @@ static void show_lnvm_bbtbl(struct nvme_nvm_bb_tbl *tbl)
        printf("Use raw output to retrieve table.\n");
 }
 
-static int __lnvm_do_get_bbtbl(int fd, struct nvme_nvm_id *id,
+static int __lnvm_do_get_bbtbl(int fd, struct nvme_nvm_id12 *id,
                                                struct ppa_addr ppa,
                                                unsigned int flags)
 {
-       struct nvme_nvm_id_group *grp = &id->groups[0];
+       struct nvme_nvm_id12_group *grp = &id->groups[0];
        int bbtblsz = ((uint16_t)le16_to_cpu(grp->num_blk) * grp->num_pln);
        int bufsz = bbtblsz + sizeof(struct nvme_nvm_bb_tbl);
        struct nvme_nvm_bb_tbl *bbtbl;
@@ -461,17 +519,23 @@ static int __lnvm_do_get_bbtbl(int fd, struct nvme_nvm_id *id,
 
 int lnvm_do_get_bbtbl(int fd, int nsid, int lunid, int chid, unsigned int flags)
 {
-       struct nvme_nvm_id nvm_id;
+       struct nvme_nvm_id12 nvm_id;
        struct ppa_addr ppa;
        int err;
 
-       err = lnvm_get_identity(fd, nsid, &nvm_id);
+       err = lnvm_get_identity(fd, nsid, (struct nvme_nvm_id *)&nvm_id);
        if (err) {
                fprintf(stderr, "NVMe Status:%s(%x)\n",
                        nvme_status_to_string(err), err);
                return err;
        }
 
+       if (nvm_id.ver_id != 1) {
+               fprintf(stderr, "Get bad block table not supported on version %d\n",
+                               nvm_id.ver_id);
+               return -EINVAL;
+       }
+
        if (chid >= nvm_id.groups[0].num_ch ||
                                        lunid >= nvm_id.groups[0].num_lun) {
                fprintf(stderr, "Out of bound channel id or LUN id\n");
@@ -513,17 +577,23 @@ int lnvm_do_set_bbtbl(int fd, int nsid,
                                int chid, int lunid, int plnid, int blkid,
                                __u8 value)
 {
-       struct nvme_nvm_id nvm_id;
+       struct nvme_nvm_id12 nvm_id;
        struct ppa_addr ppa;
        int err;
 
-       err = lnvm_get_identity(fd, nsid, &nvm_id);
+       err = lnvm_get_identity(fd, nsid, (struct nvme_nvm_id *)&nvm_id);
        if (err) {
                fprintf(stderr, "NVMe Status:%s(%x)\n",
                        nvme_status_to_string(err), err);
                return err;
        }
 
+       if (nvm_id.ver_id != 1) {
+               fprintf(stderr, "Set bad block table not supported on version %d\n",
+                               nvm_id.ver_id);
+               return -EINVAL;
+       }
+
        if (chid >= nvm_id.groups[0].num_ch ||
                                        lunid >= nvm_id.groups[0].num_lun ||
                                        plnid >= nvm_id.groups[0].num_pln ||
index 8faca80e2db61c8bfbcd26be59a5c09db170bc95..a13c0cf2cb9d1117dd4473273dc3cf6cb63f2052 100644 (file)
@@ -109,7 +109,7 @@ struct nvme_nvm_lp_tbl {
        struct nvme_nvm_lp_mlc  mlc;
 };
 
-struct nvme_nvm_id_group {
+struct nvme_nvm_id12_group {
        __u8                    mtype;
        __u8                    fmtype;
        __le16                  res16;
@@ -155,6 +155,8 @@ struct nvme_nvm_addr_format {
 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,
@@ -176,7 +178,7 @@ enum {
        LNVM_IDFY_GRP_MCCAP_ENCRYPT     = 3,
 };
 
-struct nvme_nvm_id {
+struct nvme_nvm_id12 {
        __u8                    ver_id;
        __u8                    vmnt;
        __u8                    cgrps;
@@ -185,7 +187,64 @@ struct nvme_nvm_id {
        __le32                  dom;
        struct nvme_nvm_addr_format ppaf;
        __u8                    resv[228];
-       struct nvme_nvm_id_group groups[4];
+       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));
 
 struct nvme_nvm_bb_tbl {