The branch main has been updated by bcr (doc committer):

URL: 
https://cgit.FreeBSD.org/src/commit/?id=84e86788705c176cc195e4a9831c0be08dcece31

commit 84e86788705c176cc195e4a9831c0be08dcece31
Author:     Wanpeng Qian <[email protected]>
AuthorDate: 2022-10-06 10:10:06 +0000
Commit:     Benedict Reuschling <[email protected]>
CommitDate: 2022-10-06 10:24:02 +0000

    nvmecontrol: Add Samsung Extended SMART Information logpage support
    
    Samsung PM983 SSD has a 0xca logpage. It has more information compared
    to Intel's this patch tested on PM983 M2 SSD and works as expected.
    
    Reviewed by:            imp@
    Approved by:            kp@
    Event:                  Aberdeen Hackathon 2022
    Differential revision:  https://reviews.freebsd.org/D33749
---
 sbin/nvmecontrol/modules/Makefile          |   2 +-
 sbin/nvmecontrol/modules/samsung/Makefile  |   6 ++
 sbin/nvmecontrol/modules/samsung/samsung.c | 165 +++++++++++++++++++++++++++++
 sbin/nvmecontrol/nvmecontrol.8             |   4 +-
 4 files changed, 175 insertions(+), 2 deletions(-)

diff --git a/sbin/nvmecontrol/modules/Makefile 
b/sbin/nvmecontrol/modules/Makefile
index e615eaffb8c9..7bc9712e99e5 100644
--- a/sbin/nvmecontrol/modules/Makefile
+++ b/sbin/nvmecontrol/modules/Makefile
@@ -1,5 +1,5 @@
 # $FreeBSD$
 
-SUBDIR=        intel wdc
+SUBDIR=        intel wdc samsung
 
 .include <bsd.subdir.mk>
