From: Patrick McCormick Date: Thu, 3 Dec 2015 15:27:33 +0000 (-0500) Subject: Factor out ID printing code into common.c X-Git-Tag: v0.3~14^2 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=876af32180f1549362a32da1b178de4978948348;p=users%2Fsagi%2Fnvme-cli.git Factor out ID printing code into common.c The printing output should be identical. The id structure printing functions can be more or less used by lsnvme. Signed-off-by: Patrick McCormick --- diff --git a/Makefile b/Makefile index 021fa1ae..524b683b 100644 --- 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 index 00000000..d9a0eec7 --- /dev/null +++ b/common.c @@ -0,0 +1,601 @@ +#include +#include + +#include + +#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 index 00000000..fa7aa2a9 --- /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 28c059b1..c72e6eb3 100644 --- a/nvme.c +++ b/nvme.c @@ -47,7 +47,8 @@ #include #include -#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",