aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWanpeng Qian <wanpengqian@gmail.com>2022-10-06 10:10:06 +0000
committerBenedict Reuschling <bcr@FreeBSD.org>2022-10-06 10:24:02 +0000
commit84e86788705c176cc195e4a9831c0be08dcece31 (patch)
tree9a015a963c34394cd6b67fd36c32313b4fa9bff7
parent4cb3cb2de2065bccbab65b0139c1be65f1da3fdf (diff)
downloadsrc-84e86788705c176cc195e4a9831c0be08dcece31.tar.gz
src-84e86788705c176cc195e4a9831c0be08dcece31.zip
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
-rw-r--r--sbin/nvmecontrol/modules/Makefile2
-rw-r--r--sbin/nvmecontrol/modules/samsung/Makefile6
-rw-r--r--sbin/nvmecontrol/modules/samsung/samsung.c165
-rw-r--r--sbin/nvmecontrol/nvmecontrol.84
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 <wanpengqian@gmail.org>
+ *
+ * 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