summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2021-08-12 12:01:05 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2021-08-12 12:01:05 +0000
commitec3ece1465351c6208395b7f506728e9b918b05a (patch)
tree70c498b99e795bb0abafc7eb4207c515188025ff
parentAdding upstream version 1.14. (diff)
downloadnvme-cli-ec3ece1465351c6208395b7f506728e9b918b05a.tar.xz
nvme-cli-ec3ece1465351c6208395b7f506728e9b918b05a.zip
Adding upstream version 1.15.upstream/1.15
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
-rw-r--r--Documentation/nvme-admin-passthru.114
-rw-r--r--Documentation/nvme-admin-passthru.html26
-rw-r--r--Documentation/nvme-admin-passthru.txt5
-rw-r--r--Documentation/nvme-capacity-mgmt.171
-rw-r--r--Documentation/nvme-capacity-mgmt.html845
-rw-r--r--Documentation/nvme-capacity-mgmt.txt54
-rw-r--r--Documentation/nvme-compare.114
-rw-r--r--Documentation/nvme-compare.html27
-rw-r--r--Documentation/nvme-compare.txt6
-rw-r--r--Documentation/nvme-connect-all.txt10
-rw-r--r--Documentation/nvme-connect.txt17
-rw-r--r--Documentation/nvme-discover.txt20
-rw-r--r--Documentation/nvme-get-feature.126
-rw-r--r--Documentation/nvme-get-feature.html33
-rw-r--r--Documentation/nvme-get-feature.txt9
-rw-r--r--Documentation/nvme-get-lba-status.1134
-rw-r--r--Documentation/nvme-get-lba-status.html903
-rw-r--r--Documentation/nvme-get-lba-status.txt82
-rw-r--r--Documentation/nvme-get-log.140
-rw-r--r--Documentation/nvme-get-log.html53
-rw-r--r--Documentation/nvme-get-log.txt30
-rw-r--r--Documentation/nvme-id-domain.162
-rw-r--r--Documentation/nvme-id-domain.html819
-rw-r--r--Documentation/nvme-id-domain.txt40
-rw-r--r--Documentation/nvme-id-iocs.143
-rw-r--r--Documentation/nvme-id-iocs.html38
-rw-r--r--Documentation/nvme-id-iocs.txt17
-rw-r--r--Documentation/nvme-io-passthru.114
-rw-r--r--Documentation/nvme-io-passthru.html21
-rw-r--r--Documentation/nvme-io-passthru.txt5
-rw-r--r--Documentation/nvme-list-ctrl.118
-rw-r--r--Documentation/nvme-list-ctrl.html28
-rw-r--r--Documentation/nvme-list-ctrl.txt7
-rw-r--r--Documentation/nvme-list-ns.159
-rw-r--r--Documentation/nvme-list-ns.html37
-rw-r--r--Documentation/nvme-list-ns.txt19
-rw-r--r--Documentation/nvme-micron-smart-add-log.187
-rw-r--r--Documentation/nvme-micron-smart-add-log.html815
-rw-r--r--Documentation/nvme-micron-smart-add-log.txt54
-rw-r--r--Documentation/nvme-primary-ctrl-caps.1104
-rw-r--r--Documentation/nvme-primary-ctrl-caps.html842
-rw-r--r--Documentation/nvme-primary-ctrl-caps.txt53
-rw-r--r--Documentation/nvme-read.114
-rw-r--r--Documentation/nvme-read.html17
-rw-r--r--Documentation/nvme-read.txt6
-rw-r--r--Documentation/nvme-resv-register.12
-rw-r--r--Documentation/nvme-resv-register.html2
-rw-r--r--Documentation/nvme-resv-register.txt2
-rw-r--r--Documentation/nvme-set-feature.116
-rw-r--r--Documentation/nvme-set-feature.html27
-rw-r--r--Documentation/nvme-set-feature.txt7
-rw-r--r--Documentation/nvme-verify.1151
-rw-r--r--Documentation/nvme-verify.html961
-rw-r--r--Documentation/nvme-verify.txt93
-rw-r--r--Documentation/nvme-write-zeroes.134
-rw-r--r--Documentation/nvme-write-zeroes.html49
-rw-r--r--Documentation/nvme-write-zeroes.txt13
-rw-r--r--Documentation/nvme-write.114
-rw-r--r--Documentation/nvme-write.html17
-rw-r--r--Documentation/nvme-write.txt6
-rw-r--r--Documentation/nvme-zns-close-zone.112
-rw-r--r--Documentation/nvme-zns-finish-zone.112
-rw-r--r--Documentation/nvme-zns-offline-zone.112
-rw-r--r--Documentation/nvme-zns-open-zone.112
-rw-r--r--Documentation/nvme-zns-reset-zone.110
-rw-r--r--Documentation/nvme-zns-set-zone-desc.110
-rw-r--r--Documentation/nvme-zns-zone-mgmt-send.116
-rwxr-xr-xNVME-VERSION-GEN2
-rw-r--r--cmd_handler.h8
-rw-r--r--completions/_nvme46
-rw-r--r--completions/bash-nvme-completion.sh1240
-rw-r--r--etc/discovery.conf.in2
-rw-r--r--fabrics.c145
-rw-r--r--fabrics.h2
-rw-r--r--linux/nvme.h133
-rw-r--r--linux/nvme_ioctl.h16
-rw-r--r--nvme-builtin.h2
-rw-r--r--nvme-ioctl.c169
-rw-r--r--nvme-ioctl.h30
-rwxr-xr-xnvme-print.c642
-rw-r--r--nvme-print.h7
-rw-r--r--nvme-rpmb.c2
-rw-r--r--nvme-topology.c50
-rw-r--r--nvme.c1059
-rw-r--r--nvme.h9
-rw-r--r--nvmf-autoconnect/systemd/nvmf-autoconnect.service3
-rw-r--r--plugin.c2
-rw-r--r--plugin.h1
-rw-r--r--plugins/amzn/amzn-nvme.h2
-rw-r--r--plugins/dera/dera-nvme.h2
-rw-r--r--plugins/huawei/huawei-nvme.h2
-rw-r--r--plugins/intel/intel-nvme.c10
-rw-r--r--plugins/intel/intel-nvme.h2
-rw-r--r--plugins/lnvm/lnvm-nvme.h2
-rw-r--r--plugins/memblaze/memblaze-nvme.c12
-rw-r--r--plugins/memblaze/memblaze-nvme.h2
-rw-r--r--plugins/micron/micron-nvme.c473
-rw-r--r--plugins/micron/micron-nvme.h5
-rw-r--r--plugins/netapp/netapp-nvme.h2
-rw-r--r--plugins/nvidia/nvidia-nvme.h2
-rw-r--r--plugins/scaleflux/sfx-nvme.h2
-rw-r--r--plugins/seagate/seagate-nvme.c2
-rw-r--r--plugins/seagate/seagate-nvme.h2
-rw-r--r--plugins/shannon/shannon-nvme.c4
-rw-r--r--plugins/shannon/shannon-nvme.h2
-rw-r--r--plugins/toshiba/toshiba-nvme.c2
-rw-r--r--plugins/toshiba/toshiba-nvme.h2
-rw-r--r--plugins/transcend/transcend-nvme.h2
-rw-r--r--plugins/virtium/virtium-nvme.h2
-rw-r--r--plugins/wdc/wdc-nvme.c205
-rw-r--r--plugins/wdc/wdc-nvme.h3
-rw-r--r--plugins/wdc/wdc-utils.c4
-rw-r--r--plugins/ymtc/ymtc-nvme.h2
-rw-r--r--plugins/zns/zns.c66
-rw-r--r--plugins/zns/zns.h2
-rw-r--r--scripts/gen-hostnqn.sh18
116 files changed, 10369 insertions, 1153 deletions
diff --git a/Documentation/nvme-admin-passthru.1 b/Documentation/nvme-admin-passthru.1
index 286709f..8cf0095 100644
--- a/Documentation/nvme-admin-passthru.1
+++ b/Documentation/nvme-admin-passthru.1
@@ -1,13 +1,13 @@
'\" t
.\" Title: nvme-admin-passthru
-.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
-.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 10/20/2020
+.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 06/04/2021
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-ADMIN\-PASSTHR" "1" "10/20/2020" "NVMe" "NVMe Manual"
+.TH "NVME\-ADMIN\-PASSTHR" "1" "06/04/2021" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -46,6 +46,7 @@ nvme-admin-passthru \- Submit an arbitrary admin command, return results
[\-\-dry\-run | \-d]
[\-\-raw\-binary | \-b]
[\-\-prefill=<prefill> | \-p <prefill>]
+ [\-\-latency | \-T]
.fi
.SH "DESCRIPTION"
.sp
@@ -123,6 +124,11 @@ Print the raw returned buffer to stdout if the command returns a structure\&.
.RS 4
Prefill the buffer with a predetermined byte value\&. Defaults to 0\&. This may be useful if the data you are writing is shorter than the required buffer, and you need to pad it with a known value\&. It may also be useful if you need to confirm if a device is overwriting a buffer for a data\-in command\&.
.RE
+.PP
+\-T, \-\-latency
+.RS 4
+Print out the latency the IOCTL took (in us)\&.
+.RE
.SH "EXAMPLES"
.sp
.RS 4
diff --git a/Documentation/nvme-admin-passthru.html b/Documentation/nvme-admin-passthru.html
index 4a113ba..63a7a10 100644
--- a/Documentation/nvme-admin-passthru.html
+++ b/Documentation/nvme-admin-passthru.html
@@ -1,9 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
-<meta name="generator" content="AsciiDoc 8.6.8" />
+<meta name="generator" content="AsciiDoc 8.6.10" />
<title>nvme-admin-passthru(1)</title>
<style type="text/css">
/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
@@ -94,7 +95,9 @@ ul > li > * { color: black; }
padding: 0;
margin: 0;
}
-
+pre {
+ white-space: pre-wrap;
+}
#author {
color: #527bbd;
@@ -223,7 +226,7 @@ div.exampleblock > div.content {
}
div.imageblock div.content { padding-left: 0; }
-span.image img { border-style: none; }
+span.image img { border-style: none; vertical-align: text-bottom; }
a.image:visited { color: white; }
dl {
@@ -759,7 +762,8 @@ nvme-admin-passthru(1) Manual Page
[--show-command | -s]
[--dry-run | -d]
[--raw-binary | -b]
- [--prefill=&lt;prefill&gt; | -p &lt;prefill&gt;]</pre>
+ [--prefill=&lt;prefill&gt; | -p &lt;prefill&gt;]
+ [--latency | -T]</pre>
<div class="attribution">
</div></div>
</div>
@@ -941,6 +945,17 @@ printed to stdout for another program to parse.</p></div>
is overwriting a buffer for a data-in command.
</p>
</dd>
+<dt class="hdlist1">
+-T
+</dt>
+<dt class="hdlist1">
+--latency
+</dt>
+<dd>
+<p>
+ Print out the latency the IOCTL took (in us).
+</p>
+</dd>
</dl></div>
</div>
</div>
@@ -982,7 +997,8 @@ Or if you want to save that structure to a file:
<div id="footnotes"><hr /></div>
<div id="footer">
<div id="footer-text">
-Last updated 2019-09-06 10:35:44 MDT
+Last updated
+ 2021-06-04 10:59:04 IST
</div>
</div>
</body>
diff --git a/Documentation/nvme-admin-passthru.txt b/Documentation/nvme-admin-passthru.txt
index f2bff2e..ce452fa 100644
--- a/Documentation/nvme-admin-passthru.txt
+++ b/Documentation/nvme-admin-passthru.txt
@@ -22,6 +22,7 @@ SYNOPSIS
[--dry-run | -d]
[--raw-binary | -b]
[--prefill=<prefill> | -p <prefill>]
+ [--latency | -T]
DESCRIPTION
-----------
@@ -105,6 +106,10 @@ OPTIONS
value. It may also be useful if you need to confirm if a device
is overwriting a buffer for a data-in command.
+-T::
+--latency::
+ Print out the latency the IOCTL took (in us).
+
EXAMPLES
--------
* The following will run the admin command with opcode=6 and cdw10=1, which
diff --git a/Documentation/nvme-capacity-mgmt.1 b/Documentation/nvme-capacity-mgmt.1
new file mode 100644
index 0000000..b27dd2c
--- /dev/null
+++ b/Documentation/nvme-capacity-mgmt.1
@@ -0,0 +1,71 @@
+'\" t
+.\" Title: nvme-capacity-mgmt
+.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 07/02/2021
+.\" Manual: NVMe Manual
+.\" Source: NVMe
+.\" Language: English
+.\"
+.TH "NVME\-CAPACITY\-MGMT" "1" "07/02/2021" "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-capacity-mgmt \- Send capacity management command to configure/create/delete Endurance Groups or NVM Sets, returns results\&.
+.SH "SYNOPSIS"
+.sp
+.nf
+\fInvme capacity\-mgmt\fR <device> [\-\-operation=<operation> | \-o <operation>]
+ [\-\-element\-id=<element\-id> | \-i <element\-id>]
+ [\-\-cap\-lower=<cap\-lower> | \-l <cap\-lower>]
+ [\-\-cap\-upper=<cap\-upper> | \-u <cap\-upper>]
+.fi
+.SH "DESCRIPTION"
+.sp
+For the NVMe device given, sends a capacity management command to configure/create/delete the Endurance Groups or NVM Sets with the requested operation and element_id\&. On success, if the Operation is Create Endurance group or NVM Set, CQE CDW0 contains Created element identifier else CQE CDW0 is reserved\&.
+.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)\&.
+.SH "OPTIONS"
+.PP
+\-o <operation>, \-\-operation=<operation>
+.RS 4
+Operation to be performed by the controller
+.RE
+.PP
+\-i <element\-id>, \-\-element\-id=<element\-id>
+.RS 4
+Value specific to the value of the Operation field\&.
+.RE
+.PP
+\-l <cap\-lower>, \-\-cap\-lower=<cap\-lower>
+.RS 4
+Least significant 32 bits of the capacity in bytes of the Endurance Group or NVM Set to be created
+.RE
+.PP
+\-u <cap\-upper>, \-\-cap\-upper=<cap\-upper>
+.RS 4
+Most significant 32 bits of the capacity in bytes of the Endurance Group or NVM Set to be created
+.RE
+.SH "EXAMPLES"
+.sp
+No examples provided yet\&.
+.SH "NVME"
+.sp
+Part of the nvme\-user suite
diff --git a/Documentation/nvme-capacity-mgmt.html b/Documentation/nvme-capacity-mgmt.html
new file mode 100644
index 0000000..aeb0fbc
--- /dev/null
+++ b/Documentation/nvme-capacity-mgmt.html
@@ -0,0 +1,845 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+ "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
+<meta name="generator" content="AsciiDoc 8.6.10" />
+<title>nvme-capacity-mgmt(1)</title>
+<style type="text/css">
+/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
+
+/* Default font. */
+body {
+ font-family: Georgia,serif;
+}
+
+/* Title font. */
+h1, h2, h3, h4, h5, h6,
+div.title, caption.title,
+thead, p.table.header,
+#toctitle,
+#author, #revnumber, #revdate, #revremark,
+#footer {
+ font-family: Arial,Helvetica,sans-serif;
+}
+
+body {
+ margin: 1em 5% 1em 5%;
+}
+
+a {
+ color: blue;
+ text-decoration: underline;
+}
+a:visited {
+ color: fuchsia;
+}
+
+em {
+ font-style: italic;
+ color: navy;
+}
+
+strong {
+ font-weight: bold;
+ color: #083194;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ color: #527bbd;
+ margin-top: 1.2em;
+ margin-bottom: 0.5em;
+ line-height: 1.3;
+}
+
+h1, h2, h3 {
+ border-bottom: 2px solid silver;
+}
+h2 {
+ padding-top: 0.5em;
+}
+h3 {
+ float: left;
+}
+h3 + * {
+ clear: left;
+}
+h5 {
+ font-size: 1.0em;
+}
+
+div.sectionbody {
+ margin-left: 0;
+}
+
+hr {
+ border: 1px solid silver;
+}
+
+p {
+ margin-top: 0.5em;
+ margin-bottom: 0.5em;
+}
+
+ul, ol, li > p {
+ margin-top: 0;
+}
+ul > li { color: #aaa; }
+ul > li > * { color: black; }
+
+.monospaced, code, pre {
+ font-family: "Courier New", Courier, monospace;
+ font-size: inherit;
+ color: navy;
+ padding: 0;
+ margin: 0;
+}
+pre {
+ white-space: pre-wrap;
+}
+
+#author {
+ color: #527bbd;
+ font-weight: bold;
+ font-size: 1.1em;
+}
+#email {
+}
+#revnumber, #revdate, #revremark {
+}
+
+#footer {
+ font-size: small;
+ border-top: 2px solid silver;
+ padding-top: 0.5em;
+ margin-top: 4.0em;
+}
+#footer-text {
+ float: left;
+ padding-bottom: 0.5em;
+}
+#footer-badges {
+ float: right;
+ padding-bottom: 0.5em;
+}
+
+#preamble {
+ margin-top: 1.5em;
+ margin-bottom: 1.5em;
+}
+div.imageblock, div.exampleblock, div.verseblock,
+div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
+div.admonitionblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+div.admonitionblock {
+ margin-top: 2.0em;
+ margin-bottom: 2.0em;
+ margin-right: 10%;
+ color: #606060;
+}
+
+div.content { /* Block element content. */
+ padding: 0;
+}
+
+/* Block element titles. */
+div.title, caption.title {
+ color: #527bbd;
+ font-weight: bold;
+ text-align: left;
+ margin-top: 1.0em;
+ margin-bottom: 0.5em;
+}
+div.title + * {
+ margin-top: 0;
+}
+
+td div.title:first-child {
+ margin-top: 0.0em;
+}
+div.content div.title:first-child {
+ margin-top: 0.0em;
+}
+div.content + div.title {
+ margin-top: 0.0em;
+}
+
+div.sidebarblock > div.content {
+ background: #ffffee;
+ border: 1px solid #dddddd;
+ border-left: 4px solid #f0f0f0;
+ padding: 0.5em;
+}
+
+div.listingblock > div.content {
+ border: 1px solid #dddddd;
+ border-left: 5px solid #f0f0f0;
+ background: #f8f8f8;
+ padding: 0.5em;
+}
+
+div.quoteblock, div.verseblock {
+ padding-left: 1.0em;
+ margin-left: 1.0em;
+ margin-right: 10%;
+ border-left: 5px solid #f0f0f0;
+ color: #888;
+}
+
+div.quoteblock > div.attribution {
+ padding-top: 0.5em;
+ text-align: right;
+}
+
+div.verseblock > pre.content {
+ font-family: inherit;
+ font-size: inherit;
+}
+div.verseblock > div.attribution {
+ padding-top: 0.75em;
+ text-align: left;
+}
+/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
+div.verseblock + div.attribution {
+ text-align: left;
+}
+
+div.admonitionblock .icon {
+ vertical-align: top;
+ font-size: 1.1em;
+ font-weight: bold;
+ text-decoration: underline;
+ color: #527bbd;
+ padding-right: 0.5em;
+}
+div.admonitionblock td.content {
+ padding-left: 0.5em;
+ border-left: 3px solid #dddddd;
+}
+
+div.exampleblock > div.content {
+ border-left: 3px solid #dddddd;
+ padding-left: 0.5em;
+}
+
+div.imageblock div.content { padding-left: 0; }
+span.image img { border-style: none; vertical-align: text-bottom; }
+a.image:visited { color: white; }
+
+dl {
+ margin-top: 0.8em;
+ margin-bottom: 0.8em;
+}
+dt {
+ margin-top: 0.5em;
+ margin-bottom: 0;
+ font-style: normal;
+ color: navy;
+}
+dd > *:first-child {
+ margin-top: 0.1em;
+}
+
+ul, ol {
+ list-style-position: outside;
+}
+ol.arabic {
+ list-style-type: decimal;
+}
+ol.loweralpha {
+ list-style-type: lower-alpha;
+}
+ol.upperalpha {
+ list-style-type: upper-alpha;
+}
+ol.lowerroman {
+ list-style-type: lower-roman;
+}
+ol.upperroman {
+ list-style-type: upper-roman;
+}
+
+div.compact ul, div.compact ol,
+div.compact p, div.compact p,
+div.compact div, div.compact div {
+ margin-top: 0.1em;
+ margin-bottom: 0.1em;
+}
+
+tfoot {
+ font-weight: bold;
+}
+td > div.verse {
+ white-space: pre;
+}
+
+div.hdlist {
+ margin-top: 0.8em;
+ margin-bottom: 0.8em;
+}
+div.hdlist tr {
+ padding-bottom: 15px;
+}
+dt.hdlist1.strong, td.hdlist1.strong {
+ font-weight: bold;
+}
+td.hdlist1 {
+ vertical-align: top;
+ font-style: normal;
+ padding-right: 0.8em;
+ color: navy;
+}
+td.hdlist2 {
+ vertical-align: top;
+}
+div.hdlist.compact tr {
+ margin: 0;
+ padding-bottom: 0;
+}
+
+.comment {
+ background: yellow;
+}
+
+.footnote, .footnoteref {
+ font-size: 0.8em;
+}
+
+span.footnote, span.footnoteref {
+ vertical-align: super;
+}
+
+#footnotes {
+ margin: 20px 0 20px 0;
+ padding: 7px 0 0 0;
+}
+
+#footnotes div.footnote {
+ margin: 0 0 5px 0;
+}
+
+#footnotes hr {
+ border: none;
+ border-top: 1px solid silver;
+ height: 1px;
+ text-align: left;
+ margin-left: 0;
+ width: 20%;
+ min-width: 100px;
+}
+
+div.colist td {
+ padding-right: 0.5em;
+ padding-bottom: 0.3em;
+ vertical-align: top;
+}
+div.colist td img {
+ margin-top: 0.3em;
+}
+
+@media print {
+ #footer-badges { display: none; }
+}
+
+#toc {
+ margin-bottom: 2.5em;
+}
+
+#toctitle {
+ color: #527bbd;
+ font-size: 1.1em;
+ font-weight: bold;
+ margin-top: 1.0em;
+ margin-bottom: 0.1em;
+}
+
+div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+div.toclevel2 {
+ margin-left: 2em;
+ font-size: 0.9em;
+}
+div.toclevel3 {
+ margin-left: 4em;
+ font-size: 0.9em;
+}
+div.toclevel4 {
+ margin-left: 6em;
+ font-size: 0.9em;
+}
+
+span.aqua { color: aqua; }
+span.black { color: black; }
+span.blue { color: blue; }
+span.fuchsia { color: fuchsia; }
+span.gray { color: gray; }
+span.green { color: green; }
+span.lime { color: lime; }
+span.maroon { color: maroon; }
+span.navy { color: navy; }
+span.olive { color: olive; }
+span.purple { color: purple; }
+span.red { color: red; }
+span.silver { color: silver; }
+span.teal { color: teal; }
+span.white { color: white; }
+span.yellow { color: yellow; }
+
+span.aqua-background { background: aqua; }
+span.black-background { background: black; }
+span.blue-background { background: blue; }
+span.fuchsia-background { background: fuchsia; }
+span.gray-background { background: gray; }
+span.green-background { background: green; }
+span.lime-background { background: lime; }
+span.maroon-background { background: maroon; }
+span.navy-background { background: navy; }
+span.olive-background { background: olive; }
+span.purple-background { background: purple; }
+span.red-background { background: red; }
+span.silver-background { background: silver; }
+span.teal-background { background: teal; }
+span.white-background { background: white; }
+span.yellow-background { background: yellow; }
+
+span.big { font-size: 2em; }
+span.small { font-size: 0.6em; }
+
+span.underline { text-decoration: underline; }
+span.overline { text-decoration: overline; }
+span.line-through { text-decoration: line-through; }
+
+div.unbreakable { page-break-inside: avoid; }
+
+
+/*
+ * xhtml11 specific
+ *
+ * */
+
+div.tableblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+div.tableblock > table {
+ border: 3px solid #527bbd;
+}
+thead, p.table.header {
+ font-weight: bold;
+ color: #527bbd;
+}
+p.table {
+ margin-top: 0;
+}
+/* Because the table frame attribute is overriden by CSS in most browsers. */
+div.tableblock > table[frame="void"] {
+ border-style: none;
+}
+div.tableblock > table[frame="hsides"] {
+ border-left-style: none;
+ border-right-style: none;
+}
+div.tableblock > table[frame="vsides"] {
+ border-top-style: none;
+ border-bottom-style: none;
+}
+
+
+/*
+ * html5 specific
+ *
+ * */
+
+table.tableblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+thead, p.tableblock.header {
+ font-weight: bold;
+ color: #527bbd;
+}
+p.tableblock {
+ margin-top: 0;
+}
+table.tableblock {
+ border-width: 3px;
+ border-spacing: 0px;
+ border-style: solid;
+ border-color: #527bbd;
+ border-collapse: collapse;
+}
+th.tableblock, td.tableblock {
+ border-width: 1px;
+ padding: 4px;
+ border-style: solid;
+ border-color: #527bbd;
+}
+
+table.tableblock.frame-topbot {
+ border-left-style: hidden;
+ border-right-style: hidden;
+}
+table.tableblock.frame-sides {
+ border-top-style: hidden;
+ border-bottom-style: hidden;
+}
+table.tableblock.frame-none {
+ border-style: hidden;
+}
+
+th.tableblock.halign-left, td.tableblock.halign-left {
+ text-align: left;
+}
+th.tableblock.halign-center, td.tableblock.halign-center {
+ text-align: center;
+}
+th.tableblock.halign-right, td.tableblock.halign-right {
+ text-align: right;
+}
+
+th.tableblock.valign-top, td.tableblock.valign-top {
+ vertical-align: top;
+}
+th.tableblock.valign-middle, td.tableblock.valign-middle {
+ vertical-align: middle;
+}
+th.tableblock.valign-bottom, td.tableblock.valign-bottom {
+ vertical-align: bottom;
+}
+
+
+/*
+ * manpage specific
+ *
+ * */
+
+body.manpage h1 {
+ padding-top: 0.5em;
+ padding-bottom: 0.5em;
+ border-top: 2px solid silver;
+ border-bottom: 2px solid silver;
+}
+body.manpage h2 {
+ border-style: none;
+}
+body.manpage div.sectionbody {
+ margin-left: 3em;
+}
+
+@media print {
+ body.manpage div#toc { display: none; }
+}
+
+
+</style>
+<script type="text/javascript">
+/*<![CDATA[*/
+var asciidoc = { // Namespace.
+
+/////////////////////////////////////////////////////////////////////
+// Table Of Contents generator
+/////////////////////////////////////////////////////////////////////
+
+/* Author: Mihai Bazon, September 2002
+ * http://students.infoiasi.ro/~mishoo
+ *
+ * Table Of Content generator
+ * Version: 0.4
+ *
+ * Feel free to use this script under the terms of the GNU General Public
+ * License, as long as you do not remove or alter this notice.
+ */
+
+ /* modified by Troy D. Hanson, September 2006. License: GPL */
+ /* modified by Stuart Rackham, 2006, 2009. License: GPL */
+
+// toclevels = 1..4.
+toc: function (toclevels) {
+
+ function getText(el) {
+ var text = "";
+ for (var i = el.firstChild; i != null; i = i.nextSibling) {
+ if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
+ text += i.data;
+ else if (i.firstChild != null)
+ text += getText(i);
+ }
+ return text;
+ }
+
+ function TocEntry(el, text, toclevel) {
+ this.element = el;
+ this.text = text;
+ this.toclevel = toclevel;
+ }
+
+ function tocEntries(el, toclevels) {
+ var result = new Array;
+ var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
+ // Function that scans the DOM tree for header elements (the DOM2
+ // nodeIterator API would be a better technique but not supported by all
+ // browsers).
+ var iterate = function (el) {
+ for (var i = el.firstChild; i != null; i = i.nextSibling) {
+ if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
+ var mo = re.exec(i.tagName);
+ if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
+ result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
+ }
+ iterate(i);
+ }
+ }
+ }
+ iterate(el);
+ return result;
+ }
+
+ var toc = document.getElementById("toc");
+ if (!toc) {
+ return;
+ }
+
+ // Delete existing TOC entries in case we're reloading the TOC.
+ var tocEntriesToRemove = [];
+ var i;
+ for (i = 0; i < toc.childNodes.length; i++) {
+ var entry = toc.childNodes[i];
+ if (entry.nodeName.toLowerCase() == 'div'
+ && entry.getAttribute("class")
+ && entry.getAttribute("class").match(/^toclevel/))
+ tocEntriesToRemove.push(entry);
+ }
+ for (i = 0; i < tocEntriesToRemove.length; i++) {
+ toc.removeChild(tocEntriesToRemove[i]);
+ }
+
+ // Rebuild TOC entries.
+ var entries = tocEntries(document.getElementById("content"), toclevels);
+ for (var i = 0; i < entries.length; ++i) {
+ var entry = entries[i];
+ if (entry.element.id == "")
+ entry.element.id = "_toc_" + i;
+ var a = document.createElement("a");
+ a.href = "#" + entry.element.id;
+ a.appendChild(document.createTextNode(entry.text));
+ var div = document.createElement("div");
+ div.appendChild(a);
+ div.className = "toclevel" + entry.toclevel;
+ toc.appendChild(div);
+ }
+ if (entries.length == 0)
+ toc.parentNode.removeChild(toc);
+},
+
+
+/////////////////////////////////////////////////////////////////////
+// Footnotes generator
+/////////////////////////////////////////////////////////////////////
+
+/* Based on footnote generation code from:
+ * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
+ */
+
+footnotes: function () {
+ // Delete existing footnote entries in case we're reloading the footnodes.
+ var i;
+ var noteholder = document.getElementById("footnotes");
+ if (!noteholder) {
+ return;
+ }
+ var entriesToRemove = [];
+ for (i = 0; i < noteholder.childNodes.length; i++) {
+ var entry = noteholder.childNodes[i];
+ if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
+ entriesToRemove.push(entry);
+ }
+ for (i = 0; i < entriesToRemove.length; i++) {
+ noteholder.removeChild(entriesToRemove[i]);
+ }
+
+ // Rebuild footnote entries.
+ var cont = document.getElementById("content");
+ var spans = cont.getElementsByTagName("span");
+ var refs = {};
+ var n = 0;
+ for (i=0; i<spans.length; i++) {
+ if (spans[i].className == "footnote") {
+ n++;
+ var note = spans[i].getAttribute("data-note");
+ if (!note) {
+ // Use [\s\S] in place of . so multi-line matches work.
+ // Because JavaScript has no s (dotall) regex flag.
+ note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
+ spans[i].innerHTML =
+ "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
+ "' title='View footnote' class='footnote'>" + n + "</a>]";
+ spans[i].setAttribute("data-note", note);
+ }
+ noteholder.innerHTML +=
+ "<div class='footnote' id='_footnote_" + n + "'>" +
+ "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
+ n + "</a>. " + note + "</div>";
+ var id =spans[i].getAttribute("id");
+ if (id != null) refs["#"+id] = n;
+ }
+ }
+ if (n == 0)
+ noteholder.parentNode.removeChild(noteholder);
+ else {
+ // Process footnoterefs.
+ for (i=0; i<spans.length; i++) {
+ if (spans[i].className == "footnoteref") {
+ var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
+ href = href.match(/#.*/)[0]; // Because IE return full URL.
+ n = refs[href];
+ spans[i].innerHTML =
+ "[<a href='#_footnote_" + n +
+ "' title='View footnote' class='footnote'>" + n + "</a>]";
+ }
+ }
+ }
+},
+
+install: function(toclevels) {
+ var timerId;
+
+ function reinstall() {
+ asciidoc.footnotes();
+ if (toclevels) {
+ asciidoc.toc(toclevels);
+ }
+ }
+
+ function reinstallAndRemoveTimer() {
+ clearInterval(timerId);
+ reinstall();
+ }
+
+ timerId = setInterval(reinstall, 500);
+ if (document.addEventListener)
+ document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
+ else
+ window.onload = reinstallAndRemoveTimer;
+}
+
+}
+asciidoc.install();
+/*]]>*/
+</script>
+</head>
+<body class="manpage">
+<div id="header">
+<h1>
+nvme-capacity-mgmt(1) Manual Page
+</h1>
+<h2>NAME</h2>
+<div class="sectionbody">
+<p>nvme-capacity-mgmt -
+ Send capacity management command to configure/create/delete Endurance Groups or NVM Sets, returns results.
+</p>
+</div>
+</div>
+<div id="content">
+<div class="sect1">
+<h2 id="_synopsis">SYNOPSIS</h2>
+<div class="sectionbody">
+<div class="verseblock">
+<pre class="content"><em>nvme capacity-mgmt</em> &lt;device&gt; [--operation=&lt;operation&gt; | -o &lt;operation&gt;]
+ [--element-id=&lt;element-id&gt; | -i &lt;element-id&gt;]
+ [--cap-lower=&lt;cap-lower&gt; | -l &lt;cap-lower&gt;]
+ [--cap-upper=&lt;cap-upper&gt; | -u &lt;cap-upper&gt;]</pre>
+<div class="attribution">
+</div></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_description">DESCRIPTION</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>For the NVMe device given, sends a capacity management command to configure/create/delete
+the Endurance Groups or NVM Sets with the requested operation and element_id. On success,
+if the Operation is Create Endurance group or NVM Set, CQE CDW0 contains Created element
+identifier else CQE CDW0 is reserved.</p></div>
+<div class="paragraph"><p>The &lt;device&gt; parameter is mandatory and may be either the NVMe character
+device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1).</p></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_options">OPTIONS</h2>
+<div class="sectionbody">
+<div class="dlist"><dl>
+<dt class="hdlist1">
+-o &lt;operation&gt;
+</dt>
+<dt class="hdlist1">
+--operation=&lt;operation&gt;
+</dt>
+<dd>
+<p>
+ Operation to be performed by the controller
+</p>
+</dd>
+<dt class="hdlist1">
+-i &lt;element-id&gt;
+</dt>
+<dt class="hdlist1">
+--element-id=&lt;element-id&gt;
+</dt>
+<dd>
+<p>
+ Value specific to the value of the Operation field.
+</p>
+</dd>
+<dt class="hdlist1">
+-l &lt;cap-lower&gt;
+</dt>
+<dt class="hdlist1">
+--cap-lower=&lt;cap-lower&gt;
+</dt>
+<dd>
+<p>
+ Least significant 32 bits of the capacity in bytes of the Endurance Group or
+ NVM Set to be created
+</p>
+</dd>
+<dt class="hdlist1">
+-u &lt;cap-upper&gt;
+</dt>
+<dt class="hdlist1">
+--cap-upper=&lt;cap-upper&gt;
+</dt>
+<dd>
+<p>
+ Most significant 32 bits of the capacity in bytes of the Endurance Group or
+ NVM Set to be created
+</p>
+</dd>
+</dl></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_examples">EXAMPLES</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>No examples provided yet.</p></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_nvme">NVME</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Part of the nvme-user suite</p></div>
+</div>
+</div>
+</div>
+<div id="footnotes"><hr /></div>
+<div id="footer">
+<div id="footer-text">
+Last updated
+ 2021-07-02 09:55:05 IST
+</div>
+</div>
+</body>
+</html>
diff --git a/Documentation/nvme-capacity-mgmt.txt b/Documentation/nvme-capacity-mgmt.txt
new file mode 100644
index 0000000..96274cf
--- /dev/null
+++ b/Documentation/nvme-capacity-mgmt.txt
@@ -0,0 +1,54 @@
+nvme-capacity-mgmt(1)
+=====================
+
+NAME
+----
+nvme-capacity-mgmt - Send capacity management command to configure/create/delete
+ Endurance Groups or NVM Sets, returns results.
+
+SYNOPSIS
+--------
+[verse]
+'nvme capacity-mgmt' <device> [--operation=<operation> | -o <operation>]
+ [--element-id=<element-id> | -i <element-id>]
+ [--cap-lower=<cap-lower> | -l <cap-lower>]
+ [--cap-upper=<cap-upper> | -u <cap-upper>]
+
+DESCRIPTION
+-----------
+For the NVMe device given, sends a capacity management command to
+configure/create/delete the Endurance Groups or NVM Sets with the requested
+operation and element_id. On success, if the Operation is Create Endurance
+group or NVM Set, CQE CDW0 contains Created element identifier else CQE CDW0 is
+reserved.
+
+The <device> parameter is mandatory and may be either the NVMe character
+device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1).
+
+OPTIONS
+-------
+-o <operation>::
+--operation=<operation>::
+ Operation to be performed by the controller
+
+-i <element-id>::
+--element-id=<element-id>::
+ Value specific to the value of the Operation field.
+
+-l <cap-lower>::
+--cap-lower=<cap-lower>::
+ Least significant 32 bits of the capacity in bytes of the Endurance Group or
+ NVM Set to be created
+
+-u <cap-upper>::
+--cap-upper=<cap-upper>::
+ Most significant 32 bits of the capacity in bytes of the Endurance Group or
+ NVM Set to be created
+
+EXAMPLES
+--------
+No examples provided yet.
+
+NVME
+----
+Part of the nvme-user suite \ No newline at end of file
diff --git a/Documentation/nvme-compare.1 b/Documentation/nvme-compare.1
index 0638190..ada1790 100644
--- a/Documentation/nvme-compare.1
+++ b/Documentation/nvme-compare.1
@@ -1,13 +1,13 @@
'\" t
.\" Title: nvme-compare
-.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
-.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 10/20/2020
+.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 07/09/2021
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-COMPARE" "1" "10/20/2020" "NVMe" "NVMe Manual"
+.TH "NVME\-COMPARE" "1" "07/09/2021" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -50,6 +50,7 @@ nvme-compare \- Send an NVMe Compare command, provide results
[\-\-show\-command | \-v]
[\-\-dry\-run | \-w]
[\-\-latency | \-t]
+ [\-\-storage\-tag\-check<storage\-tag\-check> | \-C <storage\-tag\-check>]
.fi
.SH "DESCRIPTION"
.sp
@@ -202,6 +203,11 @@ be set\&. Otherwise \-\-dry\-run option will be
.RS 4
Print out the latency the IOCTL took (in us)\&.
.RE
+.PP
+\-\-storage\-tag\-check=<storage\-tag\-check>, \-C <storage\-tag\-check>
+.RS 4
+This bit specifies the Storage Tag field shall be checked as part of end\-to\-end data protection processing\&.
+.RE
.SH "EXAMPLES"
.sp
No examples yet\&.
diff --git a/Documentation/nvme-compare.html b/Documentation/nvme-compare.html
index e3b6857..0c13e32 100644
--- a/Documentation/nvme-compare.html
+++ b/Documentation/nvme-compare.html
@@ -1,9 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
-<meta name="generator" content="AsciiDoc 8.6.8" />
+<meta name="generator" content="AsciiDoc 8.6.10" />
<title>nvme-compare(1)</title>
<style type="text/css">
/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
@@ -94,7 +95,9 @@ ul > li > * { color: black; }
padding: 0;
margin: 0;
}
-
+pre {
+ white-space: pre-wrap;
+}
#author {
color: #527bbd;
@@ -223,7 +226,7 @@ div.exampleblock > div.content {
}
div.imageblock div.content { padding-left: 0; }
-span.image img { border-style: none; }
+span.image img { border-style: none; vertical-align: text-bottom; }
a.image:visited { color: white; }
dl {
@@ -763,7 +766,8 @@ nvme-compare(1) Manual Page
[--dsm=&lt;dsm&gt; | -D &lt;dsm&gt;]
[--show-command | -v]
[--dry-run | -w]
- [--latency | -t]</pre>
+ [--latency | -t]
+ [--storage-tag-check&lt;storage-tag-check&gt; | -C &lt;storage-tag-check&gt;]</pre>
<div class="attribution">
</div></div>
</div>
@@ -1037,6 +1041,18 @@ metadata is passes.</p></td>
Print out the latency the IOCTL took (in us).
</p>
</dd>
+<dt class="hdlist1">
+--storage-tag-check=&lt;storage-tag-check&gt;
+</dt>
+<dt class="hdlist1">
+-C &lt;storage-tag-check&gt;
+</dt>
+<dd>
+<p>
+ This bit specifies the Storage Tag field shall be checked as part of end-to-end
+ data protection processing.
+</p>
+</dd>
</dl></div>
</div>
</div>
@@ -1056,7 +1072,8 @@ metadata is passes.</p></td>
<div id="footnotes"><hr /></div>
<div id="footer">
<div id="footer-text">
-Last updated 2018-12-17 13:07:47 MST
+Last updated
+ 2021-07-09 14:16:50 IST
</div>
</div>
</body>
diff --git a/Documentation/nvme-compare.txt b/Documentation/nvme-compare.txt
index 9185c5f..b6f8863 100644
--- a/Documentation/nvme-compare.txt
+++ b/Documentation/nvme-compare.txt
@@ -26,6 +26,7 @@ SYNOPSIS
[--show-command | -v]
[--dry-run | -w]
[--latency | -t]
+ [--storage-tag-check<storage-tag-check> | -C <storage-tag-check>]
DESCRIPTION
-----------
@@ -139,6 +140,11 @@ metadata is passes.
--latency::
Print out the latency the IOCTL took (in us).
+--storage-tag-check=<storage-tag-check>::
+-C <storage-tag-check>::
+ This bit specifies the Storage Tag field shall be checked as part of end-to-end
+ data protection processing.
+
EXAMPLES
--------
No examples yet.
diff --git a/Documentation/nvme-connect-all.txt b/Documentation/nvme-connect-all.txt
index 820dd6c..1cb7822 100644
--- a/Documentation/nvme-connect-all.txt
+++ b/Documentation/nvme-connect-all.txt
@@ -13,6 +13,7 @@ SYNOPSIS
[--traddr=<traddr> | -a <traddr>]
[--trsvcid=<trsvcid> | -s <trsvcid>]
[--host-traddr=<traddr> | -w <traddr>]
+ [--host-iface=<iface> | -f <iface>]
[--hostnqn=<hostnqn> | -q <hostnqn>]
[--hostid=<hostid> | -I <hostid>]
[--raw=<filename> | -r <filename>]
@@ -77,7 +78,14 @@ OPTIONS
-w <traddr>::
--host-traddr=<traddr>::
This field specifies the network address used on the host to connect
- to the Discovery Controller.
+ to the Controller. For TCP, this sets the source address on the socket.
+
+-f <iface>::
+--host-iface=<iface>::
+ This field specifies the network interface used on the host to connect
+ to the Controller (e.g. IP eth1, enp2s0, enx78e7d1ea46da). This forces
+ the connection to be made on a specific interface instead of letting
+ the system decide.
-q <hostnqn>::
--hostnqn=<hostnqn>::
diff --git a/Documentation/nvme-connect.txt b/Documentation/nvme-connect.txt
index 757e3d0..dd31cd3 100644
--- a/Documentation/nvme-connect.txt
+++ b/Documentation/nvme-connect.txt
@@ -14,6 +14,7 @@ SYNOPSIS
[--traddr=<traddr> | -a <traddr>]
[--trsvcid=<trsvcid> | -s <trsvcid>]
[--host-traddr=<traddr> | -w <traddr>]
+ [--host-iface=<iface> | -f <iface>]
[--hostnqn=<hostnqn> | -q <hostnqn>]
[--hostid=<hostid> | -I <hostid>]
[--nr-io-queues=<#> | -i <#>]
@@ -27,6 +28,7 @@ SYNOPSIS
[--disable-sqflow | -d]
[--hdr-digest | -g]
[--data-digest | -G]
+ [--output-format=<fmt> | -o <fmt>]
DESCRIPTION
-----------
@@ -69,7 +71,14 @@ OPTIONS
-w <traddr>::
--host-traddr=<traddr>::
This field specifies the network address used on the host to connect
- to the Controller.
+ to the Controller. For TCP, this sets the source address on the socket.
+
+-f <iface>::
+--host-iface=<iface>::
+ This field specifies the network interface used on the host to connect
+ to the Controller (e.g. IP eth1, enp2s0, enx78e7d1ea46da). This forces
+ the connection to be made on a specific interface instead of letting
+ the system decide.
-q <hostnqn>::
--hostnqn=<hostnqn>::
@@ -132,6 +141,12 @@ OPTIONS
--data-digest::
Generates/verifies data digest (TCP).
+-o <format>::
+--output-format=<format>::
+ Set the reporting format to 'normal' or 'json'. Only one output format can
+ be used at a time. When this option is specified, the device associated with
+ the connection will be printed. Nothing is printed otherwise.
+
EXAMPLES
--------
* Connect to a subsystem named nqn.2014-08.com.example:nvme:nvm-subsystem-sn-d78432
diff --git a/Documentation/nvme-discover.txt b/Documentation/nvme-discover.txt
index 74add74..d0a281a 100644
--- a/Documentation/nvme-discover.txt
+++ b/Documentation/nvme-discover.txt
@@ -13,6 +13,7 @@ SYNOPSIS
[--traddr=<traddr> | -a <traddr>]
[--trsvcid=<trsvcid> | -s <trsvcid>]
[--host-traddr=<traddr> | -w <traddr>]
+ [--host-iface=<iface> | -f <iface>]
[--hostnqn=<hostnqn> | -q <hostnqn>]
[--hostid=<hostid> | -I <hostid>]
[--raw=<filename> | -r <filename>]
@@ -35,7 +36,7 @@ DESCRIPTION
Send one or more Get Log Page requests to a NVMe-over-Fabrics Discovery
Controller.
-If no parameters are given, then 'nvme discover' will attempt to
+If no parameters are given, then 'nvme discover' will attempt to
find a /etc/nvme/discovery.conf file to use to supply a list of
Discovery commands to run. If no /etc/nvme/discovery.conf file
exists, the command will quit with an error.
@@ -46,7 +47,7 @@ request will then be sent to the specified Discovery Controller.
BACKGROUND
----------
-The NVMe-over-Fabrics specification defines the concept of a
+The NVMe-over-Fabrics specification defines the concept of a
Discovery Controller that an NVMe Host can query on a fabric
network to discover NVMe subsystems contained in NVMe Targets
which it can connect to on the network. The Discovery Controller
@@ -66,7 +67,7 @@ resources are allocated to the NVMe Host for a connection.
A Discovery Controller has it's own NQN defined in the NVMe-over-Fabrics
specification, *nqn.2014-08.org.nvmexpress.discovery*. All Discovery
Controllers must use this NQN name. This NQN is used by default by
-nvme-cli for the 'discover' command.
+nvme-cli for the 'discover' command.
OPTIONS
-------
@@ -99,11 +100,18 @@ OPTIONS
-w <traddr>::
--host-traddr=<traddr>::
This field specifies the network address used on the host to connect
- to the Discovery Controller.
-
+ to the Controller. For TCP, this sets the source address on the socket.
+
+-f <iface>::
+--host-iface=<iface>::
+ This field specifies the network interface used on the host to connect
+ to the Controller (e.g. IP eth1, enp2s0, enx78e7d1ea46da). This forces
+ the connection to be made on a specific interface instead of letting
+ the system decide.
+
-q <hostnqn>::
--hostnqn=<hostnqn>::
- Overrides the default host NQN that identifies the NVMe Host.
+ Overrides the default host NQN that identifies the NVMe Host.
If this option is not specified, the default is read from
/etc/nvme/hostnqn first. If that does not exist, the autogenerated
NQN value from the NVMe Host kernel module is used next.
diff --git a/Documentation/nvme-get-feature.1 b/Documentation/nvme-get-feature.1
index 399d1d2..d7cc726 100644
--- a/Documentation/nvme-get-feature.1
+++ b/Documentation/nvme-get-feature.1
@@ -1,13 +1,13 @@
'\" t
.\" Title: nvme-get-feature
-.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
-.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 10/20/2020
+.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 05/16/2021
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-GET\-FEATURE" "1" "10/20/2020" "NVMe" "NVMe Manual"
+.TH "NVME\-GET\-FEATURE" "1" "05/16/2021" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -34,6 +34,7 @@ nvme-get-feature \- Gets an NVMe feature, returns applicable results
.nf
\fInvme get\-feature\fR <device> [\-\-namespace\-id=<nsid> | \-n <nsid>]
[\-\-feature\-id=<fid> | \-f <fid>] [\-\-cdw11=<cdw11>]
+ [\-\-uuid\-index=<uuid\-index> | \-U <uuid_index>]
[\-\-data\-len=<data\-len> | \-l <data\-len>]
[\-\-sel=<select> | \-s <select>]
[\-\-raw\-binary | \-b]
@@ -103,6 +104,11 @@ T}
.sp 1
.RE
.PP
+\-U <uuid\-index>, \-\-uuid\-index=<uuid\-index>
+.RS 4
+UUID Index of the feature
+.RE
+.PP
\-l <data\-len>, \-\-data\-len=<data\-len>
.RS 4
The data length for the buffer returned for this feature\&. Most known features do not use this value\&. The exception is LBA Range Type
@@ -185,8 +191,20 @@ Retrieves the feature for the some vendor specific feature and specifically requ
.if n \{\
.RE
.\}
+.sp
+Get feature with UUID index
.RE
.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+# nvme get\-feature /dev/nvme0 \-f 0xc0 \-l 512 \-U 0x1
+.fi
+.if n \{\
+.RE
+.\}
+.sp
.RS 4
.ie n \{\
\h'-04'\(bu\h'+03'\c
diff --git a/Documentation/nvme-get-feature.html b/Documentation/nvme-get-feature.html
index 19c2444..62f54bd 100644
--- a/Documentation/nvme-get-feature.html
+++ b/Documentation/nvme-get-feature.html
@@ -1,9 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
-<meta name="generator" content="AsciiDoc 8.6.8" />
+<meta name="generator" content="AsciiDoc 8.6.10" />
<title>nvme-get-feature(1)</title>
<style type="text/css">
/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
@@ -94,7 +95,9 @@ ul > li > * { color: black; }
padding: 0;
margin: 0;
}
-
+pre {
+ white-space: pre-wrap;
+}
#author {
color: #527bbd;
@@ -223,7 +226,7 @@ div.exampleblock > div.content {
}
div.imageblock div.content { padding-left: 0; }
-span.image img { border-style: none; }
+span.image img { border-style: none; vertical-align: text-bottom; }
a.image:visited { color: white; }
dl {
@@ -433,7 +436,7 @@ thead, p.table.header {
p.table {
margin-top: 0;
}
-/* Because the table frame attribute is overridden by CSS in most browsers. */
+/* Because the table frame attribute is overriden by CSS in most browsers. */
div.tableblock > table[frame="void"] {
border-style: none;
}
@@ -748,6 +751,7 @@ nvme-get-feature(1) Manual Page
<div class="verseblock">
<pre class="content"><em>nvme get-feature</em> &lt;device&gt; [--namespace-id=&lt;nsid&gt; | -n &lt;nsid&gt;]
[--feature-id=&lt;fid&gt; | -f &lt;fid&gt;] [--cdw11=&lt;cdw11&gt;]
+ [--uuid-index=&lt;uuid-index&gt; | -U &lt;uuid_index&gt;]
[--data-len=&lt;data-len&gt; | -l &lt;data-len&gt;]
[--sel=&lt;select&gt; | -s &lt;select&gt;]
[--raw-binary | -b]
@@ -847,6 +851,17 @@ cellspacing="0" cellpadding="4">
</div>
</dd>
<dt class="hdlist1">
+-U &lt;uuid-index&gt;
+</dt>
+<dt class="hdlist1">
+--uuid-index=&lt;uuid-index&gt;
+</dt>
+<dd>
+<p>
+ UUID Index of the feature
+</p>
+</dd>
+<dt class="hdlist1">
-l &lt;data-len&gt;
</dt>
<dt class="hdlist1">
@@ -928,7 +943,14 @@ will be displayed to the user in as a hex dump:
<div class="content">
<pre><code># nvme get-feature /dev/nvme0 -f 0xc0 -l 512</code></pre>
</div></div>
+<div class="paragraph"><p>Get feature with UUID index</p></div>
</li>
+</ul></div>
+<div class="listingblock">
+<div class="content">
+<pre><code># nvme get-feature /dev/nvme0 -f 0xc0 -l 512 -U 0x1</code></pre>
+</div></div>
+<div class="ulist"><ul>
<li>
<p>
The following retrieves the feature for the LBA Range Type, which
@@ -954,7 +976,8 @@ format:
<div id="footnotes"><hr /></div>
<div id="footer">
<div id="footer-text">
-Last updated 2018-02-07 09:54:27 MST
+Last updated
+ 2021-05-16 00:13:16 IST
</div>
</div>
</body>
diff --git a/Documentation/nvme-get-feature.txt b/Documentation/nvme-get-feature.txt
index 56542dc..a6f57a7 100644
--- a/Documentation/nvme-get-feature.txt
+++ b/Documentation/nvme-get-feature.txt
@@ -10,6 +10,7 @@ SYNOPSIS
[verse]
'nvme get-feature' <device> [--namespace-id=<nsid> | -n <nsid>]
[--feature-id=<fid> | -f <fid>] [--cdw11=<cdw11>]
+ [--uuid-index=<uuid-index> | -U <uuid_index>]
[--data-len=<data-len> | -l <data-len>]
[--sel=<select> | -s <select>]
[--raw-binary | -b]
@@ -57,6 +58,10 @@ OPTIONS
|4–7|Reserved
|==================
+-U <uuid-index>::
+--uuid-index=<uuid-index>::
+ UUID Index of the feature
+
-l <data-len>::
--data-len=<data-len>::
The data length for the buffer returned for this feature. Most
@@ -102,6 +107,10 @@ will be displayed to the user in as a hex dump:
# nvme get-feature /dev/nvme0 -f 0xc0 -l 512
------------
+
+Get feature with UUID index
+------------
+# nvme get-feature /dev/nvme0 -f 0xc0 -l 512 -U 0x1
+------------
* The following retrieves the feature for the LBA Range Type, which
implicitly requires a buffer and will be saved to a file in its raw
diff --git a/Documentation/nvme-get-lba-status.1 b/Documentation/nvme-get-lba-status.1
new file mode 100644
index 0000000..6c78929
--- /dev/null
+++ b/Documentation/nvme-get-lba-status.1
@@ -0,0 +1,134 @@
+'\" t
+.\" Title: nvme-get-lba-status
+.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 05/11/2021
+.\" Manual: NVMe Manual
+.\" Source: NVMe
+.\" Language: English
+.\"
+.TH "NVME\-GET\-LBA\-STAT" "1" "05/11/2021" "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-get-lba-status \- Get LBA Status from NVMe device
+.SH "SYNOPSIS"
+.sp
+.nf
+\fInvme get\-lba\-status\fR <device> [\-\-namespace\-id=<nsid> | \-n <nsid>]
+ [\-\-start\-lba=<slba> | \-s <slba>]
+ [\-\-max\-dw=<max\-dw> | \-m <max\-dw>]
+ [\-\-action=<action\-type> | \-a <action\-type>]
+ [\-\-range\-len=<range\-len> | \-l <range\-len>]
+ [\-\-timeout=<timeout> | \-t <timeout> ]
+ [\-\-output\-format=<format> | \-o <format>]
+.fi
+.SH "DESCRIPTION"
+.sp
+For the NVMe device given, send an nvme Get LBA Status admin command and provides the results\&.
+.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 returned get lba data structure may be returned in one of several ways depending on the option flags; the structure may parsed by the program and printed in a readable format or the raw buffer may be printed to stdout for another program to parse\&.
+.SH "OPTIONS"
+.PP
+\-n <nsid>, \-\-namespace\-id=<nsid>
+.RS 4
+Send the Get LBA Status command for the specified nsid\&. This can be used to override the default value for either character device (unspecified) or the block device (result from NVME_IOCTL_ID)\&.
+.RE
+.PP
+\-s <slba>, \-\-start\-lba=<slba>
+.RS 4
+Starting LBA(SLBA) in 64\-bit address of the first logical block addressed
+.RE
+.PP
+\-m <max\-dw>, \-\-max\-dw=<max\-dw>
+.RS 4
+Maximum Number of Dwords(MNDW) specifies maximum number of dwords to return
+.RE
+.PP
+\-a <action\-type>, \-\-action=<action\-type>
+.RS 4
+Action Type(ATYPE) specifies the mechanism it uses in determining the LBA Status Descriptors\&.
+.RE
+.PP
+\-l <range\-len>, \-\-range\-len=<range\-len>
+.RS 4
+Range Length(RL) specifies the length of the range of contiguous LBAs beginning at SLBA
+.RE
+.PP
+\-t <timeout>, \-\-timeout=<timeout>
+.RS 4
+Override default timeout value\&. In milliseconds\&.
+.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
+.\}
+Get the LBA Status of the device using all defaults:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+# nvme get\-lba\-status /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
+.\}
+Get LBA Status of the namespace 1 from SLBA 10 for the max Dwords of 0x1000
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+# nvme get\-lba\-status /dev/nvme0 \-\-namespace\-id=1 \-\-start\-lba=10 \-\-max\-dw=0x1000
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.SH "NVME"
+.sp
+Part of the nvme\-user suite
diff --git a/Documentation/nvme-get-lba-status.html b/Documentation/nvme-get-lba-status.html
new file mode 100644
index 0000000..35aba2a
--- /dev/null
+++ b/Documentation/nvme-get-lba-status.html
@@ -0,0 +1,903 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+ "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
+<meta name="generator" content="AsciiDoc 8.6.10" />
+<title>nvme-get-lba-status(1)</title>
+<style type="text/css">
+/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
+
+/* Default font. */
+body {
+ font-family: Georgia,serif;
+}
+
+/* Title font. */
+h1, h2, h3, h4, h5, h6,
+div.title, caption.title,
+thead, p.table.header,
+#toctitle,
+#author, #revnumber, #revdate, #revremark,
+#footer {
+ font-family: Arial,Helvetica,sans-serif;
+}
+
+body {
+ margin: 1em 5% 1em 5%;
+}
+
+a {
+ color: blue;
+ text-decoration: underline;
+}
+a:visited {
+ color: fuchsia;
+}
+
+em {
+ font-style: italic;
+ color: navy;
+}
+
+strong {
+ font-weight: bold;
+ color: #083194;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ color: #527bbd;
+ margin-top: 1.2em;
+ margin-bottom: 0.5em;
+ line-height: 1.3;
+}
+
+h1, h2, h3 {
+ border-bottom: 2px solid silver;
+}
+h2 {
+ padding-top: 0.5em;
+}
+h3 {
+ float: left;
+}
+h3 + * {
+ clear: left;
+}
+h5 {
+ font-size: 1.0em;
+}
+
+div.sectionbody {
+ margin-left: 0;
+}
+
+hr {
+ border: 1px solid silver;
+}
+
+p {
+ margin-top: 0.5em;
+ margin-bottom: 0.5em;
+}
+
+ul, ol, li > p {
+ margin-top: 0;
+}
+ul > li { color: #aaa; }
+ul > li > * { color: black; }
+
+.monospaced, code, pre {
+ font-family: "Courier New", Courier, monospace;
+ font-size: inherit;
+ color: navy;
+ padding: 0;
+ margin: 0;
+}
+pre {
+ white-space: pre-wrap;
+}
+
+#author {
+ color: #527bbd;
+ font-weight: bold;
+ font-size: 1.1em;
+}
+#email {
+}
+#revnumber, #revdate, #revremark {
+}
+
+#footer {
+ font-size: small;
+ border-top: 2px solid silver;
+ padding-top: 0.5em;
+ margin-top: 4.0em;
+}
+#footer-text {
+ float: left;
+ padding-bottom: 0.5em;
+}
+#footer-badges {
+ float: right;
+ padding-bottom: 0.5em;
+}
+
+#preamble {
+ margin-top: 1.5em;
+ margin-bottom: 1.5em;
+}
+div.imageblock, div.exampleblock, div.verseblock,
+div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
+div.admonitionblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+div.admonitionblock {
+ margin-top: 2.0em;
+ margin-bottom: 2.0em;
+ margin-right: 10%;
+ color: #606060;
+}
+
+div.content { /* Block element content. */
+ padding: 0;
+}
+
+/* Block element titles. */
+div.title, caption.title {
+ color: #527bbd;
+ font-weight: bold;
+ text-align: left;
+ margin-top: 1.0em;
+ margin-bottom: 0.5em;
+}
+div.title + * {
+ margin-top: 0;
+}
+
+td div.title:first-child {
+ margin-top: 0.0em;
+}
+div.content div.title:first-child {
+ margin-top: 0.0em;
+}
+div.content + div.title {
+ margin-top: 0.0em;
+}
+
+div.sidebarblock > div.content {
+ background: #ffffee;
+ border: 1px solid #dddddd;
+ border-left: 4px solid #f0f0f0;
+ padding: 0.5em;
+}
+
+div.listingblock > div.content {
+ border: 1px solid #dddddd;
+ border-left: 5px solid #f0f0f0;
+ background: #f8f8f8;
+ padding: 0.5em;
+}
+
+div.quoteblock, div.verseblock {
+ padding-left: 1.0em;
+ margin-left: 1.0em;
+ margin-right: 10%;
+ border-left: 5px solid #f0f0f0;
+ color: #888;
+}
+
+div.quoteblock > div.attribution {
+ padding-top: 0.5em;
+ text-align: right;
+}
+
+div.verseblock > pre.content {
+ font-family: inherit;
+ font-size: inherit;
+}
+div.verseblock > div.attribution {
+ padding-top: 0.75em;
+ text-align: left;
+}
+/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
+div.verseblock + div.attribution {
+ text-align: left;
+}
+
+div.admonitionblock .icon {
+ vertical-align: top;
+ font-size: 1.1em;
+ font-weight: bold;
+ text-decoration: underline;
+ color: #527bbd;
+ padding-right: 0.5em;
+}
+div.admonitionblock td.content {
+ padding-left: 0.5em;
+ border-left: 3px solid #dddddd;
+}
+
+div.exampleblock > div.content {
+ border-left: 3px solid #dddddd;
+ padding-left: 0.5em;
+}
+
+div.imageblock div.content { padding-left: 0; }
+span.image img { border-style: none; vertical-align: text-bottom; }
+a.image:visited { color: white; }
+
+dl {
+ margin-top: 0.8em;
+ margin-bottom: 0.8em;
+}
+dt {
+ margin-top: 0.5em;
+ margin-bottom: 0;
+ font-style: normal;
+ color: navy;
+}
+dd > *:first-child {
+ margin-top: 0.1em;
+}
+
+ul, ol {
+ list-style-position: outside;
+}
+ol.arabic {
+ list-style-type: decimal;
+}
+ol.loweralpha {
+ list-style-type: lower-alpha;
+}
+ol.upperalpha {
+ list-style-type: upper-alpha;
+}
+ol.lowerroman {
+ list-style-type: lower-roman;
+}
+ol.upperroman {
+ list-style-type: upper-roman;
+}
+
+div.compact ul, div.compact ol,
+div.compact p, div.compact p,
+div.compact div, div.compact div {
+ margin-top: 0.1em;
+ margin-bottom: 0.1em;
+}
+
+tfoot {
+ font-weight: bold;
+}
+td > div.verse {
+ white-space: pre;
+}
+
+div.hdlist {
+ margin-top: 0.8em;
+ margin-bottom: 0.8em;
+}
+div.hdlist tr {
+ padding-bottom: 15px;
+}
+dt.hdlist1.strong, td.hdlist1.strong {
+ font-weight: bold;
+}
+td.hdlist1 {
+ vertical-align: top;
+ font-style: normal;
+ padding-right: 0.8em;
+ color: navy;
+}
+td.hdlist2 {
+ vertical-align: top;
+}
+div.hdlist.compact tr {
+ margin: 0;
+ padding-bottom: 0;
+}
+
+.comment {
+ background: yellow;
+}
+
+.footnote, .footnoteref {
+ font-size: 0.8em;
+}
+
+span.footnote, span.footnoteref {
+ vertical-align: super;
+}
+
+#footnotes {
+ margin: 20px 0 20px 0;
+ padding: 7px 0 0 0;
+}
+
+#footnotes div.footnote {
+ margin: 0 0 5px 0;
+}
+
+#footnotes hr {
+ border: none;
+ border-top: 1px solid silver;
+ height: 1px;
+ text-align: left;
+ margin-left: 0;
+ width: 20%;
+ min-width: 100px;
+}
+
+div.colist td {
+ padding-right: 0.5em;
+ padding-bottom: 0.3em;
+ vertical-align: top;
+}
+div.colist td img {
+ margin-top: 0.3em;
+}
+
+@media print {
+ #footer-badges { display: none; }
+}
+
+#toc {
+ margin-bottom: 2.5em;
+}
+
+#toctitle {
+ color: #527bbd;
+ font-size: 1.1em;
+ font-weight: bold;
+ margin-top: 1.0em;
+ margin-bottom: 0.1em;
+}
+
+div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+div.toclevel2 {
+ margin-left: 2em;
+ font-size: 0.9em;
+}
+div.toclevel3 {
+ margin-left: 4em;
+ font-size: 0.9em;
+}
+div.toclevel4 {
+ margin-left: 6em;
+ font-size: 0.9em;
+}
+
+span.aqua { color: aqua; }
+span.black { color: black; }
+span.blue { color: blue; }
+span.fuchsia { color: fuchsia; }
+span.gray { color: gray; }
+span.green { color: green; }
+span.lime { color: lime; }
+span.maroon { color: maroon; }
+span.navy { color: navy; }
+span.olive { color: olive; }
+span.purple { color: purple; }
+span.red { color: red; }
+span.silver { color: silver; }
+span.teal { color: teal; }
+span.white { color: white; }
+span.yellow { color: yellow; }
+
+span.aqua-background { background: aqua; }
+span.black-background { background: black; }
+span.blue-background { background: blue; }
+span.fuchsia-background { background: fuchsia; }
+span.gray-background { background: gray; }
+span.green-background { background: green; }
+span.lime-background { background: lime; }
+span.maroon-background { background: maroon; }
+span.navy-background { background: navy; }
+span.olive-background { background: olive; }
+span.purple-background { background: purple; }
+span.red-background { background: red; }
+span.silver-background { background: silver; }
+span.teal-background { background: teal; }
+span.white-background { background: white; }
+span.yellow-background { background: yellow; }
+
+span.big { font-size: 2em; }
+span.small { font-size: 0.6em; }
+
+span.underline { text-decoration: underline; }
+span.overline { text-decoration: overline; }
+span.line-through { text-decoration: line-through; }
+
+div.unbreakable { page-break-inside: avoid; }
+
+
+/*
+ * xhtml11 specific
+ *
+ * */
+
+div.tableblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+div.tableblock > table {
+ border: 3px solid #527bbd;
+}
+thead, p.table.header {
+ font-weight: bold;
+ color: #527bbd;
+}
+p.table {
+ margin-top: 0;
+}
+/* Because the table frame attribute is overriden by CSS in most browsers. */
+div.tableblock > table[frame="void"] {
+ border-style: none;
+}
+div.tableblock > table[frame="hsides"] {
+ border-left-style: none;
+ border-right-style: none;
+}
+div.tableblock > table[frame="vsides"] {
+ border-top-style: none;
+ border-bottom-style: none;
+}
+
+
+/*
+ * html5 specific
+ *
+ * */
+
+table.tableblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+thead, p.tableblock.header {
+ font-weight: bold;
+ color: #527bbd;
+}
+p.tableblock {
+ margin-top: 0;
+}
+table.tableblock {
+ border-width: 3px;
+ border-spacing: 0px;
+ border-style: solid;
+ border-color: #527bbd;
+ border-collapse: collapse;
+}
+th.tableblock, td.tableblock {
+ border-width: 1px;
+ padding: 4px;
+ border-style: solid;
+ border-color: #527bbd;
+}
+
+table.tableblock.frame-topbot {
+ border-left-style: hidden;
+ border-right-style: hidden;
+}
+table.tableblock.frame-sides {
+ border-top-style: hidden;
+ border-bottom-style: hidden;
+}
+table.tableblock.frame-none {
+ border-style: hidden;
+}
+
+th.tableblock.halign-left, td.tableblock.halign-left {
+ text-align: left;
+}
+th.tableblock.halign-center, td.tableblock.halign-center {
+ text-align: center;
+}
+th.tableblock.halign-right, td.tableblock.halign-right {
+ text-align: right;
+}
+
+th.tableblock.valign-top, td.tableblock.valign-top {
+ vertical-align: top;
+}
+th.tableblock.valign-middle, td.tableblock.valign-middle {
+ vertical-align: middle;
+}
+th.tableblock.valign-bottom, td.tableblock.valign-bottom {
+ vertical-align: bottom;
+}
+
+
+/*
+ * manpage specific
+ *
+ * */
+
+body.manpage h1 {
+ padding-top: 0.5em;
+ padding-bottom: 0.5em;
+ border-top: 2px solid silver;
+ border-bottom: 2px solid silver;
+}
+body.manpage h2 {
+ border-style: none;
+}
+body.manpage div.sectionbody {
+ margin-left: 3em;
+}
+
+@media print {
+ body.manpage div#toc { display: none; }
+}
+
+
+</style>
+<script type="text/javascript">
+/*<![CDATA[*/
+var asciidoc = { // Namespace.
+
+/////////////////////////////////////////////////////////////////////
+// Table Of Contents generator
+/////////////////////////////////////////////////////////////////////
+
+/* Author: Mihai Bazon, September 2002
+ * http://students.infoiasi.ro/~mishoo
+ *
+ * Table Of Content generator
+ * Version: 0.4
+ *
+ * Feel free to use this script under the terms of the GNU General Public
+ * License, as long as you do not remove or alter this notice.
+ */
+
+ /* modified by Troy D. Hanson, September 2006. License: GPL */
+ /* modified by Stuart Rackham, 2006, 2009. License: GPL */
+
+// toclevels = 1..4.
+toc: function (toclevels) {
+
+ function getText(el) {
+ var text = "";
+ for (var i = el.firstChild; i != null; i = i.nextSibling) {
+ if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
+ text += i.data;
+ else if (i.firstChild != null)
+ text += getText(i);
+ }
+ return text;
+ }
+
+ function TocEntry(el, text, toclevel) {
+ this.element = el;
+ this.text = text;
+ this.toclevel = toclevel;
+ }
+
+ function tocEntries(el, toclevels) {
+ var result = new Array;
+ var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
+ // Function that scans the DOM tree for header elements (the DOM2
+ // nodeIterator API would be a better technique but not supported by all
+ // browsers).
+ var iterate = function (el) {
+ for (var i = el.firstChild; i != null; i = i.nextSibling) {
+ if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
+ var mo = re.exec(i.tagName);
+ if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
+ result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
+ }
+ iterate(i);
+ }
+ }
+ }
+ iterate(el);
+ return result;
+ }
+
+ var toc = document.getElementById("toc");
+ if (!toc) {
+ return;
+ }
+
+ // Delete existing TOC entries in case we're reloading the TOC.
+ var tocEntriesToRemove = [];
+ var i;
+ for (i = 0; i < toc.childNodes.length; i++) {
+ var entry = toc.childNodes[i];
+ if (entry.nodeName.toLowerCase() == 'div'
+ && entry.getAttribute("class")
+ && entry.getAttribute("class").match(/^toclevel/))
+ tocEntriesToRemove.push(entry);
+ }
+ for (i = 0; i < tocEntriesToRemove.length; i++) {
+ toc.removeChild(tocEntriesToRemove[i]);
+ }
+
+ // Rebuild TOC entries.
+ var entries = tocEntries(document.getElementById("content"), toclevels);
+ for (var i = 0; i < entries.length; ++i) {
+ var entry = entries[i];
+ if (entry.element.id == "")
+ entry.element.id = "_toc_" + i;
+ var a = document.createElement("a");
+ a.href = "#" + entry.element.id;
+ a.appendChild(document.createTextNode(entry.text));
+ var div = document.createElement("div");
+ div.appendChild(a);
+ div.className = "toclevel" + entry.toclevel;
+ toc.appendChild(div);
+ }
+ if (entries.length == 0)
+ toc.parentNode.removeChild(toc);
+},
+
+
+/////////////////////////////////////////////////////////////////////
+// Footnotes generator
+/////////////////////////////////////////////////////////////////////
+
+/* Based on footnote generation code from:
+ * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
+ */
+
+footnotes: function () {
+ // Delete existing footnote entries in case we're reloading the footnodes.
+ var i;
+ var noteholder = document.getElementById("footnotes");
+ if (!noteholder) {
+ return;
+ }
+ var entriesToRemove = [];
+ for (i = 0; i < noteholder.childNodes.length; i++) {
+ var entry = noteholder.childNodes[i];
+ if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
+ entriesToRemove.push(entry);
+ }
+ for (i = 0; i < entriesToRemove.length; i++) {
+ noteholder.removeChild(entriesToRemove[i]);
+ }
+
+ // Rebuild footnote entries.
+ var cont = document.getElementById("content");
+ var spans = cont.getElementsByTagName("span");
+ var refs = {};
+ var n = 0;
+ for (i=0; i<spans.length; i++) {
+ if (spans[i].className == "footnote") {
+ n++;
+ var note = spans[i].getAttribute("data-note");
+ if (!note) {
+ // Use [\s\S] in place of . so multi-line matches work.
+ // Because JavaScript has no s (dotall) regex flag.
+ note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
+ spans[i].innerHTML =
+ "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
+ "' title='View footnote' class='footnote'>" + n + "</a>]";
+ spans[i].setAttribute("data-note", note);
+ }
+ noteholder.innerHTML +=
+ "<div class='footnote' id='_footnote_" + n + "'>" +
+ "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
+ n + "</a>. " + note + "</div>";
+ var id =spans[i].getAttribute("id");
+ if (id != null) refs["#"+id] = n;
+ }
+ }
+ if (n == 0)
+ noteholder.parentNode.removeChild(noteholder);
+ else {
+ // Process footnoterefs.
+ for (i=0; i<spans.length; i++) {
+ if (spans[i].className == "footnoteref") {
+ var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
+ href = href.match(/#.*/)[0]; // Because IE return full URL.
+ n = refs[href];
+ spans[i].innerHTML =
+ "[<a href='#_footnote_" + n +
+ "' title='View footnote' class='footnote'>" + n + "</a>]";
+ }
+ }
+ }
+},
+
+install: function(toclevels) {
+ var timerId;
+
+ function reinstall() {
+ asciidoc.footnotes();
+ if (toclevels) {
+ asciidoc.toc(toclevels);
+ }
+ }
+
+ function reinstallAndRemoveTimer() {
+ clearInterval(timerId);
+ reinstall();
+ }
+
+ timerId = setInterval(reinstall, 500);
+ if (document.addEventListener)
+ document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
+ else
+ window.onload = reinstallAndRemoveTimer;
+}
+
+}
+asciidoc.install();
+/*]]>*/
+</script>
+</head>
+<body class="manpage">
+<div id="header">
+<h1>
+nvme-get-lba-status(1) Manual Page
+</h1>
+<h2>NAME</h2>
+<div class="sectionbody">
+<p>nvme-get-lba-status -
+ Get LBA Status from NVMe device
+</p>
+</div>
+</div>
+<div id="content">
+<div class="sect1">
+<h2 id="_synopsis">SYNOPSIS</h2>
+<div class="sectionbody">
+<div class="verseblock">
+<pre class="content"><em>nvme get-lba-status</em> &lt;device&gt; [--namespace-id=&lt;nsid&gt; | -n &lt;nsid&gt;]
+ [--start-lba=&lt;slba&gt; | -s &lt;slba&gt;]
+ [--max-dw=&lt;max-dw&gt; | -m &lt;max-dw&gt;]
+ [--action=&lt;action-type&gt; | -a &lt;action-type&gt;]
+ [--range-len=&lt;range-len&gt; | -l &lt;range-len&gt;]
+ [--timeout=&lt;timeout&gt; | -t &lt;timeout&gt; ]
+ [--output-format=&lt;format&gt; | -o &lt;format&gt;]</pre>
+<div class="attribution">
+</div></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_description">DESCRIPTION</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>For the NVMe device given, send an nvme Get LBA Status admin command
+and provides the results.</p></div>
+<div class="paragraph"><p>The &lt;device&gt; parameter is mandatory and may be either the NVMe character
+device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1).</p></div>
+<div class="paragraph"><p>On success, the returned get lba data structure may be returned in one of
+several ways depending on the option flags; the structure may parsed by
+the program and printed in a readable format or the raw buffer may be
+printed to stdout for another program to parse.</p></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_options">OPTIONS</h2>
+<div class="sectionbody">
+<div class="dlist"><dl>
+<dt class="hdlist1">
+-n &lt;nsid&gt;
+</dt>
+<dt class="hdlist1">
+--namespace-id=&lt;nsid&gt;
+</dt>
+<dd>
+<p>
+ Send the Get LBA Status command for the specified nsid. This can be
+ used to override the default value for either character device
+ (unspecified) or the block device (result from NVME_IOCTL_ID).
+</p>
+</dd>
+<dt class="hdlist1">
+-s &lt;slba&gt;
+</dt>
+<dt class="hdlist1">
+--start-lba=&lt;slba&gt;
+</dt>
+<dd>
+<p>
+ Starting LBA(SLBA) in 64-bit address of the first logical block addressed
+</p>
+</dd>
+<dt class="hdlist1">
+-m &lt;max-dw&gt;
+</dt>
+<dt class="hdlist1">
+--max-dw=&lt;max-dw&gt;
+</dt>
+<dd>
+<p>
+ Maximum Number of Dwords(MNDW) specifies maximum number of dwords to return
+</p>
+</dd>
+<dt class="hdlist1">
+-a &lt;action-type&gt;
+</dt>
+<dt class="hdlist1">
+--action=&lt;action-type&gt;
+</dt>
+<dd>
+<p>
+ Action Type(ATYPE) specifies the mechanism it uses in determining the LBA Status Descriptors.
+</p>
+</dd>
+<dt class="hdlist1">
+-l &lt;range-len&gt;
+</dt>
+<dt class="hdlist1">
+--range-len=&lt;range-len&gt;
+</dt>
+<dd>
+<p>
+ Range Length(RL) specifies the length of the range of contiguous LBAs beginning at SLBA
+</p>
+</dd>
+<dt class="hdlist1">
+-t &lt;timeout&gt;
+</dt>
+<dt class="hdlist1">
+--timeout=&lt;timeout&gt;
+</dt>
+<dd>
+<p>
+ Override default timeout value. In milliseconds.
+</p>
+</dd>
+<dt class="hdlist1">
+-o &lt;format&gt;
+</dt>
+<dt class="hdlist1">
+--output-format=&lt;format&gt;
+</dt>
+<dd>
+<p>
+ Set the reporting format to <em>normal</em>, <em>json</em>, or
+ <em>binary</em>. Only one output format can be used at a time.
+</p>
+</dd>
+</dl></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_examples">EXAMPLES</h2>
+<div class="sectionbody">
+<div class="ulist"><ul>
+<li>
+<p>
+Get the LBA Status of the device using all defaults:
+</p>
+<div class="listingblock">
+<div class="content">
+<pre><code># nvme get-lba-status /dev/nvme0n1</code></pre>
+</div></div>
+</li>
+<li>
+<p>
+Get LBA Status of the namespace 1 from SLBA 10 for the max Dwords of 0x1000
+</p>
+<div class="listingblock">
+<div class="content">
+<pre><code># nvme get-lba-status /dev/nvme0 --namespace-id=1 --start-lba=10 --max-dw=0x1000</code></pre>
+</div></div>
+</li>
+</ul></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_nvme">NVME</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Part of the nvme-user suite</p></div>
+</div>
+</div>
+</div>
+<div id="footnotes"><hr /></div>
+<div id="footer">
+<div id="footer-text">
+Last updated
+ 2021-05-11 11:28:04 IST
+</div>
+</div>
+</body>
+</html>
diff --git a/Documentation/nvme-get-lba-status.txt b/Documentation/nvme-get-lba-status.txt
new file mode 100644
index 0000000..157dc41
--- /dev/null
+++ b/Documentation/nvme-get-lba-status.txt
@@ -0,0 +1,82 @@
+nvme-get-lba-status(1)
+======================
+
+NAME
+----
+nvme-get-lba-status - Get LBA Status from NVMe device
+
+SYNOPSIS
+--------
+[verse]
+'nvme get-lba-status' <device> [--namespace-id=<nsid> | -n <nsid>]
+ [--start-lba=<slba> | -s <slba>]
+ [--max-dw=<max-dw> | -m <max-dw>]
+ [--action=<action-type> | -a <action-type>]
+ [--range-len=<range-len> | -l <range-len>]
+ [--timeout=<timeout> | -t <timeout> ]
+ [--output-format=<format> | -o <format>]
+
+DESCRIPTION
+-----------
+For the NVMe device given, send an nvme Get LBA Status admin command
+and provides the results.
+
+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 returned get lba data structure may be returned in one of
+several ways depending on the option flags; the structure may parsed by
+the program and printed in a readable format or the raw buffer may be
+printed to stdout for another program to parse.
+
+OPTIONS
+-------
+-n <nsid>::
+--namespace-id=<nsid>::
+ Send the Get LBA Status command for the specified nsid. This can be
+ used to override the default value for either character device
+ (unspecified) or the block device (result from NVME_IOCTL_ID).
+
+-s <slba>::
+--start-lba=<slba>::
+ Starting LBA(SLBA) in 64-bit address of the first logical block addressed
+
+-m <max-dw>::
+--max-dw=<max-dw>::
+ Maximum Number of Dwords(MNDW) specifies maximum number of dwords to return
+
+-a <action-type>::
+--action=<action-type>::
+ Action Type(ATYPE) specifies the mechanism it uses in determining the LBA Status Descriptors.
+
+-l <range-len>::
+--range-len=<range-len>::
+ Range Length(RL) specifies the length of the range of contiguous LBAs beginning at SLBA
+
+-t <timeout>::
+--timeout=<timeout>::
+ Override default timeout value. In milliseconds.
+
+-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
+--------
+* Get the LBA Status of the device using all defaults:
++
+------------
+# nvme get-lba-status /dev/nvme0n1
+------------
++
+
+* Get LBA Status of the namespace 1 from SLBA 10 for the max Dwords of 0x1000
++
+------------
+# nvme get-lba-status /dev/nvme0 --namespace-id=1 --start-lba=10 --max-dw=0x1000
+------------
+
+NVME
+----
+Part of the nvme-user suite
diff --git a/Documentation/nvme-get-log.1 b/Documentation/nvme-get-log.1
index 98f81a8..ccc5ab8 100644
--- a/Documentation/nvme-get-log.1
+++ b/Documentation/nvme-get-log.1
@@ -1,13 +1,13 @@
'\" t
.\" Title: nvme-get-log
-.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
-.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 10/20/2020
+.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 06/12/2021
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-GET\-LOG" "1" "10/20/2020" "NVMe" "NVMe Manual"
+.TH "NVME\-GET\-LOG" "1" "06/12/2021" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -33,13 +33,16 @@ nvme-get-log \- Retrieves a log page from an NVMe device
.sp
.nf
\fInvme get\-log\fR <device> [\-\-log\-id=<log\-id> | \-i <log\-id>]
- [\-\-log\-len=<log\-len> | \-l <log\-len>]
- [\-\-aen=<aen> | \-a <aen>]
- [\-\-namespace\-id=<nsid> | \-n <nsid>]
- [\-\-raw\-binary | \-b]
- [\-\-lpo=<offset> | \-o <offset>]
- [\-\-lsp=<field> | \-s <field>]
- [\-\-rae | \-r]
+ [\-\-log\-len=<log\-len> | \-l <log\-len>]
+ [\-\-aen=<aen> | \-a <aen>]
+ [\-\-namespace\-id=<nsid> | \-n <nsid>]
+ [\-\-raw\-binary | \-b]
+ [\-\-lpo=<offset> | \-o <offset>]
+ [\-\-lsp=<field> | \-s <field>]
+ [\-\-lsi=<field> | \-S <field>]
+ [\-\-rae | \-r]
+ [\-\-csi=<command_set_identifier> | \-y <command_set_identifier>]
+ [\-\-ot | \-O]
.fi
.SH "DESCRIPTION"
.sp
@@ -85,10 +88,25 @@ The log page offset specifies the location within a log page to start returning
The log specified field of LID\&.
.RE
.PP
+\-S <field>, \-\-lsi=<field>
+.RS 4
+The log specified field of Log Specific Identifier\&.
+.RE
+.PP
\-r, \-\-rae
.RS 4
Retain an Asynchronous Event\&.
.RE
+.PP
+\-y <command_set_identifier>, \-\-csi=<command_set_identifier>
+.RS 4
+This field specifies the identifier of command set\&. if not issued, NVM Command Set will be selected\&.
+.RE
+.PP
+\-O, \-\-ot
+.RS 4
+Offset Type
+.RE
.SH "EXAMPLES"
.sp
.RS 4
diff --git a/Documentation/nvme-get-log.html b/Documentation/nvme-get-log.html
index 9aa20e0..53af505 100644
--- a/Documentation/nvme-get-log.html
+++ b/Documentation/nvme-get-log.html
@@ -750,13 +750,16 @@ nvme-get-log(1) Manual Page
<div class="sectionbody">
<div class="verseblock">
<pre class="content"><em>nvme get-log</em> &lt;device&gt; [--log-id=&lt;log-id&gt; | -i &lt;log-id&gt;]
- [--log-len=&lt;log-len&gt; | -l &lt;log-len&gt;]
- [--aen=&lt;aen&gt; | -a &lt;aen&gt;]
- [--namespace-id=&lt;nsid&gt; | -n &lt;nsid&gt;]
- [--raw-binary | -b]
- [--lpo=&lt;offset&gt; | -o &lt;offset&gt;]
- [--lsp=&lt;field&gt; | -s &lt;field&gt;]
- [--rae | -r]</pre>
+ [--log-len=&lt;log-len&gt; | -l &lt;log-len&gt;]
+ [--aen=&lt;aen&gt; | -a &lt;aen&gt;]
+ [--namespace-id=&lt;nsid&gt; | -n &lt;nsid&gt;]
+ [--raw-binary | -b]
+ [--lpo=&lt;offset&gt; | -o &lt;offset&gt;]
+ [--lsp=&lt;field&gt; | -s &lt;field&gt;]
+ [--lsi=&lt;field&gt; | -S &lt;field&gt;]
+ [--rae | -r]
+ [--csi=&lt;command_set_identifier&gt; | -y &lt;command_set_identifier&gt;]
+ [--ot | -O]</pre>
<div class="attribution">
</div></div>
</div>
@@ -864,6 +867,17 @@ program to parse.</p></div>
</p>
</dd>
<dt class="hdlist1">
+-S &lt;field&gt;
+</dt>
+<dt class="hdlist1">
+--lsi=&lt;field&gt;
+</dt>
+<dd>
+<p>
+ The log specified field of Log Specific Identifier.
+</p>
+</dd>
+<dt class="hdlist1">
-r
</dt>
<dt class="hdlist1">
@@ -874,6 +888,29 @@ program to parse.</p></div>
Retain an Asynchronous Event.
</p>
</dd>
+<dt class="hdlist1">
+-y &lt;command_set_identifier&gt;
+</dt>
+<dt class="hdlist1">
+--csi=&lt;command_set_identifier&gt;
+</dt>
+<dd>
+<p>
+ This field specifies the identifier of command set.
+ if not issued, NVM Command Set will be selected.
+</p>
+</dd>
+<dt class="hdlist1">
+-O
+</dt>
+<dt class="hdlist1">
+--ot
+</dt>
+<dd>
+<p>
+ Offset Type
+</p>
+</dd>
</dl></div>
</div>
</div>
@@ -918,7 +955,7 @@ Have the program return the raw log page in binary:
<div id="footer">
<div id="footer-text">
Last updated
- 2019-09-18 00:00:58 JST
+ 2021-06-12 14:47:50 IST
</div>
</div>
</body>
diff --git a/Documentation/nvme-get-log.txt b/Documentation/nvme-get-log.txt
index 1d49e28..d371f5d 100644
--- a/Documentation/nvme-get-log.txt
+++ b/Documentation/nvme-get-log.txt
@@ -9,13 +9,16 @@ SYNOPSIS
--------
[verse]
'nvme get-log' <device> [--log-id=<log-id> | -i <log-id>]
- [--log-len=<log-len> | -l <log-len>]
- [--aen=<aen> | -a <aen>]
- [--namespace-id=<nsid> | -n <nsid>]
- [--raw-binary | -b]
- [--lpo=<offset> | -o <offset>]
- [--lsp=<field> | -s <field>]
- [--rae | -r]
+ [--log-len=<log-len> | -l <log-len>]
+ [--aen=<aen> | -a <aen>]
+ [--namespace-id=<nsid> | -n <nsid>]
+ [--raw-binary | -b]
+ [--lpo=<offset> | -o <offset>]
+ [--lsp=<field> | -s <field>]
+ [--lsi=<field> | -S <field>]
+ [--rae | -r]
+ [--csi=<command_set_identifier> | -y <command_set_identifier>]
+ [--ot | -O]
DESCRIPTION
-----------
@@ -68,10 +71,23 @@ OPTIONS
--lsp=<field>::
The log specified field of LID.
+-S <field>::
+--lsi=<field>::
+ The log specified field of Log Specific Identifier.
+
-r::
--rae::
Retain an Asynchronous Event.
+-y <command_set_identifier>::
+--csi=<command_set_identifier>::
+ This field specifies the identifier of command set.
+ if not issued, NVM Command Set will be selected.
+
+-O::
+--ot::
+ Offset Type
+
EXAMPLES
--------
* Get 512 bytes from log page 2
diff --git a/Documentation/nvme-id-domain.1 b/Documentation/nvme-id-domain.1
new file mode 100644
index 0000000..ddd9c3f
--- /dev/null
+++ b/Documentation/nvme-id-domain.1
@@ -0,0 +1,62 @@
+'\" t
+.\" Title: nvme-id-domain
+.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 07/20/2021
+.\" Manual: NVMe Manual
+.\" Source: NVMe
+.\" Language: English
+.\"
+.TH "NVME\-ID\-DOMAIN" "1" "07/20/2021" "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-id-domain \- Send NVMe Identify Domain List, return result and structure
+.SH "SYNOPSIS"
+.sp
+.nf
+\fInvme id\-domain\fR <device> [\-\-dom\-id=<domian_id> | \-d <domian_id>]
+ [\-o <fmt> | \-\-output\-format=<fmt>]
+.fi
+.SH "DESCRIPTION"
+.sp
+For the NVMe device given, send an identify command and return the domian list data structure\&.
+.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)\&.
+.SH "OPTIONS"
+.PP
+\-d <domian_id>, \-\-dom\-id=<domian_id>
+.RS 4
+Retrieve the identify domain list data structure for the given domain id\&. If this value is not given, domain id will be 0xffff\&.
+.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
+No examples yet\&.
+.SH "NVME"
+.sp
+Part of the nvme\-user suite
diff --git a/Documentation/nvme-id-domain.html b/Documentation/nvme-id-domain.html
new file mode 100644
index 0000000..067cef0
--- /dev/null
+++ b/Documentation/nvme-id-domain.html
@@ -0,0 +1,819 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+ "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
+<meta name="generator" content="AsciiDoc 8.6.10" />
+<title>nvme-id-domain(1)</title>
+<style type="text/css">
+/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
+
+/* Default font. */
+body {
+ font-family: Georgia,serif;
+}
+
+/* Title font. */
+h1, h2, h3, h4, h5, h6,
+div.title, caption.title,
+thead, p.table.header,
+#toctitle,
+#author, #revnumber, #revdate, #revremark,
+#footer {
+ font-family: Arial,Helvetica,sans-serif;
+}
+
+body {
+ margin: 1em 5% 1em 5%;
+}
+
+a {
+ color: blue;
+ text-decoration: underline;
+}
+a:visited {
+ color: fuchsia;
+}
+
+em {
+ font-style: italic;
+ color: navy;
+}
+
+strong {
+ font-weight: bold;
+ color: #083194;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ color: #527bbd;
+ margin-top: 1.2em;
+ margin-bottom: 0.5em;
+ line-height: 1.3;
+}
+
+h1, h2, h3 {
+ border-bottom: 2px solid silver;
+}
+h2 {
+ padding-top: 0.5em;
+}
+h3 {
+ float: left;
+}
+h3 + * {
+ clear: left;
+}
+h5 {
+ font-size: 1.0em;
+}
+
+div.sectionbody {
+ margin-left: 0;
+}
+
+hr {
+ border: 1px solid silver;
+}
+
+p {
+ margin-top: 0.5em;
+ margin-bottom: 0.5em;
+}
+
+ul, ol, li > p {
+ margin-top: 0;
+}
+ul > li { color: #aaa; }
+ul > li > * { color: black; }
+
+.monospaced, code, pre {
+ font-family: "Courier New", Courier, monospace;
+ font-size: inherit;
+ color: navy;
+ padding: 0;
+ margin: 0;
+}
+pre {
+ white-space: pre-wrap;
+}
+
+#author {
+ color: #527bbd;
+ font-weight: bold;
+ font-size: 1.1em;
+}
+#email {
+}
+#revnumber, #revdate, #revremark {
+}
+
+#footer {
+ font-size: small;
+ border-top: 2px solid silver;
+ padding-top: 0.5em;
+ margin-top: 4.0em;
+}
+#footer-text {
+ float: left;
+ padding-bottom: 0.5em;
+}
+#footer-badges {
+ float: right;
+ padding-bottom: 0.5em;
+}
+
+#preamble {
+ margin-top: 1.5em;
+ margin-bottom: 1.5em;
+}
+div.imageblock, div.exampleblock, div.verseblock,
+div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
+div.admonitionblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+div.admonitionblock {
+ margin-top: 2.0em;
+ margin-bottom: 2.0em;
+ margin-right: 10%;
+ color: #606060;
+}
+
+div.content { /* Block element content. */
+ padding: 0;
+}
+
+/* Block element titles. */
+div.title, caption.title {
+ color: #527bbd;
+ font-weight: bold;
+ text-align: left;
+ margin-top: 1.0em;
+ margin-bottom: 0.5em;
+}
+div.title + * {
+ margin-top: 0;
+}
+
+td div.title:first-child {
+ margin-top: 0.0em;
+}
+div.content div.title:first-child {
+ margin-top: 0.0em;
+}
+div.content + div.title {
+ margin-top: 0.0em;
+}
+
+div.sidebarblock > div.content {
+ background: #ffffee;
+ border: 1px solid #dddddd;
+ border-left: 4px solid #f0f0f0;
+ padding: 0.5em;
+}
+
+div.listingblock > div.content {
+ border: 1px solid #dddddd;
+ border-left: 5px solid #f0f0f0;
+ background: #f8f8f8;
+ padding: 0.5em;
+}
+
+div.quoteblock, div.verseblock {
+ padding-left: 1.0em;
+ margin-left: 1.0em;
+ margin-right: 10%;
+ border-left: 5px solid #f0f0f0;
+ color: #888;
+}
+
+div.quoteblock > div.attribution {
+ padding-top: 0.5em;
+ text-align: right;
+}
+
+div.verseblock > pre.content {
+ font-family: inherit;
+ font-size: inherit;
+}
+div.verseblock > div.attribution {
+ padding-top: 0.75em;
+ text-align: left;
+}
+/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
+div.verseblock + div.attribution {
+ text-align: left;
+}
+
+div.admonitionblock .icon {
+ vertical-align: top;
+ font-size: 1.1em;
+ font-weight: bold;
+ text-decoration: underline;
+ color: #527bbd;
+ padding-right: 0.5em;
+}
+div.admonitionblock td.content {
+ padding-left: 0.5em;
+ border-left: 3px solid #dddddd;
+}
+
+div.exampleblock > div.content {
+ border-left: 3px solid #dddddd;
+ padding-left: 0.5em;
+}
+
+div.imageblock div.content { padding-left: 0; }
+span.image img { border-style: none; vertical-align: text-bottom; }
+a.image:visited { color: white; }
+
+dl {
+ margin-top: 0.8em;
+ margin-bottom: 0.8em;
+}
+dt {
+ margin-top: 0.5em;
+ margin-bottom: 0;
+ font-style: normal;
+ color: navy;
+}
+dd > *:first-child {
+ margin-top: 0.1em;
+}
+
+ul, ol {
+ list-style-position: outside;
+}
+ol.arabic {
+ list-style-type: decimal;
+}
+ol.loweralpha {
+ list-style-type: lower-alpha;
+}
+ol.upperalpha {
+ list-style-type: upper-alpha;
+}
+ol.lowerroman {
+ list-style-type: lower-roman;
+}
+ol.upperroman {
+ list-style-type: upper-roman;
+}
+
+div.compact ul, div.compact ol,
+div.compact p, div.compact p,
+div.compact div, div.compact div {
+ margin-top: 0.1em;
+ margin-bottom: 0.1em;
+}
+
+tfoot {
+ font-weight: bold;
+}
+td > div.verse {
+ white-space: pre;
+}
+
+div.hdlist {
+ margin-top: 0.8em;
+ margin-bottom: 0.8em;
+}
+div.hdlist tr {
+ padding-bottom: 15px;
+}
+dt.hdlist1.strong, td.hdlist1.strong {
+ font-weight: bold;
+}
+td.hdlist1 {
+ vertical-align: top;
+ font-style: normal;
+ padding-right: 0.8em;
+ color: navy;
+}
+td.hdlist2 {
+ vertical-align: top;
+}
+div.hdlist.compact tr {
+ margin: 0;
+ padding-bottom: 0;
+}
+
+.comment {
+ background: yellow;
+}
+
+.footnote, .footnoteref {
+ font-size: 0.8em;
+}
+
+span.footnote, span.footnoteref {
+ vertical-align: super;
+}
+
+#footnotes {
+ margin: 20px 0 20px 0;
+ padding: 7px 0 0 0;
+}
+
+#footnotes div.footnote {
+ margin: 0 0 5px 0;
+}
+
+#footnotes hr {
+ border: none;
+ border-top: 1px solid silver;
+ height: 1px;
+ text-align: left;
+ margin-left: 0;
+ width: 20%;
+ min-width: 100px;
+}
+
+div.colist td {
+ padding-right: 0.5em;
+ padding-bottom: 0.3em;
+ vertical-align: top;
+}
+div.colist td img {
+ margin-top: 0.3em;
+}
+
+@media print {
+ #footer-badges { display: none; }
+}
+
+#toc {
+ margin-bottom: 2.5em;
+}
+
+#toctitle {
+ color: #527bbd;
+ font-size: 1.1em;
+ font-weight: bold;
+ margin-top: 1.0em;
+ margin-bottom: 0.1em;
+}
+
+div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+div.toclevel2 {
+ margin-left: 2em;
+ font-size: 0.9em;
+}
+div.toclevel3 {
+ margin-left: 4em;
+ font-size: 0.9em;
+}
+div.toclevel4 {
+ margin-left: 6em;
+ font-size: 0.9em;
+}
+
+span.aqua { color: aqua; }
+span.black { color: black; }
+span.blue { color: blue; }
+span.fuchsia { color: fuchsia; }
+span.gray { color: gray; }
+span.green { color: green; }
+span.lime { color: lime; }
+span.maroon { color: maroon; }
+span.navy { color: navy; }
+span.olive { color: olive; }
+span.purple { color: purple; }
+span.red { color: red; }
+span.silver { color: silver; }
+span.teal { color: teal; }
+span.white { color: white; }
+span.yellow { color: yellow; }
+
+span.aqua-background { background: aqua; }
+span.black-background { background: black; }
+span.blue-background { background: blue; }
+span.fuchsia-background { background: fuchsia; }
+span.gray-background { background: gray; }
+span.green-background { background: green; }
+span.lime-background { background: lime; }
+span.maroon-background { background: maroon; }
+span.navy-background { background: navy; }
+span.olive-background { background: olive; }
+span.purple-background { background: purple; }
+span.red-background { background: red; }
+span.silver-background { background: silver; }
+span.teal-background { background: teal; }
+span.white-background { background: white; }
+span.yellow-background { background: yellow; }
+
+span.big { font-size: 2em; }
+span.small { font-size: 0.6em; }
+
+span.underline { text-decoration: underline; }
+span.overline { text-decoration: overline; }
+span.line-through { text-decoration: line-through; }
+
+div.unbreakable { page-break-inside: avoid; }
+
+
+/*
+ * xhtml11 specific
+ *
+ * */
+
+div.tableblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+div.tableblock > table {
+ border: 3px solid #527bbd;
+}
+thead, p.table.header {
+ font-weight: bold;
+ color: #527bbd;
+}
+p.table {
+ margin-top: 0;
+}
+/* Because the table frame attribute is overriden by CSS in most browsers. */
+div.tableblock > table[frame="void"] {
+ border-style: none;
+}
+div.tableblock > table[frame="hsides"] {
+ border-left-style: none;
+ border-right-style: none;
+}
+div.tableblock > table[frame="vsides"] {
+ border-top-style: none;
+ border-bottom-style: none;
+}
+
+
+/*
+ * html5 specific
+ *
+ * */
+
+table.tableblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+thead, p.tableblock.header {
+ font-weight: bold;
+ color: #527bbd;
+}
+p.tableblock {
+ margin-top: 0;
+}
+table.tableblock {
+ border-width: 3px;
+ border-spacing: 0px;
+ border-style: solid;
+ border-color: #527bbd;
+ border-collapse: collapse;
+}
+th.tableblock, td.tableblock {
+ border-width: 1px;
+ padding: 4px;
+ border-style: solid;
+ border-color: #527bbd;
+}
+
+table.tableblock.frame-topbot {
+ border-left-style: hidden;
+ border-right-style: hidden;
+}
+table.tableblock.frame-sides {
+ border-top-style: hidden;
+ border-bottom-style: hidden;
+}
+table.tableblock.frame-none {
+ border-style: hidden;
+}
+
+th.tableblock.halign-left, td.tableblock.halign-left {
+ text-align: left;
+}
+th.tableblock.halign-center, td.tableblock.halign-center {
+ text-align: center;
+}
+th.tableblock.halign-right, td.tableblock.halign-right {
+ text-align: right;
+}
+
+th.tableblock.valign-top, td.tableblock.valign-top {
+ vertical-align: top;
+}
+th.tableblock.valign-middle, td.tableblock.valign-middle {
+ vertical-align: middle;
+}
+th.tableblock.valign-bottom, td.tableblock.valign-bottom {
+ vertical-align: bottom;
+}
+
+
+/*
+ * manpage specific
+ *
+ * */
+
+body.manpage h1 {
+ padding-top: 0.5em;
+ padding-bottom: 0.5em;
+ border-top: 2px solid silver;
+ border-bottom: 2px solid silver;
+}
+body.manpage h2 {
+ border-style: none;
+}
+body.manpage div.sectionbody {
+ margin-left: 3em;
+}
+
+@media print {
+ body.manpage div#toc { display: none; }
+}
+
+
+</style>
+<script type="text/javascript">
+/*<![CDATA[*/
+var asciidoc = { // Namespace.
+
+/////////////////////////////////////////////////////////////////////
+// Table Of Contents generator
+/////////////////////////////////////////////////////////////////////
+
+/* Author: Mihai Bazon, September 2002
+ * http://students.infoiasi.ro/~mishoo
+ *
+ * Table Of Content generator
+ * Version: 0.4
+ *
+ * Feel free to use this script under the terms of the GNU General Public
+ * License, as long as you do not remove or alter this notice.
+ */
+
+ /* modified by Troy D. Hanson, September 2006. License: GPL */
+ /* modified by Stuart Rackham, 2006, 2009. License: GPL */
+
+// toclevels = 1..4.
+toc: function (toclevels) {
+
+ function getText(el) {
+ var text = "";
+ for (var i = el.firstChild; i != null; i = i.nextSibling) {
+ if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
+ text += i.data;
+ else if (i.firstChild != null)
+ text += getText(i);
+ }
+ return text;
+ }
+
+ function TocEntry(el, text, toclevel) {
+ this.element = el;
+ this.text = text;
+ this.toclevel = toclevel;
+ }
+
+ function tocEntries(el, toclevels) {
+ var result = new Array;
+ var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
+ // Function that scans the DOM tree for header elements (the DOM2
+ // nodeIterator API would be a better technique but not supported by all
+ // browsers).
+ var iterate = function (el) {
+ for (var i = el.firstChild; i != null; i = i.nextSibling) {
+ if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
+ var mo = re.exec(i.tagName);
+ if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
+ result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
+ }
+ iterate(i);
+ }
+ }
+ }
+ iterate(el);
+ return result;
+ }
+
+ var toc = document.getElementById("toc");
+ if (!toc) {
+ return;
+ }
+
+ // Delete existing TOC entries in case we're reloading the TOC.
+ var tocEntriesToRemove = [];
+ var i;
+ for (i = 0; i < toc.childNodes.length; i++) {
+ var entry = toc.childNodes[i];
+ if (entry.nodeName.toLowerCase() == 'div'
+ && entry.getAttribute("class")
+ && entry.getAttribute("class").match(/^toclevel/))
+ tocEntriesToRemove.push(entry);
+ }
+ for (i = 0; i < tocEntriesToRemove.length; i++) {
+ toc.removeChild(tocEntriesToRemove[i]);
+ }
+
+ // Rebuild TOC entries.
+ var entries = tocEntries(document.getElementById("content"), toclevels);
+ for (var i = 0; i < entries.length; ++i) {
+ var entry = entries[i];
+ if (entry.element.id == "")
+ entry.element.id = "_toc_" + i;
+ var a = document.createElement("a");
+ a.href = "#" + entry.element.id;
+ a.appendChild(document.createTextNode(entry.text));
+ var div = document.createElement("div");
+ div.appendChild(a);
+ div.className = "toclevel" + entry.toclevel;
+ toc.appendChild(div);
+ }
+ if (entries.length == 0)
+ toc.parentNode.removeChild(toc);
+},
+
+
+/////////////////////////////////////////////////////////////////////
+// Footnotes generator
+/////////////////////////////////////////////////////////////////////
+
+/* Based on footnote generation code from:
+ * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
+ */
+
+footnotes: function () {
+ // Delete existing footnote entries in case we're reloading the footnodes.
+ var i;
+ var noteholder = document.getElementById("footnotes");
+ if (!noteholder) {
+ return;
+ }
+ var entriesToRemove = [];
+ for (i = 0; i < noteholder.childNodes.length; i++) {
+ var entry = noteholder.childNodes[i];
+ if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
+ entriesToRemove.push(entry);
+ }
+ for (i = 0; i < entriesToRemove.length; i++) {
+ noteholder.removeChild(entriesToRemove[i]);
+ }
+
+ // Rebuild footnote entries.
+ var cont = document.getElementById("content");
+ var spans = cont.getElementsByTagName("span");
+ var refs = {};
+ var n = 0;
+ for (i=0; i<spans.length; i++) {
+ if (spans[i].className == "footnote") {
+ n++;
+ var note = spans[i].getAttribute("data-note");
+ if (!note) {
+ // Use [\s\S] in place of . so multi-line matches work.
+ // Because JavaScript has no s (dotall) regex flag.
+ note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
+ spans[i].innerHTML =
+ "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
+ "' title='View footnote' class='footnote'>" + n + "</a>]";
+ spans[i].setAttribute("data-note", note);
+ }
+ noteholder.innerHTML +=
+ "<div class='footnote' id='_footnote_" + n + "'>" +
+ "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
+ n + "</a>. " + note + "</div>";
+ var id =spans[i].getAttribute("id");
+ if (id != null) refs["#"+id] = n;
+ }
+ }
+ if (n == 0)
+ noteholder.parentNode.removeChild(noteholder);
+ else {
+ // Process footnoterefs.
+ for (i=0; i<spans.length; i++) {
+ if (spans[i].className == "footnoteref") {
+ var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
+ href = href.match(/#.*/)[0]; // Because IE return full URL.
+ n = refs[href];
+ spans[i].innerHTML =
+ "[<a href='#_footnote_" + n +
+ "' title='View footnote' class='footnote'>" + n + "</a>]";
+ }
+ }
+ }
+},
+
+install: function(toclevels) {
+ var timerId;
+
+ function reinstall() {
+ asciidoc.footnotes();
+ if (toclevels) {
+ asciidoc.toc(toclevels);
+ }
+ }
+
+ function reinstallAndRemoveTimer() {
+ clearInterval(timerId);
+ reinstall();
+ }
+
+ timerId = setInterval(reinstall, 500);
+ if (document.addEventListener)
+ document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
+ else
+ window.onload = reinstallAndRemoveTimer;
+}
+
+}
+asciidoc.install();
+/*]]>*/
+</script>
+</head>
+<body class="manpage">
+<div id="header">
+<h1>
+nvme-id-domain(1) Manual Page
+</h1>
+<h2>NAME</h2>
+<div class="sectionbody">
+<p>nvme-id-domain -
+ Send NVMe Identify Domain List, return result and structure
+</p>
+</div>
+</div>
+<div id="content">
+<div class="sect1">
+<h2 id="_synopsis">SYNOPSIS</h2>
+<div class="sectionbody">
+<div class="verseblock">
+<pre class="content"><em>nvme id-domain</em> &lt;device&gt; [--dom-id=&lt;domian_id&gt; | -d &lt;domian_id&gt;]
+ [-o &lt;fmt&gt; | --output-format=&lt;fmt&gt;]</pre>
+<div class="attribution">
+</div></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_description">DESCRIPTION</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>For the NVMe device given, send an identify command and return the domian list
+data structure.</p></div>
+<div class="paragraph"><p>The &lt;device&gt; parameter is mandatory and may be either the NVMe character
+device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1).</p></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_options">OPTIONS</h2>
+<div class="sectionbody">
+<div class="dlist"><dl>
+<dt class="hdlist1">
+-d &lt;domian_id&gt;
+</dt>
+<dt class="hdlist1">
+--dom-id=&lt;domian_id&gt;
+</dt>
+<dd>
+<p>
+ Retrieve the identify domain list data structure for the given
+ domain id. If this value is not given, domain id will be 0xffff.
+</p>
+</dd>
+<dt class="hdlist1">
+-o &lt;format&gt;
+</dt>
+<dt class="hdlist1">
+--output-format=&lt;format&gt;
+</dt>
+<dd>
+<p>
+ Set the reporting format to <em>normal</em>, <em>json</em>, or
+ <em>binary</em>. Only one output format can be used at a time.
+</p>
+</dd>
+</dl></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_examples">EXAMPLES</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>No examples yet.</p></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_nvme">NVME</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Part of the nvme-user suite</p></div>
+</div>
+</div>
+</div>
+<div id="footnotes"><hr /></div>
+<div id="footer">
+<div id="footer-text">
+Last updated
+ 2021-07-20 12:04:44 IST
+</div>
+</div>
+</body>
+</html>
diff --git a/Documentation/nvme-id-domain.txt b/Documentation/nvme-id-domain.txt
new file mode 100644
index 0000000..be7b81a
--- /dev/null
+++ b/Documentation/nvme-id-domain.txt
@@ -0,0 +1,40 @@
+nvme-id-domain(1)
+=================
+
+NAME
+----
+nvme-id-domain - Send NVMe Identify Domain List, return result and structure
+
+SYNOPSIS
+--------
+[verse]
+'nvme id-domain' <device> [--dom-id=<domian_id> | -d <domian_id>]
+ [-o <fmt> | --output-format=<fmt>]
+
+DESCRIPTION
+-----------
+For the NVMe device given, send an identify command and return the domian list
+data structure.
+
+The <device> parameter is mandatory and may be either the NVMe character
+device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1).
+
+OPTIONS
+-------
+-d <domian_id>::
+--dom-id=<domian_id>::
+ Retrieve the identify domain list data structure for the given
+ domain id. If this value is not given, domain id will be 0xffff.
+
+-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
+--------
+No examples yet.
+
+NVME
+----
+Part of the nvme-user suite
diff --git a/Documentation/nvme-id-iocs.1 b/Documentation/nvme-id-iocs.1
index f79b4de..2320de3 100644
--- a/Documentation/nvme-id-iocs.1
+++ b/Documentation/nvme-id-iocs.1
@@ -1,13 +1,13 @@
'\" t
.\" Title: nvme-id-iocs
-.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
-.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 10/20/2020
+.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 05/28/2021
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-ID\-IOCS" "1" "10/20/2020" "NVMe" "NVMe Manual"
+.TH "NVME\-ID\-IOCS" "1" "05/28/2021" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -33,6 +33,7 @@ nvme-id-iocs \- Send NVMe Identify I/O Command Set, return result and structure
.sp
.nf
\fInvme id\-iocs\fR <device> [\-\-controller\-id=<cntid> | \-c <cntid>]
+ [\-o <fmt> | \-\-output\-format=<fmt>]
.fi
.SH "DESCRIPTION"
.sp
@@ -45,6 +46,19 @@ The <device> parameter is mandatory and may be either the NVMe character device
.RS 4
Retrieve the identify I/O Command set data structure for the given cntid\&. If this value is not given, cntid will be 0xffff\&.
.RE
+.PP
+\-H, \-\-human\-readable
+.RS 4
+This option will parse and format many of the bit fields into human\-readable formats\&.
+.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
@@ -67,6 +81,27 @@ Have the program interpret the returned buffer and display the known fields in a
.RE
.\}
.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+show the fields in human readable format
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+# nvme id\-iocs /dev/nvme0 \-H
+.fi
+.if n \{\
+.RE
+.\}
+.RE
.SH "NVME"
.sp
Part of the nvme\-user suite
diff --git a/Documentation/nvme-id-iocs.html b/Documentation/nvme-id-iocs.html
index 6bc983f..159f306 100644
--- a/Documentation/nvme-id-iocs.html
+++ b/Documentation/nvme-id-iocs.html
@@ -749,7 +749,8 @@ nvme-id-iocs(1) Manual Page
<h2 id="_synopsis">SYNOPSIS</h2>
<div class="sectionbody">
<div class="verseblock">
-<pre class="content"><em>nvme id-iocs</em> &lt;device&gt; [--controller-id=&lt;cntid&gt; | -c &lt;cntid&gt;]</pre>
+<pre class="content"><em>nvme id-iocs</em> &lt;device&gt; [--controller-id=&lt;cntid&gt; | -c &lt;cntid&gt;]
+ [-o &lt;fmt&gt; | --output-format=&lt;fmt&gt;]</pre>
<div class="attribution">
</div></div>
</div>
@@ -779,6 +780,30 @@ device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1).</p></di
cntid. If this value is not given, cntid will be 0xffff.
</p>
</dd>
+<dt class="hdlist1">
+-H
+</dt>
+<dt class="hdlist1">
+--human-readable
+</dt>
+<dd>
+<p>
+ This option will parse and format many of the bit fields
+ into human-readable formats.
+</p>
+</dd>
+<dt class="hdlist1">
+-o &lt;format&gt;
+</dt>
+<dt class="hdlist1">
+--output-format=&lt;format&gt;
+</dt>
+<dd>
+<p>
+ Set the reporting format to <em>normal</em>, <em>json</em>, or
+ <em>binary</em>. Only one output format can be used at a time.
+</p>
+</dd>
</dl></div>
</div>
</div>
@@ -796,6 +821,15 @@ fields in a human readable format:
<pre><code># nvme id-iocs /dev/nvme0</code></pre>
</div></div>
</li>
+<li>
+<p>
+show the fields in human readable format
+</p>
+<div class="listingblock">
+<div class="content">
+<pre><code># nvme id-iocs /dev/nvme0 -H</code></pre>
+</div></div>
+</li>
</ul></div>
</div>
</div>
@@ -810,7 +844,7 @@ fields in a human readable format:
<div id="footer">
<div id="footer-text">
Last updated
- 2020-05-06 10:39:59 CEST
+ 2021-05-28 23:15:06 IST
</div>
</div>
</body>
diff --git a/Documentation/nvme-id-iocs.txt b/Documentation/nvme-id-iocs.txt
index 9e53207..a35217e 100644
--- a/Documentation/nvme-id-iocs.txt
+++ b/Documentation/nvme-id-iocs.txt
@@ -9,6 +9,7 @@ SYNOPSIS
--------
[verse]
'nvme id-iocs' <device> [--controller-id=<cntid> | -c <cntid>]
+ [-o <fmt> | --output-format=<fmt>]
DESCRIPTION
-----------
@@ -24,6 +25,15 @@ OPTIONS
--controller-id=<cntid>::
Retrieve the identify I/O Command set data structure for the given
cntid. If this value is not given, cntid will be 0xffff.
+-H::
+--human-readable::
+ This option will parse and format many of the bit fields
+ into human-readable formats.
+
+-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
--------
@@ -33,7 +43,12 @@ fields in a human readable format:
------------
# nvme id-iocs /dev/nvme0
------------
-
++
+* show the fields in human readable format
++
+------------
+# nvme id-iocs /dev/nvme0 -H
+------------
NVME
----
Part of the nvme-user suite
diff --git a/Documentation/nvme-io-passthru.1 b/Documentation/nvme-io-passthru.1
index b5e4322..ad913cc 100644
--- a/Documentation/nvme-io-passthru.1
+++ b/Documentation/nvme-io-passthru.1
@@ -1,13 +1,13 @@
'\" t
.\" Title: nvme-io-passthru
-.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
-.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 10/20/2020
+.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 06/04/2021
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-IO\-PASSTHRU" "1" "10/20/2020" "NVMe" "NVMe Manual"
+.TH "NVME\-IO\-PASSTHRU" "1" "06/04/2021" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -47,6 +47,7 @@ nvme-io-passthru \- Submit an arbitrary io command, return results
[\-\-dry\-run | \-d]
[\-\-raw\-binary | \-b]
[\-\-prefill=<prefill> | \-p <prefill>]
+ [\-\-latency | \-T]
.fi
.SH "DESCRIPTION"
.sp
@@ -125,6 +126,11 @@ Print the raw returned buffer to stdout if the command returns data or a structu
.RS 4
Prefill the buffer with a predetermined byte value\&. Defaults to 0\&. This may be useful if the data you are writing is shorter than the required buffer, and you need to pad it with a known value\&. It may also be useful if you need to confirm if a device is overwriting a buffer on a data\-in command\&.
.RE
+.PP
+\-T, \-\-latency
+.RS 4
+Print out the latency the IOCTL took (in us)\&.
+.RE
.SH "EXAMPLES"
.sp
nvme io\-passthru /dev/nvme0n1 \-\-opcode=2 \-\-namespace\-id=1 \-\-data\-len=4096 \-\-read \-\-cdw10=0 \-\-cdw11=0 \-\-cdw12=0x70000 \-\-raw\-binary
diff --git a/Documentation/nvme-io-passthru.html b/Documentation/nvme-io-passthru.html
index 96b9e1e..8463c5f 100644
--- a/Documentation/nvme-io-passthru.html
+++ b/Documentation/nvme-io-passthru.html
@@ -1,9 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
-<meta name="generator" content="AsciiDoc 8.6.9" />
+<meta name="generator" content="AsciiDoc 8.6.10" />
<title>nvme-io-passthru(1)</title>
<style type="text/css">
/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
@@ -435,7 +436,7 @@ thead, p.table.header {
p.table {
margin-top: 0;
}
-/* Because the table frame attribute is overridden by CSS in most browsers. */
+/* Because the table frame attribute is overriden by CSS in most browsers. */
div.tableblock > table[frame="void"] {
border-style: none;
}
@@ -762,7 +763,8 @@ nvme-io-passthru(1) Manual Page
[--show-command | -s]
[--dry-run | -d]
[--raw-binary | -b]
- [--prefill=&lt;prefill&gt; | -p &lt;prefill&gt;]</pre>
+ [--prefill=&lt;prefill&gt; | -p &lt;prefill&gt;]
+ [--latency | -T]</pre>
<div class="attribution">
</div></div>
</div>
@@ -944,6 +946,17 @@ printed to stdout for another program to parse.</p></div>
is overwriting a buffer on a data-in command.
</p>
</dd>
+<dt class="hdlist1">
+-T
+</dt>
+<dt class="hdlist1">
+--latency
+</dt>
+<dd>
+<p>
+ Print out the latency the IOCTL took (in us).
+</p>
+</dd>
</dl></div>
</div>
</div>
@@ -964,7 +977,7 @@ printed to stdout for another program to parse.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2018-01-30 19:28:39 KST
+ 2021-06-04 10:59:48 IST
</div>
</div>
</body>
diff --git a/Documentation/nvme-io-passthru.txt b/Documentation/nvme-io-passthru.txt
index 318e801..5a16698 100644
--- a/Documentation/nvme-io-passthru.txt
+++ b/Documentation/nvme-io-passthru.txt
@@ -23,6 +23,7 @@ SYNOPSIS
[--dry-run | -d]
[--raw-binary | -b]
[--prefill=<prefill> | -p <prefill>]
+ [--latency | -T]
DESCRIPTION
-----------
@@ -106,6 +107,10 @@ OPTIONS
value. It may also be useful if you need to confirm if a device
is overwriting a buffer on a data-in command.
+-T::
+--latency::
+ Print out the latency the IOCTL took (in us).
+
EXAMPLES
--------
diff --git a/Documentation/nvme-list-ctrl.1 b/Documentation/nvme-list-ctrl.1
index ce64471..3ab756e 100644
--- a/Documentation/nvme-list-ctrl.1
+++ b/Documentation/nvme-list-ctrl.1
@@ -1,13 +1,13 @@
'\" t
.\" Title: nvme-id-ns
-.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
-.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 10/20/2020
+.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 05/16/2021
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-ID\-NS" "1" "10/20/2020" "NVMe" "NVMe Manual"
+.TH "NVME\-ID\-NS" "1" "05/16/2021" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -33,7 +33,7 @@ nvme-list-ctrl \- Send NVMe Identify List Controllers, return result and structu
.sp
.nf
\fInvme list\-ctrl\fR <device> [\-\-cntid=<cntid> | \-c <cntid>]
- [\-\-namespace\-id=<nsid> | \-n <nsid>]
+ [\-\-namespace\-id=<nsid> | \-n <nsid>] [\-o <fmt> | \-\-output\-format=<fmt>]
DESCRIPTION
.fi
.sp
@@ -62,6 +62,14 @@ Retrieve the identify list structure starting with the given controller id\&.
.RS 4
If provided, will request the controllers attached to the specified namespace\&. If no namespace is given, or set to 0, the command requests the controller list for the entire subsystem, whether or not they are attached to namespace(s)\&.
.RE
+.PP
+\-o <format>, \-\-output\-format=<format>
+.RS 4
+Set the reporting format to
+\fInormal\fR
+or
+\fIjson\fR\&. Only one output format can be used at a time\&.
+.RE
.SH "EXAMPLES"
.sp
No examples yet\&.
diff --git a/Documentation/nvme-list-ctrl.html b/Documentation/nvme-list-ctrl.html
index c3aa941..efde99e 100644
--- a/Documentation/nvme-list-ctrl.html
+++ b/Documentation/nvme-list-ctrl.html
@@ -1,9 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
-<meta name="generator" content="AsciiDoc 8.6.8" />
+<meta name="generator" content="AsciiDoc 8.6.10" />
<title>nvme-id-ns(1)</title>
<style type="text/css">
/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
@@ -94,7 +95,9 @@ ul > li > * { color: black; }
padding: 0;
margin: 0;
}
-
+pre {
+ white-space: pre-wrap;
+}
#author {
color: #527bbd;
@@ -223,7 +226,7 @@ div.exampleblock > div.content {
}
div.imageblock div.content { padding-left: 0; }
-span.image img { border-style: none; }
+span.image img { border-style: none; vertical-align: text-bottom; }
a.image:visited { color: white; }
dl {
@@ -433,7 +436,7 @@ thead, p.table.header {
p.table {
margin-top: 0;
}
-/* Because the table frame attribute is overridden by CSS in most browsers. */
+/* Because the table frame attribute is overriden by CSS in most browsers. */
div.tableblock > table[frame="void"] {
border-style: none;
}
@@ -747,7 +750,7 @@ nvme-id-ns(1) Manual Page
<div class="sectionbody">
<div class="verseblock">
<pre class="content"><em>nvme list-ctrl</em> &lt;device&gt; [--cntid=&lt;cntid&gt; | -c &lt;cntid&gt;]
- [--namespace-id=&lt;nsid&gt; | -n &lt;nsid&gt;]
+ [--namespace-id=&lt;nsid&gt; | -n &lt;nsid&gt;] [-o &lt;fmt&gt; | --output-format=&lt;fmt&gt;]
DESCRIPTION</pre>
<div class="attribution">
</div></div>
@@ -793,6 +796,18 @@ OPTIONS</code></pre>
whether or not they are attached to namespace(s).
</p>
</dd>
+<dt class="hdlist1">
+-o &lt;format&gt;
+</dt>
+<dt class="hdlist1">
+--output-format=&lt;format&gt;
+</dt>
+<dd>
+<p>
+ Set the reporting format to <em>normal</em> or <em>json</em>. Only one output
+ format can be used at a time.
+</p>
+</dd>
</dl></div>
</div>
</div>
@@ -812,7 +827,8 @@ OPTIONS</code></pre>
<div id="footnotes"><hr /></div>
<div id="footer">
<div id="footer-text">
-Last updated 2016-05-16 12:47:42 EDT
+Last updated
+ 2021-05-16 13:00:43 IST
</div>
</div>
</body>
diff --git a/Documentation/nvme-list-ctrl.txt b/Documentation/nvme-list-ctrl.txt
index b60afb7..45707e7 100644
--- a/Documentation/nvme-list-ctrl.txt
+++ b/Documentation/nvme-list-ctrl.txt
@@ -9,7 +9,7 @@ SYNOPSIS
--------
[verse]
'nvme list-ctrl' <device> [--cntid=<cntid> | -c <cntid>]
- [--namespace-id=<nsid> | -n <nsid>]
+ [--namespace-id=<nsid> | -n <nsid>] [-o <fmt> | --output-format=<fmt>]
DESCRIPTION
-----------
For the NVMe device given, sends an identify command for controller list
@@ -37,6 +37,11 @@ OPTIONS
command requests the controller list for the entire subsystem,
whether or not they are attached to namespace(s).
+-o <format>::
+--output-format=<format>::
+ Set the reporting format to 'normal' or 'json'. Only one output
+ format can be used at a time.
+
EXAMPLES
--------
No examples yet.
diff --git a/Documentation/nvme-list-ns.1 b/Documentation/nvme-list-ns.1
index 084eb3e..6abe99f 100644
--- a/Documentation/nvme-list-ns.1
+++ b/Documentation/nvme-list-ns.1
@@ -1,13 +1,13 @@
'\" t
.\" Title: nvme-id-ns
-.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
-.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 10/20/2020
+.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 05/16/2021
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-ID\-NS" "1" "10/20/2020" "NVMe" "NVMe Manual"
+.TH "NVME\-ID\-NS" "1" "05/16/2021" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -34,7 +34,7 @@ nvme-list-ns \- Send NVMe Identify List Namespaces, return result and structure
.nf
\fInvme list\-ns\fR <device> [\-\-namespace\-id=<nsid> | \-n <nsid>]
[\-\-csi=<command_set_identifier> | \-y <command_set_identifier>]
- [\-\-all | \-a]
+ [\-\-all | \-a] [\-\-output\-format=<fmt> | \-o <fmt>]
.fi
.SH "DESCRIPTION"
.sp
@@ -59,9 +59,56 @@ If this value is given, retrieve the identify list structure associated with the
.RS 4
Retrieve the identify list structure for all namespaces in the subsystem, whether attached or inactive\&.
.RE
+.PP
+\-o <format>, \-\-output\-format=<format>
+.RS 4
+Set the reporting format to
+\fInormal\fR, or
+\fIjson\fR\&. Only one output format can be used at a time\&.
+.RE
.SH "EXAMPLES"
.sp
-No examples yet\&.
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Print the namespaces present for zoned command set in JSON format
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+# nvme list\-ns /dev/nvme0 \-y 2 \-a \-o json
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Print the namespaces present for NVM Command Set in normal format
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+# nvme list\-ns /dev/nvme0
+.fi
+.if n \{\
+.RE
+.\}
+.RE
.SH "NVME"
.sp
Part of the nvme\-user suite
diff --git a/Documentation/nvme-list-ns.html b/Documentation/nvme-list-ns.html
index f88f3e8..c79b81b 100644
--- a/Documentation/nvme-list-ns.html
+++ b/Documentation/nvme-list-ns.html
@@ -751,7 +751,7 @@ nvme-id-ns(1) Manual Page
<div class="verseblock">
<pre class="content"><em>nvme list-ns</em> &lt;device&gt; [--namespace-id=&lt;nsid&gt; | -n &lt;nsid&gt;]
[--csi=&lt;command_set_identifier&gt; | -y &lt;command_set_identifier&gt;]
- [--all | -a]</pre>
+ [--all | -a] [--output-format=&lt;fmt&gt; | -o &lt;fmt&gt;]</pre>
<div class="attribution">
</div></div>
</div>
@@ -808,13 +808,44 @@ a valid nsid.</p></div>
subsystem, whether attached or inactive.
</p>
</dd>
+<dt class="hdlist1">
+-o &lt;format&gt;
+</dt>
+<dt class="hdlist1">
+--output-format=&lt;format&gt;
+</dt>
+<dd>
+<p>
+ Set the reporting format to <em>normal</em>, or <em>json</em>.
+ Only one output format can be used at a time.
+</p>
+</dd>
</dl></div>
</div>
</div>
<div class="sect1">
<h2 id="_examples">EXAMPLES</h2>
<div class="sectionbody">
-<div class="paragraph"><p>No examples yet.</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+Print the namespaces present for zoned command set in JSON format
+</p>
+<div class="listingblock">
+<div class="content">
+<pre><code># nvme list-ns /dev/nvme0 -y 2 -a -o json</code></pre>
+</div></div>
+</li>
+<li>
+<p>
+Print the namespaces present for NVM Command Set in normal format
+</p>
+<div class="listingblock">
+<div class="content">
+<pre><code># nvme list-ns /dev/nvme0</code></pre>
+</div></div>
+</li>
+</ul></div>
</div>
</div>
<div class="sect1">
@@ -828,7 +859,7 @@ a valid nsid.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2020-05-06 10:35:44 CEST
+ 2021-05-16 10:13:29 IST
</div>
</div>
</body>
diff --git a/Documentation/nvme-list-ns.txt b/Documentation/nvme-list-ns.txt
index 6d7c1f4..0ccd1ad 100644
--- a/Documentation/nvme-list-ns.txt
+++ b/Documentation/nvme-list-ns.txt
@@ -10,7 +10,7 @@ SYNOPSIS
[verse]
'nvme list-ns' <device> [--namespace-id=<nsid> | -n <nsid>]
[--csi=<command_set_identifier> | -y <command_set_identifier>]
- [--all | -a]
+ [--all | -a] [--output-format=<fmt> | -o <fmt>]
DESCRIPTION
-----------
@@ -41,9 +41,24 @@ OPTIONS
Retrieve the identify list structure for all namespaces in the
subsystem, whether attached or inactive.
+-o <format>::
+--output-format=<format>::
+ Set the reporting format to 'normal', or 'json'.
+ Only one output format can be used at a time.
+
EXAMPLES
--------
-No examples yet.
+* Print the namespaces present for zoned command set in JSON format
++
+------------
+# nvme list-ns /dev/nvme0 -y 2 -a -o json
+------------
+
+* Print the namespaces present for NVM Command Set in normal format
++
+------------
+# nvme list-ns /dev/nvme0
+------------
NVME
----
diff --git a/Documentation/nvme-micron-smart-add-log.1 b/Documentation/nvme-micron-smart-add-log.1
new file mode 100644
index 0000000..b059970
--- /dev/null
+++ b/Documentation/nvme-micron-smart-add-log.1
@@ -0,0 +1,87 @@
+'\" t
+.\" Title: nvme-micron-smart-add-log
+.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 05/31/2021
+.\" Manual: NVMe Manual
+.\" Source: NVMe
+.\" Language: English
+.\"
+.TH "NVME\-MICRON\-SMART\" "1" "05/31/2021" "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-micron-smart-add-log \- Retrieves NAND statistics (2200 model drives) or Extended SMART information (OCP complaint models) of given micron device
+.SH "SYNOPSIS"
+.sp
+.nf
+\fInvme micron vs\-smart\-add\-log\fR <device> \-f <json|normal>
+.fi
+.SH "DESCRIPTION"
+.sp
+This command prints NAND information (Total bytes written, Bad block count and Erase failures etc) for the given micron device if its of 2200 model controller\&. For OCP complaint controllers this command print extended SMART health data along with NAND information (if available)
+.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
+The \fI\-f\fR option controls the displayed output data format based on the option value\&. If the option value is \fIjson\fR (which is enabled by default), output data is printed in JSON format\&. If option value is \fInormal\fR the output is displayed in non\-JSON format\&.
+.sp
+This will only work on Micron devices devices of model numbers 54XX and OCP complaint controllers\&. Support for new devices may be added subsequently\&.
+.SH "OPTIONS"
+.sp
+\-f <json|normal> controls the format of displayed output\&.
+.SH "EXAMPLES"
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Retrieve NAND/extended SMART data and display in json format
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+# nvme micron vs\-nand\-stats /dev/nvme0
+
+* Retrieve NAND/extended SMART data and display in non\-json format
++
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.sp
+# nvme micron vs\-nand\-stats /dev/nvme0 \-f normal
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+NVME
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Part of the nvme\-user suite
diff --git a/Documentation/nvme-micron-smart-add-log.html b/Documentation/nvme-micron-smart-add-log.html
new file mode 100644
index 0000000..1f8216b
--- /dev/null
+++ b/Documentation/nvme-micron-smart-add-log.html
@@ -0,0 +1,815 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+ "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
+<meta name="generator" content="AsciiDoc 8.6.10" />
+<title>nvme-micron-smart-add-log(1)</title>
+<style type="text/css">
+/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
+
+/* Default font. */
+body {
+ font-family: Georgia,serif;
+}
+
+/* Title font. */
+h1, h2, h3, h4, h5, h6,
+div.title, caption.title,
+thead, p.table.header,
+#toctitle,
+#author, #revnumber, #revdate, #revremark,
+#footer {
+ font-family: Arial,Helvetica,sans-serif;
+}
+
+body {
+ margin: 1em 5% 1em 5%;
+}
+
+a {
+ color: blue;
+ text-decoration: underline;
+}
+a:visited {
+ color: fuchsia;
+}
+
+em {
+ font-style: italic;
+ color: navy;
+}
+
+strong {
+ font-weight: bold;
+ color: #083194;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ color: #527bbd;
+ margin-top: 1.2em;
+ margin-bottom: 0.5em;
+ line-height: 1.3;
+}
+
+h1, h2, h3 {
+ border-bottom: 2px solid silver;
+}
+h2 {
+ padding-top: 0.5em;
+}
+h3 {
+ float: left;
+}
+h3 + * {
+ clear: left;
+}
+h5 {
+ font-size: 1.0em;
+}
+
+div.sectionbody {
+ margin-left: 0;
+}
+
+hr {
+ border: 1px solid silver;
+}
+
+p {
+ margin-top: 0.5em;
+ margin-bottom: 0.5em;
+}
+
+ul, ol, li > p {
+ margin-top: 0;
+}
+ul > li { color: #aaa; }
+ul > li > * { color: black; }
+
+.monospaced, code, pre {
+ font-family: "Courier New", Courier, monospace;
+ font-size: inherit;
+ color: navy;
+ padding: 0;
+ margin: 0;
+}
+pre {
+ white-space: pre-wrap;
+}
+
+#author {
+ color: #527bbd;
+ font-weight: bold;
+ font-size: 1.1em;
+}
+#email {
+}
+#revnumber, #revdate, #revremark {
+}
+
+#footer {
+ font-size: small;
+ border-top: 2px solid silver;
+ padding-top: 0.5em;
+ margin-top: 4.0em;
+}
+#footer-text {
+ float: left;
+ padding-bottom: 0.5em;
+}
+#footer-badges {
+ float: right;
+ padding-bottom: 0.5em;
+}
+
+#preamble {
+ margin-top: 1.5em;
+ margin-bottom: 1.5em;
+}
+div.imageblock, div.exampleblock, div.verseblock,
+div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
+div.admonitionblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+div.admonitionblock {
+ margin-top: 2.0em;
+ margin-bottom: 2.0em;
+ margin-right: 10%;
+ color: #606060;
+}
+
+div.content { /* Block element content. */
+ padding: 0;
+}
+
+/* Block element titles. */
+div.title, caption.title {
+ color: #527bbd;
+ font-weight: bold;
+ text-align: left;
+ margin-top: 1.0em;
+ margin-bottom: 0.5em;
+}
+div.title + * {
+ margin-top: 0;
+}
+
+td div.title:first-child {
+ margin-top: 0.0em;
+}
+div.content div.title:first-child {
+ margin-top: 0.0em;
+}
+div.content + div.title {
+ margin-top: 0.0em;
+}
+
+div.sidebarblock > div.content {
+ background: #ffffee;
+ border: 1px solid #dddddd;
+ border-left: 4px solid #f0f0f0;
+ padding: 0.5em;
+}
+
+div.listingblock > div.content {
+ border: 1px solid #dddddd;
+ border-left: 5px solid #f0f0f0;
+ background: #f8f8f8;
+ padding: 0.5em;
+}
+
+div.quoteblock, div.verseblock {
+ padding-left: 1.0em;
+ margin-left: 1.0em;
+ margin-right: 10%;
+ border-left: 5px solid #f0f0f0;
+ color: #888;
+}
+
+div.quoteblock > div.attribution {
+ padding-top: 0.5em;
+ text-align: right;
+}
+
+div.verseblock > pre.content {
+ font-family: inherit;
+ font-size: inherit;
+}
+div.verseblock > div.attribution {
+ padding-top: 0.75em;
+ text-align: left;
+}
+/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
+div.verseblock + div.attribution {
+ text-align: left;
+}
+
+div.admonitionblock .icon {
+ vertical-align: top;
+ font-size: 1.1em;
+ font-weight: bold;
+ text-decoration: underline;
+ color: #527bbd;
+ padding-right: 0.5em;
+}
+div.admonitionblock td.content {
+ padding-left: 0.5em;
+ border-left: 3px solid #dddddd;
+}
+
+div.exampleblock > div.content {
+ border-left: 3px solid #dddddd;
+ padding-left: 0.5em;
+}
+
+div.imageblock div.content { padding-left: 0; }
+span.image img { border-style: none; vertical-align: text-bottom; }
+a.image:visited { color: white; }
+
+dl {
+ margin-top: 0.8em;
+ margin-bottom: 0.8em;
+}
+dt {
+ margin-top: 0.5em;
+ margin-bottom: 0;
+ font-style: normal;
+ color: navy;
+}
+dd > *:first-child {
+ margin-top: 0.1em;
+}
+
+ul, ol {
+ list-style-position: outside;
+}
+ol.arabic {
+ list-style-type: decimal;
+}
+ol.loweralpha {
+ list-style-type: lower-alpha;
+}
+ol.upperalpha {
+ list-style-type: upper-alpha;
+}
+ol.lowerroman {
+ list-style-type: lower-roman;
+}
+ol.upperroman {
+ list-style-type: upper-roman;
+}
+
+div.compact ul, div.compact ol,
+div.compact p, div.compact p,
+div.compact div, div.compact div {
+ margin-top: 0.1em;
+ margin-bottom: 0.1em;
+}
+
+tfoot {
+ font-weight: bold;
+}
+td > div.verse {
+ white-space: pre;
+}
+
+div.hdlist {
+ margin-top: 0.8em;
+ margin-bottom: 0.8em;
+}
+div.hdlist tr {
+ padding-bottom: 15px;
+}
+dt.hdlist1.strong, td.hdlist1.strong {
+ font-weight: bold;
+}
+td.hdlist1 {
+ vertical-align: top;
+ font-style: normal;
+ padding-right: 0.8em;
+ color: navy;
+}
+td.hdlist2 {
+ vertical-align: top;
+}
+div.hdlist.compact tr {
+ margin: 0;
+ padding-bottom: 0;
+}
+
+.comment {
+ background: yellow;
+}
+
+.footnote, .footnoteref {
+ font-size: 0.8em;
+}
+
+span.footnote, span.footnoteref {
+ vertical-align: super;
+}
+
+#footnotes {
+ margin: 20px 0 20px 0;
+ padding: 7px 0 0 0;
+}
+
+#footnotes div.footnote {
+ margin: 0 0 5px 0;
+}
+
+#footnotes hr {
+ border: none;
+ border-top: 1px solid silver;
+ height: 1px;
+ text-align: left;
+ margin-left: 0;
+ width: 20%;
+ min-width: 100px;
+}
+
+div.colist td {
+ padding-right: 0.5em;
+ padding-bottom: 0.3em;
+ vertical-align: top;
+}
+div.colist td img {
+ margin-top: 0.3em;
+}
+
+@media print {
+ #footer-badges { display: none; }
+}
+
+#toc {
+ margin-bottom: 2.5em;
+}
+
+#toctitle {
+ color: #527bbd;
+ font-size: 1.1em;
+ font-weight: bold;
+ margin-top: 1.0em;
+ margin-bottom: 0.1em;
+}
+
+div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+div.toclevel2 {
+ margin-left: 2em;
+ font-size: 0.9em;
+}
+div.toclevel3 {
+ margin-left: 4em;
+ font-size: 0.9em;
+}
+div.toclevel4 {
+ margin-left: 6em;
+ font-size: 0.9em;
+}
+
+span.aqua { color: aqua; }
+span.black { color: black; }
+span.blue { color: blue; }
+span.fuchsia { color: fuchsia; }
+span.gray { color: gray; }
+span.green { color: green; }
+span.lime { color: lime; }
+span.maroon { color: maroon; }
+span.navy { color: navy; }
+span.olive { color: olive; }
+span.purple { color: purple; }
+span.red { color: red; }
+span.silver { color: silver; }
+span.teal { color: teal; }
+span.white { color: white; }
+span.yellow { color: yellow; }
+
+span.aqua-background { background: aqua; }
+span.black-background { background: black; }
+span.blue-background { background: blue; }
+span.fuchsia-background { background: fuchsia; }
+span.gray-background { background: gray; }
+span.green-background { background: green; }
+span.lime-background { background: lime; }
+span.maroon-background { background: maroon; }
+span.navy-background { background: navy; }
+span.olive-background { background: olive; }
+span.purple-background { background: purple; }
+span.red-background { background: red; }
+span.silver-background { background: silver; }
+span.teal-background { background: teal; }
+span.white-background { background: white; }
+span.yellow-background { background: yellow; }
+
+span.big { font-size: 2em; }
+span.small { font-size: 0.6em; }
+
+span.underline { text-decoration: underline; }
+span.overline { text-decoration: overline; }
+span.line-through { text-decoration: line-through; }
+
+div.unbreakable { page-break-inside: avoid; }
+
+
+/*
+ * xhtml11 specific
+ *
+ * */
+
+div.tableblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+div.tableblock > table {
+ border: 3px solid #527bbd;
+}
+thead, p.table.header {
+ font-weight: bold;
+ color: #527bbd;
+}
+p.table {
+ margin-top: 0;
+}
+/* Because the table frame attribute is overriden by CSS in most browsers. */
+div.tableblock > table[frame="void"] {
+ border-style: none;
+}
+div.tableblock > table[frame="hsides"] {
+ border-left-style: none;
+ border-right-style: none;
+}
+div.tableblock > table[frame="vsides"] {
+ border-top-style: none;
+ border-bottom-style: none;
+}
+
+
+/*
+ * html5 specific
+ *
+ * */
+
+table.tableblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+thead, p.tableblock.header {
+ font-weight: bold;
+ color: #527bbd;
+}
+p.tableblock {
+ margin-top: 0;
+}
+table.tableblock {
+ border-width: 3px;
+ border-spacing: 0px;
+ border-style: solid;
+ border-color: #527bbd;
+ border-collapse: collapse;
+}
+th.tableblock, td.tableblock {
+ border-width: 1px;
+ padding: 4px;
+ border-style: solid;
+ border-color: #527bbd;
+}
+
+table.tableblock.frame-topbot {
+ border-left-style: hidden;
+ border-right-style: hidden;
+}
+table.tableblock.frame-sides {
+ border-top-style: hidden;
+ border-bottom-style: hidden;
+}
+table.tableblock.frame-none {
+ border-style: hidden;
+}
+
+th.tableblock.halign-left, td.tableblock.halign-left {
+ text-align: left;
+}
+th.tableblock.halign-center, td.tableblock.halign-center {
+ text-align: center;
+}
+th.tableblock.halign-right, td.tableblock.halign-right {
+ text-align: right;
+}
+
+th.tableblock.valign-top, td.tableblock.valign-top {
+ vertical-align: top;
+}
+th.tableblock.valign-middle, td.tableblock.valign-middle {
+ vertical-align: middle;
+}
+th.tableblock.valign-bottom, td.tableblock.valign-bottom {
+ vertical-align: bottom;
+}
+
+
+/*
+ * manpage specific
+ *
+ * */
+
+body.manpage h1 {
+ padding-top: 0.5em;
+ padding-bottom: 0.5em;
+ border-top: 2px solid silver;
+ border-bottom: 2px solid silver;
+}
+body.manpage h2 {
+ border-style: none;
+}
+body.manpage div.sectionbody {
+ margin-left: 3em;
+}
+
+@media print {
+ body.manpage div#toc { display: none; }
+}
+
+
+</style>
+<script type="text/javascript">
+/*<![CDATA[*/
+var asciidoc = { // Namespace.
+
+/////////////////////////////////////////////////////////////////////
+// Table Of Contents generator
+/////////////////////////////////////////////////////////////////////
+
+/* Author: Mihai Bazon, September 2002
+ * http://students.infoiasi.ro/~mishoo
+ *
+ * Table Of Content generator
+ * Version: 0.4
+ *
+ * Feel free to use this script under the terms of the GNU General Public
+ * License, as long as you do not remove or alter this notice.
+ */
+
+ /* modified by Troy D. Hanson, September 2006. License: GPL */
+ /* modified by Stuart Rackham, 2006, 2009. License: GPL */
+
+// toclevels = 1..4.
+toc: function (toclevels) {
+
+ function getText(el) {
+ var text = "";
+ for (var i = el.firstChild; i != null; i = i.nextSibling) {
+ if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
+ text += i.data;
+ else if (i.firstChild != null)
+ text += getText(i);
+ }
+ return text;
+ }
+
+ function TocEntry(el, text, toclevel) {
+ this.element = el;
+ this.text = text;
+ this.toclevel = toclevel;
+ }
+
+ function tocEntries(el, toclevels) {
+ var result = new Array;
+ var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
+ // Function that scans the DOM tree for header elements (the DOM2
+ // nodeIterator API would be a better technique but not supported by all
+ // browsers).
+ var iterate = function (el) {
+ for (var i = el.firstChild; i != null; i = i.nextSibling) {
+ if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
+ var mo = re.exec(i.tagName);
+ if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
+ result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
+ }
+ iterate(i);
+ }
+ }
+ }
+ iterate(el);
+ return result;
+ }
+
+ var toc = document.getElementById("toc");
+ if (!toc) {
+ return;
+ }
+
+ // Delete existing TOC entries in case we're reloading the TOC.
+ var tocEntriesToRemove = [];
+ var i;
+ for (i = 0; i < toc.childNodes.length; i++) {
+ var entry = toc.childNodes[i];
+ if (entry.nodeName.toLowerCase() == 'div'
+ && entry.getAttribute("class")
+ && entry.getAttribute("class").match(/^toclevel/))
+ tocEntriesToRemove.push(entry);
+ }
+ for (i = 0; i < tocEntriesToRemove.length; i++) {
+ toc.removeChild(tocEntriesToRemove[i]);
+ }
+
+ // Rebuild TOC entries.
+ var entries = tocEntries(document.getElementById("content"), toclevels);
+ for (var i = 0; i < entries.length; ++i) {
+ var entry = entries[i];
+ if (entry.element.id == "")
+ entry.element.id = "_toc_" + i;
+ var a = document.createElement("a");
+ a.href = "#" + entry.element.id;
+ a.appendChild(document.createTextNode(entry.text));
+ var div = document.createElement("div");
+ div.appendChild(a);
+ div.className = "toclevel" + entry.toclevel;
+ toc.appendChild(div);
+ }
+ if (entries.length == 0)
+ toc.parentNode.removeChild(toc);
+},
+
+
+/////////////////////////////////////////////////////////////////////
+// Footnotes generator
+/////////////////////////////////////////////////////////////////////
+
+/* Based on footnote generation code from:
+ * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
+ */
+
+footnotes: function () {
+ // Delete existing footnote entries in case we're reloading the footnodes.
+ var i;
+ var noteholder = document.getElementById("footnotes");
+ if (!noteholder) {
+ return;
+ }
+ var entriesToRemove = [];
+ for (i = 0; i < noteholder.childNodes.length; i++) {
+ var entry = noteholder.childNodes[i];
+ if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
+ entriesToRemove.push(entry);
+ }
+ for (i = 0; i < entriesToRemove.length; i++) {
+ noteholder.removeChild(entriesToRemove[i]);
+ }
+
+ // Rebuild footnote entries.
+ var cont = document.getElementById("content");
+ var spans = cont.getElementsByTagName("span");
+ var refs = {};
+ var n = 0;
+ for (i=0; i<spans.length; i++) {
+ if (spans[i].className == "footnote") {
+ n++;
+ var note = spans[i].getAttribute("data-note");
+ if (!note) {
+ // Use [\s\S] in place of . so multi-line matches work.
+ // Because JavaScript has no s (dotall) regex flag.
+ note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
+ spans[i].innerHTML =
+ "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
+ "' title='View footnote' class='footnote'>" + n + "</a>]";
+ spans[i].setAttribute("data-note", note);
+ }
+ noteholder.innerHTML +=
+ "<div class='footnote' id='_footnote_" + n + "'>" +
+ "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
+ n + "</a>. " + note + "</div>";
+ var id =spans[i].getAttribute("id");
+ if (id != null) refs["#"+id] = n;
+ }
+ }
+ if (n == 0)
+ noteholder.parentNode.removeChild(noteholder);
+ else {
+ // Process footnoterefs.
+ for (i=0; i<spans.length; i++) {
+ if (spans[i].className == "footnoteref") {
+ var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
+ href = href.match(/#.*/)[0]; // Because IE return full URL.
+ n = refs[href];
+ spans[i].innerHTML =
+ "[<a href='#_footnote_" + n +
+ "' title='View footnote' class='footnote'>" + n + "</a>]";
+ }
+ }
+ }
+},
+
+install: function(toclevels) {
+ var timerId;
+
+ function reinstall() {
+ asciidoc.footnotes();
+ if (toclevels) {
+ asciidoc.toc(toclevels);
+ }
+ }
+
+ function reinstallAndRemoveTimer() {
+ clearInterval(timerId);
+ reinstall();
+ }
+
+ timerId = setInterval(reinstall, 500);
+ if (document.addEventListener)
+ document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
+ else
+ window.onload = reinstallAndRemoveTimer;
+}
+
+}
+asciidoc.install();
+/*]]>*/
+</script>
+</head>
+<body class="manpage">
+<div id="header">
+<h1>
+nvme-micron-smart-add-log(1) Manual Page
+</h1>
+<h2>NAME</h2>
+<div class="sectionbody">
+<p>nvme-micron-smart-add-log -
+ Retrieves NAND statistics (2200 model drives) or Extended SMART information (OCP complaint models) of given micron device
+</p>
+</div>
+</div>
+<div id="content">
+<div class="sect1">
+<h2 id="_synopsis">SYNOPSIS</h2>
+<div class="sectionbody">
+<div class="verseblock">
+<pre class="content"><em>nvme micron vs-smart-add-log</em> &lt;device&gt; -f &lt;json|normal&gt;</pre>
+<div class="attribution">
+</div></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_description">DESCRIPTION</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>This command prints NAND information (Total bytes written, Bad block count and
+Erase failures etc) for the given micron device if its of 2200 model controller.
+For OCP complaint controllers this command print extended SMART health data
+along with NAND information (if available)</p></div>
+<div class="paragraph"><p>The &lt;device&gt; parameter is mandatory and may be either the NVMe
+character device (ex: /dev/nvme0), or a namespace block device (ex:
+/dev/nvme0n1).</p></div>
+<div class="paragraph"><p>The <em>-f</em> option controls the displayed output data format based on the option
+value. If the option value is <em>json</em> (which is enabled by default), output data
+is printed in JSON format. If option value is <em>normal</em> the output is displayed
+in non-JSON format.</p></div>
+<div class="paragraph"><p>This will only work on Micron devices devices of model numbers 54XX and OCP
+complaint controllers. Support for new devices may be added subsequently.</p></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_options">OPTIONS</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>-f &lt;json|normal&gt; controls the format of displayed output.</p></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_examples">EXAMPLES</h2>
+<div class="sectionbody">
+<div class="ulist"><ul>
+<li>
+<p>
+Retrieve NAND/extended SMART data and display in json format
+</p>
+<div class="listingblock">
+<div class="content">
+<pre><code># nvme micron vs-nand-stats /dev/nvme0
+
+* Retrieve NAND/extended SMART data and display in non-json format
++</code></pre>
+</div></div>
+</li>
+</ul></div>
+<div class="paragraph"><p># nvme micron vs-nand-stats /dev/nvme0 -f normal</p></div>
+<div class="listingblock">
+<div class="content">
+<pre><code>NVME</code></pre>
+</div></div>
+<div class="paragraph"><p>Part of the nvme-user suite</p></div>
+</div>
+</div>
+</div>
+<div id="footnotes"><hr /></div>
+<div id="footer">
+<div id="footer-text">
+Last updated
+ 2021-05-31 19:28:49 IST
+</div>
+</div>
+</body>
+</html>
diff --git a/Documentation/nvme-micron-smart-add-log.txt b/Documentation/nvme-micron-smart-add-log.txt
new file mode 100644
index 0000000..1fd74ba
--- /dev/null
+++ b/Documentation/nvme-micron-smart-add-log.txt
@@ -0,0 +1,54 @@
+nvme-micron-smart-add-log(1)
+============================
+
+NAME
+----
+nvme-micron-smart-add-log - Retrieves NAND statistics (2200 model drives)
+or Extended SMART information (OCP complaint models) of given micron device
+
+SYNOPSIS
+--------
+[verse]
+'nvme micron vs-smart-add-log' <device> -f <json|normal>
+
+DESCRIPTION
+-----------
+This command prints NAND information (Total bytes written, Bad block count and
+Erase failures etc) for the given micron device if its of 2200 model controller.
+For OCP complaint controllers this command print extended SMART health data
+along with NAND information (if available)
+
+The <device> parameter is mandatory and may be either the NVMe
+character device (ex: /dev/nvme0), or a namespace block device (ex:
+/dev/nvme0n1).
+
+The '-f' option controls the displayed output data format based on the option
+value. If the option value is 'json' (which is enabled by default), output data
+is printed in JSON format. If option value is 'normal' the output is displayed
+in non-JSON format.
+
+This will only work on Micron devices devices of model numbers 54XX and OCP
+complaint controllers. Support for new devices may be added subsequently.
+
+OPTIONS
+-------
+-f <json|normal> controls the format of displayed output.
+
+
+EXAMPLES
+--------
+* Retrieve NAND/extended SMART data and display in json format
++
+------------
+# nvme micron vs-nand-stats /dev/nvme0
+
+* Retrieve NAND/extended SMART data and display in non-json format
++
+------------
+# nvme micron vs-nand-stats /dev/nvme0 -f normal
+
+------------
+
+NVME
+----
+Part of the nvme-user suite
diff --git a/Documentation/nvme-primary-ctrl-caps.1 b/Documentation/nvme-primary-ctrl-caps.1
new file mode 100644
index 0000000..cdf7529
--- /dev/null
+++ b/Documentation/nvme-primary-ctrl-caps.1
@@ -0,0 +1,104 @@
+'\" t
+.\" Title: nvme-primary-ctrl-caps
+.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 05/11/2021
+.\" Manual: NVMe Manual
+.\" Source: NVMe
+.\" Language: English
+.\"
+.TH "NVME\-PRIMARY\-CTRL\" "1" "05/11/2021" "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-primary-ctrl-caps \- Send identify Primary Controller Caps, return result and structure
+.SH "SYNOPSIS"
+.sp
+.nf
+\fInvme primary\-ctrl\-caps\fR <device> [\-o <format> | \-\-output\-format=<format>]
+.fi
+.SH "DESCRIPTION"
+.sp
+For the NVMe device given, sends an identify primary Controller caps command and provides the result and returned structure\&.
+.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
+\-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
+.PP
+\-H, \-\-human\-readable
+.RS 4
+This option will parse and format many of the bit fields into human\-readable formats\&.
+.RE
+.SH "EXAMPLES"
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Get Primary Ctrl Caps of the device in default format
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+# nvme primary\-ctrl\-caps /dev/nvme0
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.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 primary\-ctrl\-caps /dev/nvme0 \-\-human\-readbale
+# nvme primary\-ctrl\-caps /dev/nvme0 \-H
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.SH "NVME"
+.sp
+Part of the nvme\-user suite
diff --git a/Documentation/nvme-primary-ctrl-caps.html b/Documentation/nvme-primary-ctrl-caps.html
new file mode 100644
index 0000000..3cae1a2
--- /dev/null
+++ b/Documentation/nvme-primary-ctrl-caps.html
@@ -0,0 +1,842 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+ "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
+<meta name="generator" content="AsciiDoc 8.6.10" />
+<title>nvme-primary-ctrl-caps(1)</title>
+<style type="text/css">
+/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
+
+/* Default font. */
+body {
+ font-family: Georgia,serif;
+}
+
+/* Title font. */
+h1, h2, h3, h4, h5, h6,
+div.title, caption.title,
+thead, p.table.header,
+#toctitle,
+#author, #revnumber, #revdate, #revremark,
+#footer {
+ font-family: Arial,Helvetica,sans-serif;
+}
+
+body {
+ margin: 1em 5% 1em 5%;
+}
+
+a {
+ color: blue;
+ text-decoration: underline;
+}
+a:visited {
+ color: fuchsia;
+}
+
+em {
+ font-style: italic;
+ color: navy;
+}
+
+strong {
+ font-weight: bold;
+ color: #083194;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ color: #527bbd;
+ margin-top: 1.2em;
+ margin-bottom: 0.5em;
+ line-height: 1.3;
+}
+
+h1, h2, h3 {
+ border-bottom: 2px solid silver;
+}
+h2 {
+ padding-top: 0.5em;
+}
+h3 {
+ float: left;
+}
+h3 + * {
+ clear: left;
+}
+h5 {
+ font-size: 1.0em;
+}
+
+div.sectionbody {
+ margin-left: 0;
+}
+
+hr {
+ border: 1px solid silver;
+}
+
+p {
+ margin-top: 0.5em;
+ margin-bottom: 0.5em;
+}
+
+ul, ol, li > p {
+ margin-top: 0;
+}
+ul > li { color: #aaa; }
+ul > li > * { color: black; }
+
+.monospaced, code, pre {
+ font-family: "Courier New", Courier, monospace;
+ font-size: inherit;
+ color: navy;
+ padding: 0;
+ margin: 0;
+}
+pre {
+ white-space: pre-wrap;
+}
+
+#author {
+ color: #527bbd;
+ font-weight: bold;
+ font-size: 1.1em;
+}
+#email {
+}
+#revnumber, #revdate, #revremark {
+}
+
+#footer {
+ font-size: small;
+ border-top: 2px solid silver;
+ padding-top: 0.5em;
+ margin-top: 4.0em;
+}
+#footer-text {
+ float: left;
+ padding-bottom: 0.5em;
+}
+#footer-badges {
+ float: right;
+ padding-bottom: 0.5em;
+}
+
+#preamble {
+ margin-top: 1.5em;
+ margin-bottom: 1.5em;
+}
+div.imageblock, div.exampleblock, div.verseblock,
+div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
+div.admonitionblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+div.admonitionblock {
+ margin-top: 2.0em;
+ margin-bottom: 2.0em;
+ margin-right: 10%;
+ color: #606060;
+}
+
+div.content { /* Block element content. */
+ padding: 0;
+}
+
+/* Block element titles. */
+div.title, caption.title {
+ color: #527bbd;
+ font-weight: bold;
+ text-align: left;
+ margin-top: 1.0em;
+ margin-bottom: 0.5em;
+}
+div.title + * {
+ margin-top: 0;
+}
+
+td div.title:first-child {
+ margin-top: 0.0em;
+}
+div.content div.title:first-child {
+ margin-top: 0.0em;
+}
+div.content + div.title {
+ margin-top: 0.0em;
+}
+
+div.sidebarblock > div.content {
+ background: #ffffee;
+ border: 1px solid #dddddd;
+ border-left: 4px solid #f0f0f0;
+ padding: 0.5em;
+}
+
+div.listingblock > div.content {
+ border: 1px solid #dddddd;
+ border-left: 5px solid #f0f0f0;
+ background: #f8f8f8;
+ padding: 0.5em;
+}
+
+div.quoteblock, div.verseblock {
+ padding-left: 1.0em;
+ margin-left: 1.0em;
+ margin-right: 10%;
+ border-left: 5px solid #f0f0f0;
+ color: #888;
+}
+
+div.quoteblock > div.attribution {
+ padding-top: 0.5em;
+ text-align: right;
+}
+
+div.verseblock > pre.content {
+ font-family: inherit;
+ font-size: inherit;
+}
+div.verseblock > div.attribution {
+ padding-top: 0.75em;
+ text-align: left;
+}
+/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
+div.verseblock + div.attribution {
+ text-align: left;
+}
+
+div.admonitionblock .icon {
+ vertical-align: top;
+ font-size: 1.1em;
+ font-weight: bold;
+ text-decoration: underline;
+ color: #527bbd;
+ padding-right: 0.5em;
+}
+div.admonitionblock td.content {
+ padding-left: 0.5em;
+ border-left: 3px solid #dddddd;
+}
+
+div.exampleblock > div.content {
+ border-left: 3px solid #dddddd;
+ padding-left: 0.5em;
+}
+
+div.imageblock div.content { padding-left: 0; }
+span.image img { border-style: none; vertical-align: text-bottom; }
+a.image:visited { color: white; }
+
+dl {
+ margin-top: 0.8em;
+ margin-bottom: 0.8em;
+}
+dt {
+ margin-top: 0.5em;
+ margin-bottom: 0;
+ font-style: normal;
+ color: navy;
+}
+dd > *:first-child {
+ margin-top: 0.1em;
+}
+
+ul, ol {
+ list-style-position: outside;
+}
+ol.arabic {
+ list-style-type: decimal;
+}
+ol.loweralpha {
+ list-style-type: lower-alpha;
+}
+ol.upperalpha {
+ list-style-type: upper-alpha;
+}
+ol.lowerroman {
+ list-style-type: lower-roman;
+}
+ol.upperroman {
+ list-style-type: upper-roman;
+}
+
+div.compact ul, div.compact ol,
+div.compact p, div.compact p,
+div.compact div, div.compact div {
+ margin-top: 0.1em;
+ margin-bottom: 0.1em;
+}
+
+tfoot {
+ font-weight: bold;
+}
+td > div.verse {
+ white-space: pre;
+}
+
+div.hdlist {
+ margin-top: 0.8em;
+ margin-bottom: 0.8em;
+}
+div.hdlist tr {
+ padding-bottom: 15px;
+}
+dt.hdlist1.strong, td.hdlist1.strong {
+ font-weight: bold;
+}
+td.hdlist1 {
+ vertical-align: top;
+ font-style: normal;
+ padding-right: 0.8em;
+ color: navy;
+}
+td.hdlist2 {
+ vertical-align: top;
+}
+div.hdlist.compact tr {
+ margin: 0;
+ padding-bottom: 0;
+}
+
+.comment {
+ background: yellow;
+}
+
+.footnote, .footnoteref {
+ font-size: 0.8em;
+}
+
+span.footnote, span.footnoteref {
+ vertical-align: super;
+}
+
+#footnotes {
+ margin: 20px 0 20px 0;
+ padding: 7px 0 0 0;
+}
+
+#footnotes div.footnote {
+ margin: 0 0 5px 0;
+}
+
+#footnotes hr {
+ border: none;
+ border-top: 1px solid silver;
+ height: 1px;
+ text-align: left;
+ margin-left: 0;
+ width: 20%;
+ min-width: 100px;
+}
+
+div.colist td {
+ padding-right: 0.5em;
+ padding-bottom: 0.3em;
+ vertical-align: top;
+}
+div.colist td img {
+ margin-top: 0.3em;
+}
+
+@media print {
+ #footer-badges { display: none; }
+}
+
+#toc {
+ margin-bottom: 2.5em;
+}
+
+#toctitle {
+ color: #527bbd;
+ font-size: 1.1em;
+ font-weight: bold;
+ margin-top: 1.0em;
+ margin-bottom: 0.1em;
+}
+
+div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+div.toclevel2 {
+ margin-left: 2em;
+ font-size: 0.9em;
+}
+div.toclevel3 {
+ margin-left: 4em;
+ font-size: 0.9em;
+}
+div.toclevel4 {
+ margin-left: 6em;
+ font-size: 0.9em;
+}
+
+span.aqua { color: aqua; }
+span.black { color: black; }
+span.blue { color: blue; }
+span.fuchsia { color: fuchsia; }
+span.gray { color: gray; }
+span.green { color: green; }
+span.lime { color: lime; }
+span.maroon { color: maroon; }
+span.navy { color: navy; }
+span.olive { color: olive; }
+span.purple { color: purple; }
+span.red { color: red; }
+span.silver { color: silver; }
+span.teal { color: teal; }
+span.white { color: white; }
+span.yellow { color: yellow; }
+
+span.aqua-background { background: aqua; }
+span.black-background { background: black; }
+span.blue-background { background: blue; }
+span.fuchsia-background { background: fuchsia; }
+span.gray-background { background: gray; }
+span.green-background { background: green; }
+span.lime-background { background: lime; }
+span.maroon-background { background: maroon; }
+span.navy-background { background: navy; }
+span.olive-background { background: olive; }
+span.purple-background { background: purple; }
+span.red-background { background: red; }
+span.silver-background { background: silver; }
+span.teal-background { background: teal; }
+span.white-background { background: white; }
+span.yellow-background { background: yellow; }
+
+span.big { font-size: 2em; }
+span.small { font-size: 0.6em; }
+
+span.underline { text-decoration: underline; }
+span.overline { text-decoration: overline; }
+span.line-through { text-decoration: line-through; }
+
+div.unbreakable { page-break-inside: avoid; }
+
+
+/*
+ * xhtml11 specific
+ *
+ * */
+
+div.tableblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+div.tableblock > table {
+ border: 3px solid #527bbd;
+}
+thead, p.table.header {
+ font-weight: bold;
+ color: #527bbd;
+}
+p.table {
+ margin-top: 0;
+}
+/* Because the table frame attribute is overriden by CSS in most browsers. */
+div.tableblock > table[frame="void"] {
+ border-style: none;
+}
+div.tableblock > table[frame="hsides"] {
+ border-left-style: none;
+ border-right-style: none;
+}
+div.tableblock > table[frame="vsides"] {
+ border-top-style: none;
+ border-bottom-style: none;
+}
+
+
+/*
+ * html5 specific
+ *
+ * */
+
+table.tableblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+thead, p.tableblock.header {
+ font-weight: bold;
+ color: #527bbd;
+}
+p.tableblock {
+ margin-top: 0;
+}
+table.tableblock {
+ border-width: 3px;
+ border-spacing: 0px;
+ border-style: solid;
+ border-color: #527bbd;
+ border-collapse: collapse;
+}
+th.tableblock, td.tableblock {
+ border-width: 1px;
+ padding: 4px;
+ border-style: solid;
+ border-color: #527bbd;
+}
+
+table.tableblock.frame-topbot {
+ border-left-style: hidden;
+ border-right-style: hidden;
+}
+table.tableblock.frame-sides {
+ border-top-style: hidden;
+ border-bottom-style: hidden;
+}
+table.tableblock.frame-none {
+ border-style: hidden;
+}
+
+th.tableblock.halign-left, td.tableblock.halign-left {
+ text-align: left;
+}
+th.tableblock.halign-center, td.tableblock.halign-center {
+ text-align: center;
+}
+th.tableblock.halign-right, td.tableblock.halign-right {
+ text-align: right;
+}
+
+th.tableblock.valign-top, td.tableblock.valign-top {
+ vertical-align: top;
+}
+th.tableblock.valign-middle, td.tableblock.valign-middle {
+ vertical-align: middle;
+}
+th.tableblock.valign-bottom, td.tableblock.valign-bottom {
+ vertical-align: bottom;
+}
+
+
+/*
+ * manpage specific
+ *
+ * */
+
+body.manpage h1 {
+ padding-top: 0.5em;
+ padding-bottom: 0.5em;
+ border-top: 2px solid silver;
+ border-bottom: 2px solid silver;
+}
+body.manpage h2 {
+ border-style: none;
+}
+body.manpage div.sectionbody {
+ margin-left: 3em;
+}
+
+@media print {
+ body.manpage div#toc { display: none; }
+}
+
+
+</style>
+<script type="text/javascript">
+/*<![CDATA[*/
+var asciidoc = { // Namespace.
+
+/////////////////////////////////////////////////////////////////////
+// Table Of Contents generator
+/////////////////////////////////////////////////////////////////////
+
+/* Author: Mihai Bazon, September 2002
+ * http://students.infoiasi.ro/~mishoo
+ *
+ * Table Of Content generator
+ * Version: 0.4
+ *
+ * Feel free to use this script under the terms of the GNU General Public
+ * License, as long as you do not remove or alter this notice.
+ */
+
+ /* modified by Troy D. Hanson, September 2006. License: GPL */
+ /* modified by Stuart Rackham, 2006, 2009. License: GPL */
+
+// toclevels = 1..4.
+toc: function (toclevels) {
+
+ function getText(el) {
+ var text = "";
+ for (var i = el.firstChild; i != null; i = i.nextSibling) {
+ if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
+ text += i.data;
+ else if (i.firstChild != null)
+ text += getText(i);
+ }
+ return text;
+ }
+
+ function TocEntry(el, text, toclevel) {
+ this.element = el;
+ this.text = text;
+ this.toclevel = toclevel;
+ }
+
+ function tocEntries(el, toclevels) {
+ var result = new Array;
+ var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
+ // Function that scans the DOM tree for header elements (the DOM2
+ // nodeIterator API would be a better technique but not supported by all
+ // browsers).
+ var iterate = function (el) {
+ for (var i = el.firstChild; i != null; i = i.nextSibling) {
+ if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
+ var mo = re.exec(i.tagName);
+ if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
+ result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
+ }
+ iterate(i);
+ }
+ }
+ }
+ iterate(el);
+ return result;
+ }
+
+ var toc = document.getElementById("toc");
+ if (!toc) {
+ return;
+ }
+
+ // Delete existing TOC entries in case we're reloading the TOC.
+ var tocEntriesToRemove = [];
+ var i;
+ for (i = 0; i < toc.childNodes.length; i++) {
+ var entry = toc.childNodes[i];
+ if (entry.nodeName.toLowerCase() == 'div'
+ && entry.getAttribute("class")
+ && entry.getAttribute("class").match(/^toclevel/))
+ tocEntriesToRemove.push(entry);
+ }
+ for (i = 0; i < tocEntriesToRemove.length; i++) {
+ toc.removeChild(tocEntriesToRemove[i]);
+ }
+
+ // Rebuild TOC entries.
+ var entries = tocEntries(document.getElementById("content"), toclevels);
+ for (var i = 0; i < entries.length; ++i) {
+ var entry = entries[i];
+ if (entry.element.id == "")
+ entry.element.id = "_toc_" + i;
+ var a = document.createElement("a");
+ a.href = "#" + entry.element.id;
+ a.appendChild(document.createTextNode(entry.text));
+ var div = document.createElement("div");
+ div.appendChild(a);
+ div.className = "toclevel" + entry.toclevel;
+ toc.appendChild(div);
+ }
+ if (entries.length == 0)
+ toc.parentNode.removeChild(toc);
+},
+
+
+/////////////////////////////////////////////////////////////////////
+// Footnotes generator
+/////////////////////////////////////////////////////////////////////
+
+/* Based on footnote generation code from:
+ * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
+ */
+
+footnotes: function () {
+ // Delete existing footnote entries in case we're reloading the footnodes.
+ var i;
+ var noteholder = document.getElementById("footnotes");
+ if (!noteholder) {
+ return;
+ }
+ var entriesToRemove = [];
+ for (i = 0; i < noteholder.childNodes.length; i++) {
+ var entry = noteholder.childNodes[i];
+ if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
+ entriesToRemove.push(entry);
+ }
+ for (i = 0; i < entriesToRemove.length; i++) {
+ noteholder.removeChild(entriesToRemove[i]);
+ }
+
+ // Rebuild footnote entries.
+ var cont = document.getElementById("content");
+ var spans = cont.getElementsByTagName("span");
+ var refs = {};
+ var n = 0;
+ for (i=0; i<spans.length; i++) {
+ if (spans[i].className == "footnote") {
+ n++;
+ var note = spans[i].getAttribute("data-note");
+ if (!note) {
+ // Use [\s\S] in place of . so multi-line matches work.
+ // Because JavaScript has no s (dotall) regex flag.
+ note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
+ spans[i].innerHTML =
+ "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
+ "' title='View footnote' class='footnote'>" + n + "</a>]";
+ spans[i].setAttribute("data-note", note);
+ }
+ noteholder.innerHTML +=
+ "<div class='footnote' id='_footnote_" + n + "'>" +
+ "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
+ n + "</a>. " + note + "</div>";
+ var id =spans[i].getAttribute("id");
+ if (id != null) refs["#"+id] = n;
+ }
+ }
+ if (n == 0)
+ noteholder.parentNode.removeChild(noteholder);
+ else {
+ // Process footnoterefs.
+ for (i=0; i<spans.length; i++) {
+ if (spans[i].className == "footnoteref") {
+ var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
+ href = href.match(/#.*/)[0]; // Because IE return full URL.
+ n = refs[href];
+ spans[i].innerHTML =
+ "[<a href='#_footnote_" + n +
+ "' title='View footnote' class='footnote'>" + n + "</a>]";
+ }
+ }
+ }
+},
+
+install: function(toclevels) {
+ var timerId;
+
+ function reinstall() {
+ asciidoc.footnotes();
+ if (toclevels) {
+ asciidoc.toc(toclevels);
+ }
+ }
+
+ function reinstallAndRemoveTimer() {
+ clearInterval(timerId);
+ reinstall();
+ }
+
+ timerId = setInterval(reinstall, 500);
+ if (document.addEventListener)
+ document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
+ else
+ window.onload = reinstallAndRemoveTimer;
+}
+
+}
+asciidoc.install();
+/*]]>*/
+</script>
+</head>
+<body class="manpage">
+<div id="header">
+<h1>
+nvme-primary-ctrl-caps(1) Manual Page
+</h1>
+<h2>NAME</h2>
+<div class="sectionbody">
+<p>nvme-primary-ctrl-caps -
+ Send identify Primary Controller Caps, return result and structure
+</p>
+</div>
+</div>
+<div id="content">
+<div class="sect1">
+<h2 id="_synopsis">SYNOPSIS</h2>
+<div class="sectionbody">
+<div class="verseblock">
+<pre class="content"><em>nvme primary-ctrl-caps</em> &lt;device&gt; [-o &lt;format&gt; | --output-format=&lt;format&gt;]</pre>
+<div class="attribution">
+</div></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_description">DESCRIPTION</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>For the NVMe device given, sends an identify primary Controller caps command and
+provides the result and returned structure.</p></div>
+<div class="paragraph"><p>The &lt;device&gt; parameter is mandatory and may be either the NVMe character
+device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1).</p></div>
+<div class="paragraph"><p>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.</p></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_options">OPTIONS</h2>
+<div class="sectionbody">
+<div class="dlist"><dl>
+<dt class="hdlist1">
+-o &lt;format&gt;
+</dt>
+<dt class="hdlist1">
+--output-format=&lt;format&gt;
+</dt>
+<dd>
+<p>
+ Set the reporting format to <em>normal</em>, <em>json</em>, or
+ <em>binary</em>. Only one output format can be used at a time.
+</p>
+</dd>
+<dt class="hdlist1">
+-H
+</dt>
+<dt class="hdlist1">
+--human-readable
+</dt>
+<dd>
+<p>
+ This option will parse and format many of the bit fields
+ into human-readable formats.
+</p>
+</dd>
+</dl></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_examples">EXAMPLES</h2>
+<div class="sectionbody">
+<div class="ulist"><ul>
+<li>
+<p>
+Get Primary Ctrl Caps of the device in default format
+</p>
+<div class="listingblock">
+<div class="content">
+<pre><code># nvme primary-ctrl-caps /dev/nvme0</code></pre>
+</div></div>
+</li>
+<li>
+<p>
+Has the program interpret the returned buffer and display the known
+fields in a human readable format:
+</p>
+<div class="listingblock">
+<div class="content">
+<pre><code># nvme primary-ctrl-caps /dev/nvme0 --human-readbale
+# nvme primary-ctrl-caps /dev/nvme0 -H</code></pre>
+</div></div>
+</li>
+</ul></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_nvme">NVME</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Part of the nvme-user suite</p></div>
+</div>
+</div>
+</div>
+<div id="footnotes"><hr /></div>
+<div id="footer">
+<div id="footer-text">
+Last updated
+ 2021-05-11 12:31:04 IST
+</div>
+</div>
+</body>
+</html>
diff --git a/Documentation/nvme-primary-ctrl-caps.txt b/Documentation/nvme-primary-ctrl-caps.txt
new file mode 100644
index 0000000..e17093f
--- /dev/null
+++ b/Documentation/nvme-primary-ctrl-caps.txt
@@ -0,0 +1,53 @@
+nvme-primary-ctrl-caps(1)
+=========================
+
+NAME
+----
+nvme-primary-ctrl-caps - Send identify Primary Controller Caps, return result and structure
+
+SYNOPSIS
+--------
+[verse]
+'nvme primary-ctrl-caps' <device> [-o <format> | --output-format=<format>]
+
+DESCRIPTION
+-----------
+For the NVMe device given, sends an identify primary Controller caps command and
+provides the result and returned structure.
+
+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
+-------
+-o <format>::
+--output-format=<format>::
+ Set the reporting format to 'normal', 'json', or
+ 'binary'. Only one output format can be used at a time.
+
+-H::
+--human-readable::
+ This option will parse and format many of the bit fields
+ into human-readable formats.
+
+EXAMPLES
+--------
+* Get Primary Ctrl Caps of the device in default format
++
+------------
+# nvme primary-ctrl-caps /dev/nvme0
+------------
+* Has the program interpret the returned buffer and display the known
+fields in a human readable format:
++
+------------
+# nvme primary-ctrl-caps /dev/nvme0 --human-readbale
+# nvme primary-ctrl-caps /dev/nvme0 -H
+------------
+NVME
+----
+Part of the nvme-user suite
diff --git a/Documentation/nvme-read.1 b/Documentation/nvme-read.1
index 7ba8d6a..303fc05 100644
--- a/Documentation/nvme-read.1
+++ b/Documentation/nvme-read.1
@@ -1,13 +1,13 @@
'\" t
.\" Title: nvme-read
-.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
-.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 10/20/2020
+.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 07/09/2021
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-READ" "1" "10/20/2020" "NVMe" "NVMe Manual"
+.TH "NVME\-READ" "1" "07/09/2021" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -50,6 +50,7 @@ nvme-read \- Send an NVMe Read command, provide results
[\-\-show\-command | \-v]
[\-\-dry\-run | \-w]
[\-\-latency | \-t]
+ [\-\-storage\-tag\-check<storage\-tag\-check> | \-C <storage\-tag\-check>]
.fi
.SH "DESCRIPTION"
.sp
@@ -178,6 +179,11 @@ be set\&. Otherwise \-\-dry\-run option will be
.RS 4
Print out the latency the IOCTL took (in us)\&.
.RE
+.PP
+\-\-storage\-tag\-check=<storage\-tag\-check>, \-C <storage\-tag\-check>
+.RS 4
+This bit specifies the Storage Tag field shall be checked as part of end\-to\-end data protection processing\&.
+.RE
.SH "EXAMPLES"
.sp
No examples yet\&.
diff --git a/Documentation/nvme-read.html b/Documentation/nvme-read.html
index fdc1606..d61580c 100644
--- a/Documentation/nvme-read.html
+++ b/Documentation/nvme-read.html
@@ -766,7 +766,8 @@ nvme-read(1) Manual Page
[--dsm=&lt;dsm&gt; | -D &lt;dsm&gt;]
[--show-command | -v]
[--dry-run | -w]
- [--latency | -t]</pre>
+ [--latency | -t]
+ [--storage-tag-check&lt;storage-tag-check&gt; | -C &lt;storage-tag-check&gt;]</pre>
<div class="attribution">
</div></div>
</div>
@@ -1013,6 +1014,18 @@ metadata is passes.</p></td>
Print out the latency the IOCTL took (in us).
</p>
</dd>
+<dt class="hdlist1">
+--storage-tag-check=&lt;storage-tag-check&gt;
+</dt>
+<dt class="hdlist1">
+-C &lt;storage-tag-check&gt;
+</dt>
+<dd>
+<p>
+ This bit specifies the Storage Tag field shall be checked as part of end-to-end
+ data protection processing.
+</p>
+</dd>
</dl></div>
</div>
</div>
@@ -1033,7 +1046,7 @@ metadata is passes.</p></td>
<div id="footer">
<div id="footer-text">
Last updated
- 2019-10-12 00:12:24 JST
+ 2021-07-09 14:16:42 IST
</div>
</div>
</body>
diff --git a/Documentation/nvme-read.txt b/Documentation/nvme-read.txt
index 55a701c..58902e7 100644
--- a/Documentation/nvme-read.txt
+++ b/Documentation/nvme-read.txt
@@ -26,6 +26,7 @@ SYNOPSIS
[--show-command | -v]
[--dry-run | -w]
[--latency | -t]
+ [--storage-tag-check<storage-tag-check> | -C <storage-tag-check>]
DESCRIPTION
-----------
@@ -128,6 +129,11 @@ metadata is passes.
--latency::
Print out the latency the IOCTL took (in us).
+--storage-tag-check=<storage-tag-check>::
+-C <storage-tag-check>::
+ This bit specifies the Storage Tag field shall be checked as part of end-to-end
+ data protection processing.
+
EXAMPLES
--------
No examples yet.
diff --git a/Documentation/nvme-resv-register.1 b/Documentation/nvme-resv-register.1
index 48b391f..3d9a869 100644
--- a/Documentation/nvme-resv-register.1
+++ b/Documentation/nvme-resv-register.1
@@ -98,7 +98,7 @@ T}
.sp 1
.RE
.PP
-\-a <rrega>, \-\-rrega=<rrega>
+\-r <rrega>, \-\-rrega=<rrega>
.RS 4
Reservation Register Action: This field specifies the registration action that is performed by the command\&.
.TS
diff --git a/Documentation/nvme-resv-register.html b/Documentation/nvme-resv-register.html
index a17f869..15bec28 100644
--- a/Documentation/nvme-resv-register.html
+++ b/Documentation/nvme-resv-register.html
@@ -861,7 +861,7 @@ a power loss.</p></td>
</div>
</dd>
<dt class="hdlist1">
--a &lt;rrega&gt;
+-r &lt;rrega&gt;
</dt>
<dt class="hdlist1">
--rrega=&lt;rrega&gt;
diff --git a/Documentation/nvme-resv-register.txt b/Documentation/nvme-resv-register.txt
index 076e979..e0553f4 100644
--- a/Documentation/nvme-resv-register.txt
+++ b/Documentation/nvme-resv-register.txt
@@ -62,7 +62,7 @@ are cleared on a power on.
a power loss.
|=================
--a <rrega>::
+-r <rrega>::
--rrega=<rrega>::
Reservation Register Action: This field specifies the registration
action that is performed by the command.
diff --git a/Documentation/nvme-set-feature.1 b/Documentation/nvme-set-feature.1
index 913df38..57e8c08 100644
--- a/Documentation/nvme-set-feature.1
+++ b/Documentation/nvme-set-feature.1
@@ -1,13 +1,13 @@
'\" t
.\" Title: nvme-set-feature
-.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
-.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 10/20/2020
+.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 05/16/2021
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-SET\-FEATURE" "1" "10/20/2020" "NVMe" "NVMe Manual"
+.TH "NVME\-SET\-FEATURE" "1" "05/16/2021" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -34,6 +34,7 @@ nvme-set-feature \- Sets an NVMe feature, returns applicable results
.nf
\fInvme set\-feature\fR <device> [\-\-namespace\-id=<nsid> | \-n <nsid>]
[\-\-feature\-id=<fid> | \-f <fid>] [\-\-value=<value> | \-v <value>]
+ [\-\-uuid\-index=<uuid\-index> | \-U <uuid_index>]
[\-\-data\-len=<data\-len> | \-l <data\-len>]
[\-\-data=<data\-file> | \-d <data\-file>]
[\-\-save| \-s]
@@ -76,6 +77,11 @@ The value for command dword 11, the value you want to set the feature to\&.
.RS 4
Save the attribute so that it persists through all power states and resets\&.
.RE
+.PP
+\-U <uuid\-index>, \-\-uuid\-index=<uuid\-index>
+.RS 4
+UUID Index of the feature
+.RE
.SH "EXAMPLES"
.sp
.RS 4
@@ -118,6 +124,8 @@ Sets the host id to the ascii string\&.
.if n \{\
.RE
.\}
+.sp
+nvme set\-feature /dev/nvme0 \-f 0x81 \-l 8 \-U 0x1
.RE
.SH "NVME"
.sp
diff --git a/Documentation/nvme-set-feature.html b/Documentation/nvme-set-feature.html
index b813b91..b5bf779 100644
--- a/Documentation/nvme-set-feature.html
+++ b/Documentation/nvme-set-feature.html
@@ -1,9 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
-<meta name="generator" content="AsciiDoc 8.6.8" />
+<meta name="generator" content="AsciiDoc 8.6.10" />
<title>nvme-set-feature(1)</title>
<style type="text/css">
/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
@@ -94,7 +95,9 @@ ul > li > * { color: black; }
padding: 0;
margin: 0;
}
-
+pre {
+ white-space: pre-wrap;
+}
#author {
color: #527bbd;
@@ -223,7 +226,7 @@ div.exampleblock > div.content {
}
div.imageblock div.content { padding-left: 0; }
-span.image img { border-style: none; }
+span.image img { border-style: none; vertical-align: text-bottom; }
a.image:visited { color: white; }
dl {
@@ -433,7 +436,7 @@ thead, p.table.header {
p.table {
margin-top: 0;
}
-/* Because the table frame attribute is overridden by CSS in most browsers. */
+/* Because the table frame attribute is overriden by CSS in most browsers. */
div.tableblock > table[frame="void"] {
border-style: none;
}
@@ -748,6 +751,7 @@ nvme-set-feature(1) Manual Page
<div class="verseblock">
<pre class="content"><em>nvme set-feature</em> &lt;device&gt; [--namespace-id=&lt;nsid&gt; | -n &lt;nsid&gt;]
[--feature-id=&lt;fid&gt; | -f &lt;fid&gt;] [--value=&lt;value&gt; | -v &lt;value&gt;]
+ [--uuid-index=&lt;uuid-index&gt; | -U &lt;uuid_index&gt;]
[--data-len=&lt;data-len&gt; | -l &lt;data-len&gt;]
[--data=&lt;data-file&gt; | -d &lt;data-file&gt;]
[--save| -s]</pre>
@@ -844,6 +848,17 @@ device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1).</p></di
Save the attribute so that it persists through all power states and resets.
</p>
</dd>
+<dt class="hdlist1">
+-U &lt;uuid-index&gt;
+</dt>
+<dt class="hdlist1">
+--uuid-index=&lt;uuid-index&gt;
+</dt>
+<dd>
+<p>
+ UUID Index of the feature
+</p>
+</dd>
</dl></div>
</div>
</div>
@@ -868,6 +883,7 @@ Sets the host id to the ascii string.
<div class="content">
<pre><code># echo "abcdefgh" | nvme set-feature /dev/nvme0 -f 0x81 -l 8</code></pre>
</div></div>
+<div class="paragraph"><p>nvme set-feature /dev/nvme0 -f 0x81 -l 8 -U 0x1</p></div>
</li>
</ul></div>
</div>
@@ -882,7 +898,8 @@ Sets the host id to the ascii string.
<div id="footnotes"><hr /></div>
<div id="footer">
<div id="footer-text">
-Last updated 2017-02-27 10:11:58 EST
+Last updated
+ 2021-05-16 00:14:28 IST
</div>
</div>
</body>
diff --git a/Documentation/nvme-set-feature.txt b/Documentation/nvme-set-feature.txt
index ca1874d..24a9f40 100644
--- a/Documentation/nvme-set-feature.txt
+++ b/Documentation/nvme-set-feature.txt
@@ -10,6 +10,7 @@ SYNOPSIS
[verse]
'nvme set-feature' <device> [--namespace-id=<nsid> | -n <nsid>]
[--feature-id=<fid> | -f <fid>] [--value=<value> | -v <value>]
+ [--uuid-index=<uuid-index> | -U <uuid_index>]
[--data-len=<data-len> | -l <data-len>]
[--data=<data-file> | -d <data-file>]
[--save| -s]
@@ -59,6 +60,10 @@ OPTIONS
--save::
Save the attribute so that it persists through all power states and resets.
+-U <uuid-index>::
+--uuid-index=<uuid-index>::
+ UUID Index of the feature
+
EXAMPLES
--------
* Sets the Power State (PS) to 1 in feature id 2:
@@ -73,6 +78,8 @@ EXAMPLES
------------
# echo "abcdefgh" | nvme set-feature /dev/nvme0 -f 0x81 -l 8
------------
++
+nvme set-feature /dev/nvme0 -f 0x81 -l 8 -U 0x1
NVME
----
diff --git a/Documentation/nvme-verify.1 b/Documentation/nvme-verify.1
new file mode 100644
index 0000000..80ecee9
--- /dev/null
+++ b/Documentation/nvme-verify.1
@@ -0,0 +1,151 @@
+'\" t
+.\" Title: nvme-verify
+.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 07/09/2021
+.\" Manual: NVMe Manual
+.\" Source: NVMe
+.\" Language: English
+.\"
+.TH "NVME\-VERIFY" "1" "07/09/2021" "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-verify \- Send an NVMe Verify command, return results
+.SH "SYNOPSIS"
+.sp
+.nf
+\fInvme\-verify\fR <device> [\-\-namespace\-id=<nsid> | \-n <nsid>]
+ [\-\-start\-block=<slba> | \-s <slba>]
+ [\-\-block\-count=<nlb> | \-c <nlb>]
+ [\-\-limited\-retry | \-l]
+ [\-\-force\-unit\-access | \-f]
+ [\-\-prinfo=<prinfo> | \-p <prinfo>]
+ [\-\-ref\-tag=<reftag> | \-r <reftag>]
+ [\-\-app\-tag\-mask=<appmask> | \-m <appmask>]
+ [\-\-app\-tag=<apptag> | \-a <apptag>]
+ [\-\-storage\-tag<storage\-tag> | \-S <storage\-tag>]
+ [\-\-storage\-tag\-check<storage\-tag\-check> | \-C <storage\-tag\-check>]
+.fi
+.SH "DESCRIPTION"
+.sp
+The Verify command verifies the integrity of the stored information by reading data and metadata\&.
+.SH "OPTIONS"
+.PP
+\-\-namespace\-id=<nsid>, \-n <nsid>
+.RS 4
+Namespace ID use in the command\&.
+.RE
+.PP
+\-\-start\-block=<slba>, \-s <slba>
+.RS 4
+Start block address\&.
+.RE
+.PP
+\-\-block\-count=<nlb>, \-c <nlb>
+.RS 4
+Number of logical blocks to Verify\&.
+.RE
+.PP
+\-\-limited\-retry, \-l
+.RS 4
+Sets the limited retry flag\&.
+.RE
+.PP
+\-\-force\-unit\-access, \-f
+.RS 4
+Set the force\-unit access flag\&.
+.RE
+.PP
+\-\-prinfo=<prinfo>, \-p <prinfo>
+.RS 4
+Protection Information field definition\&.
+.TS
+allbox tab(:);
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt
+lt lt.
+T{
+Bit
+T}:T{
+Description
+T}
+T{
+3
+T}:T{
+PRACT: Protection Information Action\&. When set to 1, PI is stripped/inserted on read/write when the block format\(cqs metadata size is 8\&. When set to 0, metadata is passes\&.
+T}
+T{
+2:0
+T}:T{
+PRCHK: Protection Information Check:
+T}
+T{
+2
+T}:T{
+Set to 1 enables checking the guard tag
+T}
+T{
+1
+T}:T{
+Set to 1 enables checking the application tag
+T}
+T{
+0
+T}:T{
+Set to 1 enables checking the reference tag
+T}
+.TE
+.sp 1
+.RE
+.PP
+\-\-ref\-tag=<reftag>, \-r <reftag>
+.RS 4
+Optional reftag when used with protection information\&.
+.RE
+.PP
+\-\-app\-tag\-mask=<appmask>, \-m <appmask>
+.RS 4
+Optional application tag mask when used with protection information\&.
+.RE
+.PP
+\-\-app\-tag=<apptag>, \-a <apptag>
+.RS 4
+Optional application tag when used with protection information\&.
+.RE
+.PP
+\-\-storage\-tag=<storage\-tag>, \-S <storage\-tag>
+.RS 4
+Variable Sized Expected Logical Block Storage Tag(ELBST) and Expected Logical Block Reference Tag (ELBRT), CDW2 and CDW3 (00:47) bits\&.
+.RE
+.PP
+\-\-storage\-tag\-check=<storage\-tag\-check>, \-C <storage\-tag\-check>
+.RS 4
+This bit specifies the Storage Tag field shall be checked as part of Verify operation\&.
+.RE
+.SH "EXAMPLES"
+.sp
+No examples yet\&.
+.SH "NVME"
+.sp
+Part of the nvme\-user suite
diff --git a/Documentation/nvme-verify.html b/Documentation/nvme-verify.html
new file mode 100644
index 0000000..3567ec4
--- /dev/null
+++ b/Documentation/nvme-verify.html
@@ -0,0 +1,961 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+ "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
+<meta name="generator" content="AsciiDoc 8.6.10" />
+<title>nvme-verify(1)</title>
+<style type="text/css">
+/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
+
+/* Default font. */
+body {
+ font-family: Georgia,serif;
+}
+
+/* Title font. */
+h1, h2, h3, h4, h5, h6,
+div.title, caption.title,
+thead, p.table.header,
+#toctitle,
+#author, #revnumber, #revdate, #revremark,
+#footer {
+ font-family: Arial,Helvetica,sans-serif;
+}
+
+body {
+ margin: 1em 5% 1em 5%;
+}
+
+a {
+ color: blue;
+ text-decoration: underline;
+}
+a:visited {
+ color: fuchsia;
+}
+
+em {
+ font-style: italic;
+ color: navy;
+}
+
+strong {
+ font-weight: bold;
+ color: #083194;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ color: #527bbd;
+ margin-top: 1.2em;
+ margin-bottom: 0.5em;
+ line-height: 1.3;
+}
+
+h1, h2, h3 {
+ border-bottom: 2px solid silver;
+}
+h2 {
+ padding-top: 0.5em;
+}
+h3 {
+ float: left;
+}
+h3 + * {
+ clear: left;
+}
+h5 {
+ font-size: 1.0em;
+}
+
+div.sectionbody {
+ margin-left: 0;
+}
+
+hr {
+ border: 1px solid silver;
+}
+
+p {
+ margin-top: 0.5em;
+ margin-bottom: 0.5em;
+}
+
+ul, ol, li > p {
+ margin-top: 0;
+}
+ul > li { color: #aaa; }
+ul > li > * { color: black; }
+
+.monospaced, code, pre {
+ font-family: "Courier New", Courier, monospace;
+ font-size: inherit;
+ color: navy;
+ padding: 0;
+ margin: 0;
+}
+pre {
+ white-space: pre-wrap;
+}
+
+#author {
+ color: #527bbd;
+ font-weight: bold;
+ font-size: 1.1em;
+}
+#email {
+}
+#revnumber, #revdate, #revremark {
+}
+
+#footer {
+ font-size: small;
+ border-top: 2px solid silver;
+ padding-top: 0.5em;
+ margin-top: 4.0em;
+}
+#footer-text {
+ float: left;
+ padding-bottom: 0.5em;
+}
+#footer-badges {
+ float: right;
+ padding-bottom: 0.5em;
+}
+
+#preamble {
+ margin-top: 1.5em;
+ margin-bottom: 1.5em;
+}
+div.imageblock, div.exampleblock, div.verseblock,
+div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
+div.admonitionblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+div.admonitionblock {
+ margin-top: 2.0em;
+ margin-bottom: 2.0em;
+ margin-right: 10%;
+ color: #606060;
+}
+
+div.content { /* Block element content. */
+ padding: 0;
+}
+
+/* Block element titles. */
+div.title, caption.title {
+ color: #527bbd;
+ font-weight: bold;
+ text-align: left;
+ margin-top: 1.0em;
+ margin-bottom: 0.5em;
+}
+div.title + * {
+ margin-top: 0;
+}
+
+td div.title:first-child {
+ margin-top: 0.0em;
+}
+div.content div.title:first-child {
+ margin-top: 0.0em;
+}
+div.content + div.title {
+ margin-top: 0.0em;
+}
+
+div.sidebarblock > div.content {
+ background: #ffffee;
+ border: 1px solid #dddddd;
+ border-left: 4px solid #f0f0f0;
+ padding: 0.5em;
+}
+
+div.listingblock > div.content {
+ border: 1px solid #dddddd;
+ border-left: 5px solid #f0f0f0;
+ background: #f8f8f8;
+ padding: 0.5em;
+}
+
+div.quoteblock, div.verseblock {
+ padding-left: 1.0em;
+ margin-left: 1.0em;
+ margin-right: 10%;
+ border-left: 5px solid #f0f0f0;
+ color: #888;
+}
+
+div.quoteblock > div.attribution {
+ padding-top: 0.5em;
+ text-align: right;
+}
+
+div.verseblock > pre.content {
+ font-family: inherit;
+ font-size: inherit;
+}
+div.verseblock > div.attribution {
+ padding-top: 0.75em;
+ text-align: left;
+}
+/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
+div.verseblock + div.attribution {
+ text-align: left;
+}
+
+div.admonitionblock .icon {
+ vertical-align: top;
+ font-size: 1.1em;
+ font-weight: bold;
+ text-decoration: underline;
+ color: #527bbd;
+ padding-right: 0.5em;
+}
+div.admonitionblock td.content {
+ padding-left: 0.5em;
+ border-left: 3px solid #dddddd;
+}
+
+div.exampleblock > div.content {
+ border-left: 3px solid #dddddd;
+ padding-left: 0.5em;
+}
+
+div.imageblock div.content { padding-left: 0; }
+span.image img { border-style: none; vertical-align: text-bottom; }
+a.image:visited { color: white; }
+
+dl {
+ margin-top: 0.8em;
+ margin-bottom: 0.8em;
+}
+dt {
+ margin-top: 0.5em;
+ margin-bottom: 0;
+ font-style: normal;
+ color: navy;
+}
+dd > *:first-child {
+ margin-top: 0.1em;
+}
+
+ul, ol {
+ list-style-position: outside;
+}
+ol.arabic {
+ list-style-type: decimal;
+}
+ol.loweralpha {
+ list-style-type: lower-alpha;
+}
+ol.upperalpha {
+ list-style-type: upper-alpha;
+}
+ol.lowerroman {
+ list-style-type: lower-roman;
+}
+ol.upperroman {
+ list-style-type: upper-roman;
+}
+
+div.compact ul, div.compact ol,
+div.compact p, div.compact p,
+div.compact div, div.compact div {
+ margin-top: 0.1em;
+ margin-bottom: 0.1em;
+}
+
+tfoot {
+ font-weight: bold;
+}
+td > div.verse {
+ white-space: pre;
+}
+
+div.hdlist {
+ margin-top: 0.8em;
+ margin-bottom: 0.8em;
+}
+div.hdlist tr {
+ padding-bottom: 15px;
+}
+dt.hdlist1.strong, td.hdlist1.strong {
+ font-weight: bold;
+}
+td.hdlist1 {
+ vertical-align: top;
+ font-style: normal;
+ padding-right: 0.8em;
+ color: navy;
+}
+td.hdlist2 {
+ vertical-align: top;
+}
+div.hdlist.compact tr {
+ margin: 0;
+ padding-bottom: 0;
+}
+
+.comment {
+ background: yellow;
+}
+
+.footnote, .footnoteref {
+ font-size: 0.8em;
+}
+
+span.footnote, span.footnoteref {
+ vertical-align: super;
+}
+
+#footnotes {
+ margin: 20px 0 20px 0;
+ padding: 7px 0 0 0;
+}
+
+#footnotes div.footnote {
+ margin: 0 0 5px 0;
+}
+
+#footnotes hr {
+ border: none;
+ border-top: 1px solid silver;
+ height: 1px;
+ text-align: left;
+ margin-left: 0;
+ width: 20%;
+ min-width: 100px;
+}
+
+div.colist td {
+ padding-right: 0.5em;
+ padding-bottom: 0.3em;
+ vertical-align: top;
+}
+div.colist td img {
+ margin-top: 0.3em;
+}
+
+@media print {
+ #footer-badges { display: none; }
+}
+
+#toc {
+ margin-bottom: 2.5em;
+}
+
+#toctitle {
+ color: #527bbd;
+ font-size: 1.1em;
+ font-weight: bold;
+ margin-top: 1.0em;
+ margin-bottom: 0.1em;
+}
+
+div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+div.toclevel2 {
+ margin-left: 2em;
+ font-size: 0.9em;
+}
+div.toclevel3 {
+ margin-left: 4em;
+ font-size: 0.9em;
+}
+div.toclevel4 {
+ margin-left: 6em;
+ font-size: 0.9em;
+}
+
+span.aqua { color: aqua; }
+span.black { color: black; }
+span.blue { color: blue; }
+span.fuchsia { color: fuchsia; }
+span.gray { color: gray; }
+span.green { color: green; }
+span.lime { color: lime; }
+span.maroon { color: maroon; }
+span.navy { color: navy; }
+span.olive { color: olive; }
+span.purple { color: purple; }
+span.red { color: red; }
+span.silver { color: silver; }
+span.teal { color: teal; }
+span.white { color: white; }
+span.yellow { color: yellow; }
+
+span.aqua-background { background: aqua; }
+span.black-background { background: black; }
+span.blue-background { background: blue; }
+span.fuchsia-background { background: fuchsia; }
+span.gray-background { background: gray; }
+span.green-background { background: green; }
+span.lime-background { background: lime; }
+span.maroon-background { background: maroon; }
+span.navy-background { background: navy; }
+span.olive-background { background: olive; }
+span.purple-background { background: purple; }
+span.red-background { background: red; }
+span.silver-background { background: silver; }
+span.teal-background { background: teal; }
+span.white-background { background: white; }
+span.yellow-background { background: yellow; }
+
+span.big { font-size: 2em; }
+span.small { font-size: 0.6em; }
+
+span.underline { text-decoration: underline; }
+span.overline { text-decoration: overline; }
+span.line-through { text-decoration: line-through; }
+
+div.unbreakable { page-break-inside: avoid; }
+
+
+/*
+ * xhtml11 specific
+ *
+ * */
+
+div.tableblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+div.tableblock > table {
+ border: 3px solid #527bbd;
+}
+thead, p.table.header {
+ font-weight: bold;
+ color: #527bbd;
+}
+p.table {
+ margin-top: 0;
+}
+/* Because the table frame attribute is overriden by CSS in most browsers. */
+div.tableblock > table[frame="void"] {
+ border-style: none;
+}
+div.tableblock > table[frame="hsides"] {
+ border-left-style: none;
+ border-right-style: none;
+}
+div.tableblock > table[frame="vsides"] {
+ border-top-style: none;
+ border-bottom-style: none;
+}
+
+
+/*
+ * html5 specific
+ *
+ * */
+
+table.tableblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+thead, p.tableblock.header {
+ font-weight: bold;
+ color: #527bbd;
+}
+p.tableblock {
+ margin-top: 0;
+}
+table.tableblock {
+ border-width: 3px;
+ border-spacing: 0px;
+ border-style: solid;
+ border-color: #527bbd;
+ border-collapse: collapse;
+}
+th.tableblock, td.tableblock {
+ border-width: 1px;
+ padding: 4px;
+ border-style: solid;
+ border-color: #527bbd;
+}
+
+table.tableblock.frame-topbot {
+ border-left-style: hidden;
+ border-right-style: hidden;
+}
+table.tableblock.frame-sides {
+ border-top-style: hidden;
+ border-bottom-style: hidden;
+}
+table.tableblock.frame-none {
+ border-style: hidden;
+}
+
+th.tableblock.halign-left, td.tableblock.halign-left {
+ text-align: left;
+}
+th.tableblock.halign-center, td.tableblock.halign-center {
+ text-align: center;
+}
+th.tableblock.halign-right, td.tableblock.halign-right {
+ text-align: right;
+}
+
+th.tableblock.valign-top, td.tableblock.valign-top {
+ vertical-align: top;
+}
+th.tableblock.valign-middle, td.tableblock.valign-middle {
+ vertical-align: middle;
+}
+th.tableblock.valign-bottom, td.tableblock.valign-bottom {
+ vertical-align: bottom;
+}
+
+
+/*
+ * manpage specific
+ *
+ * */
+
+body.manpage h1 {
+ padding-top: 0.5em;
+ padding-bottom: 0.5em;
+ border-top: 2px solid silver;
+ border-bottom: 2px solid silver;
+}
+body.manpage h2 {
+ border-style: none;
+}
+body.manpage div.sectionbody {
+ margin-left: 3em;
+}
+
+@media print {
+ body.manpage div#toc { display: none; }
+}
+
+
+</style>
+<script type="text/javascript">
+/*<![CDATA[*/
+var asciidoc = { // Namespace.
+
+/////////////////////////////////////////////////////////////////////
+// Table Of Contents generator
+/////////////////////////////////////////////////////////////////////
+
+/* Author: Mihai Bazon, September 2002
+ * http://students.infoiasi.ro/~mishoo
+ *
+ * Table Of Content generator
+ * Version: 0.4
+ *
+ * Feel free to use this script under the terms of the GNU General Public
+ * License, as long as you do not remove or alter this notice.
+ */
+
+ /* modified by Troy D. Hanson, September 2006. License: GPL */
+ /* modified by Stuart Rackham, 2006, 2009. License: GPL */
+
+// toclevels = 1..4.
+toc: function (toclevels) {
+
+ function getText(el) {
+ var text = "";
+ for (var i = el.firstChild; i != null; i = i.nextSibling) {
+ if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
+ text += i.data;
+ else if (i.firstChild != null)
+ text += getText(i);
+ }
+ return text;
+ }
+
+ function TocEntry(el, text, toclevel) {
+ this.element = el;
+ this.text = text;
+ this.toclevel = toclevel;
+ }
+
+ function tocEntries(el, toclevels) {
+ var result = new Array;
+ var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
+ // Function that scans the DOM tree for header elements (the DOM2
+ // nodeIterator API would be a better technique but not supported by all
+ // browsers).
+ var iterate = function (el) {
+ for (var i = el.firstChild; i != null; i = i.nextSibling) {
+ if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
+ var mo = re.exec(i.tagName);
+ if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
+ result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
+ }
+ iterate(i);
+ }
+ }
+ }
+ iterate(el);
+ return result;
+ }
+
+ var toc = document.getElementById("toc");
+ if (!toc) {
+ return;
+ }
+
+ // Delete existing TOC entries in case we're reloading the TOC.
+ var tocEntriesToRemove = [];
+ var i;
+ for (i = 0; i < toc.childNodes.length; i++) {
+ var entry = toc.childNodes[i];
+ if (entry.nodeName.toLowerCase() == 'div'
+ && entry.getAttribute("class")
+ && entry.getAttribute("class").match(/^toclevel/))
+ tocEntriesToRemove.push(entry);
+ }
+ for (i = 0; i < tocEntriesToRemove.length; i++) {
+ toc.removeChild(tocEntriesToRemove[i]);
+ }
+
+ // Rebuild TOC entries.
+ var entries = tocEntries(document.getElementById("content"), toclevels);
+ for (var i = 0; i < entries.length; ++i) {
+ var entry = entries[i];
+ if (entry.element.id == "")
+ entry.element.id = "_toc_" + i;
+ var a = document.createElement("a");
+ a.href = "#" + entry.element.id;
+ a.appendChild(document.createTextNode(entry.text));
+ var div = document.createElement("div");
+ div.appendChild(a);
+ div.className = "toclevel" + entry.toclevel;
+ toc.appendChild(div);
+ }
+ if (entries.length == 0)
+ toc.parentNode.removeChild(toc);
+},
+
+
+/////////////////////////////////////////////////////////////////////
+// Footnotes generator
+/////////////////////////////////////////////////////////////////////
+
+/* Based on footnote generation code from:
+ * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
+ */
+
+footnotes: function () {
+ // Delete existing footnote entries in case we're reloading the footnodes.
+ var i;
+ var noteholder = document.getElementById("footnotes");
+ if (!noteholder) {
+ return;
+ }
+ var entriesToRemove = [];
+ for (i = 0; i < noteholder.childNodes.length; i++) {
+ var entry = noteholder.childNodes[i];
+ if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
+ entriesToRemove.push(entry);
+ }
+ for (i = 0; i < entriesToRemove.length; i++) {
+ noteholder.removeChild(entriesToRemove[i]);
+ }
+
+ // Rebuild footnote entries.
+ var cont = document.getElementById("content");
+ var spans = cont.getElementsByTagName("span");
+ var refs = {};
+ var n = 0;
+ for (i=0; i<spans.length; i++) {
+ if (spans[i].className == "footnote") {
+ n++;
+ var note = spans[i].getAttribute("data-note");
+ if (!note) {
+ // Use [\s\S] in place of . so multi-line matches work.
+ // Because JavaScript has no s (dotall) regex flag.
+ note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
+ spans[i].innerHTML =
+ "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
+ "' title='View footnote' class='footnote'>" + n + "</a>]";
+ spans[i].setAttribute("data-note", note);
+ }
+ noteholder.innerHTML +=
+ "<div class='footnote' id='_footnote_" + n + "'>" +
+ "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
+ n + "</a>. " + note + "</div>";
+ var id =spans[i].getAttribute("id");
+ if (id != null) refs["#"+id] = n;
+ }
+ }
+ if (n == 0)
+ noteholder.parentNode.removeChild(noteholder);
+ else {
+ // Process footnoterefs.
+ for (i=0; i<spans.length; i++) {
+ if (spans[i].className == "footnoteref") {
+ var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
+ href = href.match(/#.*/)[0]; // Because IE return full URL.
+ n = refs[href];
+ spans[i].innerHTML =
+ "[<a href='#_footnote_" + n +
+ "' title='View footnote' class='footnote'>" + n + "</a>]";
+ }
+ }
+ }
+},
+
+install: function(toclevels) {
+ var timerId;
+
+ function reinstall() {
+ asciidoc.footnotes();
+ if (toclevels) {
+ asciidoc.toc(toclevels);
+ }
+ }
+
+ function reinstallAndRemoveTimer() {
+ clearInterval(timerId);
+ reinstall();
+ }
+
+ timerId = setInterval(reinstall, 500);
+ if (document.addEventListener)
+ document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
+ else
+ window.onload = reinstallAndRemoveTimer;
+}
+
+}
+asciidoc.install();
+/*]]>*/
+</script>
+</head>
+<body class="manpage">
+<div id="header">
+<h1>
+nvme-verify(1) Manual Page
+</h1>
+<h2>NAME</h2>
+<div class="sectionbody">
+<p>nvme-verify -
+ Send an NVMe Verify command, return results
+</p>
+</div>
+</div>
+<div id="content">
+<div class="sect1">
+<h2 id="_synopsis">SYNOPSIS</h2>
+<div class="sectionbody">
+<div class="verseblock">
+<pre class="content"><em>nvme-verify</em> &lt;device&gt; [--namespace-id=&lt;nsid&gt; | -n &lt;nsid&gt;]
+ [--start-block=&lt;slba&gt; | -s &lt;slba&gt;]
+ [--block-count=&lt;nlb&gt; | -c &lt;nlb&gt;]
+ [--limited-retry | -l]
+ [--force-unit-access | -f]
+ [--prinfo=&lt;prinfo&gt; | -p &lt;prinfo&gt;]
+ [--ref-tag=&lt;reftag&gt; | -r &lt;reftag&gt;]
+ [--app-tag-mask=&lt;appmask&gt; | -m &lt;appmask&gt;]
+ [--app-tag=&lt;apptag&gt; | -a &lt;apptag&gt;]
+ [--storage-tag&lt;storage-tag&gt; | -S &lt;storage-tag&gt;]
+ [--storage-tag-check&lt;storage-tag-check&gt; | -C &lt;storage-tag-check&gt;]</pre>
+<div class="attribution">
+</div></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_description">DESCRIPTION</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>The Verify command verifies the integrity of the stored information by
+reading data and metadata.</p></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_options">OPTIONS</h2>
+<div class="sectionbody">
+<div class="dlist"><dl>
+<dt class="hdlist1">
+--namespace-id=&lt;nsid&gt;
+</dt>
+<dt class="hdlist1">
+-n &lt;nsid&gt;
+</dt>
+<dd>
+<p>
+ Namespace ID use in the command.
+</p>
+</dd>
+<dt class="hdlist1">
+--start-block=&lt;slba&gt;
+</dt>
+<dt class="hdlist1">
+-s &lt;slba&gt;
+</dt>
+<dd>
+<p>
+ Start block address.
+</p>
+</dd>
+<dt class="hdlist1">
+--block-count=&lt;nlb&gt;
+</dt>
+<dt class="hdlist1">
+-c &lt;nlb&gt;
+</dt>
+<dd>
+<p>
+ Number of logical blocks to Verify.
+</p>
+</dd>
+<dt class="hdlist1">
+--limited-retry
+</dt>
+<dt class="hdlist1">
+-l
+</dt>
+<dd>
+<p>
+ Sets the limited retry flag.
+</p>
+</dd>
+<dt class="hdlist1">
+--force-unit-access
+</dt>
+<dt class="hdlist1">
+-f
+</dt>
+<dd>
+<p>
+ Set the force-unit access flag.
+</p>
+</dd>
+<dt class="hdlist1">
+--prinfo=&lt;prinfo&gt;
+</dt>
+<dt class="hdlist1">
+-p &lt;prinfo&gt;
+</dt>
+<dd>
+<p>
+ Protection Information field definition.
+</p>
+<div class="tableblock">
+<table rules="all"
+width="100%"
+frame="border"
+cellspacing="0" cellpadding="4">
+<col width="50%" />
+<col width="50%" />
+<tbody>
+<tr>
+<td align="left" valign="top"><p class="table">Bit</p></td>
+<td align="left" valign="top"><p class="table">Description</p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">3</p></td>
+<td align="left" valign="top"><p class="table">PRACT: Protection Information Action. When set to 1, PI is stripped/inserted
+on read/write when the block format&#8217;s metadata size is 8. When set to 0,
+metadata is passes.</p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">2:0</p></td>
+<td align="left" valign="top"><p class="table">PRCHK: Protection Information Check:</p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">2</p></td>
+<td align="left" valign="top"><p class="table">Set to 1 enables checking the guard tag</p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">1</p></td>
+<td align="left" valign="top"><p class="table">Set to 1 enables checking the application tag</p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">0</p></td>
+<td align="left" valign="top"><p class="table">Set to 1 enables checking the reference tag</p></td>
+</tr>
+</tbody>
+</table>
+</div>
+</dd>
+<dt class="hdlist1">
+--ref-tag=&lt;reftag&gt;
+</dt>
+<dt class="hdlist1">
+-r &lt;reftag&gt;
+</dt>
+<dd>
+<p>
+ Optional reftag when used with protection information.
+</p>
+</dd>
+<dt class="hdlist1">
+--app-tag-mask=&lt;appmask&gt;
+</dt>
+<dt class="hdlist1">
+-m &lt;appmask&gt;
+</dt>
+<dd>
+<p>
+ Optional application tag mask when used with protection information.
+</p>
+</dd>
+<dt class="hdlist1">
+--app-tag=&lt;apptag&gt;
+</dt>
+<dt class="hdlist1">
+-a &lt;apptag&gt;
+</dt>
+<dd>
+<p>
+ Optional application tag when used with protection information.
+</p>
+</dd>
+<dt class="hdlist1">
+--storage-tag=&lt;storage-tag&gt;
+</dt>
+<dt class="hdlist1">
+-S &lt;storage-tag&gt;
+</dt>
+<dd>
+<p>
+ Variable Sized Expected Logical Block Storage Tag(ELBST) and Expected Logical
+ Block Reference Tag (ELBRT), CDW2 and CDW3 (00:47) bits.
+</p>
+</dd>
+<dt class="hdlist1">
+--storage-tag-check=&lt;storage-tag-check&gt;
+</dt>
+<dt class="hdlist1">
+-C &lt;storage-tag-check&gt;
+</dt>
+<dd>
+<p>
+ This bit specifies the Storage Tag field shall be checked as part of Verify operation.
+</p>
+</dd>
+</dl></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_examples">EXAMPLES</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>No examples yet.</p></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_nvme">NVME</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Part of the nvme-user suite</p></div>
+</div>
+</div>
+</div>
+<div id="footnotes"><hr /></div>
+<div id="footer">
+<div id="footer-text">
+Last updated
+ 2021-07-09 13:43:04 IST
+</div>
+</div>
+</body>
+</html>
diff --git a/Documentation/nvme-verify.txt b/Documentation/nvme-verify.txt
new file mode 100644
index 0000000..3dc2fc7
--- /dev/null
+++ b/Documentation/nvme-verify.txt
@@ -0,0 +1,93 @@
+nvme-verify(1)
+==============
+
+NAME
+----
+nvme-verify - Send an NVMe Verify command, return results
+
+SYNOPSIS
+--------
+[verse]
+'nvme-verify' <device> [--namespace-id=<nsid> | -n <nsid>]
+ [--start-block=<slba> | -s <slba>]
+ [--block-count=<nlb> | -c <nlb>]
+ [--limited-retry | -l]
+ [--force-unit-access | -f]
+ [--prinfo=<prinfo> | -p <prinfo>]
+ [--ref-tag=<reftag> | -r <reftag>]
+ [--app-tag-mask=<appmask> | -m <appmask>]
+ [--app-tag=<apptag> | -a <apptag>]
+ [--storage-tag<storage-tag> | -S <storage-tag>]
+ [--storage-tag-check<storage-tag-check> | -C <storage-tag-check>]
+
+DESCRIPTION
+-----------
+The Verify command verifies the integrity of the stored information by
+reading data and metadata.
+
+OPTIONS
+-------
+--namespace-id=<nsid>::
+-n <nsid>::
+ Namespace ID use in the command.
+
+--start-block=<slba>::
+-s <slba>::
+ Start block address.
+
+--block-count=<nlb>::
+-c <nlb>::
+ Number of logical blocks to Verify.
+
+--limited-retry::
+-l::
+ Sets the limited retry flag.
+
+--force-unit-access::
+-f::
+ Set the force-unit access flag.
+
+--prinfo=<prinfo>::
+-p <prinfo>::
+ Protection Information field definition.
++
+[]
+|=================
+|Bit|Description
+|3|PRACT: Protection Information Action. When set to 1, PI is stripped/inserted
+on read/write when the block format's metadata size is 8. When set to 0,
+metadata is passes.
+|2:0|PRCHK: Protection Information Check:
+|2|Set to 1 enables checking the guard tag
+|1|Set to 1 enables checking the application tag
+|0|Set to 1 enables checking the reference tag
+|=================
+
+--ref-tag=<reftag>::
+-r <reftag>::
+ Optional reftag when used with protection information.
+
+--app-tag-mask=<appmask>::
+-m <appmask>::
+ Optional application tag mask when used with protection information.
+
+--app-tag=<apptag>::
+-a <apptag>::
+ Optional application tag when used with protection information.
+
+--storage-tag=<storage-tag>::
+-S <storage-tag>::
+ Variable Sized Expected Logical Block Storage Tag(ELBST) and Expected Logical
+ Block Reference Tag (ELBRT), CDW2 and CDW3 (00:47) bits.
+
+--storage-tag-check=<storage-tag-check>::
+-C <storage-tag-check>::
+ This bit specifies the Storage Tag field shall be checked as part of Verify operation.
+
+EXAMPLES
+--------
+No examples yet.
+
+NVME
+----
+Part of the nvme-user suite
diff --git a/Documentation/nvme-write-zeroes.1 b/Documentation/nvme-write-zeroes.1
index d32e3ca..d7f06bb 100644
--- a/Documentation/nvme-write-zeroes.1
+++ b/Documentation/nvme-write-zeroes.1
@@ -1,13 +1,13 @@
'\" t
.\" Title: nvme-zeroes
-.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
-.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 10/20/2020
+.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 07/09/2021
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-ZEROES" "1" "10/20/2020" "NVMe" "NVMe Manual"
+.TH "NVME\-ZEROES" "1" "07/09/2021" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -42,6 +42,8 @@ nvme-write-zeroes \- Send an NVMe write zeroes command, return results
[\-\-limited\-retry | \-l]
[\-\-force\-unit\-access | \-f]
[\-\-namespace\-id=<nsid> | \-n <nsid>]
+ [\-\-storage\-tag<storage\-tag> | \-S <storage\-tag>]
+ [\-\-storage\-tag\-check<storage\-tag\-check> | \-C <storage\-tag\-check>]
.fi
.SH "DESCRIPTION"
.sp
@@ -137,19 +139,19 @@ Set the force\-unit access flag\&.
.RS 4
Namespace ID use in the command\&.
.RE
-.sp
-EXAMPLES EXAMPLES
-.sp
-.if n \{\
+.PP
+\-\-storage\-tag=<storage\-tag>, \-n <storage\-tag>
.RS 4
-.\}
-.nf
-No examples yet\&.
-
-NVME
-.fi
-.if n \{\
+Variable Sized Expected Logical Block Storage Tag(ELBST) and Expected Logical Block Reference Tag (ELBRT), CDW2 and CDW3 (00:47) bits\&.
.RE
-.\}
+.PP
+\-\-storage\-tag\-check=<storage\-tag\-check>, \-C <storage\-tag\-check>
+.RS 4
+This bit specifies the Storage Tag field shall be checked as part of end\-to\-end data protection processing\&.
+.RE
+.SH "EXAMPLES"
+.sp
+No examples yet\&.
+.SH "NVME"
.sp
Part of the nvme\-user suite
diff --git a/Documentation/nvme-write-zeroes.html b/Documentation/nvme-write-zeroes.html
index f3a3838..0912800 100644
--- a/Documentation/nvme-write-zeroes.html
+++ b/Documentation/nvme-write-zeroes.html
@@ -758,7 +758,9 @@ nvme-zeroes(1) Manual Page
[--deac | -d]
[--limited-retry | -l]
[--force-unit-access | -f]
- [--namespace-id=&lt;nsid&gt; | -n &lt;nsid&gt;]</pre>
+ [--namespace-id=&lt;nsid&gt; | -n &lt;nsid&gt;]
+ [--storage-tag&lt;storage-tag&gt; | -S &lt;storage-tag&gt;]
+ [--storage-tag-check&lt;storage-tag-check&gt; | -C &lt;storage-tag-check&gt;]</pre>
<div class="attribution">
</div></div>
</div>
@@ -920,15 +922,42 @@ metadata is passes.</p></td>
Namespace ID use in the command.
</p>
</dd>
+<dt class="hdlist1">
+--storage-tag=&lt;storage-tag&gt;
+</dt>
+<dt class="hdlist1">
+-n &lt;storage-tag&gt;
+</dt>
+<dd>
+<p>
+ Variable Sized Expected Logical Block Storage Tag(ELBST) and Expected Logical
+ Block Reference Tag (ELBRT), CDW2 and CDW3 (00:47) bits.
+</p>
+</dd>
+<dt class="hdlist1">
+--storage-tag-check=&lt;storage-tag-check&gt;
+</dt>
+<dt class="hdlist1">
+-C &lt;storage-tag-check&gt;
+</dt>
+<dd>
+<p>
+ This bit specifies the Storage Tag field shall be checked as part of end-to-end
+ data protection processing.
+</p>
+</dd>
</dl></div>
-<div class="paragraph"><p>EXAMPLES
-EXAMPLES</p></div>
-<div class="listingblock">
-<div class="content">
-<pre><code>No examples yet.
-
-NVME</code></pre>
-</div></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_examples">EXAMPLES</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>No examples yet.</p></div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_nvme">NVME</h2>
+<div class="sectionbody">
<div class="paragraph"><p>Part of the nvme-user suite</p></div>
</div>
</div>
@@ -937,7 +966,7 @@ NVME</code></pre>
<div id="footer">
<div id="footer-text">
Last updated
- 2019-09-18 00:00:58 JST
+ 2021-07-09 13:42:09 IST
</div>
</div>
</body>
diff --git a/Documentation/nvme-write-zeroes.txt b/Documentation/nvme-write-zeroes.txt
index 02adee1..34fec9d 100644
--- a/Documentation/nvme-write-zeroes.txt
+++ b/Documentation/nvme-write-zeroes.txt
@@ -18,6 +18,8 @@ SYNOPSIS
[--limited-retry | -l]
[--force-unit-access | -f]
[--namespace-id=<nsid> | -n <nsid>]
+ [--storage-tag<storage-tag> | -S <storage-tag>]
+ [--storage-tag-check<storage-tag-check> | -C <storage-tag-check>]
DESCRIPTION
-----------
@@ -77,7 +79,16 @@ metadata is passes.
-n <nsid>::
Namespace ID use in the command.
-EXAMPLES
+--storage-tag=<storage-tag>::
+-n <storage-tag>::
+ Variable Sized Expected Logical Block Storage Tag(ELBST) and Expected Logical
+ Block Reference Tag (ELBRT), CDW2 and CDW3 (00:47) bits.
+
+--storage-tag-check=<storage-tag-check>::
+-C <storage-tag-check>::
+ This bit specifies the Storage Tag field shall be checked as part of end-to-end
+ data protection processing.
+
EXAMPLES
--------
No examples yet.
diff --git a/Documentation/nvme-write.1 b/Documentation/nvme-write.1
index 727ac03..b8e49e5 100644
--- a/Documentation/nvme-write.1
+++ b/Documentation/nvme-write.1
@@ -1,13 +1,13 @@
'\" t
.\" Title: nvme-write
-.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
-.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\" Date: 10/20/2020
+.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 07/09/2021
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
-.TH "NVME\-WRITE" "1" "10/20/2020" "NVMe" "NVMe Manual"
+.TH "NVME\-WRITE" "1" "07/09/2021" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -50,6 +50,7 @@ nvme-write \- Send an NVMe write command, provide results
[\-\-show\-command | \-v]
[\-\-dry\-run | \-w]
[\-\-latency | \-t]
+ [\-\-storage\-tag\-check<storage\-tag\-check> | \-C <storage\-tag\-check>]
.fi
.SH "DESCRIPTION"
.sp
@@ -188,6 +189,11 @@ be set\&. Otherwise \-\-dry\-run option will be
.RS 4
Print out the latency the IOCTL took (in us)\&.
.RE
+.PP
+\-\-storage\-tag\-check=<storage\-tag\-check>, \-C <storage\-tag\-check>
+.RS 4
+This bit specifies the Storage Tag field shall be checked as part of end\-to\-end data protection processing\&.
+.RE
.SH "EXAMPLES"
.sp
No examples yet\&.
diff --git a/Documentation/nvme-write.html b/Documentation/nvme-write.html
index b59de9d..57dccc3 100644
--- a/Documentation/nvme-write.html
+++ b/Documentation/nvme-write.html
@@ -766,7 +766,8 @@ nvme-write(1) Manual Page
[--dsm=&lt;dsm&gt; | -D &lt;dsm&gt;]
[--show-command | -v]
[--dry-run | -w]
- [--latency | -t]</pre>
+ [--latency | -t]
+ [--storage-tag-check&lt;storage-tag-check&gt; | -C &lt;storage-tag-check&gt;]</pre>
<div class="attribution">
</div></div>
</div>
@@ -1035,6 +1036,18 @@ metadata is passes.</p></td>
Print out the latency the IOCTL took (in us).
</p>
</dd>
+<dt class="hdlist1">
+--storage-tag-check=&lt;storage-tag-check&gt;
+</dt>
+<dt class="hdlist1">
+-C &lt;storage-tag-check&gt;
+</dt>
+<dd>
+<p>
+ This bit specifies the Storage Tag field shall be checked as part of end-to-end
+ data protection processing.
+</p>
+</dd>
</dl></div>
</div>
</div>
@@ -1055,7 +1068,7 @@ metadata is passes.</p></td>
<div id="footer">
<div id="footer-text">
Last updated
- 2018-11-29 13:31:13 GMT
+ 2021-07-09 14:16:34 IST
</div>
</div>
</body>
diff --git a/Documentation/nvme-write.txt b/Documentation/nvme-write.txt
index 2074f52..c48e6ae 100644
--- a/Documentation/nvme-write.txt
+++ b/Documentation/nvme-write.txt
@@ -26,6 +26,7 @@ SYNOPSIS
[--show-command | -v]
[--dry-run | -w]
[--latency | -t]
+ [--storage-tag-check<storage-tag-check> | -C <storage-tag-check>]
DESCRIPTION
-----------
@@ -136,6 +137,11 @@ metadata is passes.
--latency::
Print out the latency the IOCTL took (in us).
+--storage-tag-check=<storage-tag-check>::
+-C <storage-tag-check>::
+ This bit specifies the Storage Tag field shall be checked as part of end-to-end
+ data protection processing.
+
EXAMPLES
--------
No examples yet.
diff --git a/Documentation/nvme-zns-close-zone.1 b/Documentation/nvme-zns-close-zone.1
index d9624c1..5f80a39 100644
--- a/Documentation/nvme-zns-close-zone.1
+++ b/Documentation/nvme-zns-close-zone.1
@@ -32,9 +32,10 @@ nvme-zns-close-zone \- Closes one or all zones
.SH "SYNOPSIS"
.sp
.nf
-\fInvme zns close\-zone nvme zns id\-ctrl\fR <device> [\-\-namespace\-id=<NUM> | \-n <NUM>]
- [\-\-start\-lba=<LBA> | \-s <LBA>]
- [\-\-select\-all | \-a]
+\fInvme zns close\-zone\fR <device> [\-\-namespace\-id=<NUM> | \-n <NUM>]
+ [\-\-start\-lba=<LBA> | \-s <LBA>]
+ [\-\-select\-all | \-a]
+ [\-\-timeout=<timeout> | \-t <timeout>]
.fi
.SH "DESCRIPTION"
.sp
@@ -57,6 +58,11 @@ The starting LBA of the zone to close\&.
.RS 4
Select all zones for this action
.RE
+.PP
+\-t <timeout>, \-\-timeout=<timeout>
+.RS 4
+Override default timeout value\&. In milliseconds\&.
+.RE
.SH "EXAMPLES"
.sp
.RS 4
diff --git a/Documentation/nvme-zns-finish-zone.1 b/Documentation/nvme-zns-finish-zone.1
index 764c683..b34801f 100644
--- a/Documentation/nvme-zns-finish-zone.1
+++ b/Documentation/nvme-zns-finish-zone.1
@@ -32,9 +32,10 @@ nvme-zns-finish-zone \- Finishes one or all zones
.SH "SYNOPSIS"
.sp
.nf
-\fInvme zns finish\-zone nvme zns id\-ctrl\fR <device> [\-\-namespace\-id=<NUM> | \-n <NUM>]
- [\-\-start\-lba=<LBA> | \-s <LBA>]
- [\-\-select\-all | \-a]
+\fInvme zns finish\-zone\fR <device> [\-\-namespace\-id=<NUM> | \-n <NUM>]
+ [\-\-start\-lba=<LBA> | \-s <LBA>]
+ [\-\-select\-all | \-a]
+ [\-\-timeout=<timeout> | \-t <timeout>]
.fi
.SH "DESCRIPTION"
.sp
@@ -57,6 +58,11 @@ The starting LBA of the zone to finish\&.
.RS 4
Select all zones for this action\&.
.RE
+.PP
+\-t <timeout>, \-\-timeout=<timeout>
+.RS 4
+Override default timeout value\&. In milliseconds\&.
+.RE
.SH "EXAMPLES"
.sp
.RS 4
diff --git a/Documentation/nvme-zns-offline-zone.1 b/Documentation/nvme-zns-offline-zone.1
index 9d2d083..2e6c178 100644
--- a/Documentation/nvme-zns-offline-zone.1
+++ b/Documentation/nvme-zns-offline-zone.1
@@ -32,9 +32,10 @@ nvme-zns-offline-zone \- Offlines one or all zones
.SH "SYNOPSIS"
.sp
.nf
-\fInvme zns offline\-zone nvme zns id\-ctrl\fR <device> [\-\-namespace\-id=<NUM> | \-n <NUM>]
- [\-\-start\-lba=<LBA> | \-s <LBA>]
- [\-\-select\-all | \-a]
+\fInvme zns offline\-zone\fR <device> [\-\-namespace\-id=<NUM> | \-n <NUM>]
+ [\-\-start\-lba=<LBA> | \-s <LBA>]
+ [\-\-select\-all | \-a]
+ [\-\-timeout=<timeout> | \-t <timeout>]
.fi
.SH "DESCRIPTION"
.sp
@@ -57,6 +58,11 @@ The starting LBA of the zone to offline\&.
.RS 4
Select all zones for this action
.RE
+.PP
+\-t <timeout>, \-\-timeout=<timeout>
+.RS 4
+Override default timeout value\&. In milliseconds\&.
+.RE
.SH "EXAMPLES"
.sp
.RS 4
diff --git a/Documentation/nvme-zns-open-zone.1 b/Documentation/nvme-zns-open-zone.1
index 8ea78f2..4120942 100644
--- a/Documentation/nvme-zns-open-zone.1
+++ b/Documentation/nvme-zns-open-zone.1
@@ -32,9 +32,10 @@ nvme-zns-open-zone \- Opens one or all zones
.SH "SYNOPSIS"
.sp
.nf
-\fInvme zns open\-zone nvme zns id\-ctrl\fR <device> [\-\-namespace\-id=<NUM> | \-n <NUM>]
- [\-\-start\-lba=<LBA> | \-s <LBA>]
- [\-\-select\-all | \-a]
+\fInvme zns open\-zone\fR <device> [\-\-namespace\-id=<NUM> | \-n <NUM>]
+ [\-\-start\-lba=<LBA> | \-s <LBA>]
+ [\-\-select\-all | \-a]
+ [\-\-timeout=<timeout> | \-t <timeout>]
.fi
.SH "DESCRIPTION"
.sp
@@ -57,6 +58,11 @@ The starting LBA of the zone to open\&.
.RS 4
Select all zones for this action
.RE
+.PP
+\-t <timeout>, \-\-timeout=<timeout>
+.RS 4
+Override default timeout value\&. In milliseconds\&.
+.RE
.SH "EXAMPLES"
.sp
.RS 4
diff --git a/Documentation/nvme-zns-reset-zone.1 b/Documentation/nvme-zns-reset-zone.1
index b02d042..7452e8b 100644
--- a/Documentation/nvme-zns-reset-zone.1
+++ b/Documentation/nvme-zns-reset-zone.1
@@ -33,8 +33,9 @@ nvme-zns-reset-zone \- Resets one or all zones
.sp
.nf
\fInvme zns reset\-zone\fR <device> [\-\-namespace\-id=<NUM> | \-n <NUM>]
- [\-\-start\-lba=<LBA> | \-s <LBA>]
- [\-\-select\-all | \-a]
+ [\-\-start\-lba=<LBA> | \-s <LBA>]
+ [\-\-select\-all | \-a]
+ [\-\-timeout=<timeout> | \-t <timeout>]
.fi
.SH "DESCRIPTION"
.sp
@@ -57,6 +58,11 @@ The starting LBA of the zone to reset\&.
.RS 4
Select all zones for this action
.RE
+.PP
+\-t <timeout>, \-\-timeout=<timeout>
+.RS 4
+Override default timeout value\&. In milliseconds\&.
+.RE
.SH "EXAMPLES"
.sp
.RS 4
diff --git a/Documentation/nvme-zns-set-zone-desc.1 b/Documentation/nvme-zns-set-zone-desc.1
index a33b06a..7b9a52a 100644
--- a/Documentation/nvme-zns-set-zone-desc.1
+++ b/Documentation/nvme-zns-set-zone-desc.1
@@ -33,8 +33,9 @@ nvme-zns-set-zone-desc \- Set extended descriptor data for a zone
.sp
.nf
\fInvme zns setzone\-desc\fR <device> [\-\-namespace\-id=<NUM> | \-n <NUM>]
- [\-\-start\-lba=<IONUM>, \-s <IONUM>]
- [\-data=<FILE>, \-d <FILE>]
+ [\-\-start\-lba=<IONUM>, \-s <IONUM>]
+ [\-data=<FILE>, \-d <FILE>]
+ [\-\-timeout=<timeout> | \-t <timeout>]
.fi
.SH "DESCRIPTION"
.sp
@@ -55,6 +56,11 @@ The starting LBA of the zone to manage send\&.
.RS 4
Optional file for data (default stdin)
.RE
+.PP
+\-t <timeout>, \-\-timeout=<timeout>
+.RS 4
+Override default timeout value\&. In milliseconds\&.
+.RE
.SH "EXAMPLES"
.sp
.RS 4
diff --git a/Documentation/nvme-zns-zone-mgmt-send.1 b/Documentation/nvme-zns-zone-mgmt-send.1
index f74d8a3..5b58bbc 100644
--- a/Documentation/nvme-zns-zone-mgmt-send.1
+++ b/Documentation/nvme-zns-zone-mgmt-send.1
@@ -33,11 +33,12 @@ nvme-zns-zone-mgmt-send \- Zone Management Send command
.sp
.nf
\fInvme zns zone\-mgmt\-send\fR <device> [\-\-namespace\-id=<NUM> | \-n <NUM>]
- [\-\-start\-lba=<IONUM>, \-s <IONUM>]
- [\-\-select\-all, \-a]
- [\-\-zsa=<NUM>, \-z <NUM>]
- [\-\-data\-len=<IONUM>, \-l <IONUM>]
- [\-data=<FILE>, \-d <FILE>]
+ [\-\-start\-lba=<IONUM>, \-s <IONUM>]
+ [\-\-select\-all, \-a]
+ [\-\-zsa=<NUM>, \-z <NUM>]
+ [\-\-data\-len=<IONUM>, \-l <IONUM>]
+ [\-data=<FILE>, \-d <FILE>]
+ [\-\-timeout=<timeout> | \-t <timeout>]
.fi
.SH "DESCRIPTION"
.sp
@@ -78,6 +79,11 @@ Buffer length if data required
.RS 4
Optional file for data (default stdin)
.RE
+.PP
+\-t <timeout>, \-\-timeout=<timeout>
+.RS 4
+Override default timeout value\&. In milliseconds\&.
+.RE
.SH "EXAMPLES"
.sp
.RS 4
diff --git a/NVME-VERSION-GEN b/NVME-VERSION-GEN
index 802bbd3..795f8ec 100755
--- a/NVME-VERSION-GEN
+++ b/NVME-VERSION-GEN
@@ -1,7 +1,7 @@
#!/bin/sh
GVF=NVME-VERSION-FILE
-DEF_VER=v1.14
+DEF_VER=v1.15
LF='
'
diff --git a/cmd_handler.h b/cmd_handler.h
index d40740d..73b5962 100644
--- a/cmd_handler.h
+++ b/cmd_handler.h
@@ -5,7 +5,7 @@
*/
#undef NAME
-#define NAME(n, d)
+#define NAME(n, d, v)
#undef ENTRY
#define ENTRY(n, h, f, ...) \
@@ -26,7 +26,7 @@ static int f(int argc, char **argv, struct command *command, struct plugin *plug
*/
#undef NAME
-#define NAME(n, d)
+#define NAME(n, d, v)
#undef ENTRY_W_ALIAS
#define ENTRY_W_ALIAS(n, h, f, a) \
@@ -63,7 +63,7 @@ static struct command f ## _cmd = { \
*/
#undef NAME
-#define NAME(n, d)
+#define NAME(n, d, v)
#undef ENTRY
#define ENTRY(n, h, f, ...) &f ## _cmd,
@@ -87,7 +87,7 @@ static struct command *commands[] = { \
*/
#undef NAME
-#define NAME(n, d) .name = n, .desc = d,
+#define NAME(n, d, v) .name = n, .desc = d, .version = v,
#undef COMMAND_LIST
#define COMMAND_LIST(args...)
diff --git a/completions/_nvme b/completions/_nvme
index 9267522..b8070d6 100644
--- a/completions/_nvme
+++ b/completions/_nvme
@@ -11,6 +11,7 @@ _nvme () {
'id-ns:display information about the namespace'
'list-ns:identify all namespace(s) attached'
'id-iocs:display information about I/O command sets'
+ 'id-domain:display information about domain list'
'create-ns:create a new namespace before attachment'
'delete-ns:delete a detached namespace'
'attach-ns:attach namespace to controller'
@@ -47,6 +48,7 @@ _nvme () {
'compare:compare data on device to data elsewhere'
'read:submit a read command'
'write:submit a write command'
+ 'capacity-mgmt: submit capacity management command'
'show-regs:shows the controller registers; requires admin character device'
'help:print brief descriptions of all nvme commands'
)
@@ -113,6 +115,16 @@ _nvme () {
_arguments '*:: :->subcmds'
_describe -t commands "nvme id-iocs options" _idiocs
;;
+ (id-domain)
+ local _iddomain
+ _iddomain=(
+ /dev/nvme':supply a device to use (required)'
+ --dom-id=':show infos for domain id <cntid>'
+ -d':alias of --dom-id'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme id-domain options" _iddomain
+ ;;
nvm-id-ctrl)
local _nvmidctrl
_nvmidctrl=(
@@ -232,14 +244,14 @@ _nvme () {
--log-entries=': Number of pending NVM Set Entries log list'
-e':alias to --log-entries'
--rae': Retain an Asynchronous Event'
- -r':alias to --rae
+ -r':alias to --rae'
--raw-binary':dump infos in binary format'
-b':alias of --raw-binary'
)
_arguments '*:: :->subcmds'
_describe -t commands "nvme pred-lat-event-agg-log options" _predlateventagglog
;;
- (predictablelatlog)
+ (predictable-lat-log)
local _predictablelatlog
_predictablelatlog=(
/dev/nvme':supply a device to use (required)'
@@ -306,7 +318,7 @@ _nvme () {
--log-entries=': Number of Endurance Group Event Agg Entries log list'
-e':alias to --log-entries'
--rae': Retain an Asynchronous Event'
- -r':alias to --rae
+ -r':alias to --rae'
--raw-binary':dump infos in binary format'
-b':alias of --raw-binary'
)
@@ -318,7 +330,7 @@ _nvme () {
_lbastatuslog=(
/dev/nvme':supply a device to use (required)'
--rae': Retain an Asynchronous Event'
- -r':alias to --rae
+ -r':alias to --rae'
)
_arguments '*:: :->subcmds'
_describe -t commands "nvme lba-status-log options" _lbastatuslog
@@ -343,6 +355,8 @@ _nvme () {
-s':alias to --sel'
--data-len=':buffer len for returned LBA Type Range or host identifier data'
-l':alias for --data-len'
+ --uuid-index=':uuid index'
+ -U':alias for --uuid-index'
--cdw11=':dword 11 value, used for interrupt vector configuration only'
--raw-binary':dump infos in binary format'
-b':alias to --raw-binary'
@@ -364,6 +378,8 @@ _nvme () {
-d':alias to --data'
--value=':new value of feature (required)'
-v'alias to --value'
+ --uuid-index=':uuid index'
+ -U':alias for --uuid-index'
)
_arguments '*:: :->subcmds'
_describe -t commands "nvme set-feature options" _setf
@@ -414,6 +430,22 @@ _nvme () {
_arguments '*:: :->subcmds'
_describe -t commands "nvme fw-download options" _fwd
;;
+ (capacity-mgmt)
+ local _fwd
+ _fwd=(
+ /dev/nvme':supply a device to use (required)'
+ --operation=':Operation to be performed by the controller'
+ -o':alias of --operation'
+ --element-id=':specific to the value of the Operation field'
+ -i':alias of --element-id'
+ --cap-lower=':Least significant 32 bits of the capacity in bytes'
+ -l':alias of --cap-lower'
+ --cap-upper=':Most significant 32 bits of the capacity in bytes'
+ -u':alias of --cap-upper'
+ )
+ _arguments '*:: :->subcmds'
+ _describe -t commands "nvme capacity-mgmt options" _fwd
+ ;;
(admin-passthru)
local _admin
_admin=(
@@ -558,7 +590,7 @@ _nvme () {
-p':alias for --prkey'
--rtype=':hexadecimal reservation type'
-t':alias for --rtype'
- --racqa=':reservation acquiry action'
+ --racqa=':reservation acquire action'
-a':alias for --racqa'
--iekey=':ignore existing reservation key'
-i':alias for --iekey'
@@ -611,7 +643,7 @@ _nvme () {
--cptpl=':change persistence through power loss setting'
-p':alias for --cptpl'
--rrega=':reservation registration action to perform'
- -a':alias for --rrega'
+ -r':alias for --rrega'
--iekey':ignore existing reservation key'
-i':alias for --iekey'
)
@@ -788,7 +820,7 @@ _nvme () {
security-send security-recv resv-acquire resv-register resv-release
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
+ resv-notif-log capacity-mgmt id-domain
)
_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
diff --git a/completions/bash-nvme-completion.sh b/completions/bash-nvme-completion.sh
index c022b89..d3cca44 100644
--- a/completions/bash-nvme-completion.sh
+++ b/completions/bash-nvme-completion.sh
@@ -2,20 +2,115 @@
# (unfortunately, bash won't let me add descriptions to cmds)
# Kelly Kaoudis kelly.n.kaoudis at intel.com, Aug. 2015
-_cmds="list id-ctrl id-ns list-ns id-iocs nvm-id-ctrl create-ns delete-ns \
- attach-ns detach-ns list-ctrl get-ns-id get-log persistent-event-log \
- pred-lat-event-agg-log fw-log smart-log smart-log-add error-log \
- predictable-lat-log get-feature set-feature format fw-activate \
- fw-download admin-passthru io-passthru security-send \
- security-recv resv-acquire resv-register resv-release \
- resv-report dsm flush compare read write write-zeroes \
- write-uncor copy reset subsystem-reset show-regs discover \
- connect-all connect disconnect version help \
- intel lnvm memblaze list-subsys endurance-event-agg-log \
- lba-status-log resv-notif-log"
+# Constant to indicate command has no options
+readonly NO_OPTS=""
+
+# Associative array of plugins and associated subcommands
+# Order here is same as PLUGIN_OBJS in Makefile
+typeset -A _plugin_subcmds
+readonly _plugin_subcmds=(
+ [intel]="id-ctrl internal-log lat-stats \
+ set-bucket-thresholds lat-stats-tracking \
+ market-name smart-log-add temp-stats"
+ [amzn]="id-ctrl"
+ [lnvm]="list info id-ns chunk-log init create \
+ remove factory diag-bbtbl diag-set-bbtbl"
+ [memblaze]="smart-log-add get-pm-status set-pm-status \
+ select-download lat-stats lat-stats-print lat-log \
+ lat-log-print clear-error-log"
+ [wdc]="cap-diag drive-log get-crash-dump get-pfail-dump \
+ id-ctrl purge purge-monitor vs-internal-log \
+ vs-nand-stats vs-smart-add-log clear-pcie-correctable-errors \
+ drive-essentials get-drive-status clear-assert-dump \
+ drive-resize vs-fw-activate-history clear-fw-activate-history \
+ enc-get-log vs-telemetry-controller-option \
+ vs-error-reason-identifier log-page-directory \
+ namespace-resize vs-drive-info vs-temperature-stats \
+ capabilities cloud-SSD-plugin-version vs-pcie-stats"
+ [huawei]="list id-ctrl"
+ [netapp]="smdevices ontapdevices"
+ [toshiba]="vs-smart-add-log vs-internal-log \
+ clear-pcie-correctable-errors"
+ [micron]="select-download vs-temperature-stats vs-pcie-stats \
+ clear-pcie-correctable-errors vs-internal-log \
+ vs-telemetry-controller-option vs-nand-stats \
+ vs-drive-info plugin-version cloud-SSD-plugin-version \
+ log-page-directory vs-fw-activate-history \
+ vs-error-reason-identifier vs-smart-add-log \
+ clear-fw-activate-history vs-smbus-option"
+ [seagate]="vs-temperature-stats vs-log-page-sup \
+ vs-smart-add-log vs-pcie-stats clear-pcie-correctable-errors \
+ get-host-tele get-ctrl-tele vs-internal-log \
+ plugin-version"
+ [virtium]="save-smart-to-vtview-log show-identify"
+ [shannon]="smart-log-add get-feature-add set-feature-add id-ctrl"
+ [dera]="smart-log-add"
+ [sfx]="smart-log-add lat-stats get-bad-block query-cap \
+ change-cap set-feature get-feature"
+ [transcend]="healthvalue badblock"
+ [zns]="id-ctrl id-ns zone-mgmt-recv \
+ zone-mgmt-send report-zones close-zone \
+ finish-zone open-zone reset-zone offline-zone \
+ set-zone-desc zone-append changed-zone-list"
+ [nvidia]="id-ctrl"
+ [ymtc]="smart-log-add"
+)
+
+# Associative array mapping plugins to coresponding option completions
+typeset -A _plugin_funcs
+readonly _plugin_funcs=(
+ [intel]="plugin_intel_opts"
+ [amzn]="plugin_amzn_opts"
+ [lnvm]="plugin_lnvm_opts"
+ [memblaze]="plugin_memblaze_opts"
+ [wdc]="plugin_wdc_opts"
+ [huawei]="plugin_huawei_opts"
+ [toshiba]="plugin_toshiba_opts"
+ [micron]="plugin_micron_opts"
+ [seagate]="plugin_seagate_opts"
+ [virtium]="plugin_virtium_opts"
+ [shannon]="plugin_shannon_opts"
+ [dera]="plugin_dera_opts"
+ [sfx]="pluginx_sfx_opts"
+ [transcend]="plugin_transcend_opts"
+ [zns]="plugin_zns_opts"
+ [nvidia]="plugin_nvidia_opts"
+ [ymtc]="plugin_ymtc_opts"
+)
+
+# Top level commands
+_cmds="list list-subsys id-ctrl id-ns \
+ id-ns-granularity list-ns list-ctrl \
+ 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 \
+ fw-log changed-ns-list-log smart-log ana-log \
+ error-log effects-log endurance-log \
+ predictable-lat-log pred-lat-event-agg-log \
+ persistent-event-log endurance-agg-log \
+ lba-status-log resv-notif-log get-feature \
+ device-self-test self-test-log set-feature \
+ set-property get-property format fw-commit \
+ fw-download admin-passthru io-passthru \
+ security-send security-recv get-lba-status \
+ resv-acquire resv-register resv-release \
+ resv-report dsm copy flush compare read \
+ write write-zeros write-uncor verify \
+ sanitize sanitize-log reset subsystem-reset \
+ ns-rescan show-regs discover connect-all \
+ connect disconnect disconnect-all gen-hostnqn \
+ show-hostnqn dir-receive dir-send virt-mgmt \
+ rpmb"
+
+# Add plugins:
+for plugin in "${!_plugin_subcmds[@]}"; do
+ _cmds+=" $plugin"
+done
+
+cmds+=" version help"
nvme_list_opts () {
- local opts=""
+ local opts=""
local compargs=""
local nonopt_args=0
@@ -31,34 +126,66 @@ nvme_list_opts () {
opts+=" "
+ # Listed here in the same order as in nvme-builtin.h
case "$1" in
"list")
- opts=""
- ;;
+ opts+=$NO_OPTS
+ ;;
+ "list-subsys")
+ opts=+=" --output-format= -o --verbose -v"
+ ;;
"id-ctrl")
opts+=" --raw-binary -b --human-readable -H \
--vendor-specific -v --output-format= -o"
- ;;
+ ;;
"id-ns")
opts+=" --namespace-id= -n --raw-binary -b \
--human-readable -H --vendor-specific -v \
--force -f --output-format= -o"
;;
+ "id-ns-granularity")
+ opts+=" --output-format= -o"
+ ;;
"list-ns")
- opts+=" --namespace-id= -n --al -a --csi= -y"
+ opts+=" --namespace-id= -n --al -a --csi= -y \
+ --outputformat= -o"
;;
- "id-iocs")
- opts+=" --controller-id= -c"
+ "list-ctrl")
+ opts+=" --namespace-id= -n --cntid= -c \
+ --output-format= -o"
+ ;;
+ "id-domain")
+ opts+=" --dom-id= -d --output-format= -o"
;;
"nvm-id-ctrl")
opts+=" --output-format= -o"
;;
+ "primary-ctrl-caps")
+ opts+=" --output-format= -o --human-readable -H"
+ ;;
+ "list-secondary")
+ opts+=" --cntid= -c --namespace-id= n --num-entries -e \
+ --output-format= -o"
+ ;;
+ "ns-descs")
+ opts+=" --namespace-id= -n --output-format -o --raw-binary -b"
+ ;;
+ "id-nvmset")
+ opts+=" --nvmeset-id= -i --output-format= -o"
+ ;;
+ "id-uuid")
+ opts+=" --output-format= -o --raw-binary -b --human-readable -H"
+ ;;
+ "id-iocs")
+ opts+=" --controller-id= -c --output-format= -o --human-readable -H"
+ ;;
"create-ns")
opts+=" --nsze= -s --ncap= -c --flbas= -f \
- --dps= -d --nmic= -n --csi= -y"
+ --dps= -d --nmic= -n --anagrp-id= -a --nvmset-id= -i \
+ --block-size= -b --timeout= -t--csi= -y"
;;
"delete-ns")
- opts+=" -namespace-id= -n"
+ opts+=" -namespace-id= -n --timeout= -t"
;;
"attach-ns")
opts+=" --namespace-id= -n --controllers= -c"
@@ -66,41 +193,55 @@ nvme_list_opts () {
"detach-ns")
opts+=" --namespace-id= -n --controllers= -c"
;;
- "list-ctrl")
- opts+=" --namespace-id= -n --cntid= -c"
- ;;
"get-ns-id")
+ opts+=$NO_OPTS
;;
"get-log")
opts+=" --log-id= -i --log-len= -l --namespace-id= -n \
- --raw-binary= -b"
- ;;
- "persistent-event-log")
- opts+=" --action= -a --log-len= -l \
- --raw-binary -b --output-format= -o"
- ;;
- "pred-lat-event-agg-log")
- opts+=" --log-entries= -e --rae -r \
- --raw-binary -b --output-format= -o"
+ --aen= -a --lpo= -o --lsp= -s --lsi= -S \
+ --rae -r --uuid-index= -U --csi= -y --ot -O \
+ --raw-binary -b"
;;
- "predictable-lat-log")
- opts+=" --nvmset-id= -i --raw-binary -b \
- --output-format= -o"
+ "telemetry-log")
+ opts+=" --output-file= -o --host-generate= -g \
+ --controller-init -c --data-area= -d"
;;
"fw-log")
opts+=" --raw-binary -b --output-format= -o"
;;
+ "changed-ns-list-log")
+ opts+=" --output-format= -o --raw-binary -b"
+ ;;
"smart-log")
opts+=" --namespace-id= -n --raw-binary -b \
--output-format= -o"
;;
- "smart-log-add")
- opts+=" --namespace-id= -n --raw-binary -b"
+ "ana-log")
+ opts+=" --output-format -o"
;;
"error-log")
- opts+=" --namespace-id= -n --raw-binary -b --log-entries= -e \
+ opts+=" --raw-binary -b --log-entries= -e \
--output-format= -o"
;;
+ "effects-log")
+ opts+=" --output-format= -o --human-readable -H \
+ --raw-binary -b"
+ ;;
+ "endurance-log")
+ opts+=" --output-format= -o --group-id -g"
+ ;;
+ "predictable-lat-log")
+ opts+=" --nvmset-id= -i --raw-binary -b \
+ --output-format= -o"
+ ;;
+ "pred-lat-event-agg-log")
+ opts+=" --log-entries= -e --rae -r \
+ --raw-binary -b --output-format= -o"
+ ;;
+ "persistent-event-log")
+ opts+=" --action= -a --log-len= -l \
+ --raw-binary -b --output-format= -o"
+ ;;
"endurance-event-agg-log")
opts+=" --log-entries= -e --rae -r \
--raw-binary -b --output-format= -o"
@@ -113,38 +254,58 @@ nvme_list_opts () {
;;
"get-feature")
opts+=" --namespace-id= -n --feature-id= -f --sel= -s \
- --data-len= -l --cdw11= --raw-binary -b \
+ --data-len= -l --cdw11= --c -uuid-index= -U --raw-binary -b \
--human-readable -H"
;;
+ "device-self-test")
+ opts+=" --namespace-id= -n --self-test-code= -s"
+ ;;
+ "self-test-log")
+ opts+=" --dst-entries= -e --output-format= -o \
+ --verbose -v"
+ ;;
"set-feature")
opts+=" --namespace-id= -n --feature-id= -f --value= -v \
- --data-len= -l -data= -d --value= --save -s"
+ --data-len= -l -data= -d --value= -v --save -s --uuid-index= -U \
+ --cdw12= -c"
+ ;;
+ "set-property")
+ opts+=" --offset= -o --value= -v"
+ ;;
+ "get-property")
+ opts=+" --offset= -o --human-readable -H"
;;
"format")
opts+=" --namespace-id= -n --timeout= -t --lbaf= -l \
--ses= -s --pil= -p -pi= -i --ms= -m --reset -r"
;;
- "fw-activate")
- opts+=" --action= -a --slot= -s"
+ "fw-commit")
+ opts+=" --slot= -s --action= -a --bpid= -b"
;;
"fw-download")
opts+=" --fw= -f --xfer= -x --offset= -o"
;;
+ "capacity-mgmt")
+ opts+=" --operation= -f --element-id= -i --cap-lower= -l \
+ --cap-upper= -u"
+ ;;
"admin-passthru")
opts+=" --opcode= -o --flags= -f --prefil= -p --rsvd= -R \
--namespace-id= -n --data-len= -l --metadata-len= -m \
--timeout= -t --cdw2= -2 --cdw3= -3 --cdw10= -4 \
--cdw11= -5 --cdw12= -6 --cdw13= -7 --cdw14= -8 \
- --cdw15= -9 --input-file= -i --raw-binary= -b \
- --show-command -s --dry-run -d --read -r --write -w"
+ --cdw15= -9 --input-file= -i --raw-binary -b \
+ --show-command -s --dry-run -d --read -r --write -w \
+ --latency -T"
;;
"io-passthru")
opts+=" --opcode= -o --flags= -f --prefill= -p --rsvd= -R \
--namespace-id= -n --data-len= -l --metadata-len= -m \
--timeout= -t --cdw2= -2 --cdw3= -3 --cdw10= -4 \
--cdw11= -5 --cdw12= -6 --cdw13= -7 --cdw14= -8 \
- --cdw15= -9 --input-file= -i --raw-binary= -b \
- --show-command -s --dry-run -d --read -r --write -w"
+ --cdw15= -9 --input-file= -i --raw-binary -b \
+ --show-command -s --dry-run -d --read -r --write -w \
+ --latency -T"
;;
"security-send")
opts+=" --namespace-id= -n --file= -f --nssf= -N --secp= -p \
@@ -154,6 +315,11 @@ nvme_list_opts () {
opts+=" --namespace-id= -n --size= -x --secp= -p --spsp= -s \
--al= -t --raw-binary -b"
;;
+ "get-lba-status")
+ opts+=" --namespace-id= -n --start-lba= -s --max-dw= -m \
+ --action= -a --range-len= -l --timeout= -t \
+ --output-format= -o"
+ ;;
"resv-acquire")
opts+=" --namespace-id= -n --crkey= -c --prkey= -p \
--rtype= -t --racqa= -a --iekey= -i"
@@ -167,15 +333,15 @@ nvme_list_opts () {
--rrela= -a --iekey -i"
;;
"resv-report")
- opts+=" --namespace-id= -n --numd= -d --raw-binary= -b \
- --output-format= -o"
+ opts+=" --namespace-id= -n --numd= -d --cdw11 -c \
+ --output-format= -o --raw-binary -b"
;;
"dsm")
- opts+=" --namespace-id= -n --ctx-attrs= -a --blocks= -b\
- -slbs= -s --ad -d --idw -w --idr -r --cdw11= -c"
+ opts+=" --namespace-id= -n --ctx-attrs= -a --blocks= -b \
+ --slbs= -s --ad -d --idw -w --idr -r --cdw11= -c"
;;
"copy")
- opts+=" --sdlba= -d --blocks= -b --slbs= -s \
+ opts+=" --namespace-id= -n --sdlba= -d --blocks= -b --slbs= -s \
--limited-retry -l --force-unit-access -f \
--prinfow= -p --prinfor= -P \
--ref-tag= -r --expected-ref-tag= -R \
@@ -191,7 +357,8 @@ nvme_list_opts () {
--metadata-size= -y --ref-tag= -r --data= -d \
--metadata= -M --prinfo= -p --app-tag-mask= -m \
--app-tag= -a --limited-retry -l \
- --force-unit-access -f --show-command -v \
+ --force-unit-access -f --storage-tag-check -C \
+ --dir-type= -T --dir-spec= -S --dsm= -D --show-command -v \
--dry-run -w --latency -t"
;;
"read")
@@ -199,7 +366,8 @@ nvme_list_opts () {
--metadata-size= -y --ref-tag= -r --data= -d \
--metadata= -M --prinfo= -p --app-tag-mask= -m \
--app-tag= -a --limited-retry -l \
- --force-unit-access -f --show-command -v \
+ --force-unit-access -f --storage-tag-check -C \
+ --dir-type= -T --dir-spec= -S --dsm= -D --show-command -v \
--dry-run -w --latency -t"
;;
"write")
@@ -207,66 +375,1004 @@ nvme_list_opts () {
--metadata-size= -y --ref-tag= -r --data= -d \
--metadata= -M --prinfo= -p --app-tag-mask= -m \
--app-tag= -a --limited-retry -l \
- --force-unit-access -f --show-command -v \
+ --force-unit-access -f --storage-tag-check -C \
+ --dir-type= -T --dir-spec= -S --dsm= -D --show-command -v \
--dry-run -w --latency -t"
;;
"write-zeros")
opts+=" --namespace-id= -n --start-block= -s \
- --block-count= -c --limited-retry -l \
+ --block-count= -c --deac -d --limited-retry -l \
--force-unit-access -f --prinfo= -p --ref-tag= -r \
- --app-tag-mask= -m --app-tag= -a"
+ --app-tag-mask= -m --app-tag= -a \
+ --storage-tag= -S --storage-tag-check -C"
;;
"write-uncor")
opts+=" --namespace-id= -n --start-block= -s \
--block-count= -c"
;;
+ "verify")
+ opts+=" --namespace-id= -n --start-block= -s \
+ --block-count= -c --limited-retry -l \
+ --force-unit-access -f --prinfo= -p --ref-tag= -r \
+ --app-tag= -a --app-tag-mask= -m \
+ --storage-tag= -S --storage-tag-check -C"
+ ;;
+ "sanitize")
+ opts+=" --no-dealloc -d --oipbp -i --owpass= -n \
+ --ause -u --sanact= -a --ovrpat= -p"
+ ;;
+ "sanitize-log")
+ opts+=" --rae -r --output-format= -o --human-readable -H \
+ --raw-binary -b"
+ ;;
"reset")
- opts+=""
+ opts+=$NO_OPTS
;;
"subsystem-reset")
- opts+=""
+ opts+=$NO_OPTS
+ ;;
+ "ns-rescan")
+ opts+=$NO_OPTS
;;
"show-regs")
- opts+=" --human-readable -H"
+ opts+=" --output-format= -o --human-readable -H"
;;
"discover")
opts+=" --transport= -t -traddr= -a -trsvcid= -s \
- --hostnqn= -q --raw= -r"
+ --host-traddr= -w --hsot-iface= -f \
+ --hostnqn= -q --hostid -I --raw= -r \
+ --raw= -r --device= -d --keep-alive-tmo= -k \
+ --ctrl-loss-tmo= -l --fast-io-fail-tmo= -f \
+ --tos= -T --hdr-digest= -g --data-digest -G \
+ --nr-io-queues= -i --nr-write-queues= -W \
+ --nr-poll-queues= -P --queue-size= -Q \
+ --persistent -p --quiet -S --matching -m \
+ --output-format= -o"
;;
"connect-all")
- opts+=" --transport= -t --traddr= -a --trsvcid= -s
- --hostnqn= -q --raw= -r"
+ opts+=" --transport= -t -traddr= -a -trsvcid= -s \
+ --host-traddr= -w --hsot-iface= -f \
+ --hostnqn= -q --hostid -I --raw= -r \
+ --raw= -r --device= -d --keep-alive-tmo= -k \
+ --ctrl-loss-tmo= -l --fast-io-fail-tmo= -f \
+ --tos= -T --hdr-digest= -g --data-digest -G \
+ --nr-io-queues= -i --nr-write-queues= -W \
+ --nr-poll-queues= -P --queue-size= -Q \
+ --persistent -p --quiet -S --matching -m \
+ --output-format= -o"
;;
"connect")
opts+=" --transport= -t --nqn= -n --traddr= -a --trsvcid -s \
- --hostnqn= -q --nr-io-queues= -i --keep-alive-tmo -k \
- --reconnect-delay -r"
+ --hostnqn= -q --host-id= -I --nr-io-queues= -i \
+ --nr-poll-queues= -P --queue-size= -Q \
+ --keep-alive-tmo= -k --reconnect-delay= -r \
+ --ctrl-loss-tmo= -l --fast-io-fail-tmo= -f \
+ --tos= -T --duplicate-connect -D --disable-sqflow -d\
+ --hdr-digest -g --data-digest -G --output-format= -o"
;;
"disconnect")
opts+=" --nqn -n --device -d"
;;
+ "disconnect-all")
+ opts+=$NO_OPTS
+ ;;
+ "gen-hostnqn")
+ opts+=$NO_OPTS
+ ;;
+ "show-hostnqn")
+ opts+=$NO_OPTS
+ ;;
+ "dir-receive")
+ opts+=" --namespace-id= -n --data-len= -l --raw-binary -b \
+ --dir-type= -D --dir-spec= -S --dir-oper= -O \
+ --req-resource= -r --human-readable -H"
+ ;;
+ "dir-send")
+ opts+=" --namespace-id= -n --data-len= -l --dir-type= -D \
+ --target-dir= -T --dir-spec= -S --dir-oper= -O \
+ --endir= -e --human-readable -H --raw-binary -b"
+ ;;
+ "virt-mgmt")
+ opts+=" --cntlid= -c --rt= -r --act= -a --nr= -n"
+ ;;
+ "rpmb")
+ opts+=" --cmd= -c --msgfile= -f --keyfile= -g \
+ --key= -k --msg= -d --address= -o --blocks= -b \
+ --target= -t"
+ ;;
"version")
- opts+=""
+ opts+=$NO_OPTS
;;
"help")
opts=$_cmds
;;
esac
- opts+=" -h --help"
+ opts+=" -h --help"
+
+ COMPREPLY+=( $( compgen $compargs -W "$opts" -- $cur ) )
+
+ return 0
+}
+
+plugin_intel_opts () {
+ local opts=""
+ local compargs=""
+
+ local nonopt_args=0
+ for (( i=0; i < ${#words[@]}-1; i++ )); do
+ if [[ ${words[i]} != -* ]]; then
+ let nonopt_args+=1
+ fi
+ done
+
+ if [ $nonopt_args -eq 3 ]; then
+ opts="/dev/nvme* "
+ fi
+
+ opts+=" "
+
+ case "$1" in
+ "id-ctrl")
+ opts+=" --raw-binary -b --human-readable -H \
+ --vendor-specific -v --output-format= -o"
+ ;;
+ "internal-log")
+ opts+=" --log= -l --region= -r --nlognum= -m \
+ --namespace-id= -n --output-file= -o \
+ --verbose-nlog -v"
+ ;;
+ "lat-stats")
+ opts+=" --write -w --raw-binary -b --json -j"
+ ;;
+ "set-bucket-thresholds")
+ opts+=" --write -w --bucket-thresholds= -t"
+ ;;
+ "lat-stats-tracking")
+ opts+=" --enable -e --disable -d"
+ ;;
+ "market-name")
+ opts+=" --raw-binary -b"
+ ;;
+ "smart-log-add")
+ opts+=" --namespace-id= -n --raw-binary -b \
+ --json -j"
+ ;;
+ "temp-stats")
+ opts+=" --raw-binary -b"
+ ;;
+ "help")
+ opts+=$NO_OPTS
+ ;;
+ esac
+
+ COMPREPLY+=( $( compgen $compargs -W "$opts" -- $cur ) )
+
+ return 0
+}
+
+plugin_amzn_opts () {
+ local opts=""
+ local compargs=""
+
+ local nonopt_args=0
+ for (( i=0; i < ${#words[@]}-1; i++ )); do
+ if [[ ${words[i]} != -* ]]; then
+ let nonopt_args+=1
+ fi
+ done
+
+ if [ $nonopt_args -eq 3 ]; then
+ opts="/dev/nvme* "
+ fi
+
+ opts+=" "
+
+ case "$1" in
+ "id-ctrl")
+ opts+=" --raw-binary -b --human-readable -H \
+ --vendor-specific -v --output-format= -o"
+ ;;
+ "help")
+ opts+=$NO_OPTS
+ ;;
+ esac
+
+ COMPREPLY+=( $( compgen $compargs -W "$opts" -- $cur ) )
+
+ return 0
+}
+
+plugin_lnvm_opts () {
+ local opts=""
+ local compargs=""
+
+ local nonopt_args=0
+ for (( i=0; i < ${#words[@]}-1; i++ )); do
+ if [[ ${words[i]} != -* ]]; then
+ let nonopt_args+=1
+ fi
+ done
+
+ if [ $nonopt_args -eq 3 ]; then
+ opts="/dev/nvme* "
+ fi
+
+ opts+=" "
+
+ case "$1" in
+ "list")
+ opts+=$NO_OPTS
+ ;;
+ "info")
+ opts+=$NO_OPTS
+ ;;
+ "id-ns")
+ opts+=" --namespace-id= -n --raw-binary -b --human-readable -H"
+ ;;
+ "chunk-log")
+ opts+=" --output-format= -o --human-readable -H"
+ ;;
+ "init")
+ opts+=" --device-name= -d --mediamgr-name -m"
+ ;;
+ "create")
+ opts+=" --device-name= -d --target-name= -n --target-type= -t \
+ --lun-begin= -b --lun-end= -e --over-prov= -o --factory -f"
+ ;;
+ "remove")
+ opts+=" --target-name= -n"
+ ;;
+ "factory")
+ opts+=" --device-name= -d --erase-only-marked -e
+ --clear-host-side-blks -s --clear-bb-blks -b"
+ ;;
+ "diag-bbtbl")
+ opts+=" --namespace-id= -n --channel-id= -c --lun-id= -l \
+ --raw-binary -b"
+ ;;
+ "diag-set-bbtbl")
+ opts+=" --namespace-id= -n --channel-id= -c --lun-id= -l \
+ --plane-id= -p --block-id= -b --value= -v"
+ ;;
+ "help")
+ opts+=$NO_OPTS
+ ;;
+ esac
+
+ COMPREPLY+=( $( compgen $compargs -W "$opts" -- $cur ) )
+
+ return 0
+}
+
+plugin_memblaze_opts () {
+ local opts=""
+ local compargs=""
+
+ local nonopt_args=0
+ for (( i=0; i < ${#words[@]}-1; i++ )); do
+ if [[ ${words[i]} != -* ]]; then
+ let nonopt_args+=1
+ fi
+ done
+
+ if [ $nonopt_args -eq 3 ]; then
+ opts="/dev/nvme* "
+ fi
+
+ opts+=" "
+
+ case "$1" in
+ "smart-log-add")
+ opts+=" --namespace-id= -n --raw-binary -b"
+ ;;
+ "get-pm-status")
+ opts+=$NO_OPTS
+ ;;
+ "set-pm-status")
+ opts+=" --value= -v --save -s"
+ ;;
+ "select-download")
+ opts+=" --fw= -f --select= -s"
+ ;;
+ "lat-stats")
+ opts+=" --enable -e --disable -d"
+ ;;
+ "lat-stats-print")
+ opts+=" --write -w"
+ ;;
+ "lat-log")
+ opts+=" --param= -p"
+ ;;
+ "lat-log-print")
+ opts+=$NO_OPTS
+ ;;
+ "clear-error-log")
+ opts+=$NO_OPTS
+ ;;
+ "help")
+ opts+=$NO_OPTS
+ ;;
+ esac
+
+ COMPREPLY+=( $( compgen $compargs -W "$opts" -- $cur ) )
+
+ return 0
+}
+
+plugin_wdc_opts () {
+ local opts=""
+ local compargs=""
+
+ local nonopt_args=0
+ for (( i=0; i < ${#words[@]}-1; i++ )); do
+ if [[ ${words[i]} != -* ]]; then
+ let nonopt_args+=1
+ fi
+ done
+
+ if [ $nonopt_args -eq 3 ]; then
+ opts="/dev/nvme* "
+ fi
+
+ opts+=" "
+
+ case "$1" in
+ "cap-diag")
+ opts+=" --output-file= -o --transfer-size= -s"
+ ;;
+ "drive-log")
+ opts+=" --output-file= -o"
+ ;;
+ "get-crash-dump")
+ opts+=" --output-file= -o"
+ ;;
+ "get-pfail-dump")
+ opts+=" --output-file= -o"
+ ;;
+ "id-ctrl")
+ opts+=" --raw-binary -b --human-readable -H \
+ --vendor-specific -v --output-format= -o"
+ ;;
+ "purge")
+ opts+=$NO_OPTS
+ ;;
+ "purge-monitor")
+ opts+=$NO_OPTS
+ ;;
+ "vs-internal-log")
+ opts+=" --output-file= -o --transfer-size= -s --data-area= -d \
+ --file-size= -f --offset= -e --type= -t --verbose -v"
+ ;;
+ "vs-nand-stats")
+ opts+=" --output-format= -o"
+ ;;
+ "vs-smart-add-log")
+ opts+=" --interval= -i --output-format= -o --log-page-version= -l \
+ --log-page-mask= -p"
+ ;;
+ "clear-pcie-correctable-errors")
+ opts+=$NO_OPTS
+ ;;
+ "drive-essentials")
+ opts+=" --dir-name= -d"
+ ;;
+ "get-drive-status")
+ opts+=$NO_OPTS
+ ;;
+ "clear-assert-dump")
+ opts+=$NO_OPTS
+ ;;
+ "drive-resize")
+ opts+=" --size= -s"
+ ;;
+ "vs-fw-activate-history")
+ opts+=" --output-format= -o"
+ ;;
+ "clear-fw-activate-history")
+ opts+=$NO_OPTS
+ ;;
+ "enc-get-log")
+ opts+=" --output-file= -o --transfer-size= -s --log-id= -l"
+ ;;
+ "vs-telemetry-controller-option")
+ opts+=" --disable -d --enable -e --status -s"
+ ;;
+ "vs-error-reason-identifier")
+ opts+=" --log-id= -i --file= -o"
+ ;;
+ "log-page-directory")
+ opts+=" --output-format= -o"
+ ;;
+ "namespace-resize")
+ opts+=" --namespace-id= -n --op-option= -o"
+ ;;
+ "vs-drive-info")
+ opts+=" --output-format= -o"
+ ;;
+ "vs-temperature-stats")
+ opts+=" --output-format= -o"
+ ;;
+ "capabilities")
+ opts+=$NO_OPTS
+ ;;
+ "cloud-SSD-plugin-version")
+ opts+=$NO_OPTS
+ ;;
+ "vs-pcie-stats")
+ opts+=" --output-format= -o"
+ ;;
+ "help")
+ opts+=$NO_OPTS
+ ;;
+ esac
+
+ COMPREPLY+=( $( compgen $compargs -W "$opts" -- $cur ) )
+
+ return 0
+}
+
+plugin_huawei_opts () {
+ local opts=""
+ local compargs=""
+
+ local nonopt_args=0
+ for (( i=0; i < ${#words[@]}-1; i++ )); do
+ if [[ ${words[i]} != -* ]]; then
+ let nonopt_args+=1
+ fi
+ done
+
+ if [ $nonopt_args -eq 3 ]; then
+ opts="/dev/nvme* "
+ fi
+
+ opts+=" "
+
+ case "$1" in
+ "list")
+ opts+=" --output-format= -o"
+ ;;
+ "id-ctrl")
+ opts+=" --raw-binary -b --human-readable -H \
+ --vendor-specific -v --output-format= -o"
+ ;;
+ "help")
+ opts+=$NO_OPTS
+ ;;
+ esac
+
+ COMPREPLY+=( $( compgen $compargs -W "$opts" -- $cur ) )
+
+ return 0
+}
+
+plugin_toshiba_opts () {
+ local opts=""
+ local compargs=""
+
+ local nonopt_args=0
+ for (( i=0; i < ${#words[@]}-1; i++ )); do
+ if [[ ${words[i]} != -* ]]; then
+ let nonopt_args+=1
+ fi
+ done
+
+ if [ $nonopt_args -eq 3 ]; then
+ opts="/dev/nvme* "
+ fi
+
+ opts+=" "
+
+ case "$1" in
+ "vs-smart-add-log")
+ opts+=" --namespace-id= -n --output-file= -o --log= -l"
+ ;;
+ "vs-internal-log")
+ opts+=" --output-file= -o --prev-log -p"
+ ;;
+ "clear-pcie-correctable-errors")
+ opts+=$NO_OPTS
+ ;;
+ "help")
+ opts+=$NO_OPTS
+ ;;
+ esac
+
+ COMPREPLY+=( $( compgen $compargs -W "$opts" -- $cur ) )
+
+ return 0
+}
+
+plugin_micron_opts () {
+ local opts=""
+ local compargs=""
+
+ local nonopt_args=0
+ for (( i=0; i < ${#words[@]}-1; i++ )); do
+ if [[ ${words[i]} != -* ]]; then
+ let nonopt_args+=1
+ fi
+ done
+
+ if [ $nonopt_args -eq 3 ]; then
+ opts="/dev/nvme* "
+ fi
+
+ opts+=" "
+
+ case "$1" in
+ "select-download")
+ opts+=" --fw= -f --select= -s"
+ ;;
+ "vs-temperature-stats")
+ opts+=" --format= -f"
+ ;;
+ "vs-pcie-stats")
+ opts+=" --format= -f"
+ ;;
+ "clear-pcie-correctable-errors")
+ opts+=$NO_OPTS
+ ;;
+ "vs-internal-log")
+ opts+=" --type= -t --package= -p --data_area= -d"
+ ;;
+ "vs-telemetry-controller-option")
+ opts+=" --option= -o --select= -s"
+ ;;
+ "vs-nand-stats")
+ opts+=" --format= -f"
+ ;;
+ "vs-drive-info")
+ opts+=" --format= -f"
+ ;;
+ "plugin-version")
+ opts+=$NO_OPTS
+ ;;
+ "cloud-SSD-plugin-version")
+ opts+=$NO_OPTS
+ ;;
+ "log-page-directory")
+ opts+=$NO_OPTS
+ ;;
+ "vs-fw-activate-history")
+ opts+=" --format= -f"
+ ;;
+ "vs-error-reason-identifier")
+ opts+=" --format= -f"
+ ;;
+ "vs-smart-add-log")
+ opts+=" --format= -f"
+ ;;
+ "clear-fw-activate-history")
+ opts+=$NO_OPTS
+ ;;
+ "vs-smbus-option")
+ opts+=" --option= -o --value= -v --save= -s"
+ ;;
+ "help")
+ opts+=$NO_OPTS
+ ;;
+ esac
+
+ COMPREPLY+=( $( compgen $compargs -W "$opts" -- $cur ) )
+
+ return 0
+}
+
+lugin_seagate_opts () {
+ local opts=""
+ local compargs=""
+
+ local nonopt_args=0
+ for (( i=0; i < ${#words[@]}-1; i++ )); do
+ if [[ ${words[i]} != -* ]]; then
+ let nonopt_args+=1
+ fi
+ done
+
+ if [ $nonopt_args -eq 3 ]; then
+ opts="/dev/nvme* "
+ fi
+
+ opts+=" "
+
+ case "$1" in
+ "vs-temperature-stats")
+ opts+=" --output-format= -o"
+ ;;
+ "vs-log-page-sup")
+ opts+=" --output-format= -o"
+ ;;
+ "vs-smart-add-log")
+ opts+=" --output-format= -o"
+ ;;
+ "vs-pcie-stats")
+ opts+=" --output-format= -o"
+ ;;
+ "clear-pcie-correctable-errors")
+ opts+=" --save -s"
+ ;;
+ "get-host-tele")
+ opts+=" --namespace-id= -n --log-specific= -i --raw-binary -b"
+ ;;
+ "get-ctrl-tele")
+ opts+=" --namespace-id= -n --raw-binary -b"
+ ;;
+ "vs-internal-log")
+ opts+=" --namespace-id= -n --dump-file= -f"
+ ;;
+ "plugin-version")
+ opts+=$NO_OPTS
+ ;;
+ "help")
+ opts+=""
+ ;;
+ esac
+
+ COMPREPLY+=( $( compgen $compargs -W "$opts" -- $cur ) )
+
+ return 0
+}
+
+plugin_virtium_opts () {
+ local opts=""
+ local compargs=""
+
+ local nonopt_args=0
+ for (( i=0; i < ${#words[@]}-1; i++ )); do
+ if [[ ${words[i]} != -* ]]; then
+ let nonopt_args+=1
+ fi
+ done
+
+ if [ $nonopt_args -eq 3 ]; then
+ opts="/dev/nvme* "
+ fi
+
+ opts+=" "
+
+ case "$1" in
+ "save-smart-to-vtview-log")
+ opts+=" --run-time= -r --freq= -f --output-file= -o --test-name= -n"
+ ;;
+ "show-identify")
+ opts+=$NO_OPTS
+ ;;
+ "help")
+ opts+=$NO_OPTS
+ ;;
+ esac
COMPREPLY+=( $( compgen $compargs -W "$opts" -- $cur ) )
return 0
}
+plugin_shannon_opts () {
+ local opts=""
+ local compargs=""
+
+ local nonopt_args=0
+ for (( i=0; i < ${#words[@]}-1; i++ )); do
+ if [[ ${words[i]} != -* ]]; then
+ let nonopt_args+=1
+ fi
+ done
+
+ if [ $nonopt_args -eq 3 ]; then
+ opts="/dev/nvme* "
+ fi
+
+ opts+=" "
+
+ case "$1" in
+ "smart-log-add")
+ opts+=" --namespace-id= -n --raw-binary -b"
+ ;;
+ "get-feature-add")
+ opts+=" --namespace-id= -n --feature-id -f --sel= -s \
+ --data-len= -l --raw-binary -b --cdw11= -c --human-readable -H"
+ ;;
+ "set-feature-add")
+ opts+=" --namespace-id= -n --feature-id= -f --value= -v \
+ --data-len= -l --data= -d --save -s"
+ ;;
+ "id-ctrl")
+ opts+=" --raw-binary -b --human-readable -H \
+ --vendor-specific -v --output-format= -o"
+ ;;
+ "help")
+ opts+=$NO_OPTS
+ ;;
+ esac
+
+ COMPREPLY+=( $( compgen $compargs -W "$opts" -- $cur ) )
+
+ return 0
+}
+
+plugin_dera_opts () {
+ local opts=""
+ local compargs=""
+
+ local nonopt_args=0
+ for (( i=0; i < ${#words[@]}-1; i++ )); do
+ if [[ ${words[i]} != -* ]]; then
+ let nonopt_args+=1
+ fi
+ done
+
+ if [ $nonopt_args -eq 3 ]; then
+ opts="/dev/nvme* "
+ fi
+
+ opts+=" "
+
+ case "$1" in
+ "smart-log-add")
+ opts+=$NO_OPTS
+ ;;
+ "help")
+ opts+=$NO_OPTS
+ ;;
+ esac
+
+ COMPREPLY+=( $( compgen $compargs -W "$opts" -- $cur ) )
+
+ return 0
+}
+
+plugin_sfx_opts () {
+ local opts=""
+ local compargs=""
+
+ local nonopt_args=0
+ for (( i=0; i < ${#words[@]}-1; i++ )); do
+ if [[ ${words[i]} != -* ]]; then
+ let nonopt_args+=1
+ fi
+ done
+
+ if [ $nonopt_args -eq 3 ]; then
+ opts="/dev/nvme* "
+ fi
+
+ opts+=" "
+
+ case "$1" in
+ "smart-log-add")
+ opts+=" --namespace-id= -n --raw-binary -b --json -j"
+ ;;
+ "lat-stats")
+ opts+=" --write -w --raw-binary -b"
+ ;;
+ "get-bad-block")
+ opts+=$NO_OPTS
+ ;;
+ "query-cap")
+ opts+=" --raw-binary --json"
+ ;;
+ "change-cap")
+ opts+=" --cap= -c --cap-byte= -z --force -f --raw-binary -b --json -j"
+ ;;
+ "set-feature")
+ opts+=" --namespace-id= -n --feature-id= -f --value= -v --force -s"
+ ;;
+ "get-feature")
+ opts+=" --namespace-id= -n --feature-id -f"
+ ;;
+ "help")
+ opts+=$NO_OPTS
+ ;;
+ esac
+
+ COMPREPLY+=( $( compgen $compargs -W "$opts" -- $cur ) )
+
+ return 0
+}
+
+plugin_transcend_opts () {
+ local opts=""
+ local compargs=""
+
+ local nonopt_args=0
+ for (( i=0; i < ${#words[@]}-1; i++ )); do
+ if [[ ${words[i]} != -* ]]; then
+ let nonopt_args+=1
+ fi
+ done
+
+ if [ $nonopt_args -eq 3 ]; then
+ opts="/dev/nvme* "
+ fi
+
+ opts+=" "
+
+ case "$1" in
+ "healthvalue")
+ opts+=$NO_OPTS
+ ;;
+ "badblock")
+ opts+=$NO_OPTS
+ ;;
+ "help")
+ opts+=$NO_OPTS
+ ;;
+ esac
+
+ COMPREPLY+=( $( compgen $compargs -W "$opts" -- $cur ) )
+
+ return 0
+}
+
+plugin_zns_opts () {
+ local opts=""
+ local compargs=""
+
+ local nonopt_args=0
+ for (( i=0; i < ${#words[@]}-1; i++ )); do
+ if [[ ${words[i]} != -* ]]; then
+ let nonopt_args+=1
+ fi
+ done
+
+ if [ $nonopt_args -eq 3 ]; then
+ opts="/dev/nvme* "
+ fi
+
+ opts+=" "
+
+ case "$1" in
+ "id-ctrl")
+ opts+=" --raw-binary -b --human-readable -H \
+ --vendor-specific -v --output-format= -o"
+ ;;
+ "id-ns")
+ opts+=" --namespace-id= -n --vendor-specific -v \
+ --output-format= -o --human-readable -H"
+ ;;
+ "zone-mgmt-recv")
+ opts+=" --output-format= -o --namespace-id= -n \
+ --start-lba= -s --zra= -z --zrasf= -S --partial -p \
+ --data-len= -l"
+ ;;
+ "zone-mgmt-send")
+ opts+=" --namespace-id= -n --start-lba= -s \
+ --select-all -a --zsa= -z --data-len= -l \
+ --data= -d --timeout= -t"
+ ;;
+ "report-zones")
+ opts+=" --namespace-id= -n --start-lba= -s \
+ --descs= -d --state= -S --output-format= -o \
+ --human-readable -H --extended -e --partial -p"
+ ;;
+ "close-zone")
+ opts+=" --namespace-id= -n --start-lba= -s \
+ --select-all -a --timeout= -t"
+ ;;
+ "finish-zone")
+ opts+=" --namespace-id= -n --start-lba= -s \
+ --select-all -a --timeout= -t"
+ ;;
+ "open-zone")
+ opts+=" --namespace-id= -n --start-lba= -s \
+ --select-all -a --timeout= -t"
+ ;;
+ "reset-zone")
+ opts+=" --namespace-id= -n --start-lba= -s \
+ --select-all -a --timeout= -t"
+ ;;
+ "offline-zone")
+ opts+=" --namespace-id= -n --start-lba= -s \
+ --select-all -a --timeout= -t"
+ ;;
+ "set-zone-desc")
+ opts+=" --namespace-id= -n --start-lba= -s \
+ --data= -d --timeout= -t"
+ ;;
+ "zone-append")
+ opts+=" --namespace-id= -n --zslba= -s --data-size= -z \
+ --metadata-size= -y --data= -d --metadata= -M \
+ --limited-retry -l --force-unit-access -f --ref-tag= -r
+ --app-tag-mask= -m --app-tag= -a --prinfo= -p \
+ --piremap -P --latency -t"
+ ;;
+ "changed-zone-list")
+ opts+=" --namespace-id= -n --output-format= -o --rae -r"
+ ;;
+ "help")
+ opts+=$NO_OPTS
+ ;;
+ esac
+
+ COMPREPLY+=( $( compgen $compargs -W "$opts" -- $cur ) )
+
+ return 0
+}
+
+plugin_nvidia_opts () {
+ local opts=""
+ local compargs=""
+
+ local nonopt_args=0
+ for (( i=0; i < ${#words[@]}-1; i++ )); do
+ if [[ ${words[i]} != -* ]]; then
+ let nonopt_args+=1
+ fi
+ done
+
+ if [ $nonopt_args -eq 3 ]; then
+ opts="/dev/nvme* "
+ fi
+
+ opts+=" "
+
+ case "$1" in
+ "id-ctrl")
+ opts+=" --raw-binary -b --human-readable -H \
+ --vendor-specific -v --output-format= -o"
+ ;;
+ "help")
+ opts+=$NO_OPTS
+ ;;
+ esac
+
+ COMPREPLY+=( $( compgen $compargs -W "$opts" -- $cur ) )
+
+ return 0
+}
+
+plugin_ymtc_opts () {
+ local opts=""
+ local compargs=""
+
+ local nonopt_args=0
+ for (( i=0; i < ${#words[@]}-1; i++ )); do
+ if [[ ${words[i]} != -* ]]; then
+ let nonopt_args+=1
+ fi
+ done
+
+ if [ $nonopt_args -eq 3 ]; then
+ opts="/dev/nvme* "
+ fi
+
+ opts+=" "
+
+ case "$1" in
+ "smart-log-add")
+ opts+=" --namespace-id= -n --raw-binary -b"
+ ;;
+ "help")
+ opts+=NO_OPTS
+ ;;
+ esac
+
+ COMPREPLY+=( $( compgen $compargs -W "$opts" -- $cur ) )
+
+ return 0
+}
+
_nvme_subcmds () {
- local cur prev words cword
+ local cur prev words cword
_init_completion || return
if [[ ${#words[*]} -lt 3 ]]; then
COMPREPLY+=( $(compgen -W "$_cmds" -- $cur ) )
else
+ for subcmd in "${!_plugin_subcmds[@]}"; do
+ if [[ ${words[1]} == $subcmd ]]; then
+ if [[ ${#words[*]} -lt 4 ]]; then
+ COMPREPLY+=( $(compgen -W "${_plugin_subcmds[$subcmd]}" -- $cur ) )
+ else
+ func=${_plugin_funcs[$subcmd]}
+ $func ${words[2]} $prev
+ fi
+ return 0
+ fi
+ done
+
nvme_list_opts ${words[1]} $prev
fi
diff --git a/etc/discovery.conf.in b/etc/discovery.conf.in
index 14e0d9c..cfdac1e 100644
--- a/etc/discovery.conf.in
+++ b/etc/discovery.conf.in
@@ -1,4 +1,4 @@
# Used for extracting default parameters for discovery
#
# Example:
-# --transport=<trtype> --traddr=<traddr> --trsvcid=<trsvcid> --host-traddr=<host-traddr>
+# --transport=<trtype> --traddr=<traddr> --trsvcid=<trsvcid> --host-traddr=<host-traddr> --host-iface=<host-iface>
diff --git a/fabrics.c b/fabrics.c
index 7dd0d27..39bee97 100644
--- a/fabrics.c
+++ b/fabrics.c
@@ -66,9 +66,11 @@ const char *conarg_transport = "transport";
const char *conarg_traddr = "traddr";
const char *conarg_trsvcid = "trsvcid";
const char *conarg_host_traddr = "host_traddr";
+const char *conarg_host_iface = "host_iface";
struct fabrics_config fabrics_cfg = {
.ctrl_loss_tmo = -1,
+ .fast_io_fail_tmo = -1,
.output_format = "normal",
};
@@ -78,6 +80,7 @@ struct connect_args {
char *traddr;
char *trsvcid;
char *host_traddr;
+ char *host_iface;
struct connect_args *next;
struct connect_args *tail;
};
@@ -300,6 +303,7 @@ static bool ctrl_matches_connectargs(const char *name, struct connect_args *args
cargs.traddr = parse_conn_arg(addr, ' ', conarg_traddr);
cargs.trsvcid = parse_conn_arg(addr, ' ', conarg_trsvcid);
cargs.host_traddr = parse_conn_arg(addr, ' ', conarg_host_traddr);
+ cargs.host_iface = parse_conn_arg(addr, ' ', conarg_host_iface);
if (!strcmp(cargs.subsysnqn, NVME_DISC_SUBSYS_NAME)) {
char *kato_str = nvme_get_ctrl_attr(path, "kato"), *p;
@@ -331,7 +335,9 @@ static bool ctrl_matches_connectargs(const char *name, struct connect_args *args
(!strcmp(cargs.trsvcid, args->trsvcid) ||
!strcmp(args->trsvcid, "none")) &&
(!strcmp(cargs.host_traddr, args->host_traddr) ||
- !strcmp(args->host_traddr, "none")))
+ !strcmp(args->host_traddr, "none")) &&
+ (!strcmp(cargs.host_iface, args->host_iface) ||
+ !strcmp(args->host_iface, "none")))
found = true;
free(cargs.subsysnqn);
@@ -339,6 +345,7 @@ static bool ctrl_matches_connectargs(const char *name, struct connect_args *args
free(cargs.traddr);
free(cargs.trsvcid);
free(cargs.host_traddr);
+ free(cargs.host_iface);
free(addr);
free(path);
@@ -394,6 +401,7 @@ static struct connect_args *extract_connect_args(char *argstr)
cargs->traddr = parse_conn_arg(argstr, ',', conarg_traddr);
cargs->trsvcid = parse_conn_arg(argstr, ',', conarg_trsvcid);
cargs->host_traddr = parse_conn_arg(argstr, ',', conarg_host_traddr);
+ cargs->host_iface = parse_conn_arg(argstr, ',', conarg_host_iface);
return cargs;
}
@@ -404,6 +412,7 @@ static void destruct_connect_args(struct connect_args *cargs)
free(cargs->traddr);
free(cargs->trsvcid);
free(cargs->host_traddr);
+ free(cargs->host_iface);
}
static void free_connect_args(struct connect_args *cargs)
@@ -670,11 +679,17 @@ static int space_strip_len(int max, const char *str)
return i + 1;
}
-static void print_discovery_log(struct nvmf_disc_rsp_page_hdr *log, int numrec)
+static void print_discovery_log(struct nvmf_disc_rsp_page_hdr *log, int numrec,
+ int instance)
{
int i;
- printf("\nDiscovery Log Number of Records %d, "
+ printf("\n");
+
+ if (fabrics_cfg.persistent)
+ printf("Persistent device: nvme%d\n", instance);
+
+ printf("Discovery Log Number of Records %d, "
"Generation counter %"PRIu64"\n",
numrec, le64_to_cpu(log->genctr));
@@ -704,7 +719,7 @@ static void print_discovery_log(struct nvmf_disc_rsp_page_hdr *log, int numrec)
printf("rdma_cms: %s\n",
cms_str(e->tsas.rdma.cms));
printf("rdma_pkey: 0x%04x\n",
- e->tsas.rdma.pkey);
+ le16_to_cpu(e->tsas.rdma.pkey));
break;
case NVMF_TRTYPE_TCP:
printf("sectype: %s\n",
@@ -714,14 +729,20 @@ static void print_discovery_log(struct nvmf_disc_rsp_page_hdr *log, int numrec)
}
}
-static void json_discovery_log(struct nvmf_disc_rsp_page_hdr *log, int numrec)
+static void json_discovery_log(struct nvmf_disc_rsp_page_hdr *log, int numrec,
+ int instance)
{
struct json_object *root;
struct json_object *entries;
+ char *dev_name = NULL;
int i;
+ if (asprintf(&dev_name, "nvme%d", instance) < 0)
+ return;
+
root = json_create_object();
entries = json_create_array();
+ json_object_add_value_string(root, "device", dev_name);
json_object_add_value_uint(root, "genctr", le64_to_cpu(log->genctr));
json_object_add_value_array(root, "records", entries);
@@ -729,6 +750,10 @@ static void json_discovery_log(struct nvmf_disc_rsp_page_hdr *log, int numrec)
struct nvmf_disc_rsp_page_entry *e = &log->entries[i];
struct json_object *entry = json_create_object();
+ nvme_strip_spaces(e->trsvcid, NVMF_TRSVCID_SIZE);
+ nvme_strip_spaces(e->subnqn, NVMF_NQN_SIZE);
+ nvme_strip_spaces(e->traddr, NVMF_TRADDR_SIZE);
+
json_object_add_value_string(entry, "trtype",
trtype_str(e->trtype));
json_object_add_value_string(entry, "adrfam",
@@ -738,8 +763,7 @@ static void json_discovery_log(struct nvmf_disc_rsp_page_hdr *log, int numrec)
json_object_add_value_string(entry,"treq",
treq_str(e->treq));
json_object_add_value_uint(entry, "portid", e->portid);
- json_object_add_value_string(entry, "trsvcid",
- e->trsvcid);
+ json_object_add_value_string(entry, "trsvcid", e->trsvcid);
json_object_add_value_string(entry, "subnqn", e->subnqn);
json_object_add_value_string(entry, "traddr", e->traddr);
@@ -752,7 +776,7 @@ static void json_discovery_log(struct nvmf_disc_rsp_page_hdr *log, int numrec)
json_object_add_value_string(entry, "rdma_cms",
cms_str(e->tsas.rdma.cms));
json_object_add_value_uint(entry, "rdma_pkey",
- e->tsas.rdma.pkey);
+ le16_to_cpu(e->tsas.rdma.pkey));
break;
case NVMF_TRTYPE_TCP:
json_object_add_value_string(entry, "sectype",
@@ -764,6 +788,7 @@ static void json_discovery_log(struct nvmf_disc_rsp_page_hdr *log, int numrec)
json_print_object(root, NULL);
printf("\n");
json_free_object(root);
+ free(dev_name);
}
static void save_discovery_log(struct nvmf_disc_rsp_page_hdr *log, int numrec)
@@ -790,6 +815,28 @@ static void save_discovery_log(struct nvmf_disc_rsp_page_hdr *log, int numrec)
close(fd);
}
+static void print_connect_msg(int instance)
+{
+ printf("device: nvme%d\n", instance);
+}
+
+static void json_connect_msg(int instance)
+{
+ struct json_object *root;
+ char *dev_name = NULL;
+
+ if (asprintf(&dev_name, "nvme%d", instance) < 0)
+ return;
+
+ root = json_create_object();
+ json_object_add_value_string(root, "device", dev_name);
+
+ json_print_object(root, NULL);
+ printf("\n");
+ json_free_object(root);
+ free(dev_name);
+}
+
static char *hostnqn_read_file(void)
{
FILE *f;
@@ -969,6 +1016,7 @@ int build_options(char *argstr, int max_len, bool discover)
if (add_argument(&argstr, &max_len, "transport", fabrics_cfg.transport) ||
add_argument(&argstr, &max_len, "traddr", fabrics_cfg.traddr) ||
add_argument(&argstr, &max_len, "host_traddr", fabrics_cfg.host_traddr) ||
+ add_argument(&argstr, &max_len, "host_iface", fabrics_cfg.host_iface) ||
add_argument(&argstr, &max_len, "trsvcid", fabrics_cfg.trsvcid) ||
((fabrics_cfg.hostnqn || nvmf_hostnqn_file()) &&
add_argument(&argstr, &max_len, "hostnqn", fabrics_cfg.hostnqn)) ||
@@ -991,6 +1039,8 @@ int build_options(char *argstr, int max_len, bool discover)
(strncmp(fabrics_cfg.transport, "loop", 4) &&
add_int_argument(&argstr, &max_len, "ctrl_loss_tmo",
fabrics_cfg.ctrl_loss_tmo, true)) ||
+ add_int_argument(&argstr, &max_len, "fast_io_fail_tmo",
+ fabrics_cfg.fast_io_fail_tmo, true) ||
add_int_argument(&argstr, &max_len, "tos",
fabrics_cfg.tos, true) ||
add_bool_argument(&argstr, &max_len, "duplicate_connect",
@@ -1014,11 +1064,16 @@ static void set_discovery_kato(struct fabrics_config *cfg)
cfg->keep_alive_tmo = 0;
}
-static void discovery_trsvcid(struct fabrics_config *fabrics_cfg)
+static void discovery_trsvcid(struct fabrics_config *fabrics_cfg, bool discover)
{
if (!strcmp(fabrics_cfg->transport, "tcp")) {
- /* Default port for NVMe/TCP discovery controllers */
- fabrics_cfg->trsvcid = __stringify(NVME_DISC_IP_PORT);
+ if (discover) {
+ /* Default port for NVMe/TCP discovery controllers */
+ fabrics_cfg->trsvcid = __stringify(NVME_DISC_IP_PORT);
+ } else {
+ /* Default port for NVMe/TCP io controllers */
+ fabrics_cfg->trsvcid = __stringify(NVME_RDMA_IP_PORT);
+ }
} else if (!strcmp(fabrics_cfg->transport, "rdma")) {
/* Default port for NVMe/RDMA controllers */
fabrics_cfg->trsvcid = __stringify(NVME_RDMA_IP_PORT);
@@ -1158,6 +1213,13 @@ retry:
p+= len;
}
+ if (fabrics_cfg.host_iface && strcmp(fabrics_cfg.host_iface, "none")) {
+ len = sprintf(p, ",host_iface=%s", fabrics_cfg.host_iface);
+ if (len < 0)
+ return -EINVAL;
+ p+= len;
+ }
+
if (fabrics_cfg.reconnect_delay) {
len = sprintf(p, ",reconnect_delay=%d", fabrics_cfg.reconnect_delay);
if (len < 0)
@@ -1172,6 +1234,13 @@ retry:
p += len;
}
+ if (fabrics_cfg.fast_io_fail_tmo) {
+ len = sprintf(p, ",fast_io_fail_tmo=%d", fabrics_cfg.fast_io_fail_tmo);
+ if (len < 0)
+ return -EINVAL;
+ p += len;
+ }
+
if (fabrics_cfg.tos != -1) {
len = sprintf(p, ",tos=%d", fabrics_cfg.tos);
if (len < 0)
@@ -1290,6 +1359,7 @@ static bool cargs_match_found(struct nvmf_disc_rsp_page_entry *entry)
cargs.subsysnqn = strdup(entry->subnqn);
cargs.trsvcid = strdup(entry->trsvcid);
cargs.host_traddr = strdup(fabrics_cfg.host_traddr ?: "\0");
+ cargs.host_iface = strdup(fabrics_cfg.host_iface ?: "\0");
/* check if we have a match in the discovery recursion */
while (c) {
@@ -1297,7 +1367,8 @@ static bool cargs_match_found(struct nvmf_disc_rsp_page_entry *entry)
!strcmp(cargs.transport, c->transport) &&
!strcmp(cargs.traddr, c->traddr) &&
!strcmp(cargs.trsvcid, c->trsvcid) &&
- !strcmp(cargs.host_traddr, c->host_traddr))
+ !strcmp(cargs.host_traddr, c->host_traddr) &&
+ !strcmp(cargs.host_iface, c->host_iface))
return true;
c = c->next;
}
@@ -1313,6 +1384,10 @@ static bool should_connect(struct nvmf_disc_rsp_page_entry *entry)
if (cargs_match_found(entry))
return false;
+ /* skip connect if the transport type doesn't match */
+ if (strcmp(fabrics_cfg.transport, trtype_str(entry->trtype)))
+ return false;
+
if (!fabrics_cfg.matching_only || !fabrics_cfg.traddr)
return true;
@@ -1404,8 +1479,6 @@ int do_discover(char *argstr, bool connect, enum nvme_print_flags flags)
return -errno;
ret = nvmf_get_log_page_discovery(dev_name, &log, &numrec, &status);
free(dev_name);
- if (fabrics_cfg.persistent)
- msg(LOG_NOTICE, "Persistent device: nvme%d\n", instance);
if (!fabrics_cfg.device && !fabrics_cfg.persistent) {
err = remove_ctrl(instance);
if (err)
@@ -1419,9 +1492,9 @@ int do_discover(char *argstr, bool connect, enum nvme_print_flags flags)
else if (fabrics_cfg.raw || flags == BINARY)
save_discovery_log(log, numrec);
else if (flags == JSON)
- json_discovery_log(log, numrec);
+ json_discovery_log(log, numrec, instance);
else
- print_discovery_log(log, numrec);
+ print_discovery_log(log, numrec, instance);
break;
case DISC_GET_NUMRECS:
msg(LOG_ERR,
@@ -1513,7 +1586,7 @@ static int discover_from_conf_file(const char *desc, char *argstr,
}
if (!fabrics_cfg.trsvcid)
- discovery_trsvcid(&fabrics_cfg);
+ discovery_trsvcid(&fabrics_cfg, true);
err = build_options(argstr, BUF_SIZE, true);
if (err) {
@@ -1529,7 +1602,8 @@ free_and_continue:
free(all_args);
free(argv);
fabrics_cfg.transport = fabrics_cfg.traddr =
- fabrics_cfg.trsvcid = fabrics_cfg.host_traddr = NULL;
+ fabrics_cfg.trsvcid = fabrics_cfg.host_traddr =
+ fabrics_cfg.host_iface = NULL;
}
out:
@@ -1548,7 +1622,8 @@ int fabrics_discover(const char *desc, int argc, char **argv, bool connect)
OPT_LIST("transport", 't', &fabrics_cfg.transport, "transport type"),
OPT_LIST("traddr", 'a', &fabrics_cfg.traddr, "transport address"),
OPT_LIST("trsvcid", 's', &fabrics_cfg.trsvcid, "transport service id (e.g. IP port)"),
- OPT_LIST("host-traddr", 'w', &fabrics_cfg.host_traddr, "host traddr (e.g. FC WWN's)"),
+ OPT_LIST("host-traddr", 'w', &fabrics_cfg.host_traddr, "host traddr (e.g. FC WWN's or IP source address)"),
+ OPT_LIST("host-iface", 'f', &fabrics_cfg.host_iface, "host transport interface (e.g. IP eth1, enp2s0)"),
OPT_LIST("hostnqn", 'q', &fabrics_cfg.hostnqn, "user-defined hostnqn (if default not used)"),
OPT_LIST("hostid", 'I', &fabrics_cfg.hostid, "user-defined hostid (if default not used)"),
OPT_LIST("raw", 'r', &fabrics_cfg.raw, "raw output file"),
@@ -1556,6 +1631,7 @@ int fabrics_discover(const char *desc, int argc, char **argv, bool connect)
OPT_INT("keep-alive-tmo", 'k', &fabrics_cfg.keep_alive_tmo, "keep alive timeout period in seconds"),
OPT_INT("reconnect-delay", 'c', &fabrics_cfg.reconnect_delay, "reconnect timeout period in seconds"),
OPT_INT("ctrl-loss-tmo", 'l', &fabrics_cfg.ctrl_loss_tmo, "controller loss timeout period in seconds"),
+ OPT_INT("fast_io_fail_tmo",'f',&fabrics_cfg.fast_io_fail_tmo, "fast I/O fail timeout (default off)"),
OPT_INT("tos", 'T', &fabrics_cfg.tos, "type of service"),
OPT_FLAG("hdr_digest", 'g', &fabrics_cfg.hdr_digest, "enable transport protocol header digest (TCP transport)"),
OPT_FLAG("data_digest", 'G', &fabrics_cfg.data_digest, "enable transport protocol data digest (TCP transport)"),
@@ -1564,7 +1640,7 @@ int fabrics_discover(const char *desc, int argc, char **argv, bool connect)
OPT_INT("nr-poll-queues", 'P', &fabrics_cfg.nr_poll_queues, "number of poll queues to use (default 0)"),
OPT_INT("queue-size", 'Q', &fabrics_cfg.queue_size, "number of io queue elements to use (default 128)"),
OPT_FLAG("persistent", 'p', &fabrics_cfg.persistent, "persistent discovery connection"),
- OPT_FLAG("quiet", 'S', &quiet, "suppress already connected errors"),
+ OPT_FLAG("quiet", 'S', &quiet, "suppress already connected errors"),
OPT_FLAG("matching", 'm', &fabrics_cfg.matching_only, "connect only records matching the traddr"),
OPT_FMT("output-format", 'o', &fabrics_cfg.output_format, output_format),
OPT_END()
@@ -1606,7 +1682,7 @@ int fabrics_discover(const char *desc, int argc, char **argv, bool connect)
}
if (!fabrics_cfg.trsvcid)
- discovery_trsvcid(&fabrics_cfg);
+ discovery_trsvcid(&fabrics_cfg, true);
ret = build_options(argstr, BUF_SIZE, true);
if (ret)
@@ -1623,13 +1699,15 @@ int fabrics_connect(const char *desc, int argc, char **argv)
{
char argstr[BUF_SIZE];
int instance, ret;
+ enum nvme_print_flags flags = -1;
OPT_ARGS(opts) = {
OPT_LIST("transport", 't', &fabrics_cfg.transport, "transport type"),
OPT_LIST("nqn", 'n', &fabrics_cfg.nqn, "nqn name"),
OPT_LIST("traddr", 'a', &fabrics_cfg.traddr, "transport address"),
OPT_LIST("trsvcid", 's', &fabrics_cfg.trsvcid, "transport service id (e.g. IP port)"),
- OPT_LIST("host-traddr", 'w', &fabrics_cfg.host_traddr, "host traddr (e.g. FC WWN's)"),
+ OPT_LIST("host-traddr", 'w', &fabrics_cfg.host_traddr, "host traddr (e.g. FC WWN's or IP source address)"),
+ OPT_LIST("host-iface", 'f', &fabrics_cfg.host_iface, "host transport interface (e.g. IP eth1, enp2s0)"),
OPT_LIST("hostnqn", 'q', &fabrics_cfg.hostnqn, "user-defined hostnqn"),
OPT_LIST("hostid", 'I', &fabrics_cfg.hostid, "user-defined hostid (if default not used)"),
OPT_INT("nr-io-queues", 'i', &fabrics_cfg.nr_io_queues, "number of io queues to use (default is core count)"),
@@ -1639,25 +1717,42 @@ int fabrics_connect(const char *desc, int argc, char **argv)
OPT_INT("keep-alive-tmo", 'k', &fabrics_cfg.keep_alive_tmo, "keep alive timeout period in seconds"),
OPT_INT("reconnect-delay", 'c', &fabrics_cfg.reconnect_delay, "reconnect timeout period in seconds"),
OPT_INT("ctrl-loss-tmo", 'l', &fabrics_cfg.ctrl_loss_tmo, "controller loss timeout period in seconds"),
+ OPT_INT("fast_io_fail_tmo", 'f', &fabrics_cfg.fast_io_fail_tmo, "fast I/O fail timeout (default off)"),
OPT_INT("tos", 'T', &fabrics_cfg.tos, "type of service"),
OPT_FLAG("duplicate-connect", 'D', &fabrics_cfg.duplicate_connect, "allow duplicate connections between same transport host and subsystem port"),
OPT_FLAG("disable-sqflow", 'd', &fabrics_cfg.disable_sqflow, "disable controller sq flow control (default false)"),
OPT_FLAG("hdr-digest", 'g', &fabrics_cfg.hdr_digest, "enable transport protocol header digest (TCP transport)"),
OPT_FLAG("data-digest", 'G', &fabrics_cfg.data_digest, "enable transport protocol data digest (TCP transport)"),
+ OPT_FMT("output-format", 'o', &fabrics_cfg.output_format, "Output format: normal|json"),
OPT_END()
};
+ fabrics_cfg.output_format = "";
fabrics_cfg.tos = -1;
ret = argconfig_parse(argc, argv, desc, opts);
if (ret)
goto out;
+ if (!strcmp(fabrics_cfg.output_format, ""))
+ flags = -1;
+ else if (!strcmp(fabrics_cfg.output_format, "normal"))
+ flags = NORMAL;
+ else if (!strcmp(fabrics_cfg.output_format, "json"))
+ flags = JSON;
+ else {
+ ret = -EINVAL;
+ goto out;
+ }
+
if (traddr_is_hostname(&fabrics_cfg)) {
ret = hostname2traddr(&fabrics_cfg);
if (ret)
goto out;
}
+ if (!fabrics_cfg.trsvcid)
+ discovery_trsvcid(&fabrics_cfg, false);
+
ret = build_options(argstr, BUF_SIZE, false);
if (ret)
goto out;
@@ -1671,6 +1766,12 @@ int fabrics_connect(const char *desc, int argc, char **argv)
instance = add_ctrl(argstr);
if (instance < 0)
ret = instance;
+ else {
+ if (flags == NORMAL)
+ print_connect_msg(instance);
+ else if (flags == JSON)
+ json_connect_msg(instance);
+ }
out:
return nvme_status_to_errno(ret, true);
diff --git a/fabrics.h b/fabrics.h
index 41e6a2d..9b2554e 100644
--- a/fabrics.h
+++ b/fabrics.h
@@ -20,6 +20,7 @@ struct fabrics_config {
const char *traddr;
const char *trsvcid;
const char *host_traddr;
+ const char *host_iface;
const char *hostnqn;
const char *hostid;
int nr_io_queues;
@@ -29,6 +30,7 @@ struct fabrics_config {
int keep_alive_tmo;
int reconnect_delay;
int ctrl_loss_tmo;
+ int fast_io_fail_tmo;
int tos;
const char *raw;
char *device;
diff --git a/linux/nvme.h b/linux/nvme.h
index 4ad09ee..589108b 100644
--- a/linux/nvme.h
+++ b/linux/nvme.h
@@ -147,6 +147,8 @@ enum {
NVME_IOCS_ZONED = 0x02,
};
+#define NVME_NUM_IOCS_COMBINATIONS 512
+
#define NVME_AQ_DEPTH 32
#define NVME_NR_AEN_COMMANDS 1
#define NVME_AQ_BLK_MQ_DEPTH (NVME_AQ_DEPTH - NVME_NR_AEN_COMMANDS)
@@ -288,7 +290,10 @@ struct nvme_id_ctrl {
__le16 crdt1;
__le16 crdt2;
__le16 crdt3;
- __u8 rsvd134[122];
+ __u8 rsvd134[119];
+ __u8 nvmsr;
+ __u8 vwci;
+ __u8 mec;
__le16 oacs;
__u8 acl;
__u8 aerl;
@@ -323,7 +328,10 @@ struct nvme_id_ctrl {
__le32 anagrpmax;
__le32 nanagrpid;
__le32 pels;
- __u8 rsvd356[156];
+ __le16 domainid;
+ __u8 rsvd358[10];
+ __u8 megcap[16];
+ __u8 rsvd384[128];
__u8 sqes;
__u8 cqes;
__le16 maxcmd;
@@ -337,10 +345,12 @@ struct nvme_id_ctrl {
__u8 icsvscc;
__u8 nwpc;
__le16 acwu;
- __u8 rsvd534[2];
+ __le16 ocfs;
__le32 sgls;
__le32 mnan;
- __u8 rsvd544[224];
+ __u8 maxdna[16];
+ __le32 maxcna;
+ __u8 rsvd564[204];
char subnqn[256];
__u8 rsvd1024[768];
__le32 ioccsz;
@@ -425,7 +435,7 @@ struct nvme_id_ns {
};
struct nvme_id_iocs {
- __le64 iocs[512];
+ __le64 iocs[NVME_NUM_IOCS_COMBINATIONS];
};
enum {
@@ -445,6 +455,7 @@ enum {
NVME_ID_CNS_SCNDRY_CTRL_LIST = 0x15,
NVME_ID_CNS_NS_GRANULARITY = 0x16,
NVME_ID_CNS_UUID_LIST = 0x17,
+ NVME_ID_CNS_DOMAIN_LIST = 0x18,
NVME_ID_CNS_CSI_NS_PRESENT_LIST = 0x1a,
NVME_ID_CNS_CSI_NS_PRESENT = 0x1b,
NVME_ID_CNS_CSI = 0x1c,
@@ -672,17 +683,17 @@ struct nvme_fw_slot_info_log {
};
struct nvme_lba_status_desc {
- __u64 dslba;
- __u32 nlb;
- __u8 rsvd_12;
- __u8 status;
- __u8 rsvd_15_14[2];
+ __le64 dslba;
+ __le32 nlb;
+ __u8 rsvd_12;
+ __u8 status;
+ __u8 rsvd_15_14[2];
};
struct nvme_lba_status {
- __u32 nlsd;
- __u8 cmpc;
- __u8 rsvd_7_5[3];
+ __le32 nlsd;
+ __u8 cmpc;
+ __u8 rsvd_7_5[3];
struct nvme_lba_status_desc descs[0];
};
@@ -964,8 +975,8 @@ struct nvme_lba_range_type {
__u8 type;
__u8 attributes;
__u8 rsvd2[14];
- __u64 slba;
- __u64 nlb;
+ __le64 slba;
+ __le64 nlb;
__u8 guid[16];
__u8 rsvd48[16];
};
@@ -1160,6 +1171,7 @@ enum {
NVME_RW_PRINFO_PRCHK_GUARD = 1 << 12,
NVME_RW_PRINFO_PRACT = 1 << 13,
NVME_RW_DTYPE_STREAMS = 1 << 4,
+ NVME_RW_STORAGE_TAG_CHECK = 1 << 8,
};
enum {
@@ -1191,6 +1203,31 @@ struct nvme_feat_auto_pst {
__le64 entries[32];
};
+struct nvme_mi_host_metadata_element_desc {
+ __u8 type; /* Element Type */
+ __u8 rev; /* Element Revision */
+ __u16 len; /* Element Length */
+ __u8 val[0]; /* Element Value (UTF-8) */
+};
+
+struct nvme_mi_host_metadata {
+ __u8 ndesc;
+ __u8 rsvd1;
+ struct nvme_mi_host_metadata_element_desc descs[0];
+};
+
+enum {
+ NVME_MI_CTRL_METADATA_OS_CTRL_NAME = 0x01,
+ NVME_MI_CTRL_METADATA_OS_DRIVER_NAME = 0x02,
+ NVME_MI_CTRL_METADATA_OS_DRIVER_VER = 0x03,
+ NVME_MI_CTRL_METADATA_PRE_BOOT_CTRL_NAME = 0x04,
+ NVME_MI_CTRL_METADATA_PRE_BOOT_DRIVER_NAME = 0x05,
+ NVME_MI_CTRL_METADATA_PRE_BOOT_DRIVER_VER = 0x06,
+
+ NVME_MI_NS_METADATA_OS_NS_NAME = 0x01,
+ NVME_MI_NS_METADATA_PRE_BOOT_NS_NAME = 0x02,
+};
+
enum {
NVME_HOST_MEM_ENABLE = (1 << 0),
NVME_HOST_MEM_RETURN = (1 << 1),
@@ -1220,6 +1257,7 @@ enum nvme_admin_opcode {
nvme_admin_virtual_mgmt = 0x1c,
nvme_admin_nvme_mi_send = 0x1d,
nvme_admin_nvme_mi_recv = 0x1e,
+ nvme_admin_capacity_mgmt = 0x20,
nvme_admin_dbbuf = 0x7C,
nvme_admin_format_nvm = 0x80,
nvme_admin_security_send = 0x81,
@@ -1284,13 +1322,17 @@ enum nvme_feat {
NVME_LBA_STATUS_INFO = 0x15,
NVME_FEAT_HOST_BEHAVIOR = 0x16,
NVME_FEAT_SANITIZE = 0x17,
- NVME_FEAT_ENDURANCE = 0x18,
+ NVME_FEAT_ENDURANCE = 0x18,
NVME_FEAT_IOCS_PROFILE = 0x19,
NVME_FEAT_SW_PROGRESS = 0x80,
NVME_FEAT_HOST_ID = 0x81,
NVME_FEAT_RESV_MASK = 0x82,
NVME_FEAT_RESV_PERSIST = 0x83,
NVME_FEAT_WRITE_PROTECT = 0x84,
+
+ NVME_MI_FEAT_CTRL_METADATA = 0x7E,
+ NVME_MI_FEAT_NS_METADATA = 0x7F,
+
} __attribute__ ((__packed__));
enum {
@@ -1329,7 +1371,7 @@ enum {
struct nvme_host_mem_buf_desc {
__le64 addr;
__le32 size;
- __u32 rsvd;
+ __u8 rsvd[4];
};
/* Sanitize Log Page */
@@ -1392,7 +1434,7 @@ struct nvmf_disc_rsp_page_entry {
__u8 prtype;
__u8 cms;
__u8 resv3[5];
- __u16 pkey;
+ __le16 pkey;
__u8 resv10[246];
} rdma;
struct tcp {
@@ -1456,21 +1498,21 @@ struct nvme_error_log_page {
struct nvme_firmware_log_page {
__u8 afi;
__u8 resv[7];
- __u64 frs[7];
+ __u8 frs[7][8];
__u8 resv2[448];
};
struct nvme_host_mem_buffer {
- __u32 hsize;
- __u32 hmdlal;
- __u32 hmdlau;
- __u32 hmdlec;
+ __le32 hsize;
+ __le32 hmdlal;
+ __le32 hmdlau;
+ __le32 hmdlec;
__u8 rsvd16[4080];
};
struct nvme_auto_pst {
- __u32 data;
- __u32 rsvd32;
+ __le32 data;
+ __u8 rsvd[4];
};
struct nvme_timestamp {
@@ -1498,10 +1540,10 @@ struct nvme_primary_ctrl_caps {
__u8 rsvd48[16];
__le32 vifrt; /* VI Resources Flexible Total */
__le32 virfa; /* VI Resources Flexible Assigned */
- __u16 virfap; /* VI Resources Flexible Allocated to Primary */
- __u16 viprt; /* VI Resources Private Total */
- __u16 vifrsm; /* VI Resources Flexible Secondary Maximum */
- __u16 vigran; /* VI Flexible Resource Preferred Granularity */
+ __le16 virfap; /* VI Resources Flexible Allocated to Primary */
+ __le16 viprt; /* VI Resources Private Total */
+ __le16 vifrsm; /* VI Resources Flexible Secondary Maximum */
+ __le16 vigran; /* VI Flexible Resource Preferred Granularity */
__u8 rsvd80[4016];
};
@@ -1523,10 +1565,10 @@ struct nvme_secondary_controllers_list {
};
struct nvme_bar_cap {
- __u16 mqes;
+ __le16 mqes;
__u8 ams_cqr;
__u8 to;
- __u16 bps_css_nssrs_dstrd;
+ __le16 bps_css_nssrs_dstrd;
__u8 mpsmax_mpsmin;
__u8 rsvd_cmbs_pmrs;
};
@@ -1595,10 +1637,14 @@ enum {
NVME_SC_PREEMPT_ABORT = 0x1B,
NVME_SC_SANITIZE_FAILED = 0x1C,
NVME_SC_SANITIZE_IN_PROGRESS = 0x1D,
+ NVME_SC_SGL_DATA_BLK_GRAN_INVALID= 0x1e,
+ NVME_SC_CMD_NOT_SUP_QUEUE_IN_CMB = 0x1f,
NVME_SC_NS_WRITE_PROTECTED = 0x20,
NVME_SC_CMD_INTERRUPTED = 0x21,
NVME_SC_TRANSIENT_TRANSPORT = 0x22,
+ NVME_SC_PROHIBITED_BY_CMD_AND_FEAT = 0x23,
+ NVME_SC_ADMIN_CMD_MEDIA_NOT_READY = 0x24,
NVME_SC_LBA_RANGE = 0x80,
NVME_SC_CAP_EXCEEDED = 0x81,
@@ -1646,6 +1692,9 @@ enum {
NVME_SC_PMR_SAN_PROHIBITED = 0x123,
NVME_SC_ANA_INVALID_GROUP_ID= 0x124,
NVME_SC_ANA_ATTACH_FAIL = 0x125,
+ NVME_SC_INSUFFICIENT_CAP = 0x126,
+ NVME_SC_NS_ATTACHMENT_LIMIT_EXCEEDED = 0x127,
+ NVME_SC_PROHIBIT_CMD_EXEC_NOT_SUPPORTED = 0x128,
/*
* Command Set Specific - Namespace Types commands:
@@ -1654,6 +1703,7 @@ enum {
NVME_SC_IOCS_NOT_ENABLED = 0x12A,
NVME_SC_IOCS_COMBINATION_REJECTED = 0x12B,
NVME_SC_INVALID_IOCS = 0x12C,
+ NVME_SC_ID_UNAVAILABLE = 0x12D,
/*
* I/O Command Set Specific - NVM commands:
@@ -1698,6 +1748,7 @@ enum {
NVME_SC_COMPARE_FAILED = 0x285,
NVME_SC_ACCESS_DENIED = 0x286,
NVME_SC_UNWRITTEN_BLOCK = 0x287,
+ NVME_SC_STORAGE_TAG_CHECK = 0x288,
/*
* Path-related Errors:
@@ -1770,8 +1821,8 @@ struct nvme_id_ctrl_nvm {
__u8 wzsl;
__u8 wusl;
__u8 dmrl;
- __u32 dmrsl;
- __u64 dmsl;
+ __le32 dmrsl;
+ __le64 dmsl;
__u8 rsvd16[4080];
};
@@ -1874,4 +1925,20 @@ enum nvme_zns_report_options {
NVME_ZNS_ZRAS_REPORT_READ_ONLY = 0x6,
NVME_ZNS_ZRAS_REPORT_OFFLINE = 0x7,
};
+
+struct nvme_id_domain_attr_entry {
+ __le16 dom_id;
+ __u8 rsvd2[14];
+ __u8 dom_cap[16];
+ __u8 unalloc_dom_cap[16];
+ __u8 max_egrp_dom_cap[16];
+ __u8 rsvd64[64];
+};
+
+struct nvme_id_domain_list {
+ __u8 num_entries;
+ __u8 rsvd1[127];
+ struct nvme_id_domain_attr_entry domain_attr[];
+};
+
#endif /* _LINUX_NVME_H */
diff --git a/linux/nvme_ioctl.h b/linux/nvme_ioctl.h
index d569414..b4fd4e2 100644
--- a/linux/nvme_ioctl.h
+++ b/linux/nvme_ioctl.h
@@ -18,21 +18,6 @@
#include <linux/types.h>
#include <sys/ioctl.h>
-struct nvme_user_io {
- __u8 opcode;
- __u8 flags;
- __u16 control;
- __u16 nblocks;
- __u16 rsvd;
- __u64 metadata;
- __u64 addr;
- __u64 slba;
- __u32 dsmgmt;
- __u32 reftag;
- __u16 apptag;
- __u16 appmask;
-};
-
struct nvme_passthru_cmd {
__u8 opcode;
__u8 flags;
@@ -80,7 +65,6 @@ struct nvme_passthru_cmd64 {
#define NVME_IOCTL_ID _IO('N', 0x40)
#define NVME_IOCTL_ADMIN_CMD _IOWR('N', 0x41, struct nvme_admin_cmd)
-#define NVME_IOCTL_SUBMIT_IO _IOW('N', 0x42, struct nvme_user_io)
#define NVME_IOCTL_IO_CMD _IOWR('N', 0x43, struct nvme_passthru_cmd)
#define NVME_IOCTL_RESET _IO('N', 0x44)
#define NVME_IOCTL_SUBSYS_RESET _IO('N', 0x45)
diff --git a/nvme-builtin.h b/nvme-builtin.h
index a413d00..8083941 100644
--- a/nvme-builtin.h
+++ b/nvme-builtin.h
@@ -21,6 +21,7 @@ COMMAND_LIST(
ENTRY("id-nvmset", "Send NVMe Identify NVM Set List, display structure", id_nvmset)
ENTRY("id-uuid", "Send NVMe Identify UUID List, display structure", id_uuid)
ENTRY("id-iocs", "Send NVMe Identify I/O Command Set, display structure", id_iocs)
+ ENTRY("id-domain", "Send NVMe Identify Domain List, display structure", id_domain)
ENTRY("create-ns", "Creates a namespace with the provided parameters", create_ns)
ENTRY("delete-ns", "Deletes a namespace from the controller", delete_ns)
ENTRY("attach-ns", "Attaches a namespace to requested controller(s)", attach_ns)
@@ -55,6 +56,7 @@ COMMAND_LIST(
ENTRY("security-send", "Submit a Security Send command, return results", sec_send)
ENTRY("security-recv", "Submit a Security Receive command, return results", sec_recv)
ENTRY("get-lba-status", "Submit a Get LBA Status command, return results", get_lba_status)
+ ENTRY("capacity-mgmt", "Submit Capacity Management Command, return results", capacity_mgmt)
ENTRY("resv-acquire", "Submit a Reservation Acquire, return results", resv_acquire)
ENTRY("resv-register", "Submit a Reservation Register, return results", resv_register)
ENTRY("resv-release", "Submit a Reservation Release, return results", resv_release)
diff --git a/nvme-ioctl.c b/nvme-ioctl.c
index 2801075..c511808 100644
--- a/nvme-ioctl.c
+++ b/nvme-ioctl.c
@@ -68,7 +68,7 @@ int nvme_get_nsid(int fd)
int err = fstat(fd, &nvme_stat);
if (err < 0)
- return -errno;
+ return err;
return ioctl(fd, NVME_IOCTL_ID);
}
@@ -124,33 +124,37 @@ int nvme_passthru(int fd, unsigned long ioctl_cmd, __u8 opcode,
return err;
}
-int nvme_io(int fd, __u8 opcode, __u64 slba, __u16 nblocks, __u16 control,
- __u32 dsmgmt, __u32 reftag, __u16 apptag, __u16 appmask, void *data,
- void *metadata)
+int nvme_io(int fd, __u8 opcode, __u32 nsid, __u64 slba, __u16 nblocks,
+ __u16 control, __u32 dsmgmt, __u32 reftag, __u16 apptag,
+ __u16 appmask, __u64 storage_tag, void *data, void *metadata)
{
- struct nvme_user_io io = {
+ struct nvme_passthru_cmd cmd = {
.opcode = opcode,
- .flags = 0,
- .control = control,
- .nblocks = nblocks,
- .rsvd = 0,
+ .nsid = nsid,
.metadata = (__u64)(uintptr_t) metadata,
.addr = (__u64)(uintptr_t) data,
- .slba = slba,
- .dsmgmt = dsmgmt,
- .reftag = reftag,
- .appmask = appmask,
- .apptag = apptag,
+ .cdw2 = storage_tag & 0xffffffff,
+ .cdw3 = (storage_tag >> 32) & 0xffff,
+ .cdw10 = slba & 0xffffffff,
+ .cdw11 = slba >> 32,
+ .cdw12 = nblocks | (control << 16),
+ .cdw13 = dsmgmt,
+ .cdw14 = reftag,
+ .cdw15 = apptag | (appmask << 16),
};
- return ioctl(fd, NVME_IOCTL_SUBMIT_IO, &io);
+
+ return nvme_submit_io_passthru(fd, &cmd);
}
int nvme_verify(int fd, __u32 nsid, __u64 slba, __u16 nblocks,
- __u16 control, __u32 reftag, __u16 apptag, __u16 appmask)
+ __u16 control, __u32 reftag, __u16 apptag, __u16 appmask,
+ __u64 storage_tag)
{
struct nvme_passthru_cmd cmd = {
.opcode = nvme_cmd_verify,
.nsid = nsid,
+ .cdw2 = storage_tag & 0xffffffff,
+ .cdw3 = (storage_tag >> 32) & 0xffff,
.cdw10 = slba & 0xffffffff,
.cdw11 = slba >> 32,
.cdw12 = nblocks | (control << 16),
@@ -174,11 +178,14 @@ int nvme_passthru_io(int fd, __u8 opcode, __u8 flags, __u16 rsvd,
}
int nvme_write_zeros(int fd, __u32 nsid, __u64 slba, __u16 nlb,
- __u16 control, __u32 reftag, __u16 apptag, __u16 appmask)
+ __u16 control, __u32 reftag, __u16 apptag, __u16 appmask,
+ __u64 storage_tag)
{
struct nvme_passthru_cmd cmd = {
.opcode = nvme_cmd_write_zeroes,
.nsid = nsid,
+ .cdw2 = storage_tag & 0xffffffff,
+ .cdw3 = (storage_tag >> 32) & 0xffff,
.cdw10 = slba & 0xffffffff,
.cdw11 = slba >> 32,
.cdw12 = nlb | (control << 16),
@@ -401,11 +408,6 @@ int nvme_identify_ns_list_csi(int fd, __u32 nsid, __u8 csi, bool all, void *data
return nvme_identify13(fd, nsid, cns, csi << 24, data);
}
-int nvme_identify_ns_list(int fd, __u32 nsid, bool all, void *data)
-{
- return nvme_identify_ns_list_csi(fd, nsid, 0x0, all, data);
-}
-
int nvme_identify_ctrl_list(int fd, __u32 nsid, __u16 cntid, void *data)
{
int cns = nsid ? NVME_ID_CNS_CTRL_NS_LIST : NVME_ID_CNS_CTRL_LIST;
@@ -464,12 +466,19 @@ int nvme_identify_iocs(int fd, __u16 cntid, void *data)
return nvme_identify(fd, 0, (cntid << 16) | NVME_ID_CNS_CSI, data);
}
+int nvme_identify_domain_list(int fd, __u16 dom_id, void *data)
+{
+ return nvme_identify13(fd, 0, NVME_ID_CNS_DOMAIN_LIST, dom_id, data);
+}
+
int nvme_get_log14(int fd, __u32 nsid, __u8 log_id, __u8 lsp, __u64 lpo,
- __u16 lsi, bool rae, __u8 uuid_ix, __u32 data_len, void *data)
+ __u16 lsi, bool rae, __u8 uuid_ix, __u8 csi, bool ot,
+ __u32 data_len, void *data)
{
__u32 numd = (data_len >> 2) - 1;
__u16 numdu = numd >> 16, numdl = numd & 0xffff;
__u32 cdw10 = log_id | (numdl << 16) | (rae ? 1 << 15 : 0) | lsp << 8;
+ __u32 cdw14 = uuid_ix | (ot ? 1 << 23 : 0) | csi << 24;
struct nvme_admin_cmd cmd = {
.opcode = nvme_admin_get_log_page,
@@ -480,7 +489,7 @@ int nvme_get_log14(int fd, __u32 nsid, __u8 log_id, __u8 lsp, __u64 lpo,
.cdw11 = numdu | (lsi << 16),
.cdw12 = lpo & 0xffffffff,
.cdw13 = lpo >> 32,
- .cdw14 = uuid_ix,
+ .cdw14 = cdw14,
};
return nvme_submit_admin_passthru(fd, &cmd);
@@ -491,7 +500,7 @@ int nvme_get_log13(int fd, __u32 nsid, __u8 log_id, __u8 lsp,
void *data)
{
return nvme_get_log14(fd, nsid, log_id, lsp, lpo, lsi, rae, 0,
- data_len, data);
+ 0, false, data_len, data);
}
int nvme_get_log(int fd, __u32 nsid, __u8 log_id, bool rae,
@@ -646,7 +655,7 @@ int nvme_resv_notif_log(int fd, struct nvme_resv_notif_log *resv)
}
int nvme_feature(int fd, __u8 opcode, __u32 nsid, __u32 cdw10, __u32 cdw11,
- __u32 cdw12, __u32 data_len, void *data, __u32 *result)
+ __u32 cdw12, __u32 cdw14, __u32 data_len, void *data, __u32 *result)
{
struct nvme_admin_cmd cmd = {
.opcode = opcode,
@@ -654,6 +663,7 @@ int nvme_feature(int fd, __u8 opcode, __u32 nsid, __u32 cdw10, __u32 cdw11,
.cdw10 = cdw10,
.cdw11 = cdw11,
.cdw12 = cdw12,
+ .cdw14 = cdw14,
.addr = (__u64)(uintptr_t) data,
.data_len = data_len,
};
@@ -666,12 +676,13 @@ int nvme_feature(int fd, __u8 opcode, __u32 nsid, __u32 cdw10, __u32 cdw11,
}
int nvme_set_feature(int fd, __u32 nsid, __u8 fid, __u32 value, __u32 cdw12,
- bool save, __u32 data_len, void *data, __u32 *result)
+ bool save, __u8 uuid_index, __u32 data_len, void *data, __u32 *result)
{
__u32 cdw10 = fid | (save ? 1 << 31 : 0);
+ __u32 cdw14 = uuid_index;
return nvme_feature(fd, nvme_admin_set_features, nsid, cdw10, value,
- cdw12, data_len, data, result);
+ cdw12, cdw14, data_len, data, result);
}
@@ -740,18 +751,23 @@ int nvme_set_property(int fd, int offset, uint64_t value)
}
int nvme_get_feature(int fd, __u32 nsid, __u8 fid, __u8 sel, __u32 cdw11,
- __u32 data_len, void *data, __u32 *result)
+ __u8 uuid_index, __u32 data_len, void *data, __u32 *result)
{
__u32 cdw10 = fid | sel << 8;
+ __u32 cdw14 = uuid_index;
return nvme_feature(fd, nvme_admin_get_features, nsid, cdw10, cdw11,
- 0, data_len, data, result);
+ 0, cdw14, data_len, data, result);
}
int nvme_format(int fd, __u32 nsid, __u8 lbaf, __u8 ses, __u8 pi,
__u8 pil, __u8 ms, __u32 timeout)
{
- __u32 cdw10 = lbaf | ms << 4 | pi << 5 | pil << 8 | ses << 9;
+ __u8 lbafl = lbaf & 0xf;
+ __u8 lbafu = (lbaf >> 4) & 0x3;
+ __u32 cdw10 = lbafl | ms << 4 | pi << 5 | pil << 8 | ses << 9 |
+ lbafu << 12;
+
struct nvme_admin_cmd cmd = {
.opcode = nvme_admin_format_nvm,
.nsid = nsid,
@@ -839,18 +855,23 @@ int nvme_fw_download(int fd, __u32 offset, __u32 data_len, void *data)
return nvme_submit_admin_passthru(fd, &cmd);
}
-int nvme_fw_commit(int fd, __u8 slot, __u8 action, __u8 bpid)
+int nvme_fw_commit(int fd, __u8 slot, __u8 action, __u8 bpid, __u32 *result)
{
+ int err;
+
struct nvme_admin_cmd cmd = {
.opcode = nvme_admin_activate_fw,
.cdw10 = (bpid << 31) | (action << 3) | slot,
};
- return nvme_submit_admin_passthru(fd, &cmd);
+ err = nvme_submit_admin_passthru(fd, &cmd);
+ if (!err && result)
+ *result = cmd.result;
+ return err;
}
int nvme_sec_send(int fd, __u32 nsid, __u8 nssf, __u16 spsp,
- __u8 secp, __u32 tl, __u32 data_len, void *data)
+ __u8 secp, __u32 data_len, void *data)
{
struct nvme_admin_cmd cmd = {
.opcode = nvme_admin_security_send,
@@ -858,7 +879,7 @@ int nvme_sec_send(int fd, __u32 nsid, __u8 nssf, __u16 spsp,
.data_len = data_len,
.nsid = nsid,
.cdw10 = secp << 24 | spsp << 8 | nssf,
- .cdw11 = tl,
+ .cdw11 = data_len,
};
return nvme_submit_admin_passthru(fd, &cmd);
@@ -900,41 +921,60 @@ int nvme_get_lba_status(int fd, __u32 namespace_id, __u64 slba, __u32 mndw,
int nvme_dir_send(int fd, __u32 nsid, __u16 dspec, __u8 dtype, __u8 doper,
__u32 data_len, __u32 dw12, void *data, __u32 *result)
{
- struct nvme_admin_cmd cmd = {
- .opcode = nvme_admin_directive_send,
- .addr = (__u64)(uintptr_t) data,
- .data_len = data_len,
- .nsid = nsid,
- .cdw10 = data_len? (data_len >> 2) - 1 : 0,
- .cdw11 = dspec << 16 | dtype << 8 | doper,
- .cdw12 = dw12,
- };
- int err;
+ struct nvme_admin_cmd cmd = {
+ .opcode = nvme_admin_directive_send,
+ .addr = (__u64)(uintptr_t) data,
+ .data_len = data_len,
+ .nsid = nsid,
+ .cdw10 = data_len? (data_len >> 2) - 1 : 0,
+ .cdw11 = dspec << 16 | dtype << 8 | doper,
+ .cdw12 = dw12,
+ };
+ int err;
- err = nvme_submit_admin_passthru(fd, &cmd);
- if (!err && result)
- *result = cmd.result;
- return err;
+ err = nvme_submit_admin_passthru(fd, &cmd);
+ if (!err && result)
+ *result = cmd.result;
+ return err;
}
int nvme_dir_recv(int fd, __u32 nsid, __u16 dspec, __u8 dtype, __u8 doper,
__u32 data_len, __u32 dw12, void *data, __u32 *result)
{
- struct nvme_admin_cmd cmd = {
- .opcode = nvme_admin_directive_recv,
- .addr = (__u64)(uintptr_t) data,
- .data_len = data_len,
- .nsid = nsid,
- .cdw10 = data_len? (data_len >> 2) - 1 : 0,
- .cdw11 = dspec << 16 | dtype << 8 | doper,
- .cdw12 = dw12,
- };
- int err;
+ struct nvme_admin_cmd cmd = {
+ .opcode = nvme_admin_directive_recv,
+ .addr = (__u64)(uintptr_t) data,
+ .data_len = data_len,
+ .nsid = nsid,
+ .cdw10 = data_len? (data_len >> 2) - 1 : 0,
+ .cdw11 = dspec << 16 | dtype << 8 | doper,
+ .cdw12 = dw12,
+ };
+ int err;
- err = nvme_submit_admin_passthru(fd, &cmd);
- if (!err && result)
- *result = cmd.result;
- return err;
+ err = nvme_submit_admin_passthru(fd, &cmd);
+ if (!err && result)
+ *result = cmd.result;
+ return err;
+}
+
+int nvme_cap_mgmt(int fd, __u8 op, __u16 element_id, __u32 dw11,
+ __u32 dw12, __u32 *result)
+{
+ int err;
+ __u32 dw10 = op | element_id << 16;
+
+ struct nvme_admin_cmd cmd = {
+ .opcode = nvme_admin_capacity_mgmt,
+ .cdw10 = dw10,
+ .cdw11 = dw11,
+ .cdw12 = dw12,
+ };
+
+ err = nvme_submit_admin_passthru(fd, &cmd);
+ if (!err && result)
+ *result = cmd.result;
+ return err;
}
int nvme_sanitize(int fd, __u8 sanact, __u8 ause, __u8 owpass, __u8 oipbp,
@@ -979,7 +1019,7 @@ int nvme_virtual_mgmt(int fd, __u32 cdw10, __u32 cdw11, __u32 *result)
}
int nvme_zns_mgmt_send(int fd, __u32 nsid, __u64 slba, bool select_all,
- enum nvme_zns_send_action zsa, __u32 data_len,
+ __u32 timeout, enum nvme_zns_send_action zsa, __u32 data_len,
void *data)
{
__u32 cdw10 = slba & 0xffffffff;
@@ -994,6 +1034,7 @@ int nvme_zns_mgmt_send(int fd, __u32 nsid, __u64 slba, bool select_all,
.cdw13 = cdw13,
.addr = (__u64)(uintptr_t)data,
.data_len = data_len,
+ .timeout_ms = timeout,
};
return nvme_submit_io_passthru(fd, &cmd);
diff --git a/nvme-ioctl.h b/nvme-ioctl.h
index b0184c7..2e24b83 100644
--- a/nvme-ioctl.h
+++ b/nvme-ioctl.h
@@ -25,9 +25,9 @@ int nvme_passthru(int fd, unsigned long ioctl_cmd, __u8 opcode, __u8 flags,
/* NVME_SUBMIT_IO */
-int nvme_io(int fd, __u8 opcode, __u64 slba, __u16 nblocks, __u16 control,
- __u32 dsmgmt, __u32 reftag, __u16 apptag,
- __u16 appmask, void *data, void *metadata);
+int nvme_io(int fd, __u8 opcode, __u32 nsid, __u64 slba, __u16 nblocks,
+ __u16 control, __u32 dsmgmt, __u32 reftag, __u16 apptag,
+ __u16 appmask, __u64 storage_tag, void *data, void *metadata);
/* NVME_IO_CMD */
int nvme_passthru_io(int fd, __u8 opcode, __u8 flags, __u16 rsvd,
@@ -38,12 +38,14 @@ int nvme_passthru_io(int fd, __u8 opcode, __u8 flags, __u16 rsvd,
void *metadata, __u32 timeout);
int nvme_write_zeros(int fd, __u32 nsid, __u64 slba, __u16 nlb,
- __u16 control, __u32 reftag, __u16 apptag, __u16 appmask);
+ __u16 control, __u32 reftag, __u16 apptag, __u16 appmask,
+ __u64 storage_tag);
int nvme_write_uncorrectable(int fd, __u32 nsid, __u64 slba, __u16 nlb);
int nvme_verify(int fd, __u32 nsid, __u64 slba, __u16 nblocks,
- __u16 control, __u32 reftag, __u16 apptag, __u16 appmask);
+ __u16 control, __u32 reftag, __u16 apptag, __u16 appmask,
+ __u64 storage_tag);
int nvme_flush(int fd, __u32 nsid);
@@ -73,7 +75,6 @@ int nvme_identify13(int fd, __u32 nsid, __u32 cdw10, __u32 cdw11, void *data);
int nvme_identify(int fd, __u32 nsid, __u32 cdw10, void *data);
int nvme_identify_ctrl(int fd, void *data);
int nvme_identify_ns(int fd, __u32 nsid, bool present, void *data);
-int nvme_identify_ns_list(int fd, __u32 nsid, bool all, void *data);
int nvme_identify_ns_list_csi(int fd, __u32 nsid, __u8 csi, bool all, void *data);
int nvme_identify_ctrl_list(int fd, __u32 nsid, __u16 cntid, void *data);
int nvme_identify_ns_descs(int fd, __u32 nsid, void *data);
@@ -86,10 +87,11 @@ int nvme_identify_ctrl_nvm(int fd, void *data);
int nvme_zns_identify_ctrl(int fd, void *data);
int nvme_zns_identify_ns(int fd, __u32 nsid, void *data);
int nvme_identify_iocs(int fd, __u16 cntid, void *data);
+int nvme_identify_domain_list(int fd, __u16 dom_id, void *data);
int nvme_get_log(int fd, __u32 nsid, __u8 log_id, bool rae,
__u8 lsp, __u32 data_len, void *data);
int nvme_get_log14(int fd, __u32 nsid, __u8 log_id, __u8 lsp, __u64 lpo,
- __u16 group_id, bool rae, __u8 uuid_ix,
+ __u16 group_id, bool rae, __u8 uuid_ix, __u8 csi, bool ot,
__u32 data_len, void *data);
int nvme_get_log13(int fd, __u32 nsid, __u8 log_id, __u8 lsp,
__u64 lpo, __u16 lsi, bool rae, __u32 data_len,
@@ -119,12 +121,12 @@ int nvme_lba_status_log(int fd, void *lba_status, bool rae,
__u32 size);
int nvme_resv_notif_log(int fd, struct nvme_resv_notif_log *resv);
int nvme_feature(int fd, __u8 opcode, __u32 nsid, __u32 cdw10,
- __u32 cdw11, __u32 cdw12, __u32 data_len, void *data,
+ __u32 cdw11, __u32 cdw12, __u32 cdw14, __u32 data_len, void *data,
__u32 *result);
int nvme_set_feature(int fd, __u32 nsid, __u8 fid, __u32 value, __u32 cdw12,
- bool save, __u32 data_len, void *data, __u32 *result);
+ bool save, __u8 uuid_index, __u32 data_len, void *data, __u32 *result);
int nvme_get_feature(int fd, __u32 nsid, __u8 fid, __u8 sel,
- __u32 cdw11, __u32 data_len, void *data, __u32 *result);
+ __u32 cdw11, __u8 uuid_index, __u32 data_len, void *data, __u32 *result);
int nvme_format(int fd, __u32 nsid, __u8 lbaf, __u8 ses, __u8 pi,
__u8 pil, __u8 ms, __u32 timeout);
@@ -138,10 +140,10 @@ int nvme_ns_attachment(int fd, __u32 nsid, __u16 num_ctrls,
__u16 *ctrlist, bool attach);
int nvme_fw_download(int fd, __u32 offset, __u32 data_len, void *data);
-int nvme_fw_commit(int fd, __u8 slot, __u8 action, __u8 bpid);
+int nvme_fw_commit(int fd, __u8 slot, __u8 action, __u8 bpid, __u32 *result);
int nvme_sec_send(int fd, __u32 nsid, __u8 nssf, __u16 spsp,
- __u8 secp, __u32 tl, __u32 data_len, void *data);
+ __u8 secp, __u32 data_len, void *data);
int nvme_sec_recv(int fd, __u32 nsid, __u8 nssf, __u16 spsp,
__u8 secp, __u32 al, __u32 data_len, void *data);
@@ -155,6 +157,8 @@ int nvme_dir_send(int fd, __u32 nsid, __u16 dspec, __u8 dtype, __u8 doper,
__u32 data_len, __u32 dw12, void *data, __u32 *result);
int nvme_dir_recv(int fd, __u32 nsid, __u16 dspec, __u8 dtype, __u8 doper,
__u32 data_len, __u32 dw12, void *data, __u32 *result);
+int nvme_cap_mgmt(int fd, __u8 op, __u16 element_id, __u32 dw11,
+ __u32 dw12, __u32 *result);
int nvme_get_properties(int fd, void **pbar);
int nvme_set_property(int fd, int offset, uint64_t value);
int nvme_get_property(int fd, int offset, uint64_t *value);
@@ -165,7 +169,7 @@ int nvme_self_test_log(int fd, __u32 nsid, struct nvme_self_test_log *self_test_
int nvme_virtual_mgmt(int fd, __u32 cdw10, __u32 cdw11, __u32 *result);
int nvme_zns_mgmt_send(int fd, __u32 nsid, __u64 slba, bool select_all,
- enum nvme_zns_send_action zsa, __u32 data_len,
+ __u32 timeout, enum nvme_zns_send_action zsa, __u32 data_len,
void *data);
int nvme_zns_mgmt_recv(int fd, __u32 nsid, __u64 slba,
enum nvme_zns_recv_action zra, __u8 zrasf,
diff --git a/nvme-print.c b/nvme-print.c
index b01a842..1d2fb0c 100755
--- a/nvme-print.c
+++ b/nvme-print.c
@@ -11,6 +11,13 @@
#include "util/suffix.h"
#include "common.h"
+#define ABSOLUTE_ZERO_CELSIUS -273
+
+static inline long kelvin_to_celsius(long t)
+{
+ return t + ABSOLUTE_ZERO_CELSIUS;
+}
+
static const uint8_t zero_uuid[16] = { 0 };
static const uint8_t invalid_uuid[16] = {[0 ... 15] = 0xff };
static const char dash[100] = {[0 ... 99] = '-'};
@@ -97,16 +104,12 @@ const char *nvme_cmd_to_string(int admin, __u8 opcode)
return "Unknown";
}
-static const char *fw_to_string(__u64 fw)
+static char *fw_to_string(__u8 fw[])
{
- static char ret[9];
- char *c = (char *)&fw;
- int i;
+ static char frs[9];
- for (i = 0; i < 8; i++)
- ret[i] = c[i] >= '!' && c[i] <= '~' ? c[i] : '.';
- ret[i] = '\0';
- return ret;
+ snprintf(frs, sizeof(frs), "%-.*s", 8, fw);
+ return frs;
}
static const char *get_sanitize_log_sstat_status_str(__u16 status)
@@ -216,6 +219,8 @@ static void json_nvme_id_ctrl(struct nvme_id_ctrl *ctrl,
long double tnvmcap = int128_to_double(ctrl->tnvmcap);
long double unvmcap = int128_to_double(ctrl->unvmcap);
+ long double megcap = int128_to_double(ctrl->megcap);
+ long double maxdna = int128_to_double(ctrl->maxdna);
char sn[sizeof(ctrl->sn) + 1], mn[sizeof(ctrl->mn) + 1],
fr[sizeof(ctrl->fr) + 1], subnqn[sizeof(ctrl->subnqn) + 1];
@@ -249,6 +254,9 @@ static void json_nvme_id_ctrl(struct nvme_id_ctrl *ctrl,
json_object_add_value_int(root, "crdt1", le16_to_cpu(ctrl->crdt1));
json_object_add_value_int(root, "crdt2", le16_to_cpu(ctrl->crdt2));
json_object_add_value_int(root, "crdt3", le16_to_cpu(ctrl->crdt3));
+ json_object_add_value_int(root, "nvmsr", ctrl->nvmsr);
+ json_object_add_value_int(root, "vwci", ctrl->vwci);
+ json_object_add_value_int(root, "mec", ctrl->mec);
json_object_add_value_int(root, "oacs", le16_to_cpu(ctrl->oacs));
json_object_add_value_int(root, "acl", ctrl->acl);
json_object_add_value_int(root, "aerl", ctrl->aerl);
@@ -285,6 +293,8 @@ static void json_nvme_id_ctrl(struct nvme_id_ctrl *ctrl,
le32_to_cpu(ctrl->anagrpmax));
json_object_add_value_int(root, "nanagrpid",
le32_to_cpu(ctrl->nanagrpid));
+ json_object_add_value_int(root, "domainid", le16_to_cpu(ctrl->domainid));
+ json_object_add_value_float(root, "megcap", megcap);
json_object_add_value_int(root, "sqes", ctrl->sqes);
json_object_add_value_int(root, "cqes", ctrl->cqes);
json_object_add_value_int(root, "maxcmd", le16_to_cpu(ctrl->maxcmd));
@@ -298,7 +308,10 @@ static void json_nvme_id_ctrl(struct nvme_id_ctrl *ctrl,
json_object_add_value_int(root, "icsvscc", ctrl->icsvscc);
json_object_add_value_int(root, "nwpc", ctrl->nwpc);
json_object_add_value_int(root, "acwu", le16_to_cpu(ctrl->acwu));
+ json_object_add_value_int(root, "ocfs", le16_to_cpu(ctrl->ocfs));
json_object_add_value_int(root, "sgls", le32_to_cpu(ctrl->sgls));
+ json_object_add_value_float(root, "maxdna", maxdna);
+ json_object_add_value_int(root, "maxcna", le32_to_cpu(ctrl->maxcna));
if (strlen(subnqn))
json_object_add_value_string(root, "subnqn", subnqn);
@@ -471,27 +484,26 @@ static void json_nvme_resv_report(struct nvme_reservation_status *status,
static void json_fw_log(struct nvme_firmware_log_page *fw_log, const char *devname)
{
+ int i;
struct json_object *root;
struct json_object *fwsi;
char fmt[21];
- char str[32];
- int i;
root = json_create_object();
fwsi = json_create_object();
json_object_add_value_int(fwsi, "Active Firmware Slot (afi)",
fw_log->afi);
+
for (i = 0; i < 7; i++) {
- if (fw_log->frs[i]) {
+ if (strcmp(fw_to_string(fw_log->frs[i]), "\0")) {
snprintf(fmt, sizeof(fmt), "Firmware Rev Slot %d",
i + 1);
- snprintf(str, sizeof(str), "%"PRIu64" (%s)",
- (uint64_t)fw_log->frs[i],
- fw_to_string(fw_log->frs[i]));
- json_object_add_value_string(fwsi, fmt, str);
+ json_object_add_value_string(fwsi, fmt,
+ fw_to_string(fw_log->frs[i]));
}
}
+
json_object_add_value_object(root, devname, fwsi);
json_print_object(root, NULL);
@@ -1882,6 +1894,9 @@ static void nvme_show_registers_cap(struct nvme_bar_cap *cap)
(cap->bps_css_nssrs_dstrd & 0x0020) ? "Supported" : "Not Supported");
printf("\t One or more I/O Command Sets are %s\n",
(cap->bps_css_nssrs_dstrd & 0x0800) ? "Supported" : "Not Supported");
+ printf("\t %s\n",
+ (cap->bps_css_nssrs_dstrd & 0x1000) ? "Only Admin Command Set Supported" :
+ "I/O Command Set is Supported");
printf("\tNVM Subsystem Reset Supported (NSSRS): %s\n",
(cap->bps_css_nssrs_dstrd & 0x0010) ? "Yes":"No");
printf("\tDoorbell Stride (DSTRD): %u bytes\n",
@@ -2089,11 +2104,6 @@ static void nvme_show_registers_bpinfo_brs(__u8 brs)
static void nvme_show_registers_bpinfo(__u32 bpinfo)
{
- if (bpinfo == 0) {
- printf("\tBoot Partition feature is not supported\n\n");
- return;
- }
-
printf("\tActive Boot Partition ID (ABPID): %u\n",
(bpinfo & 0x80000000) >> 31);
nvme_show_registers_bpinfo_brs((bpinfo & 0x03000000) >> 24);
@@ -2103,11 +2113,6 @@ static void nvme_show_registers_bpinfo(__u32 bpinfo)
static void nvme_show_registers_bprsel(__u32 bprsel)
{
- if (bprsel == 0) {
- printf("\tBoot Partition feature is not supported\n\n");
- return;
- }
-
printf("\tBoot Partition Identifier (BPID): %u\n",
(bprsel & 0x80000000) >> 31);
printf("\tBoot Partition Read Offset (BPROF): %x\n",
@@ -2118,10 +2123,6 @@ static void nvme_show_registers_bprsel(__u32 bprsel)
static void nvme_show_registers_bpmbl(uint64_t bpmbl)
{
- if (bpmbl == 0) {
- printf("\tBoot Partition feature is not supported\n\n");
- return;
- }
printf("\tBoot Partition Memory Buffer Base Address (BMBBA): %"PRIx64"\n",
bpmbl);
@@ -2714,46 +2715,61 @@ static void nvme_show_id_ctrl_cmic(__u8 cmic)
static void nvme_show_id_ctrl_oaes(__le32 ctrl_oaes)
{
__u32 oaes = le32_to_cpu(ctrl_oaes);
- __u32 rsvd0 = (oaes & 0xF0000000) >> 28;
+ __u32 disc = (oaes >> 31) & 0x1;
+ __u32 rsvd0 = (oaes & 0x70000000) >> 28;
__u32 zicn = (oaes & 0x08000000) >> 27;
- __u32 rsvd1 = (oaes & 0x07FF8000) >> 15;
- __u32 nace = (oaes & 0x100) >> 8;
- __u32 fan = (oaes & 0x200) >> 9;
- __u32 anacn = (oaes & 0x800) >> 11;
- __u32 plealcn = (oaes & 0x1000) >> 12;
- __u32 lbasin = (oaes & 0x2000) >> 13;
+ __u32 rsvd1 = (oaes & 0x07FF0000) >> 16;
+ __u32 normal_shn = (oaes >> 15) & 0x1;
__u32 egealpcn = (oaes & 0x4000) >> 14;
- __u32 rsvd2 = oaes & 0xFF;
+ __u32 lbasin = (oaes & 0x2000) >> 13;
+ __u32 plealcn = (oaes & 0x1000) >> 12;
+ __u32 anacn = (oaes & 0x800) >> 11;
+ __u32 rsvd2 = (oaes >> 10) & 0x1;
+ __u32 fan = (oaes & 0x200) >> 9;
+ __u32 nace = (oaes & 0x100) >> 8;
+ __u32 rsvd3 = oaes & 0xFF;
+ printf(" [31:31] : %#x\tDiscovery Log Change Notice %sSupported\n",
+ disc, disc ? "" : "Not ");
if (rsvd0)
- printf(" [31:28] : %#x\tReserved\n", rsvd0);
- printf("[27:27] : %#x\tZone Descriptor Changed Notices %sSupported\n",
+ printf(" [30:28] : %#x\tReserved\n", rsvd0);
+ printf(" [27:27] : %#x\tZone Descriptor Changed Notices %sSupported\n",
zicn, zicn ? "" : "Not ");
if (rsvd1)
- printf(" [26:15] : %#x\tReserved\n", rsvd1);
- printf("[14:14] : %#x\tEndurance Group Event Aggregate Log Page"\
+ printf(" [26:16] : %#x\tReserved\n", rsvd1);
+ printf(" [15:15] : %#x\tNormal NSS Shutdown Event %sSupported\n",
+ normal_shn, normal_shn ? "" : "Not ");
+ printf(" [14:14] : %#x\tEndurance Group Event Aggregate Log Page"\
" Change Notice %sSupported\n",
egealpcn, egealpcn ? "" : "Not ");
- printf("[13:13] : %#x\tLBA Status Information Notices %sSupported\n",
+ printf(" [13:13] : %#x\tLBA Status Information Notices %sSupported\n",
lbasin, lbasin ? "" : "Not ");
- printf("[12:12] : %#x\tPredictable Latency Event Aggregate Log Change"\
+ printf(" [12:12] : %#x\tPredictable Latency Event Aggregate Log Change"\
" Notices %sSupported\n",
plealcn, plealcn ? "" : "Not ");
- printf("[11:11] : %#x\tAsymmetric Namespace Access Change Notices"\
+ printf(" [11:11] : %#x\tAsymmetric Namespace Access Change Notices"\
" %sSupported\n", anacn, anacn ? "" : "Not ");
+ if (rsvd2)
+ printf(" [10:10] : %#x\tReserved\n", rsvd2);
printf(" [9:9] : %#x\tFirmware Activation Notices %sSupported\n",
fan, fan ? "" : "Not ");
printf(" [8:8] : %#x\tNamespace Attribute Changed Event %sSupported\n",
nace, nace ? "" : "Not ");
- if (rsvd2)
- printf(" [7:0] : %#x\tReserved\n", rsvd1);
+ if (rsvd3)
+ printf(" [7:0] : %#x\tReserved\n", rsvd3);
printf("\n");
}
static void nvme_show_id_ctrl_ctratt(__le32 ctrl_ctratt)
{
__u32 ctratt = le32_to_cpu(ctrl_ctratt);
- __u32 rsvd = ctratt >> 10;
+ __u32 rsvd = ctratt >> 16;
+ __u32 elbas = (ctratt >> 15) & 0x1;
+ __u32 delnvmset = (ctratt >> 14) & 0x1;
+ __u32 delegrp = (ctratt >> 13) & 0x1;
+ __u32 vcap = (ctratt >> 12) & 0x1;
+ __u32 fcap = (ctratt >> 11) & 0x1;
+ __u32 mds = (ctratt >> 10) & 0x1;
__u32 hostid128 = (ctratt & NVME_CTRL_CTRATT_128_ID) >> 0;
__u32 psp = (ctratt & NVME_CTRL_CTRATT_NON_OP_PSP) >> 1;
__u32 sets = (ctratt & NVME_CTRL_CTRATT_NVM_SETS) >> 2;
@@ -2766,8 +2782,19 @@ static void nvme_show_id_ctrl_ctratt(__le32 ctrl_ctratt)
__u32 rsvd8 = (ctratt & 0x00000100) >> 8;
if (rsvd)
- printf(" [31:10] : %#x\tReserved\n", rsvd);
-
+ printf(" [31:16] : %#x\tReserved\n", rsvd);
+ printf(" [15:15] : %#x\tExtended LBA Formats %sSupported\n",
+ elbas, elbas ? "" : "Not ");
+ printf(" [14:14] : %#x\tDelete NVM Set %sSupported\n",
+ delnvmset, delnvmset ? "" : "Not ");
+ printf(" [13:13] : %#x\tDelete Endurance Group %sSupported\n",
+ delegrp, delegrp ? "" : "Not ");
+ printf(" [12:12] : %#x\tVariable Capacity Management %sSupported\n",
+ vcap, vcap ? "" : "Not ");
+ printf(" [11:11] : %#x\tFixed Capacity Management %sSupported\n",
+ fcap, fcap ? "" : "Not ");
+ printf(" [10:10] : %#x\tMulti Domain Subsystem %sSupported\n",
+ mds, mds ? "" : "Not ");
printf(" [9:9] : %#x\tUUID List %sSupported\n",
uuidlist, uuidlist ? "" : "Not ");
if (rsvd8)
@@ -2807,10 +2834,54 @@ static void nvme_show_id_ctrl_cntrltype(__u8 cntrltype)
printf(" [1:0] : %#x\t%s\n", cntrltype, type[cntrl]);
}
+static void nvme_show_id_ctrl_nvmsr(__u8 nvmsr)
+{
+ __u8 rsvd = (nvmsr >> 2) & 0xfc;
+ __u8 nvmee = (nvmsr >> 1) & 0x1;
+ __u8 nvmesd = nvmsr & 0x1;
+
+ if (rsvd)
+ printf(" [7:2] : %#x\tReserved\n", rsvd);
+ printf(" [1:1] : %#x\tNVM subsystem %spart of an Enclosure\n",
+ nvmee, nvmee ? "" : "Not ");
+ printf(" [0:0] : %#x\tNVM subsystem %spart of an Storage Device\n",
+ nvmesd, nvmesd ? "" : "Not ");
+ printf("\n");
+}
+
+static void nvme_show_id_ctrl_vwci(__u8 vwci)
+{
+ __u8 vwcrv = (vwci >> 7) & 0x1;
+ __u8 vwcr = vwci & 0xfe;
+
+ printf(" [7:7] : %#x\tVPD Write Cycles Remaining field is %svalid.\n",
+ vwcrv, vwcrv ? "" : "Not ");
+ printf(" [6:0] : %#x\tVPD Write Cycles Remaining \n", vwcr);
+ printf("\n");
+
+}
+
+static void nvme_show_id_ctrl_mec(__u8 mec)
+{
+ __u8 rsvd = (mec >> 2) & 0xfc;
+ __u8 pcieme = (mec >> 1) & 0x1;
+ __u8 smbusme = mec & 0x1;
+
+ if (rsvd)
+ printf(" [7:2] : %#x\tReserved\n", rsvd);
+ printf(" [1:1] : %#x\tNVM subsystem %scontains a Management Endpoint"\
+ " on a PCIe port\n", pcieme, pcieme ? "" : "Not ");
+ printf(" [0:0] : %#x\tNVM subsystem %scontains a Management Endpoint"\
+ " on an SMBus/I2C port\n", smbusme, smbusme ? "" : "Not ");
+ printf("\n");
+
+}
+
static void nvme_show_id_ctrl_oacs(__le16 ctrl_oacs)
{
__u16 oacs = le16_to_cpu(ctrl_oacs);
- __u16 rsvd = (oacs & 0xFC00) >> 10;
+ __u16 rsvd = (oacs & 0xF800) >> 11;
+ __u16 lock = (oacs >> 10) & 0x1;
__u16 glbas = (oacs & 0x200) >> 9;
__u16 dbc = (oacs & 0x100) >> 8;
__u16 vir = (oacs & 0x80) >> 7;
@@ -2823,7 +2894,9 @@ static void nvme_show_id_ctrl_oacs(__le16 ctrl_oacs)
__u16 sec = oacs & 0x1;
if (rsvd)
- printf(" [15:9] : %#x\tReserved\n", rsvd);
+ printf(" [15:11] : %#x\tReserved\n", rsvd);
+ printf(" [10:10] : %#x\tLockdown Command and Feature %sSupported\n",
+ lock, lock ? "" : "Not ");
printf(" [9:9] : %#x\tGet LBA Status Capability %sSupported\n",
glbas, glbas ? "" : "Not ");
printf(" [8:8] : %#x\tDoorbell Buffer Config %sSupported\n",
@@ -2849,13 +2922,16 @@ static void nvme_show_id_ctrl_oacs(__le16 ctrl_oacs)
static void nvme_show_id_ctrl_frmw(__u8 frmw)
{
- __u8 rsvd = (frmw & 0xE0) >> 5;
+ __u8 rsvd = (frmw & 0xC0) >> 6;
+ __u8 smud = (frmw >> 5) & 0x1;
__u8 fawr = (frmw & 0x10) >> 4;
__u8 nfws = (frmw & 0xE) >> 1;
__u8 s1ro = frmw & 0x1;
if (rsvd)
- printf(" [7:5] : %#x\tReserved\n", rsvd);
+ printf(" [7:6] : %#x\tReserved\n", rsvd);
+ printf(" [5:5] : %#x\tMultiple FW or Boot Update Detection %sSupported\n",
+ smud, smud ? "" : "Not ");
printf(" [4:4] : %#x\tFirmware Activate Without Reset %sSupported\n",
fawr, fawr ? "" : "Not ");
printf(" [3:1] : %#x\tNumber of Firmware Slots\n", nfws);
@@ -2866,7 +2942,9 @@ static void nvme_show_id_ctrl_frmw(__u8 frmw)
static void nvme_show_id_ctrl_lpa(__u8 lpa)
{
- __u8 rsvd = (lpa & 0xE0) >> 5;
+ __u8 rsvd = (lpa & 0x80) >> 7;
+ __u8 tel = (lpa >> 6) & 0x1;
+ __u8 lid_sup = (lpa >> 5) & 0x1;
__u8 persevnt = (lpa & 0x10) >> 4;
__u8 telem = (lpa & 0x8) >> 3;
__u8 ed = (lpa & 0x4) >> 2;
@@ -2874,7 +2952,11 @@ static void nvme_show_id_ctrl_lpa(__u8 lpa)
__u8 smlp = lpa & 0x1;
if (rsvd)
- printf(" [7:4] : %#x\tReserved\n", rsvd);
+ printf(" [7:7] : %#x\tReserved\n", rsvd);
+ printf(" [6:6] : %#x\tTelemetry Log Data Area 4 %sSupported\n",
+ tel, tel ? "" : "Not ");
+ printf(" [5:5] : %#x\tLID 0x0, Scope of each command in LID 0x5, "\
+ "0x12, 0x13 %sSupported\n", lid_sup, lid_sup ? "" : "Not ");
printf(" [4:4] : %#x\tPersistent Event log %sSupported\n",
persevnt, persevnt ? "" : "Not ");
printf(" [3:3] : %#x\tTelemetry host/controller initiated log page %sSupported\n",
@@ -2910,6 +2992,20 @@ static void nvme_show_id_ctrl_apsta(__u8 apsta)
printf("\n");
}
+static void nvme_show_id_ctrl_wctemp(__le16 wctemp)
+{
+ printf(" [16:0] : %ld C (%u Kelvin)\tWarning temperature (WCTEMP)\n",
+ kelvin_to_celsius(le16_to_cpu(wctemp)), le16_to_cpu(wctemp));
+ printf("\n");
+}
+
+static void nvme_show_id_ctrl_cctemp(__le16 cctemp)
+{
+ printf(" [16:0] : %ld C (%u Kelvin)\tCritical temperature (CCTEMP)\n",
+ kelvin_to_celsius(le16_to_cpu(cctemp)), le16_to_cpu(cctemp));
+ printf("\n");
+}
+
void nvme_show_id_ctrl_rpmbs(__le32 ctrl_rpmbs)
{
__u32 rpmbs = le32_to_cpu(ctrl_rpmbs);
@@ -3072,12 +3168,15 @@ static void nvme_show_id_ctrl_fuses(__le16 ctrl_fuses)
static void nvme_show_id_ctrl_fna(__u8 fna)
{
- __u8 rsvd = (fna & 0xF8) >> 3;
+ __u8 rsvd = (fna & 0xF0) >> 4;
+ __u8 bcnsid = (fna & 0x8) >> 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(" [7:4] : %#x\tReserved\n", rsvd);
+ printf(" [3:3] : %#x\tFormatNVM Broadcast NSID (FFFFFFFFh) %sSupported\n",
+ bcnsid, bcnsid ? "Not " : "");
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",
@@ -3138,6 +3237,21 @@ static void nvme_show_id_ctrl_nwpc(__u8 nwpc)
printf("\n");
}
+static void nvme_show_id_ctrl_ocfs(__le16 ctrl_ocfs)
+{
+ __u16 ocfs = le16_to_cpu(ctrl_ocfs);
+ __u16 rsvd = (ocfs & 0xfffc) >> 2;
+ __u8 copy_fmt_1 = (ocfs >> 1) & 0x1;
+ __u8 copy_fmt_0 = ocfs & 0x1;
+ if (rsvd)
+ printf(" [15:2] : %#x\tReserved\n", rsvd);
+ printf(" [1:1] : %#x\tController Copy Format 1h %sSupported\n",
+ copy_fmt_1, copy_fmt_1 ? "" : "Not ");
+ printf(" [0:0] : %#x\tController Copy Format 0h %sSupported\n",
+ copy_fmt_0, copy_fmt_0 ? "" : "Not ");
+ printf("\n");
+}
+
static void nvme_show_id_ctrl_sgls(__le32 ctrl_sgls)
{
__u32 sgls = le32_to_cpu(ctrl_sgls);
@@ -3148,7 +3262,8 @@ static void nvme_show_id_ctrl_sgls(__le32 ctrl_sgls)
__u32 sglltb = (sgls & 0x40000) >> 18;
__u32 bacmdb = (sgls & 0x20000) >> 17;
__u32 bbs = (sgls & 0x10000) >> 16;
- __u32 rsvd1 = (sgls & 0xFFF8) >> 3;
+ __u32 sdt = (sgls >> 8) & 0xff;
+ __u32 rsvd1 = (sgls & 0xF8) >> 3;
__u32 key = (sgls & 0x4) >> 2;
__u32 sglsp = sgls & 0x3;
@@ -3173,8 +3288,9 @@ static void nvme_show_id_ctrl_sgls(__le32 ctrl_sgls)
if (sglsp || (!sglsp && bbs))
printf(" [16:16]: %#x\tSGL Bit-Bucket %sSupported\n",
bbs, bbs ? "" : "Not ");
+ printf(" [15:8] : %#x\tSGL Descriptor Threshold\n", sdt);
if (rsvd1)
- printf(" [15:3] : %#x\tReserved\n", rsvd1);
+ printf(" [7:3] : %#x\tReserved\n", rsvd1);
if (sglsp || (!sglsp && key))
printf(" [2:2] : %#x\tKeyed SGL Data Block descriptor %sSupported\n",
key, key ? "" : "Not ");
@@ -3702,7 +3818,7 @@ static void nvme_show_id_ctrl_power(struct nvme_id_ctrl *ctrl)
void __nvme_show_id_ctrl(struct nvme_id_ctrl *ctrl, enum nvme_print_flags flags,
void (*vendor_show)(__u8 *vs, struct json_object *root))
{
- int human = flags & VERBOSE, vs = flags & VS;
+ bool human = flags & VERBOSE, vs = flags & VS;
if (flags & BINARY)
return d_raw((unsigned char *)ctrl, sizeof(*ctrl));
@@ -3740,6 +3856,15 @@ void __nvme_show_id_ctrl(struct nvme_id_ctrl *ctrl, enum nvme_print_flags flags,
printf("crdt1 : %u\n", le16_to_cpu(ctrl->crdt1));
printf("crdt2 : %u\n", le16_to_cpu(ctrl->crdt2));
printf("crdt3 : %u\n", le16_to_cpu(ctrl->crdt3));
+ printf("nvmsr : %u\n", ctrl->nvmsr);
+ if (human)
+ nvme_show_id_ctrl_nvmsr(ctrl->nvmsr);
+ printf("vwci : %u\n", ctrl->vwci);
+ if (human)
+ nvme_show_id_ctrl_vwci(ctrl->vwci);
+ printf("mec : %u\n", ctrl->mec);
+ if (human)
+ nvme_show_id_ctrl_mec(ctrl->vwci);
printf("oacs : %#x\n", le16_to_cpu(ctrl->oacs));
if (human)
@@ -3761,7 +3886,11 @@ void __nvme_show_id_ctrl(struct nvme_id_ctrl *ctrl, enum nvme_print_flags flags,
if (human)
nvme_show_id_ctrl_apsta(ctrl->apsta);
printf("wctemp : %d\n", le16_to_cpu(ctrl->wctemp));
+ if (human)
+ nvme_show_id_ctrl_wctemp(ctrl->wctemp);
printf("cctemp : %d\n", le16_to_cpu(ctrl->cctemp));
+ if (human)
+ nvme_show_id_ctrl_cctemp(ctrl->cctemp);
printf("mtfa : %d\n", le16_to_cpu(ctrl->mtfa));
printf("hmpre : %d\n", le32_to_cpu(ctrl->hmpre));
printf("hmmin : %d\n", le32_to_cpu(ctrl->hmmin));
@@ -3793,6 +3922,8 @@ void __nvme_show_id_ctrl(struct nvme_id_ctrl *ctrl, enum nvme_print_flags flags,
printf("anagrpmax : %d\n", ctrl->anagrpmax);
printf("nanagrpid : %d\n", le32_to_cpu(ctrl->nanagrpid));
printf("pels : %d\n", le32_to_cpu(ctrl->pels));
+ printf("domainid : %d\n", le16_to_cpu(ctrl->domainid));
+ printf("megcap : %.0Lf\n", int128_to_double(ctrl->megcap));
printf("sqes : %#x\n", ctrl->sqes);
if (human)
nvme_show_id_ctrl_sqes(ctrl->sqes);
@@ -3822,10 +3953,15 @@ void __nvme_show_id_ctrl(struct nvme_id_ctrl *ctrl, enum nvme_print_flags flags,
if (human)
nvme_show_id_ctrl_nwpc(ctrl->nwpc);
printf("acwu : %d\n", le16_to_cpu(ctrl->acwu));
+ printf("ocfs : %#x\n", le16_to_cpu(ctrl->ocfs));
+ if (human)
+ nvme_show_id_ctrl_ocfs(ctrl->ocfs);
printf("sgls : %#x\n", le32_to_cpu(ctrl->sgls));
if (human)
nvme_show_id_ctrl_sgls(ctrl->sgls);
printf("mnan : %d\n", le32_to_cpu(ctrl->mnan));
+ printf("maxdna : %.0Lf\n", int128_to_double(ctrl->maxdna));
+ printf("maxcna : %d\n", le32_to_cpu(ctrl->maxcna));
printf("subnqn : %-.*s\n", (int)sizeof(ctrl->subnqn), ctrl->subnqn);
printf("ioccsz : %d\n", le32_to_cpu(ctrl->ioccsz));
printf("iorcsz : %d\n", le32_to_cpu(ctrl->iorcsz));
@@ -3861,8 +3997,8 @@ static void json_nvme_id_ctrl_nvm(struct nvme_id_ctrl_nvm *ctrl_nvm)
json_object_add_value_uint(root, "wzsl", ctrl_nvm->wzsl);
json_object_add_value_uint(root, "wusl", ctrl_nvm->wusl);
json_object_add_value_uint(root, "dmrl", ctrl_nvm->dmrl);
- json_object_add_value_uint(root, "dmrsl", ctrl_nvm->dmrsl);
- json_object_add_value_uint(root, "dmsl", ctrl_nvm->dmsl);
+ json_object_add_value_uint(root, "dmrsl", le32_to_cpu(ctrl_nvm->dmrsl));
+ json_object_add_value_uint(root, "dmsl", le64_to_cpu(ctrl_nvm->dmsl));
json_print_object(root, NULL);
printf("\n");
@@ -4044,6 +4180,42 @@ void nvme_show_zns_id_ns(struct nvme_zns_id_ns *ns,
}
}
+static void json_nvme_list_ns(__u32 *ns_list)
+{
+ struct json_object *root;
+ struct json_object *valid_attrs;
+ struct json_object *valid;
+ int i;
+
+ root = json_create_object();
+ valid = json_create_array();
+
+ for (i = 0; i < 1024; i++) {
+ if (ns_list[i]) {
+ valid_attrs = json_create_object();
+ json_object_add_value_uint(valid_attrs, "nsid",
+ le32_to_cpu(ns_list[i]));
+ json_array_add_value_object(valid, valid_attrs);
+ }
+ }
+ json_object_add_value_array(root, "nsid_list", valid);
+ json_print_object(root, NULL);
+ printf("\n");
+ json_free_object(root);
+}
+
+void nvme_show_list_ns(__u32 *ns_list, enum nvme_print_flags flags)
+{
+ int i;
+ if (flags & JSON)
+ return json_nvme_list_ns(ns_list);
+
+ for (i = 0; i < 1024; i++) {
+ if (ns_list[i])
+ printf("[%4u]:%#x\n", i, le32_to_cpu(ns_list[i]));
+ }
+}
+
void nvme_show_zns_changed(struct nvme_zns_changed_zone_log *log,
unsigned long flags)
{
@@ -4134,6 +4306,48 @@ void nvme_show_zns_report_zones(void *report, __u32 descs,
}
}
+static void json_nvme_list_ctrl(struct nvme_controller_list *ctrl_list, __u16 num)
+{
+ struct json_object *root;
+ struct json_object *valid_attrs;
+ struct json_object *valid;
+ int i;
+
+ root = json_create_object();
+ valid = json_create_array();
+
+ json_object_add_value_uint(root, "num_ctrl",
+ le16_to_cpu(ctrl_list->num));
+
+ for (i = 0; i < min(num, 2047); i++) {
+
+ valid_attrs = json_create_object();
+ json_object_add_value_uint(valid_attrs, "ctrl_id",
+ le16_to_cpu(ctrl_list->identifier[i]));
+ json_array_add_value_object(valid, valid_attrs);
+ }
+
+ json_object_add_value_array(root, "ctrl_list", valid);
+ json_print_object(root, NULL);
+ printf("\n");
+ json_free_object(root);
+}
+
+void nvme_show_list_ctrl(struct nvme_controller_list *ctrl_list,
+ enum nvme_print_flags flags)
+{
+ int i;
+ __u16 num = le16_to_cpu(ctrl_list->num);
+
+ if (flags & JSON)
+ return json_nvme_list_ctrl(ctrl_list, num);
+
+ printf("num of ctrls present: %u\n", num);
+ for (i = 0; i < min(num, 2047); i++) {
+ printf("[%4u]:%#x\n", i, le16_to_cpu(ctrl_list->identifier[i]));
+ }
+}
+
static void json_nvme_id_nvmset(struct nvme_id_nvmset *nvmset)
{
__u32 nent = nvmset->nid;
@@ -4188,7 +4402,7 @@ void nvme_show_id_nvmset(struct nvme_id_nvmset *nvmset, unsigned nvmset_id,
printf(".................\n");
printf("nvmset_id : %d\n",
le16_to_cpu(nvmset->ent[i].id));
- printf("enduracne_group_id : %d\n",
+ printf("endurance_group_id : %d\n",
le16_to_cpu(nvmset->ent[i].endurance_group_id));
printf("random_4k_read_typical : %u\n",
le32_to_cpu(nvmset->ent[i].random_4k_read_typical));
@@ -4487,14 +4701,122 @@ void nvme_show_id_uuid_list(const struct nvme_id_uuid_list *uuid_list,
}
}
-void nvme_show_id_iocs(struct nvme_id_iocs *iocs)
+static void nvme_show_iocs_vector(__u64 iocs_vec)
+{
+ __u64 rsvd3 = iocs_vec >> 3;
+ __u8 zns_cmd_set = (iocs_vec >> 2) & 0x1;
+ __u8 kv_cmd_set = (iocs_vec >> 1) & 0x1;
+ __u8 nvm_cmd_set = iocs_vec & 0x1;
+
+ if (rsvd3)
+ printf(" [63:3] : %"PRIx64"\tReserved3\n", le64_to_cpu(rsvd3));
+ printf(" [2:2] : %#x\tZNS Command Set %sSelected\n",
+ zns_cmd_set, zns_cmd_set ? "" : "not ");
+ printf(" [1:1] : %#x\tKV Command Set %sSelected\n",
+ kv_cmd_set, kv_cmd_set ? "" : "not ");
+ printf(" [0:0] : %#x\tNVM Command Set %sSelected\n",
+ nvm_cmd_set, nvm_cmd_set ? "" : "not ");
+ printf("\n");
+}
+
+static void json_id_iocs(struct nvme_id_iocs *iocs)
{
- __u16 i;
+ struct json_object *root;
+ struct json_object *entries;
+ int i;
+
+ root = json_create_object();
+ entries = json_create_array();
- for (i = 0; i < 512; i++)
- if (iocs->iocs[i])
- printf("I/O Command Set Combination[%u]:%"PRIx64"\n", i,
+ for (i = 0; i < NVME_NUM_IOCS_COMBINATIONS; i++) {
+ if (iocs->iocs[i]) {
+ struct json_object *entry = json_create_object();
+ json_object_add_value_uint(entry, "iocs",
+ le64_to_cpu(iocs->iocs[i]));
+ json_array_add_value_object(entries, entry);
+ }
+ }
+
+ json_object_add_value_array(root, "iocs_list", entries);
+ json_print_object(root, NULL);
+ printf("\n");
+ json_free_object(root);
+
+}
+
+void nvme_show_id_iocs(struct nvme_id_iocs *iocs, enum nvme_print_flags flags)
+{
+ if (flags & BINARY)
+ return d_raw((unsigned char *)iocs, sizeof(*iocs));
+ else if (flags & JSON)
+ return json_id_iocs(iocs);
+
+ bool human = flags & VERBOSE;
+ int i;
+
+ for (i = 0; i < NVME_NUM_IOCS_COMBINATIONS; i++) {
+ if (iocs->iocs[i]) {
+ printf("I/O Command Set Combination[%u]: %"PRIx64"\n", i,
(uint64_t)le64_to_cpu(iocs->iocs[i]));
+ if (human)
+ nvme_show_iocs_vector(le64_to_cpu(iocs->iocs[i]));
+ }
+ }
+}
+
+static void json_id_domain_list(struct nvme_id_domain_list *id_dom)
+{
+ struct json_object *root;
+ struct json_object *entries;
+ struct json_object *entry;
+ int i;
+ long double dom_cap, unalloc_dom_cap, max_egrp_dom_cap;
+
+ root = json_create_object();
+ entries = json_create_array();
+
+ json_object_add_value_uint(root, "num_dom_entries", id_dom->num_entries);
+
+ for (i = 0; i < id_dom->num_entries; i++) {
+ entry = json_create_object();
+ dom_cap = int128_to_double(id_dom->domain_attr[i].dom_cap);
+ unalloc_dom_cap = int128_to_double(id_dom->domain_attr[i].unalloc_dom_cap);
+ max_egrp_dom_cap = int128_to_double(id_dom->domain_attr[i].max_egrp_dom_cap);
+
+ json_object_add_value_uint(entry, "dom_id", le16_to_cpu(id_dom->domain_attr[i].dom_id));
+ json_object_add_value_float(entry, "dom_cap", dom_cap);
+ json_object_add_value_float(entry, "unalloc_dom_cap", unalloc_dom_cap);
+ json_object_add_value_float(entry, "max_egrp_dom_cap", max_egrp_dom_cap);
+
+ json_array_add_value_object(entries, entry);
+ }
+
+ json_object_add_value_array(root, "domain_list", entries);
+ json_print_object(root, NULL);
+ printf("\n");
+ json_free_object(root);
+}
+
+void nvme_show_id_domain_list(struct nvme_id_domain_list *id_dom,
+ enum nvme_print_flags flags)
+{
+ int i;
+ if (flags & BINARY)
+ return d_raw((unsigned char *)id_dom, sizeof(*id_dom));
+ else if (flags & JSON)
+ return json_id_domain_list(id_dom);
+
+ printf("Number of Domain Entires: %u\n", id_dom->num_entries);
+ for (i = 0; i < id_dom->num_entries; i++) {
+ printf("Domain Id for Attr Entry[%u]: %u\n", i,
+ le16_to_cpu(id_dom->domain_attr[i].dom_id));
+ printf("Domain Capacity for Attr Entry[%u]: %.0Lf\\n", i,
+ int128_to_double(id_dom->domain_attr[i].dom_cap));
+ printf("Unallocated Domain Capacity for Attr Entry[%u]: %.0Lf\n", i,
+ int128_to_double(id_dom->domain_attr[i].unalloc_dom_cap));
+ printf("Max Endurange Group Domain Capacity for Attr Entry[%u]: %.0Lf\n", i,
+ int128_to_double(id_dom->domain_attr[i].max_egrp_dom_cap));
+ }
}
static const char *nvme_trtype_to_string(__u8 trtype)
@@ -4620,7 +4942,6 @@ void nvme_show_fw_log(struct nvme_firmware_log_page *fw_log,
const char *devname, enum nvme_print_flags flags)
{
int i;
-
if (flags & BINARY)
return d_raw((unsigned char *)fw_log, sizeof(*fw_log));
if (flags & JSON)
@@ -4629,10 +4950,8 @@ void nvme_show_fw_log(struct nvme_firmware_log_page *fw_log,
printf("Firmware Log for device:%s\n", devname);
printf("afi : %#x\n", fw_log->afi);
for (i = 0; i < 7; i++) {
- if (fw_log->frs[i])
- printf("frs%d : %#016"PRIx64" (%s)\n", i + 1,
- (uint64_t)fw_log->frs[i],
- fw_to_string(fw_log->frs[i]));
+ if (strcmp(fw_to_string(fw_log->frs[i]), "\0"))
+ printf("frs%d : %s\n", i + 1, fw_to_string(fw_log->frs[i]));
}
}
@@ -4771,10 +5090,9 @@ void nvme_show_endurance_log(struct nvme_endurance_group_log *endurance_log,
void nvme_show_smart_log(struct nvme_smart_log *smart, unsigned int nsid,
const char *devname, enum nvme_print_flags flags)
{
- /* convert temperature from Kelvin to Celsius */
- int temperature = ((smart->temperature[1] << 8) |
- smart->temperature[0]) - 273;
- int i, human = flags & VERBOSE;
+ __u16 temperature = smart->temperature[1] << 8 | smart->temperature[0];
+ int i;
+ bool human = flags & VERBOSE;
if (flags & BINARY)
return d_raw((unsigned char *)smart, sizeof(*smart));
@@ -4794,8 +5112,8 @@ void nvme_show_smart_log(struct nvme_smart_log *smart, unsigned int nsid,
printf(" Persistent Mem. RO[5] : %d\n", (smart->critical_warning & 0x20) >> 5);
}
- printf("temperature : %d C\n",
- temperature);
+ printf("temperature : %ld C (%u Kelvin)\n",
+ kelvin_to_celsius(temperature), temperature);
printf("available_spare : %u%%\n",
smart->avail_spare);
printf("available_spare_threshold : %u%%\n",
@@ -4833,8 +5151,8 @@ void nvme_show_smart_log(struct nvme_smart_log *smart, unsigned int nsid,
if (temp == 0)
continue;
- printf("Temperature Sensor %d : %d C\n", i + 1,
- temp - 273);
+ printf("Temperature Sensor %d : %ld C (%u Kelvin)\n",
+ i + 1, kelvin_to_celsius(temp), temp);
}
printf("Thermal Management T1 Trans Count : %u\n",
le32_to_cpu(smart->thm_temp1_trans_count));
@@ -5030,11 +5348,9 @@ void nvme_show_sanitize_log(struct nvme_sanitize_log_page *sanitize,
__u16 status = le16_to_cpu(sanitize->status) & NVME_SANITIZE_LOG_STATUS_MASK;
if (flags & BINARY)
- d_raw((unsigned char *)sanitize, sizeof(*sanitize));
- else if (flags & JSON) {
- json_sanitize_log(sanitize, devname);
- return;
- }
+ return d_raw((unsigned char *)sanitize, sizeof(*sanitize));
+ else if (flags & JSON)
+ return json_sanitize_log(sanitize, devname);
printf("Sanitize Progress (SPROG) : %u",
le16_to_cpu(sanitize->progress));
@@ -5088,7 +5404,7 @@ const char *nvme_feature_to_string(enum nvme_feat feature)
case NVME_FEAT_PLM_CONFIG: return "Predicatable Latency Mode Config";
case NVME_FEAT_PLM_WINDOW: return "Predicatable Latency Mode Window";
case NVME_LBA_STATUS_INFO: return "LBA Status Infomation Attributes";
- case NVME_FEAT_ENDURANCE: return "Enduarance Event Group Configuration";
+ case NVME_FEAT_ENDURANCE: return "Enduarance Event Group Configuration";
case NVME_FEAT_IOCS_PROFILE: return "I/O Command Set Profile";
case NVME_FEAT_SW_PROGRESS: return "Software Progress";
case NVME_FEAT_HOST_ID: return "Host Identifier";
@@ -5099,6 +5415,8 @@ const char *nvme_feature_to_string(enum nvme_feat feature)
case NVME_FEAT_HCTM: return "Host Controlled Thermal Management";
case NVME_FEAT_HOST_BEHAVIOR: return "Host Behavior";
case NVME_FEAT_SANITIZE: return "Sanitize";
+ case NVME_MI_FEAT_CTRL_METADATA:return "MI Controller Metadata";
+ case NVME_MI_FEAT_NS_METADATA: return "MI Namespace Metadata";
}
/*
* We don't use the "default:" statement to let the compiler warning if
@@ -5209,6 +5527,10 @@ const char *nvme_status_to_string(__u16 status)
return "SANITIZE_FAILED: The most recent sanitize operation failed and no recovery actions has been successfully completed";
case NVME_SC_SANITIZE_IN_PROGRESS:
return "SANITIZE_IN_PROGRESS: The requested function is prohibited while a sanitize operation is in progress";
+ case NVME_SC_SGL_DATA_BLK_GRAN_INVALID:
+ return "NVME_SC_SGL_DATA_BLK_GRAN_INVALID: Address alignment or Length granularity for an SGL Data Block descriptor is invalid";
+ case NVME_SC_CMD_NOT_SUP_QUEUE_IN_CMB:
+ return "NVME_SC_CMD_NOT_SUP_QUEUE_IN_CMB: does not support submission of the command to a SQ or completion to a CQ in the CMB";
case NVME_SC_IOCS_NOT_SUPPORTED:
return "IOCS_NOT_SUPPORTED: The I/O command set is not supported";
case NVME_SC_IOCS_NOT_ENABLED:
@@ -5217,12 +5539,18 @@ const char *nvme_status_to_string(__u16 status)
return "IOCS_COMBINATION_REJECTED: The I/O command set combination is rejected";
case NVME_SC_INVALID_IOCS:
return "INVALID_IOCS: the I/O command set is invalid";
+ case NVME_SC_ID_UNAVAILABLE:
+ return "NVME_SC_ID_UNAVAILABLE: The number of Endurance Groups or NVM Sets supported has been exceeded.";
case NVME_SC_LBA_RANGE:
return "LBA_RANGE: The command references a LBA that exceeds the size of the namespace";
case NVME_SC_NS_WRITE_PROTECTED:
return "NS_WRITE_PROTECTED: The command is prohibited while the namespace is write protected by the host.";
case NVME_SC_TRANSIENT_TRANSPORT:
return "TRANSIENT_TRANSPORT: A transient transport error was detected.";
+ case NVME_SC_PROHIBITED_BY_CMD_AND_FEAT:
+ return "NVME_SC_PROHIBITED_BY_CMD_AND_FEAT: command was aborted due to execution being prohibited by the Command and Feature Lockdown";
+ case NVME_SC_ADMIN_CMD_MEDIA_NOT_READY:
+ return "NVME_SC_ADMIN_CMD_MEDIA_NOT_READY: Admin command requires access to media and the media is not ready";
case NVME_SC_CAP_EXCEEDED:
return "CAP_EXCEEDED: The execution of the command has caused the capacity of the namespace to be exceeded";
case NVME_SC_NS_NOT_READY:
@@ -5319,6 +5647,12 @@ const char *nvme_status_to_string(__u16 status)
return "ANA_INVALID_GROUP_ID: The specified ANA Group Identifier (ANAGRPID) is not supported in the submitted command.";
case NVME_SC_ANA_ATTACH_FAIL:
return "ANA_ATTACH_FAIL: The controller is not attached to the namespace as a result of an ANA condition";
+ case NVME_SC_INSUFFICIENT_CAP:
+ return "NVME_SC_INSUFFICIENT_CAP: Requested operation requires more free space than is currently available";
+ case NVME_SC_NS_ATTACHMENT_LIMIT_EXCEEDED:
+ return "NVME_SC_NS_ATTACHMENT_LIMIT_EXCEEDED: Attaching the ns to a controller causes max number of ns attachments allowed to be exceeded";
+ case NVME_SC_PROHIBIT_CMD_EXEC_NOT_SUPPORTED:
+ return "NVME_SC_PROHIBIT_CMD_EXEC_NOT_SUPPORTED: Prohibition of Command Execution Not Supported";
case NVME_SC_BAD_ATTRIBUTES:
return "BAD_ATTRIBUTES: Bad attributes were given";
case NVME_SC_INVALID_PI:
@@ -5343,6 +5677,8 @@ const char *nvme_status_to_string(__u16 status)
return "ACCESS_DENIED: Access to the namespace and/or LBA range is denied due to lack of access rights";
case NVME_SC_UNWRITTEN_BLOCK:
return "UNWRITTEN_BLOCK: The command failed due to an attempt to read from an LBA range containing a deallocated or unwritten logical block";
+ case NVME_SC_STORAGE_TAG_CHECK:
+ return "NVME_SC_STORAGE_TAG_CHECK: command was aborted due to an end-to-end storage tag check failure";
case NVME_SC_INTERNAL_PATH_ERROR:
return "INTERNAL_PATH_ERROT: The command was not completed as the result of a controller internal error";
case NVME_SC_ANA_PERSISTENT_LOSS:
@@ -5396,8 +5732,8 @@ void nvme_show_lba_range(struct nvme_lba_range_type *lbrt, int nr_ranges)
((lbrt[i].attributes & 0x0002) >> 1) ?
"LBA range should be hidden from the OS/EFI/BIOS" :
"LBA range should be visible from the OS/EFI/BIOS");
- printf("\tslba : %#"PRIx64"\n", (uint64_t)(lbrt[i].slba));
- printf("\tnlb : %#"PRIx64"\n", (uint64_t)(lbrt[i].nlb));
+ printf("\tslba : %#"PRIx64"\n", le64_to_cpu(lbrt[i].slba));
+ printf("\tnlb : %#"PRIx64"\n", le64_to_cpu(lbrt[i].nlb));
printf("\tguid : ");
for (j = 0; j < 16; j++)
printf("%02x", lbrt[i].guid[j]);
@@ -5451,9 +5787,9 @@ static void nvme_show_auto_pst(struct nvme_auto_pst *apst)
printf("\tEntry[%2d] \n", i);
printf("\t.................\n");
printf("\tIdle Time Prior to Transition (ITPT): %u ms\n",
- (apst[i].data & 0xffffff00) >> 8);
+ (le32_to_cpu(apst[i].data) & 0xffffff00) >> 8);
printf("\tIdle Transition Power State (ITPS): %u\n",
- (apst[i].data & 0x000000f8) >> 3);
+ (le32_to_cpu(apst[i].data) & 0x000000f8) >> 3);
printf("\t.................\n");
}
}
@@ -5493,6 +5829,22 @@ static void nvme_show_host_mem_buffer(struct nvme_host_mem_buffer *hmb)
le32_to_cpu(hmb->hsize));
}
+static const char *nvme_show_ns_write_protect_config(__u8 state)
+{
+ switch (state) {
+ case NVME_NS_NO_WRITE_PROTECT:
+ return "No Write Protect";
+ case NVME_NS_WRITE_PROTECT:
+ return "Write Protect";
+ case NVME_NS_WRITE_PROTECT_POWER_CYCLE:
+ return "Write Protect Until Power Cycle";
+ case NVME_NS_WRITE_PROTECT_PERMANENT:
+ return "Permanent Write Protect";
+ default:
+ return "Reserved";
+ }
+}
+
static void nvme_directive_show_fields(__u8 dtype, __u8 doper,
unsigned int result, unsigned char *buf)
{
@@ -5592,7 +5944,8 @@ static const char *nvme_plm_window(__u32 plm)
}
}
-void nvme_show_lba_status_info(__u32 result) {
+void nvme_show_lba_status_info(__u32 result)
+{
printf("\tLBA Status Information Poll Interval (LSIPI) : %u\n", (result >> 16) & 0xffff);
printf("\tLBA Status Information Report Interval (LSIRI): %u\n", result & 0xffff);
}
@@ -5605,15 +5958,75 @@ static void nvme_show_plm_config(struct nvme_plm_config *plmcfg)
printf("\tDTWIN Time Threshold :%"PRIu64"\n", le64_to_cpu(plmcfg->dtwin_time_thresh));
}
-void nvme_feature_show_fields(enum nvme_feat fid, unsigned int result, unsigned char *buf)
+static char* nvme_show_mi_host_metadata_type_to_string(enum nvme_feat fid, __u8 type)
+{
+ switch (fid) {
+ case NVME_MI_FEAT_CTRL_METADATA:
+ switch (type) {
+ case NVME_MI_CTRL_METADATA_OS_CTRL_NAME:
+ return "Operating System Controller Name";
+ case NVME_MI_CTRL_METADATA_OS_DRIVER_NAME:
+ return "Operating System Driver Name";
+ case NVME_MI_CTRL_METADATA_OS_DRIVER_VER:
+ return "Operating System Driver Version";
+ case NVME_MI_CTRL_METADATA_PRE_BOOT_CTRL_NAME:
+ return "Pre-boot Controller Name";
+ case NVME_MI_CTRL_METADATA_PRE_BOOT_DRIVER_NAME:
+ return "Pre-boot Driver Name";
+ case NVME_MI_CTRL_METADATA_PRE_BOOT_DRIVER_VER:
+ return "Pre-boot Driver Version";
+ default:
+ return "Unknown Controller Type";
+ }
+ case NVME_MI_FEAT_NS_METADATA:
+ switch (type) {
+ case NVME_MI_NS_METADATA_OS_NS_NAME:
+ return "Operating System Namespace Name";
+ case NVME_MI_NS_METADATA_PRE_BOOT_NS_NAME:
+ return "Pre-boot Namespace Name";
+ default:
+ return "Unknown Namespace Type";
+ }
+ default:
+ return "Unknown Feature";
+ }
+}
+
+static void nvme_show_mi_host_metadata(enum nvme_feat fid,
+ struct nvme_mi_host_metadata *data)
+{
+ struct nvme_mi_host_metadata_element_desc *desc = &data->descs[0];
+ int i;
+ char val[4096];
+ __u16 len;
+
+ printf("\tNum Metadata Element Descriptors: %d\n", data->ndesc);
+ for (i = 0; i < data->ndesc; i++) {
+ len = le16_to_cpu(desc->len);
+ strncpy(val, (char *)desc->val, min(sizeof(val) - 1, len));
+
+ printf("\tElement[%-3d]:\n", i);
+ printf("\t\tType : 0x%02x (%s)\n", desc->type,
+ nvme_show_mi_host_metadata_type_to_string(fid, desc->type));
+ printf("\t\tRevision : %d\n", desc->rev);
+ printf("\t\tLength : %d\n", len);
+ printf("\t\tValue : %s\n", val);
+
+ desc = (struct nvme_mi_host_metadata_element_desc *)
+ &desc->val[desc->len];
+ }
+}
+
+void nvme_feature_show_fields(enum nvme_feat fid, unsigned int result,
+ unsigned char *buf)
{
__u8 field;
uint64_t ull;
switch (fid) {
- case NVME_FEAT_NONE:
- printf("\tFeature Identifier Reserved\n");
- break;
+ case NVME_FEAT_NONE:
+ printf("\tFeature Identifier Reserved\n");
+ break;
case NVME_FEAT_ARBITRATION:
printf("\tHigh Priority Weight (HPW): %u\n", ((result & 0xff000000) >> 24) + 1);
printf("\tMedium Priority Weight (MPW): %u\n", ((result & 0x00ff0000) >> 16) + 1);
@@ -5639,7 +6052,8 @@ void nvme_feature_show_fields(enum nvme_feat fid, unsigned int result, unsigned
printf("\tThreshold Type Select (THSEL): %u - %s\n", field, nvme_feature_temp_type_to_string(field));
field = (result & 0x000f0000) >> 16;
printf("\tThreshold Temperature Select (TMPSEL): %u - %s\n", field, nvme_feature_temp_sel_to_string(field));
- printf("\tTemperature Threshold (TMPTH): %d C\n", (result & 0x0000ffff) - 273);
+ printf("\tTemperature Threshold (TMPTH): %ld C (%u Kelvin)\n",
+ kelvin_to_celsius(result & 0x0000ffff), result & 0x0000ffff);
break;
case NVME_FEAT_ERR_RECOVERY:
printf("\tDeallocated or Unwritten Logical Block Error Enable (DULBE): %s\n", ((result & 0x00010000) >> 16) ? "Enabled":"Disabled");
@@ -5664,6 +6078,7 @@ void nvme_feature_show_fields(enum nvme_feat fid, unsigned int result, unsigned
printf("\tDisable Normal (DN): %s\n", (result & 0x00000001) ? "True":"False");
break;
case NVME_FEAT_ASYNC_EVENT:
+ printf("\tZone Descriptor Changed Notices: %s\n", ((result >> 27) & 0x1) ? "Send async event":"Do not send async event");
printf("\tEndurance Group Event Aggregate Log Change Notices: %s\n", ((result & 0x00004000) >> 14) ? "Send async event":"Do not send async event");
printf("\tLBA Status Information Notices : %s\n", ((result & 0x00002000) >> 13) ? "Send async event":"Do not send async event");
printf("\tPredictable Latency Event Aggregate Log Change Notices: %s\n", ((result & 0x00001000) >> 12) ? "Send async event":"Do not send async event");
@@ -5694,10 +6109,10 @@ void nvme_feature_show_fields(enum nvme_feat fid, unsigned int result, unsigned
case NVME_LBA_STATUS_INFO:
nvme_show_lba_status_info(result);
break;
- case NVME_FEAT_ENDURANCE:
- printf("\tEndurance Group Identifier (ENDGID): %u\n", result & 0xffff);
- printf("\tEndurance Group Critical Warnings : %u\n", (result >> 16) & 0xff);
- break;
+ case NVME_FEAT_ENDURANCE:
+ printf("\tEndurance Group Identifier (ENDGID): %u\n", result & 0xffff);
+ printf("\tEndurance Group Critical Warnings : %u\n", (result >> 16) & 0xff);
+ break;
case NVME_FEAT_IOCS_PROFILE:
printf("\tI/O Command Set Comination Index(IOCSCI): %u\n", result & 0x1ff);
break;
@@ -5716,14 +6131,16 @@ void nvme_feature_show_fields(enum nvme_feat fid, unsigned int result, unsigned
printf("\tPersist Through Power Loss (PTPL): %s\n", (result & 0x00000001) ? "True":"False");
break;
case NVME_FEAT_WRITE_PROTECT:
- printf("\tNamespace Write Protect: %s\n", result != NVME_NS_NO_WRITE_PROTECT ? "True" : "False");
+ printf("\tNamespace Write Protect state: %s\n", nvme_show_ns_write_protect_config(result & 0x7));
break;
case NVME_FEAT_TIMESTAMP:
nvme_show_timestamp((struct nvme_timestamp *)buf);
break;
case NVME_FEAT_HCTM:
- printf("\tThermal Management Temperature 1 (TMT1) : %u Kelvin\n", (result >> 16));
- printf("\tThermal Management Temperature 2 (TMT2) : %u Kelvin\n", (result & 0x0000ffff));
+ printf("\tThermal Management Temperature 1 (TMT1) : %u Kelvin (%ld C)\n",
+ result >> 16, kelvin_to_celsius(result >> 16));
+ printf("\tThermal Management Temperature 2 (TMT2) : %u Kelvin (%ld C)\n",
+ result & 0x0000ffff, kelvin_to_celsius(result & 0x0000ffff));
break;
case NVME_FEAT_KATO:
printf("\tKeep Alive Timeout (KATO) in milliseconds: %u\n", result);
@@ -5740,6 +6157,10 @@ void nvme_feature_show_fields(enum nvme_feat fid, unsigned int result, unsigned
case NVME_FEAT_RRL:
printf("\tRead Recovery Level (RRL): %u\n", result & 0xf);
break;
+ case NVME_MI_FEAT_CTRL_METADATA:
+ case NVME_MI_FEAT_NS_METADATA:
+ nvme_show_mi_host_metadata(fid, (struct nvme_mi_host_metadata *)buf);
+ break;
}
}
@@ -5751,8 +6172,8 @@ void nvme_show_lba_status(struct nvme_lba_status *list, unsigned long len,
if (flags & BINARY)
return d_raw((unsigned char *)list, len);
- printf("Number of LBA Status Descriptors(NLSD): %" PRIu64 "\n",
- le64_to_cpu(list->nlsd));
+ printf("Number of LBA Status Descriptors(NLSD): %" PRIu32 "\n",
+ le32_to_cpu(list->nlsd));
printf("Completion Condition(CMPC): %u\n", list->cmpc);
switch (list->cmpc) {
@@ -5791,6 +6212,9 @@ static void nvme_show_list_item(struct nvme_namespace *n)
struct stat st;
int ret;
+ if (!n->ctrl)
+ return;
+
sprintf(path, "%s%s", n->ctrl->path, n->name);
ret = stat(path, &st);
if (ret < 0)
@@ -5847,6 +6271,9 @@ static void nvme_show_details_ns(struct nvme_namespace *n, bool ctrl)
char usage[128];
char format[128];
+ if (!n->ctrl)
+ return;
+
sprintf(usage,"%6.2f %2sB / %6.2f %2sB", nuse, u_suffix,
nsze, s_suffix);
sprintf(format,"%3.0f %2sB + %2d B", (double)lba, l_suffix,
@@ -6063,6 +6490,9 @@ static void json_simple_ns(struct nvme_namespace *n, struct json_object *devices
char *devnode;
struct stat st;
+ if (!n->ctrl)
+ return;
+
if (asprintf(&devnode, "%s%s", n->ctrl->path, n->name) < 0)
return;
diff --git a/nvme-print.h b/nvme-print.h
index 2d8ed4d..08be8f2 100644
--- a/nvme-print.h
+++ b/nvme-print.h
@@ -83,7 +83,12 @@ void nvme_show_id_ns_granularity_list(const struct nvme_id_ns_granularity_list *
enum nvme_print_flags flags);
void nvme_show_id_uuid_list(const struct nvme_id_uuid_list *uuid_list,
enum nvme_print_flags flags);
-void nvme_show_id_iocs(struct nvme_id_iocs *iocs);
+void nvme_show_id_iocs(struct nvme_id_iocs *iocs, enum nvme_print_flags flags);
+void nvme_show_list_ctrl(struct nvme_controller_list *ctrl_list,
+ enum nvme_print_flags flags);
+void nvme_show_list_ns(__u32 *ns_list, enum nvme_print_flags flags);
+void nvme_show_id_domain_list(struct nvme_id_domain_list *id_dom,
+ enum nvme_print_flags flags);
void nvme_feature_show_fields(enum nvme_feat fid, unsigned int result, unsigned char *buf);
void nvme_directive_show(__u8 type, __u8 oper, __u16 spec, __u32 nsid, __u32 result,
diff --git a/nvme-rpmb.c b/nvme-rpmb.c
index 0e11ef3..a7658f5 100644
--- a/nvme-rpmb.c
+++ b/nvme-rpmb.c
@@ -266,7 +266,7 @@ struct rpmb_config_block_t {
#define RPMB_NVME_SPSP 0x0001
#define SEND_RPMB_REQ(tgt, size, req) \
-nvme_sec_send(fd, 0, tgt, RPMB_NVME_SPSP, RPMB_NVME_SECP, size, size, \
+nvme_sec_send(fd, 0, tgt, RPMB_NVME_SPSP, RPMB_NVME_SECP, size, \
(unsigned char *)(req))
#define RECV_RPMB_RSP(tgt, size, rsp) \
diff --git a/nvme-topology.c b/nvme-topology.c
index 31cf7f9..0a22f6b 100644
--- a/nvme-topology.c
+++ b/nvme-topology.c
@@ -155,23 +155,23 @@ static int scan_namespace(struct nvme_namespace *n)
return ret;
fd = open(path, O_RDONLY);
- if (fd < 0)
+ if (fd < 0) {
+ ret = fd;
goto free;
-
+ }
if (!n->nsid) {
- n->nsid = nvme_get_nsid(fd);
- if (n->nsid < 0)
+ ret = nvme_get_nsid(fd);
+ if (ret < 0)
goto close_fd;
+ n->nsid = ret;
}
ret = nvme_identify_ns(fd, n->nsid, 0, &n->ns);
- if (ret < 0)
- goto close_fd;
close_fd:
close(fd);
free:
free(path);
- return 0;
+ return ret;
}
static char *get_nvme_ctrl_path_ana_state(char *path, int nsid)
@@ -319,10 +319,8 @@ static int scan_ctrl(struct nvme_ctrl *c, char *p, __u32 ns_instance)
return ret;
fd = open(path, O_RDONLY);
- if (fd < 0) {
- fprintf(stderr, "Failed to open %s\n", path);
+ if (fd < 0)
goto free;
- }
ret = nvme_identify_ctrl(fd, &c->id);
if (ret < 0)
@@ -384,8 +382,12 @@ static int scan_subsystem(struct nvme_subsystem *s, __u32 ns_instance, int nsid)
for (i = 0; i < s->nr_namespaces; i++) {
n = &s->namespaces[i];
n->name = strdup(ns[i]->d_name);
- n->ctrl = &s->ctrls[0];
- scan_namespace(n);
+ for (j = 0; j < s->nr_ctrls; j++) {
+ n->ctrl = &s->ctrls[j];
+ if (!strcmp(n->ctrl->state, "live") &&
+ !scan_namespace(n))
+ break;
+ }
}
} else {
i = s->nr_namespaces;
@@ -666,6 +668,30 @@ char *nvme_char_from_block(char *dev)
return path;
}
+int nvme_logical_block_size_from_ns_char(const char *dev)
+{
+ int ret;
+ int id, nsid;
+ char *path = NULL;
+ char *s;
+
+ ret = sscanf(dev, "ng%dn%d", &id, &nsid);
+ if (ret != 2)
+ return -EINVAL;
+
+ if (asprintf(&path, "/sys/block/nvme%dn%d/queue", id, nsid) < 0)
+ path = NULL;
+
+ if (!path)
+ return -EINVAL;
+
+ s = nvme_get_ctrl_attr(path, "logical_block_size");
+ if (!s)
+ return -EINVAL;
+
+ return atoi(s);
+}
+
void *mmap_registers(const char *dev)
{
int fd;
diff --git a/nvme.c b/nvme.c
index a2075bf..c10932f 100644
--- a/nvme.c
+++ b/nvme.c
@@ -91,7 +91,9 @@ static __u16 nvme_feat_buf_len[0x100] = {
[NVME_FEAT_HOST_ID] = 8,
[NVME_FEAT_PLM_CONFIG] = 512,
[NVME_FEAT_TIMESTAMP] = 8,
- [NVME_FEAT_HOST_BEHAVIOR] = 512
+ [NVME_FEAT_HOST_BEHAVIOR] = 512,
+ [NVME_MI_FEAT_CTRL_METADATA] = 4096,
+ [NVME_MI_FEAT_NS_METADATA] = 4096,
};
const char *output_format = "Output format: normal|json|binary";
@@ -156,6 +158,11 @@ static bool is_blkdev(void)
return S_ISBLK(nvme_stat.st_mode);
}
+static bool is_ns_chardev(void)
+{
+ return !strncmp(devicename, "ng", 2) && S_ISCHR(nvme_stat.st_mode);
+}
+
static int open_dev(char *dev)
{
int err, fd;
@@ -242,7 +249,7 @@ static int get_smart_log(int argc, char **argv, struct command *cmd, struct plug
const char *raw = "output in binary format";
const char *human_readable = "show info in readable format";
enum nvme_print_flags flags;
- int err, fd;
+ int err = -1, fd;
struct config {
__u32 namespace_id;
@@ -297,7 +304,7 @@ static int get_ana_log(int argc, char **argv, struct command *cmd,
const char *desc = "Retrieve ANA log for the given device in " \
"decoded format (default), json or binary.";
void *ana_log;
- int err, fd;
+ int err = -1, fd;
int groups = 0; /* Right now get all the per ANA group NSIDS */
size_t ana_log_len;
struct nvme_id_ctrl ctrl;
@@ -339,7 +346,8 @@ static int get_ana_log(int argc, char **argv, struct command *cmd,
ana_log = malloc(ana_log_len);
if (!ana_log) {
perror("malloc");
- err = -ENOMEM;
+ errno = ENOMEM;
+ err = -1;
goto close_fd;
}
@@ -367,7 +375,7 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd, struct
const size_t bs = 512;
struct nvme_telemetry_log_page_hdr *hdr;
size_t full_size, offset = bs;
- int err = 0, fd, output;
+ int err = -1, fd, output;
void *page_log;
struct config {
@@ -397,7 +405,8 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd, struct
if (!cfg.file_name) {
fprintf(stderr, "Please provide an output file!\n");
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
@@ -406,7 +415,8 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd, struct
page_log = malloc(bs);
if (!hdr || !page_log) {
perror("failed to allocate buf for log\n");
- err = -ENOMEM;
+ errno = ENOMEM;
+ err = -1;
goto free_mem;
}
memset(hdr, 0, bs);
@@ -446,7 +456,8 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd, struct
break;
default:
fprintf(stderr, "Invalid data area requested\n");
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_output;
}
@@ -491,7 +502,7 @@ static int get_endurance_log(int argc, char **argv, struct command *cmd, struct
const char *desc = "Retrieves endurance groups log page and prints the log.";
const char *group_id = "The endurance group identifier";
enum nvme_print_flags flags;
- int err, fd;
+ int err = -1, fd;
struct config {
char *output_format;
@@ -505,7 +516,7 @@ static int get_endurance_log(int argc, char **argv, struct command *cmd, struct
OPT_ARGS(opts) = {
OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
- OPT_UINT("group-id", 'g', &cfg.group_id, group_id),
+ OPT_SHRT("group-id", 'g', &cfg.group_id, group_id),
OPT_END()
};
@@ -537,7 +548,7 @@ static int get_effects_log(int argc, char **argv, struct command *cmd, struct pl
const char *human_readable = "show log in readable format";
struct nvme_effects_log_page effects;
- int err, fd;
+ int err = -1, fd;
enum nvme_print_flags flags;
struct config {
@@ -592,7 +603,7 @@ static int get_error_log(int argc, char **argv, struct command *cmd, struct plug
struct nvme_error_log_page *err_log;
struct nvme_id_ctrl ctrl;
enum nvme_print_flags flags;
- int err, fd;
+ int err = -1, fd;
struct config {
__u32 log_entries;
@@ -624,7 +635,8 @@ static int get_error_log(int argc, char **argv, struct command *cmd, struct plug
if (!cfg.log_entries) {
fprintf(stderr, "non-zero log-entries is required param\n");
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
@@ -634,7 +646,8 @@ static int get_error_log(int argc, char **argv, struct command *cmd, struct plug
goto close_fd;
} else if (err) {
fprintf(stderr, "could not identify controller\n");
- err = -ENODEV;
+ errno = ENODEV;
+ err = -1;
goto close_fd;
}
@@ -642,7 +655,8 @@ static int get_error_log(int argc, char **argv, struct command *cmd, struct plug
err_log = calloc(cfg.log_entries, sizeof(struct nvme_error_log_page));
if (!err_log) {
perror("could not alloc buffer for error log\n");
- err = -ENOMEM;
+ errno = ENOMEM;
+ err = -1;
goto close_fd;
}
@@ -667,7 +681,7 @@ static int get_fw_log(int argc, char **argv, struct command *cmd, struct plugin
const char *raw = "use binary output";
struct nvme_firmware_log_page fw_log;
enum nvme_print_flags flags;
- int err, fd;
+ int err = -1, fd;
struct config {
int raw_binary;
@@ -715,7 +729,7 @@ static int get_changed_ns_list_log(int argc, char **argv, struct command *cmd, s
"(default) or binary.";
const char *raw = "output in binary format";
enum nvme_print_flags flags;
- int err, fd;
+ int err = -1, fd;
struct config {
int raw_binary;
@@ -766,7 +780,7 @@ static int get_pred_lat_per_nvmset_log(int argc, char **argv,
const char *raw = "use binary output";
struct nvme_predlat_per_nvmset_log_page plpns_log;
enum nvme_print_flags flags;
- int err, fd;
+ int err = -1, fd;
struct config {
__u16 nvmset_id;
@@ -780,7 +794,7 @@ static int get_pred_lat_per_nvmset_log(int argc, char **argv,
};
OPT_ARGS(opts) = {
- OPT_UINT("nvmset-id", 'i', &cfg.nvmset_id, nvmset_id),
+ OPT_SHRT("nvmset-id", 'i', &cfg.nvmset_id, nvmset_id),
OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw),
OPT_END()
@@ -826,7 +840,7 @@ static int get_pred_lat_event_agg_log(int argc, char **argv,
void *pea_log;
struct nvme_id_ctrl ctrl;
enum nvme_print_flags flags;
- int err, fd;
+ int err = -1, fd;
__u32 log_size;
struct config {
@@ -862,7 +876,8 @@ static int get_pred_lat_event_agg_log(int argc, char **argv,
if (!cfg.log_entries) {
fprintf(stderr, "non-zero log-entries is required param\n");
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
@@ -881,7 +896,8 @@ static int get_pred_lat_event_agg_log(int argc, char **argv,
if (!pea_log) {
perror("could not alloc buffer for predictable " \
"latency event agggregate log entries\n");
- err = -ENOMEM;
+ errno = ENOMEM;
+ err = -1;
goto close_fd;
}
@@ -913,9 +929,9 @@ static int get_persistent_event_log(int argc, char **argv,
const char *log_len = "number of bytes to retrieve";
const char *raw = "use binary output";
void *pevent_log_info;
- struct nvme_persistent_event_log_head *pevent_log_head;
+ struct nvme_persistent_event_log_head *pevent_log_head = NULL;
enum nvme_print_flags flags;
- int err, fd;
+ int err = -1, fd;
bool huge;
struct config {
@@ -932,7 +948,7 @@ static int get_persistent_event_log(int argc, char **argv,
};
OPT_ARGS(opts) = {
- OPT_UINT("action", 'a', &cfg.action, action),
+ OPT_BYTE("action", 'a', &cfg.action, action),
OPT_UINT("log_len", 'l', &cfg.log_len, log_len),
OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw),
@@ -949,11 +965,19 @@ static int get_persistent_event_log(int argc, char **argv,
if (cfg.raw_binary)
flags = BINARY;
+ if (cfg.action > 3) {
+ fprintf(stderr, "invalid action field: %u\n", cfg.action);
+ errno = EINVAL;
+ err = -1;
+ goto close_fd;
+ }
+
pevent_log_head = calloc(sizeof(*pevent_log_head), 1);
if (!pevent_log_head) {
perror("could not alloc buffer for persistent " \
"event log header\n");
- err = -ENOMEM;
+ errno = ENOMEM;
+ err = -1;
goto close_fd;
}
@@ -992,7 +1016,8 @@ static int get_persistent_event_log(int argc, char **argv,
pevent_log_info = nvme_alloc(cfg.log_len, &huge);
if (!pevent_log_info) {
perror("could not alloc buffer for persistent event log page\n");
- err = -ENOMEM;
+ errno = ENOMEM;
+ err = -1;
goto close_fd;
}
err = nvme_persistent_event_log(fd, cfg.action,
@@ -1028,7 +1053,7 @@ static int get_endurance_event_agg_log(int argc, char **argv,
void *endurance_log;
struct nvme_id_ctrl ctrl;
enum nvme_print_flags flags;
- int err, fd;
+ int err = -1, fd;
__u32 log_size;
struct config {
@@ -1064,7 +1089,8 @@ static int get_endurance_event_agg_log(int argc, char **argv,
if (!cfg.log_entries) {
fprintf(stderr, "non-zero log-entries is required param\n");
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
@@ -1074,7 +1100,8 @@ static int get_endurance_event_agg_log(int argc, char **argv,
goto close_fd;
} else if (err) {
fprintf(stderr, "could not identify controller\n");
- err = -ENODEV;
+ errno = ENODEV;
+ err = -1;
goto close_fd;
}
@@ -1084,7 +1111,8 @@ static int get_endurance_event_agg_log(int argc, char **argv,
if (!endurance_log) {
perror("could not alloc buffer for endurance group" \
" event agggregate log entries\n");
- err = -ENOMEM;
+ errno = ENOMEM;
+ err = -1;
goto close_fd;
}
@@ -1114,7 +1142,7 @@ static int get_lba_status_log(int argc, char **argv,
const char *rae = "Retain an Asynchronous Event";
void *lab_status;
enum nvme_print_flags flags;
- int err, fd;
+ int err = -1, fd;
__u32 lslplen;
struct config {
@@ -1153,7 +1181,8 @@ static int get_lba_status_log(int argc, char **argv,
lab_status = calloc(lslplen, 1);
if (!lab_status) {
perror("could not alloc buffer for lba status log");
- err = -ENOMEM;
+ errno = ENOMEM;
+ err = -1;
goto close_fd;
}
@@ -1182,7 +1211,7 @@ static int get_resv_notif_log(int argc, char **argv,
"json or binary.";
struct nvme_resv_notif_log resv;
enum nvme_print_flags flags;
- int err, fd;
+ int err = -1, fd;
struct config {
char *output_format;
@@ -1231,12 +1260,17 @@ static int get_log(int argc, char **argv, struct command *cmd, struct plugin *pl
const char *aen = "result of the aen, use to override log id";
const char *lsp = "log specific field";
const char *lpo = "log page offset specifies the location within a log page from where to start returning data";
+ const char *lsi = "log specific identifier specifies an identifier that is required for a particular log page";
const char *rae = "retain an asynchronous event";
const char *raw = "output in raw format";
const char *uuid_index = "UUID index";
- int err, fd;
+ const char *csi = "command set identifier";
+ const char *offset_type = "offset type";
+ int err = -1, fd;
+ unsigned char *log;
struct config {
+ __u16 lsi;
__u32 namespace_id;
__u8 log_id;
__u32 log_len;
@@ -1244,6 +1278,8 @@ static int get_log(int argc, char **argv, struct command *cmd, struct plugin *pl
__u64 lpo;
__u8 lsp;
__u8 uuid_index;
+ __u8 csi;
+ int ot;
int rae;
int raw_binary;
};
@@ -1254,19 +1290,25 @@ static int get_log(int argc, char **argv, struct command *cmd, struct plugin *pl
.log_len = 0,
.lpo = NVME_NO_LOG_LPO,
.lsp = NVME_NO_LOG_LSP,
+ .lsi = 0,
.rae = 0,
.uuid_index = 0,
+ .csi = 0,
+ .ot = 0,
};
OPT_ARGS(opts) = {
OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
- OPT_UINT("log-id", 'i', &cfg.log_id, log_id),
+ OPT_BYTE("log-id", 'i', &cfg.log_id, log_id),
OPT_UINT("log-len", 'l', &cfg.log_len, log_len),
OPT_UINT("aen", 'a', &cfg.aen, aen),
- OPT_LONG("lpo", 'o', &cfg.lpo, lpo),
+ OPT_SUFFIX("lpo", 'o', &cfg.lpo, lpo),
OPT_BYTE("lsp", 's', &cfg.lsp, lsp),
+ OPT_SHRT("lsi", 'S', &cfg.lsi, lsi),
OPT_FLAG("rae", 'r', &cfg.rae, rae),
OPT_BYTE("uuid-index", 'U', &cfg.uuid_index, uuid_index),
+ OPT_BYTE("csi", 'y', &cfg.csi, csi),
+ OPT_FLAG("ot", 'O', &cfg.ot, offset_type),
OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw),
OPT_END()
};
@@ -1282,34 +1324,49 @@ static int get_log(int argc, char **argv, struct command *cmd, struct plugin *pl
if (!cfg.log_len) {
fprintf(stderr, "non-zero log-len is required param\n");
- err = -EINVAL;
- } else {
- unsigned char *log;
+ errno = EINVAL;
+ err = -1;
+ goto close_fd;
+ }
- log = malloc(cfg.log_len);
- if (!log) {
- perror("could not alloc buffer for log\n");
- err = -ENOMEM;
- goto close_fd;
- }
+ if (cfg.lsp > 128) {
+ fprintf(stderr, "invalid lsp param: %u\n", cfg.lsp);
+ errno = EINVAL;
+ err = -1;
+ goto close_fd;
+ }
- err = nvme_get_log14(fd, cfg.namespace_id, cfg.log_id,
- cfg.lsp, cfg.lpo, 0, cfg.rae,
- cfg.uuid_index, cfg.log_len, log);
- if (!err) {
- if (!cfg.raw_binary) {
- printf("Device:%s log-id:%d namespace-id:%#x\n",
- devicename, cfg.log_id,
- cfg.namespace_id);
- d(log, cfg.log_len, 16, 1);
- } else
- d_raw((unsigned char *)log, cfg.log_len);
- } else if (err > 0)
- nvme_show_status(err);
- else
- perror("log page");
- free(log);
+ if (cfg.uuid_index > 128) {
+ fprintf(stderr, "invalid uuid index param: %u\n", cfg.uuid_index);
+ errno = EINVAL;
+ err = -1;
+ goto close_fd;
}
+
+ log = malloc(cfg.log_len);
+ if (!log) {
+ perror("could not alloc buffer for log\n");
+ err = -ENOMEM;
+ goto close_fd;
+ }
+
+ err = nvme_get_log14(fd, cfg.namespace_id, cfg.log_id,
+ cfg.lsp, cfg.lpo, cfg.lsi, cfg.rae,
+ cfg.uuid_index, cfg.csi, cfg.ot, cfg.log_len, log);
+ if (!err) {
+ if (!cfg.raw_binary) {
+ printf("Device:%s log-id:%d namespace-id:%#x\n",
+ devicename, cfg.log_id,
+ cfg.namespace_id);
+ d(log, cfg.log_len, 16, 1);
+ } else
+ d_raw((unsigned char *)log, cfg.log_len);
+ } else if (err > 0)
+ nvme_show_status(err);
+ else
+ perror("log page");
+ free(log);
+
close_fd:
close(fd);
ret:
@@ -1324,7 +1381,7 @@ static int sanitize_log(int argc, char **argv, struct command *command, struct p
const char *human_readable = "show log in readable format";
struct nvme_sanitize_log_page sanitize_log;
enum nvme_print_flags flags;
- int fd, err;
+ int fd, err = -1;
struct config {
bool rae;
@@ -1377,21 +1434,25 @@ static int list_ctrl(int argc, char **argv, struct command *cmd, struct plugin *
"given device is part of, or optionally controllers attached to a specific namespace.";
const char *controller = "controller to display";
const char *namespace_id = "optional namespace attached to controller";
- int err, i, fd;
+ int err = -1, fd;
struct nvme_controller_list *cntlist;
+ enum nvme_print_flags flags;
struct config {
__u16 cntid;
__u32 namespace_id;
+ char *output_format;
};
struct config cfg = {
.cntid = 0,
+ .output_format = "normal",
};
OPT_ARGS(opts) = {
- OPT_SHRT("cntid", 'c', &cfg.cntid, controller),
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
+ OPT_SHRT("cntid", 'c', &cfg.cntid, controller),
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
+ OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
OPT_END()
};
@@ -1399,19 +1460,25 @@ static int list_ctrl(int argc, char **argv, struct command *cmd, struct plugin *
if (fd < 0)
goto ret;
+ err = flags = validate_output_format(cfg.output_format);
+ if (flags < 0)
+ goto close_fd;
+ if (flags != JSON && flags != NORMAL) {
+ err = -EINVAL;
+ goto close_fd;
+ }
+
if (posix_memalign((void *)&cntlist, getpagesize(), 0x1000)) {
fprintf(stderr, "can not allocate controller list payload\n");
- err = -ENOMEM;
+ errno = ENOMEM;
+ err = -1;
goto close_fd;
}
err = nvme_identify_ctrl_list(fd, cfg.namespace_id, cfg.cntid, cntlist);
- if (!err) {
- __u16 num = le16_to_cpu(cntlist->num);
-
- for (i = 0; i < (min(num, 2048)); i++)
- printf("[%4u]:%#x\n", i, le16_to_cpu(cntlist->identifier[i]));
- } else if (err > 0)
+ if (!err)
+ nvme_show_list_ctrl(cntlist, flags);
+ else if (err > 0)
nvme_show_status(err);
else
perror("id controller list");
@@ -1430,23 +1497,27 @@ static int list_ns(int argc, char **argv, struct command *cmd, struct plugin *pl
const char *namespace_id = "first nsid returned list should start from";
const char *csi = "I/O command set identifier";
const char *all = "show all namespaces in the subsystem, whether attached or inactive";
- int err, i, fd;
+ int err = -1, fd;
__le32 ns_list[1024];
+ enum nvme_print_flags flags;
struct config {
__u32 namespace_id;
int all;
- __u16 csi;
+ __u8 csi;
+ char *output_format;
};
struct config cfg = {
.namespace_id = 1,
+ .output_format = "normal",
};
OPT_ARGS(opts) = {
- OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
- OPT_BYTE("csi", 'y', &cfg.csi, csi),
- OPT_FLAG("all", 'a', &cfg.all, all),
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
+ OPT_BYTE("csi", 'y', &cfg.csi, csi),
+ OPT_FLAG("all", 'a', &cfg.all, all),
+ OPT_FMT("output-format", 'o', &cfg.output_format, output_format_no_binary),
OPT_END()
};
@@ -1454,19 +1525,26 @@ static int list_ns(int argc, char **argv, struct command *cmd, struct plugin *pl
if (fd < 0)
goto ret;
- if (!cfg.namespace_id) {
+ err = flags = validate_output_format(cfg.output_format);
+ if (flags < 0)
+ goto close_fd;
+ if (flags != JSON && flags != NORMAL) {
err = -EINVAL;
+ goto close_fd;
+ }
+
+ if (!cfg.namespace_id) {
+ errno = EINVAL;
+ err = -1;
fprintf(stderr, "invalid nsid parameter\n");
goto close_fd;
}
err = nvme_identify_ns_list_csi(fd, cfg.namespace_id - 1, cfg.csi,
!!cfg.all, ns_list);
- if (!err) {
- for (i = 0; i < 1024; i++)
- if (ns_list[i])
- printf("[%4u]:%#x\n", i, le32_to_cpu(ns_list[i]));
- } else if (err > 0)
+ if (!err)
+ nvme_show_list_ns(ns_list, flags);
+ else if (err > 0)
nvme_show_status(err);
else
perror("id namespace list");
@@ -1486,7 +1564,7 @@ static int delete_ns(int argc, char **argv, struct command *cmd, struct plugin *
"the namespace is not already inactive, once deleted.";
const char *namespace_id = "namespace to delete";
const char *timeout = "timeout value, in milliseconds";
- int err, fd;
+ int err = -1, fd;
struct config {
__u32 namespace_id;
@@ -1533,7 +1611,7 @@ ret:
static int nvme_attach_ns(int argc, char **argv, int attach, const char *desc, struct command *cmd)
{
- int err, num, i, fd, list[2048];
+ int err = -1, num, i, fd, list[2048];
__u16 ctrlist[2048];
const char *namespace_id = "namespace to attach";
@@ -1562,7 +1640,8 @@ static int nvme_attach_ns(int argc, char **argv, int attach, const char *desc, s
if (!cfg.namespace_id) {
fprintf(stderr, "%s: namespace-id parameter required\n",
cmd->name);
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
@@ -1574,7 +1653,8 @@ static int nvme_attach_ns(int argc, char **argv, int attach, const char *desc, s
if (num == -1) {
fprintf(stderr, "%s: controller id list is malformed\n",
cmd->name);
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
@@ -1635,7 +1715,7 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
const char *bs = "target block size, specify only if \'FLBAS\' "\
"value not entered";
- int err = 0, fd, i;
+ int err = -1, fd, i;
struct nvme_id_ns ns;
__u32 nsid;
@@ -1681,7 +1761,8 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
if (cfg.flbas != 0xff && cfg.bs != 0x00) {
fprintf(stderr,
"Invalid specification of both FLBAS and Block Size, please specify only one\n");
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
if (cfg.bs) {
@@ -1689,7 +1770,8 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
fprintf(stderr,
"Invalid value for block size (%"PRIu64"). Block size must be a power of two\n",
(uint64_t)cfg.bs);
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
err = nvme_identify_ns(fd, NVME_NSID_ALL, 0, &ns);
@@ -1717,7 +1799,8 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
fprintf(stderr,
"Please correct block size, or specify FLBAS directly\n");
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
@@ -1746,7 +1829,7 @@ static int list_subsys(int argc, char **argv, struct command *cmd,
const char *desc = "Retrieve information for subsystems";
const char *verbose = "Increase output verbosity";
__u32 ns_instance = 0;
- int err, nsid = 0;
+ int err = -1, nsid = 0;
struct config {
char *output_format;
@@ -1777,7 +1860,8 @@ static int list_subsys(int argc, char **argv, struct command *cmd,
if (sscanf(devicename, "nvme%dn%d", &id, &ns_instance) != 2) {
fprintf(stderr, "%s is not a NVMe namespace device\n",
argv[optind]);
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto ret;
}
sprintf(path, "/dev/%s", devicename);
@@ -1785,7 +1869,8 @@ static int list_subsys(int argc, char **argv, struct command *cmd,
if (fd < 0) {
fprintf(stderr, "Cannot read nsid from %s\n",
devicename);
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto ret;
}
nsid = nvme_get_nsid(fd);
@@ -1793,7 +1878,8 @@ static int list_subsys(int argc, char **argv, struct command *cmd,
if (nsid < 0) {
fprintf(stderr, "Cannot read nsid from %s\n",
devicename);
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto ret;
}
sprintf(path, "/sys/block/%s/device", devicename);
@@ -1801,7 +1887,8 @@ static int list_subsys(int argc, char **argv, struct command *cmd,
if (!subsysnqn) {
fprintf(stderr, "Cannot read subsys NQN from %s\n",
devicename);
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto ret;
}
optind++;
@@ -1811,7 +1898,8 @@ static int list_subsys(int argc, char **argv, struct command *cmd,
if (flags < 0)
goto free;
if (flags != JSON && flags != NORMAL) {
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto free;
}
if (cfg.verbose)
@@ -1837,7 +1925,7 @@ static int list(int argc, char **argv, struct command *cmd, struct plugin *plugi
const char *verbose = "Increase output verbosity";
struct nvme_topology t = { };
enum nvme_print_flags flags;
- int err = 0;
+ int err = -1;
struct config {
char *device_dir;
@@ -1896,7 +1984,7 @@ int __id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin,
const char *human_readable = "show identify in readable format";
enum nvme_print_flags flags;
struct nvme_id_ctrl ctrl;
- int err, fd;
+ int err = -1, fd;
struct config {
int vendor_specific;
@@ -2001,7 +2089,7 @@ static int ns_descs(int argc, char **argv, struct command *cmd, struct plugin *p
const char *raw = "show descriptors in binary format";
const char *namespace_id = "identifier of desired namespace";
enum nvme_print_flags flags;
- int err, fd;
+ int err = -1, fd;
void *nsdescs;
struct config {
@@ -2042,7 +2130,8 @@ static int ns_descs(int argc, char **argv, struct command *cmd, struct plugin *p
if (posix_memalign(&nsdescs, getpagesize(), 0x1000)) {
fprintf(stderr, "can not allocate controller list payload\n");
- err = -ENOMEM;
+ errno = ENOMEM;
+ err = -1;
goto close_fd;
}
@@ -2074,7 +2163,7 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug
enum nvme_print_flags flags;
struct nvme_id_ns ns;
- int err, fd;
+ int err = -1, fd;
struct config {
__u32 namespace_id;
@@ -2143,7 +2232,7 @@ static int id_ns_granularity(int argc, char **argv, struct command *cmd, struct
struct nvme_id_ns_granularity_list *granularity_list;
enum nvme_print_flags flags;
- int err, fd;
+ int err = -1, fd;
struct config {
char *output_format;
@@ -2168,7 +2257,8 @@ static int id_ns_granularity(int argc, char **argv, struct command *cmd, struct
if (posix_memalign((void *)&granularity_list, getpagesize(), NVME_IDENTIFY_DATA_SIZE)) {
fprintf(stderr, "can not allocate granularity list payload\n");
- err = -ENOMEM;
+ errno = ENOMEM;
+ err = -1;
goto close_fd;
}
@@ -2196,7 +2286,7 @@ static int id_nvmset(int argc, char **argv, struct command *cmd, struct plugin *
struct nvme_id_nvmset nvmset;
enum nvme_print_flags flags;
- int err, fd;
+ int err = -1, fd;
struct config {
__u16 nvmset_id;
@@ -2209,7 +2299,7 @@ static int id_nvmset(int argc, char **argv, struct command *cmd, struct plugin *
};
OPT_ARGS(opts) = {
- OPT_UINT("nvmset_id", 'i', &cfg.nvmset_id, nvmset_id),
+ OPT_SHRT("nvmset_id", 'i', &cfg.nvmset_id, nvmset_id),
OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
OPT_END()
};
@@ -2246,7 +2336,7 @@ static int id_uuid(int argc, char **argv, struct command *cmd, struct plugin *pl
struct nvme_id_uuid_list uuid_list;
enum nvme_print_flags flags;
- int err, fd;
+ int err = -1, fd;
struct config {
int raw_binary;
@@ -2265,9 +2355,9 @@ static int id_uuid(int argc, char **argv, struct command *cmd, struct plugin *pl
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
+ err = fd = parse_and_open(argc, argv, desc, opts);
if (fd < 0)
- return fd;
+ goto ret;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
@@ -2286,7 +2376,8 @@ static int id_uuid(int argc, char **argv, struct command *cmd, struct plugin *pl
perror("identify UUID list");
close_fd:
close(fd);
- return err;
+ret:
+ return nvme_status_to_errno(err, false);;
}
static int id_iocs(int argc, char **argv, struct command *cmd, struct plugin *plugin)
@@ -2295,19 +2386,26 @@ static int id_iocs(int argc, char **argv, struct command *cmd, struct plugin *pl
"given device, returns properties of the specified controller "\
"in either human-readable or binary format.";
const char *controller_id = "identifier of desired controller";
+ const char *human_readable = "show info in human readable format";
struct nvme_id_iocs iocs;
+ enum nvme_print_flags flags;
int err, fd;
struct config {
__u16 cntid;
+ char *output_format;
+ int human_readable;
};
struct config cfg = {
.cntid = 0xffff,
+ .output_format = "normal",
};
OPT_ARGS(opts) = {
- OPT_SHRT("controller-id", 'c', &cfg.cntid, controller_id),
+ OPT_SHRT("controller-id", 'c', &cfg.cntid, controller_id),
+ OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
+ OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable),
OPT_END()
};
@@ -2317,15 +2415,73 @@ static int id_iocs(int argc, char **argv, struct command *cmd, struct plugin *pl
goto ret;
}
+ err = flags = validate_output_format(cfg.output_format);
+ if (flags < 0)
+ goto close_fd;
+ if (cfg.human_readable)
+ flags |= VERBOSE;
+
err = nvme_identify_iocs(fd, cfg.cntid, &iocs);
if (!err) {
printf("NVMe Identify I/O Command Set:\n");
- nvme_show_id_iocs(&iocs);
+ nvme_show_id_iocs(&iocs, flags);
} else if (err > 0)
nvme_show_status(err);
else
perror("NVMe Identify I/O Command Set");
+close_fd:
+ close(fd);
+ret:
+ return nvme_status_to_errno(err, false);
+}
+
+static int id_domain(int argc, char **argv, struct command *cmd, struct plugin *plugin) {
+ const char *desc = "Send an Identify Domain List command to the "\
+ "given device, returns properties of the specified domain "\
+ "in either normal|json|binary format.";
+ const char *domain_id = "identifier of desired domain";
+ struct nvme_id_domain_list id_domain;
+ enum nvme_print_flags flags;
+ int err, fd;
+
+ struct config {
+ __u16 dom_id;
+ char *output_format;
+ };
+
+ struct config cfg = {
+ .dom_id = 0xffff,
+ .output_format = "normal",
+ };
+
+ OPT_ARGS(opts) = {
+ OPT_SHRT("dom-id", 'd', &cfg.dom_id, domain_id),
+ OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
+ OPT_END()
+ };
+
+ fd = parse_and_open(argc, argv, desc, opts);
+ if (fd < 0) {
+ err = fd;
+ goto ret;
+ }
+
+ err = flags = validate_output_format(cfg.output_format);
+ if (flags < 0)
+ goto close_fd;
+
+ err = nvme_identify_domain_list(fd, cfg.dom_id, &id_domain);
+ if (!err) {
+ printf("NVMe Identify command for Domain List is successful:\n");
+ printf("NVMe Identify Domain List:\n");
+ nvme_show_id_domain_list(&id_domain, flags);
+ } else if (err > 0)
+ nvme_show_status(err);
+ else
+ perror("NVMe Identify Domain List");
+
+close_fd:
close(fd);
ret:
return nvme_status_to_errno(err, false);
@@ -2376,7 +2532,7 @@ static int virtual_mgmt(int argc, char **argv, struct command *cmd, struct plugi
"8h: Secondary Assign\n"\
"9h: Secondary Online";
const char *nr = "Number of Controller Resources(NR)";
- int fd, err;
+ int fd, err = -1;
__u32 result, cdw10;
struct config {
@@ -2395,9 +2551,9 @@ static int virtual_mgmt(int argc, char **argv, struct command *cmd, struct plugi
OPT_ARGS(opts) = {
OPT_UINT("cntlid", 'c', &cfg.cntlid, cntlid),
- OPT_UINT("rt", 'r', &cfg.rt, rt),
- OPT_UINT("act", 'a', &cfg.act, act),
- OPT_UINT("nr", 'n', &cfg.nr, nr),
+ OPT_BYTE("rt", 'r', &cfg.rt, rt),
+ OPT_BYTE("act", 'a', &cfg.act, act),
+ OPT_SHRT("nr", 'n', &cfg.nr, nr),
OPT_END()
};
@@ -2429,7 +2585,7 @@ static int primary_ctrl_caps(int argc, char **argv, struct command *cmd, struct
const char *human_readable = "show info in readable format";
struct nvme_primary_ctrl_caps caps;
- int err, fd;
+ int err = -1, fd;
enum nvme_print_flags flags;
struct config {
@@ -2480,7 +2636,7 @@ static int list_secondary_ctrl(int argc, char **argv, struct command *cmd, struc
struct nvme_secondary_controllers_list *sc_list;
enum nvme_print_flags flags;
- int err, fd;
+ int err = -1, fd;
struct config {
__u16 cntid;
@@ -2514,13 +2670,15 @@ static int list_secondary_ctrl(int argc, char **argv, struct command *cmd, struc
if (!cfg.num_entries) {
fprintf(stderr, "non-zero num-entries is required param\n");
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
if (posix_memalign((void *)&sc_list, getpagesize(), sizeof(*sc_list))) {
fprintf(stderr, "can not allocate controller list payload\n");
- err = -ENOMEM;
+ errno = ENOMEM;
+ err = -1;
goto close_fd;
}
@@ -2551,7 +2709,7 @@ static int device_self_test(int argc, char **argv, struct command *cmd, struct p
"2h Start a extended device self-test operation\n"\
"eh Start a vendor specific device self-test operation\n"\
"fh abort the device self-test operation\n";
- int fd, err;
+ int fd, err = -1;
struct config {
__u32 namespace_id;
@@ -2565,7 +2723,7 @@ static int device_self_test(int argc, char **argv, struct command *cmd, struct p
OPT_ARGS(opts) = {
OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
- OPT_UINT("self-test-code", 's', &cfg.stc, self_test_code),
+ OPT_BYTE("self-test-code", 's', &cfg.stc, self_test_code),
OPT_END()
};
@@ -2602,7 +2760,7 @@ static int self_test_log(int argc, char **argv, struct command *cmd, struct plug
struct nvme_self_test_log self_test_log;
enum nvme_print_flags flags;
- int err, fd;
+ int err = -1, fd;
__u32 log_size;
struct config {
@@ -2617,7 +2775,7 @@ static int self_test_log(int argc, char **argv, struct command *cmd, struct plug
};
OPT_ARGS(opts) = {
- OPT_UINT("dst-entries", 'e', &cfg.dst_entries, dst_entries),
+ OPT_BYTE("dst-entries", 'e', &cfg.dst_entries, dst_entries),
OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
OPT_FLAG("verbose", 'v', &cfg.verbose, verbose),
OPT_END()
@@ -2666,7 +2824,8 @@ static int get_feature(int argc, char **argv, struct command *cmd, struct plugin
const char *data_len = "buffer len if data is returned through host memory buffer";
const char *cdw11 = "dword 11 for interrupt vector config";
const char *human_readable = "show feature in readable format";
- int err, fd;
+ const char *uuid_index = "specify uuid index";
+ int err = -1, fd;
__u32 result;
void *buf = NULL;
@@ -2675,6 +2834,7 @@ static int get_feature(int argc, char **argv, struct command *cmd, struct plugin
__u8 feature_id;
__u8 sel;
__u32 cdw11;
+ __u8 uuid_index;
__u32 data_len;
int raw_binary;
int human_readable;
@@ -2685,16 +2845,18 @@ static int get_feature(int argc, char **argv, struct command *cmd, struct plugin
.feature_id = 0,
.sel = 0,
.cdw11 = 0,
+ .uuid_index = 0,
.data_len = 0,
};
OPT_ARGS(opts) = {
OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
- OPT_UINT("feature-id", 'f', &cfg.feature_id, feature_id),
+ OPT_BYTE("feature-id", 'f', &cfg.feature_id, feature_id),
OPT_BYTE("sel", 's', &cfg.sel, sel),
OPT_UINT("data-len", 'l', &cfg.data_len, data_len),
OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw),
OPT_UINT("cdw11", 'c', &cfg.cdw11, cdw11),
+ OPT_BYTE("uuid-index", 'U', &cfg.uuid_index, uuid_index),
OPT_FLAG("human-readable",'H', &cfg.human_readable, human_readable),
OPT_END()
};
@@ -2717,16 +2879,26 @@ static int get_feature(int argc, char **argv, struct command *cmd, struct plugin
if (cfg.sel > 7) {
fprintf(stderr, "invalid 'select' param:%d\n", cfg.sel);
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
if (!cfg.feature_id) {
fprintf(stderr, "feature-id required param\n");
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
- cfg.data_len = nvme_feat_buf_len[cfg.feature_id];
+ if (cfg.uuid_index > 128) {
+ fprintf(stderr, "invalid uuid index param: %u\n", cfg.uuid_index);
+ errno = EINVAL;
+ err = -1;
+ goto close_fd;
+ }
+
+ if (!cfg.data_len)
+ cfg.data_len = nvme_feat_buf_len[cfg.feature_id];
/* check for Extended Host Identifier */
if (cfg.feature_id == NVME_FEAT_HOST_ID && (cfg.cdw11 & 0x1))
@@ -2738,19 +2910,22 @@ static int get_feature(int argc, char **argv, struct command *cmd, struct plugin
if (cfg.data_len) {
if (posix_memalign(&buf, getpagesize(), cfg.data_len)) {
fprintf(stderr, "can not allocate feature payload\n");
- err = -ENOMEM;
+ errno = ENOMEM;
+ err = -1;
goto close_fd;
}
memset(buf, 0, cfg.data_len);
}
err = nvme_get_feature(fd, cfg.namespace_id, cfg.feature_id, cfg.sel, cfg.cdw11,
- cfg.data_len, buf, &result);
+ cfg.uuid_index, cfg.data_len, buf, &result);
if (!err) {
if (!cfg.raw_binary || !buf) {
- printf("get-feature:%#02x (%s), %s value:%#08x\n", cfg.feature_id,
- nvme_feature_to_string(cfg.feature_id),
- nvme_select_to_string(cfg.sel), result);
+ printf("get-feature:%#0*x (%s), %s value:%#0*x\n",
+ cfg.feature_id ? 4 : 2, cfg.feature_id,
+ nvme_feature_to_string(cfg.feature_id),
+ nvme_select_to_string(cfg.sel), result ? 10 : 8,
+ result);
if (cfg.sel == 3)
nvme_show_select_result(result);
else if (cfg.human_readable)
@@ -2785,7 +2960,7 @@ static int fw_download(int argc, char **argv, struct command *cmd, struct plugin
const char *fw = "firmware file (required)";
const char *xfer = "transfer chunksize limit";
const char *offset = "starting dword offset, default 0";
- int err, fd, fw_fd = -1;
+ int err = -1, fd, fw_fd = -1;
unsigned int fw_size;
struct stat sb;
void *fw_buf, *buf;
@@ -2819,7 +2994,8 @@ static int fw_download(int argc, char **argv, struct command *cmd, struct plugin
if (fw_fd < 0) {
fprintf(stderr, "Failed to open firmware file %s: %s\n",
cfg.fw, strerror(errno));
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
@@ -2832,7 +3008,8 @@ static int fw_download(int argc, char **argv, struct command *cmd, struct plugin
fw_size = sb.st_size;
if ((fw_size & 0x3) || (fw_size == 0)) {
fprintf(stderr, "Invalid size:%d for f/w image\n", fw_size);
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fw_fd;
}
@@ -2846,7 +3023,8 @@ static int fw_download(int argc, char **argv, struct command *cmd, struct plugin
if (!fw_buf) {
perror("No memory for f/w size:\n");
- err = -ENOMEM;
+ errno = ENOMEM;
+ err = -1;
goto close_fw_fd;
}
@@ -2905,7 +3083,8 @@ static int fw_commit(int argc, char **argv, struct command *cmd, struct plugin *
const char *slot = "[0-7]: firmware slot for commit action";
const char *action = "[0-7]: commit action";
const char *bpid = "[0,1]: boot partition identifier, if applicable (default: 0)";
- int err, fd;
+ int err = -1, fd;
+ __u32 result;
struct config {
__u8 slot;
@@ -2932,21 +3111,24 @@ static int fw_commit(int argc, char **argv, struct command *cmd, struct plugin *
if (cfg.slot > 7) {
fprintf(stderr, "invalid slot:%d\n", cfg.slot);
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
if (cfg.action > 7 || cfg.action == 4 || cfg.action == 5) {
fprintf(stderr, "invalid action:%d\n", cfg.action);
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
if (cfg.bpid > 1) {
fprintf(stderr, "invalid boot partition id:%d\n", cfg.bpid);
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
- err = nvme_fw_commit(fd, cfg.slot, cfg.action, cfg.bpid);
+ err = nvme_fw_commit(fd, cfg.slot, cfg.action, cfg.bpid, &result);
if (err < 0)
perror("fw-commit");
else if (err != 0)
@@ -2972,6 +3154,16 @@ static int fw_commit(int argc, char **argv, struct command *cmd, struct plugin *
printf("\n");
}
+ if (err >= 0) {
+ printf("Multiple Update Detected (MUD) Value: %u\n", result);
+ if (result & 0x1)
+ printf("Detected an overlapping firmware/boot partition image update command "\
+ "sequence due to processing a command from a Management Endpoint");
+ if ((result >> 1) & 0x1)
+ printf("Detected an overlapping firmware/boot partition image update command "\
+ "sequence due to processing a command from an Admin SQ on a controller");
+ }
+
close_fd:
close(fd);
ret:
@@ -2981,7 +3173,7 @@ ret:
static int subsystem_reset(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
const char *desc = "Resets the NVMe subsystem\n";
- int err, fd;
+ int err = -1, fd;
OPT_ARGS(opts) = {
OPT_END()
@@ -3008,7 +3200,7 @@ ret:
static int reset(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
const char *desc = "Resets the NVMe controller\n";
- int err, fd;
+ int err = -1, fd;
OPT_ARGS(opts) = {
OPT_END()
@@ -3059,7 +3251,7 @@ static int sanitize(int argc, char **argv, struct command *cmd, struct plugin *p
const char *sanact_desc = "Sanitize action.";
const char *ovrpat_desc = "Overwrite pattern.";
- int fd, ret;
+ int fd, ret = -1;
struct config {
int no_dealloc;
@@ -3101,14 +3293,16 @@ static int sanitize(int argc, char **argv, struct command *cmd, struct plugin *p
break;
default:
fprintf(stderr, "Invalid Sanitize Action\n");
- ret = -EINVAL;
+ errno = EINVAL;
+ ret = -1;
goto close_fd;
}
if (cfg.sanact == NVME_SANITIZE_ACT_EXIT) {
if (cfg.ause || cfg.no_dealloc) {
fprintf(stderr, "SANACT is Exit Failure Mode\n");
- ret = -EINVAL;
+ errno = EINVAL;
+ ret = -1;
goto close_fd;
}
}
@@ -3116,13 +3310,15 @@ static int sanitize(int argc, char **argv, struct command *cmd, struct plugin *p
if (cfg.sanact == NVME_SANITIZE_ACT_OVERWRITE) {
if (cfg.owpass >= 16) {
fprintf(stderr, "OWPASS out of range [0-15]\n");
- ret = -EINVAL;
+ errno = EINVAL;
+ ret = -1;
goto close_fd;
}
} else {
if (cfg.owpass || cfg.oipbp || cfg.ovrpat) {
fprintf(stderr, "SANACT is not Overwrite\n");
- ret = -EINVAL;
+ errno = EINVAL;
+ ret = -1;
goto close_fd;
}
}
@@ -3149,7 +3345,7 @@ static int show_registers(int argc, char **argv, struct command *cmd, struct plu
enum nvme_print_flags flags;
bool fabrics = true;
- int fd, err;
+ int fd, err = -1;
void *bar;
struct config {
@@ -3207,7 +3403,7 @@ static int get_property(int argc, char **argv, struct command *cmd, struct plugi
const char *offset = "offset of the requested property";
const char *human_readable = "show property in readable format";
- int fd, err;
+ int fd, err = -1;
uint64_t value;
struct config {
@@ -3232,7 +3428,8 @@ static int get_property(int argc, char **argv, struct command *cmd, struct plugi
if (cfg.offset == -1) {
fprintf(stderr, "offset required param\n");
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
@@ -3257,7 +3454,7 @@ static int set_property(int argc, char **argv, struct command *cmd, struct plugi
"for NVMe ove Fabric";
const char *offset = "the offset of the property";
const char *value = "the value of the property to be set";
- int fd, err;
+ int fd, err = -1;
struct config {
int offset;
@@ -3281,12 +3478,14 @@ static int set_property(int argc, char **argv, struct command *cmd, struct plugi
if (cfg.offset == -1) {
fprintf(stderr, "offset required param\n");
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
if (cfg.value == -1) {
fprintf(stderr, "value required param\n");
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
@@ -3313,7 +3512,8 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
"data erase) or delete data encryption key if specified. "\
"Can also be used to change LBAF to change the namespaces reported physical block format.";
const char *namespace_id = "identifier of desired namespace";
- const char *lbaf = "LBA format to apply (required)";
+ const char *lbaf = "[0-63]: LBA format lower (LBAFL) and upper (LBAFU), "\
+ "mention directly LBAF format that needs be applied (required)";
const char *ses = "[0-2]: secure erase";
const char *pil = "[0-1]: protection info location last/first 8 bytes of metadata";
const char *pi = "[0-3]: protection info off/Type 1/Type 2/Type 3";
@@ -3324,7 +3524,7 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
const char *force = "The \"I know what I'm doing\" flag, skip confirmation before sending command";
struct nvme_id_ns ns;
struct nvme_id_ctrl ctrl;
- int err, fd, i;
+ int err = -1, fd, i;
int block_size;
__u8 prev_lbaf = 0;
@@ -3373,7 +3573,8 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
if (cfg.lbaf != 0xff && cfg.bs !=0) {
fprintf(stderr,
"Invalid specification of both LBAF and Block Size, please specify only one\n");
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
if (cfg.bs) {
@@ -3381,7 +3582,8 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
fprintf(stderr,
"Invalid value for block size (%"PRIu64"), must be a power of two\n",
(uint64_t) cfg.bs);
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
}
@@ -3412,7 +3614,8 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
"Invalid namespace ID, "
"specify a namespace to format or use '-n 0xffffffff' "
"to format all namespaces on this controller.\n");
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
@@ -3443,7 +3646,8 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
(uint64_t)cfg.bs);
fprintf(stderr,
"Please correct block size, or specify LBAF directly\n");
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
} else if (cfg.lbaf == 0xff)
@@ -3455,27 +3659,32 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
/* ses & pi checks set to 7 for forward-compatibility */
if (cfg.ses > 7) {
fprintf(stderr, "invalid secure erase settings:%d\n", cfg.ses);
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
- if (cfg.lbaf > 15) {
+ if (cfg.lbaf > 63) {
fprintf(stderr, "invalid lbaf:%d\n", cfg.lbaf);
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
if (cfg.pi > 7) {
fprintf(stderr, "invalid pi:%d\n", cfg.pi);
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
if (cfg.pil > 1) {
fprintf(stderr, "invalid pil:%d\n", cfg.pil);
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
if (cfg.ms > 1) {
fprintf(stderr, "invalid ms:%d\n", cfg.ms);
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
@@ -3561,12 +3770,11 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
const char *value = "new value of feature (required)";
const char *cdw12 = "feature cdw12, if used";
const char *save = "specifies that the controller shall save the attribute";
- int err;
+ const char *uuid_index = "specify uuid index";
+ int err = -1;
__u32 result;
void *buf = NULL;
int fd, ffd = STDIN_FILENO;
- char *endptr = NULL;
- uint64_t number = 0;
struct config {
char *file;
@@ -3574,6 +3782,7 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
__u8 feature_id;
__u64 value;
__u32 cdw12;
+ __u8 uuid_index;
__u32 data_len;
int save;
};
@@ -3583,15 +3792,17 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
.namespace_id = 0,
.feature_id = 0,
.value = 0,
+ .uuid_index = 0,
.data_len = 0,
.save = 0,
};
OPT_ARGS(opts) = {
OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
- OPT_UINT("feature-id", 'f', &cfg.feature_id, feature_id),
- OPT_LONG("value", 'v', &cfg.value, value),
+ OPT_BYTE("feature-id", 'f', &cfg.feature_id, feature_id),
+ OPT_SUFFIX("value", 'v', &cfg.value, value),
OPT_UINT("cdw12", 'c', &cfg.cdw12, cdw12),
+ OPT_BYTE("uuid-index", 'U', &cfg.uuid_index, uuid_index),
OPT_UINT("data-len", 'l', &cfg.data_len, data_len),
OPT_FILE("data", 'd', &cfg.file, data),
OPT_FLAG("save", 's', &cfg.save, save),
@@ -3616,59 +3827,72 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
if (!cfg.feature_id) {
fprintf(stderr, "feature-id required param\n");
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
- cfg.data_len = nvme_feat_buf_len[cfg.feature_id];
+ if (cfg.uuid_index > 128) {
+ fprintf(stderr, "invalid uuid index param: %u\n", cfg.uuid_index);
+ errno = EINVAL;
+ err = -1;
+ goto close_fd;
+ }
+
+ if (!cfg.data_len)
+ cfg.data_len = nvme_feat_buf_len[cfg.feature_id];
if (cfg.data_len) {
if (posix_memalign(&buf, getpagesize(), cfg.data_len)) {
fprintf(stderr, "can not allocate feature payload\n");
- err = -ENOMEM;
+ errno = ENOMEM;
+ err = -1;
goto close_fd;
}
memset(buf, 0, cfg.data_len);
}
if (buf) {
- /* if feature ID is 0x0E, get timestamp value by -v option */
- if (NVME_FEAT_TIMESTAMP == cfg.feature_id && cfg.value) {
- memcpy(buf, &cfg.value, NVME_FEAT_TIMESTAMP_DATA_SIZE);
- } else {
- if (strlen(cfg.file)) {
- ffd = open(cfg.file, O_RDONLY);
- if (ffd <= 0) {
- fprintf(stderr, "Failed to open file %s: %s\n",
- cfg.file, strerror(errno));
- err = -EINVAL;
- goto free;
- }
- }
- err = read(ffd, (void *)buf, cfg.data_len);
- if (err < 0) {
- err = -errno;
- fprintf(stderr, "failed to read data buffer from input"
- " file: %s\n", strerror(errno));
- goto close_ffd;
- }
- /* if feature ID is 0x0E, then change string from file to integer */
- if (NVME_FEAT_TIMESTAMP == cfg.feature_id) {
- number = strtoul(buf, &endptr, STRTOUL_AUTO_BASE);
- memset(buf, 0, cfg.data_len);
- memcpy(buf, &number, NVME_FEAT_TIMESTAMP_DATA_SIZE);
- }
- }
+ /*
+ * Use the '-v' value for the timestamp feature if provided as
+ * a convenience since it can often fit in 4-bytes. The user
+ * should use the buffer method if the value exceeds this
+ * length.
+ */
+ if (NVME_FEAT_TIMESTAMP == cfg.feature_id && cfg.value) {
+ memcpy(buf, &cfg.value, NVME_FEAT_TIMESTAMP_DATA_SIZE);
+ } else {
+ if (strlen(cfg.file)) {
+ ffd = open(cfg.file, O_RDONLY);
+ if (ffd <= 0) {
+ errno = EINVAL;
+ fprintf(stderr, "Failed to open file %s: %s\n",
+ cfg.file, strerror(errno));
+ err = -1;
+ goto free;
+ }
+ }
+
+ err = read(ffd, (void *)buf, cfg.data_len);
+ if (err < 0) {
+ err = -errno;
+ fprintf(stderr, "failed to read data buffer from input"
+ " file: %s\n", strerror(errno));
+ goto close_ffd;
+ }
+ }
}
err = nvme_set_feature(fd, cfg.namespace_id, cfg.feature_id, cfg.value,
- cfg.cdw12, cfg.save, cfg.data_len, buf, &result);
+ cfg.cdw12, cfg.save, cfg.uuid_index, cfg.data_len, buf, &result);
if (err < 0) {
perror("set-feature");
} else if (!err) {
- printf("set-feature:%#02x (%s), value:%#08"PRIx64", cdw12:%#08"PRIx32", \
- save:%#x\n", cfg.feature_id, nvme_feature_to_string(cfg.feature_id),
- (uint64_t)cfg.value, cfg.cdw12, cfg.save);
+ printf("set-feature:%#0*x (%s), value:%#0*"PRIx64", cdw12:%#0*x, save:%#x\n",
+ cfg.feature_id ? 4 : 2, cfg.feature_id,
+ nvme_feature_to_string(cfg.feature_id),
+ cfg.value ? 10 : 8, (uint64_t)cfg.value,
+ cfg.cdw12 ? 10 : 8, cfg.cdw12, cfg.save);
if (cfg.feature_id == NVME_LBA_STATUS_INFO) {
nvme_show_lba_status_info(result);
}
@@ -3706,7 +3930,7 @@ static int sec_send(int argc, char **argv, struct command *cmd, struct plugin *p
const char *tl = "transfer length (cf. SPC-4)";
const char *namespace_id = "desired namespace";
const char *nssf = "NVMe Security Specific Field";
- int err, fd, sec_fd = -1;
+ int err = -1, fd, sec_fd = -1;
void *sec_buf;
unsigned int sec_size;
@@ -3740,27 +3964,55 @@ static int sec_send(int argc, char **argv, struct command *cmd, struct plugin *p
if (fd < 0)
goto ret;
+ if (cfg.tl == 0) {
+ fprintf(stderr, "--tl unspecified or zero\n");
+ err = -EINVAL;
+ goto close_fd;
+ }
+
sec_fd = open(cfg.file, O_RDONLY);
if (sec_fd < 0) {
fprintf(stderr, "Failed to open %s: %s\n",
cfg.file, strerror(errno));
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
- err = fstat(sec_fd, &sb);
- if (err < 0) {
- perror("fstat");
- goto close_sec_fd;
+ if ((cfg.tl & 3) != 0)
+ fprintf(stderr, "WARNING: --tl not dword aligned; unaligned bytes may be truncated\n");
+
+ if (strlen(cfg.file) == 0) {
+ sec_fd = STDIN_FILENO;
+ sec_size = cfg.tl;
+ } else {
+ sec_fd = open(cfg.file, O_RDONLY);
+ if (sec_fd < 0) {
+ fprintf(stderr, "Failed to open %s: %s\n",
+ cfg.file, strerror(errno));
+ err = -EINVAL;
+ goto close_fd;
+ }
+
+ err = fstat(sec_fd, &sb);
+ if (err < 0) {
+ perror("fstat");
+ goto close_sec_fd;
+ }
+
+ sec_size = cfg.tl > sb.st_size ? cfg.tl : sb.st_size;
}
sec_size = sb.st_size;
if (posix_memalign(&sec_buf, getpagesize(), sec_size)) {
fprintf(stderr, "No memory for security size:%d\n", sec_size);
- err = -ENOMEM;
+ errno = ENOMEM;
+ err = -1;
goto close_sec_fd;
}
+ memset(sec_buf, 0, cfg.tl); // ensure zero fill if cfg.tl > sec_size
+
err = read(sec_fd, sec_buf, sec_size);
if (err < 0) {
err = -errno;
@@ -3770,7 +4022,7 @@ static int sec_send(int argc, char **argv, struct command *cmd, struct plugin *p
}
err = nvme_sec_send(fd, cfg.namespace_id, cfg.nssf, cfg.spsp, cfg.secp,
- cfg.tl, sec_size, sec_buf);
+ cfg.tl, sec_buf);
if (err < 0)
perror("security-send");
else if (err != 0)
@@ -3801,7 +4053,7 @@ static int dir_send(int argc, char **argv, struct command *cmd, struct plugin *p
const char *endir = "directive enable";
const char *ttype = "target directive type to be enabled/disabled";
const char *human_readable = "show directive in readable format";
- int err, fd;
+ int err = -1, fd;
__u32 result;
__u32 dw12 = 0;
void *buf = NULL;
@@ -3854,14 +4106,16 @@ static int dir_send(int argc, char **argv, struct command *cmd, struct plugin *p
case NVME_DIR_SND_ID_OP_ENABLE:
if (!cfg.ttype) {
fprintf(stderr, "target-dir required param\n");
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
dw12 = cfg.ttype << 8 | cfg.endir;
break;
default:
fprintf(stderr, "invalid directive operations for Identify Directives\n");
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
break;
@@ -3872,20 +4126,23 @@ static int dir_send(int argc, char **argv, struct command *cmd, struct plugin *p
break;
default:
fprintf(stderr, "invalid directive operations for Streams Directives\n");
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
break;
default:
fprintf(stderr, "invalid directive type\n");
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
if (cfg.data_len) {
if (posix_memalign(&buf, getpagesize(), cfg.data_len)) {
- err = -ENOMEM;
+ errno = ENOMEM;
+ err = -1;
goto close_fd;
}
memset(buf, 0, cfg.data_len);
@@ -3897,7 +4154,8 @@ static int dir_send(int argc, char **argv, struct command *cmd, struct plugin *p
if (ffd <= 0) {
fprintf(stderr, "Failed to open file %s: %s\n",
cfg.file, strerror(errno));
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto free;
}
}
@@ -3940,7 +4198,7 @@ ret:
static int write_uncor(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- int err, fd;
+ int err = -1, fd;
const char *desc = "The Write Uncorrectable command is used to set a "\
"range of logical blocks to invalid.";
const char *namespace_id = "desired namespace";
@@ -3995,7 +4253,7 @@ ret:
static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- int err, fd;
+ int err = -1, fd;
__u16 control = 0;
const char *desc = "The Write Zeroes command is used to set a "\
"range of logical blocks to zero.";
@@ -4008,7 +4266,11 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi
const char *ref_tag = "reference tag (for end to end PI)";
const char *app_tag_mask = "app tag mask (for end to end PI)";
const char *app_tag = "app tag (for end to end PI)";
+ const char *storage_tag = "storage tag, CDW2 and CDW3 (00:47) bits "\
+ "(for end to end PI)";
const char *deac = "Set DEAC bit, requesting controller to deallocate specified logical blocks";
+ const char *storage_tag_check = "This bit specifies the Storage Tag field shall be checked as "\
+ "part of end-to-end data protection processing";
struct config {
__u64 start_block;
@@ -4018,18 +4280,22 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi
__u16 app_tag_mask;
__u16 block_count;
__u8 prinfo;
+ __u64 storage_tag;
int deac;
int limited_retry;
int force_unit_access;
+ int storage_tag_check;
};
struct config cfg = {
- .start_block = 0,
- .block_count = 0,
- .prinfo = 0,
- .ref_tag = 0,
- .app_tag_mask = 0,
- .app_tag = 0,
+ .start_block = 0,
+ .block_count = 0,
+ .prinfo = 0,
+ .ref_tag = 0,
+ .app_tag_mask = 0,
+ .app_tag = 0,
+ .storage_tag = 0,
+ .storage_tag_check = 0,
};
OPT_ARGS(opts) = {
@@ -4043,6 +4309,8 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi
OPT_UINT("ref-tag", 'r', &cfg.ref_tag, ref_tag),
OPT_SHRT("app-tag-mask", 'm', &cfg.app_tag_mask, app_tag_mask),
OPT_SHRT("app-tag", 'a', &cfg.app_tag, app_tag),
+ OPT_SUFFIX("storage-tag", 'S', &cfg.storage_tag, storage_tag),
+ OPT_FLAG("storage-tag-check", 'C', &cfg.storage_tag_check, storage_tag_check),
OPT_END()
};
@@ -4051,7 +4319,9 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi
goto ret;
if (cfg.prinfo > 0xf) {
- err = -EINVAL;
+ fprintf(stderr, "invalid prinfo: %u\n", cfg.prinfo);
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
@@ -4062,6 +4332,8 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi
control |= NVME_RW_FUA;
if (cfg.deac)
control |= NVME_RW_DEAC;
+ if (cfg.storage_tag_check)
+ control |= NVME_RW_STORAGE_TAG_CHECK;
if (!cfg.namespace_id) {
err = cfg.namespace_id = nvme_get_nsid(fd);
if (err < 0) {
@@ -4071,7 +4343,7 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi
}
err = nvme_write_zeros(fd, cfg.namespace_id, cfg.start_block, cfg.block_count,
- control, cfg.ref_tag, cfg.app_tag, cfg.app_tag_mask);
+ control, cfg.ref_tag, cfg.app_tag, cfg.app_tag_mask, cfg.storage_tag);
if (err < 0)
perror("write-zeroes");
else if (err != 0)
@@ -4100,7 +4372,7 @@ static int dsm(int argc, char **argv, struct command *cmd, struct plugin *plugin
const char *idr = "Attribute Integral Dataset for Read";
const char *cdw11 = "All the command DWORD 11 attributes. Use instead of specifying individual attributes";
- int err, fd;
+ int err = -1, fd;
uint16_t nr, nc, nb, ns;
int ctx_attrs[256] = {0,};
int nlbs[256] = {0,};
@@ -4151,7 +4423,8 @@ static int dsm(int argc, char **argv, struct command *cmd, struct plugin *plugin
nr = max(nc, max(nb, ns));
if (!nr || nr > 256) {
fprintf(stderr, "No range definition provided\n");
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
@@ -4168,7 +4441,8 @@ static int dsm(int argc, char **argv, struct command *cmd, struct plugin *plugin
dsm = nvme_setup_dsm_range(ctx_attrs, nlbs, slbas, nr);
if (!dsm) {
fprintf(stderr, "failed to allocate data set payload\n");
- err = -ENOMEM;
+ errno = ENOMEM;
+ err = -1;
goto close_fd;
}
@@ -4213,7 +4487,7 @@ static int copy(int argc, char **argv, struct command *cmd, struct plugin *plugi
const char *d_dspec = "directive specific (write part)";
const char *d_format = "source range entry format";
- int err, fd;
+ int err = -1, fd;
uint16_t nr, nb, ns, nrts, natms, nats;
int nlbs[128] = { 0 };
unsigned long long slbas[128] = {0,};
@@ -4287,7 +4561,8 @@ static int copy(int argc, char **argv, struct command *cmd, struct plugin *plugi
nr = max(nb, max(ns, max(nrts, max(natms, nats))));
if (!nr || nr > 128) {
fprintf(stderr, "invalid range\n");
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
@@ -4302,7 +4577,8 @@ static int copy(int argc, char **argv, struct command *cmd, struct plugin *plugi
copy = nvme_setup_copy_range(nlbs, slbas, eilbrts, elbatms, elbats, nr);
if (!copy) {
fprintf(stderr, "failed to allocate payload\n");
- err = -ENOMEM;
+ errno = ENOMEM;
+ err = -1;
goto close_fd;
}
@@ -4332,14 +4608,14 @@ static int flush(int argc, char **argv, struct command *cmd, struct plugin *plug
"flushed by the controller, from any namespace, depending on controller and "\
"associated namespace status.";
const char *namespace_id = "identifier of desired namespace";
- int err, fd;
+ int err = -1, fd;
struct config {
__u32 namespace_id;
};
struct config cfg = {
- .namespace_id = NVME_NSID_ALL,
+ .namespace_id = 0,
};
OPT_ARGS(opts) = {
@@ -4384,9 +4660,9 @@ static int resv_acquire(int argc, char **argv, struct command *cmd, struct plugi
const char *crkey = "current reservation key";
const char *prkey = "pre-empt reservation key";
const char *rtype = "reservation type";
- const char *racqa = "reservation acquiry action";
+ const char *racqa = "reservation acquire action";
const char *iekey = "ignore existing res. key";
- int err, fd;
+ int err = -1, fd;
struct config {
__u32 namespace_id;
@@ -4407,8 +4683,8 @@ static int resv_acquire(int argc, char **argv, struct command *cmd, struct plugi
OPT_ARGS(opts) = {
OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
- OPT_LONG("crkey", 'c', &cfg.crkey, crkey),
- OPT_LONG("prkey", 'p', &cfg.prkey, prkey),
+ OPT_SUFFIX("crkey", 'c', &cfg.crkey, crkey),
+ OPT_SUFFIX("prkey", 'p', &cfg.prkey, prkey),
OPT_BYTE("rtype", 't', &cfg.rtype, rtype),
OPT_BYTE("racqa", 'a', &cfg.racqa, racqa),
OPT_FLAG("iekey", 'i', &cfg.iekey, iekey),
@@ -4428,7 +4704,8 @@ static int resv_acquire(int argc, char **argv, struct command *cmd, struct plugi
}
if (cfg.racqa > 7) {
fprintf(stderr, "invalid racqa:%d\n", cfg.racqa);
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
@@ -4458,7 +4735,7 @@ static int resv_register(int argc, char **argv, struct command *cmd, struct plug
const char *nrkey = "new reservation key";
const char *rrega = "reservation registration action";
const char *cptpl = "change persistence through power loss setting";
- int err, fd;
+ int err = -1, fd;
struct config {
__u32 namespace_id;
@@ -4479,8 +4756,8 @@ static int resv_register(int argc, char **argv, struct command *cmd, struct plug
OPT_ARGS(opts) = {
OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
- OPT_LONG("crkey", 'c', &cfg.crkey, crkey),
- OPT_LONG("nrkey", 'k', &cfg.nrkey, nrkey),
+ OPT_SUFFIX("crkey", 'c', &cfg.crkey, crkey),
+ OPT_SUFFIX("nrkey", 'k', &cfg.nrkey, nrkey),
OPT_BYTE("rrega", 'r', &cfg.rrega, rrega),
OPT_BYTE("cptpl", 'p', &cfg.cptpl, cptpl),
OPT_FLAG("iekey", 'i', &cfg.iekey, iekey),
@@ -4500,13 +4777,15 @@ static int resv_register(int argc, char **argv, struct command *cmd, struct plug
}
if (cfg.cptpl > 3) {
fprintf(stderr, "invalid cptpl:%d\n", cfg.cptpl);
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
if (cfg.rrega > 7) {
fprintf(stderr, "invalid rrega:%d\n", cfg.rrega);
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
@@ -4540,7 +4819,7 @@ static int resv_release(int argc, char **argv, struct command *cmd, struct plugi
const char *iekey = "ignore existing res. key";
const char *rtype = "reservation type";
const char *rrela = "reservation release action";
- int err, fd;
+ int err = -1, fd;
struct config {
__u32 namespace_id;
@@ -4560,7 +4839,7 @@ static int resv_release(int argc, char **argv, struct command *cmd, struct plugi
OPT_ARGS(opts) = {
OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
- OPT_LONG("crkey", 'c', &cfg.crkey, crkey),
+ OPT_SUFFIX("crkey", 'c', &cfg.crkey, crkey),
OPT_BYTE("rtype", 't', &cfg.rtype, rtype),
OPT_BYTE("rrela", 'a', &cfg.rrela, rrela),
OPT_FLAG("iekey", 'i', &cfg.iekey, iekey),
@@ -4580,7 +4859,8 @@ static int resv_release(int argc, char **argv, struct command *cmd, struct plugi
}
if (cfg.rrela > 7) {
fprintf(stderr, "invalid rrela:%d\n", cfg.rrela);
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
@@ -4613,7 +4893,7 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin
struct nvme_reservation_status *status;
enum nvme_print_flags flags;
- int err, fd, size;
+ int err = -1, fd, size;
struct config {
__u32 namespace_id;
@@ -4666,7 +4946,8 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin
if (posix_memalign((void **)&status, getpagesize(), size)) {
fprintf(stderr, "No memory for resv report:%d\n", size);
- err = -ENOMEM;
+ errno = ENOMEM;
+ err = -1;
goto close_fd;
}
memset(status, 0, size);
@@ -4698,7 +4979,7 @@ static int submit_io(int opcode, char *command, const char *desc,
{
struct timeval start_time, end_time;
void *buffer, *mbuffer = NULL;
- int err = 0;
+ int err = -1;
int dfd, mfd, fd;
int flags = opcode & 1 ? O_RDONLY : O_WRONLY | O_CREAT;
int mode = S_IRUSR | S_IWUSR |S_IRGRP | S_IWGRP| S_IROTH;
@@ -4710,6 +4991,7 @@ static int submit_io(int opcode, char *command, const char *desc,
struct nvme_id_ns ns;
__u8 lba_index, ms = 0;
+ const char *namespace_id = "desired namespace";
const char *start_block = "64-bit addr of first block to access";
const char *block_count = "number of blocks (zeroes based) on device to access";
const char *data_size = "size of data in bytes";
@@ -4728,8 +5010,13 @@ static int submit_io(int opcode, char *command, const char *desc,
const char *dtype = "directive type (for write-only)";
const char *dspec = "directive specific (for write-only)";
const char *dsm = "dataset management attributes (lower 16 bits)";
+ const char *storage_tag_check = "This bit specifies the Storage Tag field shall be " \
+ "checked as part of end-to-end data protection processing";
+ const char *storage_tag = "storage tag, CDW2 and CDW3 (00:47) bits "\
+ "(for end to end PI)";
struct config {
+ __u32 namespace_id;
__u64 start_block;
__u16 block_count;
__u64 data_size;
@@ -4743,27 +5030,33 @@ static int submit_io(int opcode, char *command, const char *desc,
__u16 dsmgmt;
__u16 app_tag_mask;
__u16 app_tag;
+ __u64 storage_tag;
int limited_retry;
int force_unit_access;
+ int storage_tag_check;
int show;
int dry_run;
int latency;
};
struct config cfg = {
- .start_block = 0,
- .block_count = 0,
- .data_size = 0,
- .metadata_size = 0,
- .ref_tag = 0,
- .data = "",
- .metadata = "",
- .prinfo = 0,
- .app_tag_mask = 0,
- .app_tag = 0,
+ .namespace_id = 0,
+ .start_block = 0,
+ .block_count = 0,
+ .data_size = 0,
+ .metadata_size = 0,
+ .ref_tag = 0,
+ .data = "",
+ .metadata = "",
+ .prinfo = 0,
+ .app_tag_mask = 0,
+ .app_tag = 0,
+ .storage_tag_check = 0,
+ .storage_tag = 0,
};
OPT_ARGS(opts) = {
+ OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
OPT_SUFFIX("start-block", 's', &cfg.start_block, start_block),
OPT_SHRT("block-count", 'c', &cfg.block_count, block_count),
OPT_SUFFIX("data-size", 'z', &cfg.data_size, data_size),
@@ -4774,8 +5067,10 @@ static int submit_io(int opcode, char *command, const char *desc,
OPT_BYTE("prinfo", 'p', &cfg.prinfo, prinfo),
OPT_SHRT("app-tag-mask", 'm', &cfg.app_tag_mask, app_tag_mask),
OPT_SHRT("app-tag", 'a', &cfg.app_tag, app_tag),
+ OPT_SUFFIX("storage-tag", 'g', &cfg.storage_tag, storage_tag),
OPT_FLAG("limited-retry", 'l', &cfg.limited_retry, limited_retry),
OPT_FLAG("force-unit-access", 'f', &cfg.force_unit_access, force),
+ OPT_FLAG("storage-tag-check", 'C', &cfg.storage_tag_check, storage_tag_check),
OPT_BYTE("dir-type", 'T', &cfg.dtype, dtype),
OPT_SHRT("dir-spec", 'S', &cfg.dspec, dspec),
OPT_SHRT("dsm", 'D', &cfg.dsmgmt, dsm),
@@ -4789,9 +5084,18 @@ static int submit_io(int opcode, char *command, const char *desc,
if (fd < 0)
goto ret;
+ if (!cfg.namespace_id) {
+ err = cfg.namespace_id = nvme_get_nsid(fd);
+ if (err < 0) {
+ perror("get-namespace-id");
+ goto close_fd;
+ }
+ }
+
dfd = mfd = opcode & 1 ? STDIN_FILENO : STDOUT_FILENO;
if (cfg.prinfo > 0xf) {
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
@@ -4801,11 +5105,14 @@ static int submit_io(int opcode, char *command, const char *desc,
control |= NVME_RW_LR;
if (cfg.force_unit_access)
control |= NVME_RW_FUA;
+ if (cfg.storage_tag_check)
+ control |= NVME_RW_STORAGE_TAG_CHECK;
if (cfg.dtype) {
if (cfg.dtype > 0xf) {
fprintf(stderr, "Invalid directive type, %x\n",
cfg.dtype);
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
control |= cfg.dtype << 4;
@@ -4816,7 +5123,8 @@ static int submit_io(int opcode, char *command, const char *desc,
dfd = open(cfg.data, flags, mode);
if (dfd < 0) {
perror(cfg.data);
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
mfd = dfd;
@@ -4825,19 +5133,26 @@ static int submit_io(int opcode, char *command, const char *desc,
mfd = open(cfg.metadata, flags, mode);
if (mfd < 0) {
perror(cfg.metadata);
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_dfd;
}
}
if (!cfg.data_size) {
fprintf(stderr, "data size not provided\n");
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_mfd;
}
- if (ioctl(fd, BLKSSZGET, &logical_block_size) < 0)
- goto close_mfd;
+ if (is_ns_chardev()) {
+ logical_block_size =
+ nvme_logical_block_size_from_ns_char(devicename);
+ } else {
+ if (ioctl(fd, BLKSSZGET, &logical_block_size) < 0)
+ goto close_mfd;
+ }
buffer_size = (cfg.block_count + 1) * logical_block_size;
if (cfg.data_size < buffer_size) {
@@ -4850,7 +5165,8 @@ static int submit_io(int opcode, char *command, const char *desc,
buffer = nvme_alloc(buffer_size, &huge);
if (!buffer) {
perror("can not allocate io payload\n");
- err = -ENOMEM;
+ errno = ENOMEM;
+ err = -1;
goto close_mfd;
}
@@ -4880,7 +5196,8 @@ static int submit_io(int opcode, char *command, const char *desc,
mbuffer = malloc(mbuffer_size);
if (!mbuffer) {
perror("can not allocate buf for io metadata payload\n");
- err = -ENOMEM;
+ errno = ENOMEM;
+ err = -1;
goto free_buffer;
}
memset(mbuffer, 0, mbuffer_size);
@@ -4907,24 +5224,27 @@ static int submit_io(int opcode, char *command, const char *desc,
}
if (cfg.show) {
- printf("opcode : %02x\n", opcode);
- printf("flags : %02x\n", 0);
- printf("control : %04x\n", control);
- printf("nblocks : %04x\n", cfg.block_count);
- printf("metadata : %"PRIx64"\n", (uint64_t)(uintptr_t)mbuffer);
- printf("addr : %"PRIx64"\n", (uint64_t)(uintptr_t)buffer);
- printf("slba : %"PRIx64"\n", (uint64_t)cfg.start_block);
- printf("dsmgmt : %08x\n", dsmgmt);
- printf("reftag : %08x\n", cfg.ref_tag);
- printf("apptag : %04x\n", cfg.app_tag);
- printf("appmask : %04x\n", cfg.app_tag_mask);
+ printf("opcode : %02x\n", opcode);
+ printf("nsid : %02x\n", cfg.namespace_id);
+ printf("control : %04x\n", control);
+ printf("nblocks : %04x\n", cfg.block_count);
+ printf("metadata : %"PRIx64"\n", (uint64_t)(uintptr_t)mbuffer);
+ printf("addr : %"PRIx64"\n", (uint64_t)(uintptr_t)buffer);
+ printf("slba : %"PRIx64"\n", (uint64_t)cfg.start_block);
+ printf("dsmgmt : %08x\n", dsmgmt);
+ printf("reftag : %08x\n", cfg.ref_tag);
+ printf("apptag : %04x\n", cfg.app_tag);
+ printf("appmask : %04x\n", cfg.app_tag_mask);
+ printf("storagetagcheck : %04x\n", cfg.storage_tag_check);
+ printf("storagetag : %"PRIx64"\n", (uint64_t)cfg.storage_tag);
}
if (cfg.dry_run)
goto free_mbuffer;
gettimeofday(&start_time, NULL);
- err = nvme_io(fd, opcode, cfg.start_block, cfg.block_count, control, dsmgmt,
- cfg.ref_tag, cfg.app_tag, cfg.app_tag_mask, buffer, mbuffer);
+ err = nvme_io(fd, opcode, cfg.namespace_id, cfg.start_block, cfg.block_count,
+ control, dsmgmt, cfg.ref_tag, cfg.app_tag, cfg.app_tag_mask,
+ cfg.storage_tag, buffer, mbuffer);
gettimeofday(&end_time, NULL);
if (cfg.latency)
printf(" latency: %s: %llu us\n",
@@ -4937,12 +5257,14 @@ static int submit_io(int opcode, char *command, const char *desc,
if (!(opcode & 1) && write(dfd, (void *)buffer, cfg.data_size) < 0) {
fprintf(stderr, "write: %s: failed to write buffer to output file\n",
strerror(errno));
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
} else if (!(opcode & 1) && cfg.metadata_size &&
write(mfd, (void *)mbuffer, mbuffer_size) < 0) {
fprintf(stderr, "write: %s: failed to write meta-data buffer to output file\n",
strerror(errno));
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
} else
fprintf(stderr, "%s: Success\n", command);
}
@@ -4987,7 +5309,7 @@ static int write_cmd(int argc, char **argv, struct command *cmd, struct plugin *
static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- int err, fd;
+ int err = -1, fd;
__u16 control = 0;
const char *desc = "Verify specified logical blocks on the given device.";
const char *namespace_id = "desired namespace";
@@ -4999,6 +5321,10 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin
const char *ref_tag = "reference tag (for end to end PI)";
const char *app_tag_mask = "app tag mask (for end to end PI)";
const char *app_tag = "app tag (for end to end PI)";
+ const char *storage_tag = "storage tag, CDW2 and CDW3 (00:47) bits "\
+ "(for end to end PI)";
+ const char *storage_tag_check = "This bit specifies the Storage Tag field shall "\
+ "be checked as part of Verify operation";
struct config {
__u64 start_block;
@@ -5008,6 +5334,8 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin
__u16 app_tag_mask;
__u16 block_count;
__u8 prinfo;
+ __u64 storage_tag;
+ int storage_tag_check;
int limited_retry;
int force_unit_access;
};
@@ -5022,6 +5350,8 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin
.app_tag_mask = 0,
.limited_retry = 0,
.force_unit_access = 0,
+ .storage_tag = 0,
+ .storage_tag_check = 0,
};
OPT_ARGS(opts) = {
@@ -5034,15 +5364,19 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin
OPT_UINT("ref-tag", 'r', &cfg.ref_tag, ref_tag),
OPT_SHRT("app-tag", 'a', &cfg.app_tag, app_tag),
OPT_SHRT("app-tag-mask", 'm', &cfg.app_tag_mask, app_tag_mask),
+ OPT_SUFFIX("storage-tag", 'S', &cfg.storage_tag, storage_tag),
+ OPT_FLAG("storage-tag-check", 'C', &cfg.storage_tag_check, storage_tag_check),
OPT_END()
};
err = fd = parse_and_open(argc, argv, desc, opts);
if (fd < 0)
- goto err;
+ goto ret;
if (cfg.prinfo > 0xf) {
- err = EINVAL;
+ fprintf(stderr, "invalid 'prinfo' param:%u\n", cfg.prinfo);
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
@@ -5051,6 +5385,8 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin
control |= NVME_RW_LR;
if (cfg.force_unit_access)
control |= NVME_RW_FUA;
+ if (cfg.storage_tag_check)
+ control |= NVME_RW_STORAGE_TAG_CHECK;
if (!cfg.namespace_id) {
err = cfg.namespace_id = nvme_get_nsid(fd);
@@ -5061,7 +5397,7 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin
}
err = nvme_verify(fd, cfg.namespace_id, cfg.start_block, cfg.block_count,
- control, cfg.ref_tag, cfg.app_tag, cfg.app_tag_mask);
+ control, cfg.ref_tag, cfg.app_tag, cfg.app_tag_mask, cfg.storage_tag);
if (err < 0)
perror("verify");
else if (err != 0)
@@ -5071,8 +5407,8 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin
close_fd:
close(fd);
-err:
- return err;
+ret:
+ return nvme_status_to_errno(err, false);;
}
static int sec_recv(int argc, char **argv, struct command *cmd, struct plugin *plugin)
@@ -5090,7 +5426,7 @@ static int sec_recv(int argc, char **argv, struct command *cmd, struct plugin *p
const char *raw = "dump output in binary format";
const char *namespace_id = "desired namespace";
const char *nssf = "NVMe Security Specific Field";
- int err, fd;
+ int err = -1, fd;
void *sec_buf = NULL;
struct config {
@@ -5129,7 +5465,8 @@ static int sec_recv(int argc, char **argv, struct command *cmd, struct plugin *p
if (posix_memalign(&sec_buf, getpagesize(), cfg.size)) {
fprintf(stderr, "No memory for security size:%d\n",
cfg.size);
- err = -ENOMEM;
+ errno = ENOMEM;
+ err = -1;
goto close_fd;
}
}
@@ -5165,7 +5502,7 @@ static int get_lba_status(int argc, char **argv, struct command *cmd,
" logical block addressed by this command";
const char *mndw = "Maximum Number of Dwords(MNDW) specifies maximum"\
" number of dwords to return";
- const char *atype = "Action Type(ATYPE) specifies the mechanism the"\
+ const char *atype = "Action Type(ATYPE) specifies the mechanism"\
" the controller uses in determining the LBA"\
" Status Descriptors to return.";
const char *rl = "Range Length(RL) specifies the length of the range"\
@@ -5174,7 +5511,7 @@ static int get_lba_status(int argc, char **argv, struct command *cmd,
enum nvme_print_flags flags;
unsigned long buf_len;
- int err, fd;
+ int err = -1, fd;
void *buf;
struct config {
@@ -5218,7 +5555,8 @@ static int get_lba_status(int argc, char **argv, struct command *cmd,
if (!cfg.atype) {
fprintf(stderr, "action type (--action) has to be given\n");
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
@@ -5226,7 +5564,8 @@ static int get_lba_status(int argc, char **argv, struct command *cmd,
buf = calloc(1, buf_len);
if (!buf) {
perror("could not alloc memory for get lba status");
- err = -ENOMEM;
+ errno = ENOMEM;
+ err = -1;
goto close_fd;
}
@@ -5245,6 +5584,75 @@ err:
return nvme_status_to_errno(err, false);
}
+static int capacity_mgmt(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+ const char *desc = "Host software uses the Capacity Management command to "\
+ "configure Endurance Groups and NVM Sets in an NVM subsystem by either " \
+ "selecting one of a set of supported configurations or by specifying the "\
+ "capacity of the Endurance Group or NVM Set to be created";
+ const char *operation = "Operation to be performed by the controller";
+ const char *element_id = "Value specific to the value of the Operation field.";
+ const char *cap_lower = "Least significant 32 bits of the capacity in bytes of the "\
+ "Endurance Group or NVM Set to be created";
+ const char *cap_upper = "Most significant 32 bits of the capacity in bytes of the "\
+ "Endurance Group or NVM Set to be created";
+
+ int err = -1, fd;
+ __u32 result;
+
+ struct config {
+ __u8 operation;
+ __u16 element_id;
+ __u32 dw11;
+ __u32 dw12;
+ };
+
+ struct config cfg = {
+ .operation = 0xff,
+ .element_id = 0xffff,
+ .dw11 = 0,
+ .dw12 = 0,
+ };
+
+ OPT_ARGS(opts) = {
+ OPT_BYTE("operation", 'o', &cfg.operation, operation),
+ OPT_SHRT("element-id", 'i', &cfg.element_id, element_id),
+ OPT_UINT("cap-lower", 'l', &cfg.dw11, cap_lower),
+ OPT_UINT("cap-upper", 'u', &cfg.dw12, cap_upper),
+ OPT_END()
+ };
+
+ err = fd = parse_and_open(argc, argv, desc, opts);
+ if (fd < 0)
+ goto ret;
+
+ if (cfg.operation > 0xf) {
+ fprintf(stderr, "invalid operation field: %u\n", cfg.operation);
+ errno = EINVAL;
+ err = -1;
+ goto close_fd;
+ }
+
+ err = nvme_cap_mgmt(fd, cfg.operation, cfg.element_id, cfg.dw11,
+ cfg.dw12, &result);
+ if (!err) {
+ printf("Capacity Management Command is Success\n");
+ if (cfg.operation == 1) {
+ printf("Created Element Identifier for Endurance Group is: %u\n", result);
+ } else if (cfg.operation == 3) {
+ printf("Created Element Identifier for NVM Set is: %u\n", result);
+ }
+ } else if (err > 0)
+ nvme_show_status(err);
+ else if (err < 0)
+ perror("capacity management");
+
+close_fd:
+ close(fd);
+ret:
+ return nvme_status_to_errno(err, false);
+}
+
static int dir_receive(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
const char *desc = "Read directive parameters of the "\
@@ -5259,7 +5667,7 @@ static int dir_receive(int argc, char **argv, struct command *cmd, struct plugin
const char *human_readable = "show directive in readable format";
enum nvme_print_flags flags = NORMAL;
- int err, fd;
+ int err = -1, fd;
__u32 result;
__u32 dw12 = 0;
void *buf = NULL;
@@ -5314,7 +5722,8 @@ static int dir_receive(int argc, char **argv, struct command *cmd, struct plugin
break;
default:
fprintf(stderr, "invalid directive operations for Identify Directives\n");
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
break;
@@ -5333,19 +5742,22 @@ static int dir_receive(int argc, char **argv, struct command *cmd, struct plugin
break;
default:
fprintf(stderr, "invalid directive operations for Streams Directives\n");
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
break;
default:
fprintf(stderr, "invalid directive type\n");
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
if (cfg.data_len) {
if (posix_memalign(&buf, getpagesize(), cfg.data_len)) {
- err = -ENOMEM;
+ errno = ENOMEM;
+ err = -1;
goto close_fd;
}
memset(buf, 0, cfg.data_len);
@@ -5401,11 +5813,14 @@ static int passthru(int argc, char **argv, int ioctl_cmd, uint8_t cmd_type,
const char *re = "set dataflow direction to receive";
const char *wr = "set dataflow direction to send";
const char *prefill = "prefill buffers with known byte-value, default 0";
+ const char *latency = "output latency statistics";
+
void *data = NULL, *metadata = NULL;
- int err = 0, wfd = STDIN_FILENO, fd;
+ int err = -1, wfd = STDIN_FILENO, fd;
__u32 result;
bool huge;
const char *cmd_name = NULL;
+ struct timeval start_time, end_time;
struct config {
__u8 opcode;
@@ -5430,6 +5845,7 @@ static int passthru(int argc, char **argv, int ioctl_cmd, uint8_t cmd_type,
int read;
int write;
__u8 prefill;
+ int latency;
};
struct config cfg = {
@@ -5475,6 +5891,7 @@ static int passthru(int argc, char **argv, int ioctl_cmd, uint8_t cmd_type,
OPT_FLAG("dry-run", 'd', &cfg.dry_run, dry),
OPT_FLAG("read", 'r', &cfg.read, re),
OPT_FLAG("write", 'w', &cfg.write, wr),
+ OPT_FLAG("latency", 'T', &cfg.latency, latency),
OPT_END()
};
@@ -5487,7 +5904,8 @@ static int passthru(int argc, char **argv, int ioctl_cmd, uint8_t cmd_type,
S_IRUSR | S_IRGRP | S_IROTH);
if (wfd < 0) {
perror(cfg.input_file);
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto close_fd;
}
}
@@ -5496,7 +5914,8 @@ static int passthru(int argc, char **argv, int ioctl_cmd, uint8_t cmd_type,
metadata = malloc(cfg.metadata_len);
if (!metadata) {
perror("can not allocate metadata payload\n");
- err = -ENOMEM;
+ errno = ENOMEM;
+ err = -1;
goto close_wfd;
}
memset(metadata, cfg.prefill, cfg.metadata_len);
@@ -5505,7 +5924,8 @@ static int passthru(int argc, char **argv, int ioctl_cmd, uint8_t cmd_type,
data = nvme_alloc(cfg.data_len, &huge);
if (!data) {
perror("can not allocate data payload\n");
- err = -ENOMEM;
+ errno = ENOMEM;
+ err = -1;
goto free_metadata;
}
@@ -5520,7 +5940,8 @@ static int passthru(int argc, char **argv, int ioctl_cmd, uint8_t cmd_type,
memset(data, cfg.prefill, cfg.data_len);
if (!cfg.read && !cfg.write) {
fprintf(stderr, "data direction not given\n");
- err = -EINVAL;
+ errno = EINVAL;
+ err = -1;
goto free_data;
} else if (cfg.write) {
if (read(wfd, data, cfg.data_len) < 0) {
@@ -5554,17 +5975,27 @@ static int passthru(int argc, char **argv, int ioctl_cmd, uint8_t cmd_type,
if (cfg.dry_run)
goto free_data;
+ gettimeofday(&start_time, NULL);
+
err = nvme_passthru(fd, ioctl_cmd, cfg.opcode, cfg.flags, cfg.rsvd,
cfg.namespace_id, cfg.cdw2, cfg.cdw3, cfg.cdw10,
cfg.cdw11, cfg.cdw12, cfg.cdw13, cfg.cdw14, cfg.cdw15,
cfg.data_len, data, cfg.metadata_len, metadata,
cfg.timeout, &result);
+
+ gettimeofday(&end_time, NULL);
+ cmd_name = nvme_cmd_to_string(cmd_type, cfg.opcode);
+ if (cfg.latency)
+ printf("%s Command %s latency: %llu us\n",
+ cmd_type ? "Admin": "IO",
+ strcmp(cmd_name, "Unknown") ? cmd_name: "Vendor Specific",
+ elapsed_utime(start_time, end_time));
+
if (err < 0)
perror("passthru");
else if (err)
nvme_show_status(err);
else {
- cmd_name = nvme_cmd_to_string(cmd_type, cfg.opcode);
fprintf(stderr, "%s Command %s is Success and result: 0x%08x\n",
cmd_type ? "Admin": "IO",
strcmp(cmd_name, "Unknown") ? cmd_name: "Vendor Specific",
diff --git a/nvme.h b/nvme.h
index e33094d..5150c8d 100644
--- a/nvme.h
+++ b/nvme.h
@@ -82,6 +82,7 @@ struct nvme_ctrl {
char *traddr;
char *trsvcid;
char *host_traddr;
+ char *host_iface;
char *hostnqn;
char *hostid;
@@ -120,6 +121,7 @@ enum nvme_print_flags validate_output_format(const char *format);
int __id_ctrl(int argc, char **argv, struct command *cmd,
struct plugin *plugin, void (*vs)(__u8 *vs, struct json_object *root));
char *nvme_char_from_block(char *block);
+int nvme_logical_block_size_from_ns_char(const char *dev);
void *mmap_registers(const char *dev);
extern int current_index;
@@ -144,4 +146,11 @@ int uuid_from_systemd(char *uuid);
unsigned long long elapsed_utime(struct timeval start_time,
struct timeval end_time);
+
+static inline void nvme_strip_spaces(char *s, int l)
+{
+ while (l && (s[l] == '\0' || s[l] == ' '))
+ s[l--] = '\0';
+}
+
#endif /* _NVME_H */
diff --git a/nvmf-autoconnect/systemd/nvmf-autoconnect.service b/nvmf-autoconnect/systemd/nvmf-autoconnect.service
index 2690467..b1be272 100644
--- a/nvmf-autoconnect/systemd/nvmf-autoconnect.service
+++ b/nvmf-autoconnect/systemd/nvmf-autoconnect.service
@@ -1,11 +1,12 @@
[Unit]
Description=Connect NVMe-oF subsystems automatically during boot
ConditionPathExists=/etc/nvme/discovery.conf
-After=network.target
+After=network-online.target
Before=remote-fs-pre.target
[Service]
Type=oneshot
+ExecStartPre=/sbin/modprobe nvme-fabrics
ExecStart=/usr/sbin/nvme connect-all
[Install]
diff --git a/plugin.c b/plugin.c
index c7d6b2e..78f03ab 100644
--- a/plugin.c
+++ b/plugin.c
@@ -11,7 +11,7 @@ static int version(struct plugin *plugin)
struct program *prog = plugin->parent;
if (plugin->name)
- printf("%s %s version %s\n", prog->name, plugin->name, prog->version);
+ printf("%s %s version %s\n", prog->name, plugin->name, plugin->version);
else
printf("%s version %s\n", prog->name, prog->version);
return 0;
diff --git a/plugin.h b/plugin.h
index 91079fb..7a8ed09 100644
--- a/plugin.h
+++ b/plugin.h
@@ -16,6 +16,7 @@ struct program {
struct plugin {
const char *name;
const char *desc;
+ const char *version;
struct command **commands;
struct program *parent;
struct plugin *next;
diff --git a/plugins/amzn/amzn-nvme.h b/plugins/amzn/amzn-nvme.h
index 9b8d797..f969c0e 100644
--- a/plugins/amzn/amzn-nvme.h
+++ b/plugins/amzn/amzn-nvme.h
@@ -6,7 +6,7 @@
#include "cmd.h"
-PLUGIN(NAME("amzn", "Amazon vendor specific extensions"),
+PLUGIN(NAME("amzn", "Amazon vendor specific extensions", NVME_VERSION),
COMMAND_LIST(
ENTRY("id-ctrl", "Send NVMe Identify Controller", id_ctrl)
)
diff --git a/plugins/dera/dera-nvme.h b/plugins/dera/dera-nvme.h
index dc54fab..d3a8b0b 100644
--- a/plugins/dera/dera-nvme.h
+++ b/plugins/dera/dera-nvme.h
@@ -6,7 +6,7 @@
#include "cmd.h"
-PLUGIN(NAME("dera", "Dera vendor specific extensions"),
+PLUGIN(NAME("dera", "Dera vendor specific extensions", NVME_VERSION),
COMMAND_LIST(
ENTRY("smart-log-add", "Retrieve Dera SMART Log, show it", get_status, "stat")
)
diff --git a/plugins/huawei/huawei-nvme.h b/plugins/huawei/huawei-nvme.h
index 7aac90c..175ddd5 100644
--- a/plugins/huawei/huawei-nvme.h
+++ b/plugins/huawei/huawei-nvme.h
@@ -6,7 +6,7 @@
#include "cmd.h"
-PLUGIN(NAME("huawei", "Huawei vendor specific extensions"),
+PLUGIN(NAME("huawei", "Huawei vendor specific extensions", NVME_VERSION),
COMMAND_LIST(
ENTRY("list", "List all Huawei NVMe devices and namespaces on machine", huawei_list)
ENTRY("id-ctrl", "Huawei identify controller", huawei_id_ctrl)
diff --git a/plugins/intel/intel-nvme.c b/plugins/intel/intel-nvme.c
index 27b065d..aaa40ad 100644
--- a/plugins/intel/intel-nvme.c
+++ b/plugins/intel/intel-nvme.c
@@ -454,7 +454,7 @@ static int get_temp_stats_log(int argc, char **argv, struct command *cmd, struct
struct intel_temp_stats stats;
int err, fd;
- const char *desc = "Get Intel Marketing Name log and show it.";
+ const char *desc = "Get Temperature Statistics log and show it.";
const char *raw = "dump output in binary format";
struct config {
int raw_binary;
@@ -1065,7 +1065,7 @@ static int get_lat_stats_log(int argc, char **argv, struct command *cmd, struct
__u32 thresholds[OPTANE_V1000_BUCKET_LEN] = {0};
__u32 result;
- err = nvme_get_feature(fd, 0, 0xf7, 0, cfg.write ? 0x1 : 0x0,
+ err = nvme_get_feature(fd, 0, 0xf7, 0, cfg.write ? 0x1 : 0x0, 0,
sizeof(thresholds), thresholds, &result);
if (err) {
fprintf(stderr, "Quering thresholds failed. NVMe Status:%s(%x)\n",
@@ -1542,7 +1542,7 @@ static int enable_lat_stats_tracking(int argc, char **argv,
return fd;
switch (option) {
case None:
- err = nvme_get_feature(fd, nsid, fid, sel, cdw11, data_len, buf,
+ err = nvme_get_feature(fd, nsid, fid, sel, cdw11, 0, data_len, buf,
&result);
if (!err) {
printf(
@@ -1555,7 +1555,7 @@ static int enable_lat_stats_tracking(int argc, char **argv,
break;
case True:
case False:
- err = nvme_set_feature(fd, nsid, fid, option, cdw12, save,
+ err = nvme_set_feature(fd, nsid, fid, option, cdw12, save, 0,
data_len, buf, &result);
if (err > 0) {
fprintf(stderr, "NVMe Status:%s(%x)\n",
@@ -1636,7 +1636,7 @@ static int set_lat_stats_thresholds(int argc, char **argv,
}
err = nvme_set_feature(fd, nsid, fid, cfg.write ? 0x1 : 0x0,
- cdw12, save, OPTANE_V1000_BUCKET_LEN,
+ cdw12, save, 0, OPTANE_V1000_BUCKET_LEN,
thresholds, &result);
if (err > 0) {
diff --git a/plugins/intel/intel-nvme.h b/plugins/intel/intel-nvme.h
index b119004..af1231a 100644
--- a/plugins/intel/intel-nvme.h
+++ b/plugins/intel/intel-nvme.h
@@ -6,7 +6,7 @@
#include "cmd.h"
-PLUGIN(NAME("intel", "Intel vendor specific extensions"),
+PLUGIN(NAME("intel", "Intel vendor specific extensions", NVME_VERSION),
COMMAND_LIST(
ENTRY("id-ctrl", "Send NVMe Identify Controller", id_ctrl)
ENTRY("internal-log", "Retrieve Intel internal firmware log, save it", get_internal_log)
diff --git a/plugins/lnvm/lnvm-nvme.h b/plugins/lnvm/lnvm-nvme.h
index 45b3cf0..18dffe1 100644
--- a/plugins/lnvm/lnvm-nvme.h
+++ b/plugins/lnvm/lnvm-nvme.h
@@ -7,7 +7,7 @@
#include "cmd.h"
-PLUGIN(NAME("lnvm", "LightNVM specific extensions"),
+PLUGIN(NAME("lnvm", "LightNVM specific extensions", NVME_VERSION),
COMMAND_LIST(
ENTRY("list", "List available LightNVM devices", lnvm_list)
ENTRY("info", "List general information and available target engines", lnvm_info)
diff --git a/plugins/memblaze/memblaze-nvme.c b/plugins/memblaze/memblaze-nvme.c
index d330835..e3807f1 100644
--- a/plugins/memblaze/memblaze-nvme.c
+++ b/plugins/memblaze/memblaze-nvme.c
@@ -503,7 +503,7 @@ static int mb_get_powermanager_status(int argc, char **argv, struct command *cmd
fd = parse_and_open(argc, argv, desc, opts);
if (fd < 0) return fd;
- err = nvme_get_feature(fd, 0, feature_id, 0, 0, 0, NULL, &result);
+ err = nvme_get_feature(fd, 0, feature_id, 0, 0, 0, 0, NULL, &result);
if (err < 0) {
perror("get-feature");
}
@@ -545,7 +545,7 @@ static int mb_set_powermanager_status(int argc, char **argv, struct command *cmd
fd = parse_and_open(argc, argv, desc, opts);
if (fd < 0) return fd;
- err = nvme_set_feature(fd, 0, cfg.feature_id, cfg.value, 0, cfg.save, 0, NULL, &result);
+ err = nvme_set_feature(fd, 0, cfg.feature_id, cfg.value, 0, cfg.save, 0, 0, NULL, &result);
if (err < 0) {
perror("set-feature");
}
@@ -602,7 +602,7 @@ static int mb_set_high_latency_log(int argc, char **argv, struct command *cmd, s
}
cfg.value = (param1 << MB_FEAT_HIGH_LATENCY_VALUE_SHIFT) | param2;
- err = nvme_set_feature(fd, 0, cfg.feature_id, cfg.value, 0, 0, 0, NULL, &result);
+ err = nvme_set_feature(fd, 0, cfg.feature_id, cfg.value, 0, 0, 0, 0, NULL, &result);
if (err < 0) {
perror("set-feature");
}
@@ -1038,7 +1038,7 @@ static int memblaze_clear_error_log(int argc, char **argv, struct command *cmd,
- err = nvme_set_feature(fd, 0, cfg.feature_id, cfg.value, 0, cfg.save, 0, NULL, &result);
+ err = nvme_set_feature(fd, 0, cfg.feature_id, cfg.value, 0, cfg.save, 0, 0, NULL, &result);
if (err < 0) {
perror("set-feature");
}
@@ -1115,7 +1115,7 @@ static int mb_set_lat_stats(int argc, char **argv,
return fd;
switch (option) {
case None:
- err = nvme_get_feature(fd, nsid, fid, sel, cdw11, data_len, buf,
+ err = nvme_get_feature(fd, nsid, fid, sel, cdw11, 0, data_len, buf,
&result);
if (!err) {
printf(
@@ -1128,7 +1128,7 @@ static int mb_set_lat_stats(int argc, char **argv,
break;
case True:
case False:
- err = nvme_set_feature(fd, nsid, fid, option, cdw12, save,
+ err = nvme_set_feature(fd, nsid, fid, option, cdw12, save, 0,
data_len, buf, &result);
if (err > 0) {
fprintf(stderr, "NVMe Status:%s(%x)\n",
diff --git a/plugins/memblaze/memblaze-nvme.h b/plugins/memblaze/memblaze-nvme.h
index 043d0a8..6f10bd7 100644
--- a/plugins/memblaze/memblaze-nvme.h
+++ b/plugins/memblaze/memblaze-nvme.h
@@ -12,7 +12,7 @@
#include <sys/types.h>
#include <sys/stat.h>
-PLUGIN(NAME("memblaze", "Memblaze vendor specific extensions"),
+PLUGIN(NAME("memblaze", "Memblaze vendor specific extensions", NVME_VERSION),
COMMAND_LIST(
ENTRY("smart-log-add", "Retrieve Memblaze SMART Log, show it", mb_get_additional_smart_log)
ENTRY("get-pm-status", "Get Memblaze Power Manager Status", mb_get_powermanager_status)
diff --git a/plugins/micron/micron-nvme.c b/plugins/micron/micron-nvme.c
index f76c015..840682d 100644
--- a/plugins/micron/micron-nvme.c
+++ b/plugins/micron/micron-nvme.c
@@ -11,6 +11,7 @@
#include <sys/stat.h>
#include "nvme.h"
#include "nvme-print.h"
+#include "nvme-status.h"
#include "nvme-ioctl.h"
#include <sys/ioctl.h>
#include <limits.h>
@@ -38,7 +39,7 @@
/* Plugin version major_number.minor_number.patch */
static const char *__version_major = "1";
static const char *__version_minor = "0";
-static const char *__version_patch = "5";
+static const char *__version_patch = "6";
/* supported models of micron plugin; new models should be added at the end
* before UNKNOWN_MODEL. Make sure M5410 is first in the list !
@@ -626,7 +627,7 @@ static int micron_smbus_option(int argc, char **argv,
if (!strcmp(opt.option, "enable")) {
cdw11 = opt.value << 1 | 1;
- err = nvme_set_feature(fd, 1, fid, cdw11, 0, opt.save, 0, 0, &result);
+ err = nvme_set_feature(fd, 1, fid, cdw11, 0, opt.save, 0, 0, 0, &result);
if (err == 0) {
printf("successfully enabled SMBus on drive\n");
} else {
@@ -635,7 +636,7 @@ static int micron_smbus_option(int argc, char **argv,
}
else if (!strcmp(opt.option, "status")) {
cdw10 = opt.value;
- err = nvme_get_feature(fd, 1, fid, cdw10, 0, 0, 0, &result);
+ err = nvme_get_feature(fd, 1, fid, cdw10, 0, 0, 0, 0, &result);
if (err == 0) {
printf("SMBus status on the drive: %s (returns %s temperature) \n",
(result & 1) ? "enabled" : "disabled",
@@ -646,7 +647,7 @@ static int micron_smbus_option(int argc, char **argv,
}
else if (!strcmp(opt.option, "disable")) {
cdw11 = opt.value << 1 | 0;
- err = nvme_set_feature(fd, 1, fid, cdw11, 0, opt.save, 0, 0, &result);
+ err = nvme_set_feature(fd, 1, fid, cdw11, 0, opt.save, 0, 0, 0, &result);
if (err == 0) {
printf("Successfully disabled SMBus on drive\n");
} else {
@@ -932,9 +933,11 @@ static int micron_clear_pcie_correctable_errors(int argc, char **argv,
/* For M51CX models, PCIe errors are cleared using 0xC3 feature */
if (model == M51CX) {
- err = nvme_set_feature(fd, 0, fid, (1 << 31), 0, 0, 0, 0, &result);
+ err = nvme_set_feature(fd, 0, fid, (1 << 31), 0, 0, 0, 0, 0, &result);
if (err == 0 && (err = (int)result) == 0)
printf("Device correctable errors cleared!\n");
+ else if (err > 0)
+ nvme_show_status(err);
else
printf("Error clearing Device correctable errors = 0x%x\n", err);
goto out;
@@ -1056,11 +1059,12 @@ static void init_d0_log_page(__u8 *buf, __u8 nsze)
/* OCP and Vendor specific log data format */
struct micron_vs_logpage {
char *field;
- int size;
+ int size; /* FB client spec version 1.0 sizes - M5410 models */
+ int size2; /* FB client spec version 0.7 sizes - M5407 models */
}
-/* Smart Health Log information as per OCP spec */
+/* Smart Health Log information as per OCP spec M51CX models */
ocp_c0_log_page[] = {
- { "Physical Media Units Written", 16 },
+ { "Physical Media Units Written", 16},
{ "Physical Media Units Read", 16 },
{ "Raw Bad User NAND Block Count", 6},
{ "Normalized Bad User NAND Block Count", 2},
@@ -1096,43 +1100,56 @@ ocp_c0_log_page[] = {
},
/* Vendor Specific Health Log information */
fb_log_page[] = {
- { "Physical Media Units Written - TLC", 16 },
- { "Physical Media Units Written - SLC", 16 },
- { "Normalized Bad User NAND Block Count", 2},
- { "Raw Bad User NAND Block Count", 6},
- { "XOR Recovery Count", 8},
- { "Uncorrectable Read Error Count", 8},
- { "SSD End to End Corrected Errors", 8},
- { "SSD End to End Detected Counts", 4},
- { "SSD End to End Uncorrected Counts", 4},
- { "System data % life-used", 1},
- { "Minimum User Data Erase Count - TLC", 8},
- { "Maximum User Data Erase Count - TLC", 8},
- { "Minimum User Data Erase Count - SLC", 8},
- { "Maximum User Data Erase Count - SLC", 8},
- { "Normalized Program Fail Count", 2},
- { "Raw Program Fail Count", 6},
- { "Normalized Erase Fail Count", 2},
- { "Raw Erase Fail Count", 6},
- { "Pcie Correctable Error Count", 8},
- { "% Free Blocks (User)", 1},
- { "Security Version Number", 8},
- { "% Free Blocks (System)", 1},
- { "Dataset Management (Deallocate) Commands", 16},
- { "Incomplete TRIM Data", 8},
- { "% Age of Completed TRIM", 1},
- { "Background Back-Pressure Gauge", 1},
- { "Soft ECC Error Count", 8},
- { "Refresh Count", 8},
- { "Normalized Bad System NAND Block Count", 2},
- { "Raw Bad System NAND Block Count", 6},
- { "Endurance Estimate", 16},
- { "Thermal Throttling Count", 1},
- { "Thermal Throttling Status", 1},
- { "Unaligned I/O", 8},
- { "Physical Media Units Read", 16},
- { "Reserved", 279},
- { "Log Page Version", 2}
+ { "Physical Media Units Written - TLC", 16, 16 },
+ { "Physical Media Units Written - SLC", 16, 16 },
+ { "Normalized Bad User NAND Block Count", 2, 2},
+ { "Raw Bad User NAND Block Count", 6, 6},
+ { "XOR Recovery Count", 8, 8},
+ { "Uncorrectable Read Error Count", 8, 8},
+ { "SSD End to End Corrected Errors", 8, 8},
+ { "SSD End to End Detected Counts", 4, 8},
+ { "SSD End to End Uncorrected Counts", 4, 8},
+ { "System data % life-used", 1, 1},
+ { "Reserved", 0, 3},
+ { "Minimum User Data Erase Count - TLC", 8, 8},
+ { "Maximum User Data Erase Count - TLC", 8, 8},
+ { "Average User Data Erase Count - TLC", 0, 8},
+ { "Minimum User Data Erase Count - SLC", 8, 8},
+ { "Maximum User Data Erase Count - SLC", 8, 8},
+ { "Average User Data Erase Count - SLC", 0, 8},
+ { "Normalized Program Fail Count", 2, 2},
+ { "Raw Program Fail Count", 6, 6},
+ { "Normalized Erase Fail Count", 2, 2},
+ { "Raw Erase Fail Count", 6, 6},
+ { "Pcie Correctable Error Count", 8, 8},
+ { "% Free Blocks (User)", 1, 1},
+ { "Reserved", 0, 3},
+ { "Security Version Number", 8, 8},
+ { "% Free Blocks (System)", 1, 1},
+ { "Reserved", 0, 3},
+ { "Dataset Management (Deallocate) Commands", 16, 16},
+ { "Incomplete TRIM Data", 8, 8},
+ { "% Age of Completed TRIM", 1, 2},
+ { "Background Back-Pressure Gauge", 1, 1},
+ { "Reserved", 0, 3},
+ { "Soft ECC Error Count", 8, 8},
+ { "Refresh Count", 8, 8},
+ { "Normalized Bad System NAND Block Count", 2, 2},
+ { "Raw Bad System NAND Block Count", 6, 6},
+ { "Endurance Estimate", 16, 16},
+ { "Thermal Throttling Count", 1, 1},
+ { "Thermal Throttling Status", 1, 1},
+ { "Unaligned I/O", 8, 8},
+ { "Physical Media Units Read", 16, 16},
+ { "Reserved", 279, 0},
+ { "Log Page Version", 2, 0},
+ { "READ CMDs exceeding threshold", 0, 4},
+ { "WRITE CMDs exceeding threshold", 0, 4},
+ { "TRIMs CMDs exceeding threshold", 0, 4},
+ { "Reserved", 0, 4},
+ { "Reserved", 0, 210},
+ { "Log Page Version", 0, 2},
+ { "Log Page GUID", 0, 16},
};
/* Common function to print Micron VS log pages */
@@ -1140,66 +1157,70 @@ static void print_micron_vs_logs(
__u8 *buf, /* raw log data */
struct micron_vs_logpage *log_page, /* format of the data */
int field_count, /* log field count */
- struct json_object *stats /* json object to add fields */
+ struct json_object *stats, /* json object to add fields */
+ __u8 spec /* ocp spec index */
)
{
__u64 lval_lo, lval_hi;
__u32 ival;
__u16 sval;
__u8 cval, lval[8] = { 0 };
- int field, guid_index;
+ int field;
int offset = 0;
for (field = 0; field < field_count; field++) {
char datastr[1024] = { 0 };
- if (log_page[field].size == 16) {
- if (strstr(log_page[field].field, "GUID")) {
- char *tmpstr = datastr;
- tmpstr += sprintf(datastr, "0x");
- for(guid_index = 0; guid_index < 16; guid_index++)
- tmpstr += sprintf(tmpstr, "%01X", buf[offset + guid_index]);
+ char *sfield = NULL;
+ int size = (spec == 0) ? log_page[field].size : log_page[field].size2;
+ if (size == 0) continue;
+ sfield = log_page[field].field;
+ if (size == 16) {
+ if (strstr(sfield, "GUID")) {
+ sprintf(datastr, "0x%"PRIx64"%"PRIx64"",
+ (uint64_t)le64_to_cpu(*(uint64_t *)(&buf[offset + 8])),
+ (uint64_t)le64_to_cpu(*(uint64_t *)(&buf[offset])));
} else {
lval_lo = *((__u64 *)(&buf[offset]));
lval_hi = *((__u64 *)(&buf[offset + 8]));
if (lval_hi)
- sprintf(datastr, "0x%"PRIx64"_%"PRIx64"",
+ sprintf(datastr, "0x%"PRIx64"%016"PRIx64"",
le64_to_cpu(lval_hi), le64_to_cpu(lval_lo));
else
sprintf(datastr, "0x%"PRIx64"", le64_to_cpu(lval_lo));
}
- } else if (log_page[field].size == 8) {
+ } else if (size == 8) {
lval_lo = *((__u64 *)(&buf[offset]));
sprintf(datastr, "0x%"PRIx64"", le64_to_cpu(lval_lo));
- } else if (log_page[field].size == 7) {
+ } else if (size == 7) {
/* 7 bytes will be in little-endian format, with last byte as MSB */
memcpy(&lval[0], &buf[offset], 7);
memcpy((void *)&lval_lo, lval, 8);
sprintf(datastr, "0x%"PRIx64"", le64_to_cpu(lval_lo));
- } else if (log_page[field].size == 6) {
+ } else if (size == 6) {
ival = *((__u32 *)(&buf[offset]));
sval = *((__u16 *)(&buf[offset + 4]));
lval_lo = (((__u64)sval << 32) | ival);
sprintf(datastr, "0x%"PRIx64"", le64_to_cpu(lval_lo));
- } else if (log_page[field].size == 4) {
+ } else if (size == 4) {
ival = *((__u32 *)(&buf[offset]));
sprintf(datastr, "0x%x", le32_to_cpu(ival));
- } else if (log_page[field].size == 2) {
+ } else if (size == 2) {
sval = *((__u16 *)(&buf[offset]));
sprintf(datastr, "0x%04x", le16_to_cpu(sval));
- } else if (log_page[field].size == 1) {
+ } else if (size == 1) {
cval = buf[offset];
sprintf(datastr, "0x%02x", cval);
} else {
sprintf(datastr, "0");
}
- offset += log_page[field].size;
+ offset += size;
/* do not print reserved values */
- if (strstr(log_page[field].field, "Reserved"))
+ if (strstr(sfield, "Reserved"))
continue;
if (stats != NULL) {
- json_object_add_value_string(stats, log_page[field].field, datastr);
+ json_object_add_value_string(stats, sfield, datastr);
} else {
- printf("%-40s : %-4s\n", log_page[field].field, datastr);
+ printf("%-40s : %-4s\n", sfield, datastr);
}
}
}
@@ -1219,7 +1240,7 @@ static void print_smart_cloud_health_log(__u8 *buf, bool is_json)
logPages);
}
- print_micron_vs_logs(buf, ocp_c0_log_page, field_count, stats);
+ print_micron_vs_logs(buf, ocp_c0_log_page, field_count, stats, 0);
if (is_json) {
json_array_add_value_object(logPages, stats);
@@ -1229,7 +1250,7 @@ static void print_smart_cloud_health_log(__u8 *buf, bool is_json)
}
}
-static void print_nand_stats_fb(__u8 *buf, __u8 *buf2, __u8 nsze, bool is_json)
+static void print_nand_stats_fb(__u8 *buf, __u8 *buf2, __u8 nsze, bool is_json, __u8 spec)
{
struct json_object *root;
struct json_object *logPages;
@@ -1244,20 +1265,22 @@ static void print_nand_stats_fb(__u8 *buf, __u8 *buf2, __u8 nsze, bool is_json)
logPages);
}
- print_micron_vs_logs(buf, fb_log_page, field_count, stats);
+ print_micron_vs_logs(buf, fb_log_page, field_count, stats, spec);
/* print last three entries from D0 log page */
- init_d0_log_page(buf2, nsze);
+ if (buf2 != NULL) {
+ init_d0_log_page(buf2, nsze);
- if (is_json) {
- for (int i = 4; i < 7; i++) {
- json_object_add_value_string(stats,
- d0_log_page[i].field,
- d0_log_page[i].datastr);
- }
- } else {
- for (int i = 4; i < 7; i++) {
- printf("%-40s : %s\n", d0_log_page[i].field, d0_log_page[i].datastr);
+ if (is_json) {
+ for (int i = 0; i < 7; i++) {
+ json_object_add_value_string(stats,
+ d0_log_page[i].field,
+ d0_log_page[i].datastr);
+ }
+ } else {
+ for (int i = 0; i < 7; i++) {
+ printf("%-40s : %s\n", d0_log_page[i].field, d0_log_page[i].datastr);
+ }
}
}
@@ -1337,14 +1360,16 @@ static int micron_nand_stats(int argc, char **argv,
is_json = false;
err = nvme_identify_ctrl(fd, &ctrl);
- if (err)
+ if (err) {
+ printf("Error %d retrieving controller identification data\n", err);
goto out;
+ }
/* pull log details based on the model name */
sscanf(argv[optind], "/dev/nvme%d", &ctrlIdx);
if ((eModel = GetDriveModel(ctrlIdx)) == UNKNOWN_MODEL) {
printf ("Unsupported drive model for vs-nand-stats command\n");
- close(fd);
+ err = -1;
goto out;
}
@@ -1353,27 +1378,29 @@ static int micron_nand_stats(int argc, char **argv,
has_d0_log = (0 == err);
/* should check for firmware version if this log is supported or not */
- if (eModel == M5407 || eModel == M5410) {
+ if (eModel != M5407 && eModel != M5410) {
err = nvme_get_log(fd, NVME_NSID_ALL, 0xFB, false, NVME_NO_LOG_LSP,
FB_log_size, logFB);
has_fb_log = (0 == err);
}
nsze = (ctrl.vs[987] == 0x12);
+
if (nsze == 0 && nsze_from_oacs)
nsze = ((ctrl.oacs >> 3) & 0x1);
- err = 0;
- if (has_fb_log)
- print_nand_stats_fb((__u8 *)logFB, (__u8 *)extSmartLog, nsze, is_json);
- else if (has_d0_log)
+
+ if (has_fb_log) {
+ __u8 spec = (eModel == M5410) ? 0 : 1; /* FB spec version */
+ print_nand_stats_fb((__u8 *)logFB, (__u8 *)extSmartLog, nsze, is_json, spec);
+ } else if (has_d0_log) {
print_nand_stats_d0((__u8 *)extSmartLog, nsze, is_json);
- else {
- printf("Unable to retrieve extended smart log for the drive\n");
- err = -ENOTTY;
+ err = 0;
}
out:
close(fd);
- return err;
+ if (err > 0)
+ nvme_show_status(err);
+ return nvme_status_to_errno(err, false);
}
@@ -1483,6 +1510,62 @@ static void GetErrorlogData(int fd, int entries, const char *dir)
free(error_log);
}
+static void GetGenericLogs(int fd, const char *dir)
+{
+ struct nvme_self_test_log self_test_log;
+ struct nvme_firmware_log_page fw_log;
+ struct nvme_effects_log_page effects;
+ struct nvme_persistent_event_log_head pevent_log_head;
+ void *pevent_log_info = NULL;
+ __u32 log_len = 0;
+ int err = 0 ;
+ bool huge = false;
+
+ /* get self test log */
+ if (nvme_self_test_log(fd, sizeof(self_test_log), &self_test_log) == 0) {
+ WriteData((__u8*)&self_test_log, sizeof(self_test_log), dir,
+ "drive_self_test.bin", "self test log");
+ }
+
+ /* get fw slot info log */
+ if (nvme_fw_log(fd, &fw_log) == 0) {
+ WriteData((__u8*)&fw_log, sizeof(fw_log), dir,
+ "firmware_slot_info_log.bin", "firmware log");
+ }
+
+ /* get effects log */
+ if (nvme_effects_log(fd, &effects) == 0) {
+ WriteData((__u8*)&effects, sizeof(effects), dir,
+ "command_effects_log.bin", "effects log");
+ }
+
+ /* get persistent event log */
+ (void)nvme_persistent_event_log(fd, NVME_PEVENT_LOG_RELEASE_CTX,
+ sizeof(pevent_log_head), &pevent_log_head);
+ memset(&pevent_log_head, 0, sizeof(pevent_log_head));
+ err = nvme_persistent_event_log(fd, NVME_PEVENT_LOG_EST_CTX_AND_READ,
+ sizeof(pevent_log_head), &pevent_log_head);
+ if (err) {
+ fprintf(stderr, "Setting persistent event log read ctx failed (ignored)!\n");
+ return;
+ }
+
+ log_len = le64_to_cpu(pevent_log_head.tll);
+ pevent_log_info = nvme_alloc(log_len, &huge);
+ if (!pevent_log_info) {
+ perror("could not alloc buffer for persistent event log page (ignored)!\n");
+ return;
+ }
+ err = nvme_persistent_event_log(fd, NVME_PEVENT_LOG_READ,
+ log_len, pevent_log_info);
+ if (err == 0) {
+ WriteData((__u8*)pevent_log_info, log_len, dir,
+ "persistent_event_log.bin", "persistent event log");
+ }
+ nvme_free(pevent_log_info, huge);
+ return;
+}
+
static void GetNSIDDInfo(int fd, const char *dir, int nsid)
{
char file[PATH_MAX] = { 0 };
@@ -1537,14 +1620,14 @@ static void GetOSConfig(const char *strOSDirName)
static int micron_telemetry_log(int fd, __u8 gen, __u8 type, __u8 **data,
int *logSize, int da)
{
- int err;
+ int err, bs = 512, offset = bs;
unsigned short data_area[4];
unsigned char ctrl_init = (type == 0x8);
- __u8 *buffer = (unsigned char *)calloc(512, 1);
+ __u8 *buffer = (unsigned char *)calloc(bs, 1);
if (buffer == NULL)
return -1;
- err = nvme_get_telemetry_log(fd, buffer, gen, ctrl_init, 512, 0);
+ err = nvme_get_telemetry_log(fd, buffer, gen, ctrl_init, bs, 0);
if (err != 0) {
fprintf(stderr, "Failed to get telemetry log header for 0x%X\n", type);
if (buffer != NULL) {
@@ -1553,10 +1636,10 @@ static int micron_telemetry_log(int fd, __u8 gen, __u8 type, __u8 **data,
return err;
}
- // compute size of the log
- data_area[1] = buffer[9] << 16 | buffer[8];
- data_area[2] = buffer[11] << 16 | buffer[10];
- data_area[3] = buffer[13] << 16 | buffer[12];
+ /* compute size of the log */
+ data_area[1] = buffer[9] << 8 | buffer[8];
+ data_area[2] = buffer[11] << 8 | buffer[10];
+ data_area[3] = buffer[13] << 8 | buffer[12];
data_area[0] = data_area[1] > data_area[2] ? data_area[1] : data_area[2];
data_area[0] = data_area[3] > data_area[0] ? data_area[3] : data_area[0];
@@ -1569,9 +1652,14 @@ static int micron_telemetry_log(int fd, __u8 gen, __u8 type, __u8 **data,
return -1;
}
- *logSize = data_area[da] * 512;
+ *logSize = data_area[da] * bs;
+ offset = bs;
+ err = 0;
if ((buffer = (unsigned char *)realloc(buffer, (size_t)(*logSize))) != NULL) {
- err = nvme_get_telemetry_log(fd, buffer, gen, ctrl_init, *logSize, 0);
+ while (err == 0 && offset != *logSize) {
+ err = nvme_get_telemetry_log(fd, buffer + offset, gen, ctrl_init, bs, offset);
+ offset += bs;
+ }
}
if (err == 0 && buffer != NULL) {
@@ -1594,12 +1682,13 @@ static int GetTelemetryData(int fd, const char *dir)
__u8 log;
char *file;
} tmap[] = {
- {0x07, "nvme_host_telemetry.bin"},
- {0x08, "nvme_cntrl_telemetry.bin"},
+ {0x07, "nvmetelemetrylog.bin"},
+ {0x08, "nvmetelemetrylog.bin"},
};
for(i = 0; i < (int)(sizeof(tmap)/sizeof(tmap[0])); i++) {
- err = micron_telemetry_log(fd, 0, tmap[i].log, &buffer, &logSize, 0);
+ err = micron_telemetry_log(fd, (tmap[i].log == 0x07),
+ tmap[i].log, &buffer, &logSize, 0);
if (err == 0 && logSize > 0 && buffer != NULL) {
sprintf(msg, "telemetry log: 0x%X", tmap[i].log);
WriteData(buffer, logSize, dir, tmap[i].file, msg);
@@ -1646,7 +1735,7 @@ static int GetFeatureSettings(int fd, const char *dir)
bufp = NULL;
}
- err = nvme_get_feature(fd, 1, fmap[i].id, 0, 0x0, len, bufp, &attrVal);
+ err = nvme_get_feature(fd, 1, fmap[i].id, 0, 0x0, 0, len, bufp, &attrVal);
if (err == 0) {
sprintf(msg, "feature: 0x%X", fmap[i].id);
WriteData((__u8*)&attrVal, sizeof(attrVal), dir, fmap[i].file, msg);
@@ -1654,7 +1743,8 @@ static int GetFeatureSettings(int fd, const char *dir)
WriteData(bufp, len, dir, fmap[i].file, msg);
}
} else {
- printf("Failed to retrieve feature 0x%x data !\n", fmap[i].id);
+ fprintf(stderr, "Feature 0x%x data not retrieved, error %d (ignored)!\n",
+ fmap[i].id, err);
errcnt++;
}
}
@@ -1667,20 +1757,98 @@ static int micron_drive_info(int argc, char **argv, struct command *cmd,
const char *desc = "Get drive HW information";
int fd, err = 0;
struct nvme_id_ctrl ctrl = { 0 };
+ struct nvme_admin_cmd admin_cmd = { 0 };
+ struct fb_drive_info {
+ unsigned char hw_ver_major;
+ unsigned char hw_ver_minor;
+ unsigned char ftl_unit_size;
+ unsigned char bs_ver_major;
+ unsigned char bs_ver_minor;
+ } dinfo = { 0 };
+ eDriveModel model = UNKNOWN_MODEL;
+ bool is_json = false;
+ struct json_object *root, *driveInfo;
+ struct format {
+ char *fmt;
+ };
+
+ const char *fmt = "output format normal";
+ struct format cfg = {
+ .fmt = "normal",
+ };
+
OPT_ARGS(opts) = {
+ OPT_FMT("format", 'f', &cfg.fmt, fmt),
OPT_END()
};
- if ((fd = micron_parse_options(argc, argv, desc, opts, NULL)) < 0)
+ if ((fd = micron_parse_options(argc, argv, desc, opts, &model)) < 0)
return err;
- err = nvme_identify_ctrl(fd, &ctrl);
- if (err) {
- fprintf(stderr, "ERROR : nvme_identify_ctrl() failed with 0x%x\n", err);
+ if (model == UNKNOWN_MODEL) {
+ fprintf(stderr, "ERROR : Unsupported drive for vs-drive-info cmd");
return -1;
}
- printf("%u.%u\n", ctrl.vs[820], ctrl.vs[821]);
+ if (strcmp(cfg.fmt, "json") == 0)
+ is_json = true;
+
+ if (model == M5407) {
+ admin_cmd.opcode = 0xDA,
+ admin_cmd.addr = (__u64) (uintptr_t) &dinfo;
+ admin_cmd.data_len = (__u32)sizeof(dinfo);
+ admin_cmd.cdw12 = 3;
+ err = ioctl(fd, NVME_IOCTL_ADMIN_CMD, &admin_cmd);
+ if (err) {
+ fprintf(stderr, "ERROR : drive-info opcode failed with 0x%x\n", err);
+ return -1;
+ }
+ } else {
+ err = nvme_identify_ctrl(fd, &ctrl);
+ if (err) {
+ fprintf(stderr, "ERROR : identify_ctrl() failed with 0x%x\n", err);
+ return -1;
+ }
+ dinfo.hw_ver_major = ctrl.vs[820];
+ dinfo.hw_ver_minor = ctrl.vs[821];
+ }
+
+ if (is_json) {
+ struct json_object *pinfo = json_create_object();
+ char tempstr[64] = { 0 };
+ root = json_create_object();
+ driveInfo = json_create_array();
+ json_object_add_value_array(root, "Micron Drive HW Information", driveInfo);
+ sprintf(tempstr, "%hhu.%hhu", dinfo.hw_ver_major, dinfo.hw_ver_minor);
+ json_object_add_value_string(pinfo, "Drive Hardware Version", tempstr);
+
+ if (dinfo.ftl_unit_size) {
+ sprintf(tempstr, "%hhu KB", dinfo.ftl_unit_size);
+ json_object_add_value_string(pinfo, "FTL_unit_size", tempstr);
+ }
+
+ if (dinfo.bs_ver_major != 0 || dinfo.bs_ver_minor != 0) {
+ sprintf(tempstr, "%hhu.%hhu", dinfo.bs_ver_major, dinfo.bs_ver_minor);
+ json_object_add_value_string(pinfo, "Boot Spec.Version", tempstr);
+ }
+
+ json_array_add_value_object(driveInfo, pinfo);
+ json_print_object(root, NULL);
+ printf("\n");
+ json_free_object(root);
+ } else {
+ printf("Drive Hardware Version: %hhu.%hhu\n",
+ dinfo.hw_ver_major, dinfo.hw_ver_minor);
+
+ if (dinfo.ftl_unit_size)
+ printf("FTL_unit_size: %hhu KB\n", dinfo.ftl_unit_size);
+
+ if (dinfo.bs_ver_major != 0 || dinfo.bs_ver_minor != 0) {
+ printf("Boot Spec.Version: %hhu.%hhu\n",
+ dinfo.bs_ver_major, dinfo.bs_ver_minor);
+ }
+ }
+
return 0;
}
@@ -1825,8 +1993,7 @@ static int micron_fw_activation_history(int argc, char **argv, struct command *c
int count = 0;
unsigned int logC2[C2_log_size/sizeof(int)] = { 0 };
eDriveModel eModel = UNKNOWN_MODEL;
- struct nvme_id_ctrl ctrl;
- int fd, err, ctrlIdx;
+ int fd, err;
struct format {
char *fmt;
};
@@ -1841,9 +2008,7 @@ static int micron_fw_activation_history(int argc, char **argv, struct command *c
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0) {
- printf("\nDevice not found \n");;
+ if ((fd = micron_parse_options(argc, argv, desc, opts, &eModel)) < 0) {
return -1;
}
@@ -1853,16 +2018,8 @@ static int micron_fw_activation_history(int argc, char **argv, struct command *c
return -1;
}
- err = nvme_identify_ctrl(fd, &ctrl);
- if (err) {
- fprintf(stderr, "failed get device identification data, error: %x\n", err);
- goto out;
- }
-
/* check if product supports fw_history log */
err = -EINVAL;
- sscanf(argv[optind], "/dev/nvme%d", &ctrlIdx);
- eModel = GetDriveModel(ctrlIdx);
if (eModel != M51CX) {
fprintf(stderr, "Unsupported drive model for vs-fw-activate-history command\n");
goto out;
@@ -1916,18 +2073,19 @@ static int micron_error_reason(int argc, char **argv, struct command *cmd,
static int micron_ocp_smart_health_logs(int argc, char **argv, struct command *cmd,
struct plugin *plugin)
{
- const char *desc = "Retrieve Micron OCP Smart Health log for the given device ";
+ const char *desc = "Retrieve Smart or Extended Smart Health log for the given device ";
unsigned int logC0[C0_log_size/sizeof(int)] = { 0 };
- eDriveModel eModel = UNKNOWN_MODEL;
+ unsigned int logFB[FB_log_size/sizeof(int)] = { 0 };
struct nvme_id_ctrl ctrl;
- int fd, err, ctrlIdx;
- bool is_json = false;
+ eDriveModel eModel = UNKNOWN_MODEL;
+ int fd, err = 0;
+ bool is_json = true;
struct format {
char *fmt;
};
const char *fmt = "output format normal|json";
struct format cfg = {
- .fmt = "normal",
+ .fmt = "json",
};
OPT_ARGS(opts) = {
@@ -1935,41 +2093,53 @@ static int micron_ocp_smart_health_logs(int argc, char **argv, struct command *c
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0) {
- printf("\nDevice not found \n");;
+ if ((fd = micron_parse_options(argc, argv, desc, opts, &eModel)) < 0) {
return -1;
}
- if (strcmp(cfg.fmt, "json") == 0)
- is_json = true;
+ if (strcmp(cfg.fmt, "normal") == 0)
+ is_json = false;
- err = nvme_identify_ctrl(fd, &ctrl);
- if (err)
+ /* For M5410 and M5407, this option prints 0xFB log page */
+ if (eModel == M5410 || eModel == M5407) {
+ __u8 spec = (eModel == M5410) ? 0 : 1;
+ __u8 nsze;
+
+ if ((err = nvme_identify_ctrl(fd, &ctrl)) == 0)
+ err = nvme_get_log(fd, NVME_NSID_ALL, 0xFB, false, NVME_NO_LOG_LSP,
+ FB_log_size, logFB);
+ if (err) {
+ if (err < 0)
+ printf("Unable to retrieve smart log 0xFB for the drive\n");
+ goto out;
+ }
+
+ nsze = (ctrl.vs[987] == 0x12);
+ if (nsze == 0 && nsze_from_oacs)
+ nsze = ((ctrl.oacs >> 3) & 0x1);
+ print_nand_stats_fb((__u8 *)logFB, NULL, nsze, is_json, spec);
goto out;
+ }
- /* pull log details based on the model name */
- sscanf(argv[optind], "/dev/nvme%d", &ctrlIdx);
- if ((eModel = GetDriveModel(ctrlIdx)) == UNKNOWN_MODEL) {
+ /* check for models that support 0xC0 log */
+ if (eModel != M51CX) {
printf ("Unsupported drive model for vs-smart-add-log commmand\n");
- close(fd);
+ err = -1;
goto out;
}
- /* should check for firmware version if this log is supported or not */
- if (eModel == M5407 || eModel == M5410) {
- err = nvme_get_log(fd, NVME_NSID_ALL, 0xC0, false, NVME_NO_LOG_LSP,
- C0_log_size, logC0);
- }
- if (err < 0) {
- printf("Unable to retrieve extended smart log for the drive\n");
- err = -ENOTTY;
- } else {
+ err = nvme_get_log(fd, NVME_NSID_ALL, 0xC0, false, NVME_NO_LOG_LSP,
+ C0_log_size, logC0);
+ if (err == 0) {
print_smart_cloud_health_log((__u8 *)logC0, is_json);
+ } else if (err < 0) {
+ printf("Unable to retrieve extended smart log 0xC0 for the drive\n");
}
out:
close(fd);
- return err;
+ if (err > 0)
+ nvme_show_status(err);
+ return nvme_status_to_errno(err, false);
}
static int micron_clr_fw_activation_history(int argc, char **argv,
@@ -1994,7 +2164,7 @@ static int micron_clr_fw_activation_history(int argc, char **argv,
}
//err = nvme_set_feature(fd, 1, fid, cdw11, 0, opt.save, 0, 0, &result);
- err = nvme_set_feature(fd, 1, fid, 0, 0, 0, 0, 0, &result);
+ err = nvme_set_feature(fd, 1, fid, 0, 0, 0, 0, 0, 0, &result);
if (err == 0) err = (int)result;
return err;
}
@@ -2040,14 +2210,14 @@ static int micron_telemetry_cntrl_option(int argc, char **argv,
}
if (!strcmp(opt.option, "enable")) {
- err = nvme_set_feature(fd, 1, fid, 1, 0, (opt.select & 0x1), 0, 0, &result);
+ err = nvme_set_feature(fd, 1, fid, 1, 0, (opt.select & 0x1), 0, 0, 0, &result);
if (err == 0) {
printf("successfully set controller telemetry option\n");
} else {
printf("Failed to set controller telemetry option\n");
}
} else if (!strcmp(opt.option, "disable")) {
- err = nvme_set_feature(fd, 1, fid, 0, 0, (opt.select & 0x1), 0, 0, &result);
+ err = nvme_set_feature(fd, 1, fid, 0, 0, (opt.select & 0x1), 0, 0, 0, &result);
if (err == 0) {
printf("successfully disabled controller telemetry option\n");
} else {
@@ -2055,7 +2225,7 @@ static int micron_telemetry_cntrl_option(int argc, char **argv,
}
} else if (!strcmp(opt.option, "status")) {
opt.select &= 0x3;
- err = nvme_get_feature(fd, 1, fid, opt.select, 0, 0, 0, &result);
+ err = nvme_get_feature(fd, 1, fid, opt.select, 0, 0, 0, 0, &result);
if (err == 0) {
printf("Controller telemetry option : %s\n",
(result) ? "enabled" : "disabled");
@@ -2249,6 +2419,7 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd,
GetSmartlogData(fd, strCtrlDirName);
GetErrorlogData(fd, ctrl.elpe, strCtrlDirName);
+ GetGenericLogs(fd, strCtrlDirName);
// pull if telemetry log data is supported
if ((ctrl.lpa & 0x8) == 0x8)
@@ -2256,7 +2427,7 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd,
GetFeatureSettings(fd, strCtrlDirName);
- if (eModel != M5410) {
+ if (eModel != M5410 && eModel != M5407) {
memcpy(aVendorLogs, aM51XXLogs, sizeof(aM51XXLogs));
if (eModel == M51AX)
memcpy((char *)aVendorLogs + sizeof(aM51XXLogs), aM51AXLogs, sizeof(aM51AXLogs));
diff --git a/plugins/micron/micron-nvme.h b/plugins/micron/micron-nvme.h
index 118f8cd..be80544 100644
--- a/plugins/micron/micron-nvme.h
+++ b/plugins/micron/micron-nvme.h
@@ -6,8 +6,9 @@
#include "cmd.h"
-PLUGIN(NAME("micron", "Micron vendor specific extensions"),
- COMMAND_LIST(ENTRY("select-download", "Selective Firmware Download", micron_selective_download)
+PLUGIN(NAME("micron", "Micron vendor specific extensions", NVME_VERSION),
+ COMMAND_LIST(
+ ENTRY("select-download", "Selective Firmware Download", micron_selective_download)
ENTRY("vs-temperature-stats", "Retrieve Micron temperature statistics ", micron_temp_stats)
ENTRY("vs-pcie-stats", "Retrieve Micron PCIe error stats", micron_pcie_stats)
ENTRY("clear-pcie-correctable-errors", "Clear correctable PCIe errors", micron_clear_pcie_correctable_errors)
diff --git a/plugins/netapp/netapp-nvme.h b/plugins/netapp/netapp-nvme.h
index d4eebd6..2599db0 100644
--- a/plugins/netapp/netapp-nvme.h
+++ b/plugins/netapp/netapp-nvme.h
@@ -6,7 +6,7 @@
#include "cmd.h"
-PLUGIN(NAME("netapp", "NetApp vendor specific extensions"),
+PLUGIN(NAME("netapp", "NetApp vendor specific extensions", NVME_VERSION),
COMMAND_LIST(
ENTRY("smdevices", "NetApp SMdevices", netapp_smdevices)
ENTRY("ontapdevices", "NetApp ONTAPdevices", netapp_ontapdevices)
diff --git a/plugins/nvidia/nvidia-nvme.h b/plugins/nvidia/nvidia-nvme.h
index bf562b9..74a20b8 100644
--- a/plugins/nvidia/nvidia-nvme.h
+++ b/plugins/nvidia/nvidia-nvme.h
@@ -6,7 +6,7 @@
#include "cmd.h"
-PLUGIN(NAME("nvidia", "NVIDIA vendor specific extensions"),
+PLUGIN(NAME("nvidia", "NVIDIA vendor specific extensions", NVME_VERSION),
COMMAND_LIST(
ENTRY("id-ctrl", "Send NVMe Identify Controller", id_ctrl)
)
diff --git a/plugins/scaleflux/sfx-nvme.h b/plugins/scaleflux/sfx-nvme.h
index 8f14501..fde5ba3 100644
--- a/plugins/scaleflux/sfx-nvme.h
+++ b/plugins/scaleflux/sfx-nvme.h
@@ -6,7 +6,7 @@
#include "cmd.h"
-PLUGIN(NAME("sfx", "ScaleFlux vendor specific extensions"),
+PLUGIN(NAME("sfx", "ScaleFlux vendor specific extensions", NVME_VERSION),
COMMAND_LIST(
ENTRY("smart-log-add", "Retrieve ScaleFlux SMART Log, show it", get_additional_smart_log)
ENTRY("lat-stats", "Retrieve ScaleFlux IO Latency Statistics log, show it", get_lat_stats_log)
diff --git a/plugins/seagate/seagate-nvme.c b/plugins/seagate/seagate-nvme.c
index d5ef32b..9512cda 100644
--- a/plugins/seagate/seagate-nvme.c
+++ b/plugins/seagate/seagate-nvme.c
@@ -1051,7 +1051,7 @@ static int vs_clr_pcie_correctable_errs(int argc, char **argv, struct command *c
fd = parse_and_open(argc, argv, desc, opts);
- err = nvme_set_feature(fd, 0, 0xE1, 0xCB, 0, cfg.save, 0, buf, &result);
+ err = nvme_set_feature(fd, 0, 0xE1, 0xCB, 0, cfg.save, 0, 0, buf, &result);
if (err < 0) {
perror("set-feature");
diff --git a/plugins/seagate/seagate-nvme.h b/plugins/seagate/seagate-nvme.h
index f570697..a4989f1 100644
--- a/plugins/seagate/seagate-nvme.h
+++ b/plugins/seagate/seagate-nvme.h
@@ -27,7 +27,7 @@
#include "cmd.h"
-PLUGIN(NAME("seagate", "Seagate vendor specific extensions"),
+PLUGIN(NAME("seagate", "Seagate vendor specific extensions", NVME_VERSION),
COMMAND_LIST(
ENTRY("vs-temperature-stats", "Retrieve Seagate temperature statistics ", temp_stats)
ENTRY("vs-log-page-sup", "Retrieve Seagate Supported Log-pages Information ", log_pages_supp)
diff --git a/plugins/shannon/shannon-nvme.c b/plugins/shannon/shannon-nvme.c
index 588f4f3..1909e45 100644
--- a/plugins/shannon/shannon-nvme.c
+++ b/plugins/shannon/shannon-nvme.c
@@ -231,7 +231,7 @@ static int get_additional_feature(int argc, char **argv, struct command *cmd, st
memset(buf, 0, cfg.data_len);
}
- err = nvme_get_feature(fd, cfg.namespace_id, cfg.feature_id, cfg.sel, cfg.cdw11,
+ err = nvme_get_feature(fd, cfg.namespace_id, cfg.feature_id, cfg.sel, cfg.cdw11, 0,
cfg.data_len, buf, &result);
if (!err) {
printf("get-feature:0x%02x (%s), %s value: %#08x\n", cfg.feature_id,
@@ -344,7 +344,7 @@ static int set_additional_feature(int argc, char **argv, struct command *cmd, st
}
err = nvme_set_feature(fd, cfg.namespace_id, cfg.feature_id, cfg.value,
- 0, cfg.save, cfg.data_len, buf, &result);
+ 0, cfg.save, 0, cfg.data_len, buf, &result);
if (err < 0) {
perror("set-feature");
goto free;
diff --git a/plugins/shannon/shannon-nvme.h b/plugins/shannon/shannon-nvme.h
index d40732e..db25828 100644
--- a/plugins/shannon/shannon-nvme.h
+++ b/plugins/shannon/shannon-nvme.h
@@ -6,7 +6,7 @@
#include "cmd.h"
-PLUGIN(NAME("shannon", "Shannon vendor specific extensions"),
+PLUGIN(NAME("shannon", "Shannon vendor specific extensions", NVME_VERSION),
COMMAND_LIST(
ENTRY("smart-log-add", "Retrieve Shannon SMART Log, show it", get_additional_smart_log)
ENTRY("get-feature-add", "Get Shannon feature and show the resulting value", get_additional_feature)
diff --git a/plugins/toshiba/toshiba-nvme.c b/plugins/toshiba/toshiba-nvme.c
index 53d54bc..cba1af8 100644
--- a/plugins/toshiba/toshiba-nvme.c
+++ b/plugins/toshiba/toshiba-nvme.c
@@ -551,7 +551,7 @@ static int clear_correctable_errors(int argc, char **argv, struct command *cmd,
goto end;
err = nvme_set_feature(fd, namespace_id, feature_id, value, cdw12, save,
- 0, NULL, &result);
+ 0, 0, NULL, &result);
if (err)
fprintf(stderr, "%s: couldn't clear PCIe correctable errors \n",
__func__);
diff --git a/plugins/toshiba/toshiba-nvme.h b/plugins/toshiba/toshiba-nvme.h
index c405e78..ebd7575 100644
--- a/plugins/toshiba/toshiba-nvme.h
+++ b/plugins/toshiba/toshiba-nvme.h
@@ -7,7 +7,7 @@
#include "cmd.h"
#include "plugin.h"
-PLUGIN(NAME("toshiba", "Toshiba NVME plugin"),
+PLUGIN(NAME("toshiba", "Toshiba NVME plugin", NVME_VERSION),
COMMAND_LIST(
ENTRY("vs-smart-add-log", "Extended SMART information", vendor_log)
ENTRY("vs-internal-log", "Get Internal Log", internal_log)
diff --git a/plugins/transcend/transcend-nvme.h b/plugins/transcend/transcend-nvme.h
index 14d62ec..317793a 100644
--- a/plugins/transcend/transcend-nvme.h
+++ b/plugins/transcend/transcend-nvme.h
@@ -7,7 +7,7 @@
#include "cmd.h"
-PLUGIN(NAME("transcend", "Transcend vendor specific extensions"),
+PLUGIN(NAME("transcend", "Transcend vendor specific extensions", NVME_VERSION),
COMMAND_LIST(
ENTRY("healthvalue", "NVME health percentage", getHealthValue)
ENTRY("badblock", "Get NVME bad block number", getBadblock)
diff --git a/plugins/virtium/virtium-nvme.h b/plugins/virtium/virtium-nvme.h
index b95c910..124ab18 100644
--- a/plugins/virtium/virtium-nvme.h
+++ b/plugins/virtium/virtium-nvme.h
@@ -7,7 +7,7 @@
#include "cmd.h"
#include "plugin.h"
-PLUGIN(NAME("virtium", "Virtium vendor specific extensions"),
+PLUGIN(NAME("virtium", "Virtium vendor specific extensions", NVME_VERSION),
COMMAND_LIST(
ENTRY("save-smart-to-vtview-log", "Periodically save smart attributes into a log file.\n\
The data in this log file can be analyzed using excel or using Virtium’s vtView.\n\
diff --git a/plugins/wdc/wdc-nvme.c b/plugins/wdc/wdc-nvme.c
index f7a5b31..4468344 100644
--- a/plugins/wdc/wdc-nvme.c
+++ b/plugins/wdc/wdc-nvme.c
@@ -79,6 +79,8 @@
#define WDC_NVME_SN650_DEV_ID_1 0x2701
#define WDC_NVME_SN650_DEV_ID_2 0x2702
#define WDC_NVME_SN650_DEV_ID_3 0x2720
+#define WDC_NVME_SN450_DEV_ID_1 0x2712
+#define WDC_NVME_SN450_DEV_ID_2 0x2713
#define WDC_NVME_SXSLCL_DEV_ID 0x2001
#define WDC_NVME_SN520_DEV_ID 0x5003
#define WDC_NVME_SN520_DEV_ID_1 0x5004
@@ -125,6 +127,7 @@
#define WDC_DRIVE_CAP_DUI_DATA 0x0000000200000000
#define WDC_SN730B_CAP_VUC_LOG 0x0000000400000000
#define WDC_DRIVE_CAP_DUI 0x0000000800000000
+#define WDC_DRIVE_CAP_PURGE 0x0000001000000000
#define WDC_DRIVE_CAP_SMART_LOG_MASK (WDC_DRIVE_CAP_C0_LOG_PAGE | WDC_DRIVE_CAP_C1_LOG_PAGE | \
WDC_DRIVE_CAP_CA_LOG_PAGE | WDC_DRIVE_CAP_D0_LOG_PAGE)
#define WDC_DRIVE_CAP_CLEAR_PCIE_MASK (WDC_DRIVE_CAP_CLEAR_PCIE | \
@@ -954,7 +957,7 @@ struct __attribute__((__packed__)) wdc_fw_act_history_log_format_c2 {
__u8 log_identifier;
__u8 reserved[3];
__le32 num_entries;
- struct wdc_fw_act_history_log_entry_c2 entry[20];
+ struct wdc_fw_act_history_log_entry_c2 entry[WDC_MAX_NUM_ACT_HIST_ENTRIES];
__u8 reserved2[2790];
__le16 log_page_version;
__u8 log_page_guid[WDC_C2_GUID_LENGTH];
@@ -1181,11 +1184,13 @@ static __u64 wdc_get_drive_capabilities(int fd) {
switch (read_device_id) {
case WDC_NVME_SN100_DEV_ID:
capabilities = (WDC_DRIVE_CAP_CAP_DIAG | WDC_DRIVE_CAP_INTERNAL_LOG | WDC_DRIVE_CAP_C1_LOG_PAGE |
- WDC_DRIVE_CAP_DRIVE_LOG | WDC_DRIVE_CAP_CRASH_DUMP | WDC_DRIVE_CAP_PFAIL_DUMP);
+ WDC_DRIVE_CAP_DRIVE_LOG | WDC_DRIVE_CAP_CRASH_DUMP | WDC_DRIVE_CAP_PFAIL_DUMP |
+ WDC_DRIVE_CAP_PURGE);
break;
case WDC_NVME_SN200_DEV_ID:
capabilities = (WDC_DRIVE_CAP_CAP_DIAG | WDC_DRIVE_CAP_INTERNAL_LOG | WDC_DRIVE_CAP_CLEAR_PCIE |
- WDC_DRIVE_CAP_DRIVE_LOG | WDC_DRIVE_CAP_CRASH_DUMP | WDC_DRIVE_CAP_PFAIL_DUMP);
+ WDC_DRIVE_CAP_DRIVE_LOG | WDC_DRIVE_CAP_CRASH_DUMP | WDC_DRIVE_CAP_PFAIL_DUMP |
+ WDC_DRIVE_CAP_PURGE);
/* verify the 0xCA log page is supported */
if (wdc_nvme_check_supported_log_page(fd, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE) == true)
@@ -1287,6 +1292,8 @@ static __u64 wdc_get_drive_capabilities(int fd) {
case WDC_NVME_SN650_DEV_ID_1:
case WDC_NVME_SN650_DEV_ID_2:
case WDC_NVME_SN650_DEV_ID_3:
+ case WDC_NVME_SN450_DEV_ID_1:
+ case WDC_NVME_SN450_DEV_ID_2:
/* verify the 0xC0 log page is supported */
if (wdc_nvme_check_supported_log_page(fd, WDC_NVME_GET_EOL_STATUS_LOG_OPCODE) == true) {
capabilities |= WDC_DRIVE_CAP_C0_LOG_PAGE;
@@ -1614,7 +1621,7 @@ static bool get_dev_mgment_cbs_data(int fd, __u8 log_id, void **cbs_data)
memset(data, 0, sizeof (__u8) * WDC_C2_LOG_BUF_LEN);
/* get the log page length */
- ret = nvme_get_log14(fd, 0xFFFFFFFF, lid, NVME_NO_LOG_LSP, 0, 0, false, uuid_ix, WDC_C2_LOG_BUF_LEN, data);
+ ret = nvme_get_log14(fd, 0xFFFFFFFF, lid, NVME_NO_LOG_LSP, 0, 0, false, uuid_ix, 0, false, WDC_C2_LOG_BUF_LEN, data);
if (ret) {
fprintf(stderr, "ERROR : WDC : Unable to get 0x%x Log Page length, ret = 0x%x\n", lid, ret);
goto end;
@@ -1633,7 +1640,7 @@ static bool get_dev_mgment_cbs_data(int fd, __u8 log_id, void **cbs_data)
}
/* get the log page data */
- ret = nvme_get_log14(fd, 0xFFFFFFFF, lid, NVME_NO_LOG_LSP, 0, 0, false, uuid_ix, le32_to_cpu(hdr_ptr->length), data);
+ ret = nvme_get_log14(fd, 0xFFFFFFFF, lid, NVME_NO_LOG_LSP, 0, 0, false, uuid_ix, 0, false, le32_to_cpu(hdr_ptr->length), data);
if (ret) {
fprintf(stderr, "ERROR : WDC : Unable to read 0x%x Log Page data, ret = 0x%x\n", lid, ret);
goto end;
@@ -1652,7 +1659,7 @@ static bool get_dev_mgment_cbs_data(int fd, __u8 log_id, void **cbs_data)
/* not found with uuid = 1 try with uuid = 0 */
uuid_ix = 0;
/* get the log page data */
- ret = nvme_get_log14(fd, 0xFFFFFFFF, lid, NVME_NO_LOG_LSP, 0, 0, false, uuid_ix, le32_to_cpu(hdr_ptr->length), data);
+ ret = nvme_get_log14(fd, 0xFFFFFFFF, lid, NVME_NO_LOG_LSP, 0, 0, false, uuid_ix, 0, false, le32_to_cpu(hdr_ptr->length), data);
hdr_ptr = (struct wdc_c2_log_page_header *)data;
sph = (struct wdc_c2_log_subpage_header *)(data + length);
found = wdc_get_dev_mng_log_entry(hdr_ptr->length, log_id, hdr_ptr, &sph);
@@ -1980,7 +1987,7 @@ static int wdc_do_cap_telemetry_log(int fd, char *file, __u32 bs, int type, int
} else if (type == WDC_TELEMETRY_TYPE_CONTROLLER) {
/* Verify the Controller Initiated Option is enabled */
err = nvme_get_feature(fd, 0, WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID, 0, 0,
- 4, buf, &result);
+ 0, 4, buf, &result);
if (err == 0) {
if (result == 0) {
/* enabled */
@@ -3263,15 +3270,12 @@ static int wdc_purge(int argc, char **argv,
char *err_str;
int fd, ret;
struct nvme_passthru_cmd admin_cmd;
+ __u64 capabilities = 0;
OPT_ARGS(opts) = {
OPT_END()
};
- err_str = "";
- memset(&admin_cmd, 0, sizeof (admin_cmd));
- admin_cmd.opcode = WDC_NVME_PURGE_CMD_OPCODE;
-
fd = parse_and_open(argc, argv, desc, opts);
if (fd < 0)
return fd;
@@ -3279,23 +3283,33 @@ static int wdc_purge(int argc, char **argv,
if (!wdc_check_device(fd))
return -1;
- ret = nvme_submit_admin_passthru(fd, &admin_cmd);
- if (ret > 0) {
- switch (ret) {
- case WDC_NVME_PURGE_CMD_SEQ_ERR:
- err_str = "ERROR : WDC : Cannot execute purge, "
- "Purge operation is in progress.\n";
- break;
- case WDC_NVME_PURGE_INT_DEV_ERR:
- err_str = "ERROR : WDC : Internal Device Error.\n";
- break;
- default:
- err_str = "ERROR : WDC\n";
+ capabilities = wdc_get_drive_capabilities(fd);
+ if((capabilities & WDC_DRIVE_CAP_PURGE) == 0) {
+ ret = -1;
+ fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ } else {
+ err_str = "";
+ memset(&admin_cmd, 0, sizeof (admin_cmd));
+ admin_cmd.opcode = WDC_NVME_PURGE_CMD_OPCODE;
+
+ ret = nvme_submit_admin_passthru(fd, &admin_cmd);
+ if (ret > 0) {
+ switch (ret) {
+ case WDC_NVME_PURGE_CMD_SEQ_ERR:
+ err_str = "ERROR : WDC : Cannot execute purge, "
+ "Purge operation is in progress.\n";
+ break;
+ case WDC_NVME_PURGE_INT_DEV_ERR:
+ err_str = "ERROR : WDC : Internal Device Error.\n";
+ break;
+ default:
+ err_str = "ERROR : WDC\n";
+ }
}
- }
- fprintf(stderr, "%s", err_str);
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ fprintf(stderr, "%s", err_str);
+ fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ }
return ret;
}
@@ -3308,19 +3322,12 @@ static int wdc_purge_monitor(int argc, char **argv,
double progress_percent;
struct nvme_passthru_cmd admin_cmd;
struct wdc_nvme_purge_monitor_data *mon;
+ __u64 capabilities = 0;
OPT_ARGS(opts) = {
OPT_END()
};
- memset(output, 0, sizeof (output));
- memset(&admin_cmd, 0, sizeof (struct nvme_admin_cmd));
- admin_cmd.opcode = WDC_NVME_PURGE_MONITOR_OPCODE;
- admin_cmd.addr = (__u64)(uintptr_t)output;
- admin_cmd.data_len = WDC_NVME_PURGE_MONITOR_DATA_LEN;
- admin_cmd.cdw10 = WDC_NVME_PURGE_MONITOR_CMD_CDW10;
- admin_cmd.timeout_ms = WDC_NVME_PURGE_MONITOR_TIMEOUT;
-
fd = parse_and_open(argc, argv, desc, opts);
if (fd < 0)
return fd;
@@ -3328,20 +3335,34 @@ static int wdc_purge_monitor(int argc, char **argv,
if (!wdc_check_device(fd))
return -1;
- ret = nvme_submit_admin_passthru(fd, &admin_cmd);
- if (ret == 0) {
- mon = (struct wdc_nvme_purge_monitor_data *) output;
- printf("Purge state = 0x%0x\n", admin_cmd.result);
- printf("%s\n", wdc_purge_mon_status_to_string(admin_cmd.result));
- if (admin_cmd.result == WDC_NVME_PURGE_STATE_BUSY) {
- progress_percent =
- ((double)le32_to_cpu(mon->entire_progress_current) * 100) /
- le32_to_cpu(mon->entire_progress_total);
- printf("Purge Progress = %f%%\n", progress_percent);
+ capabilities = wdc_get_drive_capabilities(fd);
+ if((capabilities & WDC_DRIVE_CAP_PURGE) == 0) {
+ ret = -1;
+ fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
+ } else {
+ memset(output, 0, sizeof (output));
+ memset(&admin_cmd, 0, sizeof (struct nvme_admin_cmd));
+ admin_cmd.opcode = WDC_NVME_PURGE_MONITOR_OPCODE;
+ admin_cmd.addr = (__u64)(uintptr_t)output;
+ admin_cmd.data_len = WDC_NVME_PURGE_MONITOR_DATA_LEN;
+ admin_cmd.cdw10 = WDC_NVME_PURGE_MONITOR_CMD_CDW10;
+ admin_cmd.timeout_ms = WDC_NVME_PURGE_MONITOR_TIMEOUT;
+
+ ret = nvme_submit_admin_passthru(fd, &admin_cmd);
+ if (ret == 0) {
+ mon = (struct wdc_nvme_purge_monitor_data *) output;
+ printf("Purge state = 0x%0x\n", admin_cmd.result);
+ printf("%s\n", wdc_purge_mon_status_to_string(admin_cmd.result));
+ if (admin_cmd.result == WDC_NVME_PURGE_STATE_BUSY) {
+ progress_percent =
+ ((double)le32_to_cpu(mon->entire_progress_current) * 100) /
+ le32_to_cpu(mon->entire_progress_total);
+ printf("Purge Progress = %f%%\n", progress_percent);
+ }
}
- }
- fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
+ }
return ret;
}
@@ -4006,9 +4027,9 @@ static void wdc_get_commit_action_bin(__u8 commit_action_type, char *action_bin)
}
-static void wdc_print_fw_act_history_log_normal(__u8 *data, int num_entries, __u32 cust_id)
+static void wdc_print_fw_act_history_log_normal(__u8 *data, int num_entries, __u32 cust_id, __u32 vendor_id)
{
- int i;
+ int i, j;
char previous_fw[9];
char new_fw[9];
char commit_action_bin[8];
@@ -4019,7 +4040,7 @@ static void wdc_print_fw_act_history_log_normal(__u8 *data, int num_entries, __u
if (data[0] == WDC_NVME_GET_FW_ACT_HISTORY_C2_LOG_ID) {
printf(" Firmware Activate History Log \n");
- if (cust_id == WDC_CUSTOMER_ID_0x1005) {
+ if (cust_id == WDC_CUSTOMER_ID_0x1005 || vendor_id == WDC_NVME_SNDK_VID) {
printf(" Power on Hour Power Cycle Previous New \n");
printf(" Entry hh:mm:ss Count Firmware Firmware Slot Action Result \n");
printf(" ----- ----------------- ----------------- --------- --------- ----- ------ -------\n");
@@ -4028,14 +4049,16 @@ static void wdc_print_fw_act_history_log_normal(__u8 *data, int num_entries, __u
printf(" Entry Timestamp Count Firmware Firmware Slot Action Result \n");
printf(" ----- ----------------- ----------------- --------- --------- ----- ------ -------\n");
}
+
struct wdc_fw_act_history_log_format_c2 *fw_act_history_entry = (struct wdc_fw_act_history_log_format_c2 *)(data);
if (num_entries == WDC_MAX_NUM_ACT_HIST_ENTRIES) {
/* find lowest/oldest entry */
for (i = 0; i < num_entries; i++) {
+ j = (i+1 == WDC_MAX_NUM_ACT_HIST_ENTRIES) ? 0 : i+1;
if (le16_to_cpu(fw_act_history_entry->entry[i].fw_act_hist_entries) >
- le16_to_cpu(fw_act_history_entry->entry[i+1].fw_act_hist_entries)) {
- oldestEntryIdx = i+1;
+ le16_to_cpu(fw_act_history_entry->entry[j].fw_act_hist_entries)) {
+ oldestEntryIdx = j;
break;
}
}
@@ -4066,6 +4089,14 @@ static void wdc_print_fw_act_history_log_normal(__u8 *data, int num_entries, __u
printf("%s", time_str);
printf(" ");
+ } else if(vendor_id == WDC_NVME_SNDK_VID) {
+ printf(" ");
+ uint64_t timestamp = (0x0000FFFFFFFFFFFF & le64_to_cpu(fw_act_history_entry->entry[entryIdx].timestamp));
+ memset((void *)time_str, 0, 9);
+ sprintf((char *)time_str, "%04d:%02d:%02d", (int)((timestamp/(3600*1000))%24), (int)((timestamp/(1000*60))%60),
+ (int)((timestamp/1000)%60));
+ printf("%s", time_str);
+ printf(" ");
} else {
printf(" ");
uint64_t timestamp = (0x0000FFFFFFFFFFFF & le64_to_cpu(fw_act_history_entry->entry[entryIdx].timestamp));
@@ -4161,10 +4192,10 @@ static void wdc_print_fw_act_history_log_normal(__u8 *data, int num_entries, __u
}
}
-static void wdc_print_fw_act_history_log_json(__u8 *data, int num_entries, __u32 cust_id)
+static void wdc_print_fw_act_history_log_json(__u8 *data, int num_entries, __u32 cust_id, __u32 vendor_id)
{
struct json_object *root;
- int i;
+ int i, j;
char previous_fw[9];
char new_fw[9];
char commit_action_bin[8];
@@ -4186,9 +4217,10 @@ static void wdc_print_fw_act_history_log_json(__u8 *data, int num_entries, __u32
if (num_entries == WDC_MAX_NUM_ACT_HIST_ENTRIES) {
/* find lowest/oldest entry */
for (i = 0; i < num_entries; i++) {
+ j = (i+1 == WDC_MAX_NUM_ACT_HIST_ENTRIES) ? 0 : i+1;
if (le16_to_cpu(fw_act_history_entry->entry[i].fw_act_hist_entries) >
- le16_to_cpu(fw_act_history_entry->entry[i+1].fw_act_hist_entries)) {
- oldestEntryIdx = i+1;
+ le16_to_cpu(fw_act_history_entry->entry[j].fw_act_hist_entries)) {
+ oldestEntryIdx = j;
break;
}
}
@@ -4215,6 +4247,11 @@ static void wdc_print_fw_act_history_log_json(__u8 *data, int num_entries, __u32
json_object_add_value_string(root, "Power on Hour", time_str);
+ } else if (vendor_id == WDC_NVME_SNDK_VID) {
+ uint64_t timestamp = (0x0000FFFFFFFFFFFF & le64_to_cpu(fw_act_history_entry->entry[entryIdx].timestamp));
+ sprintf((char *)time_str, "%04d:%02d:%02d", (int)((timestamp/(3600*1000))%24), (int)((timestamp/(1000*60))%60),
+ (int)((timestamp/1000)%60));
+ json_object_add_value_string(root, "Power on Hour", time_str);
} else {
uint64_t timestamp = (0x0000FFFFFFFFFFFF & le64_to_cpu(fw_act_history_entry->entry[entryIdx].timestamp));
json_object_add_value_int(root, "Timestamp", timestamp);
@@ -4369,7 +4406,7 @@ static void wdc_print_smart_cloud_attr_C0_normal(void *data)
smart_log_ver = (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_LPV]);
printf(" Log page version %"PRIu16"\n",smart_log_ver);
printf(" Log page GUID 0x");
- printf("%lX%lX\n",(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG + 8]),
+ printf("0x%"PRIx64"%"PRIx64"\n",(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG + 8]),
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG]));
if(smart_log_ver > 2) {
printf(" Errata Version Field %d\n",
@@ -4451,9 +4488,8 @@ static void wdc_print_smart_cloud_attr_C0_json(void *data)
json_object_add_value_uint(root, "Log page version", smart_log_ver);
char guid[40];
memset((void*)guid, 0, 40);
- sprintf((char*)guid, "0x%lX%lX",(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG + 8]),
+ sprintf((char*)guid, "0x%"PRIx64"%"PRIx64"",(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG + 8]),
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG]));
- printf("GUID string:%s", guid);
json_object_add_value_string(root, "Log page GUID", guid);
if(smart_log_ver > 2){
json_object_add_value_uint(root, "Errata Version Field",
@@ -4605,7 +4641,7 @@ static int wdc_get_c0_log_page(int fd, char *format, int uuid_index)
/* Get the 0xC0 log data */
ret = nvme_get_log14(fd, 0xFFFFFFFF, WDC_NVME_GET_EOL_STATUS_LOG_OPCODE,
- NVME_NO_LOG_LSP, 0, 0, false, uuid_index, WDC_NVME_SMART_CLOUD_ATTR_LEN, data);
+ NVME_NO_LOG_LSP, 0, 0, false, uuid_index, 0, false, WDC_NVME_SMART_CLOUD_ATTR_LEN, data);
if (strcmp(format, "json"))
fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
@@ -4652,7 +4688,7 @@ static int wdc_get_c0_log_page(int fd, char *format, int uuid_index)
/* Get the 0xC0 log data */
ret = nvme_get_log14(fd, 0xFFFFFFFF, WDC_NVME_GET_EOL_STATUS_LOG_OPCODE,
- NVME_NO_LOG_LSP, 0, 0, false, uuid_index, WDC_NVME_EOL_STATUS_LOG_LEN, data);
+ NVME_NO_LOG_LSP, 0, 0, false, uuid_index, 0, false, WDC_NVME_EOL_STATUS_LOG_LEN, data);
if (strcmp(format, "json"))
fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
@@ -4783,7 +4819,7 @@ static int wdc_print_d0_log(struct wdc_ssd_d0_smart_log *perf, int fmt)
return 0;
}
-static int wdc_print_fw_act_history_log(__u8 *data, int num_entries, int fmt, __u32 cust_id)
+static int wdc_print_fw_act_history_log(__u8 *data, int num_entries, int fmt, __u32 cust_id, __u32 vendor_id)
{
if (!data) {
fprintf(stderr, "ERROR : WDC : Invalid buffer to read fw activate history entries\n");
@@ -4792,10 +4828,10 @@ static int wdc_print_fw_act_history_log(__u8 *data, int num_entries, int fmt, __
switch (fmt) {
case NORMAL:
- wdc_print_fw_act_history_log_normal(data, num_entries, cust_id);
+ wdc_print_fw_act_history_log_normal(data, num_entries, cust_id, vendor_id);
break;
case JSON:
- wdc_print_fw_act_history_log_json(data, num_entries, cust_id);
+ wdc_print_fw_act_history_log_json(data, num_entries, cust_id, vendor_id);
break;
}
return 0;
@@ -5200,7 +5236,7 @@ static int wdc_do_clear_pcie_correctable_errors_fid(int fd)
__u32 value = 1 << 31; /* Bit 31 - clear PCIe correctable count */
ret = nvme_set_feature(fd, 0, WDC_NVME_CLEAR_PCIE_CORR_FEATURE_ID, value,
- 0, 0, 0, NULL, &result);
+ 0, 0, 0, 0, NULL, &result);
fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
return ret;
@@ -5448,7 +5484,7 @@ static int wdc_get_fw_act_history(int fd, char *format)
fw_act_history_hdr = (struct wdc_fw_act_history_log_hdr *)(data);
if ((fw_act_history_hdr->num_entries > 0) && (fw_act_history_hdr->num_entries <= WDC_MAX_NUM_ACT_HIST_ENTRIES))
- ret = wdc_print_fw_act_history_log(data, fw_act_history_hdr->num_entries, fmt, 0);
+ ret = wdc_print_fw_act_history_log(data, fw_act_history_hdr->num_entries, fmt, 0, 0);
else if (fw_act_history_hdr->num_entries == 0) {
fprintf(stderr, "INFO : WDC : No FW Activate History entries found.\n");
ret = 0;
@@ -5473,7 +5509,8 @@ static int wdc_get_fw_act_history_C2(int fd, char *format)
__u8 *data;
__u32 *cust_id;
struct wdc_fw_act_history_log_format_c2 *fw_act_history_log;
- __u32 num_entries = 0;
+ __u32 tot_entries = 0, num_entries = 0;
+ __u32 vendor_id = 0, device_id = 0;
if (!wdc_check_device(fd))
return -1;
@@ -5483,6 +5520,7 @@ static int wdc_get_fw_act_history_C2(int fd, char *format)
fprintf(stderr, "ERROR : WDC : invalid output format\n");
return fmt;
}
+ ret = wdc_get_pci_ids(&device_id, &vendor_id);
if ((data = (__u8*) malloc(sizeof (__u8) * WDC_FW_ACT_HISTORY_C2_LOG_BUF_LEN)) == NULL) {
fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
@@ -5500,25 +5538,22 @@ static int wdc_get_fw_act_history_C2(int fd, char *format)
if (ret == 0) {
/* parse the data */
fw_act_history_log = (struct wdc_fw_act_history_log_format_c2*)(data);
- num_entries = le32_to_cpu(fw_act_history_log->num_entries);
+ tot_entries = le32_to_cpu(fw_act_history_log->num_entries);
- if ((num_entries > 0) && (num_entries <= WDC_MAX_NUM_ACT_HIST_ENTRIES)) {
+ if (tot_entries > 0) {
/* get the FW customer id */
if (!get_dev_mgment_cbs_data(fd, WDC_C2_CUSTOMER_ID_ID, (void*)&cust_id)) {
fprintf(stderr, "%s: ERROR : WDC : 0xC2 Log Page entry ID 0x%x not found\n", __func__, WDC_C2_CUSTOMER_ID_ID);
ret = -1;
goto freeData;
}
-
- ret = wdc_print_fw_act_history_log(data, num_entries, fmt, *cust_id);
- } else if (num_entries == 0) {
+ num_entries = (tot_entries < WDC_MAX_NUM_ACT_HIST_ENTRIES) ? tot_entries :
+ WDC_MAX_NUM_ACT_HIST_ENTRIES;
+ ret = wdc_print_fw_act_history_log(data, num_entries, fmt, *cust_id, vendor_id);
+ } else {
fprintf(stderr, "INFO : WDC : No FW Activate History entries found.\n");
ret = 0;
}
- else {
- fprintf(stderr, "ERROR : WDC : Invalid number entries found in FW Activate History Log Page - %d\n", num_entries);
- ret = -1;
- }
} else {
fprintf(stderr, "ERROR : WDC : Unable to read FW Activate History Log Page data\n");
ret = -1;
@@ -5578,7 +5613,7 @@ static int wdc_vs_fw_activate_history(int argc, char **argv, struct command *com
/* Get the 0xC0 log data */
ret = nvme_get_log14(fd, 0xFFFFFFFF, WDC_NVME_GET_SMART_CLOUD_ATTR_LOG_OPCODE,
- NVME_NO_LOG_LSP, 0, 0, false, uuid_index, WDC_NVME_SMART_CLOUD_ATTR_LEN, data);
+ NVME_NO_LOG_LSP, 0, 0, false, uuid_index, 0, false, WDC_NVME_SMART_CLOUD_ATTR_LEN, data);
if (ret == 0) {
/* Verify GUID matches */
@@ -5634,7 +5669,7 @@ static int wdc_do_clear_fw_activate_history_fid(int fd)
__u32 value = 1 << 31; /* Bit 31 - Clear Firmware Update History Log */
ret = nvme_set_feature(fd, 0, WDC_NVME_CLEAR_FW_ACT_HIST_VU_FID, value,
- 0, 0, 0, NULL, &result);
+ 0, 0, 0, 0, NULL, &result);
fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
return ret;
@@ -5728,18 +5763,18 @@ static int wdc_vs_telemetry_controller_option(int argc, char **argv, struct comm
if (cfg.disable) {
ret = nvme_set_feature(fd, 0, WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID, 1,
- 0, 0, 0, buf, &result);
+ 0, 0, 0, 0, buf, &result);
wdc_clear_reason_id(fd);
}
else {
if (cfg.enable) {
ret = nvme_set_feature(fd, 0, WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID, 0,
- 0, 0, 0, buf, &result);
+ 0, 0, 0, 0, buf, &result);
}
else if (cfg.status) {
ret = nvme_get_feature(fd, 0, WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID, 0, 0,
- 4, buf, &result);
+ 0, 4, buf, &result);
if (ret == 0) {
if (result)
fprintf(stderr, "Controller Option Telemetry Log Page State: Disabled\n");
@@ -6363,7 +6398,7 @@ static int wdc_do_drive_essentials(int fd, char *dir, char *key)
if (deFeatureIdList[listIdx].featureId == FID_LBA_RANGE_TYPE)
continue;
ret = nvme_get_feature(fd, WDC_DE_GLOBAL_NSID, deFeatureIdList[listIdx].featureId, FS_CURRENT, 0,
- sizeof(featureIdBuff), &featureIdBuff, &result);
+ 0, sizeof(featureIdBuff), &featureIdBuff, &result);
if (ret) {
fprintf(stderr, "ERROR : WDC : nvme_get_feature id 0x%x failed, ret = %d\n",
@@ -7713,7 +7748,7 @@ static int wdc_vs_temperature_stats(int argc, char **argv,
temperature = ((smart_log.temperature[1] << 8) | smart_log.temperature[0]) - 273;
/* retrieve HCTM Thermal Management Temperatures */
- nvme_get_feature(fd, 0, 0x10, 0, 0, 0, 0, &hctm_tmt);
+ nvme_get_feature(fd, 0, 0x10, 0, 0, 0, 0, 0, &hctm_tmt);
temp_tmt1 = ((hctm_tmt >> 16) & 0xffff) ? ((hctm_tmt >> 16) & 0xffff) - 273 : 0;
temp_tmt2 = (hctm_tmt & 0xffff) ? (hctm_tmt & 0xffff) - 273 : 0;
@@ -7800,8 +7835,10 @@ static int wdc_capabilities(int argc, char **argv,
printf("get-pfail-dump : %s\n",
capabilities & WDC_DRIVE_CAP_PFAIL_DUMP ? "Supported" : "Not Supported");
printf("id-ctrl : Supported\n");
- printf("purge : Supported\n");
- printf("purge-monitor : Supported\n");
+ printf("purge : %s\n",
+ capabilities & WDC_DRIVE_CAP_PURGE ? "Supported" : "Not Supported");
+ printf("purge-monitor : %s\n",
+ capabilities & WDC_DRIVE_CAP_PURGE ? "Supported" : "Not Supported");
printf("vs-internal-log : %s\n",
capabilities & WDC_DRIVE_CAP_INTERNAL_LOG_MASK ? "Supported" : "Not Supported");
printf("vs-nand-stats : %s\n",
diff --git a/plugins/wdc/wdc-nvme.h b/plugins/wdc/wdc-nvme.h
index de6affa..29ff6a0 100644
--- a/plugins/wdc/wdc-nvme.h
+++ b/plugins/wdc/wdc-nvme.h
@@ -4,9 +4,10 @@
#if !defined(WDC_NVME) || defined(CMD_HEADER_MULTI_READ)
#define WDC_NVME
+#define WDC_PLUGIN_VERSION "1.14.1"
#include "cmd.h"
-PLUGIN(NAME("wdc", "Western Digital vendor specific extensions"),
+PLUGIN(NAME("wdc", "Western Digital vendor specific extensions", WDC_PLUGIN_VERSION),
COMMAND_LIST(
ENTRY("cap-diag", "WDC Capture-Diagnostics", wdc_cap_diag)
ENTRY("drive-log", "WDC Drive Log", wdc_drive_log)
diff --git a/plugins/wdc/wdc-utils.c b/plugins/wdc/wdc-utils.c
index 2740181..52c427b 100644
--- a/plugins/wdc/wdc-utils.c
+++ b/plugins/wdc/wdc-utils.c
@@ -77,7 +77,11 @@ int wdc_UtilsGetTime(PUtilsTimeInfo timeInfo)
timeInfo->second = currTimeInfo.tm_sec;
timeInfo->msecs = 0;
timeInfo->isDST = currTimeInfo.tm_isdst;
+#if defined(__GLIBC__) && !defined(__UCLIBC__) && !defined(__MUSL__)
timeInfo->zone = -currTimeInfo.tm_gmtoff / 60;
+#else
+ timeInfo->zone = -1 * (timezone / SECONDS_IN_MIN);
+#endif
return WDC_STATUS_SUCCESS;
}
diff --git a/plugins/ymtc/ymtc-nvme.h b/plugins/ymtc/ymtc-nvme.h
index 739fd37..c1ebc11 100644
--- a/plugins/ymtc/ymtc-nvme.h
+++ b/plugins/ymtc/ymtc-nvme.h
@@ -12,7 +12,7 @@
#include <sys/types.h>
#include <sys/stat.h>
-PLUGIN(NAME("ymtc", "Ymtc vendor specific extensions"),
+PLUGIN(NAME("ymtc", "Ymtc vendor specific extensions", NVME_VERSION),
COMMAND_LIST(
ENTRY("smart-log-add", "Retrieve Ymtc SMART Log, show it", get_additional_smart_log)
)
diff --git a/plugins/zns/zns.c b/plugins/zns/zns.c
index 7f6f52e..e558317 100644
--- a/plugins/zns/zns.c
+++ b/plugins/zns/zns.c
@@ -130,12 +130,13 @@ close_fd:
return nvme_status_to_errno(err, false);
}
-static int __zns_mgmt_send(int fd, __u32 namespace_id, __u64 zslba,
- bool select_all, enum nvme_zns_send_action zsa, __u32 data_len, void *buf)
+static int __zns_mgmt_send(int fd, __u32 namespace_id, __u64 zslba,
+ bool select_all, __u32 timeout, enum nvme_zns_send_action zsa,
+ __u32 data_len, void *buf)
{
int err;
- err = nvme_zns_mgmt_send(fd, namespace_id, zslba, select_all, zsa,
+ err = nvme_zns_mgmt_send(fd, namespace_id, zslba, select_all, timeout, zsa,
data_len, buf);
close(fd);
return err;
@@ -146,6 +147,7 @@ static int zns_mgmt_send(int argc, char **argv, struct command *cmd, struct plug
{
const char *zslba = "starting LBA of the zone for this command";
const char *select_all = "send command to all zones";
+ const char *timeout = "timeout value, in milliseconds";
int err, fd;
char *command;
@@ -154,15 +156,16 @@ static int zns_mgmt_send(int argc, char **argv, struct command *cmd, struct plug
__u64 zslba;
__u32 namespace_id;
bool select_all;
+ __u32 timeout;
};
- struct config cfg = {
- };
+ struct config cfg = {};
OPT_ARGS(opts) = {
OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
OPT_SUFFIX("start-lba", 's', &cfg.zslba, zslba),
OPT_FLAG("select-all", 'a', &cfg.select_all, select_all),
+ OPT_UINT("timeout", 't', &cfg.timeout, timeout),
OPT_END()
};
@@ -183,7 +186,7 @@ static int zns_mgmt_send(int argc, char **argv, struct command *cmd, struct plug
}
err = __zns_mgmt_send(fd, cfg.namespace_id, cfg.zslba,
- cfg.select_all, zsa, 0, NULL);
+ cfg.select_all, cfg.timeout, zsa, 0, NULL);
if (!err)
printf("%s: Success, action:%d zone:%"PRIx64" all:%d nsid:%d\n",
command, zsa, (uint64_t)cfg.zslba, (int)cfg.select_all,
@@ -207,23 +210,21 @@ static int get_zdes_bytes(int fd, __u32 nsid)
int err;
err = nvme_identify_ns(fd, nsid, false, &id_ns);
- if (err > 0){
+ if (err > 0) {
nvme_show_status(err);
- return err;
- }
- else if (err < 0){
+ return -1;
+ } else if (err < 0) {
perror("identify namespace");
- return err;
+ return -1;
}
err = nvme_zns_identify_ns(fd, nsid, &ns);
- if (err > 0){
+ if (err > 0) {
nvme_show_status(err);
- return err;
- }
- else if (err < 0){
+ return -1;
+ } else if (err < 0) {
perror("zns identify namespace");
- return err;
+ return -1;
}
lbaf = id_ns.flbas & NVME_NS_FLBAS_LBA_MASK;
@@ -238,6 +239,7 @@ static int zone_mgmt_send(int argc, char **argv, struct command *cmd, struct plu
const char *zsa = "zone send action";
const char *data_len = "buffer length if data required";
const char *data = "optional file for data (default stdin)";
+ const char *timeout = "timeout value, in milliseconds";
int fd, ffd = STDIN_FILENO, err = -1;
void *buf = NULL;
@@ -247,20 +249,21 @@ static int zone_mgmt_send(int argc, char **argv, struct command *cmd, struct plu
__u32 namespace_id;
bool select_all;
__u8 zsa;
- int data_len;
+ int data_len;
char *file;
+ __u32 timeout;
};
- struct config cfg = {
- };
+ struct config cfg = {};
OPT_ARGS(opts) = {
OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
OPT_SUFFIX("start-lba", 's', &cfg.zslba, zslba),
OPT_FLAG("select-all", 'a', &cfg.select_all, select_all),
OPT_BYTE("zsa", 'z', &cfg.zsa, zsa),
- OPT_UINT("data-len", 'l', &cfg.data_len, data_len),
- OPT_FILE("data", 'd', &cfg.file, data),
+ OPT_UINT("data-len", 'l', &cfg.data_len, data_len),
+ OPT_FILE("data", 'd', &cfg.file, data),
+ OPT_UINT("timeout", 't', &cfg.timeout, timeout),
OPT_END()
};
@@ -285,9 +288,9 @@ static int zone_mgmt_send(int argc, char **argv, struct command *cmd, struct plu
if (cfg.zsa == NVME_ZNS_ZSA_SET_DESC_EXT) {
if(!cfg.data_len) {
cfg.data_len = get_zdes_bytes(fd, cfg.namespace_id);
- if (cfg.data_len == 0) {
+ if (!cfg.data_len || cfg.data_len < 0) {
fprintf(stderr,
- "Zone Descriptor Extensions are not supported\n");
+ "Zone Descriptor Extensions are not supported\n");
goto close_fd;
} else if (cfg.data_len < 0) {
err = cfg.data_len;
@@ -323,7 +326,7 @@ static int zone_mgmt_send(int argc, char **argv, struct command *cmd, struct plu
}
err = __zns_mgmt_send(fd, cfg.namespace_id, cfg.zslba, cfg.select_all,
- cfg.zsa, cfg.data_len, buf);
+ cfg.timeout, cfg.zsa, cfg.data_len, buf);
if (!err)
printf("zone-mgmt-send: Success, action:%d zone:%"PRIx64" "
"all:%d nsid:%d\n",
@@ -384,6 +387,7 @@ static int set_zone_desc(int argc, char **argv, struct command *cmd, struct plug
const char *desc = "Set Zone Descriptor Extension\n";
const char *zslba = "starting LBA of the zone for this command";
const char *data = "optional file for zone extention data (default stdin)";
+ const char *timeout = "timeout value, in milliseconds";
int fd, ffd = STDIN_FILENO, err;
void *buf = NULL;
@@ -393,15 +397,16 @@ static int set_zone_desc(int argc, char **argv, struct command *cmd, struct plug
__u64 zslba;
__u32 namespace_id;
char *file;
+ __u32 timeout;
};
- struct config cfg = {
- };
+ struct config cfg = {};
OPT_ARGS(opts) = {
OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
OPT_SUFFIX("start-lba", 's', &cfg.zslba, zslba),
- OPT_FILE("data", 'd', &cfg.file, data),
+ OPT_FILE("data", 'd', &cfg.file, data),
+ OPT_UINT("timeout", 't', &cfg.timeout, timeout),
OPT_END()
};
@@ -419,7 +424,7 @@ static int set_zone_desc(int argc, char **argv, struct command *cmd, struct plug
data_len = get_zdes_bytes(fd, cfg.namespace_id);
- if (!data_len) {
+ if (!data_len || data_len < 0) {
fprintf(stderr,
"zone format does not provide descriptor extention\n");
errno = EINVAL;
@@ -449,7 +454,7 @@ static int set_zone_desc(int argc, char **argv, struct command *cmd, struct plug
goto close_ffd;
}
- err = __zns_mgmt_send(fd, cfg.namespace_id, cfg.zslba, 0,
+ err = __zns_mgmt_send(fd, cfg.namespace_id, cfg.zslba, 0, cfg.timeout,
NVME_ZNS_ZSA_SET_DESC_EXT, data_len, buf);
if (!err)
printf("set-zone-desc: Success, zone:%"PRIx64" nsid:%d\n",
@@ -708,8 +713,7 @@ static int zone_append(int argc, char **argv, struct command *cmd, struct plugin
int latency;
};
- struct config cfg = {
- };
+ struct config cfg = {};
OPT_ARGS(opts) = {
OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
diff --git a/plugins/zns/zns.h b/plugins/zns/zns.h
index a92de69..61063f7 100644
--- a/plugins/zns/zns.h
+++ b/plugins/zns/zns.h
@@ -6,7 +6,7 @@
#include "cmd.h"
-PLUGIN(NAME("zns", "Zoned Namespace Command Set"),
+PLUGIN(NAME("zns", "Zoned Namespace Command Set", NVME_VERSION),
COMMAND_LIST(
ENTRY("id-ctrl", "Retrieve ZNS controller identification", id_ctrl)
ENTRY("id-ns", "Retrieve ZNS namespace identification", id_ns)
diff --git a/scripts/gen-hostnqn.sh b/scripts/gen-hostnqn.sh
index 5138f0c..563aa60 100644
--- a/scripts/gen-hostnqn.sh
+++ b/scripts/gen-hostnqn.sh
@@ -23,24 +23,6 @@ if ! [[ $UUID =~ ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$
exit 2
fi
-# HEURISTIC:
-# (1) if any one given character occurs more than 50% of the time, it is likely
-# that the UUID is fake.
-# (2) if the first or the last group consists of mostly the same character, it
-# is likely that the UUID is fake.
-FIRST_GROUP="$(echo $UUID | cut -d'-' -f1)"
-LAST_GROUP="$(echo $UUID | cut -d'-' -f5)"
-for i in {{0..9},{a..f}} ; do
- COUNT_TOTAL="${UUID//[^$i]}"
- COUNT_FIRST="${FIRST_GROUP//[^$i]}"
- COUNT_LAST="${LAST_GROUP//[^$i]}"
- if [ ${#COUNT_TOTAL} -ge 16 ] || [ ${#COUNT_FIRST} -ge 7 ] || [ ${#COUNT_LAST} -ge 11 ] ; then
- >&2 echo "UUID is too repetitive. This may be a false alert."
- >&2 echo "Repetitive UUID: ${UUID}"
- exit 3
- fi
-done
-
HOSTNQN="nqn.2014-08.org.nvmexpress:uuid:${UUID}"
echo $HOSTNQN