]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
Factor out ID printing code into common.c
authorPatrick McCormick <patrick.m.mccormick@intel.com>
Thu, 3 Dec 2015 15:27:33 +0000 (10:27 -0500)
committerPatrick McCormick <patrick.m.mccormick@intel.com>
Thu, 3 Dec 2015 17:26:20 +0000 (12:26 -0500)
The printing output should be identical. The id structure
printing functions can be more or less used by lsnvme.

Signed-off-by: Patrick McCormick <patrick.m.mccormick@intel.com>
Makefile
common.c [new file with mode: 0644]
common.h [new file with mode: 0644]
nvme.c

index 021fa1ae8c5b2b273d5a05990ceb1a191912c999..524b683b3607895726a327f3569c28baf9b50572 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -26,8 +26,8 @@ NVME-VERSION-FILE: FORCE
 -include NVME-VERSION-FILE
 override CFLAGS += -DNVME_VERSION='"$(NVME_VERSION)"'
 
-nvme: nvme.c ./linux/nvme.h argconfig.o suffix.o NVME-VERSION-FILE
-       $(CC) $(CFLAGS) nvme.c $(LDFLAGS) -o $(NVME) argconfig.o suffix.o
+nvme: nvme.c ./linux/nvme.h argconfig.o suffix.o common.o NVME-VERSION-FILE
+       $(CC) $(CFLAGS) nvme.c $(LDFLAGS) -o $(NVME) argconfig.o suffix.o common.o
 
 argconfig.o: $(SRC)/argconfig.c $(SRC)/argconfig.h $(SRC)/suffix.h
        $(CC) -c $(CFLAGS) $(SRC)/argconfig.c
@@ -35,6 +35,8 @@ argconfig.o: $(SRC)/argconfig.c $(SRC)/argconfig.h $(SRC)/suffix.h
 suffix.o: $(SRC)/suffix.c $(SRC)/suffix.h
        $(CC) -c $(CFLAGS) $(SRC)/suffix.c
 
+common.o: common.c
+
 doc: $(NVME)
        $(MAKE) -C Documentation
 
