Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sbin/nvmectl nvmectl(8): sync with FreeBSD HEAD r316105.



details:   https://anonhg.NetBSD.org/src/rev/74e6a0a31003
branches:  trunk
changeset: 823613:74e6a0a31003
user:      nonaka <nonaka%NetBSD.org@localhost>
date:      Sat Apr 29 00:06:40 2017 +0000

description:
nvmectl(8): sync with FreeBSD HEAD r316105.

 - Expand the SMART / Health Information Log Page (Page 02) printout based on
   NVM Express 1.2.1 Standard.
 - Implement Intel-specific log pages.
 - Implement HGST-specific log pages.
 - Implement wdc-specific nvme control options.
 - Add the ability to dump log pages directly in binary to stdout.

diffstat:

 sbin/nvmectl/Makefile   |    3 +-
 sbin/nvmectl/firmware.c |    8 +-
 sbin/nvmectl/logpage.c  |  773 +++++++++++++++++++++++++++++++++++++++++++----
 sbin/nvmectl/nvme.h     |   38 +-
 sbin/nvmectl/nvmectl.8  |   73 ++++-
 sbin/nvmectl/nvmectl.c  |   53 +-
 sbin/nvmectl/nvmectl.h  |   31 +-
 7 files changed, 863 insertions(+), 116 deletions(-)

diffs (truncated from 1333 to 300 lines):

diff -r 7c8529350101 -r 74e6a0a31003 sbin/nvmectl/Makefile
--- a/sbin/nvmectl/Makefile     Sat Apr 29 00:05:35 2017 +0000
+++ b/sbin/nvmectl/Makefile     Sat Apr 29 00:06:40 2017 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: Makefile,v 1.2 2017/02/13 11:16:46 nonaka Exp $
+#      $NetBSD: Makefile,v 1.3 2017/04/29 00:06:40 nonaka Exp $
 
 .include <bsd.own.mk>
 
@@ -11,6 +11,7 @@
 SRCS+= perftest.c
 SRCS+= power.c
 SRCS+= reset.c
+SRCS+= wdc.c
 SRCS+= bignum.c
 SRCS+= humanize_bignum.c
 MAN=   nvmectl.8
diff -r 7c8529350101 -r 74e6a0a31003 sbin/nvmectl/firmware.c
--- a/sbin/nvmectl/firmware.c   Sat Apr 29 00:05:35 2017 +0000
+++ b/sbin/nvmectl/firmware.c   Sat Apr 29 00:06:40 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: firmware.c,v 1.1 2016/06/04 16:29:35 nonaka Exp $      */
+/*     $NetBSD: firmware.c,v 1.2 2017/04/29 00:06:40 nonaka Exp $      */
 
 /*-
  * Copyright (c) 2013 EMC Corp.
@@ -31,9 +31,9 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: firmware.c,v 1.1 2016/06/04 16:29:35 nonaka Exp $");
+__RCSID("$NetBSD: firmware.c,v 1.2 2017/04/29 00:06:40 nonaka Exp $");
 #if 0
-__FBSDID("$FreeBSD: head/sbin/nvmecontrol/firmware.c 258071 2013-11-12 21:14:19Z jimharris $");
+__FBSDID("$FreeBSD: head/sbin/nvmecontrol/firmware.c 313188 2017-02-04 05:52:50Z imp $");
 #endif
 #endif
 
@@ -121,7 +121,7 @@
        off = 0;
        resid = payload_size;
 
-       if ((chunk = malloc(NVME_MAX_XFER_SIZE)) == NULL)
+       if ((chunk = aligned_alloc(PAGE_SIZE, NVME_MAX_XFER_SIZE)) == NULL)
                errx(1, "unable to malloc %d bytes", NVME_MAX_XFER_SIZE);
 
        while (resid > 0) {
diff -r 7c8529350101 -r 74e6a0a31003 sbin/nvmectl/logpage.c
--- a/sbin/nvmectl/logpage.c    Sat Apr 29 00:05:35 2017 +0000
+++ b/sbin/nvmectl/logpage.c    Sat Apr 29 00:06:40 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: logpage.c,v 1.3 2017/02/13 11:16:46 nonaka Exp $       */
+/*     $NetBSD: logpage.c,v 1.4 2017/04/29 00:06:40 nonaka Exp $       */
 
 /*-
  * Copyright (c) 2013 EMC Corp.
@@ -31,14 +31,15 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: logpage.c,v 1.3 2017/02/13 11:16:46 nonaka Exp $");
+__RCSID("$NetBSD: logpage.c,v 1.4 2017/04/29 00:06:40 nonaka Exp $");
 #if 0
-__FBSDID("$FreeBSD: head/sbin/nvmecontrol/logpage.c 285796 2015-07-22 16:10:29Z jimharris $");
+__FBSDID("$FreeBSD: head/sbin/nvmecontrol/logpage.c 314230 2017-02-25 00:09:16Z imp $");
 #endif
 #endif
 
 #include <sys/param.h>
 #include <sys/ioccom.h>
+#include <sys/endian.h>
 
 #include <ctype.h>
 #include <err.h>
@@ -58,6 +59,39 @@
 
 typedef void (*print_fn_t)(void *buf, uint32_t size);
 
+struct kv_name {
+       uint32_t key;
+       const char *name;
+};
+
+static const char *
+kv_lookup(const struct kv_name *kv, size_t kv_count, uint32_t key)
+{
+       static char bad[32];
+       size_t i;
+
+       for (i = 0; i < kv_count; i++, kv++)
+               if (kv->key == key)
+                       return kv->name;
+       snprintf(bad, sizeof(bad), "Attribute %#x", key);
+       return bad;
+}
+
+static void
+print_bin(void *data, uint32_t length)
+{
+       write(STDOUT_FILENO, data, length);
+}
+
+/* "Missing" from endian.h */
+static __inline uint64_t
+le48dec(const void *pp)
+{
+       uint8_t const *p = (uint8_t const *)pp;
+
+       return (((uint64_t)le16dec(p + 4) << 32) | le32dec(p));
+}
+
 static void *
 get_log_buffer(uint32_t size)
 {
@@ -178,10 +212,17 @@
 }
 
 static 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);
