aboutsummaryrefslogtreecommitdiff
path: root/src/sg_logs.c
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2019-02-06 23:24:46 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2019-02-06 23:24:46 +0000
commitd491f4c710d6d1d123d421eb0ba7aeddee9cf7d7 (patch)
treeef74075454c2237144874f57bdb21cae709b7631 /src/sg_logs.c
parent04adb7f5027fb9f8b4368e4eaa561e14591bb1a7 (diff)
downloadsg3_utils-d491f4c710d6d1d123d421eb0ba7aeddee9cf7d7.tar.gz
sg_logs+sg_vpd: tweaks for WDC SSD; sgh_dd add oflag=swait
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@810 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'src/sg_logs.c')
-rw-r--r--src/sg_logs.c219
1 files changed, 134 insertions, 85 deletions
diff --git a/src/sg_logs.c b/src/sg_logs.c
index 33a77b38..25088b45 100644
--- a/src/sg_logs.c
+++ b/src/sg_logs.c
@@ -36,7 +36,7 @@
#include "sg_unaligned.h"
#include "sg_pr2serr.h"
-static const char * version_str = "1.70 20190104"; /* spc5r19 + sbc4r11 */
+static const char * version_str = "1.72 20190203"; /* spc5r20 + sbc4r16 */
#define MX_ALLOC_LEN (0xfffc)
#define SHORT_RESP_LEN 128
@@ -180,6 +180,7 @@ struct opts_t {
int paramp;
int no_inq;
int dev_pdt; /* from device or --pdt=DT */
+ int decod_subpg_code;
const char * device_name;
const char * in_fn;
const char * pg_arg;
@@ -1868,6 +1869,7 @@ show_error_counter_page(const uint8_t * resp, int len,
const struct opts_t * op)
{
int num, pl, pc, pg_code;
+ uint64_t val;
const uint8_t * bp;
char str[PCB_STR_LEN];
@@ -1921,8 +1923,13 @@ show_error_counter_page(const uint8_t * resp, int len,
case 0x8015: printf(" Positioning errors [Hitachi]"); break;
default: printf(" Reserved or vendor specific [0x%x]", pc); break;
}
- printf(" = %" PRIu64 "", sg_get_unaligned_be(pl - 4, bp + 4));
- printf("\n");
+ val = sg_get_unaligned_be(pl - 4, bp + 4);
+ printf(" = %" PRIu64 "", val);
+ if (val > (1UL << 40))
+ printf(" [%" PRIu64 " TB]\n",
+ (val / (1000UL * 1000 * 1000 * 1000)));
+ else
+ printf("\n");
if (op->do_pcb)
printf(" <%s>\n", get_pcb_str(bp[2], str, sizeof(str)));
if (op->filter_given)
@@ -2884,8 +2891,9 @@ show_self_test_page(const uint8_t * resp, int len, const struct opts_t * op)
if (bp[17] || bp[18])
printf(" [%s]\n", sg_get_asc_ascq_str(bp[17], bp[18],
sizeof(b), b));
+ else
+ printf("\n");
}
- printf("\n");
if (op->do_pcb)
printf(" <%s>\n", get_pcb_str(bp[2], str, sizeof(str)));
if (op->filter_given)
@@ -3212,87 +3220,123 @@ show_ie_page(const uint8_t * resp, int len, const struct opts_t * op)
}
break;
default:
- if ((! is_smstr) || (param_len < 24)) {
+ if (is_smstr && (param_len >= 24)) {
+ switch (pc) {
+ case 0x1:
+ cp = "Read error rate";
+ break;
+ case 0x2:
+ cp = "Flash rom check";
+ break;
+ case 0x5:
+ cp = "Realloc block count";
+ break;
+ case 0x9:
+ cp = "Power on hours";
+ break;
+ case 0xc:
+ cp = "Power cycles";
+ break;
+ case 0xd:
+ cp = "Ecc rate";
+ break;
+ case 0x20:
+ cp = "Write amp";
+ break;
+ case 0xb1: /* 177 */
+ cp = "Percent life remaining";
+ break;
+ case 0xb4: /* 180 */
+ cp = "Unused reserved block count";
+ break;
+ case 0xb5: /* 181 */
+ cp = "Program fail count";
+ break;
+ case 0xb6: /* 182 */
+ cp = "Erase fail count";
+ break;
+ case 0xbe: /* 190 */
+ cp = "Drive temperature warn";
+ break;
+ case 0xc2: /* 194 */
+ cp = "Drive temperature";
+ break;
+ case 0xc3: /* 195 */
+ cp = "Uncorrected error count";
+ break;
+ case 0xc6: /* 198 */
+ cp = "Offline scan uncorrected sector count";
+ break;
+ case 0xe9: /* 233 */
+ cp = "Number of writes";
+ break;
+ default:
+ snprintf(bb, sizeof(bb), "parameter_code=0x%x (%d)",
+ pc, pc);
+ cp = bb;
+ break;
+ }
+ if (cp && (param_len >= 24)) {
+ if (! has_header) {
+ has_header = true;
+ printf(" Has|Ever %% to worst %% Current "
+ "Worst Threshold Attribute\n");
+ printf(" tripped fail to fail "
+ "value value\n");
+ }
+ printf(" %2d %2d %4d %4d %10u %10u %10u %s",
+ !!(0x80 & bp[4]), !!(0x40 & bp[4]), bp[5], bp[6],
+ sg_get_unaligned_be32(bp + 8),
+ sg_get_unaligned_be32(bp + 12),
+ sg_get_unaligned_be32(bp + 16),
+ cp);
+ decoded = true;
+ }
+ } else if (VP_HITA == op->vend_prod_num) {
+ switch (pc) {
+ case 0x1:
+ cp = "Remaining reserve 1";
+ break;
+ case 0x2:
+ cp = "Remaining reserve XOR";
+ break;
+ case 0x3:
+ cp = "XOR depletion";
+ break;
+ case 0x4:
+ cp = "Volatile memory backup failure";
+ break;
+ case 0x5:
+ cp = "Wear indicator";
+ break;
+ case 0x6:
+ cp = "System area wear indicator";
+ break;
+ case 0x7:
+ cp = "Channel hangs";
+ break;
+ case 0x8:
+ cp = "Flash scan failure";
+ break;
+ default:
+ decoded = false;
+ break;
+ }
+ if (cp) {
+ printf(" %s:\n", cp);
+ printf(" SMART sense_code=0x%x sense_qualifier=0x%x "
+ "threshold=%d%% trip=%d", bp[4], bp[5], bp[6],
+ bp[7]);
+ }
+ } else
decoded = false;
- break;
- }
- switch (pc) {
- case 0x1:
- cp = "Read error rate";
- break;
- case 0x2:
- cp = "Flash rom check";
- break;
- case 0x5:
- cp = "Realloc block count";
- break;
- case 0x9:
- cp = "Power on hours";
- break;
- case 0xc:
- cp = "Power cycles";
- break;
- case 0xd:
- cp = "Ecc rate";
- break;
- case 0x20:
- cp = "Write amp";
- break;
- case 0xb1: /* 177 */
- cp = "Percent life remaining";
- break;
- case 0xb4: /* 180 */
- cp = "Unused reserved block count";
- break;
- case 0xb5: /* 181 */
- cp = "Program fail count";
- break;
- case 0xb6: /* 182 */
- cp = "Erase fail count";
- break;
- case 0xbe: /* 190 */
- cp = "Drive temperature warn";
- break;
- case 0xc2: /* 194 */
- cp = "Drive temperature";
- break;
- case 0xc3: /* 195 */
- cp = "Uncorrected error count";
- break;
- case 0xc6: /* 198 */
- cp = "Offline scan uncorrected sector count";
- break;
- case 0xe9: /* 233 */
- cp = "Number of writes";
- break;
- default:
- snprintf(bb, sizeof(bb), "parameter_code=0x%x (%d)",
- pc, pc);
- cp = bb;
- break;
- }
break;
} /* end of switch statement */
- if (cp && (param_len >= 24)) {
- if (! has_header) {
- has_header = true;
- printf(" Has|Ever %% to worst %% Current "
- "Worst Threshold Attribute\n");
- printf(" tripped fail to fail "
- "value value\n");
- }
- printf(" %2d %2d %4d %4d %10u %10u %10u %s",
- !!(0x80 & bp[4]), !!(0x40 & bp[4]), bp[5], bp[6],
- sg_get_unaligned_be32(bp + 8),
- sg_get_unaligned_be32(bp + 12),
- sg_get_unaligned_be32(bp + 16),
- cp);
- /* decoded = true; */
- } else if ((! decoded) && full) {
+ if ((! decoded) && full) {
printf(" parameter code = 0x%x, contents in hex:\n", pc);
hex2stdout(bp, param_len, 1);
- }
- printf("\n");
+ } else
+ printf("\n");
if (op->do_pcb)
printf(" <%s>\n", get_pcb_str(bp[2], str, sizeof(str)));
if (op->filter_given)
@@ -6589,7 +6633,8 @@ show_hgst_misc_page(const uint8_t * resp, int len, const struct opts_t * op)
char str[PCB_STR_LEN];
if (op->verbose || ((! op->do_raw) && (0 == op->do_hex)))
- printf("HGST/WDC miscellaneous page [0x37]\n");
+ printf("HGST/WDC miscellaneous page [0x37, 0x%x]\n",
+ op->decod_subpg_code);
num = len - 4;
if (num < 0x30) {
printf("HGST/WDC miscellaneous page too short (%d) < 48\n", num);
@@ -6705,7 +6750,7 @@ skip:
}
static void
-decode_page_contents(const uint8_t * resp, int len, const struct opts_t * op)
+decode_page_contents(const uint8_t * resp, int len, struct opts_t * op)
{
int pg_code, subpg_code, vpn;
bool spf;
@@ -6718,7 +6763,11 @@ decode_page_contents(const uint8_t * resp, int len, const struct opts_t * op)
}
spf = !!(resp[0] & 0x40);
pg_code = resp[0] & 0x3f;
- subpg_code = spf ? resp[1] : 0;
+ if ((VP_HITA == op->vend_prod_num) && (pg_code >= 0x30))
+ subpg_code = resp[1]; /* Hitachi don't set SPF on VS pages */
+ else
+ subpg_code = spf ? resp[1] : 0;
+ op->decod_subpg_code = subpg_code;
if ((SUPP_SPGS_SUBPG == subpg_code) && (SUPP_PAGES_LPAGE != pg_code)) {
done = show_supported_pgs_sub_page(resp, len, op);
if (done)
@@ -6729,8 +6778,8 @@ decode_page_contents(const uint8_t * resp, int len, const struct opts_t * op)
if (lep && lep->show_pagep)
done = (*lep->show_pagep)(resp, len, op);
- if (! done) {
- if (spf)
+ if (! done) {
+ if (subpg_code > 0)
printf("Unable to decode page = 0x%x, subpage = 0x%x, here is "
"hex:\n", pg_code, subpg_code);
else