diff --git a/common.c b/common.c
new file mode 100644 (file)
index 0000000..d9a0eec
--- /dev/null
+++ b/common.c
@@ -0,0 +1,601 @@
+#include <stdio.h>
+#include <inttypes.h>
+
+#include <endian.h>
+
+#include "common.h"
+
+long double int128_to_double(__u8 *data)
+{
+       int i;
+       long double result = 0;
+
+       for (i = 0; i < 16; i++) {
+               result *= 256;
+               result += data[15 - i];
+       }
+       return result;
+}
+
+void d(unsigned char *buf, int len, int width, int group)
+{
+       int i, offset = 0, line_done = 0;
+       char ascii[width + 1];
+
+       printf("     ");
+       for (i = 0; i <= 15; i++)
+               printf("%3x", i);
+       for (i = 0; i < len; i++) {
+               line_done = 0;
+               if (i % width == 0)
+                       fprintf(stdout, "\n%04x:", offset);
+               if (i % group == 0)
+                       fprintf(stdout, " %02x", buf[i]);
+               else
+                       fprintf(stdout, "%02x", buf[i]);
+               ascii[i % width] = (buf[i] >= '!' && buf[i] <= '~') ? buf[i] : '.';
+               if (((i + 1) % width) == 0) {
+                       ascii[i % width + 1] = '\0';
+                       fprintf(stdout, " \"%.*s\"", width, ascii);
+                       offset += width;
+                       line_done = 1;
+               }
+       }
+       if (!line_done) {
+               unsigned b = width - (i % width);
+               ascii[i % width + 1] = '\0';
+               fprintf(stdout, " %*s \"%.*s\"",
+                               2 * b + b / group + (b % group ? 1 : 0), "",
+                               width, ascii);
+       }
+       fprintf(stdout, "\n");
+}
+
+static void show_nvme_id_ctrl_cmic(__u8 cmic)
+{
+       __u8 rsvd = (cmic & 0xF8) >> 3;
+       __u8 sriov = (cmic & 0x4) >> 2;
+       __u8 mctl = (cmic & 0x2) >> 1;
+       __u8 mp = cmic & 0x1;
+       if (rsvd)
+               printf("  [7:3] : %#x\tReserved\n", rsvd);
+       printf("  [2:2] : %#x\t%s\n", sriov, sriov ? "SR-IOV" : "PCI");
+       printf("  [1:1] : %#x\t%s Controller\n",
+               mctl, mctl ? "Multi" : "Single");
+       printf("  [0:0] : %#x\t%s Port\n", mp, mp ? "Multi" : "Single");
+       printf("\n");
+}
+
+static void show_nvme_id_ctrl_oaes(__le32 oaes)
+{
+       __le32 rsvd0 = (oaes & 0xFFFFFE00) >> 9;
+       __le32 nace = (oaes & 0x100) >> 8;
+       __le32 rsvd1 = oaes & 0xFF;
+       if (rsvd0)
+               printf(" [31:9] : %#x\tReserved\n", rsvd0);
+       printf("  [8:8] : %#x\tNamespace Attribute Changed Event %sSupported\n",
+               nace, nace ? "" : "Not ");
+       if (rsvd1)
+               printf("  [7:0] : %#x\tReserved\n", rsvd1);
+       printf("\n");
+}
+
+static void show_nvme_id_ctrl_oacs(__le16 oacs)
+{
+       __le16 rsvd = (oacs & 0xFFF0) >> 4;
+       __le16 nsm = (oacs & 0x8) >> 3;
+       __le16 fwc = (oacs & 0x4) >> 2;
+       __le16 fmt = (oacs & 0x2) >> 1;
+       __le16 sec = oacs & 0x1;
+       if (rsvd)
+               printf(" [15:4] : %#x\tReserved\n", rsvd);
+       printf("  [3:3] : %#x\tNS Management and Attachment %sSupported\n",
+               nsm, nsm ? "" : "Not ");
+       printf("  [2:2] : %#x\tFW Commit and Download %sSupported\n",
+               fwc, fwc ? "" : "Not ");
+       printf("  [1:1] : %#x\tFormat NVM %sSupported\n",
+               fmt, fmt ? "" : "Not ");
+       printf("  [0:0] : %#x\tSec. Send and Receive %sSupported\n",
+               sec, sec ? "" : "Not ");
+       printf("\n");
+}
+
+static void show_nvme_id_ctrl_frmw(__u8 frmw)
+{
+       __u8 rsvd = (frmw & 0xE0) >> 5;
+       __u8 fawr = (frmw & 0x10) >> 4;
+       __u8 nfws = (frmw & 0xE) >> 1;
+       __u8 s1ro = frmw & 0x1;
+       if (rsvd)
+               printf("  [7:5] : %#x\tReserved\n", rsvd);
+       printf("  [4:4] : %#x\tFirmware Activate Without Reset %sSupported\n",
+               fawr, fawr ? "" : "Not ");
+       printf("  [3:1] : %#x\tNumber of Firmware Slots\n", nfws);
+       printf("  [0:0] : %#x\tFirmware Slot 1 Read%s\n",
+               s1ro, s1ro ? "-Only" : "/Write");
+       printf("\n");
+}
+
+static void show_nvme_id_ctrl_lpa(__u8 lpa)
+{
+       __u8 rsvd = (lpa & 0xFC) >> 2;
+       __u8 celp = (lpa & 0x2) >> 1;
+       __u8 smlp = lpa & 0x1;
+       if (rsvd)
+               printf("  [7:2] : %#x\tReserved\n", rsvd);
+       printf("  [1:1] : %#x\tCommand Effects Log Page %sSupported\n",
+               celp, celp ? "" : "Not ");
+       printf("  [0:0] : %#x\tSMART/Health Log Page per NS %sSupported\n",
+               smlp, smlp ? "" : "Not ");
+       printf("\n");
+}
+
+static void show_nvme_id_ctrl_avscc(__u8 avscc)
+{
+       __u8 rsvd = (avscc & 0xFE) >> 1;
+       __u8 fmt = avscc & 0x1;
+       if (rsvd)
+               printf("  [7:1] : %#x\tReserved\n", rsvd);
+       printf("  [0:0] : %#x\tAdmin Vendor Specific Commands uses %s Format\n",
+               fmt, fmt ? "NVMe" : "Vendor Specific");
+       printf("\n");
+}
+
+static void show_nvme_id_ctrl_apsta(__u8 apsta)
+{
+       __u8 rsvd = (apsta & 0xFE) >> 1;
+       __u8 apst = apsta & 0x1;
+       if (rsvd)
+               printf("  [7:1] : %#x\tReserved\n", rsvd);
+       printf("  [0:0] : %#x\tAutonomous Power State Transitions %sSupported\n",
+               apst, apst ? "" : "Not ");
+       printf("\n");
+}
+
+static void show_nvme_id_ctrl_rpmbs(__le32 rpmbs)
+{
+       __le32 asz = (rpmbs & 0xFF000000) >> 24;
+       __le32 tsz = (rpmbs & 0xFF0000) >> 16;
+       __le32 rsvd = (rpmbs & 0xFFC0) >> 6;
+       __le32 auth = (rpmbs & 0x38) >> 3;
+       __le32 rpmb = rpmbs & 0x3;
+       printf(" [31:24]: %#x\tAccess Size\n", asz);
+       printf(" [23:16]: %#x\tTotal Size\n", tsz);
+       if (rsvd)
+               printf(" [15:6] : %#x\tReserved\n", rsvd);
+       printf("  [5:3] : %#x\tAuthentication Method\n", auth);
+       printf("  [2:0] : %#x\tNumber of RPMB Units\n", rpmb);
+       printf("\n");
+}
+
+static void show_nvme_id_ctrl_sqes(__u8 sqes)
+{
+       __u8 msqes = (sqes & 0xF0) >> 4;
+       __u8 rsqes = sqes & 0xF;
+       printf("  [7:4] : %#x\tMax SQ Entry Size (%d)\n", msqes, 1 << msqes);
+       printf("  [3:0] : %#x\tMin SQ Entry Size (%d)\n", rsqes, 1 << rsqes);
+       printf("\n");
+}
+
+static void show_nvme_id_ctrl_cqes(__u8 cqes)
+{
+       __u8 mcqes = (cqes & 0xF0) >> 4;
+       __u8 rcqes = cqes & 0xF;
+       printf("  [7:4] : %#x\tMax CQ Entry Size (%d)\n", mcqes, 1 << mcqes);
+       printf("  [3:0] : %#x\tMin CQ Entry Size (%d)\n", rcqes, 1 << rcqes);
+       printf("\n");
+}
+
+static void show_nvme_id_ctrl_oncs(__le16 oncs)
+{
+       __le16 rsvd = (oncs & 0xFFC0) >> 6;
+       __le16 resv = (oncs & 0x20) >> 5;
+       __le16 save = (oncs & 0x10) >> 4;
+       __le16 wzro = (oncs & 0x8) >> 3;
+       __le16 dsms = (oncs & 0x4) >> 2;
+       __le16 wunc = (oncs & 0x2) >> 1;
+       __le16 cmp = oncs & 0x1;
+       if (rsvd)
+               printf(" [15:6] : %#x\tReserved\n", rsvd);
+       printf("  [5:5] : %#x\tReservations %sSupported\n",
+               resv, resv ? "" : "Not ");
+       printf("  [4:4] : %#x\tSave and Select %sSupported\n",
+               save, save ? "" : "Not ");
+       printf("  [3:3] : %#x\tWrite Zeroes %sSupported\n",
+               wzro, wzro ? "" : "Not ");
+       printf("  [2:2] : %#x\tData Set Management %sSupported\n",
+               dsms, dsms ? "" : "Not ");
+       printf("  [1:1] : %#x\tWrite Uncorrectable %sSupported\n",
+               wunc, wunc ? "" : "Not ");
+       printf("  [0:0] : %#x\tCompare %sSupported\n",
+               cmp, cmp ? "" : "Not ");
+       printf("\n");
+}
+
+static void show_nvme_id_ctrl_fuses(__le16 fuses)
+{
+       __le16 rsvd = (fuses & 0xFE) >> 1;
+       __le16 cmpw = fuses & 0x1;
+       if (rsvd)
+               printf(" [15:1] : %#x\tReserved\n", rsvd);
+       printf("  [0:0] : %#x\tFused Compare and Write %sSupported\n",
+               cmpw, cmpw ? "" : "Not ");
+       printf("\n");
+}
+
+static void show_nvme_id_ctrl_fna(__u8 fna)
+{
+       __u8 rsvd = (fna & 0xF8) >> 3;
+       __u8 cese = (fna & 0x4) >> 2;
+       __u8 cens = (fna & 0x2) >> 1;
+       __u8 fmns = fna & 0x1;
+       if (rsvd)
+               printf("  [7:3] : %#x\tReserved\n", rsvd);
+       printf("  [2:2] : %#x\tCrypto Erase %sSupported as part of Secure Erase\n",
+               cese, cese ? "" : "Not ");
+       printf("  [1:1] : %#x\tCrypto Erase Applies to %s Namespace(s)\n",
+               cens, cens ? "All" : "Single");
+       printf("  [0:0] : %#x\tFormat Applies to %s Namespace(s)\n",
+               fmns, fmns ? "All" : "Single");
+       printf("\n");
+}
+
+static void show_nvme_id_ctrl_vwc(__u8 vwc)
+{
+       __u8 rsvd = (vwc & 0xFE) >> 1;
+       __u8 vwcp = vwc & 0x1;
+       if (rsvd)
+               printf("  [7:3] : %#x\tReserved\n", rsvd);
+       printf("  [0:0] : %#x\tVolatile Write Cache %sPresent\n",
+               vwcp, vwcp ? "" : "Not ");
+       printf("\n");
+}
+
+static void show_nvme_id_ctrl_nvscc(__u8 nvscc)
+{
+       __u8 rsvd = (nvscc & 0xFE) >> 1;
+       __u8 fmt = nvscc & 0x1;
+       if (rsvd)
+               printf("  [7:1] : %#x\tReserved\n", rsvd);
+       printf("  [0:0] : %#x\tNVM Vendor Specific Commands uses %s Format\n",
+               fmt, fmt ? "NVMe" : "Vendor Specific");
+       printf("\n");
+}
+
+static void show_nvme_id_ctrl_sgls(__le32 sgls)
+{
+       __le32 rsvd0 = (sgls & 0xFFF80000) >> 19;
+       __le32 sglltb = (sgls & 0x40000) >> 18;
+       __le32 bacmdb = (sgls & 0x20000) >> 17;
+       __le32 bbs = (sgls & 0x10000) >> 16;
+       __le32 rsvd1 = (sgls & 0xFFFE) >> 1;
+       __le32 sglsp = sgls & 0x1;
+       if (rsvd0)
+               printf(" [31:19]: %#x\tReserved\n", rsvd0);
+       if (sglsp || (!sglsp && sglltb))
+               printf(" [18:18]: %#x\tSGL Length Larger than Buffer %sSupported\n",
+                       sglltb, sglltb ? "" : "Not ");
+       if (sglsp || (!sglsp && bacmdb))
+               printf(" [17:17]: %#x\tByte-Aligned Contig. MD Buffer %sSupported\n",
+                       bacmdb, bacmdb ? "" : "Not ");
+       if (sglsp || (!sglsp && bbs))
+               printf(" [16:16]: %#x\tSGL Bit-Bucket %sSupported\n",
+                       bbs, bbs ? "" : "Not ");
+       if (rsvd1)
+               printf(" [15:1] : %#x\tReserved\n", rsvd1);
+       printf("  [0:0] : %#x\tScatter-Gather Lists %sSupported\n",
+               sglsp, sglsp ? "" : "Not ");
+       printf("\n");
+}
+
+static void show_nvme_id_ns_nsfeat(__u8 nsfeat)
+{
+       __u8 rsvd = (nsfeat & 0xF8) >> 3;
+       __u8 dulbe = (nsfeat & 0x4) >> 2;
+       __u8 na = (nsfeat & 0x2) >> 1;
+       __u8 thin = nsfeat & 0x1;
+       if (rsvd)
+               printf("  [7:3] : %#x\tReserved\n", rsvd);
+       printf("  [2:2] : %#x\tDeallocated or Unwritten Logical Block error %sSupported\n",
+               dulbe, dulbe ? "" : "Not ");
+       printf("  [1:1] : %#x\tNamespace uses %s\n",
+               na, na ? "NAWUN, NAWUPF, and NACWU" : "AWUN, AWUPF, and ACWU");
+       printf("  [0:0] : %#x\tThin Provisioning %sSupported\n",
+               thin, thin ? "" : "Not ");
+       printf("\n");
+}
+
+static void show_nvme_id_ns_flbas(__u8 flbas)
+{
+       __u8 rsvd = (flbas & 0xE0) >> 5;
+       __u8 mdedata = (flbas & 0x10) >> 4;
+       __u8 lbaf = flbas & 0xF;
+       if (rsvd)
+               printf("  [7:5] : %#x\tReserved\n", rsvd);
+       printf("  [4:4] : %#x\tMetadata Transferred %s\n",
+               mdedata, mdedata ? "at End of Data LBA" : "in Separate Contiguous Buffer");
+       printf("  [3:0] : %#x\tCurrent LBA Format Selected\n", lbaf);
+       printf("\n");
+}
+
+static void show_nvme_id_ns_mc(__u8 mc)
+{
+       __u8 rsvd = (mc & 0xFC) >> 2;
+       __u8 mdp = (mc & 0x2) >> 1;
+       __u8 extdlba = mc & 0x1;
+       if (rsvd)
+               printf("  [7:2] : %#x\tReserved\n", rsvd);
+       printf("  [1:1] : %#x\tMetadata Pointer %sSupported\n",
+               mdp, mdp ? "" : "Not ");
+       printf("  [0:0] : %#x\tMetadata as Part of Extended Data LBA %sSupported\n",
+               extdlba, extdlba ? "" : "Not ");
+       printf("\n");
+}
+
+static void show_nvme_id_ns_dpc(__u8 dpc)
+{
+       __u8 rsvd = (dpc & 0xE0) >> 5;
+       __u8 pil8 = (dpc & 0x10) >> 4;
+       __u8 pif8 = (dpc & 0x8) >> 3;
+       __u8 pit3 = (dpc & 0x4) >> 2;
+       __u8 pit2 = (dpc & 0x2) >> 1;
+       __u8 pit1 = dpc & 0x1;
+       if (rsvd)
+               printf("  [7:5] : %#x\tReserved\n", rsvd);
+       printf("  [4:4] : %#x\tProtection Information Transferred as Last 8 Bytes of Metadata %sSupported\n",
+               pil8, pil8 ? "" : "Not ");
+       printf("  [3:3] : %#x\tProtection Information Transferred as First 8 Bytes of Metadata %sSupported\n",
+               pif8, pif8 ? "" : "Not ");
+       printf("  [2:2] : %#x\tProtection Information Type 3 %sSupported\n",
+               pit3, pit3 ? "" : "Not ");
+       printf("  [1:1] : %#x\tProtection Information Type 2 %sSupported\n",
+               pit2, pit2 ? "" : "Not ");
+       printf("  [0:0] : %#x\tProtection Information Type 1 %sSupported\n",
+               pit1, pit1 ? "" : "Not ");
+       printf("\n");
+}
+
+static void show_nvme_id_ns_dps(__u8 dps)
+{
+       __u8 rsvd = (dps & 0xF0) >> 4;
+       __u8 pif8 = (dps & 0x8) >> 3;
+       __u8 pit = dps & 0x7;
+       if (rsvd)
+               printf("  [7:4] : %#x\tReserved\n", rsvd);
+       printf("  [3:3] : %#x\tProtection Information is Transferred as %s 8 Bytes of Metadata\n",
+               pif8, pif8 ? "First" : "Last");
+       printf("  [2:0] : %#x\tProtection Information %s\n", pit,
+               pit == 3 ? "Type 3 Enabled" :
+               pit == 2 ? "Type 2 Enabled" :
+               pit == 1 ? "Type 1 Enabled" :
+               pit == 0 ? "Disabled" : "Reserved Enabled");
+       printf("\n");
+}
+
+static void show_nvme_id_ns_nmic(__u8 nmic)
+{
+       __u8 rsvd = (nmic & 0xFE) >> 1;
+       __u8 mp = nmic & 0x1;
+       if (rsvd)
+               printf("  [7:1] : %#x\tReserved\n", rsvd);
+       printf("  [0:0] : %#x\tNamespace Multipath %sCapable\n",
+               mp, mp ? "" : "Not ");
+       printf("\n");
+}
+
+static void show_nvme_id_ns_rescap(__u8 rescap)
+{
+       __u8 rsvd = (rescap & 0x80) >> 7;
+       __u8 eaar = (rescap & 0x40) >> 6;
+       __u8 wear = (rescap & 0x20) >> 5;
+       __u8 earo = (rescap & 0x10) >> 4;
+       __u8 wero = (rescap & 0x8) >> 3;
+       __u8 ea = (rescap & 0x4) >> 2;
+       __u8 we = (rescap & 0x2) >> 1;
+       __u8 ptpl = rescap & 0x1;
+       if (rsvd)
+               printf("  [7:7] : %#x\tReserved\n", rsvd);
+       printf("  [6:6] : %#x\tExclusive Access - All Registrants %sSupported\n",
+               eaar, eaar ? "" : "Not ");
+       printf("  [5:5] : %#x\tWrite Exclusive - All Registrants %sSupported\n",
+               wear, wear ? "" : "Not ");
+       printf("  [4:4] : %#x\tExclusive Access - Registrants Only %sSupported\n",
+               earo, earo ? "" : "Not ");
+       printf("  [3:3] : %#x\tWrite Exclusive - Registrants Only %sSupported\n",
+               wero, wero ? "" : "Not ");
+       printf("  [2:2] : %#x\tExclusive Access %sSupported\n",
+               ea, ea ? "" : "Not ");
+       printf("  [1:1] : %#x\tWrite Exclusive %sSupported\n",
+               we, we ? "" : "Not ");
+       printf("  [0:0] : %#x\tPersist Through Power Loss %sSupported\n",
+               ptpl, ptpl ? "" : "Not ");
+       printf("\n");
+}
+
+static void show_nvme_id_ns_fpi(__u8 fpi)
+{
+       __u8 fpis = (fpi & 0x80) >> 7;
+       __u8 fpii = fpi & 0x7F;
+       printf("  [7:7] : %#x\tFormat Progress Indicator %sSupported\n",
+               fpis, fpis ? "" : "Not ");
+       if (fpis || (!fpis && fpii))
+       printf("  [6:0] : %#x\tFormat Progress Indicator (Remaining %d%%)\n",
+               fpii, 100 - fpii);
+       printf("\n");
+}
+
+void show_nvme_id_ns(struct nvme_id_ns *ns, unsigned int mode)
+{
+       int i;
+       int human = mode&HUMAN,
+               vs = mode&VS;
+
+       printf("nsze    : %#"PRIx64"\n", (uint64_t)le64toh(ns->nsze));
+       printf("ncap    : %#"PRIx64"\n", (uint64_t)le64toh(ns->ncap));
+       printf("nuse    : %#"PRIx64"\n", (uint64_t)le64toh(ns->nuse));
+       printf("nsfeat  : %#x\n", ns->nsfeat);
+       if (human)
+               show_nvme_id_ns_nsfeat(ns->nsfeat);
+       printf("nlbaf   : %d\n", ns->nlbaf);
+       printf("flbas   : %#x\n", ns->flbas);
+       if (human)
+               show_nvme_id_ns_flbas(ns->flbas);
+       printf("mc      : %#x\n", ns->mc);
+       if (human)
+               show_nvme_id_ns_mc(ns->mc);
+       printf("dpc     : %#x\n", ns->dpc);
+       if (human)
+               show_nvme_id_ns_dpc(ns->dpc);
+       printf("dps     : %#x\n", ns->dps);
+       if (human)
+               show_nvme_id_ns_dps(ns->dps);
+       printf("nmic    : %#x\n", ns->nmic);
+       if (human)
+               show_nvme_id_ns_nmic(ns->nmic);
+       printf("rescap  : %#x\n", ns->rescap);
+       if (human)
+               show_nvme_id_ns_rescap(ns->rescap);
+       printf("fpi     : %#x\n", ns->fpi);
+       if (human)
+               show_nvme_id_ns_fpi(ns->fpi);
+       printf("nawun   : %d\n", ns->nawun);
+       printf("nawupf  : %d\n", ns->nawupf);
+       printf("nacwu   : %d\n", ns->nacwu);
+       printf("nabsn   : %d\n", ns->nabsn);
+       printf("nabo    : %d\n", ns->nabo);
+       printf("nabspf  : %d\n", ns->nabspf);
+       printf("nvmcap  : %.0Lf\n", int128_to_double(ns->nvmcap));
+
+       printf("nguid   : ");
+       for (i = 0; i < 16; i++)
+               printf("%02x", ns->nguid[i]);
+       printf("\n");
+
+       printf("eui64   : ");
+       for (i = 0; i < 8; i++)
+               printf("%02x", ns->eui64[i]);
+       printf("\n");
+
+       for (i = 0; i <= ns->nlbaf; i++) {
+               if (human)
+                       printf("LBA Format %2d : Metadata Size: %-3d bytes - "
+                               "Data Size: %-2d bytes - Relative Performance: %#x %s %s\n", i,
+                               ns->lbaf[i].ms, 1 << ns->lbaf[i].ds, ns->lbaf[i].rp,
+                               ns->lbaf[i].rp == 3 ? "Degraded" :
+                               ns->lbaf[i].rp == 2 ? "Good" :
+                               ns->lbaf[i].rp == 1 ? "Better" : "Best",
+                               i == (ns->flbas & 0xf) ? "(in use)" : "");
+               else
+                       printf("lbaf %2d : ms:%-3d ds:%-2d rp:%#x %s\n", i,
+                               ns->lbaf[i].ms, ns->lbaf[i].ds, ns->lbaf[i].rp,
+                               i == (ns->flbas & 0xf) ? "(in use)" : "");
+       }
+       if (vs) {
+               printf("vs[]:");
+               d(ns->vs, sizeof(ns->vs), 16, 1);
+       }
+}
+
+void show_nvme_id_ctrl(struct nvme_id_ctrl *ctrl, unsigned int mode)
+{
+       int i;
+       int human = mode&HUMAN,
+               vs = mode&VS;
+
+       ctrl->sn[sizeof(ctrl->sn)-1] = 0;
+       ctrl->mn[sizeof(ctrl->mn)-1] = 0;
+       ctrl->fr[sizeof(ctrl->fr)-1] = 0;
+
+       printf("vid     : %#x\n", ctrl->vid);
+       printf("ssvid   : %#x\n", ctrl->ssvid);
+       printf("sn      : %s\n", ctrl->sn);
+       printf("mn      : %s\n", ctrl->mn);
+       printf("fr      : %s\n", ctrl->fr);
+       printf("rab     : %d\n", ctrl->rab);
+       printf("ieee    : %02x%02x%02x\n",
+               ctrl->ieee[2], ctrl->ieee[1], ctrl->ieee[0]);
+       printf("cmic    : %#x\n", ctrl->cmic);
+       if (human)
+               show_nvme_id_ctrl_cmic(ctrl->cmic);
+       printf("mdts    : %d\n", ctrl->mdts);
+       printf("cntlid  : %x\n", ctrl->cntlid);
+       printf("ver     : %x\n", ctrl->ver);
+       printf("rtd3r   : %x\n", ctrl->rtd3r);
+       printf("rtd3e   : %x\n", ctrl->rtd3e);
+       printf("oaes    : %#x\n", ctrl->oaes);
+       if (human)
+               show_nvme_id_ctrl_oaes(ctrl->oaes);
+       printf("oacs    : %#x\n", ctrl->oacs);
+       if (human)
+               show_nvme_id_ctrl_oacs(ctrl->oacs);
+       printf("acl     : %d\n", ctrl->acl);
+       printf("aerl    : %d\n", ctrl->aerl);
+       printf("frmw    : %#x\n", ctrl->frmw);
+       if (human)
+               show_nvme_id_ctrl_frmw(ctrl->frmw);
+       printf("lpa     : %#x\n", ctrl->lpa);
+       if (human)
+               show_nvme_id_ctrl_lpa(ctrl->lpa);
+       printf("elpe    : %d\n", ctrl->elpe);
+       printf("npss    : %d\n", ctrl->npss);
+       printf("avscc   : %#x\n", ctrl->avscc);
+       if (human)
+               show_nvme_id_ctrl_avscc(ctrl->avscc);
+       printf("apsta   : %#x\n", ctrl->apsta);
+       if (human)
+               show_nvme_id_ctrl_apsta(ctrl->apsta);
+       printf("wctemp  : %d\n", ctrl->wctemp);
+       printf("cctemp  : %d\n", ctrl->cctemp);
+       printf("mtfa    : %d\n", ctrl->mtfa);
+       printf("hmmin   : %d\n", ctrl->hmmin);
+       printf("tnvmcap : %.0Lf\n", int128_to_double(ctrl->tnvmcap));
+       printf("unvmcap : %.0Lf\n", int128_to_double(ctrl->unvmcap));
+       printf("rpmbs   : %#x\n", ctrl->rpmbs);
+       if (human)
+               show_nvme_id_ctrl_rpmbs(ctrl->rpmbs);
+       printf("sqes    : %#x\n", ctrl->sqes);
+       if (human)
+               show_nvme_id_ctrl_sqes(ctrl->sqes);
+       printf("cqes    : %#x\n", ctrl->cqes);
+       if (human)
+               show_nvme_id_ctrl_cqes(ctrl->cqes);
+       printf("nn      : %d\n", ctrl->nn);
+       printf("oncs    : %#x\n", ctrl->oncs);
+       if (human)
+               show_nvme_id_ctrl_oncs(ctrl->oncs);
+       printf("fuses   : %#x\n", ctrl->fuses);
+       if (human)
+               show_nvme_id_ctrl_fuses(ctrl->fuses);
+       printf("fna     : %#x\n", ctrl->fna);
+       if (human)
+               show_nvme_id_ctrl_fna(ctrl->fna);
+       printf("vwc     : %#x\n", ctrl->vwc);
+       if (human)
+               show_nvme_id_ctrl_vwc(ctrl->vwc);
+       printf("awun    : %d\n", ctrl->awun);
+       printf("awupf   : %d\n", ctrl->awupf);
+       printf("nvscc   : %d\n", ctrl->nvscc);
+       if (human)
+               show_nvme_id_ctrl_nvscc(ctrl->nvscc);
+       printf("acwu    : %d\n", ctrl->acwu);
+       printf("sgls    : %x\n", ctrl->sgls);
+       if (human)
+               show_nvme_id_ctrl_sgls(ctrl->sgls);
+
+       for (i = 0; i <= ctrl->npss; i++) {
+               printf("ps %4d : mp:%d flags:%x enlat:%d exlat:%d rrt:%d rrl:%d\n"
+                       "          rwt:%d rwl:%d idlp:%d ips:%x actp:%x ap flags:%x\n",
+                       i, ctrl->psd[i].max_power, ctrl->psd[i].flags,
+                       ctrl->psd[i].entry_lat, ctrl->psd[i].exit_lat,
+                       ctrl->psd[i].read_tput, ctrl->psd[i].read_lat,
+                       ctrl->psd[i].write_tput, ctrl->psd[i].write_lat,
+                       ctrl->psd[i].idle_power, ctrl->psd[i].idle_scale,
+                       ctrl->psd[i].active_power, ctrl->psd[i].active_work_scale);
+       }
+       if (vs) {
+               printf("vs[]:\n");
+               d(ctrl->vs, sizeof(ctrl->vs), 16, 1);
+       }
+}
+
+
diff --git a/common.h b/common.h
new file mode 100644 (file)
index 0000000..fa7aa2a
--- /dev/null
+++ b/common.h
@@ -0,0 +1,20 @@
+#ifndef COMMON_H
+#define COMMON_H
+
+#include "linux/nvme.h"
+
+enum {
+       TERSE = 0x1u,   // only show a few useful fields
+       HUMAN = 0x2u,   // interpret some values for humans
+       VS    = 0x4u,   // print vendor specific data area
+       RAW   = 0x8u,   // just dump raw bytes
+};
+
+void d(unsigned char *buf, int len, int width, int group);
+
+long double int128_to_double(__u8 *data);
+
+void show_nvme_id_ctrl(struct nvme_id_ctrl *ctrl, unsigned int mode);
+void show_nvme_id_ns(struct nvme_id_ns *ns, unsigned int flags);
+
+#endif
diff --git a/nvme.c b/nvme.c
index 28c059b123069263af7441ca1de91d039873b1cb..c72e6eb359ea53acf391083dc9b1463e322eb320 100644 (file)
--- a/nvme.c
+++ b/nvme.c
@@ -47,7 +47,8 @@
 #include <sys/stat.h>
 #include <sys/time.h>
 