+}
+
+static void
 print_log_health(void *buf, uint32_t size __unused)
 {
        struct nvme_health_information_page *health = buf;
-       float composite_temperature = health->composite_temperature;
+       int i;
 
        printf("SMART/Health Information Log\n");
        printf("============================\n");
@@ -203,10 +244,8 @@
        printf(" Volatile memory backup:        %d\n",
            (uint8_t)__SHIFTOUT(health->critical_warning,
              NVME_HEALTH_PAGE_CW_VOLATILE_MEMORY_BACKUP));
-       printf("Temperature:                    %u K, %2.2f C, %3.2f F\n",
-           health->composite_temperature,
-           composite_temperature - (float)273.15,
-           (composite_temperature * (float)9/5) - (float)459.67);
+       printf("Temperature:                    ");
+       print_temp(health->composite_temperature);
        printf("Available spare:                %u\n",
            health->available_spare);
        printf("Available spare threshold:      %u\n",
@@ -214,26 +253,28 @@
        printf("Percentage used:                %u\n",
            health->percentage_used);
 
-       print_bignum("Data units (512 byte) read:",
-           health->data_units_read, "");
-       print_bignum("Data units (512 byte) written:",
-           health->data_units_written, "");
-       print_bignum("Host read commands:",
-           health->host_read_commands, "");
-       print_bignum("Host write commands:",
-           health->host_write_commands, "");
-       print_bignum("Controller busy time (minutes):",
-           health->controller_busy_time, "");
-       print_bignum("Power cycles:",
-           health->power_cycles, "");
-       print_bignum("Power on hours:",
-           health->power_on_hours, "");
-       print_bignum("Unsafe shutdowns:",
-           health->unsafe_shutdowns, "");
-       print_bignum("Media errors:",
-           health->media_errors, "");
+       print_bignum("Data units (512 byte) read:", health->data_units_read, "");
+       print_bignum("Data units (512 byte) written:", health->data_units_written,
+           "");
+       print_bignum("Host read commands:", health->host_read_commands, "");
+       print_bignum("Host write commands:", health->host_write_commands, "");
+       print_bignum("Controller busy time (minutes):", health->controller_busy_time,
+           "");
+       print_bignum("Power cycles:", health->power_cycles, "");
+       print_bignum("Power on hours:", health->power_on_hours, "");
+       print_bignum("Unsafe shutdowns:", health->unsafe_shutdowns, "");
+       print_bignum("Media errors:", health->media_errors, "");
        print_bignum("No. error info log entries:",
            health->num_error_info_log_entries, "");
+
+       printf("Warning Temp Composite Time:    %d\n", health->warning_temp_time);
+       printf("Error Temp Composite Time:      %d\n", health->error_temp_time);
+       for (i = 0; i < 7; i++) {
+               if (health->temp_sensor[i] == 0)
+                       continue;
+               printf("Temperature Sensor %d:           ", i + 1);
+               print_temp(health->temp_sensor[i]);
+       }
 }
 
 static void
@@ -265,14 +306,593 @@
        }
 }
 
+/*
+ * 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(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(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(void *buf, uint32_t size)
+{
+
+       printf("Intel Read Latency Log\n");
+       printf("======================\n");
+       print_intel_read_write_lat_log(buf, size);
+}
+
+static void
+print_intel_write_lat_log(void *buf, uint32_t size)
+{
+
+       printf("Intel Write Latency Log\n");
+       printf("=======================\n");
+       print_intel_read_write_lat_log(buf, size);
+}
+
+/*
+ * Table 19. 5.4 SMART Attributes.
+ * Samsung also implements this and some extra data not documented.
+ */
+static void
+print_intel_add_smart(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" },
+       };
+



Home | Main Index | Thread Index | Old Index