]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
nvme: add support for persistent event log page
authorGollu Appalanaidu <anaidu.gollu@samsung.com>
Mon, 11 Jan 2021 08:17:45 +0000 (13:47 +0530)
committerKeith Busch <kbusch@kernel.org>
Mon, 11 Jan 2021 16:55:05 +0000 (09:55 -0700)
This is to add support for LID = 0x0D, Persistent Event log page,
this log page contains information about significant events not
specific to a particular command. The information in this log page
shall be retained across power cycles and resets. For More details
see NVM Express 1.4 Spec. Section 5.14.1.13 Persistent Event Log
(Log Identifier 0Dh)

Change nvme get log to read the whole log page interms of 4096 bytes.
Adding LSP argument in nvme get log fuction and change this across
the nvme get log function wherever has been used with NVME_NO_LOG_LSP.

This Adds support for the persistent event types:
01h SMART / Health Log Snapshot
02h Firmware Commit
03h Timestamp Change
04h Power-on or Reset
05h NVM Subsystem Hardware Error
06h Change Namespace
07h Format NVM Start
08h Format NVM Completion
09h Sanitize Start
0Ah Sanitize Completion
0Dh Thermal Excursion

Signed-off-by: Gollu Appalanaidu <anaidu.gollu@samsung.com>
Co-Authored-By: Karthik Balan <karthik.b82@samsung.com>
Co-Authored-By: Steven Seungcheol Lee <sc108.lee@samsung.com>
22 files changed:
Documentation/nvme-persistent-event-log.1 [new file with mode: 0644]
Documentation/nvme-persistent-event-log.html [new file with mode: 0644]
Documentation/nvme-persistent-event-log.txt [new file with mode: 0644]
completions/_nvme
completions/bash-nvme-completion.sh
linux/nvme.h
nvme-builtin.h
nvme-ioctl.c
nvme-ioctl.h
nvme-print.c
nvme-print.h
nvme.c
plugins/dera/dera-nvme.c
plugins/intel/intel-nvme.c
plugins/memblaze/memblaze-nvme.c
plugins/micron/micron-nvme.c
plugins/scaleflux/sfx-nvme.c
plugins/seagate/seagate-nvme.c
plugins/shannon/shannon-nvme.c
plugins/toshiba/toshiba-nvme.c
plugins/wdc/wdc-nvme.c
plugins/zns/zns.c

