*
* Home page of code is: http://smartmontools.sourceforge.net
*
- * Copyright (C) 2002-9 Bruce Allen <smartmontools-support@lists.sourceforge.net>
+ * Copyright (C) 2002-11 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
*
* Additional SCSI work:
- * Copyright (C) 2003-9 Douglas Gilbert <dougg@torque.net>
+ * Copyright (C) 2003-10 Douglas Gilbert <dgilbert@interlog.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include "config.h"
#include "int64.h"
-#include "extern.h"
#include "scsicmds.h"
#include "atacmds.h" // smart_command_set
#include "dev_interface.h"
#define GBUF_SIZE 65535
-const char * scsiprint_c_cvsid = "$Id: scsiprint.cpp 2861 2009-07-24 16:47:03Z chrfranke $"
+const char * scsiprint_c_cvsid = "$Id: scsiprint.cpp 3441 2011-10-12 17:22:15Z chrfranke $"
SCSIPRINT_H_CVSID;
-// control block which points to external global control variables
-extern smartmonctrl *con;
UINT8 gBuf[GBUF_SIZE];
#define LOG_RESP_LEN 252
static int gBackgroundResultsLPage = 0;
static int gProtocolSpecificLPage = 0;
static int gTapeAlertsLPage = 0;
+static int gSSMediaLPage = 0;
+
+/* Vendor specific log pages */
static int gSeagateCacheLPage = 0;
static int gSeagateFactoryLPage = 0;
/* Remember last successful mode sense/select command */
static int modese_len = 0;
-// Compares failure type to policy in effect, and either exits or
-// simply returns to the calling routine.
-extern void failuretest(int type, int returnvalue);
-
static void scsiGetSupportedLogPages(scsi_device * device)
{
int i, err;
if ((err = scsiLogSense(device, SUPPORTED_LPAGES, 0, gBuf,
LOG_RESP_LEN, 0))) {
- if (con->reportscsiioctl > 0)
+ if (scsi_debugmode > 0)
pout("Log Sense for supported pages failed [%s]\n",
scsiErrString(err));
return;
case TAPE_ALERTS_LPAGE:
gTapeAlertsLPage = 1;
break;
+ case SS_MEDIA_LPAGE:
+ gSSMediaLPage = 1;
+ break;
case SEAGATE_CACHE_LPAGE:
gSeagateCacheLPage = 1;
break;
const char * cp;
int err = 0;
- PRINT_ON(con);
+ print_on();
if (scsiCheckIE(device, gSmartLPage, gTempLPage, &asc, &ascq,
¤ttemp, &triptemp)) {
/* error message already announced */
- PRINT_OFF(con);
+ print_off();
return -1;
}
- PRINT_OFF(con);
+ print_off();
cp = scsiGetIEString(asc, ascq);
if (cp) {
err = -2;
- PRINT_ON(con);
+ print_on();
pout("SMART Health Status: %s [asc=%x, ascq=%x]\n", cp, asc, ascq);
- PRINT_OFF(con);
+ print_off();
} else if (gIecMPage)
pout("SMART Health Status: OK\n");
const char *ts;
int failures = 0;
- PRINT_ON(con);
+ print_on();
if ((err = scsiLogSense(device, TAPE_ALERTS_LPAGE, 0, gBuf,
LOG_RESP_TAPE_ALERT_LEN, LOG_RESP_TAPE_ALERT_LEN))) {
pout("scsiGetTapesAlertData Failed [%s]\n", scsiErrString(err));
- PRINT_OFF(con);
+ print_off();
return -1;
}
if (gBuf[0] != 0x2e) {
pout("TapeAlerts Log Sense Failed\n");
- PRINT_OFF(con);
+ print_off();
return -1;
}
pagelength = (unsigned short) gBuf[2] << 8 | gBuf[3];
}
}
}
- PRINT_OFF(con);
+ print_off();
if (! failures)
pout("TapeAlert: OK\n");
if ((err = scsiLogSense(device, STARTSTOP_CYCLE_COUNTER_LPAGE, 0, gBuf,
LOG_RESP_LEN, 0))) {
- PRINT_ON(con);
+ print_on();
pout("scsiGetStartStopData Failed [%s]\n", scsiErrString(err));
- PRINT_OFF(con);
+ print_off();
return;
}
if ((gBuf[0] & 0x3f) != STARTSTOP_CYCLE_COUNTER_LPAGE) {
- PRINT_ON(con);
+ print_on();
pout("StartStop Log Sense Failed, page mismatch\n");
- PRINT_OFF(con);
+ print_off();
return;
}
len = ((gBuf[2] << 8) | gBuf[3]);
ucp = gBuf + 4;
for (k = len; k > 0; k -= extra, ucp += extra) {
if (k < 3) {
- PRINT_ON(con);
+ print_on();
pout("StartStop Log Sense Failed: short\n");
- PRINT_OFF(con);
+ print_off();
return;
}
extra = ucp[3] + 4;
memset(gBuf, 0, 4);
if ((err = scsiReadDefect10(device, 0 /* req_plist */, 1 /* req_glist */,
4 /* bytes from index */, gBuf, 4))) {
- if (con->reportscsiioctl > 0) {
- PRINT_ON(con);
+ if (scsi_debugmode > 0) {
+ print_on();
pout("Read defect list (10) Failed: %s\n", scsiErrString(err));
- PRINT_OFF(con);
+ print_off();
}
return;
}
if (0x8 != (gBuf[1] & 0x18)) {
- PRINT_ON(con);
+ print_on();
pout("Read defect list: asked for grown list but didn't get it\n");
- PRINT_OFF(con);
+ print_off();
return;
}
div = 0;
div = 8;
break;
default:
- PRINT_ON(con);
+ print_on();
pout("defect list format %d unknown\n", dl_format);
- PRINT_OFF(con);
+ print_off();
break;
}
dl_len = (gBuf[2] << 8) + gBuf[3];
if ((err = scsiLogSense(device, SEAGATE_CACHE_LPAGE, 0, gBuf,
LOG_RESP_LEN, 0))) {
- PRINT_ON(con);
+ print_on();
pout("Seagate Cache Log Sense Failed: %s\n", scsiErrString(err));
- PRINT_OFF(con);
+ print_off();
return;
}
if ((gBuf[0] & 0x3f) != SEAGATE_CACHE_LPAGE) {
- PRINT_ON(con);
+ print_on();
pout("Seagate Cache Log Sense Failed, page mismatch\n");
- PRINT_OFF(con);
+ print_off();
return;
}
len = ((gBuf[2] << 8) | gBuf[3]) + 4;
case 0: case 1: case 2: case 3: case 4:
break;
default:
- if (con->reportscsiioctl > 0) {
- PRINT_ON(con);
+ if (scsi_debugmode > 0) {
+ print_on();
pout("Vendor (Seagate) cache lpage has unexpected parameter"
", skip\n");
- PRINT_OFF(con);
+ print_off();
}
return;
}
if ((err = scsiLogSense(device, SEAGATE_FACTORY_LPAGE, 0, gBuf,
LOG_RESP_LEN, 0))) {
- PRINT_ON(con);
+ print_on();
pout("scsiPrintSeagateFactoryLPage Failed [%s]\n", scsiErrString(err));
- PRINT_OFF(con);
+ print_off();
return;
}
if ((gBuf[0] & 0x3f) != SEAGATE_FACTORY_LPAGE) {
- PRINT_ON(con);
+ print_on();
pout("Seagate/Hitachi Factory Log Sense Failed, page mismatch\n");
- PRINT_OFF(con);
+ print_off();
return;
}
len = ((gBuf[2] << 8) | gBuf[3]) + 4;
ucp += pl;
}
if ((good < 2) || (bad > 4)) { /* heuristic */
- if (con->reportscsiioctl > 0) {
- PRINT_ON(con);
+ if (scsi_debugmode > 0) {
+ print_on();
pout("\nVendor (Seagate/Hitachi) factory lpage has too many "
"unexpected parameters, skip\n");
- PRINT_OFF(con);
+ print_off();
}
return;
}
good = 1;
break;
default:
- if (con->reportscsiioctl > 0) {
- PRINT_ON(con);
+ if (scsi_debugmode > 0) {
+ print_on();
pout("Vendor (Seagate/Hitachi) factory lpage: "
"unknown parameter code [0x%x]\n", pc);
- PRINT_OFF(con);
+ print_off();
}
break;
}
ull |= xp[j];
}
if (0 == pc)
- pout(" = %.2f\n", uint64_to_double(ull) / 60.0 );
+ pout(" = %.2f\n", ull / 60.0 );
else
pout(" = %"PRIu64"\n", ull);
}
struct scsiNonMediumError nme;
int found[3] = {0, 0, 0};
const char * pageNames[3] = {"read: ", "write: ", "verify: "};
- int k;
double processed_gb;
if (gReadECounterLPage && (0 == scsiLogSense(device,
VERIFY_ERROR_COUNTER_LPAGE, 0, gBuf, LOG_RESP_LEN, 0))) {
scsiDecodeErrCounterPage(gBuf, &errCounterArr[2]);
ecp = &errCounterArr[2];
- for (k = 0; k < 7; ++k) {
+ for (int k = 0; k < 7; ++k) {
if (ecp->gotPC[k] && ecp->counter[k]) {
found[2] = 1;
break;
"algorithm processed uncorrected\n");
pout(" fast | delayed rewrites corrected "
"invocations [10^9 bytes] errors\n");
- for (k = 0; k < 3; ++k) {
+ for (int k = 0; k < 3; ++k) {
if (! found[k])
continue;
ecp = &errCounterArr[k];
pout("%s%8"PRIu64" %8"PRIu64" %8"PRIu64" %8"PRIu64" %8"PRIu64,
pageNames[k], ecp->counter[0], ecp->counter[1],
ecp->counter[2], ecp->counter[3], ecp->counter[4]);
- processed_gb = uint64_to_double(ecp->counter[5]) / 1000000000.0;
+ processed_gb = ecp->counter[5] / 1000000000.0;
pout(" %12.3f %8"PRIu64"\n", processed_gb, ecp->counter[6]);
}
}
}
if (gLastNErrorLPage && (0 == scsiLogSense(device,
LAST_N_ERROR_LPAGE, 0, gBuf, LOG_RESP_LONG_LEN, 0))) {
- unsigned char * ucp;
- int num, k, pc, pl, truncated;
-
- num = (gBuf[2] << 8) + gBuf[3] + 4;
- truncated = (num > LOG_RESP_LONG_LEN) ? num : 0;
+ int num = (gBuf[2] << 8) + gBuf[3] + 4;
+ int truncated = (num > LOG_RESP_LONG_LEN) ? num : 0;
if (truncated)
num = LOG_RESP_LONG_LEN;
- ucp = gBuf + 4;
+ unsigned char * ucp = gBuf + 4;
num -= 4;
if (num < 4)
pout("\nNo error events logged\n");
else {
pout("\nLast n error events log page\n");
- for (k = num; k > 0; k -= pl, ucp += pl) {
+ for (int k = num, pl; k > 0; k -= pl, ucp += pl) {
if (k < 3) {
pout(" <<short Last n error events log page>>\n");
break;
}
pl = ucp[3] + 4;
- pc = (ucp[0] << 8) + ucp[1];
+ int pc = (ucp[0] << 8) + ucp[1];
if (pl > 4) {
if ((ucp[2] & 0x1) && (ucp[2] & 0x2)) {
pout(" Error event %d:\n", pc);
pout(" Error event %d:\n", pc);
pout(" %.*s\n", pl - 4, (const char *)(ucp + 4));
} else {
- if (con->reportscsiioctl > 0) {
+ if (scsi_debugmode > 0) {
pout(" Error event %d:\n", pc);
pout(" [data counter??]:\n");
dStrHex((const char *)ucp + 4, pl - 4, 1);
if ((err = scsiLogSense(device, SELFTEST_RESULTS_LPAGE, 0, gBuf,
LOG_RESP_SELF_TEST_LEN, 0))) {
- PRINT_ON(con);
+ print_on();
pout("scsiPrintSelfTest Failed [%s]\n", scsiErrString(err));
- PRINT_OFF(con);
+ print_off();
return FAILSMART;
}
if ((gBuf[0] & 0x3f) != SELFTEST_RESULTS_LPAGE) {
- PRINT_ON(con);
+ print_on();
pout("Self-test Log Sense Failed, page mismatch\n");
- PRINT_OFF(con);
+ print_off();
return FAILSMART;
}
// compute page length
num = (gBuf[2] << 8) + gBuf[3];
// Log sense page length 0x190 bytes
if (num != 0x190) {
- PRINT_ON(con);
+ print_on();
pout("Self-test Log Sense length is 0x%x not 0x190 bytes\n",num);
- PRINT_OFF(con);
+ print_off();
return FAILSMART;
}
// loop through the twenty possible entries
if ((err = scsiLogSense(device, BACKGROUND_RESULTS_LPAGE, 0, gBuf,
LOG_RESP_LONG_LEN, 0))) {
- PRINT_ON(con);
+ print_on();
pout("scsiPrintBackgroundResults Failed [%s]\n", scsiErrString(err));
- PRINT_OFF(con);
+ print_off();
return FAILSMART;
}
if ((gBuf[0] & 0x3f) != BACKGROUND_RESULTS_LPAGE) {
- PRINT_ON(con);
+ print_on();
pout("Background scan results Log Sense Failed, page mismatch\n");
- PRINT_OFF(con);
+ print_off();
return FAILSMART;
}
// compute page length
num = (gBuf[2] << 8) + gBuf[3] + 4;
if (num < 20) {
- PRINT_ON(con);
+ print_on();
pout("Background scan results Log Sense length is %d, no scan "
"status\n", num);
- PRINT_OFF(con);
+ print_off();
return FAILSMART;
}
truncated = (num > LOG_RESP_LONG_LEN) ? num : 0;
return retval;
}
+// See SCSI Block Commands - 3 (SBC-3) rev 27 (draft) section 6.3.6 .
+// Returns 0 if ok else FAIL* bitmask. Note can have a status entry
+// and up to 2048 events (although would hope to have less). May set
+// FAILLOG if serious errors detected (in the future).
+static int scsiPrintSSMedia(scsi_device * device)
+{
+ int num, err, pc, pl, truncated;
+ int retval = 0;
+ UINT8 * ucp;
+
+ if ((err = scsiLogSense(device, SS_MEDIA_LPAGE, 0, gBuf,
+ LOG_RESP_LONG_LEN, 0))) {
+ print_on();
+ pout("scsiPrintSSMedia Failed [%s]\n", scsiErrString(err));
+ print_off();
+ return FAILSMART;
+ }
+ if ((gBuf[0] & 0x3f) != SS_MEDIA_LPAGE) {
+ print_on();
+ pout("Solid state media Log Sense Failed, page mismatch\n");
+ print_off();
+ return FAILSMART;
+ }
+ // compute page length
+ num = (gBuf[2] << 8) + gBuf[3] + 4;
+ if (num < 12) {
+ print_on();
+ pout("Solid state media Log Sense length is %d, too short\n", num);
+ print_off();
+ return FAILSMART;
+ }
+ truncated = (num > LOG_RESP_LONG_LEN) ? num : 0;
+ if (truncated)
+ num = LOG_RESP_LONG_LEN;
+ ucp = gBuf + 4;
+ num -= 4;
+ while (num > 3) {
+ pc = (ucp[0] << 8) | ucp[1];
+ // pcb = ucp[2];
+ pl = ucp[3] + 4;
+ switch (pc) {
+ case 1:
+ if (pl < 8) {
+ print_on();
+ pout("Percentage used endurance indicator too short (pl=%d)\n", pl);
+ print_off();
+ return FAILSMART;
+ }
+ pout("SS Media used endurance indicator: %d%%\n", ucp[7]);
+ default: /* ignore other parameter codes */
+ break;
+ }
+ num -= pl;
+ ucp += pl;
+ }
+ return retval;
+}
static void show_sas_phy_event_info(int peis, unsigned int val,
unsigned thresh_val)
static void show_sas_port_param(unsigned char * ucp, int param_len)
{
- int j, m, n, nphys, pcb, t, sz, spld_len;
+ int j, m, n, nphys, t, sz, spld_len;
unsigned char * vcp;
uint64_t ull;
unsigned int ui;
char s[64];
sz = sizeof(s);
- pcb = ucp[2];
+ // pcb = ucp[2];
t = (ucp[0] << 8) | ucp[1];
pout("relative target port id = %d\n", t);
pout(" generation code = %d\n", ucp[6]);
if ((err = scsiLogSense(device, PROTOCOL_SPECIFIC_LPAGE, 0, gBuf,
LOG_RESP_LONG_LEN, 0))) {
- PRINT_ON(con);
+ print_on();
pout("scsiPrintSasPhy Log Sense Failed [%s]\n", scsiErrString(err));
- PRINT_OFF(con);
+ print_off();
return FAILSMART;
}
if ((gBuf[0] & 0x3f) != PROTOCOL_SPECIFIC_LPAGE) {
- PRINT_ON(con);
+ print_on();
pout("Protocol specific Log Sense Failed, page mismatch\n");
- PRINT_OFF(con);
+ print_off();
return FAILSMART;
}
// compute page length
num = (gBuf[2] << 8) + gBuf[3];
if (1 != show_protocol_specific_page(gBuf, num + 4)) {
- PRINT_ON(con);
+ print_on();
pout("Only support protocol specific log page on SAS devices\n");
- PRINT_OFF(con);
+ print_off();
return FAILSMART;
}
if (reset) {
if ((err = scsiLogSelect(device, 1 /* pcr */, 0 /* sp */, 0 /* pc */,
PROTOCOL_SPECIFIC_LPAGE, 0, NULL, 0))) {
- PRINT_ON(con);
+ print_on();
pout("scsiPrintSasPhy Log Select (reset) Failed [%s]\n",
scsiErrString(err));
- PRINT_OFF(con);
+ print_off();
return FAILSMART;
}
}
/* Returns 0 on success, 1 on general error and 2 for early, clean exit */
static int scsiGetDriveInfo(scsi_device * device, UINT8 * peripheral_type, bool all)
{
- char manufacturer[9];
- char product[17];
- char revision[5];
char timedatetz[DATEANDEPOCHLEN];
struct scsi_iec_mode_page iec;
- int err, iec_err, len, req_len, avail_len, val;
+ int err, iec_err, len, req_len, avail_len;
int is_tape = 0;
int peri_dt = 0;
- int returnval=0;
+ int returnval = 0;
+ int transport = -1;
memset(gBuf, 0, 96);
req_len = 36;
if ((err = scsiStdInquiry(device, gBuf, req_len))) {
- PRINT_ON(con);
+ print_on();
pout("Standard Inquiry (36 bytes) failed [%s]\n", scsiErrString(err));
pout("Retrying with a 64 byte Standard Inquiry\n");
- PRINT_OFF(con);
+ print_off();
/* Marvell controllers fail on a 36 bytes StdInquiry, but 64 suffices */
req_len = 64;
if ((err = scsiStdInquiry(device, gBuf, req_len))) {
- PRINT_ON(con);
+ print_on();
pout("Standard Inquiry (64 bytes) failed [%s]\n",
scsiErrString(err));
- PRINT_OFF(con);
+ print_off();
return 1;
}
}
*peripheral_type = peri_dt;
if (len < 36) {
- PRINT_ON(con);
+ print_on();
pout("Short INQUIRY response, skip product id\n");
- PRINT_OFF(con);
+ print_off();
return 1;
}
- memset(manufacturer, 0, sizeof(manufacturer));
- strncpy(manufacturer, (char *)&gBuf[8], 8);
-
- memset(product, 0, sizeof(product));
- strncpy(product, (char *)&gBuf[16], 16);
-
- memset(revision, 0, sizeof(revision));
- strncpy(revision, (char *)&gBuf[32], 4);
- if (all && (0 != strncmp(manufacturer, "ATA", 3)))
- pout("Device: %s %s Version: %s\n", manufacturer, product, revision);
+ if (all && (0 != strncmp((char *)&gBuf[8], "ATA", 3))) {
+ pout("Vendor: %.8s\n", (char *)&gBuf[8]);
+ pout("Product: %.16s\n", (char *)&gBuf[16]);
+ if (gBuf[32] >= ' ')
+ pout("Revision: %.4s\n", (char *)&gBuf[32]);
+ }
if (!*device->get_req_type()/*no type requested*/ &&
- (0 == strncmp(manufacturer, "ATA", 3))) {
+ (0 == strncmp((char *)&gBuf[8], "ATA", 3))) {
pout("\nProbable ATA device behind a SAT layer\n"
"Try an additional '-d ata' or '-d sat' argument.\n");
return 2;
if (! all)
return 0;
+ unsigned int lb_size;
+ char cap_str[64];
+ char si_str[64];
+ char lb_str[16];
+ uint64_t capacity = scsiGetSize(device, &lb_size);
+
+ if (capacity) {
+ format_with_thousands_sep(cap_str, sizeof(cap_str), capacity);
+ format_capacity(si_str, sizeof(si_str), capacity);
+ pout("User Capacity: %s bytes [%s]\n", cap_str, si_str);
+ snprintf(lb_str, sizeof(lb_str) - 1, "%u", lb_size);
+ pout("Logical block size: %s bytes\n", lb_str);
+ }
+
/* Do this here to try and detect badly conforming devices (some USB
keys) that will lock up on a InquiryVpd or log sense or ... */
if ((iec_err = scsiFetchIECmpage(device, &iec, modese_len))) {
if (SIMPLE_ERR_BAD_RESP == iec_err) {
pout(">> Terminate command early due to bad response to IEC "
"mode page\n");
- PRINT_OFF(con);
+ print_off();
gIecMPage = 0;
return 1;
}
} else
modese_len = iec.modese_len;
- if (!con->dont_print_serial) {
- if (0 == (err = scsiInquiryVpd(device, 0x80, gBuf, 64))) {
- /* should use VPD page 0x83 and fall back to this page (0x80)
- * if 0x83 not supported. NAA requires a lot of decoding code */
+ if (! dont_print_serial_number) {
+ if (0 == (err = scsiInquiryVpd(device, 0x83, gBuf, 200))) {
+ char s[256];
+
len = gBuf[3];
- gBuf[4 + len] = '\0';
- pout("Serial number: %s\n", &gBuf[4]);
+ scsi_decode_lu_dev_id(gBuf + 4, len, s, sizeof(s), &transport);
+ if (strlen(s) > 0)
+ pout("Logical Unit id: %s\n", s);
+ } else if (scsi_debugmode > 0) {
+ print_on();
+ if (SIMPLE_ERR_BAD_RESP == err)
+ pout("Vital Product Data (VPD) bit ignored in INQUIRY\n");
+ else
+ pout("Vital Product Data (VPD) INQUIRY failed [%d]\n", err);
+ print_off();
}
- else if (con->reportscsiioctl > 0) {
- PRINT_ON(con);
+ if (0 == (err = scsiInquiryVpd(device, 0x80, gBuf, 64))) {
+ len = gBuf[3];
+ gBuf[4 + len] = '\0';
+ pout("Serial number: %s\n", &gBuf[4]);
+ } else if (scsi_debugmode > 0) {
+ print_on();
if (SIMPLE_ERR_BAD_RESP == err)
pout("Vital Product Data (VPD) bit ignored in INQUIRY\n");
else
pout("Vital Product Data (VPD) INQUIRY failed [%d]\n", err);
- PRINT_OFF(con);
+ print_off();
}
}
// print SCSI peripheral device type
if (peri_dt < (int)(sizeof(peripheral_dt_arr) /
sizeof(peripheral_dt_arr[0])))
- pout("Device type: %s\n", peripheral_dt_arr[peri_dt]);
+ pout("Device type: %s\n", peripheral_dt_arr[peri_dt]);
else
- pout("Device type: <%d>\n", peri_dt);
+ pout("Device type: <%d>\n", peri_dt);
// See if transport protocol is known
- val = scsiFetchTransportProtocol(device, modese_len);
- if ((val >= 0) && (val <= 0xf))
- pout("Transport protocol: %s\n", transport_proto_arr[val]);
+ if (transport < 0)
+ transport = scsiFetchTransportProtocol(device, modese_len);
+ if ((transport >= 0) && (transport <= 0xf))
+ pout("Transport protocol: %s\n", transport_proto_arr[transport]);
// print current time and date and timezone
dateandtimezone(timedatetz);
- pout("Local Time is: %s\n", timedatetz);
+ pout("Local Time is: %s\n", timedatetz);
if ((SCSI_PT_SEQUENTIAL_ACCESS == *peripheral_type) ||
(SCSI_PT_MEDIUM_CHANGER == *peripheral_type))
// See if unit accepts SCSI commmands from us
if ((err = scsiTestUnitReady(device))) {
if (SIMPLE_ERR_NOT_READY == err) {
- PRINT_ON(con);
+ print_on();
if (!is_tape)
pout("device is NOT READY (e.g. spun down, busy)\n");
else
pout("device is NOT READY (e.g. no tape)\n");
- PRINT_OFF(con);
+ print_off();
} else if (SIMPLE_ERR_NO_MEDIUM == err) {
- PRINT_ON(con);
+ print_on();
pout("NO MEDIUM present on device\n");
- PRINT_OFF(con);
+ print_off();
} else if (SIMPLE_ERR_BECOMING_READY == err) {
- PRINT_ON(con);
+ print_on();
pout("device becoming ready (wait)\n");
- PRINT_OFF(con);
+ print_off();
} else {
- PRINT_ON(con);
+ print_on();
pout("device Test Unit Ready [%s]\n", scsiErrString(err));
- PRINT_OFF(con);
+ print_off();
}
failuretest(MANDATORY_CMD, returnval|=FAILID);
}
if (iec_err) {
if (!is_tape) {
- PRINT_ON(con);
+ print_on();
pout("Device does not support SMART");
- if (con->reportscsiioctl > 0)
+ if (scsi_debugmode > 0)
pout(" [%s]\n", scsiErrString(iec_err));
else
pout("\n");
- PRINT_OFF(con);
+ print_off();
}
gIecMPage = 0;
return 0;
int err;
if ((err = scsiFetchIECmpage(device, &iec, modese_len))) {
- PRINT_ON(con);
+ print_on();
pout("unable to fetch IEC (SMART) mode page [%s]\n",
scsiErrString(err));
- PRINT_OFF(con);
+ print_off();
return 1;
} else
modese_len = iec.modese_len;
if ((err = scsiSetExceptionControlAndWarning(device, 1, &iec))) {
- PRINT_ON(con);
+ print_on();
pout("unable to enable Exception control and warning [%s]\n",
scsiErrString(err));
- PRINT_OFF(con);
+ print_off();
return 1;
}
/* Need to refetch 'iec' since could be modified by previous call */
int err;
if ((err = scsiFetchIECmpage(device, &iec, modese_len))) {
- PRINT_ON(con);
+ print_on();
pout("unable to fetch IEC (SMART) mode page [%s]\n",
scsiErrString(err));
- PRINT_OFF(con);
+ print_off();
return 1;
} else
modese_len = iec.modese_len;
if ((err = scsiSetExceptionControlAndWarning(device, 0, &iec))) {
- PRINT_ON(con);
+ print_on();
pout("unable to disable Exception control and warning [%s]\n",
scsiErrString(err));
- PRINT_OFF(con);
+ print_off();
return 1;
}
/* Need to refetch 'iec' since could be modified by previous call */
int returnval = 0;
int res, durationSec;
+ bool any_output = options.drive_info;
+
res = scsiGetDriveInfo(device, &peripheral_type, options.drive_info);
if (res) {
if (2 == res)
return 0;
else
failuretest(MANDATORY_CMD, returnval |= FAILID);
+ any_output = true;
}
if (options.smart_enable) {
if (scsiSmartEnable(device))
failuretest(MANDATORY_CMD, returnval |= FAILSMART);
+ any_output = true;
}
if (options.smart_disable) {
if (scsiSmartDisable(device))
failuretest(MANDATORY_CMD,returnval |= FAILSMART);
+ any_output = true;
}
if (options.smart_auto_save_enable) {
pout("Enable autosave (clear GLTSD bit) failed\n");
failuretest(OPTIONAL_CMD,returnval |= FAILSMART);
}
+ any_output = true;
}
if (options.smart_auto_save_disable) {
pout("Disable autosave (set GLTSD bit) failed\n");
failuretest(OPTIONAL_CMD,returnval |= FAILSMART);
}
+ any_output = true;
}
if (options.smart_check_status) {
returnval |= FAILSMART;
}
}
+ any_output = true;
}
+ if (options.smart_ss_media_log) {
+ if (! checkedSupportedLogPages)
+ scsiGetSupportedLogPages(device);
+ res = 0;
+ if (gSSMediaLPage)
+ res = scsiPrintSSMedia(device);
+ if (0 != res)
+ failuretest(OPTIONAL_CMD, returnval|=res);
+ any_output = true;
+ }
if (options.smart_vendor_attrib) {
if (! checkedSupportedLogPages)
scsiGetSupportedLogPages(device);
if (gSeagateFactoryLPage)
scsiPrintSeagateFactoryLPage(device);
}
+ any_output = true;
}
if (options.smart_error_log) {
if (! checkedSupportedLogPages)
if (1 == scsiFetchControlGLTSD(device, modese_len, 1))
pout("\n[GLTSD (Global Logging Target Save Disable) set. "
"Enable Save with '-S on']\n");
+ any_output = true;
}
if (options.smart_selftest_log) {
if (! checkedSupportedLogPages)
}
if (0 != res)
failuretest(OPTIONAL_CMD, returnval|=res);
+ any_output = true;
}
if (options.smart_background_log) {
if (! checkedSupportedLogPages)
}
if (0 != res)
failuretest(OPTIONAL_CMD, returnval|=res);
+ any_output = true;
}
if (options.smart_default_selftest) {
if (scsiSmartDefaultSelfTest(device))
return returnval | FAILSMART;
pout("Default Self Test Successful\n");
+ any_output = true;
}
if (options.smart_short_cap_selftest) {
if (scsiSmartShortCapSelfTest(device))
return returnval | FAILSMART;
pout("Short Foreground Self Test Successful\n");
+ any_output = true;
}
if (options.smart_short_selftest) {
if (scsiSmartShortSelfTest(device))
return returnval | FAILSMART;
pout("Short Background Self Test has begun\n");
pout("Use smartctl -X to abort test\n");
+ any_output = true;
}
if (options.smart_extend_selftest) {
if (scsiSmartExtendSelfTest(device))
pout("Estimated completion time: %s\n", ctime(&t));
}
pout("Use smartctl -X to abort test\n");
+ any_output = true;
}
if (options.smart_extend_cap_selftest) {
if (scsiSmartExtendCapSelfTest(device))
if (scsiSmartSelfTestAbort(device))
return returnval | FAILSMART;
pout("Self Test returned without error\n");
+ any_output = true;
}
if (options.sasphy) {
if (scsiPrintSasPhy(device, options.sasphy_reset))
return returnval | FAILSMART;
+ any_output = true;
}
+
+ if (!any_output)
+ pout("SCSI device successfully opened\n\n"
+ "Use 'smartctl -a' (or '-x') to print SMART (and more) information\n\n");
+
return returnval;
}