-#include "linux/nvme.h"
+#include "common.h"
+
 #include "src/argconfig.h"
 #include "src/suffix.h"
 
@@ -238,18 +239,6 @@ static void show_fw_log(struct nvme_firmware_log_page *fw_log)
                                                fw_to_string(fw_log->frs[i]));
 }
 
-static long double int128_to_double(__u8 *data)
-{
-       int i;
-       long double result = 0;
-
-       for (i = 0; i < 16; i++) {
-               result *= 256;
-               result += data[15 - i];
-       }
-       return result;
-}
-
 static unsigned long int48_to_long(__u8 *data)
 {
        int i;
@@ -457,385 +446,6 @@ static void d_raw(unsigned char *buf, unsigned len)
                putchar(*(buf+i));
 }
 
-static void d(unsigned char *buf, int len, int width, int group)
-{
-       int i, offset = 0, line_done = 0;
-       char ascii[width + 1];
-
-       printf("     ");
-       for (i = 0; i <= 15; i++)
-               printf("%3x", i);
-       for (i = 0; i < len; i++) {
-               line_done = 0;
-               if (i % width == 0)
-                       fprintf(stdout, "\n%04x:", offset);
-               if (i % group == 0)
-                       fprintf(stdout, " %02x", buf[i]);
-               else
-                       fprintf(stdout, "%02x", buf[i]);
-               ascii[i % width] = (buf[i] >= '!' && buf[i] <= '~') ? buf[i] : '.';
-               if (((i + 1) % width) == 0) {
-                       ascii[i % width + 1] = '\0';
-                       fprintf(stdout, " \"%.*s\"", width, ascii);
-                       offset += width;
-                       line_done = 1;
-               }
-       }
-       if (!line_done) {
-               unsigned b = width - (i % width);
-               ascii[i % width + 1] = '\0';
-               fprintf(stdout, " %*s \"%.*s\"",
-                               2 * b + b / group + (b % group ? 1 : 0), "",
-                               width, ascii);
-       }
-       fprintf(stdout, "\n");
-}
-
-static void show_nvme_id_ctrl_cmic(__u8 cmic)
-{
-       __u8 rsvd = (cmic & 0xF8) >> 3;
-       __u8 sriov = (cmic & 0x4) >> 2;
-       __u8 mctl = (cmic & 0x2) >> 1;
-       __u8 mp = cmic & 0x1;
-       if (rsvd)
-               printf("  [7:3] : %#x\tReserved\n", rsvd);
-       printf("  [2:2] : %#x\t%s\n", sriov, sriov ? "SR-IOV" : "PCI");
-       printf("  [1:1] : %#x\t%s Controller\n",
-               mctl, mctl ? "Multi" : "Single");
-       printf("  [0:0] : %#x\t%s Port\n", mp, mp ? "Multi" : "Single");
-       printf("\n");
-}
-
-static void show_nvme_id_ctrl_oaes(__le32 oaes)
-{
-       __le32 rsvd0 = (oaes & 0xFFFFFE00) >> 9;
-       __le32 nace = (oaes & 0x100) >> 8;
-       __le32 rsvd1 = oaes & 0xFF;
-       if (rsvd0)
-               printf(" [31:9] : %#x\tReserved\n", rsvd0);
-       printf("  [8:8] : %#x\tNamespace Attribute Changed Event %sSupported\n",
-               nace, nace ? "" : "Not ");
-       if (rsvd1)
-               printf("  [7:0] : %#x\tReserved\n", rsvd1);
-       printf("\n");
-}
-
-static void show_nvme_id_ctrl_oacs(__le16 oacs)
-{
-       __le16 rsvd = (oacs & 0xFFF0) >> 4;
-       __le16 nsm = (oacs & 0x8) >> 3;
-       __le16 fwc = (oacs & 0x4) >> 2;
-       __le16 fmt = (oacs & 0x2) >> 1;
-       __le16 sec = oacs & 0x1;
-       if (rsvd)
-               printf(" [15:4] : %#x\tReserved\n", rsvd);
-       printf("  [3:3] : %#x\tNS Management and Attachment %sSupported\n",
-               nsm, nsm ? "" : "Not ");
-       printf("  [2:2] : %#x\tFW Commit and Download %sSupported\n",
-               fwc, fwc ? "" : "Not ");
-       printf("  [1:1] : %#x\tFormat NVM %sSupported\n",
-               fmt, fmt ? "" : "Not ");
-       printf("  [0:0] : %#x\tSec. Send and Receive %sSupported\n",
-               sec, sec ? "" : "Not ");
-       printf("\n");
-}
-
-static void show_nvme_id_ctrl_frmw(__u8 frmw)
-{
-       __u8 rsvd = (frmw & 0xE0) >> 5;
-       __u8 fawr = (frmw & 0x10) >> 4;
-       __u8 nfws = (frmw & 0xE) >> 1;
-       __u8 s1ro = frmw & 0x1;
-       if (rsvd)
-               printf("  [7:5] : %#x\tReserved\n", rsvd);
-       printf("  [4:4] : %#x\tFirmware Activate Without Reset %sSupported\n",
-               fawr, fawr ? "" : "Not ");
-       printf("  [3:1] : %#x\tNumber of Firmware Slots\n", nfws);
-       printf("  [0:0] : %#x\tFirmware Slot 1 Read%s\n",
-               s1ro, s1ro ? "-Only" : "/Write");
-       printf("\n");
-}
-
-static void show_nvme_id_ctrl_lpa(__u8 lpa)
-{
-       __u8 rsvd = (lpa & 0xFC) >> 2;
-       __u8 celp = (lpa & 0x2) >> 1;
-       __u8 smlp = lpa & 0x1;
-       if (rsvd)
-               printf("  [7:2] : %#x\tReserved\n", rsvd);
-       printf("  [1:1] : %#x\tCommand Effects Log Page %sSupported\n",
-               celp, celp ? "" : "Not ");
-       printf("  [0:0] : %#x\tSMART/Health Log Page per NS %sSupported\n",
-               smlp, smlp ? "" : "Not ");
-       printf("\n");
-}
-
-static void show_nvme_id_ctrl_avscc(__u8 avscc)
-{
-       __u8 rsvd = (avscc & 0xFE) >> 1;
-       __u8 fmt = avscc & 0x1;
-       if (rsvd)
-               printf("  [7:1] : %#x\tReserved\n", rsvd);
-       printf("  [0:0] : %#x\tAdmin Vendor Specific Commands uses %s Format\n",
-               fmt, fmt ? "NVMe" : "Vendor Specific");
-       printf("\n");
-}
-
-static void show_nvme_id_ctrl_apsta(__u8 apsta)
-{
-       __u8 rsvd = (apsta & 0xFE) >> 1;
-       __u8 apst = apsta & 0x1;
-       if (rsvd)
-               printf("  [7:1] : %#x\tReserved\n", rsvd);
-       printf("  [0:0] : %#x\tAutonomous Power State Transitions %sSupported\n",
-               apst, apst ? "" : "Not ");
-       printf("\n");
-}
-
-static void show_nvme_id_ctrl_rpmbs(__le32 rpmbs)
-{
-       __le32 asz = (rpmbs & 0xFF000000) >> 24;
-       __le32 tsz = (rpmbs & 0xFF0000) >> 16;
-       __le32 rsvd = (rpmbs & 0xFFC0) >> 6;
-       __le32 auth = (rpmbs & 0x38) >> 3;
-       __le32 rpmb = rpmbs & 0x3;
-       printf(" [31:24]: %#x\tAccess Size\n", asz);
-       printf(" [23:16]: %#x\tTotal Size\n", tsz);
-       if (rsvd)
-               printf(" [15:6] : %#x\tReserved\n", rsvd);
-       printf("  [5:3] : %#x\tAuthentication Method\n", auth);
-       printf("  [2:0] : %#x\tNumber of RPMB Units\n", rpmb);
-       printf("\n");
-}
-
-static void show_nvme_id_ctrl_sqes(__u8 sqes)
-{
-       __u8 msqes = (sqes & 0xF0) >> 4;
-       __u8 rsqes = sqes & 0xF;
-       printf("  [7:4] : %#x\tMax SQ Entry Size (%d)\n", msqes, 1 << msqes);
-       printf("  [3:0] : %#x\tMin SQ Entry Size (%d)\n", rsqes, 1 << rsqes);
-       printf("\n");
-}
-
-static void show_nvme_id_ctrl_cqes(__u8 cqes)
-{
-       __u8 mcqes = (cqes & 0xF0) >> 4;
-       __u8 rcqes = cqes & 0xF;
-       printf("  [7:4] : %#x\tMax CQ Entry Size (%d)\n", mcqes, 1 << mcqes);
-       printf("  [3:0] : %#x\tMin CQ Entry Size (%d)\n", rcqes, 1 << rcqes);
-       printf("\n");
-}
-
-static void show_nvme_id_ctrl_oncs(__le16 oncs)
-{
-       __le16 rsvd = (oncs & 0xFFC0) >> 6;
-       __le16 resv = (oncs & 0x20) >> 5;
-       __le16 save = (oncs & 0x10) >> 4;
-       __le16 wzro = (oncs & 0x8) >> 3;
-       __le16 dsms = (oncs & 0x4) >> 2;
-       __le16 wunc = (oncs & 0x2) >> 1;
-       __le16 cmp = oncs & 0x1;
-       if (rsvd)
-               printf(" [15:6] : %#x\tReserved\n", rsvd);
-       printf("  [5:5] : %#x\tReservations %sSupported\n",
-               resv, resv ? "" : "Not ");
-       printf("  [4:4] : %#x\tSave and Select %sSupported\n",
-               save, save ? "" : "Not ");
-       printf("  [3:3] : %#x\tWrite Zeroes %sSupported\n",
-               wzro, wzro ? "" : "Not ");
-       printf("  [2:2] : %#x\tData Set Management %sSupported\n",
-               dsms, dsms ? "" : "Not ");
-       printf("  [1:1] : %#x\tWrite Uncorrectable %sSupported\n",
-               wunc, wunc ? "" : "Not ");
-       printf("  [0:0] : %#x\tCompare %sSupported\n",
-               cmp, cmp ? "" : "Not ");
-       printf("\n");
-}
-
-static void show_nvme_id_ctrl_fuses(__le16 fuses)
-{
-       __le16 rsvd = (fuses & 0xFE) >> 1;
-       __le16 cmpw = fuses & 0x1;
-       if (rsvd)
-               printf(" [15:1] : %#x\tReserved\n", rsvd);
-       printf("  [0:0] : %#x\tFused Compare and Write %sSupported\n",
-               cmpw, cmpw ? "" : "Not ");
-       printf("\n");
-}
-
-static void show_nvme_id_ctrl_fna(__u8 fna)
-{
-       __u8 rsvd = (fna & 0xF8) >> 3;
-       __u8 cese = (fna & 0x4) >> 2;
-       __u8 cens = (fna & 0x2) >> 1;
-       __u8 fmns = fna & 0x1;
-       if (rsvd)
-               printf("  [7:3] : %#x\tReserved\n", rsvd);
-       printf("  [2:2] : %#x\tCrypto Erase %sSupported as part of Secure Erase\n",
-               cese, cese ? "" : "Not ");
-       printf("  [1:1] : %#x\tCrypto Erase Applies to %s Namespace(s)\n",
-               cens, cens ? "All" : "Single");
-       printf("  [0:0] : %#x\tFormat Applies to %s Namespace(s)\n",
-               fmns, fmns ? "All" : "Single");
-       printf("\n");
-}
-
-static void show_nvme_id_ctrl_vwc(__u8 vwc)
-{
-       __u8 rsvd = (vwc & 0xFE) >> 1;
-       __u8 vwcp = vwc & 0x1;
-       if (rsvd)
-               printf("  [7:3] : %#x\tReserved\n", rsvd);
-       printf("  [0:0] : %#x\tVolatile Write Cache %sPresent\n",
-               vwcp, vwcp ? "" : "Not ");
-       printf("\n");
-}
-
-static void show_nvme_id_ctrl_nvscc(__u8 nvscc)
-{
-       __u8 rsvd = (nvscc & 0xFE) >> 1;
-       __u8 fmt = nvscc & 0x1;
-       if (rsvd)
-               printf("  [7:1] : %#x\tReserved\n", rsvd);
-       printf("  [0:0] : %#x\tNVM Vendor Specific Commands uses %s Format\n",
-               fmt, fmt ? "NVMe" : "Vendor Specific");
-       printf("\n");
-}
-
-static void show_nvme_id_ctrl_sgls(__le32 sgls)
-{
-       __le32 rsvd0 = (sgls & 0xFFF80000) >> 19;
-       __le32 sglltb = (sgls & 0x40000) >> 18;
-       __le32 bacmdb = (sgls & 0x20000) >> 17;
-       __le32 bbs = (sgls & 0x10000) >> 16;
-       __le32 rsvd1 = (sgls & 0xFFFE) >> 1;
-       __le32 sglsp = sgls & 0x1;
-       if (rsvd0)
-               printf(" [31:19]: %#x\tReserved\n", rsvd0);
-       if (sglsp || (!sglsp && sglltb))
-               printf(" [18:18]: %#x\tSGL Length Larger than Buffer %sSupported\n",
-                       sglltb, sglltb ? "" : "Not ");
-       if (sglsp || (!sglsp && bacmdb))
-               printf(" [17:17]: %#x\tByte-Aligned Contig. MD Buffer %sSupported\n",
-                       bacmdb, bacmdb ? "" : "Not ");
-       if (sglsp || (!sglsp && bbs))
-               printf(" [16:16]: %#x\tSGL Bit-Bucket %sSupported\n",
-                       bbs, bbs ? "" : "Not ");
-       if (rsvd1)
-               printf(" [15:1] : %#x\tReserved\n", rsvd1);
-       printf("  [0:0] : %#x\tScatter-Gather Lists %sSupported\n",
-               sglsp, sglsp ? "" : "Not ");
-       printf("\n");
-}
-
-static void show_nvme_id_ctrl(struct nvme_id_ctrl *ctrl, int vs, int human)
-{
-       int i;
-       char sn[sizeof(ctrl->sn) + 1];
-       char mn[sizeof(ctrl->mn) + 1];
-       char fr[sizeof(ctrl->fr) + 1];
-
-       memcpy(sn, ctrl->sn, sizeof(ctrl->sn));
-       memcpy(mn, ctrl->mn, sizeof(ctrl->mn));
-       memcpy(fr, ctrl->fr, sizeof(ctrl->fr));
-
-       sn[sizeof(ctrl->sn)] = '\0';
-       mn[sizeof(ctrl->mn)] = '\0';
-       fr[sizeof(ctrl->fr)] = '\0';
-
-       printf("NVME Identify Controller:\n");
-       printf("vid     : %#x\n", ctrl->vid);
-       printf("ssvid   : %#x\n", ctrl->ssvid);
-       printf("sn      : %s\n", sn);
-       printf("mn      : %s\n", mn);
-       printf("fr      : %s\n", fr);
-       printf("rab     : %d\n", ctrl->rab);
-       printf("ieee    : %02x%02x%02x\n",
-               ctrl->ieee[2], ctrl->ieee[1], ctrl->ieee[0]);
-       printf("cmic    : %#x\n", ctrl->cmic);
-       if (human)
-               show_nvme_id_ctrl_cmic(ctrl->cmic);
-       printf("mdts    : %d\n", ctrl->mdts);
-       printf("cntlid  : %x\n", ctrl->cntlid);
-       printf("ver     : %x\n", ctrl->ver);
-       printf("rtd3r   : %x\n", ctrl->rtd3r);
-       printf("rtd3e   : %x\n", ctrl->rtd3e);
-       printf("oaes    : %#x\n", ctrl->oaes);
-       if (human)
-               show_nvme_id_ctrl_oaes(ctrl->oaes);
-       printf("oacs    : %#x\n", ctrl->oacs);
-       if (human)
-               show_nvme_id_ctrl_oacs(ctrl->oacs);
-       printf("acl     : %d\n", ctrl->acl);
-       printf("aerl    : %d\n", ctrl->aerl);
-       printf("frmw    : %#x\n", ctrl->frmw);
-       if (human)
-               show_nvme_id_ctrl_frmw(ctrl->frmw);
-       printf("lpa     : %#x\n", ctrl->lpa);
-       if (human)
-               show_nvme_id_ctrl_lpa(ctrl->lpa);
-       printf("elpe    : %d\n", ctrl->elpe);
-       printf("npss    : %d\n", ctrl->npss);
-       printf("avscc   : %#x\n", ctrl->avscc);
-       if (human)
-               show_nvme_id_ctrl_avscc(ctrl->avscc);
-       printf("apsta   : %#x\n", ctrl->apsta);
-       if (human)
-               show_nvme_id_ctrl_apsta(ctrl->apsta);
-       printf("wctemp  : %d\n", ctrl->wctemp);
-       printf("cctemp  : %d\n", ctrl->cctemp);
-       printf("mtfa    : %d\n", ctrl->mtfa);
-       printf("hmmin   : %d\n", ctrl->hmmin);
-       printf("tnvmcap : %.0Lf\n", int128_to_double(ctrl->tnvmcap));
-       printf("unvmcap : %.0Lf\n", int128_to_double(ctrl->unvmcap));
-       printf("rpmbs   : %#x\n", ctrl->rpmbs);
-       if (human)
-               show_nvme_id_ctrl_rpmbs(ctrl->rpmbs);
-       printf("sqes    : %#x\n", ctrl->sqes);
-       if (human)
-               show_nvme_id_ctrl_sqes(ctrl->sqes);
-       printf("cqes    : %#x\n", ctrl->cqes);
-       if (human)
-               show_nvme_id_ctrl_cqes(ctrl->cqes);
-       printf("nn      : %d\n", ctrl->nn);
-       printf("oncs    : %#x\n", ctrl->oncs);
-       if (human)
-               show_nvme_id_ctrl_oncs(ctrl->oncs);
-       printf("fuses   : %#x\n", ctrl->fuses);
-       if (human)
-               show_nvme_id_ctrl_fuses(ctrl->fuses);
-       printf("fna     : %#x\n", ctrl->fna);
-       if (human)
-               show_nvme_id_ctrl_fna(ctrl->fna);
-       printf("vwc     : %#x\n", ctrl->vwc);
-       if (human)
-               show_nvme_id_ctrl_vwc(ctrl->vwc);
-       printf("awun    : %d\n", ctrl->awun);
-       printf("awupf   : %d\n", ctrl->awupf);
-       printf("nvscc   : %d\n", ctrl->nvscc);
-       if (human)
-               show_nvme_id_ctrl_nvscc(ctrl->nvscc);
-       printf("acwu    : %d\n", ctrl->acwu);
-       printf("sgls    : %x\n", ctrl->sgls);
-       if (human)
-               show_nvme_id_ctrl_sgls(ctrl->sgls);
-
-       for (i = 0; i <= ctrl->npss; i++) {
-               printf("ps %4d : mp:%d flags:%x enlat:%d exlat:%d rrt:%d rrl:%d\n"
-                       "          rwt:%d rwl:%d idlp:%d ips:%x actp:%x ap flags:%x\n",
-                       i, ctrl->psd[i].max_power, ctrl->psd[i].flags,
-                       ctrl->psd[i].entry_lat, ctrl->psd[i].exit_lat,
-                       ctrl->psd[i].read_tput, ctrl->psd[i].read_lat,
-                       ctrl->psd[i].write_tput, ctrl->psd[i].write_lat,
-                       ctrl->psd[i].idle_power, ctrl->psd[i].idle_scale,
-                       ctrl->psd[i].active_power, ctrl->psd[i].active_work_scale);
-       }
-       if (vs) {
-               printf("vs[]:\n");
-               d(ctrl->vs, sizeof(ctrl->vs), 16, 1);
-       }
-}
-
 char* nvme_feature_lba_type_to_string(__u8 type)
 {
        switch (type)
@@ -870,213 +480,6 @@ static void show_lba_range(struct nvme_lba_range_type *lbrt, int nr_ranges)
        }
 }
 