diff --git a/Documentation/nvme-persistent-event-log.1 b/Documentation/nvme-persistent-event-log.1
new file mode 100644 (file)
index 0000000..5d74346
--- /dev/null
@@ -0,0 +1,118 @@
+'\" t
+.\"     Title: persistent-event-log
+.\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\"      Date: 01/11/2021
+.\"    Manual: NVMe Manual
+.\"    Source: NVMe
+.\"  Language: English
+.\"
+.TH "PERSISTENT\-EVENT\-L" "1" "01/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-persistent-event-log \- Send NVMe persistent event log page request, returns result and log
+.SH "SYNOPSIS"
+.sp
+.nf
+\fInvme persistent\-event\-log\fR <device> [\-\-action=<action> | \-a <action>]
+            [\-\-log\-len=<log\-len> | \-l <log\-len>]
+            [\-\-raw\-binary | \-b]
+            [\-\-output\-format=<fmt> | \-o <fmt>]
+.fi
+.SH "DESCRIPTION"
+.sp
+Retrieves the NVMe persistent event log page from an NVMe device and provides the 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 returned persistent event log 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
+\-a <action>, \-\-action=<action>
+.RS 4
+While try to retrieve this log action the controller shall take during processing this persistent log page command\&. This mandatory field, based on the value issued it may Read Log Data, Establish Context and Read Log Data or Release Context can occur\&. For More details see NVM Express 1\&.4 Spec\&. Section 5\&.14\&.1\&.13 Persistent Event Log (Log Identifier 0Dh)
+.RE
+.PP
+\-l <log\-len>, \-\-log\-len=<log\-len>
+.RS 4
+Allocates a buffer of <log\-len> bytes size and requests this many bytes be returned in the constructed NVMe command\&. This param is mandatory\&. If <log\-len> given is 0 and action is 0, it will read the Total Log Length(TLL) of the page\&.
+.RE
+.PP
+\-b, \-\-raw\-binary
+.RS 4
+Print the raw persistent event log buffer to stdout\&.
+.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
+.\}
+Print the persistent event log page in a human readable format:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+# nvme persistent\-event\-log /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
+.\}
+Print the raw persistent event log to a file:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+# nvme persistent\-event\-log /dev/nvme0 \-\-raw\-binary > persistent_log\&.raw
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+It is probably a bad idea to not redirect stdout when using this mode\&.
+.RE
+.SH "NVME"
+.sp
+Part of the nvme\-user suite
diff --git a/Documentation/nvme-persistent-event-log.html b/Documentation/nvme-persistent-event-log.html
new file mode 100644 (file)
index 0000000..44a6499
--- /dev/null
@@ -0,0 +1,874 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"\r
+    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\r
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">\r
+<head>\r
+<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />\r
+<meta name="generator" content="AsciiDoc 8.6.10" />\r
+<title>persistent-event-log(1)</title>\r
+<style type="text/css">\r
+/* Shared CSS for AsciiDoc xhtml11 and html5 backends */\r
+\r
+/* Default font. */\r
+body {\r
+  font-family: Georgia,serif;\r
+}\r
+\r
+/* Title font. */\r
+h1, h2, h3, h4, h5, h6,\r
+div.title, caption.title,\r
+thead, p.table.header,\r
+#toctitle,\r
+#author, #revnumber, #revdate, #revremark,\r
+#footer {\r
+  font-family: Arial,Helvetica,sans-serif;\r
+}\r
+\r
+body {\r
+  margin: 1em 5% 1em 5%;\r
+}\r
+\r
+a {\r
+  color: blue;\r
+  text-decoration: underline;\r
+}\r
+a:visited {\r
+  color: fuchsia;\r
+}\r
+\r
+em {\r
+  font-style: italic;\r
+  color: navy;\r
+}\r
+\r
+strong {\r
+  font-weight: bold;\r
+  color: #083194;\r
+}\r
+\r
+h1, h2, h3, h4, h5, h6 {\r
+  color: #527bbd;\r
+  margin-top: 1.2em;\r
+  margin-bottom: 0.5em;\r
+  line-height: 1.3;\r
+}\r
+\r
+h1, h2, h3 {\r
+  border-bottom: 2px solid silver;\r
+}\r
+h2 {\r
+  padding-top: 0.5em;\r
+}\r
+h3 {\r
+  float: left;\r
+}\r
+h3 + * {\r
+  clear: left;\r
+}\r
+h5 {\r
+  font-size: 1.0em;\r
+}\r
+\r
+div.sectionbody {\r
+  margin-left: 0;\r
+}\r
+\r
+hr {\r
+  border: 1px solid silver;\r
+}\r
+\r
+p {\r
+  margin-top: 0.5em;\r
+  margin-bottom: 0.5em;\r
+}\r
+\r
+ul, ol, li > p {\r
+  margin-top: 0;\r
+}\r
+ul > li     { color: #aaa; }\r
+ul > li > * { color: black; }\r
+\r
+.monospaced, code, pre {\r
+  font-family: "Courier New", Courier, monospace;\r
+  font-size: inherit;\r
+  color: navy;\r
+  padding: 0;\r
+  margin: 0;\r
+}\r
+pre {\r
+  white-space: pre-wrap;\r
+}\r
+\r
+#author {\r
+  color: #527bbd;\r
+  font-weight: bold;\r
+  font-size: 1.1em;\r
+}\r
+#email {\r
+}\r
+#revnumber, #revdate, #revremark {\r
+}\r
+\r
+#footer {\r
+  font-size: small;\r
+  border-top: 2px solid silver;\r
+  padding-top: 0.5em;\r
+  margin-top: 4.0em;\r
+}\r
+#footer-text {\r
+  float: left;\r
+  padding-bottom: 0.5em;\r
+}\r
+#footer-badges {\r
+  float: right;\r
+  padding-bottom: 0.5em;\r
+}\r
+\r
+#preamble {\r
+  margin-top: 1.5em;\r
+  margin-bottom: 1.5em;\r
+}\r
+div.imageblock, div.exampleblock, div.verseblock,\r
+div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,\r
+div.admonitionblock {\r
+  margin-top: 1.0em;\r
+  margin-bottom: 1.5em;\r
+}\r
+div.admonitionblock {\r
+  margin-top: 2.0em;\r
+  margin-bottom: 2.0em;\r
+  margin-right: 10%;\r
+  color: #606060;\r
+}\r
+\r
+div.content { /* Block element content. */\r
+  padding: 0;\r
+}\r
+\r
+/* Block element titles. */\r
+div.title, caption.title {\r
+  color: #527bbd;\r
+  font-weight: bold;\r
+  text-align: left;\r
+  margin-top: 1.0em;\r
+  margin-bottom: 0.5em;\r
+}\r
+div.title + * {\r
+  margin-top: 0;\r
+}\r
+\r
+td div.title:first-child {\r
+  margin-top: 0.0em;\r
+}\r
+div.content div.title:first-child {\r
+  margin-top: 0.0em;\r
+}\r
+div.content + div.title {\r
+  margin-top: 0.0em;\r
+}\r
+\r
+div.sidebarblock > div.content {\r
+  background: #ffffee;\r
+  border: 1px solid #dddddd;\r
+  border-left: 4px solid #f0f0f0;\r
+  padding: 0.5em;\r
+}\r
+\r
+div.listingblock > div.content {\r
+  border: 1px solid #dddddd;\r
+  border-left: 5px solid #f0f0f0;\r
+  background: #f8f8f8;\r
+  padding: 0.5em;\r
+}\r
+\r
+div.quoteblock, div.verseblock {\r
+  padding-left: 1.0em;\r
+  margin-left: 1.0em;\r
+  margin-right: 10%;\r
+  border-left: 5px solid #f0f0f0;\r
+  color: #888;\r
+}\r
+\r
+div.quoteblock > div.attribution {\r
+  padding-top: 0.5em;\r
+  text-align: right;\r
+}\r
+\r
+div.verseblock > pre.content {\r
+  font-family: inherit;\r
+  font-size: inherit;\r
+}\r
+div.verseblock > div.attribution {\r
+  padding-top: 0.75em;\r
+  text-align: left;\r
+}\r
+/* DEPRECATED: Pre version 8.2.7 verse style literal block. */\r
+div.verseblock + div.attribution {\r
+  text-align: left;\r
+}\r
+\r
+div.admonitionblock .icon {\r
+  vertical-align: top;\r
+  font-size: 1.1em;\r
+  font-weight: bold;\r
+  text-decoration: underline;\r
+  color: #527bbd;\r
+  padding-right: 0.5em;\r
+}\r
+div.admonitionblock td.content {\r
+  padding-left: 0.5em;\r
+  border-left: 3px solid #dddddd;\r
+}\r
+\r
+div.exampleblock > div.content {\r
+  border-left: 3px solid #dddddd;\r
+  padding-left: 0.5em;\r
+}\r
+\r
+div.imageblock div.content { padding-left: 0; }\r
+span.image img { border-style: none; vertical-align: text-bottom; }\r
+a.image:visited { color: white; }\r
+\r
+dl {\r
+  margin-top: 0.8em;\r
+  margin-bottom: 0.8em;\r
+}\r
+dt {\r
+  margin-top: 0.5em;\r
+  margin-bottom: 0;\r
+  font-style: normal;\r
+  color: navy;\r
+}\r
+dd > *:first-child {\r
+  margin-top: 0.1em;\r
+}\r
+\r
+ul, ol {\r
+    list-style-position: outside;\r
+}\r
+ol.arabic {\r
+  list-style-type: decimal;\r
+}\r
+ol.loweralpha {\r
+  list-style-type: lower-alpha;\r
+}\r
+ol.upperalpha {\r
+  list-style-type: upper-alpha;\r
+}\r
+ol.lowerroman {\r
+  list-style-type: lower-roman;\r
+}\r
+ol.upperroman {\r
+  list-style-type: upper-roman;\r
+}\r
+\r
+div.compact ul, div.compact ol,\r
+div.compact p, div.compact p,\r
+div.compact div, div.compact div {\r
+  margin-top: 0.1em;\r
+  margin-bottom: 0.1em;\r
+}\r
+\r
+tfoot {\r
+  font-weight: bold;\r
+}\r
+td > div.verse {\r
+  white-space: pre;\r
+}\r
+\r
+div.hdlist {\r
+  margin-top: 0.8em;\r
+  margin-bottom: 0.8em;\r
+}\r
+div.hdlist tr {\r
+  padding-bottom: 15px;\r
+}\r
+dt.hdlist1.strong, td.hdlist1.strong {\r
+  font-weight: bold;\r
+}\r
+td.hdlist1 {\r
+  vertical-align: top;\r
+  font-style: normal;\r
+  padding-right: 0.8em;\r
+  color: navy;\r
+}\r
+td.hdlist2 {\r
+  vertical-align: top;\r
+}\r
+div.hdlist.compact tr {\r
+  margin: 0;\r
+  padding-bottom: 0;\r
+}\r
+\r
+.comment {\r
+  background: yellow;\r
+}\r
+\r
+.footnote, .footnoteref {\r
+  font-size: 0.8em;\r
+}\r
+\r
+span.footnote, span.footnoteref {\r
+  vertical-align: super;\r
+}\r
+\r
+#footnotes {\r
+  margin: 20px 0 20px 0;\r
+  padding: 7px 0 0 0;\r
+}\r
+\r
+#footnotes div.footnote {\r
+  margin: 0 0 5px 0;\r
+}\r
+\r
+#footnotes hr {\r
+  border: none;\r
+  border-top: 1px solid silver;\r
+  height: 1px;\r
+  text-align: left;\r
+  margin-left: 0;\r
+  width: 20%;\r
+  min-width: 100px;\r
+}\r
+\r
+div.colist td {\r
+  padding-right: 0.5em;\r
+  padding-bottom: 0.3em;\r
+  vertical-align: top;\r
+}\r
+div.colist td img {\r
+  margin-top: 0.3em;\r
+}\r
+\r
+@media print {\r
+  #footer-badges { display: none; }\r
+}\r
+\r
+#toc {\r
+  margin-bottom: 2.5em;\r
+}\r
+\r
+#toctitle {\r
+  color: #527bbd;\r
+  font-size: 1.1em;\r
+  font-weight: bold;\r
+  margin-top: 1.0em;\r
+  margin-bottom: 0.1em;\r
+}\r
+\r
+div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {\r
+  margin-top: 0;\r
+  margin-bottom: 0;\r
+}\r
+div.toclevel2 {\r
+  margin-left: 2em;\r
+  font-size: 0.9em;\r
+}\r
+div.toclevel3 {\r
+  margin-left: 4em;\r
+  font-size: 0.9em;\r
+}\r
+div.toclevel4 {\r
+  margin-left: 6em;\r
+  font-size: 0.9em;\r
+}\r
+\r
+span.aqua { color: aqua; }\r
+span.black { color: black; }\r
+span.blue { color: blue; }\r
+span.fuchsia { color: fuchsia; }\r
+span.gray { color: gray; }\r
+span.green { color: green; }\r
+span.lime { color: lime; }\r
+span.maroon { color: maroon; }\r
+span.navy { color: navy; }\r
+span.olive { color: olive; }\r
+span.purple { color: purple; }\r
+span.red { color: red; }\r
+span.silver { color: silver; }\r
+span.teal { color: teal; }\r
+span.white { color: white; }\r
+span.yellow { color: yellow; }\r
+\r
+span.aqua-background { background: aqua; }\r
+span.black-background { background: black; }\r
+span.blue-background { background: blue; }\r
+span.fuchsia-background { background: fuchsia; }\r
+span.gray-background { background: gray; }\r
+span.green-background { background: green; }\r
+span.lime-background { background: lime; }\r
+span.maroon-background { background: maroon; }\r
+span.navy-background { background: navy; }\r
+span.olive-background { background: olive; }\r
+span.purple-background { background: purple; }\r
+span.red-background { background: red; }\r
+span.silver-background { background: silver; }\r
+span.teal-background { background: teal; }\r
+span.white-background { background: white; }\r
+span.yellow-background { background: yellow; }\r
+\r
+span.big { font-size: 2em; }\r
+span.small { font-size: 0.6em; }\r
+\r
+span.underline { text-decoration: underline; }\r
+span.overline { text-decoration: overline; }\r
+span.line-through { text-decoration: line-through; }\r
+\r
+div.unbreakable { page-break-inside: avoid; }\r
+\r
+\r
+/*\r
+ * xhtml11 specific\r
+ *\r
+ * */\r
+\r
+div.tableblock {\r
+  margin-top: 1.0em;\r
+  margin-bottom: 1.5em;\r
+}\r
+div.tableblock > table {\r
+  border: 3px solid #527bbd;\r
+}\r
+thead, p.table.header {\r
+  font-weight: bold;\r
+  color: #527bbd;\r
+}\r
+p.table {\r
+  margin-top: 0;\r
+}\r
+/* Because the table frame attribute is overriden by CSS in most browsers. */\r
+div.tableblock > table[frame="void"] {\r
+  border-style: none;\r
+}\r
+div.tableblock > table[frame="hsides"] {\r
+  border-left-style: none;\r
+  border-right-style: none;\r
+}\r
+div.tableblock > table[frame="vsides"] {\r
+  border-top-style: none;\r
+  border-bottom-style: none;\r
+}\r
+\r
+\r
+/*\r
+ * html5 specific\r
+ *\r
+ * */\r
+\r
+table.tableblock {\r
+  margin-top: 1.0em;\r
+  margin-bottom: 1.5em;\r
+}\r
+thead, p.tableblock.header {\r
+  font-weight: bold;\r
+  color: #527bbd;\r
+}\r
+p.tableblock {\r
+  margin-top: 0;\r
+}\r
+table.tableblock {\r
+  border-width: 3px;\r
+  border-spacing: 0px;\r
+  border-style: solid;\r
+  border-color: #527bbd;\r
+  border-collapse: collapse;\r
+}\r
+th.tableblock, td.tableblock {\r
+  border-width: 1px;\r
+  padding: 4px;\r
+  border-style: solid;\r
+  border-color: #527bbd;\r
+}\r
+\r
+table.tableblock.frame-topbot {\r
+  border-left-style: hidden;\r
+  border-right-style: hidden;\r
+}\r
+table.tableblock.frame-sides {\r
+  border-top-style: hidden;\r
+  border-bottom-style: hidden;\r
+}\r
+table.tableblock.frame-none {\r
+  border-style: hidden;\r
+}\r
+\r
+th.tableblock.halign-left, td.tableblock.halign-left {\r
+  text-align: left;\r
+}\r
+th.tableblock.halign-center, td.tableblock.halign-center {\r
+  text-align: center;\r
+}\r
+th.tableblock.halign-right, td.tableblock.halign-right {\r
+  text-align: right;\r
+}\r
+\r
+th.tableblock.valign-top, td.tableblock.valign-top {\r
+  vertical-align: top;\r
+}\r
+th.tableblock.valign-middle, td.tableblock.valign-middle {\r
+  vertical-align: middle;\r
+}\r
+th.tableblock.valign-bottom, td.tableblock.valign-bottom {\r
+  vertical-align: bottom;\r
+}\r
+\r
+\r
+/*\r
+ * manpage specific\r
+ *\r
+ * */\r
+\r
+body.manpage h1 {\r
+  padding-top: 0.5em;\r
+  padding-bottom: 0.5em;\r
+  border-top: 2px solid silver;\r
+  border-bottom: 2px solid silver;\r
+}\r
+body.manpage h2 {\r
+  border-style: none;\r
+}\r
+body.manpage div.sectionbody {\r
+  margin-left: 3em;\r
+}\r
+\r
+@media print {\r
+  body.manpage div#toc { display: none; }\r
+}\r
+\r
+\r
+</style>\r
+<script type="text/javascript">\r
+/*<![CDATA[*/\r
+var asciidoc = {  // Namespace.\r
+\r
+/////////////////////////////////////////////////////////////////////\r
+// Table Of Contents generator\r
+/////////////////////////////////////////////////////////////////////\r
+\r
+/* Author: Mihai Bazon, September 2002\r
+ * http://students.infoiasi.ro/~mishoo\r
+ *\r
+ * Table Of Content generator\r
+ * Version: 0.4\r
+ *\r
+ * Feel free to use this script under the terms of the GNU General Public\r
+ * License, as long as you do not remove or alter this notice.\r
+ */\r
+\r
+ /* modified by Troy D. Hanson, September 2006. License: GPL */\r
+ /* modified by Stuart Rackham, 2006, 2009. License: GPL */\r
+\r
+// toclevels = 1..4.\r
+toc: function (toclevels) {\r
+\r
+  function getText(el) {\r
+    var text = "";\r
+    for (var i = el.firstChild; i != null; i = i.nextSibling) {\r
+      if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.\r
+        text += i.data;\r
+      else if (i.firstChild != null)\r
+        text += getText(i);\r
+    }\r
+    return text;\r
+  }\r
+\r
+  function TocEntry(el, text, toclevel) {\r
+    this.element = el;\r
+    this.text = text;\r
+    this.toclevel = toclevel;\r
+  }\r
+\r
+  function tocEntries(el, toclevels) {\r
+    var result = new Array;\r
+    var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');\r
+    // Function that scans the DOM tree for header elements (the DOM2\r
+    // nodeIterator API would be a better technique but not supported by all\r
+    // browsers).\r
+    var iterate = function (el) {\r
+      for (var i = el.firstChild; i != null; i = i.nextSibling) {\r
+        if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {\r
+          var mo = re.exec(i.tagName);\r
+          if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {\r
+            result[result.length] = new TocEntry(i, getText(i), mo[1]-1);\r
+          }\r
+          iterate(i);\r
+        }\r
+      }\r
+    }\r
+    iterate(el);\r
+    return result;\r
+  }\r
+\r
+  var toc = document.getElementById("toc");\r
+  if (!toc) {\r
+    return;\r
+  }\r
+\r
+  // Delete existing TOC entries in case we're reloading the TOC.\r
+  var tocEntriesToRemove = [];\r
+  var i;\r
+  for (i = 0; i < toc.childNodes.length; i++) {\r
+    var entry = toc.childNodes[i];\r
+    if (entry.nodeName.toLowerCase() == 'div'\r
+     && entry.getAttribute("class")\r
+     && entry.getAttribute("class").match(/^toclevel/))\r
+      tocEntriesToRemove.push(entry);\r
+  }\r
+  for (i = 0; i < tocEntriesToRemove.length; i++) {\r
+    toc.removeChild(tocEntriesToRemove[i]);\r
+  }\r
+\r
+  // Rebuild TOC entries.\r
+  var entries = tocEntries(document.getElementById("content"), toclevels);\r
+  for (var i = 0; i < entries.length; ++i) {\r
+    var entry = entries[i];\r
+    if (entry.element.id == "")\r
+      entry.element.id = "_toc_" + i;\r
+    var a = document.createElement("a");\r
+    a.href = "#" + entry.element.id;\r
+    a.appendChild(document.createTextNode(entry.text));\r
+    var div = document.createElement("div");\r
+    div.appendChild(a);\r
+    div.className = "toclevel" + entry.toclevel;\r
+    toc.appendChild(div);\r
+  }\r
+  if (entries.length == 0)\r
+    toc.parentNode.removeChild(toc);\r
+},\r
+\r
+\r
+/////////////////////////////////////////////////////////////////////\r
+// Footnotes generator\r
+/////////////////////////////////////////////////////////////////////\r
+\r
+/* Based on footnote generation code from:\r
+ * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html\r
+ */\r
+\r
+footnotes: function () {\r
+  // Delete existing footnote entries in case we're reloading the footnodes.\r
+  var i;\r
+  var noteholder = document.getElementById("footnotes");\r
+  if (!noteholder) {\r
+    return;\r
+  }\r
+  var entriesToRemove = [];\r
+  for (i = 0; i < noteholder.childNodes.length; i++) {\r
+    var entry = noteholder.childNodes[i];\r
+    if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")\r
+      entriesToRemove.push(entry);\r
+  }\r
+  for (i = 0; i < entriesToRemove.length; i++) {\r
+    noteholder.removeChild(entriesToRemove[i]);\r
+  }\r
+\r
+  // Rebuild footnote entries.\r
+  var cont = document.getElementById("content");\r
+  var spans = cont.getElementsByTagName("span");\r
+  var refs = {};\r
+  var n = 0;\r
+  for (i=0; i<spans.length; i++) {\r
+    if (spans[i].className == "footnote") {\r
+      n++;\r
+      var note = spans[i].getAttribute("data-note");\r
+      if (!note) {\r
+        // Use [\s\S] in place of . so multi-line matches work.\r
+        // Because JavaScript has no s (dotall) regex flag.\r
+        note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];\r
+        spans[i].innerHTML =\r
+          "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +\r
+          "' title='View footnote' class='footnote'>" + n + "</a>]";\r
+        spans[i].setAttribute("data-note", note);\r
+      }\r
+      noteholder.innerHTML +=\r
+        "<div class='footnote' id='_footnote_" + n + "'>" +\r
+        "<a href='#_footnoteref_" + n + "' title='Return to text'>" +\r
+        n + "</a>. " + note + "</div>";\r
+      var id =spans[i].getAttribute("id");\r
+      if (id != null) refs["#"+id] = n;\r
+    }\r
+  }\r
+  if (n == 0)\r
+    noteholder.parentNode.removeChild(noteholder);\r
+  else {\r
+    // Process footnoterefs.\r
+    for (i=0; i<spans.length; i++) {\r
+      if (spans[i].className == "footnoteref") {\r
+        var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");\r
+        href = href.match(/#.*/)[0];  // Because IE return full URL.\r
+        n = refs[href];\r
+        spans[i].innerHTML =\r
+          "[<a href='#_footnote_" + n +\r
+          "' title='View footnote' class='footnote'>" + n + "</a>]";\r
+      }\r
+    }\r
+  }\r
+},\r
+\r
+install: function(toclevels) {\r
+  var timerId;\r
+\r
+  function reinstall() {\r
+    asciidoc.footnotes();\r
+    if (toclevels) {\r
+      asciidoc.toc(toclevels);\r
+    }\r
+  }\r
+\r
+  function reinstallAndRemoveTimer() {\r
+    clearInterval(timerId);\r
+    reinstall();\r
+  }\r
+\r
+  timerId = setInterval(reinstall, 500);\r
+  if (document.addEventListener)\r
+    document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);\r
+  else\r
+    window.onload = reinstallAndRemoveTimer;\r
+}\r
+\r
+}\r
+asciidoc.install();\r
+/*]]>*/\r
+</script>\r
+</head>\r
+<body class="manpage">\r
+<div id="header">\r
+<h1>\r
+persistent-event-log(1) Manual Page\r
+</h1>\r
+<h2>NAME</h2>\r
+<div class="sectionbody">\r
+<p>nvme-persistent-event-log -\r
+   Send NVMe persistent event log page request, returns result and log\r
+</p>\r
+</div>\r
+</div>\r
+<div id="content">\r
+<div class="sect1">\r
+<h2 id="_synopsis">SYNOPSIS</h2>\r
+<div class="sectionbody">\r
+<div class="verseblock">\r
+<pre class="content"><em>nvme persistent-event-log</em> &lt;device&gt; [--action=&lt;action&gt; | -a &lt;action&gt;]\r
+            [--log-len=&lt;log-len&gt; | -l &lt;log-len&gt;]\r
+            [--raw-binary | -b]\r
+            [--output-format=&lt;fmt&gt; | -o &lt;fmt&gt;]</pre>\r
+<div class="attribution">\r
+</div></div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
+<h2 id="_description">DESCRIPTION</h2>\r
+<div class="sectionbody">\r
+<div class="paragraph"><p>Retrieves the NVMe persistent event log page from an NVMe device\r
+and provides the returned structure.</p></div>\r
+<div class="paragraph"><p>The &lt;device&gt; parameter is mandatory and may be either the NVMe character\r
+device (ex: /dev/nvme0), or a namespace block device (ex: /dev/nvme0n1).</p></div>\r
+<div class="paragraph"><p>On success, the returned persistent event log structure may be returned\r
+in one of several ways depending on the option flags; the structure may\r
+parsed by the program and printed in a readable format or the raw buffer\r
+may be printed to stdout for another program to parse.</p></div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
+<h2 id="_options">OPTIONS</h2>\r
+<div class="sectionbody">\r
+<div class="dlist"><dl>\r
+<dt class="hdlist1">\r
+-a &lt;action&gt;\r
+</dt>\r
+<dt class="hdlist1">\r
+--action=&lt;action&gt;\r
+</dt>\r
+<dd>\r
+<p>\r
+    While try to retrieve this log action the controller shall take\r
+    during processing this persistent log page command. This mandatory\r
+    field, based on the value issued it may Read Log Data, Establish\r
+    Context and Read Log Data or Release Context can occur. For More\r
+    details see NVM Express 1.4 Spec. Section 5.14.1.13 Persistent\r
+    Event Log (Log Identifier 0Dh)\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+-l &lt;log-len&gt;\r
+</dt>\r
+<dt class="hdlist1">\r
+--log-len=&lt;log-len&gt;\r
+</dt>\r
+<dd>\r
+<p>\r
+    Allocates a buffer of &lt;log-len&gt; bytes size and requests this\r
+    many bytes be returned in the constructed NVMe command. This\r
+    param is mandatory. If &lt;log-len&gt; given is 0 and action is 0,\r
+    it will read the Total Log Length(TLL) of the page.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+-b\r
+</dt>\r
+<dt class="hdlist1">\r
+--raw-binary\r
+</dt>\r
+<dd>\r
+<p>\r
+    Print the raw persistent event log buffer to stdout.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+-o &lt;format&gt;\r
+</dt>\r
+<dt class="hdlist1">\r
+--output-format=&lt;format&gt;\r
+</dt>\r
+<dd>\r
+<p>\r
+    Set the reporting format to <em>normal</em>, <em>json</em>, or <em>binary</em>.\r
+    Only one output format can be used at a time.\r
+</p>\r
+</dd>\r
+</dl></div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
+<h2 id="_examples">EXAMPLES</h2>\r
+<div class="sectionbody">\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+Print the persistent event log page in a human readable format:\r
+</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><code># nvme persistent-event-log /dev/nvme0</code></pre>\r
+</div></div>\r
+</li>\r
+<li>\r
+<p>\r
+Print the raw persistent event log to a file:\r
+</p>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><code># nvme persistent-event-log /dev/nvme0 --raw-binary &gt; persistent_log.raw</code></pre>\r
+</div></div>\r
+<div class="paragraph"><p>It is probably a bad idea to not redirect stdout when using this mode.</p></div>\r
+</li>\r
+</ul></div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
+<h2 id="_nvme">NVME</h2>\r
+<div class="sectionbody">\r
+<div class="paragraph"><p>Part of the nvme-user suite</p></div>\r
+</div>\r
+</div>\r
+</div>\r
+<div id="footnotes"><hr /></div>\r
+<div id="footer">\r
+<div id="footer-text">\r
+Last updated\r
+ 2021-01-11 17:07:01 IST\r
+</div>\r
+</div>\r
+</body>\r
+</html>\r
diff --git a/Documentation/nvme-persistent-event-log.txt b/Documentation/nvme-persistent-event-log.txt
new file mode 100644 (file)
index 0000000..833491f
--- /dev/null
@@ -0,0 +1,76 @@
+persistent-event-log(1)
+=======================
+
+NAME
+----
+nvme-persistent-event-log - Send NVMe persistent event log page request,
+returns result and log
+
+SYNOPSIS
+--------
+[verse]
+'nvme persistent-event-log' <device> [--action=<action> | -a <action>]
+            [--log-len=<log-len> | -l <log-len>]
+            [--raw-binary | -b]
+            [--output-format=<fmt> | -o <fmt>]
+
+DESCRIPTION
+-----------
+Retrieves the NVMe persistent event log page from an NVMe device
+and provides the 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 returned persistent event log 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
+-------
+-a <action>::
+--action=<action>::
+    While try to retrieve this log action the controller shall take
+    during processing this persistent log page command. This mandatory
+    field, based on the value issued it may Read Log Data, Establish
+    Context and Read Log Data or Release Context can occur. For More
+    details see NVM Express 1.4 Spec. Section 5.14.1.13 Persistent
+    Event Log (Log Identifier 0Dh)
+
+-l <log-len>::
+--log-len=<log-len>::
+    Allocates a buffer of <log-len> bytes size and requests this
+    many bytes be returned in the constructed NVMe command. This
+    param is mandatory. If <log-len> given is 0 and action is 0,
+    it will read the Total Log Length(TLL) of the page.
+
+-b::
+--raw-binary::
+    Print the raw persistent event log buffer to stdout.
+
+-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
+--------
+* Print the persistent event log page in a human readable format:
++
+------------
+# nvme persistent-event-log /dev/nvme0
+------------
++
+
+* Print the raw persistent event log to a file:
++
+------------
+# nvme persistent-event-log /dev/nvme0 --raw-binary > persistent_log.raw
+------------
++
+It is probably a bad idea to not redirect stdout when using this mode.
+
+NVME
+----
+Part of the nvme-user suite
index 7599f04228c58d87835a122f5a0395bac37e686e..6030547a08af811dfdb1f0d257b70de2f7d86c51 100644 (file)
@@ -18,6 +18,7 @@ _nvme () {
        'list-ctrl:identify all controller(s) attached'
        'get-ns-id:get namespace id of opened block device'
        'get-log:retrieve any log in raw format'
+       'persistent-event-log:retrieve presistent event log'
        'fw-log:retrieve fw log'
        'smart-log:retrieve SMART log'
        'smart-log-add:retrieve additional SMART log'
@@ -196,6 +197,20 @@ _nvme () {
                        _arguments '*:: :->subcmds'
                        _describe -t commands "nvme get-log options" _getlog
                        ;;
+               (persistent-event-log)
+                       local _persistenteventlog
+                       _persistenteventlog=(
+                       /dev/nvme':supply a device to use (required)'
+                       --action=': action the controller shall take for this log page'
+                       -a':alias to --action'
+                       --log-len=':number of bytes to show for requested log'
+                       -l':alias of --log-len'
+                       --raw-binary':dump infos in binary format'
+                       -b':alias of --raw-binary'
+                       )
+                       _arguments '*:: :->subcmds'
+                       _describe -t commands "persistent-event-log options" _persistenteventlog
+                       ;;
                (fw-log)
                        local _fwlog
                        _fwlog=(
@@ -699,7 +714,7 @@ _nvme () {
                             list-ctrl get-ns-id get-log fw-log smart-log error-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 flush compare read write copy show-regs
+                            resv-report flush compare read write copy show-regs persistent-event-log
                           )
                        _arguments '*:: :->subcmds'
                        _describe -t commands "help: infos on a specific nvme command, or provide no option to see a synopsis of all nvme commands" _h
index d417d06f314b1e0a95e6a28c2defb6f07b4959a9..4c308975e119f5521c778466126967c8caba839a 100644 (file)
@@ -3,7 +3,7 @@
 # Kelly Kaoudis kelly.n.kaoudis at intel.com, Aug. 2015
 
 _cmds="list id-ctrl id-ns list-ns id-iocs create-ns delete-ns \
-       attach-ns detach-ns list-ctrl get-ns-id get-log \
+       attach-ns detach-ns list-ctrl get-ns-id get-log persistent-event-log \
        fw-log smart-log smart-log-add error-log \
        get-feature set-feature format fw-activate \
        fw-download admin-passthru io-passthru security-send \
@@ -71,6 +71,10 @@ nvme_list_opts () {
                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"
+                       ;;
                "fw-log")
                opts+=" --raw-binary -b --output-format= -o"
                        ;;
index 08fd6b905f3ce0ad78e403e49da32696703d0df6..ea32c1abacdda88c3faf6788fa2c855428b37f1d 100644 (file)
@@ -737,6 +737,149 @@ struct nvme_ana_rsp_hdr {
        __le16  rsvd10[3];
 };
 
+/* persistent event type 02h */
+struct nvme_fw_commit_event {
+    __le64     old_fw_rev;
+    __le64     new_fw_rev;
+    __u8       fw_commit_action;
+    __u8       fw_slot;
+    __u8       sct_fw;
+    __u8       sc_fw;
+    __le16     vndr_assign_fw_commit_rc;
+} __attribute__((packed));
+
+/* persistent event type 03h */
+struct nvme_time_stamp_change_event {
+    __le64     previous_timestamp;
+    __le64     ml_secs_since_reset;
+};
+
+/* persistent event type 04h */
+struct nvme_power_on_reset_info_list {
+    __le16   cid;
+    __u8     fw_act;
+    __u8     op_in_prog;
+    __u8     rsvd4[12];
+    __le32   ctrl_power_cycle;
+    __le64   power_on_ml_seconds;
+    __le64   ctrl_time_stamp;
+} __attribute__((packed));
+
+/* persistent event type 05h */
+struct nvme_nss_hw_err_event {
+    __le16     nss_hw_err_event_code;
+    __u8       rsvd2[2];
+    __u8       *add_hw_err_info;
+};
+
+/* persistent event type 06h */
+struct nvme_change_ns_event {
+       __le32  nsmgt_cdw10;
+       __u8    rsvd4[4];
+       __le64  nsze;
+       __u8    nscap[16];
+       __u8    flbas;
+       __u8    dps;
+       __u8    nmic;
+       __u8    rsvd35;
+       __le32  ana_grp_id;
+       __le16  nvmset_id;
+       __le16  rsvd42;
+       __le32  nsid;
+};
+
+/* persistent event type 07h */
+struct nvme_format_nvm_start_event {
+    __le32     nsid;
+    __u8       fna;
+    __u8       rsvd5[3];
+    __le32     format_nvm_cdw10;
+};
+
+/* persistent event type 08h */
+struct nvme_format_nvm_compln_event {
+    __le32     nsid;
+    __u8       smallest_fpi;
+    __u8       format_nvm_status;
+    __le16     compln_info;
+    __le32     status_field;
+};
+
+/* persistent event type 09h */
+struct nvme_sanitize_start_event {
+    __le32     sani_cap;
+    __le32     sani_cdw10;
+    __le32     sani_cdw11;
+};
+
+/* persistent event type 0Ah */
+struct nvme_sanitize_compln_event {
+    __le16     sani_prog;
+    __le16     sani_status;
+    __le16     cmpln_info;
+       __u8    rsvd6[2];
+};
+
+/* persistent event type 0Dh */
+struct nvme_thermal_exc_event {
+    __u8       over_temp;
+    __u8       threshold;
+};
+
+/* persistent event entry head */
+struct nvme_persistent_event_entry_head {
+       __u8    etype;
+       __u8    etype_rev;
+       __u8    ehl;
+       __u8    rsvd3;
+       __le16  ctrl_id;
+       __le64  etimestamp;
+       __u8    rsvd14[6];
+       __le16  vsil;
+       __le16  el;
+} __attribute__((packed));
+
+/* persistent event log head */
+struct nvme_persistent_event_log_head {
+       __u8    log_id;
+       __u8    rsvd1[3];
+       __le32  tnev;
+       __le64  tll;
+       __u8    log_rev;
+       __u8    rsvd17;
+       __le16  head_len;
+       __le64  timestamp;
+       __u8    poh[16];
+       __le64  pcc;
+       __le16  vid;
+       __le16  ssvid;
+       __u8    sn[20];
+       __u8    mn[40];
+       __u8    subnqn[256];
+       __u8    rsvd372[108];
+       __u8    supp_event_bm[32];
+} __attribute__((packed));
+
+enum nvme_persistent_event_types {
+    NVME_SMART_HEALTH_EVENT         = 0x01,
+    NVME_FW_COMMIT_EVENT            = 0x02,
+    NVME_TIMESTAMP_EVENT            = 0x03,
+    NVME_POWER_ON_RESET_EVENT       = 0x04,
+    NVME_NSS_HW_ERROR_EVENT         = 0x05,
+    NVME_CHANGE_NS_EVENT            = 0x06,
+    NVME_FORMAT_START_EVENT         = 0x07,
+    NVME_FORMAT_COMPLETION_EVENT    = 0x08,
+    NVME_SANITIZE_START_EVENT       = 0x09,
+    NVME_SANITIZE_COMPLETION_EVENT  = 0x0a,
+    NVME_THERMAL_EXCURSION_EVENT    = 0x0d
+};
+
+enum nvme_persistent_event_log_actions {
+       NVME_PEVENT_LOG_READ                            = 0x0,
+       NVME_PEVENT_LOG_EST_CTX_AND_READ        = 0x1,
+       NVME_PEVENT_LOG_RELEASE_CTX                     = 0x2,
+};
+
 enum {
        NVME_SMART_CRIT_SPARE           = 1 << 0,
        NVME_SMART_CRIT_TEMPERATURE     = 1 << 1,
@@ -1036,6 +1179,7 @@ enum {
        NVME_LOG_TELEMETRY_CTRL = 0x08,
        NVME_LOG_ENDURANCE_GROUP = 0x09,
        NVME_LOG_ANA            = 0x0c,
+       NVME_LOG_PERSISTENT_EVENT   = 0x0d,
        NVME_LOG_DISC           = 0x70,
        NVME_LOG_RESERVATION    = 0x80,
        NVME_LOG_SANITIZE       = 0x81,
index 21b6ff5e7c307808248df6891cbbe40f7e157815..f2080254062e13b5553d177a57007f6d9dc341ae 100644 (file)
@@ -33,6 +33,7 @@ COMMAND_LIST(
        ENTRY("error-log", "Retrieve Error Log, show it", get_error_log)
        ENTRY("effects-log", "Retrieve Command Effects Log, show it", get_effects_log)
        ENTRY("endurance-log", "Retrieve Endurance Group Log, show it", get_endurance_log)
+       ENTRY("persistent-event-log", "Retrieve Presistent Event Log, show it", get_persistent_event_log)
        ENTRY("get-feature", "Get feature and show the resulting value", get_feature)
        ENTRY("device-self-test", "Perform the necessary tests to observe the performance", device_self_test)
        ENTRY("self-test-log", "Retrieve the SELF-TEST Log, show it", self_test_log)
index 0c516b262f28a66aef602da69a8c707dbd17a490..0b668666c4e36b87722a8ad707b7911d90cbcac5 100644 (file)
@@ -508,7 +508,7 @@ int nvme_get_log13(int fd, __u32 nsid, __u8 log_id, __u8 lsp,
 }
 
 int nvme_get_log(int fd, __u32 nsid, __u8 log_id, bool rae,
-                __u32 data_len, void *data)
+                __u8 lsp, __u32 data_len, void *data)
 {
        __u32 offset = 0, xfer_len = data_len;
        void *ptr = data;
@@ -524,7 +524,7 @@ int nvme_get_log(int fd, __u32 nsid, __u8 log_id, bool rae,
                if (xfer_len > 4096)
                        xfer_len = 4096;
 
-               ret = nvme_get_log13(fd, nsid, log_id, NVME_NO_LOG_LSP,
+               ret = nvme_get_log13(fd, nsid, log_id, lsp,
                                     offset, 0, rae, xfer_len, ptr);
                if (ret)
                        return ret;
@@ -556,20 +556,20 @@ int nvme_get_telemetry_log(int fd, void *lp, int generate_report,
 int nvme_fw_log(int fd, struct nvme_firmware_log_page *fw_log)
 {
        return nvme_get_log(fd, NVME_NSID_ALL, NVME_LOG_FW_SLOT, true,
-                       sizeof(*fw_log), fw_log);
+                       NVME_NO_LOG_LSP, sizeof(*fw_log), fw_log);
 }
 
 int nvme_changed_ns_list_log(int fd, struct nvme_changed_ns_list_log *changed_ns_list_log)
 {
        return nvme_get_log(fd, 0, NVME_LOG_CHANGED_NS, true,
-                       sizeof(changed_ns_list_log->log),
+                       NVME_NO_LOG_LSP, sizeof(changed_ns_list_log->log),
                        changed_ns_list_log->log);
 }
 
 int nvme_error_log(int fd, int entries, struct nvme_error_log_page *err_log)
 {
        return nvme_get_log(fd, NVME_NSID_ALL, NVME_LOG_ERROR, false,
-                       entries * sizeof(*err_log), err_log);
+                       NVME_NO_LOG_LSP, entries * sizeof(*err_log), err_log);
 }
 
 int nvme_endurance_log(int fd, __u16 group_id, struct nvme_endurance_group_log *endurance_log)
@@ -581,7 +581,7 @@ int nvme_endurance_log(int fd, __u16 group_id, struct nvme_endurance_group_log *
 int nvme_smart_log(int fd, __u32 nsid, struct nvme_smart_log *smart_log)
 {
        return nvme_get_log(fd, nsid, NVME_LOG_SMART, false,
-                       sizeof(*smart_log), smart_log);
+                       NVME_NO_LOG_LSP, sizeof(*smart_log), smart_log);
 }
 
 int nvme_ana_log(int fd, void *ana_log, size_t ana_log_len, int rgo)
@@ -593,24 +593,31 @@ int nvme_ana_log(int fd, void *ana_log, size_t ana_log_len, int rgo)
 int nvme_self_test_log(int fd, __u32 nsid, struct nvme_self_test_log *self_test_log)
 {
        return nvme_get_log(fd, nsid, NVME_LOG_DEVICE_SELF_TEST, false,
-               sizeof(*self_test_log), self_test_log);
+               NVME_NO_LOG_LSP, sizeof(*self_test_log), self_test_log);
 }
 
 int nvme_effects_log(int fd, struct nvme_effects_log_page *effects_log)
 {
        return nvme_get_log(fd, NVME_NSID_ALL, NVME_LOG_CMD_EFFECTS, false,
-                       sizeof(*effects_log), effects_log);
+                       NVME_NO_LOG_LSP, sizeof(*effects_log), effects_log);
 }
 
 int nvme_discovery_log(int fd, struct nvmf_disc_rsp_page_hdr *log, __u32 size)
 {
-       return nvme_get_log(fd, 0, NVME_LOG_DISC, false, size, log);
+       return nvme_get_log(fd, 0, NVME_LOG_DISC, false, NVME_NO_LOG_LSP, size, log);
 }
 
 int nvme_sanitize_log(int fd, struct nvme_sanitize_log_page *sanitize_log)
 {
        return nvme_get_log(fd, 0, NVME_LOG_SANITIZE, false,
-                       sizeof(*sanitize_log), sanitize_log);
+                       NVME_NO_LOG_LSP, sizeof(*sanitize_log), sanitize_log);
+}
+
+int nvme_persistent_event_log(int fd, __u8 action, __u32 size,
+       void *pevent_log_info)
+{
+       return nvme_get_log(fd, NVME_NSID_ALL, NVME_LOG_PERSISTENT_EVENT,
+                       false, action, size, pevent_log_info);
 }
 
 int nvme_feature(int fd, __u8 opcode, __u32 nsid, __u32 cdw10, __u32 cdw11,
index 89cb4792f2701d947f03d4f7c24df7fdf89ce818..9f422236fe1aef5133b7c6e91acf3eba6f779495 100644 (file)
@@ -97,7 +97,7 @@ 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_get_log(int fd, __u32 nsid, __u8 log_id, bool rae,
-                __u32 data_len, void *data);
+                __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,
                   __u32 data_len, void *data);
@@ -115,6 +115,8 @@ int nvme_ana_log(int fd, void *ana_log, size_t ana_log_len, int rgo);
 int nvme_effects_log(int fd, struct nvme_effects_log_page *effects_log);
 int nvme_discovery_log(int fd, struct nvmf_disc_rsp_page_hdr *log, __u32 size);
 int nvme_sanitize_log(int fd, struct nvme_sanitize_log_page *sanitize_log);
+int nvme_persistent_event_log(int fd, __u8 action, __u32 size,
+               void *pevent_log_info);
 int nvme_endurance_log(int fd, __u16 group_id,
                       struct nvme_endurance_group_log *endurance_log);
 
index 88b97314e7270bbb791d606cd42cbd8ddedb2aa0..c5003ae36d36ec3bce77aa530874e3b93f9bb7c2 100644 (file)
@@ -866,6 +866,582 @@ static void json_sanitize_log(struct nvme_sanitize_log_page *sanitize_log,
        json_free_object(root);
 }
 
+static const char *nvme_show_nss_hw_error(__u16 error_code)
+{
+       switch(error_code) {
+               case 0x01:
+                       return "PCIe Correctable Error";
+               case 0x02:
+                       return "PCIe Uncorrectable Non fatal Error";
+               case 0x03:
+                       return "PCIe Uncorrectable Fatal Error";
+               case 0x04:
+                       return "PCIe Link Status Change";
+               case 0x05:
+                       return "PCIe Link Not Active";
+               case 0x06:
+                       return "Critical Warning Condition";
+               case 0x07:
+                       return "Endurance Group Critical Warning Condition";
+               case 0x08:
+                       return "Unsafe Shutdown";
+               case 0x09:
+                       return "Controller Fatal Status";
+               case 0xA:
+                       return "Media and Data Integrity Status";
+               default:
+                       return "Reserved";
+       }
+}
+
+void json_persistent_event_log(void *pevent_log_info,
+       __u32 size, enum nvme_print_flags flags)
+{
+       struct json_object *root;
+       struct json_object *valid_attrs;
+       struct json_array *valid;
+       __u32 offset, por_info_len, por_info_list;
+       __u64 *fw_rev;
+       char key[128];
+       struct nvme_smart_log *smart_event;
+       struct nvme_fw_commit_event *fw_commit_event;
+       struct nvme_time_stamp_change_event *ts_change_event;
+       struct nvme_power_on_reset_info_list *por_event;
+       struct nvme_nss_hw_err_event *nss_hw_err_event;
+       struct nvme_change_ns_event     *ns_event;
+       struct nvme_format_nvm_start_event *format_start_event;
+       struct nvme_format_nvm_compln_event *format_cmpln_event;
+       struct nvme_sanitize_start_event *sanitize_start_event;
+       struct nvme_sanitize_compln_event *sanitize_cmpln_event;
+       struct nvme_thermal_exc_event *thermal_exc_event;
+       struct nvme_persistent_event_log_head *pevent_log_head;
+       struct nvme_persistent_event_entry_head *pevent_entry_head;
+
+       root = json_create_object();
+       valid = json_create_array();
+
+       offset = sizeof(*pevent_log_head);
+       if (size >= offset) {
+               pevent_log_head = pevent_log_info;
+               char sn[sizeof(pevent_log_head->sn) + 1],
+                       mn[sizeof(pevent_log_head->mn) + 1],
+                       subnqn[sizeof(pevent_log_head->subnqn) + 1];
+
+               snprintf(sn, sizeof(sn), "%-.*s",
+                       (int)sizeof(pevent_log_head->sn), pevent_log_head->sn);
+               snprintf(mn, sizeof(mn), "%-.*s",
+                       (int)sizeof(pevent_log_head->mn), pevent_log_head->mn);
+               snprintf(subnqn, sizeof(subnqn), "%-.*s",
+                       (int)sizeof(pevent_log_head->subnqn), pevent_log_head->subnqn);
+
+               json_object_add_value_uint(root, "log_id",
+                       pevent_log_head->log_id);
+               json_object_add_value_uint(root, "total_num_of_events",
+                       le32_to_cpu(pevent_log_head->tnev));
+               json_object_add_value_uint(root, "total_log_len",
+                       le64_to_cpu(pevent_log_head->tll));
+               json_object_add_value_uint(root, "log_revision",
+                       pevent_log_head->log_rev);
+               json_object_add_value_uint(root, "log_header_len",
+                       le16_to_cpu(pevent_log_head->head_len));
+               json_object_add_value_uint(root, "timestamp",
+                       le64_to_cpu(pevent_log_head->timestamp));
+               json_object_add_value_float(root, "power_on_hours",
+                       int128_to_double(pevent_log_head->poh));
+               json_object_add_value_uint(root, "power_cycle_count",
+                       le64_to_cpu(pevent_log_head->pcc));
+               json_object_add_value_uint(root, "pci_vid",
+                       le16_to_cpu(pevent_log_head->vid));
+               json_object_add_value_uint(root, "pci_ssvid",
+                       le16_to_cpu(pevent_log_head->ssvid));
+               json_object_add_value_string(root, "sn", sn);
+               json_object_add_value_string(root, "mn", mn);
+               json_object_add_value_string(root, "subnqn", subnqn);
+               for (int i = 0; i < 32; i++) {
+                       if (pevent_log_head->supp_event_bm[i] == 0)
+                               continue;
+                       sprintf(key, "bitmap_%d", i);
+                       json_object_add_value_uint(root, key,
+                               pevent_log_head->supp_event_bm[i]);
+               }
+       } else {
+               printf("No log data can be shown with this log len at least " \
+                       "512 bytes is required or can be 0 to read the complete "\
+                       "log page after context established\n");
+               return;
+       }
+       for (int i = 0; i < le32_to_cpu(pevent_log_head->tnev); i++) {
+               if (offset + sizeof(*pevent_entry_head) >= size)
+                       break;
+
+               pevent_entry_head = pevent_log_info + offset;
+
+               if ((offset + pevent_entry_head->ehl + 3 +
+                       le16_to_cpu(pevent_entry_head->el)) >= size)
+                       break;
+               valid_attrs = json_create_object();
+
+               json_object_add_value_uint(valid_attrs, "event_type",
+                       pevent_entry_head->etype);
+               json_object_add_value_uint(valid_attrs, "event_type_rev",
+                       pevent_entry_head->etype_rev);
+               json_object_add_value_uint(valid_attrs, "event_header_len",
+                       pevent_entry_head->ehl);
+               json_object_add_value_uint(valid_attrs, "ctrl_id",
+                       le16_to_cpu(pevent_entry_head->ctrl_id));
+               json_object_add_value_uint(valid_attrs, "event_time_stamp",
+                       le64_to_cpu(pevent_entry_head->etimestamp));
+               json_object_add_value_uint(valid_attrs, "vu_info_len",
+                       le16_to_cpu(pevent_entry_head->vsil));
+               json_object_add_value_uint(valid_attrs, "event_len",
+                       le16_to_cpu(pevent_entry_head->el));
+
+               offset += pevent_entry_head->ehl + 3;
+
+               switch(pevent_entry_head->etype) {
+                       case NVME_SMART_HEALTH_EVENT:
+                               smart_event = pevent_log_info + offset;
+                               unsigned int temperature = ((smart_event->temperature[1] << 8) |
+                                       smart_event->temperature[0]);
+
+                               long double data_units_read = int128_to_double(smart_event->data_units_read);
+                               long double data_units_written = int128_to_double(smart_event->data_units_written);
+                               long double host_read_commands = int128_to_double(smart_event->host_reads);
+                               long double host_write_commands = int128_to_double(smart_event->host_writes);
+                               long double controller_busy_time = int128_to_double(smart_event->ctrl_busy_time);
+                               long double power_cycles = int128_to_double(smart_event->power_cycles);
+                               long double power_on_hours = int128_to_double(smart_event->power_on_hours);
+                               long double unsafe_shutdowns = int128_to_double(smart_event->unsafe_shutdowns);
+                               long double media_errors = int128_to_double(smart_event->media_errors);
+                               long double num_err_log_entries = int128_to_double(smart_event->num_err_log_entries);
+                               json_object_add_value_int(valid_attrs, "critical_warning",
+                                       smart_event->critical_warning);
+
+                               json_object_add_value_int(valid_attrs, "temperature",
+                                       temperature);
+                               json_object_add_value_int(valid_attrs, "avail_spare",
+                                       smart_event->avail_spare);
+                               json_object_add_value_int(valid_attrs, "spare_thresh",
+                                       smart_event->spare_thresh);
+                               json_object_add_value_int(valid_attrs, "percent_used",
+                                       smart_event->percent_used);
+                               json_object_add_value_int(valid_attrs,
+                                       "endurance_grp_critical_warning_summary",
+                                       smart_event->endu_grp_crit_warn_sumry);
+                               json_object_add_value_float(valid_attrs, "data_units_read",
+                                       data_units_read);
+                               json_object_add_value_float(valid_attrs, "data_units_written",
+                                       data_units_written);
+                               json_object_add_value_float(valid_attrs, "host_read_commands",
+                                       host_read_commands);
+                               json_object_add_value_float(valid_attrs, "host_write_commands",
+                                       host_write_commands);
+                               json_object_add_value_float(valid_attrs, "controller_busy_time",
+                                       controller_busy_time);
+                               json_object_add_value_float(valid_attrs, "power_cycles",
+                                       power_cycles);
+                               json_object_add_value_float(valid_attrs, "power_on_hours",
+                                       power_on_hours);
+                               json_object_add_value_float(valid_attrs, "unsafe_shutdowns",
+                                       unsafe_shutdowns);
+                               json_object_add_value_float(valid_attrs, "media_errors",
+                                       media_errors);
+                               json_object_add_value_float(valid_attrs, "num_err_log_entries",
+                                       num_err_log_entries);
+                               json_object_add_value_uint(valid_attrs, "warning_temp_time",
+                                               le32_to_cpu(smart_event->warning_temp_time));
+                               json_object_add_value_uint(valid_attrs, "critical_comp_time",
+                                               le32_to_cpu(smart_event->critical_comp_time));
+
+                               for (int c = 0; c < 8; c++) {
+                                       __s32 temp = le16_to_cpu(smart_event->temp_sensor[c]);
+                                       if (temp == 0)
+                                               continue;
+                                       sprintf(key, "temperature_sensor_%d",c + 1);
+                                       json_object_add_value_int(valid_attrs, key, temp);
+                               }
+
+                               json_object_add_value_uint(valid_attrs, "thm_temp1_trans_count",
+                                               le32_to_cpu(smart_event->thm_temp1_trans_count));
+                               json_object_add_value_uint(valid_attrs, "thm_temp2_trans_count",
+                                               le32_to_cpu(smart_event->thm_temp2_trans_count));
+                               json_object_add_value_uint(valid_attrs, "thm_temp1_total_time",
+                                               le32_to_cpu(smart_event->thm_temp1_total_time));
+                               json_object_add_value_uint(valid_attrs, "thm_temp2_total_time",
+                                               le32_to_cpu(smart_event->thm_temp2_total_time));
+                               break;
+                       case NVME_FW_COMMIT_EVENT:
+                               fw_commit_event = pevent_log_info + offset;
+                               json_object_add_value_uint(valid_attrs, "old_fw_rev",
+                                       le64_to_cpu(fw_commit_event->old_fw_rev));
+                               json_object_add_value_uint(valid_attrs, "new_fw_rev",
+                                       le64_to_cpu(fw_commit_event->new_fw_rev));
+                               json_object_add_value_uint(valid_attrs, "fw_commit_action",
+                                       fw_commit_event->fw_commit_action);
+                               json_object_add_value_uint(valid_attrs, "fw_slot",
+                                       fw_commit_event->fw_slot);
+                               json_object_add_value_uint(valid_attrs, "sct_fw",
+                                       fw_commit_event->sct_fw);
+                               json_object_add_value_uint(valid_attrs, "sc_fw",
+                                       fw_commit_event->sc_fw);
+                               json_object_add_value_uint(valid_attrs,
+                                       "vu_assign_fw_commit_rc",
+                                       le16_to_cpu(fw_commit_event->vndr_assign_fw_commit_rc));
+                               break;
+                       case NVME_TIMESTAMP_EVENT:
+                               ts_change_event = pevent_log_info + offset;
+                               json_object_add_value_uint(valid_attrs, "prev_ts",
+                                       le64_to_cpu(ts_change_event->previous_timestamp));
+                               json_object_add_value_uint(valid_attrs,
+                                       "ml_secs_since_reset",
+                                       le64_to_cpu(ts_change_event->ml_secs_since_reset));
+                               break;
+                       case NVME_POWER_ON_RESET_EVENT:
+                               por_info_len = (le16_to_cpu(pevent_entry_head->el) -
+                                       le16_to_cpu(pevent_entry_head->vsil) - sizeof(*fw_rev));
+
+                               por_info_list = por_info_len / sizeof(*por_event);
+
+                               fw_rev = pevent_log_info + offset;
+                               json_object_add_value_uint(valid_attrs, "fw_rev",
+                                       le64_to_cpu(*fw_rev));
+                               for (int i = 0; i < por_info_list; i++) {
+                                       por_event = pevent_log_info + offset +
+                                               sizeof(*fw_rev) + i * sizeof(*por_event);
+                                       json_object_add_value_uint(valid_attrs, "ctrl_id",
+                                               le16_to_cpu(por_event->cid));
+                                       json_object_add_value_uint(valid_attrs, "fw_act",
+                                               por_event->fw_act);
+                                       json_object_add_value_uint(valid_attrs, "op_in_prog",
+                                               por_event->op_in_prog);
+                                       json_object_add_value_uint(valid_attrs, "ctrl_power_cycle",
+                                               le32_to_cpu(por_event->ctrl_power_cycle));
+                                       json_object_add_value_uint(valid_attrs, "power_on_ml_secs",
+                                               le64_to_cpu(por_event->power_on_ml_seconds));
+                                       json_object_add_value_uint(valid_attrs, "ctrl_time_stamp",
+                                               le64_to_cpu(por_event->ctrl_time_stamp));
+                               }
+                               break;
+                       case NVME_NSS_HW_ERROR_EVENT:
+                               nss_hw_err_event = pevent_log_info + offset;
+                               json_object_add_value_uint(valid_attrs, "nss_hw_err_code",
+                                       le16_to_cpu(nss_hw_err_event->nss_hw_err_event_code));
+                               break;
+                       case NVME_CHANGE_NS_EVENT:
+                               ns_event = pevent_log_info + offset;
+                               json_object_add_value_uint(valid_attrs, "nsmgt_cdw10",
+                                       le32_to_cpu(ns_event->nsmgt_cdw10));
+                               json_object_add_value_uint(valid_attrs, "nsze",
+                                       le64_to_cpu(ns_event->nsze));
+                               long double nscap = int128_to_double(ns_event->nscap);
+                               json_object_add_value_float(valid_attrs, "nscap",
+                                       nscap);
+                               json_object_add_value_uint(valid_attrs, "flbas",
+                                       ns_event->flbas);
+                               json_object_add_value_uint(valid_attrs, "dps",
+                                       ns_event->dps);
+                               json_object_add_value_uint(valid_attrs, "nmic",
+                                       ns_event->nmic);
+                               json_object_add_value_uint(valid_attrs, "ana_grp_id",
+                                       le32_to_cpu(ns_event->ana_grp_id));
+                               json_object_add_value_uint(valid_attrs, "nvmset_id",
+                                       le16_to_cpu(ns_event->nvmset_id));
+                               json_object_add_value_uint(valid_attrs, "nsid",
+                                       le32_to_cpu(ns_event->nsid));
+                               break;
+                       case NVME_FORMAT_START_EVENT:
+                               format_start_event = pevent_log_info + offset;
+                               json_object_add_value_uint(valid_attrs, "nsid",
+                                       le32_to_cpu(format_start_event->nsid));
+                               json_object_add_value_uint(valid_attrs, "fna",
+                                       format_start_event->fna);
+                               json_object_add_value_uint(valid_attrs, "format_nvm_cdw10",
+                                       le32_to_cpu(format_start_event->format_nvm_cdw10));
+                               break;
+                       case NVME_FORMAT_COMPLETION_EVENT:
+                               format_cmpln_event = pevent_log_info + offset;
+                               json_object_add_value_uint(valid_attrs, "nsid",
+                                       le32_to_cpu(format_cmpln_event->nsid));
+                               json_object_add_value_uint(valid_attrs, "smallest_fpi",
+                                       format_cmpln_event->smallest_fpi);
+                               json_object_add_value_uint(valid_attrs, "format_nvm_status",
+                                       format_cmpln_event->format_nvm_status);
+                               json_object_add_value_uint(valid_attrs, "compln_info",
+                                       le16_to_cpu(format_cmpln_event->compln_info));
+                               json_object_add_value_uint(valid_attrs, "status_field",
+                                       le32_to_cpu(format_cmpln_event->status_field));
+                               break;
+                       case NVME_SANITIZE_START_EVENT:
+                               sanitize_start_event = pevent_log_info + offset;
+                               json_object_add_value_uint(valid_attrs, "SANICAP",
+                                       le32_to_cpu(sanitize_start_event->sani_cap));
+                               json_object_add_value_uint(valid_attrs, "sani_cdw10",
+                                       le32_to_cpu(sanitize_start_event->sani_cdw10));
+                               json_object_add_value_uint(valid_attrs, "sani_cdw11",
+                                       le32_to_cpu(sanitize_start_event->sani_cdw11));
+                               break;
+                       case NVME_SANITIZE_COMPLETION_EVENT:
+                               sanitize_cmpln_event = pevent_log_info + offset;
+                               json_object_add_value_uint(valid_attrs, "sani_prog",
+                                       le16_to_cpu(sanitize_cmpln_event->sani_prog));
+                               json_object_add_value_uint(valid_attrs, "sani_status",
+                                       le16_to_cpu(sanitize_cmpln_event->sani_status));
+                               json_object_add_value_uint(valid_attrs, "cmpln_info",
+                                       le16_to_cpu(sanitize_cmpln_event->cmpln_info));
+                               break;
+                       case NVME_THERMAL_EXCURSION_EVENT:
+                               thermal_exc_event = pevent_log_info + offset;
+                               json_object_add_value_uint(valid_attrs, "over_temp",
+                                       thermal_exc_event->over_temp);
+                               json_object_add_value_uint(valid_attrs, "threshold",
+                                       thermal_exc_event->threshold);
+                               break;
+               }
+
+               json_array_add_value_object(valid, valid_attrs);
+               offset += le16_to_cpu(pevent_entry_head->el);
+       }
+
+       json_object_add_value_array(root, "list_of_event_entries", valid);
+       json_print_object(root, NULL);
+       printf("\n");
+       json_free_object(root);
+}
+
+void nvme_show_persistent_event_log(void *pevent_log_info,
+       __u8 action, __u32 size, const char *devname,
+       enum nvme_print_flags flags)
+{
+       __u32 offset, por_info_len, por_info_list;
+       __u64 *fw_rev;
+       struct nvme_smart_log *smart_event;
+       struct nvme_fw_commit_event *fw_commit_event;
+       struct nvme_time_stamp_change_event *ts_change_event;
+       struct nvme_power_on_reset_info_list *por_event;
+       struct nvme_nss_hw_err_event *nss_hw_err_event;
+       struct nvme_change_ns_event     *ns_event;
+       struct nvme_format_nvm_start_event *format_start_event;
+       struct nvme_format_nvm_compln_event *format_cmpln_event;
+       struct nvme_sanitize_start_event *sanitize_start_event;
+       struct nvme_sanitize_compln_event *sanitize_cmpln_event;
+       struct nvme_thermal_exc_event *thermal_exc_event;
+       struct nvme_persistent_event_log_head *pevent_log_head;
+       struct nvme_persistent_event_entry_head *pevent_entry_head;
+
+       if (flags & BINARY)
+               return d_raw((unsigned char *)pevent_log_info, size);
+       if (flags & JSON)
+               return json_persistent_event_log(pevent_log_info, size,
+                       flags);
+
+       offset = sizeof(*pevent_log_head);
+
+       printf("Persistent Event Log for device: %s\n", devname);
+       printf("Action for Persistent Event Log: %u\n", action);
+       if (size >= offset) {
+               pevent_log_head = pevent_log_info;
+               printf("Log Identifier: %u\n", pevent_log_head->log_id);
+               printf("Total Number of Events: %u\n",
+                       le32_to_cpu(pevent_log_head->tnev));
+               printf("Total Log Length : %"PRIu64"\n",
+                       le64_to_cpu(pevent_log_head->tll));
+               printf("Log Revision: %u\n", pevent_log_head->log_rev);
+               printf("Log Header Length: %u\n", pevent_log_head->head_len);
+               printf("Timestamp: %"PRIu64"\n",
+                       le64_to_cpu(pevent_log_head->timestamp));
+               printf("Power On Hours (POH): %'.0Lf\n",
+                       int128_to_double(pevent_log_head->poh));
+               printf("Power Cycle Count: %"PRIu64"\n",
+                       le64_to_cpu(pevent_log_head->pcc));
+               printf("PCI Vendor ID (VID): %u\n",
+                       le16_to_cpu(pevent_log_head->vid));
+               printf("PCI Subsystem Vendor ID (SSVID): %u\n",
+                       le16_to_cpu(pevent_log_head->ssvid));
+               printf("Serial Number (SN): %-.*s\n",
+                       (int)sizeof(pevent_log_head->sn), pevent_log_head->sn);
+               printf("Model Number (MN): %-.*s\n",
+                       (int)sizeof(pevent_log_head->mn), pevent_log_head->mn);
+               printf("NVM Subsystem NVMe Qualified Name (SUBNQN): %-.*s\n",
+                       (int)sizeof(pevent_log_head->subnqn),
+                       pevent_log_head->subnqn);
+               printf("Supported Events Bitmap: ");
+               for (int i = 0; i < 32; i++) {
+                       if (pevent_log_head->supp_event_bm[i] == 0)
+                               continue;
+                       printf("BitMap[%d] is 0x%x\n", i,
+                               pevent_log_head->supp_event_bm[i]);
+               }
+       } else {
+               printf("No log data can be shown with this log len at least " \
+                       "512 bytes is required or can be 0 to read the complete "\
+                       "log page after context established\n");
+               return;
+       }
+       printf("\n");
+       printf("\nPersistent Event Entries:\n");
+       for (int i = 0; i < le32_to_cpu(pevent_log_head->tnev); i++) {
+               if (offset + sizeof(*pevent_entry_head) >= size)
+                       break;
+
+               pevent_entry_head = pevent_log_info + offset;
+
+               if ((offset + pevent_entry_head->ehl + 3 +
+                       le16_to_cpu(pevent_entry_head->el)) >= size)
+                       break;
+
+               printf("Event Type: %u\n", pevent_entry_head->etype);
+               printf("Event Type Revision: %u\n", pevent_entry_head->etype_rev);
+               printf("Event Header Length: %u\n", pevent_entry_head->ehl);
+               printf("Controller Identifier: %u\n",
+                       le16_to_cpu(pevent_entry_head->ctrl_id));
+               printf("Event Timestamp: %"PRIu64"\n",
+                       le64_to_cpu(pevent_entry_head->etimestamp));
+               printf("Vendor Specific Information Length: %u\n",
+                       le16_to_cpu(pevent_entry_head->vsil));
+               printf("Event Length: %u\n", le16_to_cpu(pevent_entry_head->el));
+
+               offset += pevent_entry_head->ehl + 3;
+
+               switch(pevent_entry_head->etype) {
+                       case NVME_SMART_HEALTH_EVENT:
+                               smart_event = pevent_log_info + offset;
+                               printf("Smart Health Event: \n");
+                               nvme_show_smart_log(smart_event, NVME_NSID_ALL, devname, flags);
+                               break;
+                       case NVME_FW_COMMIT_EVENT:
+                               fw_commit_event = pevent_log_info + offset;
+                               printf("FW Commit Event: \n");
+                               printf("Old Firmware Revision: %"PRIu64"\n",
+                                       le64_to_cpu(fw_commit_event->old_fw_rev));
+                               printf("New Firmware Revision: %"PRIu64"\n",
+                                       le64_to_cpu(fw_commit_event->new_fw_rev));
+                               printf("FW Commit Action: %u\n",
+                                       fw_commit_event->fw_commit_action);
+                               printf("FW Slot: %u\n", fw_commit_event->fw_slot);
+                               printf("Status Code Type for Firmware Commit Command: %u\n",
+                                       fw_commit_event->sct_fw);
+                               printf("Status Returned for Firmware Commit Command: %u\n",
+                                       fw_commit_event->sc_fw);
+                               printf("Vendor Assigned Firmware Commit Result Code: %u\n",
+                                       le16_to_cpu(fw_commit_event->vndr_assign_fw_commit_rc));
+                               break;
+                       case NVME_TIMESTAMP_EVENT:
+                               ts_change_event = pevent_log_info + offset;
+                               printf("Time Stamp Change Event: \n");
+                               printf("Previous Timestamp: %"PRIu64"\n",
+                                       le64_to_cpu(ts_change_event->previous_timestamp));
+                               printf("Milliseconds Since Reset: %"PRIu64"\n",
+                                       le64_to_cpu(ts_change_event->ml_secs_since_reset));
+                               break;
+                       case NVME_POWER_ON_RESET_EVENT:
+                               por_info_len = (le16_to_cpu(pevent_entry_head->el) -
+                                       le16_to_cpu(pevent_entry_head->vsil) - sizeof(*fw_rev));
+
+                               por_info_list = por_info_len / sizeof(*por_event);
+
+                               printf("Power On Reset Event: \n");
+                               fw_rev = pevent_log_info + offset;
+                               printf("Firmware Revision: %"PRIu64"\n", le64_to_cpu(*fw_rev));
+                               printf("Reset Information List: \n");
+
+                               for (int i = 0; i < por_info_list; i++) {
+                                       por_event = pevent_log_info + offset +
+                                               sizeof(*fw_rev) + i * sizeof(*por_event);
+                                       printf("Controller ID: %u\n", le16_to_cpu(por_event->cid));
+                                       printf("Firmware Activation: %u\n",
+                                               por_event->fw_act);
+                                       printf("Operation in Progress: %u\n",
+                                               por_event->op_in_prog);
+                                       printf("Controller Power Cycle: %u\n",
+                                               le32_to_cpu(por_event->ctrl_power_cycle));
+                                       printf("Power on milliseconds: %"PRIu64"\n",
+                                               le64_to_cpu(por_event->power_on_ml_seconds));
+                                       printf("Controller Timestamp: %"PRIu64"\n",
+                                               le64_to_cpu(por_event->ctrl_time_stamp));
+                               }
+                               break;
+                       case NVME_NSS_HW_ERROR_EVENT:
+                               nss_hw_err_event = pevent_log_info + offset;
+                               printf("NVM Subsystem Hardware Error Event Code: %u, %s\n",
+                                       le16_to_cpu(nss_hw_err_event->nss_hw_err_event_code),
+                                       nvme_show_nss_hw_error(nss_hw_err_event->nss_hw_err_event_code));
+                               break;
+                       case NVME_CHANGE_NS_EVENT:
+                               ns_event = pevent_log_info + offset;
+                               printf("Change Namespace Event: \n");
+                               printf("Namespace Management CDW10: %u\n",
+                                       le32_to_cpu(ns_event->nsmgt_cdw10));
+                               printf("Namespace Size: %"PRIu64"\n",
+                                       le64_to_cpu(ns_event->nsze));
+                               printf("Namespace Capacity: %'.0Lf\n",
+                                       int128_to_double(ns_event->nscap));
+                               printf("Formatted LBA Size: %u\n", ns_event->flbas);
+                               printf("End-to-end Data Protection Type Settings: %u\n",
+                                       ns_event->dps);
+                               printf("Namespace Multi-path I/O and Namespace Sharing" \
+                                       " Capabilities: %u\n", ns_event->nmic);
+                               printf("ANA Group Identifier: %u\n",
+                                       le32_to_cpu(ns_event->ana_grp_id));
+                               printf("NVM Set Identifier: %u\n", le16_to_cpu(ns_event->nvmset_id));
+                               printf("Namespace ID: %u\n", le32_to_cpu(ns_event->nsid));
+                               break;
+                       case NVME_FORMAT_START_EVENT:
+                               format_start_event = pevent_log_info + offset;
+                               printf("Format NVM Start Event: \n");
+                               printf("Namespace Identifier: %u\n",
+                                       le32_to_cpu(format_start_event->nsid));
+                               printf("Format NVM Attributes: %u\n",
+                                       format_start_event->fna);
+                               printf("Format NVM CDW10: %u\n",
+                                       le32_to_cpu(format_start_event->format_nvm_cdw10));
+                               break;
+                       case NVME_FORMAT_COMPLETION_EVENT:
+                               format_cmpln_event = pevent_log_info + offset;
+                               printf("Format NVM Completion Event: \n");
+                               printf("Namespace Identifier: %u\n",
+                                       le32_to_cpu(format_cmpln_event->nsid));
+                               printf("Smallest Format Progress Indicator: %u\n",
+                                       format_cmpln_event->smallest_fpi);
+                               printf("Format NVM Status: %u\n",
+                                       format_cmpln_event->format_nvm_status);
+                               printf("Completion Information: %u\n",
+                                       le16_to_cpu(format_cmpln_event->compln_info));
+                               printf("Status Field: %u\n",
+                                       le32_to_cpu(format_cmpln_event->status_field));
+                               break;
+                       case NVME_SANITIZE_START_EVENT:
+                               sanitize_start_event = pevent_log_info + offset;
+                               printf("Sanitize Start Event: \n");
+                               printf("SANICAP: %u\n", sanitize_start_event->sani_cap);
+                               printf("Sanitize CDW10: %u\n",
+                                       le32_to_cpu(sanitize_start_event->sani_cdw10));
+                               printf("Sanitize CDW11: %u\n",
+                                       le32_to_cpu(sanitize_start_event->sani_cdw11));
+                               break;
+                       case NVME_SANITIZE_COMPLETION_EVENT:
+                               sanitize_cmpln_event = pevent_log_info + offset;
+                               printf("Sanitize Completion Event: \n");
+                               printf("Sanitize Progress: %u\n",
+                                       le16_to_cpu(sanitize_cmpln_event->sani_prog));
+                               printf("Sanitize Status: %u\n",
+                                       le16_to_cpu(sanitize_cmpln_event->sani_status));
+                               printf("Completion Information: %u\n",
+                                       le16_to_cpu(sanitize_cmpln_event->cmpln_info));
+                               break;
+                       case NVME_THERMAL_EXCURSION_EVENT:
+                               thermal_exc_event = pevent_log_info + offset;
+                               printf("Thermal Excursion Event: \n");
+                               printf("Over Temperature: %u\n", thermal_exc_event->over_temp);
+                               printf("Threshold: %u\n", thermal_exc_event->threshold);
+                               break;
+                       default:
+                               printf("Reserved Event\n\n");
+               }
+               offset += le16_to_cpu(pevent_entry_head->el);
+               printf("\n");
+       }
+}
+
 static void nvme_show_subsystem(struct nvme_subsystem *s)
 {
        int i;
index a1d1ad42cc0ab4a7a0c1d717cc1a60e7619f3487..6e142d4a1537e029dc6d938b7bea020e4490d6c1 100644 (file)
@@ -37,6 +37,11 @@ void nvme_show_endurance_log(struct nvme_endurance_group_log *endurance_log,
        __u16 group_id, const char *devname, enum nvme_print_flags flags);
 void nvme_show_sanitize_log(struct nvme_sanitize_log_page *sanitize,
        const char *devname, enum nvme_print_flags flags);
+void json_persistent_event_log(void *pevent_log_info,
+       __u32 size, enum nvme_print_flags flags);
+void nvme_show_persistent_event_log(void *pevent_log_info,
+       __u8 action, __u32 size, const char *devname,
+       enum nvme_print_flags flags);
 void nvme_show_ctrl_registers(void *bar, bool fabrics, enum nvme_print_flags flags);
 void nvme_show_single_property(int offset, uint64_t prop, int human);
 void nvme_show_id_ns_descs(void *data, unsigned nsid, enum nvme_print_flags flags);
diff --git a/nvme.c b/nvme.c
index ee4b6cf56becca4f863a83c3e4c3da324d8cc34e..a86bc464abb3127784d88d47608ad3f29a0d1ac7 100644 (file)
--- a/nvme.c
+++ b/nvme.c
@@ -737,6 +737,119 @@ ret:
        return nvme_status_to_errno(err, false);
 }
 
+static int get_persistent_event_log(int argc, char **argv,
+               struct command *cmd, struct plugin *plugin)
+{
+       const char *desc = "Retrieve Persistent Event log info for"\
+                       "the given device in either decoded format(default),"\
+                       " json or binary.";
+       const char *action = "action the controller shall take during"\
+                       "processing this persistent log page command.";
+       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;
+       enum nvme_print_flags flags;
+       int err, fd;
+       bool huge;
+
+       struct config {
+               __u8 action;
+               __u32 log_len;
+               int raw_binary;
+               char *output_format;
+       };
+
+       struct config cfg = {
+               .action = 0xff,
+               .log_len = 0,
+               .output_format = "normal",
+       };
+
+       OPT_ARGS(opts) = {
+               OPT_UINT("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),
+               OPT_END()
+       };
+
+       err = fd = parse_and_open(argc, argv, desc, opts);
+       if (fd < 0)
+               goto ret;
+
+       err = flags = validate_output_format(cfg.output_format);
+       if (flags < 0)
+               goto close_fd;
+       if (cfg.raw_binary)
+               flags = BINARY;
+
+       pevent_log_head = calloc(sizeof(*pevent_log_head), 1);
+       if (!pevent_log_head) {
+               fprintf(stderr, "could not alloc buffer for persistent " \
+                       "event log header\n");
+               err = -ENOMEM;
+               goto close_fd;
+       }
+
+       err = nvme_persistent_event_log(fd, cfg.action,
+                       sizeof(*pevent_log_head), pevent_log_head);
+       if (err < 0) {
+               perror("persistent event log");
+               goto close_fd;
+       } else if (err) {
+               nvme_show_status(err);
+               goto close_fd;
+       }
+
+       if (cfg.action == NVME_PEVENT_LOG_RELEASE_CTX) {
+               printf("Releasing Persistent Event Log Context\n");
+               goto close_fd;
+       }
+
+       if (!cfg.log_len && cfg.action != NVME_PEVENT_LOG_EST_CTX_AND_READ) {
+               cfg.log_len = le64_to_cpu(pevent_log_head->tll);
+       } else if (!cfg.log_len && cfg.action == NVME_PEVENT_LOG_EST_CTX_AND_READ) {
+               printf("Establishing Persistent Event Log Context\n");
+               goto close_fd;
+       }
+
+       /*
+        * if header aleady read with context establish action 0x1,
+        * action shall not be 0x1 again in the subsequent request,
+        * until the current context is released by issuing action
+        * with 0x2, otherwise throws command sequence error, make
+        * it as zero to read the log page
+        */
+       if (cfg.action == NVME_PEVENT_LOG_EST_CTX_AND_READ)
+               cfg.action = NVME_PEVENT_LOG_READ;
+
+       pevent_log_info = nvme_alloc(cfg.log_len, &huge);
+       if (!pevent_log_info) {
+               fprintf(stderr, "could not alloc buffer for persistent " \
+                       "event log page\n");
+               err = -ENOMEM;
+               goto close_fd;
+       }
+       err = nvme_persistent_event_log(fd, cfg.action,
+               cfg.log_len, pevent_log_info);
+       if (!err)
+               nvme_show_persistent_event_log(pevent_log_info, cfg.action,
+                       cfg.log_len, devicename, flags);
+       else if (err > 0)
+               nvme_show_status(err);
+       else
+               perror("persistent event log");
+
+       nvme_free(pevent_log_info, huge);
+
+close_fd:
+       free(pevent_log_head);
+       close(fd);
+ret:
+       return nvme_status_to_errno(err, false);
+}
+
 static int get_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
        const char *desc = "Retrieve desired number of bytes "\
index dbb40cc6d66787e3c9ed00a0cb73fe31395b7f86..be78930771ed82bb8cbb261b4739c1d557f75471 100644 (file)
@@ -131,7 +131,8 @@ static int get_status(int argc, char **argv, struct command *cmd, struct plugin
        if (fd < 0)
                return fd;
        
-       err = nvme_get_log(fd, 0xffffffff, 0xc0, false, sizeof(log), &log);
+       err = nvme_get_log(fd, 0xffffffff, 0xc0, false, NVME_NO_LOG_LSP,
+               sizeof(log), &log);
        if (err) {
                goto exit;
        }
index c796db0f1148e04e756216a5a0ad372ff1bbcdf4..b99749dbeeee06030d02e0a278f8aecd621dddf8 100644 (file)
@@ -372,7 +372,7 @@ static int get_additional_smart_log(int argc, char **argv, struct command *cmd,
                return fd;
 
        err = nvme_get_log(fd, cfg.namespace_id, 0xca, false,
-                          sizeof(smart_log), &smart_log);
+                          NVME_NO_LOG_LSP, sizeof(smart_log), &smart_log);
        if (!err) {
                if (cfg.json)
                        show_intel_smart_log_jsn(&smart_log, cfg.namespace_id, devicename);
@@ -412,7 +412,7 @@ static int get_market_log(int argc, char **argv, struct command *cmd, struct plu
                return fd;
 
        err = nvme_get_log(fd, NVME_NSID_ALL, 0xdd, false,
-                          sizeof(log), log);
+                          NVME_NO_LOG_LSP, sizeof(log), log);
        if (!err) {
                if (!cfg.raw_binary)
                        printf("Intel Marketing Name Log:\n%s\n", log);
@@ -474,7 +474,7 @@ static int get_temp_stats_log(int argc, char **argv, struct command *cmd, struct
                return fd;
 
        err = nvme_get_log(fd, NVME_NSID_ALL, 0xc5, false,
-                          sizeof(stats), &stats);
+                          NVME_NO_LOG_LSP, sizeof(stats), &stats);
        if (!err) {
                if (!cfg.raw_binary)
                        show_temp_stats(&stats);
@@ -895,7 +895,7 @@ static int get_lat_stats_log(int argc, char **argv, struct command *cmd, struct
                flags = BINARY;
 
        err = nvme_get_log(fd, NVME_NSID_ALL, cfg.write ? 0xc2 : 0xc1,
-                          false, sizeof(stats), &stats);
+                          false, NVME_NO_LOG_LSP, sizeof(stats), &stats);
        if (!err) {
                if (flags & JSON)
                        json_lat_stats(&stats, cfg.write);
index c75f49cd4dacd2a39df8492d455881aec0ad245d..52d8bdb1160ebd79db267f30f5b6e40779c295b6 100644 (file)
@@ -408,7 +408,7 @@ static int get_additional_smart_log(int argc, char **argv, struct command *cmd,
                return fd;
 
        err = nvme_get_log(fd, cfg.namespace_id, 0xca, false,
-                          sizeof(smart_log), &smart_log);
+                          NVME_NO_LOG_LSP, sizeof(smart_log), &smart_log);
        if (!err) {
                if (!cfg.raw_binary)
                        err = show_memblaze_smart_log(fd, cfg.namespace_id, devicename, &smart_log);
index 6e7109b800c4b5d2d4de10a6fbe79855980fd09e..29d8bdb681f8d3badbbc6db20d430793cbbb57d6 100644 (file)
@@ -289,7 +289,8 @@ static int GetLogPageSize(int nFD, unsigned char ucLogID, int *nLogSize)
     LogPageHeader_t *pLogHeader = NULL;
 
     if (ucLogID == 0xC1 || ucLogID == 0xC2 || ucLogID == 0xC4) {
-        err = nvme_get_log(nFD, NVME_NSID_ALL, ucLogID, false, CommonChunkSize, pTmpBuf);
+        err = nvme_get_log(nFD, NVME_NSID_ALL, ucLogID, false, NVME_NO_LOG_LSP,
+            CommonChunkSize, pTmpBuf);
         if (err == 0) {
             pLogHeader = (LogPageHeader_t *) pTmpBuf;
             LogPageHeader_t *pLogHeader1 = (LogPageHeader_t *) pLogHeader;
@@ -397,7 +398,8 @@ static int GetCommonLogPage(int nFD, unsigned char ucLogID, unsigned char **pBuf
         goto exit_status;
     }
     memset(pTempPtr, 0, nBuffSize);
-    err = nvme_get_log(nFD, NVME_NSID_ALL, ucLogID, false, nBuffSize, pTempPtr);
+    err = nvme_get_log(nFD, NVME_NSID_ALL, ucLogID, false, NVME_NO_LOG_LSP,
+        nBuffSize, pTempPtr);
     *pBuffer = pTempPtr;
 
 exit_status:
@@ -1100,7 +1102,8 @@ static int micron_nand_stats(int argc, char **argv, struct command *cmd, struct
         log_page = 0xFB;
         log_size = FB_log_size;
     }
-    err = nvme_get_log(fd, NVME_NSID_ALL, log_page, false, log_size, extSmartLog);
+    err = nvme_get_log(fd, NVME_NSID_ALL, log_page, false, NVME_NO_LOG_LSP,
+        log_size, extSmartLog);
     if (err) {
         printf("Unable to retrieve extended smart log for the drive\n");
         goto out;
@@ -1777,7 +1780,8 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd,
             }
             if (bSize != 0 && (dataBuffer = (unsigned char *)malloc(bSize)) != NULL) {
                 memset(dataBuffer, 0, bSize);
-                err = nvme_get_log(fd, NVME_NSID_ALL, aVendorLogs[i].ucLogPage, false, bSize, dataBuffer);
+                err = nvme_get_log(fd, NVME_NSID_ALL, aVendorLogs[i].ucLogPage, false, NVME_NO_LOG_LSP,
+                    bSize, dataBuffer);
             }
             break;
 
@@ -1794,12 +1798,14 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd,
                break;
             }
             memset(dataBuffer, 0, bSize);
-            err = nvme_get_log(fd, NVME_NSID_ALL, aVendorLogs[i].ucLogPage, false, bSize, dataBuffer);
+            err = nvme_get_log(fd, NVME_NSID_ALL, aVendorLogs[i].ucLogPage, false, NVME_NO_LOG_LSP,
+                bSize, dataBuffer);
             maxSize = aVendorLogs[i].nMaxSize - bSize;
             while (err == 0 && maxSize > 0 && ((unsigned int *)dataBuffer)[0] != 0xdeadbeef) {
                 sprintf(msg, "log 0x%x", aVendorLogs[i].ucLogPage);
                 WriteData(dataBuffer, bSize, strCtrlDirName, aVendorLogs[i].strFileName, msg);
-                err = nvme_get_log(fd, NVME_NSID_ALL, aVendorLogs[i].ucLogPage, false, bSize, dataBuffer);
+                err = nvme_get_log(fd, NVME_NSID_ALL, aVendorLogs[i].ucLogPage, false, NVME_NO_LOG_LSP,
+                    bSize, dataBuffer);
                 if (err || (((unsigned int *)dataBuffer)[0] == 0xdeadbeef))
                     break;
                 maxSize -= bSize;
index 1ce8996047a8f6bc960e93e2dead52eccca34749..8e3619d9045d6d2aca7a9822ae3887687a3bb29b 100644 (file)
@@ -362,8 +362,8 @@ static int get_additional_smart_log(int argc, char **argv, struct command *cmd,
 
        fd = parse_and_open(argc, argv, desc, opts);
 
-       err = nvme_get_log(fd, cfg.namespace_id, 0xca, false, sizeof(smart_log),
-                       (void *)&smart_log);
+       err = nvme_get_log(fd, cfg.namespace_id, 0xca, false, NVME_NO_LOG_LSP,
+               sizeof(smart_log), (void *)&smart_log);
        if (!err) {
                if (cfg.json)
                        show_sfx_smart_log_jsn(&smart_log, cfg.namespace_id, devicename);
@@ -444,7 +444,8 @@ static int get_lat_stats_log(int argc, char **argv, struct command *cmd, struct
 
        fd = parse_and_open(argc, argv, desc, opts);
 
-       err = nvme_get_log(fd, 0xffffffff, cfg.write ? 0xc3 : 0xc1, false, sizeof(stats), (void *)&stats);
+       err = nvme_get_log(fd, 0xffffffff, cfg.write ? 0xc3 : 0xc1, false, NVME_NO_LOG_LSP,
+               sizeof(stats), (void *)&stats);
        if (!err) {
                if (!cfg.raw_binary)
                        show_lat_stats(&stats, cfg.write);
index 5a7ade82e32317cb150d92b7ab832c9e03cff9f5..ed77f04dc88b2d2fb6fb381ce79602da499cd707 100644 (file)
@@ -177,7 +177,8 @@ static int log_pages_supp(int argc, char **argv, struct command *cmd,
        };
 
        fd = parse_and_open(argc, argv, desc, opts);
-       err = nvme_get_log(fd, 1, 0xc5, false, sizeof(logPageMap), &logPageMap);
+       err = nvme_get_log(fd, 1, 0xc5, false, NVME_NO_LOG_LSP,
+               sizeof(logPageMap), &logPageMap);
        if (!err) {
                if (strcmp(cfg.output_format,"json")) {
                        printf ("Seagate Supported Log-pages count :%d\n",
@@ -741,7 +742,8 @@ static int vs_smart_log(int argc, char **argv, struct command *cmd, struct plugi
        if (strcmp(cfg.output_format,"json"))
                printf("Seagate Extended SMART Information :\n");
 
-       err = nvme_get_log(fd, 1, 0xC4, false, sizeof(ExtdSMARTInfo), &ExtdSMARTInfo);
+       err = nvme_get_log(fd, 1, 0xC4, false, NVME_NO_LOG_LSP,
+               sizeof(ExtdSMARTInfo), &ExtdSMARTInfo);
        if (!err) {
                if (strcmp(cfg.output_format,"json")) {
                        printf("%-39s %-15s %-19s \n", "Description", "Ext-Smart-Id", "Ext-Smart-Value");
@@ -763,7 +765,8 @@ static int vs_smart_log(int argc, char **argv, struct command *cmd, struct plugi
                 * Next get Log Page 0xCF
                 */
 
-               err = nvme_get_log(fd, 1, 0xCF, false, sizeof(logPageCF), &logPageCF);
+               err = nvme_get_log(fd, 1, 0xCF, false, NVME_NO_LOG_LSP,
+                       sizeof(logPageCF), &logPageCF);
                if (!err) {
                        if(strcmp(cfg.output_format,"json")) {
                                /*printf("Seagate DRAM Supercap SMART Attributes :\n");*/
@@ -860,7 +863,8 @@ static int temp_stats(int argc, char **argv, struct command *cmd, struct plugin
        }
 
        /* STEP-2 : Get Max temperature form Ext SMART-id 194 */
-       err = nvme_get_log(fd, 1, 0xC4, false, sizeof(ExtdSMARTInfo), &ExtdSMARTInfo);
+       err = nvme_get_log(fd, 1, 0xC4, false, NVME_NO_LOG_LSP,
+               sizeof(ExtdSMARTInfo), &ExtdSMARTInfo);
        if (!err) {
                for(index = 0; index < NUMBER_EXTENDED_SMART_ATTRIBUTES; index++) {
                        if (ExtdSMARTInfo.vendorData[index].AttributeNumber == VS_ATTR_ID_MAX_LIFE_TEMPERATURE) {
@@ -882,7 +886,8 @@ static int temp_stats(int argc, char **argv, struct command *cmd, struct plugin
                fprintf(stderr, "NVMe Status:%s(%x)\n",
                        nvme_status_to_string(err), err);
 
-       cf_err = nvme_get_log(fd, 1, 0xCF, false, sizeof(ExtdSMARTInfo), &logPageCF);
+       cf_err = nvme_get_log(fd, 1, 0xCF, false, NVME_NO_LOG_LSP,
+               sizeof(ExtdSMARTInfo), &logPageCF);
 
        if(!cf_err) {
                scCurrentTemp = logPageCF.AttrCF.SuperCapCurrentTemperature;
@@ -1011,7 +1016,8 @@ static int vs_pcie_error_log(int argc, char **argv, struct command *cmd, struct
        if(strcmp(cfg.output_format,"json"))
                printf("Seagate PCIe error counters Information :\n");
 
-       err = nvme_get_log(fd, 1, 0xCB, false, sizeof(pcieErrorLog), &pcieErrorLog);
+       err = nvme_get_log(fd, 1, 0xCB, false, NVME_NO_LOG_LSP,
+               sizeof(pcieErrorLog), &pcieErrorLog);
        if (!err) {
                if(strcmp(cfg.output_format,"json")) {
                        print_vs_pcie_error_log(pcieErrorLog);
index a1fa9eccea73342b9d32650fec89844a0003d851..46ace75d30548618cbb7fb5e95dced56336a2bd5 100644 (file)
@@ -143,7 +143,7 @@ static int get_additional_smart_log(int argc, char **argv, struct command *cmd,
 
        fd = parse_and_open(argc, argv, desc, opts);
        err = nvme_get_log(fd, cfg.namespace_id, 0xca, false,
-                  sizeof(smart_log), &smart_log);
+                  NVME_NO_LOG_LSP, sizeof(smart_log), &smart_log);
        if (!err) {
                if (!cfg.raw_binary)
                        show_shannon_smart_log(&smart_log, cfg.namespace_id, devicename);
index c067ce8e082d84982796b3c46f23c8fd9e82b903..53d54bcc553b3ec8714e98762c765350251051a4 100644 (file)
@@ -393,7 +393,7 @@ static int nvme_get_vendor_log(int fd, __u32 namespace_id, int log_page,
                goto end;
        }
        err = nvme_get_log(fd, namespace_id, log_page, false,
-                   log_len, log);
+                   NVME_NO_LOG_LSP, log_len, log);
        if (err) {
                fprintf(stderr, "%s: couldn't get log 0x%x\n", __func__,
                        log_page);
index e997e17c7a124944206895b075a6825f049f8f00..c185ec0302408e9408cc111d6654d7b82470a1a6 100644 (file)
@@ -4518,7 +4518,7 @@ static int wdc_get_c0_log_page(int fd, char *format, int uuid_index)
 
                        /* Get the 0xC0 log data */
                        ret = nvme_get_log(fd, 0xFFFFFFFF, WDC_NVME_GET_EOL_STATUS_LOG_OPCODE,
-                                          false, WDC_NVME_EOL_STATUS_LOG_LEN, data);
+                                          false, NVME_NO_LOG_LSP, WDC_NVME_EOL_STATUS_LOG_LEN, data);
 
                        if (strcmp(format, "json"))
                                fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
@@ -4544,7 +4544,7 @@ static int wdc_get_c0_log_page(int fd, char *format, int uuid_index)
 
                /* Get the 0xC0 log data */
                ret = nvme_get_log(fd, 0xFFFFFFFF, WDC_NVME_GET_SMART_CLOUD_ATTR_LOG_OPCODE,
-                                       false, WDC_NVME_SMART_CLOUD_ATTR_LEN, data);
+                                       false, NVME_NO_LOG_LSP, WDC_NVME_SMART_CLOUD_ATTR_LEN, data);
 
                if (strcmp(format, "json"))
                        fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
@@ -4686,7 +4686,7 @@ static int wdc_get_ca_log_page(int fd, char *format)
                        memset(data, 0, sizeof (__u8) * WDC_FB_CA_LOG_BUF_LEN);
 
                        ret = nvme_get_log(fd, 0xFFFFFFFF, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE,
-                                          false, WDC_FB_CA_LOG_BUF_LEN, data);
+                                          false, NVME_NO_LOG_LSP, WDC_FB_CA_LOG_BUF_LEN, data);
                        if (strcmp(format, "json"))
                                fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
 
@@ -4722,7 +4722,7 @@ static int wdc_get_ca_log_page(int fd, char *format)
                        memset(data, 0, sizeof (__u8) * WDC_FB_CA_LOG_BUF_LEN);
 
                        ret = nvme_get_log(fd, 0xFFFFFFFF, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE,
-                                          false, WDC_FB_CA_LOG_BUF_LEN, data);
+                                          false, NVME_NO_LOG_LSP, WDC_FB_CA_LOG_BUF_LEN, data);
                        if (strcmp(format, "json"))
                                fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
 
@@ -4743,7 +4743,7 @@ static int wdc_get_ca_log_page(int fd, char *format)
 
                        memset(data, 0, sizeof (__u8) * WDC_BD_CA_LOG_BUF_LEN);
                        ret = nvme_get_log(fd, 0xFFFFFFFF, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE,
-                                          false, WDC_BD_CA_LOG_BUF_LEN, data);
+                                          false, NVME_NO_LOG_LSP, WDC_BD_CA_LOG_BUF_LEN, data);
                        if (strcmp(format, "json"))
                                fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
 
@@ -4807,7 +4807,7 @@ static int wdc_get_c1_log_page(int fd, char *format, uint8_t interval)
        memset(data, 0, sizeof (__u8) * WDC_ADD_LOG_BUF_LEN);
 
        ret = nvme_get_log(fd, 0x01, WDC_NVME_ADD_LOG_OPCODE, false,
-                          WDC_ADD_LOG_BUF_LEN, data);
+                          NVME_NO_LOG_LSP, WDC_ADD_LOG_BUF_LEN, data);
        if (strcmp(format, "json"))
                fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
        if (ret == 0) {
@@ -4860,7 +4860,7 @@ static int wdc_get_d0_log_page(int fd, char *format)
        memset(data, 0, sizeof (__u8) * WDC_NVME_VU_SMART_LOG_LEN);
 
        ret = nvme_get_log(fd, 0xFFFFFFFF, WDC_NVME_GET_VU_SMART_LOG_OPCODE,
-                          false, WDC_NVME_VU_SMART_LOG_LEN, data);
+                          false, NVME_NO_LOG_LSP, WDC_NVME_VU_SMART_LOG_LEN, data);
        if (strcmp(format, "json"))
                fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
 
@@ -5276,7 +5276,7 @@ static int wdc_get_fw_act_history(int fd, char *format)
        memset(data, 0, sizeof (__u8) * WDC_FW_ACT_HISTORY_LOG_BUF_LEN);
 
        ret = nvme_get_log(fd, 0xFFFFFFFF, WDC_NVME_GET_FW_ACT_HISTORY_LOG_ID,
-                          false, WDC_FW_ACT_HISTORY_LOG_BUF_LEN, data);
+                          false, NVME_NO_LOG_LSP, WDC_FW_ACT_HISTORY_LOG_BUF_LEN, data);
 
        if (strcmp(format, "json"))
                fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
@@ -5323,7 +5323,7 @@ static int wdc_get_fw_act_history_C2(int fd, char *format)
        memset(data, 0, sizeof (__u8) * WDC_FW_ACT_HISTORY_C2_LOG_BUF_LEN);
 
        ret = nvme_get_log(fd, 0xFFFFFFFF, WDC_NVME_GET_FW_ACT_HISTORY_C2_LOG_ID,
-                          false, WDC_FW_ACT_HISTORY_C2_LOG_BUF_LEN, data);
+                          false, NVME_NO_LOG_LSP, WDC_FW_ACT_HISTORY_C2_LOG_BUF_LEN, data);
 
        if (strcmp(format, "json"))
                fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
@@ -6155,7 +6155,7 @@ static int wdc_do_drive_essentials(int fd, char *dir, char *key)
                memset(dataBuffer, 0, dataBufferSize);
 
                ret = nvme_get_log(fd, WDC_DE_GLOBAL_NSID, deVULogPagesList[vuLogIdx].logPageId,
-                                  false, dataBufferSize, dataBuffer);
+                                  false, NVME_NO_LOG_LSP, dataBufferSize, dataBuffer);
                if (ret) {
                        fprintf(stderr, "ERROR : WDC : nvme_get_log() for log page 0x%x failed, ret = %d\n",
                                        deVULogPagesList[vuLogIdx].logPageId, ret);
@@ -7151,7 +7151,7 @@ static int wdc_do_vs_nand_stats(int fd, char *format)
        }
 
        ret = nvme_get_log(fd, 0xFFFFFFFF, WDC_NVME_NAND_STATS_LOG_ID,
-                          false, WDC_NVME_NAND_STATS_SIZE, (void*)output);
+                          false, NVME_NO_LOG_LSP, WDC_NVME_NAND_STATS_SIZE, (void*)output);
        if (ret) {
                fprintf(stderr, "ERROR : WDC : %s : Failed to retreive NAND stats\n", __func__);
                goto out;
index d0a1865e650cd46587d504b5297c2c97198374af..1287c97528173e314c971743fd950793092d4ebe 100644 (file)
@@ -891,7 +891,7 @@ static int changed_zone_list(int argc, char **argv, struct command *cmd, struct
        }
 
        err = nvme_get_log(fd, cfg.namespace_id, NVME_LOG_ZONE_CHANGED_LIST, 
-                                               cfg.rae, sizeof(log), &log);
+                                               cfg.rae, NVME_NO_LOG_LSP, sizeof(log), &log);
        if (!err)
                nvme_show_zns_changed(&log, flags);
        else if (err > 0)