]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
nvme: Add NVM Command Set specific identify namespace command
authorSteven Seungcheol Lee <sc108.lee@samsung.com>
Thu, 6 Jan 2022 12:53:08 +0000 (21:53 +0900)
committerDaniel Wagner <dwagner@suse.de>
Fri, 4 Feb 2022 13:07:09 +0000 (14:07 +0100)
Signed-off-by: Steven Seungcheol Lee <sc108.lee@samsung.com>
Documentation/nvme-nvm-id-ns.1 [new file with mode: 0644]
Documentation/nvme-nvm-id-ns.html [new file with mode: 0644]
Documentation/nvme-nvm-id-ns.txt [new file with mode: 0644]
completions/_nvme
completions/bash-nvme-completion.sh
nvme-builtin.h
nvme-print.c
nvme-print.h
nvme.c

diff --git a/Documentation/nvme-nvm-id-ns.1 b/Documentation/nvme-nvm-id-ns.1
new file mode 100644 (file)
index 0000000..fde30b7
--- /dev/null
@@ -0,0 +1,162 @@
+'\" t
+.\"     Title: nvme-nvm-id-ns
+.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
+.\"      Date: 01/07/2022
+.\"    Manual: NVMe Manual
+.\"    Source: NVMe
+.\"  Language: English
+.\"
+.TH "NVME\-NVM\-ID\-NS" "1" "01/07/2022" "NVMe" "NVMe Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+nvme-nvm-id-ns \- Send NVMe Identify NVM Command Set specific Namespace data structure, display structure
+.SH "SYNOPSIS"
+.sp
+.nf
+\fInvme nvm\-id\-ns\fR <device> [\-\-uuid\-index=<uuid\-index> | \-U <uuid_index>]
+                        [\-\-namespace\-id=<NUM> | \-n <NUM>]
+                        [\-v | \-\-verbose]
+                        [\-\-output\-format=<fmt> | \-o <fmt>]
+.fi
+.SH "DESCRIPTION"
+.sp
+Identify NVM Command Set specific Namespace data structure for the specified NSID for the NVM Command Set specified in the CSI field\&.
+.sp
+The <device> parameter is mandatory and may be either the NVMe character device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1)\&.
+.sp
+On success, the structure may be returned in one of several ways depending on the option flags; the structure may be parsed by the program or the raw buffer may be printed to stdout\&.
+.SH "OPTIONS"
+.PP
+\-n <NUM>, \-\-namespace\-id=<NUM>
+.RS 4
+Use the provided namespace id for the command\&. If not provided, the namespace id of the block device will be used\&. If the command is issued to a non\-block device, the parameter is required\&.
+.RE
+.PP
+\-U <uuid\-index>, \-\-uuid\-index=<uuid\-index>
+.RS 4
+UUID Index of the feature
+.RE
+.PP
+\-v, \-\-verbose
+.RS 4
+Increase the information detail in the output\&.
+.RE
+.PP
+\-o <format>, \-\-output\-format=<format>
+.RS 4
+Set the reporting format to
+\fInormal\fR,
+\fIjson\fR, or
+\fIbinary\fR\&. Only one output format can be used at a time\&.
+.RE
+.SH "EXAMPLES"
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Has the program interpret the returned buffer and display the known fields in a human readable format:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+# nvme nvm\-id\-ns /dev/nvme0n1
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+If using the character device or overriding namespace id:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+# nvme nvm\-id\-ns /dev/nvme0 \-n 1
+# nvme nvm\-id\-ns /dev/nvme0n1 \-n 1
+# nvme nvm\-id\-ns /dev/nvme0 \-\-namespace\-id=1
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Have the program return the raw structure in binary:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+# nvme nvm\-id\-ns /dev/nvme0n1 \-o binary > id_ns\&.raw
+# nvme nvm\-id\-ns /dev/nvme0n1 \-\-output\-format=binary > id_ns\&.raw
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+It is probably a bad idea to not redirect stdout when using this mode\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Alternatively you may want to send the data to another program that can parse the raw buffer\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+NVME
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.sp
+Part of the nvme\-user suite
diff --git a/Documentation/nvme-nvm-id-ns.html b/Documentation/nvme-nvm-id-ns.html
new file mode 100644 (file)
index 0000000..82645dc
--- /dev/null
@@ -0,0 +1,881 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"\r
+    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\r
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">\r
+<head>\r
+<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />\r
+<meta name="generator" content="AsciiDoc 8.6.8" />\r
+<title>nvme-nvm-id-ns(1)</title>\r
+<style type="text/css">\r
+/* Shared CSS for AsciiDoc xhtml11 and html5 backends */\r
+\r
+/* Default font. */\r
+body {\r
+  font-family: Georgia,serif;\r
+}\r
+\r
+/* Title font. */\r
+h1, h2, h3, h4, h5, h6,\r
+div.title, caption.title,\r
+thead, p.table.header,\r
+#toctitle,\r
+#author, #revnumber, #revdate, #revremark,\r
+#footer {\r
+  font-family: Arial,Helvetica,sans-serif;\r
+}\r
+\r
+body {\r
+  margin: 1em 5% 1em 5%;\r
+}\r
+\r
+a {\r
+  color: blue;\r
+  text-decoration: underline;\r
+}\r
+a:visited {\r
+  color: fuchsia;\r
+}\r
+\r
+em {\r
+  font-style: italic;\r
+  color: navy;\r
+}\r
+\r
+strong {\r
+  font-weight: bold;\r
+  color: #083194;\r
+}\r
+\r
+h1, h2, h3, h4, h5, h6 {\r
+  color: #527bbd;\r
+  margin-top: 1.2em;\r
+  margin-bottom: 0.5em;\r
+  line-height: 1.3;\r
+}\r
+\r
+h1, h2, h3 {\r
+  border-bottom: 2px solid silver;\r
+}\r
+h2 {\r
+  padding-top: 0.5em;\r
+}\r
+h3 {\r
+  float: left;\r
+}\r
+h3 + * {\r
+  clear: left;\r
+}\r
+h5 {\r
+  font-size: 1.0em;\r
+}\r
+\r
+div.sectionbody {\r
+  margin-left: 0;\r
+}\r
+\r
+hr {\r
+  border: 1px solid silver;\r
+}\r
+\r
+p {\r
+  margin-top: 0.5em;\r
+  margin-bottom: 0.5em;\r
+}\r
+\r
+ul, ol, li > p {\r
+  margin-top: 0;\r
+}\r
+ul > li     { color: #aaa; }\r
+ul > li > * { color: black; }\r
+\r
+.monospaced, code, pre {\r
+  font-family: "Courier New", Courier, monospace;\r
+  font-size: inherit;\r
+  color: navy;\r
+  padding: 0;\r
+  margin: 0;\r
+}\r
+\r
+\r
+#author {\r
+  color: #527bbd;\r
+  font-weight: bold;\r
+  font-size: 1.1em;\r
+}\r
+#email {\r
+}\r
+#revnumber, #revdate, #revremark {\r
+}\r
+\r
+#footer {\r
+  font-size: small;\r
+  border-top: 2px solid silver;\r
+  padding-top: 0.5em;\r
+  margin-top: 4.0em;\r
+}\r
+#footer-text {\r
+  float: left;\r
+  padding-bottom: 0.5em;\r
+}\r
+#footer-badges {\r
+  float: right;\r
+  padding-bottom: 0.5em;\r
+}\r
+\r
+#preamble {\r
+  margin-top: 1.5em;\r
+  margin-bottom: 1.5em;\r
+}\r
+div.imageblock, div.exampleblock, div.verseblock,\r
+div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,\r
+div.admonitionblock {\r
+  margin-top: 1.0em;\r
+  margin-bottom: 1.5em;\r
+}\r
+div.admonitionblock {\r
+  margin-top: 2.0em;\r
+  margin-bottom: 2.0em;\r
+  margin-right: 10%;\r
+  color: #606060;\r
+}\r
+\r
+div.content { /* Block element content. */\r
+  padding: 0;\r
+}\r
+\r
+/* Block element titles. */\r
+div.title, caption.title {\r
+  color: #527bbd;\r
+  font-weight: bold;\r
+  text-align: left;\r
+  margin-top: 1.0em;\r
+  margin-bottom: 0.5em;\r
+}\r
+div.title + * {\r
+  margin-top: 0;\r
+}\r
+\r
+td div.title:first-child {\r
+  margin-top: 0.0em;\r
+}\r
+div.content div.title:first-child {\r
+  margin-top: 0.0em;\r
+}\r
+div.content + div.title {\r
+  margin-top: 0.0em;\r
+}\r
+\r
+div.sidebarblock > div.content {\r
+  background: #ffffee;\r
+  border: 1px solid #dddddd;\r
+  border-left: 4px solid #f0f0f0;\r
+  padding: 0.5em;\r
+}\r
+\r
+div.listingblock > div.content {\r
+  border: 1px solid #dddddd;\r
+  border-left: 5px solid #f0f0f0;\r
+  background: #f8f8f8;\r
+  padding: 0.5em;\r
+}\r
+\r
+div.quoteblock, div.verseblock {\r
+  padding-left: 1.0em;\r
+  margin-left: 1.0em;\r
+  margin-right: 10%;\r
+  border-left: 5px solid #f0f0f0;\r
+  color: #888;\r
+}\r
+\r
+div.quoteblock > div.attribution {\r
+  padding-top: 0.5em;\r
+  text-align: right;\r
+}\r
+\r
+div.verseblock > pre.content {\r
+  font-family: inherit;\r
+  font-size: inherit;\r
+}\r
+div.verseblock > div.attribution {\r
+  padding-top: 0.75em;\r
+  text-align: left;\r
+}\r
+/* DEPRECATED: Pre version 8.2.7 verse style literal block. */\r
+div.verseblock + div.attribution {\r
+  text-align: left;\r
+}\r
+\r
+div.admonitionblock .icon {\r
+  vertical-align: top;\r
+  font-size: 1.1em;\r
+  font-weight: bold;\r
+  text-decoration: underline;\r
+  color: #527bbd;\r
+  padding-right: 0.5em;\r
+}\r
+div.admonitionblock td.content {\r
+  padding-left: 0.5em;\r
+  border-left: 3px solid #dddddd;\r
+}\r
+\r
+div.exampleblock > div.content {\r
+  border-left: 3px solid #dddddd;\r
+  padding-left: 0.5em;\r
+}\r
+\r
+div.imageblock div.content { padding-left: 0; }\r
+span.image img { border-style: none; }\r
+a.image:visited { color: white; }\r
+\r
+dl {\r
+  margin-top: 0.8em;\r
+  margin-bottom: 0.8em;\r
+}\r
+dt {\r
+  margin-top: 0.5em;\r
+  margin-bottom: 0;\r
+  font-style: normal;\r
+  color: navy;\r
+}\r
+dd > *:first-child {\r
+  margin-top: 0.1em;\r
+}\r
+\r
+ul, ol {\r
+    list-style-position: outside;\r
+}\r
+ol.arabic {\r
+  list-style-type: decimal;\r
+}\r
+ol.loweralpha {\r
+  list-style-type: lower-alpha;\r
+}\r
+ol.upperalpha {\r
+  list-style-type: upper-alpha;\r
+}\r
+ol.lowerroman {\r
+  list-style-type: lower-roman;\r
+}\r
+ol.upperroman {\r
+  list-style-type: upper-roman;\r
+}\r
+\r
+div.compact ul, div.compact ol,\r
+div.compact p, div.compact p,\r
+div.compact div, div.compact div {\r
+  margin-top: 0.1em;\r
+  margin-bottom: 0.1em;\r
+}\r
+\r
+tfoot {\r
+  font-weight: bold;\r
+}\r
+td > div.verse {\r
+  white-space: pre;\r
+}\r
+\r
+div.hdlist {\r
+  margin-top: 0.8em;\r
+  margin-bottom: 0.8em;\r
+}\r
+div.hdlist tr {\r
+  padding-bottom: 15px;\r
+}\r
+dt.hdlist1.strong, td.hdlist1.strong {\r
+  font-weight: bold;\r
+}\r
+td.hdlist1 {\r
+  vertical-align: top;\r
+  font-style: normal;\r
+  padding-right: 0.8em;\r
+  color: navy;\r
+}\r
+td.hdlist2 {\r
+  vertical-align: top;\r
+}\r
+div.hdlist.compact tr {\r
+  margin: 0;\r
+  padding-bottom: 0;\r
+}\r
+\r
+.comment {\r
+  background: yellow;\r
+}\r
+\r
+.footnote, .footnoteref {\r
+  font-size: 0.8em;\r
+}\r
+\r
+span.footnote, span.footnoteref {\r
+  vertical-align: super;\r
+}\r
+\r
+#footnotes {\r
+  margin: 20px 0 20px 0;\r
+  padding: 7px 0 0 0;\r
+}\r
+\r
+#footnotes div.footnote {\r
+  margin: 0 0 5px 0;\r
+}\r
+\r
+#footnotes hr {\r
+  border: none;\r
+  border-top: 1px solid silver;\r
+  height: 1px;\r
+  text-align: left;\r
+  margin-left: 0;\r
+  width: 20%;\r
+  min-width: 100px;\r
+}\r
+\r
+div.colist td {\r
+  padding-right: 0.5em;\r
+  padding-bottom: 0.3em;\r
+  vertical-align: top;\r
+}\r
+div.colist td img {\r
+  margin-top: 0.3em;\r
+}\r
+\r
+@media print {\r
+  #footer-badges { display: none; }\r
+}\r
+\r
+#toc {\r
+  margin-bottom: 2.5em;\r
+}\r
+\r
+#toctitle {\r
+  color: #527bbd;\r
+  font-size: 1.1em;\r
+  font-weight: bold;\r
+  margin-top: 1.0em;\r
+  margin-bottom: 0.1em;\r
+}\r
+\r
+div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {\r
+  margin-top: 0;\r
+  margin-bottom: 0;\r
+}\r
+div.toclevel2 {\r
+  margin-left: 2em;\r
+  font-size: 0.9em;\r
+}\r
+div.toclevel3 {\r
+  margin-left: 4em;\r
+  font-size: 0.9em;\r
+}\r
+div.toclevel4 {\r
+  margin-left: 6em;\r
+  font-size: 0.9em;\r
+}\r
+\r
+span.aqua { color: aqua; }\r
+span.black { color: black; }\r
+span.blue { color: blue; }\r
+span.fuchsia { color: fuchsia; }\r
+span.gray { color: gray; }\r
+span.green { color: green; }\r
+span.lime { color: lime; }\r
+span.maroon { color: maroon; }\r
+span.navy { color: navy; }\r
+span.olive { color: olive; }\r
+span.purple { color: purple; }\r
+span.red { color: red; }\r
+span.silver { color: silver; }\r
+span.teal { color: teal; }\r
+span.white { color: white; }\r
+span.yellow { color: yellow; }\r
+\r
+span.aqua-background { background: aqua; }\r
+span.black-background { background: black; }\r
+span.blue-background { background: blue; }\r
+span.fuchsia-background { background: fuchsia; }\r
+span.gray-background { background: gray; }\r
+span.green-background { background: green; }\r
+span.lime-background { background: lime; }\r
+span.maroon-background { background: maroon; }\r
+span.navy-background { background: navy; }\r
+span.olive-background { background: olive; }\r
+span.purple-background { background: purple; }\r
+span.red-background { background: red; }\r
+span.silver-background { background: silver; }\r
+span.teal-background { background: teal; }\r
+span.white-background { background: white; }\r
+span.yellow-background { background: yellow; }\r
+\r
+span.big { font-size: 2em; }\r
+span.small { font-size: 0.6em; }\r
+\r
+span.underline { text-decoration: underline; }\r
+span.overline { text-decoration: overline; }\r
+span.line-through { text-decoration: line-through; }\r
+\r
+div.unbreakable { page-break-inside: avoid; }\r
+\r
+\r
+/*\r
+ * xhtml11 specific\r
+ *\r
+ * */\r
+\r
+div.tableblock {\r
+  margin-top: 1.0em;\r
+  margin-bottom: 1.5em;\r
+}\r
+div.tableblock > table {\r
+  border: 3px solid #527bbd;\r
+}\r
+thead, p.table.header {\r
+  font-weight: bold;\r
+  color: #527bbd;\r
+}\r
+p.table {\r
+  margin-top: 0;\r
+}\r
+/* Because the table frame attribute is overridden by CSS in most browsers. */\r
+div.tableblock > table[frame="void"] {\r
+  border-style: none;\r
+}\r
+div.tableblock > table[frame="hsides"] {\r
+  border-left-style: none;\r
+  border-right-style: none;\r
+}\r
+div.tableblock > table[frame="vsides"] {\r
+  border-top-style: none;\r
+  border-bottom-style: none;\r
+}\r
+\r
+\r
+/*\r
+ * html5 specific\r
+ *\r
+ * */\r
+\r
+table.tableblock {\r
+  margin-top: 1.0em;\r
+  margin-bottom: 1.5em;\r
+}\r
+thead, p.tableblock.header {\r
+  font-weight: bold;\r
+  color: #527bbd;\r
+}\r
+p.tableblock {\r
+  margin-top: 0;\r
+}\r
+table.tableblock {\r
+  border-width: 3px;\r
+  border-spacing: 0px;\r
+  border-style: solid;\r
+  border-color: #527bbd;\r
+  border-collapse: collapse;\r
+}\r
+th.tableblock, td.tableblock {\r
+  border-width: 1px;\r
+  padding: 4px;\r
+  border-style: solid;\r
+  border-color: #527bbd;\r
+}\r
+\r
+table.tableblock.frame-topbot {\r
+  border-left-style: hidden;\r
+  border-right-style: hidden;\r
+}\r
+table.tableblock.frame-sides {\r
+  border-top-style: hidden;\r
+  border-bottom-style: hidden;\r
+}\r
+table.tableblock.frame-none {\r
+  border-style: hidden;\r
+}\r
+\r
+th.tableblock.halign-left, td.tableblock.halign-left {\r
+  text-align: left;\r
+}\r
+th.tableblock.halign-center, td.tableblock.halign-center {\r
+  text-align: center;\r
+}\r
+th.tableblock.halign-right, td.tableblock.halign-right {\r
+  text-align: right;\r
+}\r
+\r
+th.tableblock.valign-top, td.tableblock.valign-top {\r
+  vertical-align: top;\r
+}\r
+th.tableblock.valign-middle, td.tableblock.valign-middle {\r
+  vertical-align: middle;\r
+}\r
+th.tableblock.valign-bottom, td.tableblock.valign-bottom {\r
+  vertical-align: bottom;\r
+}\r
+\r
+\r
+/*\r
+ * manpage specific\r
+ *\r
+ * */\r
+\r
+body.manpage h1 {\r
+  padding-top: 0.5em;\r
+  padding-bottom: 0.5em;\r
+  border-top: 2px solid silver;\r
+  border-bottom: 2px solid silver;\r
+}\r
+body.manpage h2 {\r
+  border-style: none;\r
+}\r
+body.manpage div.sectionbody {\r
+  margin-left: 3em;\r
+}\r
+\r
+@media print {\r
+  body.manpage div#toc { display: none; }\r
+}\r
+\r
+\r
+</style>\r
+<script type="text/javascript">\r
+/*<![CDATA[*/\r
+var asciidoc = {  // Namespace.\r
+\r
+/////////////////////////////////////////////////////////////////////\r
+// Table Of Contents generator\r
+/////////////////////////////////////////////////////////////////////\r
+\r
+/* Author: Mihai Bazon, September 2002\r
+ * http://students.infoiasi.ro/~mishoo\r
+ *\r
+ * Table Of Content generator\r
+ * Version: 0.4\r
+ *\r
+ * Feel free to use this script under the terms of the GNU General Public\r
+ * License, as long as you do not remove or alter this notice.\r
+ */\r
+\r
+ /* modified by Troy D. Hanson, September 2006. License: GPL */\r
+ /* modified by Stuart Rackham, 2006, 2009. License: GPL */\r
+\r
+// toclevels = 1..4.\r
+toc: function (toclevels) {\r
+\r
+  function getText(el) {\r
+    var text = "";\r
+    for (var i = el.firstChild; i != null; i = i.nextSibling) {\r
+      if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.\r
+        text += i.data;\r
+      else if (i.firstChild != null)\r
+        text += getText(i);\r
+    }\r
+    return text;\r
+  }\r
+\r
+  function TocEntry(el, text, toclevel) {\r
+    this.element = el;\r
+    this.text = text;\r
+    this.toclevel = toclevel;\r
+  }\r
+\r
+  function tocEntries(el, toclevels) {\r
+    var result = new Array;\r
+    var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');\r
+    // Function that scans the DOM tree for header elements (the DOM2\r
+    // nodeIterator API would be a better technique but not supported by all\r
+    // browsers).\r
+    var iterate = function (el) {\r
+      for (var i = el.firstChild; i != null; i = i.nextSibling) {\r
+        if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {\r
+          var mo = re.exec(i.tagName);\r
+          if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {\r
+            result[result.length] = new TocEntry(i, getText(i), mo[1]-1);\r
+          }\r
+          iterate(i);\r
+        }\r
+      }\r
+    }\r
+    iterate(el);\r
+    return result;\r
+  }\r
+\r
+  var toc = document.getElementById("toc");\r
+  if (!toc) {\r
+    return;\r
+  }\r
+\r
+  // Delete existing TOC entries in case we're reloading the TOC.\r
+  var tocEntriesToRemove = [];\r
+  var i;\r
+  for (i = 0; i < toc.childNodes.length; i++) {\r
+    var entry = toc.childNodes[i];\r
+    if (entry.nodeName.toLowerCase() == 'div'\r
+     && entry.getAttribute("class")\r
+     && entry.getAttribute("class").match(/^toclevel/))\r
+      tocEntriesToRemove.push(entry);\r
+  }\r
+  for (i = 0; i < tocEntriesToRemove.length; i++) {\r
+    toc.removeChild(tocEntriesToRemove[i]);\r
+  }\r
+\r
+  // Rebuild TOC entries.\r
+  var entries = tocEntries(document.getElementById("content"), toclevels);\r
+  for (var i = 0; i < entries.length; ++i) {\r
+    var entry = entries[i];\r
+    if (entry.element.id == "")\r
+      entry.element.id = "_toc_" + i;\r
+    var a = document.createElement("a");\r
+    a.href = "#" + entry.element.id;\r
+    a.appendChild(document.createTextNode(entry.text));\r
+    var div = document.createElement("div");\r
+    div.appendChild(a);\r
+    div.className = "toclevel" + entry.toclevel;\r
+    toc.appendChild(div);\r
+  }\r
+  if (entries.length == 0)\r
+    toc.parentNode.removeChild(toc);\r
+},\r
+\r
+\r
+/////////////////////////////////////////////////////////////////////\r
+// Footnotes generator\r
+/////////////////////////////////////////////////////////////////////\r
+\r
+/* Based on footnote generation code from:\r
+ * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html\r
+ */\r
+\r
+footnotes: function () {\r
+  // Delete existing footnote entries in case we're reloading the footnodes.\r
+  var i;\r
+  var noteholder = document.getElementById("footnotes");\r
+  if (!noteholder) {\r
+    return;\r
+  }\r
+  var entriesToRemove = [];\r
+  for (i = 0; i < noteholder.childNodes.length; i++) {\r
+    var entry = noteholder.childNodes[i];\r
+    if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")\r
+      entriesToRemove.push(entry);\r
+  }\r
+  for (i = 0; i < entriesToRemove.length; i++) {\r
+    noteholder.removeChild(entriesToRemove[i]);\r
+  }\r
+\r
+  // Rebuild footnote entries.\r
+  var cont = document.getElementById("content");\r
+  var spans = cont.getElementsByTagName("span");\r
+  var refs = {};\r
+  var n = 0;\r
+  for (i=0; i<spans.length; i++) {\r
+    if (spans[i].className == "footnote") {\r
+      n++;\r
+      var note = spans[i].getAttribute("data-note");\r
+      if (!note) {\r
+        // Use [\s\S] in place of . so multi-line matches work.\r
+        // Because JavaScript has no s (dotall) regex flag.\r
+        note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];\r
+        spans[i].innerHTML =\r
+          "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +\r
+          "' title='View footnote' class='footnote'>" + n + "</a>]";\r
+        spans[i].setAttribute("data-note", note);\r
+      }\r
+      noteholder.innerHTML +=\r
+        "<div class='footnote' id='_footnote_" + n + "'>" +\r
+        "<a href='#_footnoteref_" + n + "' title='Return to text'>" +\r
+        n + "</a>. " + note + "</div>";\r
+      var id =spans[i].getAttribute("id");\r
+      if (id != null) refs["#"+id] = n;\r
+    }\r
+  }\r
+  if (n == 0)\r
+    noteholder.parentNode.removeChild(noteholder);\r
+  else {\r
+    // Process footnoterefs.\r
+    for (i=0; i<spans.length; i++) {\r
+      if (spans[i].className == "footnoteref") {\r
+        var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");\r
+        href = href.match(/#.*/)[0];  // Because IE return full URL.\r
+        n = refs[href];\r
+        spans[i].innerHTML =\r
+          "[<a href='#_footnote_" + n +\r
+          "' title='View footnote' class='footnote'>" + n + "</a>]";\r
+      }\r
+    }\r
+  }\r
+},\r
+\r
+install: function(toclevels) {\r
+  var timerId;\r
+\r
+  function reinstall() {\r
+    asciidoc.footnotes();\r
+    if (toclevels) {\r
+      asciidoc.toc(toclevels);\r
+    }\r
+  }\r
+\r
+  function reinstallAndRemoveTimer() {\r
+    clearInterval(timerId);\r
+    reinstall();\r
+  }\r
+\r
+  timerId = setInterval(reinstall, 500);\r
+  if (document.addEventListener)\r
+    document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);\r
+  else\r
+    window.onload = reinstallAndRemoveTimer;\r
+}\r
+\r
+}\r
+asciidoc.install();\r
+/*]]>*/\r
+</script>\r
+</head>\r
+<body class="manpage">\r
+<div id="header">\r
+<h1>\r
+nvme-nvm-id-ns(1) Manual Page\r
+</h1>\r
+<h2>NAME</h2>\r
+<div class="sectionbody">\r
+<p>nvme-nvm-id-ns -\r
+   Send NVMe Identify NVM Command Set specific Namespace data structure, display structure\r
+</p>\r
+</div>\r
+</div>\r
+<div id="content">\r
+<div class="sect1">\r
+<h2 id="_synopsis">SYNOPSIS</h2>\r
+<div class="sectionbody">\r
+<div class="verseblock">\r
+<pre class="content"><em>nvme nvm-id-ns</em> &lt;device&gt; [--uuid-index=&lt;uuid-index&gt; | -U &lt;uuid_index&gt;]\r
+                        [--namespace-id=&lt;NUM&gt; | -n &lt;NUM&gt;]\r
+                        [-v | --verbose]\r
+                        [--output-format=&lt;fmt&gt; | -o &lt;fmt&gt;]</pre>\r
+<div class="attribution">\r
+</div></div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
+<h2 id="_description">DESCRIPTION</h2>\r
+<div class="sectionbody">\r
+<div class="paragraph"><p>Identify NVM Command Set specific Namespace data structure for the specified\r
+NSID for the NVM Command Set specified in the CSI field.</p></div>\r
+<div class="paragraph"><p>The &lt;device&gt; parameter is mandatory and may be either the NVMe character\r
+device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1).</p></div>\r
+<div class="paragraph"><p>On success, the structure may be returned in one of several ways depending\r
+on the option flags; the structure may be parsed by the program or the\r
+raw buffer may be printed to stdout.</p></div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
+<h2 id="_options">OPTIONS</h2>\r
+<div class="sectionbody">\r
+<div class="dlist"><dl>\r
+<dt class="hdlist1">\r
+-n &lt;NUM&gt;\r
+</dt>\r
+<dt class="hdlist1">\r
+--namespace-id=&lt;NUM&gt;\r
+</dt>\r
+<dd>\r
+<p>\r
+        Use the provided namespace id for the command. If not provided, the\r
+        namespace id of the block device will be used. If the command is issued\r
+        to a non-block device, the parameter is required.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+-U &lt;uuid-index&gt;\r
+</dt>\r
+<dt class="hdlist1">\r
+--uuid-index=&lt;uuid-index&gt;\r
+</dt>\r
+<dd>\r
+<p>\r
+        UUID Index of the feature\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+-v\r
+</dt>\r
+<dt class="hdlist1">\r
+--verbose\r
+</dt>\r
+<dd>\r
+<p>\r
+        Increase the information detail in the output.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+-o &lt;format&gt;\r
+</dt>\r
+<dt class="hdlist1">\r
+--output-format=&lt;format&gt;\r
+</dt>\r
+<dd>\r
+<p>\r
+              Set the reporting format to <em>normal</em>, <em>json</em>, or\r
+              <em>binary</em>. Only one output format can be used at a time.\r
+</p>\r
+</dd>\r
+</dl></div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
+<h2 id="_examples">EXAMPLES</h2>\r
+<div class="sectionbody">\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+Has the program interpret the returned buffer and display the known\r
+fields in a human readable format:\r
+</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><code># nvme nvm-id-ns /dev/nvme0n1</code></pre>\r
+</div></div>\r
+</li>\r
+<li>\r
+<p>\r
+If using the character device or overriding namespace id:\r
+</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><code># nvme nvm-id-ns /dev/nvme0 -n 1\r
+# nvme nvm-id-ns /dev/nvme0n1 -n 1\r
+# nvme nvm-id-ns /dev/nvme0 --namespace-id=1</code></pre>\r
+</div></div>\r
+</li>\r
+<li>\r
+<p>\r
+Have the program return the raw structure in binary:\r
+</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><code># nvme nvm-id-ns /dev/nvme0n1 -o binary &gt; id_ns.raw\r
+# nvme nvm-id-ns /dev/nvme0n1 --output-format=binary &gt; id_ns.raw</code></pre>\r
+</div></div>\r
+<div class="paragraph"><p>It is probably a bad idea to not redirect stdout when using this mode.</p></div>\r
+</li>\r
+<li>\r
+<p>\r
+Alternatively you may want to send the data to another program that\r
+can parse the raw buffer.\r
+</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><code>NVME</code></pre>\r
+</div></div>\r
+</li>\r
+</ul></div>\r
+<div class="paragraph"><p>Part of the nvme-user suite</p></div>\r
+</div>\r
+</div>\r
+</div>\r
+<div id="footnotes"><hr /></div>\r
+<div id="footer">\r
+<div id="footer-text">\r
+Last updated 2022-01-07 14:55:44 KST\r
+</div>\r
+</div>\r
+</body>\r
+</html>\r
diff --git a/Documentation/nvme-nvm-id-ns.txt b/Documentation/nvme-nvm-id-ns.txt
new file mode 100644 (file)
index 0000000..dfbbfaa
--- /dev/null
@@ -0,0 +1,83 @@
+nvme-nvm-id-ns(1)
+=================
+
+NAME
+----
+nvme-nvm-id-ns - Send NVMe Identify NVM Command Set specific Namespace data structure, display structure
+
+SYNOPSIS
+--------
+[verse]
+'nvme nvm-id-ns' <device> [--uuid-index=<uuid-index> | -U <uuid_index>]
+                       [--namespace-id=<NUM> | -n <NUM>]
+                       [-v | --verbose]
+                       [--output-format=<fmt> | -o <fmt>]
+
+DESCRIPTION
+-----------
+Identify NVM Command Set specific Namespace data structure for the specified
+NSID for the NVM Command Set specified in the CSI field.
+
+The <device> parameter is mandatory and may be either the NVMe character
+device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1).
+
+On success, the structure may be returned in one of several ways depending
+on the option flags; the structure may be parsed by the program or the
+raw buffer may be printed to stdout.
+
+OPTIONS
+-------
+-n <NUM>::
+--namespace-id=<NUM>::
+       Use the provided namespace id for the command. If not provided, the
+       namespace id of the block device will be used. If the command is issued
+       to a non-block device, the parameter is required.
+
+-U <uuid-index>::
+--uuid-index=<uuid-index>::
+       UUID Index of the feature
+
+-v::
+--verbose::
+       Increase the information detail in the output.
+
+-o <format>::
+--output-format=<format>::
+              Set the reporting format to 'normal', 'json', or
+              'binary'. Only one output format can be used at a time.
+
+EXAMPLES
+--------
+* Has the program interpret the returned buffer and display the known
+fields in a human readable format:
++
+------------
+# nvme nvm-id-ns /dev/nvme0n1
+------------
++
+
+* If using the character device or overriding namespace id:
++
+------------
+# nvme nvm-id-ns /dev/nvme0 -n 1
+# nvme nvm-id-ns /dev/nvme0n1 -n 1
+# nvme nvm-id-ns /dev/nvme0 --namespace-id=1
+------------
++
+* Have the program return the raw structure in binary:
++
+------------
+# nvme nvm-id-ns /dev/nvme0n1 -o binary > id_ns.raw
+# nvme nvm-id-ns /dev/nvme0n1 --output-format=binary > id_ns.raw
+------------
++
+It is probably a bad idea to not redirect stdout when using this mode.
+
+* Alternatively you may want to send the data to another program that
+can parse the raw buffer.
++
+------------
+
+NVME
+----
+Part of the nvme-user suite
index 03398f3a58285886fe6c694341af44914a0e29cf..980dbc9ed3754549ce0fb9df582c611ea6f60fc7 100644 (file)
@@ -20,6 +20,7 @@ _nvme () {
        'detach-ns:detach namespace from controller'
        'list-ctrl:identify all controller(s) attached'
        'nvm-id-ctrl:display information about the nvm command set'
+       'nvm-id-ns:display information about the namespace of nvm command set'
        'list-endgrp:display information about nvme endurance group list'
        'get-ns-id:get namespace id of opened block device'
        'get-log:retrieve any log in raw format'
@@ -163,7 +164,7 @@ _nvme () {
                        _arguments '*:: :->subcmds'
                        _describe -t commands "nvme id-domain options" _iddomain
                        ;;
-               nvm-id-ctrl)
+               (nvm-id-ctrl)
                        local _nvmidctrl
                        _nvmidctrl=(
                        /dev/nvme':supply a device to use (required)'
@@ -171,6 +172,22 @@ _nvme () {
                        _arguments '*:: :->subcmds'
                        _describe -t commands "nvme nvm-id-ctrl options" _nvmidctrl
                        ;;
+               (nvm-id-ns)
+                       local _nvmidns
+                       _nvmidns=(
+                       /dev/nvme':supply a device to use (required)'
+                       --namespace-id=':show infos for namespace <nsid>'
+                       -n':alias of --namespace-id'
+                       --uuid-index=':uuid index'
+                       -U':alias for --uuid-index'
+                       --output-format=':Output format: normal|json|binary'
+                       -o':alias for --output-format'
+                       --verbose':show infos verbosely'
+                       -v':alias of --verbose'
+                       )
+                       _arguments '*:: :->subcmds'
+                       _describe -t commands "nvme nvm-id-ns options" _nvmidns
+                       ;;
                (list-endgrp)
                        local _listendgrp
                        _listendgrp=(
@@ -931,7 +948,7 @@ _nvme () {
                             resv-report flush compare read write copy show-regs persistent-event-log
                                 pred-lat-event-agg-log nvm-id-ctrl endurance-event-agg-log lba-status-log
                                 resv-notif-log capacity-mgmt id-domain boot-part-log fid-support-effects-log
-                                supported-log-pages lockdown media-unit-stat-log id-ns-lba-format
+                                supported-log-pages lockdown media-unit-stat-log id-ns-lba-format nvm-id-ns
                           )
                        _arguments '*:: :->subcmds'
                        _describe -t commands "help: infos on a specific nvme command, or provide no option to see a synopsis of all nvme commands" _h
index facffb87e6615b86bdbdf4041185c19d5146ac18..da9ed9bfc0154c826ceb55c96db4f1b2a155b85c 100644 (file)
@@ -78,7 +78,7 @@ readonly _plugin_funcs=(
 # Top level commands
 _cmds="list list-subsys id-ctrl id-ns \
        id-ns-granularity list-ns list-ctrl \
-       id-ns-lba-format \
+       id-ns-lba-format nvm-id-ns \
        nvm-id-ctrl primary-ctrl-caps list-secondary \
        ns-descs id-nvmset id-uuid id-iocs create-ns \
        delete-ns get-ns-id get-log telemetry-log \
@@ -164,6 +164,10 @@ nvme_list_opts () {
                "nvm-id-ctrl")
                opts+=" --output-format= -o"
                        ;;
+               "nvm-id-ns")
+               opts+=" --namespace-id= -n --uuid-index= -U\
+                       --verbose -v --output-format= -o"
+                       ;;
                "primary-ctrl-caps")
                opts+=" --output-format= -o --human-readable -H"
                        ;;
index 89c3c14f615582d2deb080473415ceae107af29f..bac94cba2ff7d5557d60dd1897443465a06575f9 100644 (file)
@@ -16,6 +16,7 @@ COMMAND_LIST(
        ENTRY("list-ns", "Send NVMe Identify List, display structure", list_ns)
        ENTRY("list-ctrl", "Send NVMe Identify Controller List, display structure", list_ctrl)
        ENTRY("nvm-id-ctrl", "Send NVMe Identify Controller NVM Command Set, display structure", nvm_id_ctrl)
+       ENTRY("nvm-id-ns", "Send NVMe Identify Namespace NVM Command Set, display structure", nvm_id_ns)
        ENTRY("primary-ctrl-caps", "Send NVMe Identify Primary Controller Capabilities", primary_ctrl_caps)
        ENTRY("list-secondary", "List Secondary Controllers associated with a Primary Controller", list_secondary_ctrl)
        ENTRY("cmdset-ind-id-ns", "I/O Command Set Independent Identify Namespace", cmd_set_independent_id_ns)
index 0da0ba564e72cf35cd32adff7992767a669df424..2fb6197ea462a66ce541493c8d05a9bf40d54708 100644 (file)
@@ -4424,6 +4424,86 @@ void nvme_show_id_ctrl_nvm(struct nvme_id_ctrl_nvm *ctrl_nvm,
        printf("dmsl   : %"PRIu64"\n", le64_to_cpu(ctrl_nvm->dmsl));
 }
 
+static void json_nvme_nvm_id_ns(struct nvme_nvm_id_ns *nvm_ns,
+                                                               struct nvme_id_ns *ns)
+{
+       struct json_object *root;
+       struct json_object *elbafs;
+       int i;
+
+       root = json_create_object();
+
+       json_object_add_value_uint64(root, "lbstm", le64_to_cpu(nvm_ns->lbstm));
+       json_object_add_value_int(root, "pic", nvm_ns->pic);
+
+       elbafs = json_create_array();
+       json_object_add_value_array(root, "elbafs", elbafs);
+
+       for (i = 0; i <= ns->nlbaf; i++) {
+               struct json_object *elbaf = json_create_object();
+               unsigned int elbaf_val = le32_to_cpu(nvm_ns->elbaf[i]);
+
+               json_object_add_value_int(elbaf, "sts", elbaf_val & 0x7F);
+               json_object_add_value_int(elbaf, "pif", (elbaf_val >> 7) & 0x3);
+
+               json_array_add_value_object(elbafs, elbaf);
+       }
+
+       json_print_object(root, NULL);
+       printf("\n");
+       json_free_object(root);
+}
+
+static void nvme_show_nvm_id_ns_pic(__u8 pic)
+{
+       __u8 rsvd = (pic & 0xFC) >> 2;
+       __u8 pic_16bpistm = (pic & 0x2) >> 1;
+       __u8 pic_16bpists = pic & 0x1;
+
+       if (rsvd)
+               printf("  [7:2] : %#x\tReserved\n", rsvd);
+       printf("  [1:1] : %#x\t16b Guard Protection Information Storage Tag Mask\n",
+               pic_16bpistm);
+       printf("  [0:0] : %#x\t16b Guard Protection Information Storage Tag Support\n",
+               pic_16bpists);
+       printf("\n");
+}
+
+void nvme_show_nvm_id_ns(struct nvme_nvm_id_ns *nvm_ns, unsigned int nsid,
+                                               struct nvme_id_ns *ns, enum nvme_print_flags flags)
+{
+       int i, verbose = flags & VERBOSE;
+       __u32 elbaf;
+       int pif, sts;
+
+       if (flags & BINARY)
+               return d_raw((unsigned char *)nvm_ns, sizeof(*nvm_ns));
+       else if (flags & JSON)
+               return json_nvme_nvm_id_ns(nvm_ns, ns);
+
+       printf("NVMe NVM Identify Namespace %d:\n", nsid);
+       printf("lbstm : %#"PRIx64"\n", le64_to_cpu(nvm_ns->lbstm));
+       printf("pic   : %#x\n", nvm_ns->pic);
+       if (verbose)
+               nvme_show_nvm_id_ns_pic(nvm_ns->pic);
+
+       for (i = 0; i <= ns->nlbaf; i++) {
+               elbaf = le32_to_cpu(nvm_ns->elbaf[i]);
+               pif = (elbaf >> 7) & 0x3;
+               sts = elbaf & 0x7f;
+               if (verbose)
+                       printf("Extended LBA Format %2d : Protection Information Format: "
+                               "%s(%d) - Storage Tag Size (MSB): %-2d %s\n",
+                               i, pif == 3 ? "Reserved" :
+                                       pif == 2 ? "64b Guard" :
+                                       pif == 1 ? "32b Guard" : "16b Guard",
+                                       pif, sts, i == (ns->flbas & 0xf) ? "(in use)" : "");
+               else
+                       printf("elbaf %2d : pif:%d lbads:%-2d %s\n", i,
+                               pif, sts, i == (ns->flbas & 0xf) ? "(in use)" : "");
+       }
+}
+
 static void json_nvme_zns_id_ctrl(struct nvme_zns_id_ctrl *ctrl)
 {
        struct json_object *root;
index 073e171e929dd249ca7011d2a00dba2e896a9567..f9ba54d4e554528193022208e4793ca736fdb115 100644 (file)
@@ -112,6 +112,8 @@ void nvme_show_select_result(__u32 result);
 void nvme_show_zns_id_ctrl(struct nvme_zns_id_ctrl *ctrl, unsigned int mode);
 void nvme_show_id_ctrl_nvm(struct nvme_id_ctrl_nvm *ctrl_nvm,
        enum nvme_print_flags flags);
+void nvme_show_nvm_id_ns(struct nvme_nvm_id_ns *nvm_ns, unsigned int nsid,
+                                               struct nvme_id_ns *ns, enum nvme_print_flags flags);
 void nvme_show_zns_id_ns(struct nvme_zns_id_ns *ns,
        struct nvme_id_ns *id_ns, unsigned long flags);
 void nvme_show_zns_changed( struct nvme_zns_changed_zone_log *log,
diff --git a/nvme.c b/nvme.c
index dbf557b778d7f6e6c1429a7379dcfdfb8aa7a041..1c7069cfb854d40f6ee453ea9fe89c48ace45ffa 100644 (file)
--- a/nvme.c
+++ b/nvme.c
@@ -2655,6 +2655,81 @@ ret:
        return err;
 }
 
+static int nvm_id_ns(int argc, char **argv, struct command *cmd,
+       struct plugin *plugin)
+{
+       const char *desc = "Send an Identify Namespace NVM Command Set "\
+               "command to the given device and report information about "\
+               "the specified namespace in various formats.";
+       const char *namespace_id = "identifier of desired namespace";
+       const char *uuid_index = "UUID index";
+       const char *verbose = "Increase output verbosity";
+       enum nvme_print_flags flags;
+       struct nvme_nvm_id_ns id_ns;
+       struct nvme_id_ns ns;
+       int fd, err = -1;
+
+       struct config {
+               __u32 namespace_id;
+               __u8  uuid_index;
+               char *output_format;
+               int verbose;
+       };
+
+       struct config cfg = {
+               .namespace_id = 0,
+               .uuid_index = NVME_UUID_NONE,
+               .output_format = "normal",
+               .verbose = 0,
+       };
+
+       OPT_ARGS(opts) = {
+               OPT_UINT("namespace-id", 'n', &cfg.namespace_id,    namespace_id),
+               OPT_BYTE("uuid-index",   'U', &cfg.uuid_index,      uuid_index),
+               OPT_FMT("output-format", 'o', &cfg.output_format,   output_format),
+               OPT_FLAG("verbose",      'v', &cfg.verbose,         verbose),
+               OPT_END()
+       };
+
+       fd = parse_and_open(argc, argv, desc, opts);
+       if (fd < 0)
+               goto ret;
+
+       err = flags = validate_output_format(cfg.output_format);
+       if (flags < 0)
+               goto close_fd;
+
+       if (cfg.verbose)
+               flags |= VERBOSE;
+
+       if (!cfg.namespace_id) {
+               err = nvme_get_nsid(fd, &cfg.namespace_id);
+               if (err < 0) {
+                       perror("get-namespace-id");
+                       goto close_fd;
+               }
+       }
+
+       err = nvme_identify_ns(fd, cfg.namespace_id, &ns);
+       if (err) {
+               nvme_show_status(err);
+               goto close_fd;
+       }
+
+       err = nvme_identify_ns_csi(fd, cfg.namespace_id, cfg.uuid_index,
+                                                       NVME_CSI_NVM, &id_ns);
+       if (!err)
+               nvme_show_nvm_id_ns(&id_ns, cfg.namespace_id, &ns, flags);
+       else if (err > 0)
+               nvme_show_status(err);
+       else
+               perror("nvm identify namespace");
+close_fd:
+       close(fd);
+ret:
+       return nvme_status_to_errno(err, false);
+}
+
 static int ns_descs(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
        const char *desc = "Send Namespace Identification Descriptors command to the "\