-static void show_nvme_id_ns_nsfeat(__u8 nsfeat)
-{
-       __u8 rsvd = (nsfeat & 0xF8) >> 3;
-       __u8 dulbe = (nsfeat & 0x4) >> 2;
-       __u8 na = (nsfeat & 0x2) >> 1;
-       __u8 thin = nsfeat & 0x1;
-       if (rsvd)
-               printf("  [7:3] : %#x\tReserved\n", rsvd);
-       printf("  [2:2] : %#x\tDeallocated or Unwritten Logical Block error %sSupported\n",
-               dulbe, dulbe ? "" : "Not ");
-       printf("  [1:1] : %#x\tNamespace uses %s\n",
-               na, na ? "NAWUN, NAWUPF, and NACWU" : "AWUN, AWUPF, and ACWU");
-       printf("  [0:0] : %#x\tThin Provisioning %sSupported\n",
-               thin, thin ? "" : "Not ");
-       printf("\n");
-}
-
-static void show_nvme_id_ns_flbas(__u8 flbas)
-{
-       __u8 rsvd = (flbas & 0xE0) >> 5;
-       __u8 mdedata = (flbas & 0x10) >> 4;
-       __u8 lbaf = flbas & 0xF;
-       if (rsvd)
-               printf("  [7:5] : %#x\tReserved\n", rsvd);
-       printf("  [4:4] : %#x\tMetadata Transferred %s\n",
-               mdedata, mdedata ? "at End of Data LBA" : "in Separate Contiguous Buffer");
-       printf("  [3:0] : %#x\tCurrent LBA Format Selected\n", lbaf);
-       printf("\n");
-}
-
-static void show_nvme_id_ns_mc(__u8 mc)
-{
-       __u8 rsvd = (mc & 0xFC) >> 2;
-       __u8 mdp = (mc & 0x2) >> 1;
-       __u8 extdlba = mc & 0x1;
-       if (rsvd)
-               printf("  [7:2] : %#x\tReserved\n", rsvd);
-       printf("  [1:1] : %#x\tMetadata Pointer %sSupported\n",
-               mdp, mdp ? "" : "Not ");
-       printf("  [0:0] : %#x\tMetadata as Part of Extended Data LBA %sSupported\n",
-               extdlba, extdlba ? "" : "Not ");
-       printf("\n");
-}
-
-static void show_nvme_id_ns_dpc(__u8 dpc)
-{
-       __u8 rsvd = (dpc & 0xE0) >> 5;
-       __u8 pil8 = (dpc & 0x10) >> 4;
-       __u8 pif8 = (dpc & 0x8) >> 3;
-       __u8 pit3 = (dpc & 0x4) >> 2;
-       __u8 pit2 = (dpc & 0x2) >> 1;
-       __u8 pit1 = dpc & 0x1;
-       if (rsvd)
-               printf("  [7:5] : %#x\tReserved\n", rsvd);
-       printf("  [4:4] : %#x\tProtection Information Transferred as Last 8 Bytes of Metadata %sSupported\n",
-               pil8, pil8 ? "" : "Not ");
-       printf("  [3:3] : %#x\tProtection Information Transferred as First 8 Bytes of Metadata %sSupported\n",
-               pif8, pif8 ? "" : "Not ");
-       printf("  [2:2] : %#x\tProtection Information Type 3 %sSupported\n",
-               pit3, pit3 ? "" : "Not ");
-       printf("  [1:1] : %#x\tProtection Information Type 2 %sSupported\n",
-               pit2, pit2 ? "" : "Not ");
-       printf("  [0:0] : %#x\tProtection Information Type 1 %sSupported\n",
-               pit1, pit1 ? "" : "Not ");
-       printf("\n");
-}
-
-static void show_nvme_id_ns_dps(__u8 dps)
-{
-       __u8 rsvd = (dps & 0xF0) >> 4;
-       __u8 pif8 = (dps & 0x8) >> 3;
-       __u8 pit = dps & 0x7;
-       if (rsvd)
-               printf("  [7:4] : %#x\tReserved\n", rsvd);
-       printf("  [3:3] : %#x\tProtection Information is Transferred as %s 8 Bytes of Metadata\n",
-               pif8, pif8 ? "First" : "Last");
-       printf("  [2:0] : %#x\tProtection Information %s\n", pit,
-               pit == 3 ? "Type 3 Enabled" :
-               pit == 2 ? "Type 2 Enabled" :
-               pit == 1 ? "Type 1 Enabled" :
-               pit == 0 ? "Disabled" : "Reserved Enabled");
-       printf("\n");
-}
-
-static void show_nvme_id_ns_nmic(__u8 nmic)
-{
-       __u8 rsvd = (nmic & 0xFE) >> 1;
-       __u8 mp = nmic & 0x1;
-       if (rsvd)
-               printf("  [7:1] : %#x\tReserved\n", rsvd);
-       printf("  [0:0] : %#x\tNamespace Multipath %sCapable\n",
-               mp, mp ? "" : "Not ");
-       printf("\n");
-}
-
-static void show_nvme_id_ns_rescap(__u8 rescap)
-{
-       __u8 rsvd = (rescap & 0x80) >> 7;
-       __u8 eaar = (rescap & 0x40) >> 6;
-       __u8 wear = (rescap & 0x20) >> 5;
-       __u8 earo = (rescap & 0x10) >> 4;
-       __u8 wero = (rescap & 0x8) >> 3;
-       __u8 ea = (rescap & 0x4) >> 2;
-       __u8 we = (rescap & 0x2) >> 1;
-       __u8 ptpl = rescap & 0x1;
-       if (rsvd)
-               printf("  [7:7] : %#x\tReserved\n", rsvd);
-       printf("  [6:6] : %#x\tExclusive Access - All Registrants %sSupported\n",
-               eaar, eaar ? "" : "Not ");
-       printf("  [5:5] : %#x\tWrite Exclusive - All Registrants %sSupported\n",
-               wear, wear ? "" : "Not ");
-       printf("  [4:4] : %#x\tExclusive Access - Registrants Only %sSupported\n",
-               earo, earo ? "" : "Not ");
-       printf("  [3:3] : %#x\tWrite Exclusive - Registrants Only %sSupported\n",
-               wero, wero ? "" : "Not ");
-       printf("  [2:2] : %#x\tExclusive Access %sSupported\n",
-               ea, ea ? "" : "Not ");
-       printf("  [1:1] : %#x\tWrite Exclusive %sSupported\n",
-               we, we ? "" : "Not ");
-       printf("  [0:0] : %#x\tPersist Through Power Loss %sSupported\n",
-               ptpl, ptpl ? "" : "Not ");
-       printf("\n");
-}
-
-static void show_nvme_id_ns_fpi(__u8 fpi)
-{
-       __u8 fpis = (fpi & 0x80) >> 7;
-       __u8 fpii = fpi & 0x7F;
-       printf("  [7:7] : %#x\tFormat Progress Indicator %sSupported\n",
-               fpis, fpis ? "" : "Not ");
-       if (fpis || (!fpis && fpii))
-       printf("  [6:0] : %#x\tFormat Progress Indicator (Remaining %d%%)\n",
-               fpii, 100 - fpii);
-       printf("\n");
-}
-
-static void show_nvme_id_ns(struct nvme_id_ns *ns, int id, int vs, int human)
-{
-       int i;
-
-       printf("NVME Identify Namespace %d:\n", id);
-       printf("nsze    : %#"PRIx64"\n", (uint64_t)le64toh(ns->nsze));
-       printf("ncap    : %#"PRIx64"\n", (uint64_t)le64toh(ns->ncap));
-       printf("nuse    : %#"PRIx64"\n", (uint64_t)le64toh(ns->nuse));
-       printf("nsfeat  : %#x\n", ns->nsfeat);
-       if (human)
-               show_nvme_id_ns_nsfeat(ns->nsfeat);
-       printf("nlbaf   : %d\n", ns->nlbaf);
-       printf("flbas   : %#x\n", ns->flbas);
-       if (human)
-               show_nvme_id_ns_flbas(ns->flbas);
-       printf("mc      : %#x\n", ns->mc);
-       if (human)
-               show_nvme_id_ns_mc(ns->mc);
-       printf("dpc     : %#x\n", ns->dpc);
-       if (human)
-               show_nvme_id_ns_dpc(ns->dpc);
-       printf("dps     : %#x\n", ns->dps);
-       if (human)
-               show_nvme_id_ns_dps(ns->dps);
-       printf("nmic    : %#x\n", ns->nmic);
-       if (human)
-               show_nvme_id_ns_nmic(ns->nmic);
-       printf("rescap  : %#x\n", ns->rescap);
-       if (human)
-               show_nvme_id_ns_rescap(ns->rescap);
-       printf("fpi     : %#x\n", ns->fpi);
-       if (human)
-               show_nvme_id_ns_fpi(ns->fpi);
-       printf("nawun   : %d\n", ns->nawun);
-       printf("nawupf  : %d\n", ns->nawupf);
-       printf("nacwu   : %d\n", ns->nacwu);
-       printf("nabsn   : %d\n", ns->nabsn);
-       printf("nabo    : %d\n", ns->nabo);
-       printf("nabspf  : %d\n", ns->nabspf);
-       printf("nvmcap  : %.0Lf\n", int128_to_double(ns->nvmcap));
-
-       printf("nguid   : ");
-       for (i = 0; i < 16; i++)
-               printf("%02x", ns->nguid[i]);
-       printf("\n");
-
-       printf("eui64   : ");
-       for (i = 0; i < 8; i++)
-               printf("%02x", ns->eui64[i]);
-       printf("\n");
-
-       for (i = 0; i <= ns->nlbaf; i++) {
-               if (human)
-                       printf("LBA Format %2d : Metadata Size: %-3d bytes - "
-                               "Data Size: %-2d bytes - Relative Performance: %#x %s %s\n", i,
-                               ns->lbaf[i].ms, 1 << ns->lbaf[i].ds, ns->lbaf[i].rp,
-                               ns->lbaf[i].rp == 3 ? "Degraded" :
-                               ns->lbaf[i].rp == 2 ? "Good" :
-                               ns->lbaf[i].rp == 1 ? "Better" : "Best",
-                               i == (ns->flbas & 0xf) ? "(in use)" : "");
-               else
-                       printf("lbaf %2d : ms:%-3d ds:%-2d rp:%#x %s\n", i,
-                               ns->lbaf[i].ms, ns->lbaf[i].ds, ns->lbaf[i].rp,
-                               i == (ns->flbas & 0xf) ? "(in use)" : "");
-       }
-       if (vs) {
-               printf("vs[]:");
-               d(ns->vs, sizeof(ns->vs), 16, 1);
-       }
-}
-
 static int get_smart_log(int argc, char **argv)
 {
        struct nvme_smart_log smart_log;
@@ -1832,6 +1235,7 @@ static int id_ctrl(int argc, char **argv)
        const char *raw_binary = "show infos in binary format";
        const char *human_readable = "show infos in readable format";
        int err;
+       unsigned int flags = 0;
        struct nvme_id_ctrl ctrl;
 
        struct config {
@@ -1857,14 +1261,21 @@ static int id_ctrl(int argc, char **argv)
        argconfig_parse(argc, argv, desc, command_line_options,
                        &defaults, &cfg, sizeof(cfg));
 
+       if (cfg.vendor_specific)
+               flags |= VS;
+       if (cfg.human_readable)
+               flags |= HUMAN;
+
        get_dev(1, argc, argv);
 
        err = identify(0, &ctrl, 1);
        if (!err) {
-               if (cfg.raw_binary)
+               if (cfg.raw_binary) {
                        d_raw((unsigned char *)&ctrl, sizeof(ctrl));
-               else
-                       show_nvme_id_ctrl(&ctrl, cfg.vendor_specific, cfg.human_readable);
+               } else {
+                       printf("NVME Identify Controller:\n");
+                       show_nvme_id_ctrl(&ctrl, flags);
+               }
        }
        else if (err > 0)
                fprintf(stderr, "NVMe Status:%s(%x)\n",
@@ -1885,6 +1296,7 @@ static int id_ns(int argc, char **argv)
        const char *namespace_id = "name of desired namespace";
        struct nvme_id_ns ns;
        int err;
+       unsigned int flags = 0;
 
        struct config {
                __u32 namespace_id;
@@ -1913,6 +1325,11 @@ static int id_ns(int argc, char **argv)
        argconfig_parse(argc, argv, desc, command_line_options,
                        &defaults, &cfg, sizeof(cfg));
 
+       if (cfg.vendor_specific)
+               flags |= VS;
+       if (cfg.human_readable)
+               flags |= HUMAN;
+
        get_dev(1, argc, argv);
 
        if (!cfg.namespace_id) {
@@ -1932,8 +1349,10 @@ static int id_ns(int argc, char **argv)
        if (!err) {
                if (cfg.raw_binary)
                        d_raw((unsigned char *)&ns, sizeof(ns));
-               else
-                       show_nvme_id_ns(&ns, cfg.namespace_id, cfg.vendor_specific, cfg.human_readable);
+               else {
+                       printf("NVME Identify Namespace %d:\n", cfg.namespace_id);
+                       show_nvme_id_ns(&ns, flags);
+               }
        }
        else if (err > 0)
                fprintf(stderr, "NVMe Status:%s(%x) NSID:%d\n",