summaryrefslogtreecommitdiff
path: root/sbin/nvmecontrol
diff options
context:
space:
mode:
authorWarner Losh <imp@FreeBSD.org>2018-12-02 23:13:24 +0000
committerWarner Losh <imp@FreeBSD.org>2018-12-02 23:13:24 +0000
commit2da383a59a3adfb6a37058933a2d13246b1e3e93 (patch)
tree187bb777110264c946ba33b3a4722a0b58bf50af /sbin/nvmecontrol
parentd4fdb249f234dcd9daed181d57eff5a3812e9316 (diff)
downloadsrc-test2-2da383a59a3adfb6a37058933a2d13246b1e3e93.tar.gz
src-test2-2da383a59a3adfb6a37058933a2d13246b1e3e93.zip
Notes
Diffstat (limited to 'sbin/nvmecontrol')
-rw-r--r--sbin/nvmecontrol/Makefile3
-rw-r--r--sbin/nvmecontrol/intel.c198
-rw-r--r--sbin/nvmecontrol/logpage.c151
-rw-r--r--sbin/nvmecontrol/nvmecontrol.h1
4 files changed, 202 insertions, 151 deletions
diff --git a/sbin/nvmecontrol/Makefile b/sbin/nvmecontrol/Makefile
index d436c2622f55..21102cfae44c 100644
--- a/sbin/nvmecontrol/Makefile
+++ b/sbin/nvmecontrol/Makefile
@@ -3,7 +3,8 @@
PACKAGE=runtime
PROG= nvmecontrol
SRCS= nvmecontrol.c devlist.c firmware.c format.c identify.c identify_ext.c logpage.c \
- perftest.c reset.c ns.c nvme_util.c power.c nc_util.c wdc.c
+ perftest.c reset.c ns.c nvme_util.c power.c nc_util.c
+SRCS+= wdc.c intel.c
MAN= nvmecontrol.8
.PATH: ${SRCTOP}/sys/dev/nvme
diff --git a/sbin/nvmecontrol/intel.c b/sbin/nvmecontrol/intel.c
new file mode 100644
index 000000000000..abc0374600ed
--- /dev/null
+++ b/sbin/nvmecontrol/intel.c
@@ -0,0 +1,198 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2013 EMC Corp.
+ * All rights reserved.
+ *
+ * Copyright (C) 2012-2013 Intel Corporation
+ * All rights reserved.
+ *
+ * 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"
+
+/*
+ * Intel specific log pages from
+ * http://www.intel.com/content/dam/www/public/us/en/documents/product-specifications/ssd-dc-p3700-spec.pdf
+ *
+ * Though the version as of this date has a typo for the size of log page 0xca,
+ * offset 147: it is only 1 byte, not 6.
+ */
+static void
+print_intel_temp_stats(const struct nvme_controller_data *cdata __unused, void *buf, uint32_t size __unused)
+{
+ struct intel_log_temp_stats *temp = buf;
+
+ printf("Intel Temperature Log\n");
+ printf("=====================\n");
+
+ printf("Current: ");
+ print_temp(temp->current);
+ printf("Overtemp Last Flags %#jx\n", (uintmax_t)temp->overtemp_flag_last);
+ printf("Overtemp Lifetime Flags %#jx\n", (uintmax_t)temp->overtemp_flag_life);
+ printf("Max Temperature ");
+ print_temp(temp->max_temp);
+ printf("Min Temperature ");
+ print_temp(temp->min_temp);
+ printf("Max Operating Temperature ");
+ print_temp(temp->max_oper_temp);
+ printf("Min Operating Temperature ");
+ print_temp(temp->min_oper_temp);
+ printf("Estimated Temperature Offset: %ju C/K\n", (uintmax_t)temp->est_offset);
+}
+
+/*
+ * Format from Table 22, section 5.7 IO Command Latency Statistics.
+ * Read and write stats pages have identical encoding.
+ */
+static void
+print_intel_read_write_lat_log(const struct nvme_controller_data *cdata __unused, void *buf, uint32_t size __unused)
+{
+ const char *walker = buf;
+ int i;
+
+ printf("Major: %d\n", le16dec(walker + 0));
+ printf("Minor: %d\n", le16dec(walker + 2));
+ for (i = 0; i < 32; i++)
+ printf("%4dus-%4dus: %ju\n", i * 32, (i + 1) * 32, (uintmax_t)le32dec(walker + 4 + i * 4));
+ for (i = 1; i < 32; i++)
+ printf("%4dms-%4dms: %ju\n", i, i + 1, (uintmax_t)le32dec(walker + 132 + i * 4));
+ for (i = 1; i < 32; i++)
+ printf("%4dms-%4dms: %ju\n", i * 32, (i + 1) * 32, (uintmax_t)le32dec(walker + 256 + i * 4));
+}
+
+static void
+print_intel_read_lat_log(const struct nvme_controller_data *cdata __unused, void *buf, uint32_t size)
+{
+
+ printf("Intel Read Latency Log\n");
+ printf("======================\n");
+ print_intel_read_write_lat_log(cdata, buf, size);
+}
+
+static void
+print_intel_write_lat_log(const struct nvme_controller_data *cdata __unused, void *buf, uint32_t size)
+{
+
+ printf("Intel Write Latency Log\n");
+ printf("=======================\n");
+ print_intel_read_write_lat_log(cdata, buf, size);
+}
+
+/*
+ * Table 19. 5.4 SMART Attributes. Samsung also implements this and some extra data not documented.
+ */
+static void
+print_intel_add_smart(const struct nvme_controller_data *cdata __unused, void *buf, uint32_t size __unused)
+{
+ uint8_t *walker = buf;
+ uint8_t *end = walker + 150;
+ const char *name;
+ uint64_t raw;
+ uint8_t normalized;
+
+ static struct kv_name kv[] =
+ {
+ { 0xab, "Program Fail Count" },
+ { 0xac, "Erase Fail Count" },
+ { 0xad, "Wear Leveling Count" },
+ { 0xb8, "End to End Error Count" },
+ { 0xc7, "CRC Error Count" },
+ { 0xe2, "Timed: Media Wear" },
+ { 0xe3, "Timed: Host Read %" },
+ { 0xe4, "Timed: Elapsed Time" },
+ { 0xea, "Thermal Throttle Status" },
+ { 0xf0, "Retry Buffer Overflows" },
+ { 0xf3, "PLL Lock Loss Count" },
+ { 0xf4, "NAND Bytes Written" },
+ { 0xf5, "Host Bytes Written" },
+ };
+
+ printf("Additional SMART Data Log\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("%-32s: %3d min: %u max: %u ave: %u\n", name, normalized,
+ le16dec(walker + 5), le16dec(walker + 7), le16dec(walker + 9));
+ break;
+ case 0xe2:
+ printf("%-32s: %3d %.3f%%\n", name, normalized, raw / 1024.0);
+ break;
+ case 0xea:
+ printf("%-32s: %3d %d%% %d times\n", name, normalized, walker[5], le32dec(walker+6));
+ break;
+ default:
+ printf("%-32s: %3d %ju\n", name, normalized, (uintmax_t)raw);
+ break;
+ }
+ walker += 12;
+ }
+}
+
+NVME_LOGPAGE(intel_temp,
+ INTEL_LOG_TEMP_STATS, "intel", "Temperature Stats",
+ print_intel_temp_stats, sizeof(struct intel_log_temp_stats));
+NVME_LOGPAGE(intel_rlat,
+ INTEL_LOG_READ_LAT_LOG, "intel", "Read Latencies",
+ print_intel_read_lat_log, DEFAULT_SIZE);
+NVME_LOGPAGE(intel_wlat,
+ INTEL_LOG_WRITE_LAT_LOG, "intel", "Write Latencies",
+ print_intel_write_lat_log, DEFAULT_SIZE);
+NVME_LOGPAGE(intel_smart,
+ INTEL_LOG_ADD_SMART, "intel", "Extra Health/SMART Data",
+ print_intel_add_smart, DEFAULT_SIZE);
+NVME_LOGPAGE(samsung_smart, /* NOTE, this will be deleted before 13.0 */
+ INTEL_LOG_ADD_SMART, "samsung", "Extra Health/SMART Data",
+ print_intel_add_smart, DEFAULT_SIZE);
diff --git a/sbin/nvmecontrol/logpage.c b/sbin/nvmecontrol/logpage.c
index a6249a6d3f8b..6a73304e79f9 100644
--- a/sbin/nvmecontrol/logpage.c
+++ b/sbin/nvmecontrol/logpage.c
@@ -191,7 +191,7 @@ print_log_error(const struct nvme_controller_data *cdata __unused, void *buf, ui
}
}
-static void
+void
print_temp(uint16_t t)
{
printf("%u K, %2.2f C, %3.2f F\n", t, (float)t - 273.15, (float)t * 9 / 5 - 459.67);
@@ -308,142 +308,8 @@ print_log_firmware(const struct nvme_controller_data *cdata, void *buf, uint32_t
}
/*
- * Intel specific log pages from
- * http://www.intel.com/content/dam/www/public/us/en/documents/product-specifications/ssd-dc-p3700-spec.pdf
- *
- * Though the version as of this date has a typo for the size of log page 0xca,
- * offset 147: it is only 1 byte, not 6.
- */
-static void
-print_intel_temp_stats(const struct nvme_controller_data *cdata __unused, void *buf, uint32_t size __unused)
-{
- struct intel_log_temp_stats *temp = buf;
-
- printf("Intel Temperature Log\n");
- printf("=====================\n");
-
- printf("Current: ");
- print_temp(temp->current);
- printf("Overtemp Last Flags %#jx\n", (uintmax_t)temp->overtemp_flag_last);
- printf("Overtemp Lifetime Flags %#jx\n", (uintmax_t)temp->overtemp_flag_life);
- printf("Max Temperature ");
- print_temp(temp->max_temp);
- printf("Min Temperature ");
- print_temp(temp->min_temp);
- printf("Max Operating Temperature ");
- print_temp(temp->max_oper_temp);
- printf("Min Operating Temperature ");
- print_temp(temp->min_oper_temp);
- printf("Estimated Temperature Offset: %ju C/K\n", (uintmax_t)temp->est_offset);
-}
-
-/*
- * Format from Table 22, section 5.7 IO Command Latency Statistics.
- * Read and write stats pages have identical encoding.
- */
-static void
-print_intel_read_write_lat_log(const struct nvme_controller_data *cdata __unused, void *buf, uint32_t size __unused)
-{
- const char *walker = buf;
- int i;
-
- printf("Major: %d\n", le16dec(walker + 0));
- printf("Minor: %d\n", le16dec(walker + 2));
- for (i = 0; i < 32; i++)
- printf("%4dus-%4dus: %ju\n", i * 32, (i + 1) * 32, (uintmax_t)le32dec(walker + 4 + i * 4));
- for (i = 1; i < 32; i++)
- printf("%4dms-%4dms: %ju\n", i, i + 1, (uintmax_t)le32dec(walker + 132 + i * 4));
- for (i = 1; i < 32; i++)
- printf("%4dms-%4dms: %ju\n", i * 32, (i + 1) * 32, (uintmax_t)le32dec(walker + 256 + i * 4));
-}
-
-static void
-print_intel_read_lat_log(const struct nvme_controller_data *cdata __unused, void *buf, uint32_t size)
-{
-
- printf("Intel Read Latency Log\n");
- printf("======================\n");
- print_intel_read_write_lat_log(cdata, buf, size);
-}
-
-static void
-print_intel_write_lat_log(const struct nvme_controller_data *cdata __unused, void *buf, uint32_t size)
-{
-
- printf("Intel Write Latency Log\n");
- printf("=======================\n");
- print_intel_read_write_lat_log(cdata, buf, size);
-}
-
-/*
- * Table 19. 5.4 SMART Attributes. Samsung also implements this and some extra data not documented.
- */
-static void
-print_intel_add_smart(const struct nvme_controller_data *cdata __unused, void *buf, uint32_t size __unused)
-{
- uint8_t *walker = buf;
- uint8_t *end = walker + 150;
- const char *name;
- uint64_t raw;
- uint8_t normalized;
-
- static struct kv_name kv[] =
- {
- { 0xab, "Program Fail Count" },
- { 0xac, "Erase Fail Count" },
- { 0xad, "Wear Leveling Count" },
- { 0xb8, "End to End Error Count" },
- { 0xc7, "CRC Error Count" },
- { 0xe2, "Timed: Media Wear" },
- { 0xe3, "Timed: Host Read %" },
- { 0xe4, "Timed: Elapsed Time" },
- { 0xea, "Thermal Throttle Status" },
- { 0xf0, "Retry Buffer Overflows" },
- { 0xf3, "PLL Lock Loss Count" },
- { 0xf4, "NAND Bytes Written" },
- { 0xf5, "Host Bytes Written" },
- };
-
- printf("Additional SMART Data Log\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("%-32s: %3d min: %u max: %u ave: %u\n", name, normalized,
- le16dec(walker + 5), le16dec(walker + 7), le16dec(walker + 9));
- break;
- case 0xe2:
- printf("%-32s: %3d %.3f%%\n", name, normalized, raw / 1024.0);
- break;
- case 0xea:
- printf("%-32s: %3d %d%% %d times\n", name, normalized, walker[5], le32dec(walker+6));
- break;
- default:
- printf("%-32s: %3d %ju\n", name, normalized, (uintmax_t)raw);
- break;
- }
- walker += 12;
- }
-}
-
-/*
* Table of log page printer / sizing.
*
- * This includes Intel specific pages that are widely implemented.
* Make sure you keep all the pages of one vendor together so -v help
* lists all the vendors pages.
*/
@@ -456,21 +322,6 @@ NVME_LOGPAGE(health,
NVME_LOGPAGE(fw,
NVME_LOG_FIRMWARE_SLOT, NULL, "Firmware Information",
print_log_firmware, sizeof(struct nvme_firmware_page));
-NVME_LOGPAGE(intel_temp,
- INTEL_LOG_TEMP_STATS, "intel", "Temperature Stats",
- print_intel_temp_stats, sizeof(struct intel_log_temp_stats));
-NVME_LOGPAGE(intel_rlat,
- INTEL_LOG_READ_LAT_LOG, "intel", "Read Latencies",
- print_intel_read_lat_log, DEFAULT_SIZE);
-NVME_LOGPAGE(intel_wlat,
- INTEL_LOG_WRITE_LAT_LOG, "intel", "Write Latencies",
- print_intel_write_lat_log, DEFAULT_SIZE);
-NVME_LOGPAGE(intel_smart,
- INTEL_LOG_ADD_SMART, "intel", "Extra Health/SMART Data",
- print_intel_add_smart, DEFAULT_SIZE);
-NVME_LOGPAGE(samsung_smart,
- INTEL_LOG_ADD_SMART, "samsung", "Extra Health/SMART Data",
- print_intel_add_smart, DEFAULT_SIZE);
static void
logpage_help(void)
diff --git a/sbin/nvmecontrol/nvmecontrol.h b/sbin/nvmecontrol/nvmecontrol.h
index d643816d9d2a..2b39f6a30b65 100644
--- a/sbin/nvmecontrol/nvmecontrol.h
+++ b/sbin/nvmecontrol/nvmecontrol.h
@@ -88,6 +88,7 @@ void read_namespace_data(int fd, uint32_t nsid, struct nvme_namespace_data *nsda
void print_hex(void *data, uint32_t length);
void read_logpage(int fd, uint8_t log_page, uint32_t nsid, void *payload,
uint32_t payload_size);
+void print_temp(uint16_t t);
void usage(const struct nvme_function *f);
void dispatch_set(int argc, char *argv[], struct nvme_function **tbl,