Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sbin/atactl "smart status" already obtains the ata parameter...
details: https://anonhg.NetBSD.org/src/rev/55fc52598d11
branches: trunk
changeset: 995069:55fc52598d11
user: mrg <mrg%NetBSD.org@localhost>
date: Wed Dec 05 06:49:54 2018 +0000
description:
"smart status" already obtains the ata parameters to check if smart
is actually supported, so we can attempt to guess a vendor smart
table from the model name. add basic support for all the micron /
crucial disk names i could find, and add a couple more micron
specific values.
XXX: probably should add regex support for matching, and probably
should be more restrictive with the current matches.
diffstat:
sbin/atactl/atactl.8 | 10 +++-
sbin/atactl/atactl.c | 129 +++++++++++++++++++++++++++++++++++---------------
2 files changed, 99 insertions(+), 40 deletions(-)
diffs (truncated from 312 to 300 lines):
diff -r 62d72aca4172 -r 55fc52598d11 sbin/atactl/atactl.8
--- a/sbin/atactl/atactl.8 Wed Dec 05 05:52:23 2018 +0000
+++ b/sbin/atactl/atactl.8 Wed Dec 05 06:49:54 2018 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: atactl.8,v 1.26 2018/11/03 10:51:14 wiz Exp $
+.\" $NetBSD: atactl.8,v 1.27 2018/12/05 06:49:54 mrg Exp $
.\"
.\" Copyright (c) 1998 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -27,7 +27,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd October 4, 2018
+.Dd December 5, 2018
.Dt ATACTL 8
.Os
.Sh NAME
@@ -162,6 +162,8 @@
Currently, only
.Dq micron
has a vendor-specific table.
+If the vendor is not supplied, it may be guessed from devices' model
+or other data available.
.It Ar offline #
Runs the numbered offline self-test on the drive.
.It Ar error-log
@@ -273,6 +275,10 @@
.Xr scsictl 8
command written by
.An Jason R. Thorpe .
+.An Matthew R. Green
+significantly enhanced the
+.Cm smart status
+support.
.Sh BUGS
The output from the
.Cm identify
diff -r 62d72aca4172 -r 55fc52598d11 sbin/atactl/atactl.c
--- a/sbin/atactl/atactl.c Wed Dec 05 05:52:23 2018 +0000
+++ b/sbin/atactl/atactl.c Wed Dec 05 06:49:54 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: atactl.c,v 1.78 2018/10/31 20:00:56 mrg Exp $ */
+/* $NetBSD: atactl.c,v 1.79 2018/12/05 06:49:54 mrg Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: atactl.c,v 1.78 2018/10/31 20:00:56 mrg Exp $");
+__RCSID("$NetBSD: atactl.c,v 1.79 2018/12/05 06:49:54 mrg Exp $");
#endif
@@ -114,7 +114,7 @@
static void print_error(const void *);
static void print_selftest(const void *);
-static const struct ataparams *getataparams(void);
+static void fillataparams(void);
static int is_smart(void);
@@ -122,6 +122,10 @@
static const char *dvname; /* device name */
static char dvname_store[MAXPATHLEN]; /* for opendisk(3) */
static const char *cmdname; /* command user issued */
+static const struct ataparams *inqbuf; /* inquiry buffer */
+static char model[sizeof(inqbuf->atap_model)+1];
+static char revision[sizeof(inqbuf->atap_revision)+1];
+static char serial[sizeof(inqbuf->atap_serial)+1];
static void device_identify(int, char *[]);
static void device_setidle(int, char *[]);
@@ -355,7 +359,9 @@
static const struct attr_table micron_smart_names[] = {
{ 5, "Reallocated NAND block count", NULL },
{ 173, "Average block erase count", NULL },
+ { 181, "Non 4K aligned access count", NULL },
{ 184, "Error correction count", NULL },
+ { 189, "Factory bad block count", NULL },
{ 197, "Current pending ECC count", NULL },
{ 198, "SMART offline scan uncorrectable error count", NULL },
{ 202, "Percent lifetime remaining", NULL },
@@ -855,14 +861,19 @@
print_selftest_entry(i, &stlog->log_entries[i]);
}
-static const struct ataparams *
-getataparams(void)
+static void
+fillataparams(void)
{
struct atareq req;
static union {
unsigned char inbuf[DEV_BSIZE];
struct ataparams inqbuf;
} inbuf;
+ static int first = 1;
+
+ if (!first)
+ return;
+ first = 0;
memset(&inbuf, 0, sizeof(inbuf));
memset(&req, 0, sizeof(req));
@@ -875,7 +886,7 @@
ata_command(&req);
- return (&inbuf.inqbuf);
+ inqbuf = &inbuf.inqbuf;
}
/*
@@ -888,10 +899,9 @@
is_smart(void)
{
int retval = 0;
- const struct ataparams *inqbuf;
const char *status;
- inqbuf = getataparams();
+ fillataparams();
if (inqbuf->atap_cmd_def != 0 && inqbuf->atap_cmd_def != 0xffff) {
if (!(inqbuf->atap_cmd_set1 & WDC_CMD1_SMART)) {
@@ -951,8 +961,7 @@
}
static void
-compute_capacity(const struct ataparams *inqbuf, uint64_t *capacityp,
- uint64_t *sectorsp, uint32_t *secsizep)
+compute_capacity(uint64_t *capacityp, uint64_t *sectorsp, uint32_t *secsizep)
{
uint64_t capacity;
uint64_t sectors;
@@ -994,38 +1003,51 @@
}
/*
- * DEVICE COMMANDS
+ * Inspect the inqbuf and guess what vendor to use. This list is fairly
+ * basic, and probably should be converted into a regexp scheme.
*/
+static const char *
+guess_vendor(void)
+{
+ struct {
+ const char *model;
+ const char *vendor;
+ } model_to_vendor[] = {
+ { "Crucial", "Micron" },
+ { "Micron", "Micron" },
+ { "C300-CT", "Micron" },
+ { "C400-MT", "Micron" },
+ { "M4-CT", "Micron" },
+ { "M500", "Micron" },
+ { "M510", "Micron" },
+ { "M550", "Micron" },
+ { "MTFDDA", "Micron" },
+ { "EEFDDA", "Micron" },
+ };
+ unsigned i;
+
+ for (i = 0; i < __arraycount(model_to_vendor); i++)
+ if (strncasecmp(model, model_to_vendor[i].model,
+ strlen(model_to_vendor[i].model)) == 0)
+ return model_to_vendor[i].vendor;
+
+ return NULL;
+}
/*
- * device_identify:
- *
- * Display the identity of the device
+ * identify_fixup() - Given an obtained ataparams, fix up the endian and
+ * other issues before using them.
*/
static void
-device_identify(int argc, char *argv[])
+identify_fixup(void)
{
- const struct ataparams *inqbuf;
- char model[sizeof(inqbuf->atap_model)+1];
- char revision[sizeof(inqbuf->atap_revision)+1];
- char serial[sizeof(inqbuf->atap_serial)+1];
- char hnum[12];
- uint64_t capacity;
- uint64_t sectors;
- uint32_t secsize;
- int lb_per_pb;
int needswap = 0;
- int i;
- uint8_t checksum;
-
- /* No arguments. */
- if (argc != 0)
- usage();
-
- inqbuf = getataparams();
if ((inqbuf->atap_integrity & WDC_INTEGRITY_MAGIC_MASK) ==
WDC_INTEGRITY_MAGIC) {
+ int i;
+ uint8_t checksum;
+
for (i = checksum = 0; i < 512; i++)
checksum += ((const uint8_t *)inqbuf)[i];
if (checksum != 0)
@@ -1062,6 +1084,33 @@
inqbuf->atap_serial, sizeof(inqbuf->atap_serial),
needswap);
+}
+
+/*
+ * DEVICE COMMANDS
+ */
+
+/*
+ * device_identify:
+ *
+ * Display the identity of the device
+ */
+static void
+device_identify(int argc, char *argv[])
+{
+ char hnum[12];
+ uint64_t capacity;
+ uint64_t sectors;
+ uint32_t secsize;
+ int lb_per_pb;
+
+ /* No arguments. */
+ if (argc != 0)
+ usage();
+
+ fillataparams();
+ identify_fixup();
+
printf("Model: %s, Rev: %s, Serial #: %s\n",
model, revision, serial);
@@ -1081,7 +1130,7 @@
inqbuf->atap_config & ATA_CFG_FIXED ? "fixed" : "removable");
printf("\n");
- compute_capacity(inqbuf, &capacity, §ors, &secsize);
+ compute_capacity(&capacity, §ors, &secsize);
humanize_number(hnum, sizeof(hnum), capacity, "bytes",
HN_AUTOSCALE, HN_DIVISOR_1000);
@@ -1361,7 +1410,7 @@
is_smart();
} else if (strcmp(argv[0], "status") == 0) {
int rv;
- char *vendor = argc > 1 ? argv[1] : NULL;
+ const char *vendor = argc > 1 ? argv[1] : NULL;
rv = is_smart();
@@ -1416,6 +1465,11 @@
ata_command(&req);
+ if (!vendor || strcmp(vendor, "noauto") == 0) {
+ fillataparams();
+ identify_fixup();
+ vendor = guess_vendor();
+ }
print_smart_status(inbuf, inbuf2, vendor);
} else if (strcmp(argv[0], "offline") == 0) {
@@ -1490,7 +1544,6 @@
device_security(int argc, char *argv[])
{
struct atareq req;
- const struct ataparams *inqbuf;
unsigned char data[DEV_BSIZE];
char *pass;
@@ -1500,7 +1553,7 @@
memset(&req, 0, sizeof(req));
if (strcmp(argv[0], "status") == 0) {
- inqbuf = getataparams();
+ fillataparams();
print_bitinfo("\t", "\n", inqbuf->atap_sec_st, ata_sec_st);
} else if (strcmp(argv[0], "freeze") == 0) {
req.command = WDCC_SECURITY_FREEZE;
@@ -1551,7 +1604,7 @@
} else if (strcmp(argv[0], "erase") == 0) {
struct atareq prepare;
- inqbuf = getataparams();
+ fillataparams();
Home |
Main Index |
Thread Index |
Old Index