diff --git a/sbin/nvmecontrol/modules/samsung/Makefile 
b/sbin/nvmecontrol/modules/samsung/Makefile
new file mode 100644
index 000000000000..c22e8b2b4fdf
--- /dev/null
+++ b/sbin/nvmecontrol/modules/samsung/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+LIB=   samsung
+SRCS=  samsung.c
+
+.include <bsd.lib.mk>
diff --git a/sbin/nvmecontrol/modules/samsung/samsung.c 
b/sbin/nvmecontrol/modules/samsung/samsung.c
new file mode 100644
index 000000000000..50f0a89db13b
--- /dev/null
+++ b/sbin/nvmecontrol/modules/samsung/samsung.c
@@ -0,0 +1,165 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (C) 2022 Wanpeng Qian <[email protected]>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/ioccom.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/endian.h>
+
+#include "nvmecontrol.h"
+
+struct samsung_log_extended_smart
+{
+       uint8_t         kv[256];/* Key-Value pair */
+       uint32_t        lwaf;   /* Lifetime Write Amplification */
+       uint32_t        thwaf;  /* Trailing Hour Write Amplification Factor */
+       uint64_t        luw[2]; /* Lifetime User Writes */
+       uint64_t        lnw[2]; /* Lifetime NAND Writes */
+       uint64_t        lur[2]; /* Lifetime User Reads */
+       uint32_t        lrbc;   /* Lifetime Retired Block Count */
+       uint16_t        ct;     /* Current Temperature */
+       uint16_t        ch;     /* Capacitor Health */
+       uint32_t        luurb;  /* Lifetime Unused Reserved Block */
+       uint64_t        rrc;    /* Read Reclaim Count */
+       uint64_t        lueccc; /* Lifetime Uncorrectable ECC count */
+       uint32_t        lurb;   /* Lifetime Used Reserved Block */
+       uint64_t        poh[2]; /* Power on Hours */
+       uint64_t        npoc[2];/* Normal Power Off Count */
+       uint64_t        spoc[2];/* Sudden Power Off Count */
+       uint32_t        pi;     /* Performance Indicator */
+} __packed;
+
+static void
+print_samsung_extended_smart(const struct nvme_controller_data *cdata 
__unused, void *buf, uint32_t size __unused)
+{
+       struct samsung_log_extended_smart *temp = buf;
+       char cbuf[UINT128_DIG + 1];
+       uint8_t *walker = buf;
+       uint8_t *end = walker + 150;
+       const char *name;
+       uint64_t raw;
+       uint8_t normalized;
+
+       static struct kv_name kv[] =
+       {
+               { 0xab, "Lifetime Program Fail Count" },
+               { 0xac, "Lifetime Erase Fail Count" },
+               { 0xad, "Lifetime Wear Leveling Count" },
+               { 0xb8, "Lifetime End to End Error Count" },
+               { 0xc7, "Lifetime CRC Error Count" },
+               { 0xe2, "Media Wear %" },
+               { 0xe3, "Host Read %" },
+               { 0xe4, "Workload Timer" },
+               { 0xea, "Lifetime Thermal Throttle Status" },
+               { 0xf4, "Lifetime Phy Pages Written Count" },
+               { 0xf5, "Lifetime Data Units Written" },
+       };
+
+       printf("Extended SMART Information\n");
+       printf("=========================\n");
+       /*
+        * walker[0] = Key
+        * walker[1,2] = reserved
+        * walker[3] = Normalized Value
+        * walker[4] = reserved
+        * walker[5..10] = Little Endian Raw value
+        *      (or other represenations)
+        * walker[11] = reserved
+        */
+       while (walker < end) {
+               name = kv_lookup(kv, nitems(kv), *walker);
+               normalized = walker[3];
+               raw = le48dec(walker + 5);
+               switch (*walker){
+               case 0:
+                       break;
+               case 0xad:
+                       printf("%2X %-41s: %3d min: %u max: %u ave: %u\n",
+                           le16dec(walker), name, normalized,
+                           le16dec(walker + 5), le16dec(walker + 7), 
le16dec(walker + 9));
+                       break;
+               case 0xe2:
+                       printf("%2X %-41s: %3d %.3f%%\n",
+                           le16dec(walker), name, normalized,
+                           raw / 1024.0);
+                       break;
+               case 0xea:
+                       printf("%2X %-41s: %3d %d%% %d times\n",
+                           le16dec(walker), name, normalized,
+                           walker[5], le32dec(walker+6));
+                       break;
+               default:
+                       printf("%2X %-41s: %3d %ju\n",
+                           le16dec(walker), name, normalized,
+                           (uintmax_t)raw);
+                       break;
+               }
+               walker += 12;
+       }
+
+       printf("   Lifetime Write Amplification Factor      : %u\n", 
le32dec(&temp->lwaf));
+       printf("   Trailing Hour Write Amplification Factor : %u\n", 
le32dec(&temp->thwaf));
+       printf("   Lifetime User Writes                     : %s\n",
+           uint128_to_str(to128(temp->luw), cbuf, sizeof(cbuf)));
+       printf("   Lifetime NAND Writes                     : %s\n",
+           uint128_to_str(to128(temp->lnw), cbuf, sizeof(cbuf)));
+       printf("   Lifetime User Reads                      : %s\n",
+           uint128_to_str(to128(temp->lur), cbuf, sizeof(cbuf)));
+       printf("   Lifetime Retired Block Count             : %u\n", 
le32dec(&temp->lrbc));
+       printf("   Current Temperature                      : ");
+       print_temp(le16dec(&temp->ct));
+       printf("   Capacitor Health                         : %u\n", 
le16dec(&temp->ch));
+       printf("   Reserved Erase Block Count               : %u\n", 
le32dec(&temp->luurb));
+       printf("   Read Reclaim Count                       : %lu\n", 
le64dec(&temp->rrc));
+       printf("   Lifetime Uncorrectable ECC Count         : %lu\n", 
le64dec(&temp->lueccc));
+       printf("   Reallocated Block Count                  : %u\n", 
le32dec(&temp->lurb));
+       printf("   Power on Hours                           : %s\n",
+           uint128_to_str(to128(temp->poh), cbuf, sizeof(cbuf)));
+       printf("   Normal Power Off Count                   : %s\n",
+           uint128_to_str(to128(temp->npoc), cbuf, sizeof(cbuf)));
+       printf("   Sudden Power Off Count                   : %s\n",
+           uint128_to_str(to128(temp->spoc), cbuf, sizeof(cbuf)));
+       printf("   Performance Indicator                    : %u\n", 
le32dec(&temp->pi));
+}
+
+#define SAMSUNG_LOG_EXTEND_SMART 0xca
+
+NVME_LOGPAGE(samsung_extended_smart,
+    SAMSUNG_LOG_EXTEND_SMART,          "samsung", "Extended SMART Information",
+    print_samsung_extended_smart,      DEFAULT_SIZE);
diff --git a/sbin/nvmecontrol/nvmecontrol.8 b/sbin/nvmecontrol/nvmecontrol.8
index 7d70e1762f73..d6b41889a727 100644
--- a/sbin/nvmecontrol/nvmecontrol.8
+++ b/sbin/nvmecontrol/nvmecontrol.8
@@ -244,7 +244,7 @@ data associated with that drive.
 .El
 .Ss logpage
 The logpage command knows how to print log pages of various types.
-It also knows about vendor specific log pages from hgst/wdc and intel.
+It also knows about vendor specific log pages from hgst/wdc, samsung and intel.
 Note that some vendors use the same log page numbers for different data.
 .Pp
 .Bl -tag -compact -width "Page 0x00"
@@ -274,6 +274,8 @@ Wite latency stats (Intel)
 Temperature stats (Intel)
 .It Dv Page 0xca
 Advanced SMART information (Intel)
+.It Dv Page 0xca
+Extended SMART information (Samsung)
 .El
 .Pp
 Specifying

Reply via email to