📄 scsiprint.cpp
字号:
/* * scsiprint.cpp * * Home page of code is: http://smartmontools.sourceforge.net * * Copyright (C) 2002-8 Bruce Allen <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org> * * Additional SCSI work: * Copyright (C) 2003-8 Douglas Gilbert <dougg@torque.net> * * 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 * the Free Software Foundation; either version 2, or (at your option) * any later version. * * You should have received a copy of the GNU General Public License * (for example COPYING); if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * This code was originally developed as a Senior Thesis by Michael Cornwell * at the Concurrent Systems Laboratory (now part of the Storage Systems * Research Center), Jack Baskin School of Engineering, University of * California, Santa Cruz. http://ssrc.soe.ucsc.edu/ * */#include <stdio.h>#include <string.h>#include <fcntl.h>#include <errno.h>#include "config.h"#include "int64.h"#include "extern.h"#include "scsicmds.h"#include "scsiprint.h"#include "smartctl.h"#include "utility.h"#include "scsiata.h"#define GBUF_SIZE 65535const char* scsiprint_c_cvsid="$Id: scsiprint.cpp,v 1.121 2008/03/04 22:09:47 ballen4705 Exp $"CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID SCSICMDS_H_CVSID SCSIPRINT_H_CVSID SMARTCTL_H_CVSID UTILITY_H_CVSID;// control block which points to external global control variablesextern smartmonctrl *con;// to hold onto exit code for atexit routineextern int exitstatus;UINT8 gBuf[GBUF_SIZE];#define LOG_RESP_LEN 252#define LOG_RESP_LONG_LEN 16384#define LOG_RESP_TAPE_ALERT_LEN 0x144/* Log pages supported */static int gSmartLPage = 0; /* Informational Exceptions log page */static int gTempLPage = 0;static int gSelfTestLPage = 0;static int gStartStopLPage = 0;static int gReadECounterLPage = 0;static int gWriteECounterLPage = 0;static int gVerifyECounterLPage = 0;static int gNonMediumELPage = 0;static int gLastNErrorLPage = 0;static int gBackgroundResultsLPage = 0;static int gTapeAlertsLPage = 0;static int gSeagateCacheLPage = 0;static int gSeagateFactoryLPage = 0;/* Mode pages supported */static int gIecMPage = 1; /* N.B. assume it until we know otherwise *//* 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(int device){ int i, err; if ((err = scsiLogSense(device, SUPPORTED_LPAGES, 0, gBuf, LOG_RESP_LEN, 0))) { if (con->reportscsiioctl > 0) pout("Log Sense for supported pages failed [%s]\n", scsiErrString(err)); return; } for (i = 4; i < gBuf[3] + LOGPAGEHDRSIZE; i++) { switch (gBuf[i]) { case READ_ERROR_COUNTER_LPAGE: gReadECounterLPage = 1; break; case WRITE_ERROR_COUNTER_LPAGE: gWriteECounterLPage = 1; break; case VERIFY_ERROR_COUNTER_LPAGE: gVerifyECounterLPage = 1; break; case LAST_N_ERROR_LPAGE: gLastNErrorLPage = 1; break; case NON_MEDIUM_ERROR_LPAGE: gNonMediumELPage = 1; break; case TEMPERATURE_LPAGE: gTempLPage = 1; break; case STARTSTOP_CYCLE_COUNTER_LPAGE: gStartStopLPage = 1; break; case SELFTEST_RESULTS_LPAGE: gSelfTestLPage = 1; break; case IE_LPAGE: gSmartLPage = 1; break; case BACKGROUND_RESULTS_LPAGE: gBackgroundResultsLPage = 1; break; case TAPE_ALERTS_LPAGE: gTapeAlertsLPage = 1; break; case SEAGATE_CACHE_LPAGE: gSeagateCacheLPage = 1; break; case SEAGATE_FACTORY_LPAGE: gSeagateFactoryLPage = 1; break; default: break; } }}/* Returns 0 if ok, -1 if can't check IE, -2 if can check and bad (or at least something to report). */static int scsiGetSmartData(int device, int attribs){ UINT8 asc; UINT8 ascq; UINT8 currenttemp = 0; UINT8 triptemp = 0; const char * cp; int err = 0; PRINT_ON(con); if (scsiCheckIE(device, gSmartLPage, gTempLPage, &asc, &ascq, ¤ttemp, &triptemp)) { /* error message already announced */ PRINT_OFF(con); return -1; } PRINT_OFF(con); cp = scsiGetIEString(asc, ascq); if (cp) { err = -2; PRINT_ON(con); pout("SMART Health Status: %s [asc=%x, ascq=%x]\n", cp, asc, ascq); PRINT_OFF(con); } else if (gIecMPage) pout("SMART Health Status: OK\n"); if (attribs && !gTempLPage) { if (currenttemp || triptemp) pout("\n"); if (currenttemp) { if (255 != currenttemp) pout("Current Drive Temperature: %d C\n", currenttemp); else pout("Current Drive Temperature: <not available>\n"); } if (triptemp) pout("Drive Trip Temperature: %d C\n", triptemp); } return err;}// Returns number of logged errors or zero if none or -1 if fetching// TapeAlerts failsstatic char *severities = "CWI";static int scsiGetTapeAlertsData(int device, int peripheral_type){ unsigned short pagelength; unsigned short parametercode; int i, err; char *s; const char *ts; int failures = 0; PRINT_ON(con); 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); return -1; } if (gBuf[0] != 0x2e) { pout("TapeAlerts Log Sense Failed\n"); PRINT_OFF(con); return -1; } pagelength = (unsigned short) gBuf[2] << 8 | gBuf[3]; for (s=severities; *s; s++) { for (i = 4; i < pagelength; i += 5) { parametercode = (unsigned short) gBuf[i] << 8 | gBuf[i+1]; if (gBuf[i + 4]) { ts = SCSI_PT_MEDIUM_CHANGER == peripheral_type ? scsiTapeAlertsChangerDevice(parametercode) : scsiTapeAlertsTapeDevice(parametercode); if (*ts == *s) { if (!failures) pout("TapeAlert Errors (C=Critical, W=Warning, I=Informational):\n"); pout("[0x%02x] %s\n", parametercode, ts); failures += 1; } } } } PRINT_OFF(con); if (! failures) pout("TapeAlert: OK\n"); return failures;}static void scsiGetStartStopData(int device){ UINT32 u; int err, len, k, extra, pc; unsigned char * ucp; if ((err = scsiLogSense(device, STARTSTOP_CYCLE_COUNTER_LPAGE, 0, gBuf, LOG_RESP_LEN, 0))) { PRINT_ON(con); pout("scsiGetStartStopData Failed [%s]\n", scsiErrString(err)); PRINT_OFF(con); return; } if ((gBuf[0] & 0x3f) != STARTSTOP_CYCLE_COUNTER_LPAGE) { PRINT_ON(con); pout("StartStop Log Sense Failed, page mismatch\n"); PRINT_OFF(con); 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); pout("StartStop Log Sense Failed: short\n"); PRINT_OFF(con); return; } extra = ucp[3] + 4; pc = (ucp[0] << 8) + ucp[1]; switch (pc) { case 1: if (10 == extra) pout("Manufactured in week %.2s of year %.4s\n", ucp + 8, ucp + 4); break; case 2: /* ignore Accounting date */ break; case 3: if (extra > 7) { u = (ucp[4] << 24) | (ucp[5] << 16) | (ucp[6] << 8) | ucp[7]; if (0xffffffff != u) pout("Recommended maximum start stop count: %u times\n", u); } break; case 4: if (extra > 7) { u = (ucp[4] << 24) | (ucp[5] << 16) | (ucp[6] << 8) | ucp[7]; if (0xffffffff != u) pout("Current start stop count: %u times\n", u); } break; default: /* ignore */ break; } }} static void scsiPrintGrownDefectListLen(int device){ int err, dl_format, dl_len, div; 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); pout("Read defect list (10) Failed: %s\n", scsiErrString(err)); PRINT_OFF(con); } return; } if (0x8 != (gBuf[1] & 0x18)) { PRINT_ON(con); pout("Read defect list: asked for grown list but didn't get it\n"); PRINT_OFF(con); return; } div = 0; dl_format = (gBuf[1] & 0x7); switch (dl_format) { case 0: /* short block */ div = 4; break; case 3: /* long block */ case 4: /* bytes from index */ case 5: /* physical sector */ div = 8; break; default: PRINT_ON(con); pout("defect list format %d unknown\n", dl_format); PRINT_OFF(con); break; } dl_len = (gBuf[2] << 8) + gBuf[3]; if (0 == dl_len) pout("Elements in grown defect list: 0\n"); else { if (0 == div) pout("Grown defect list length=%d bytes [unknown " "number of elements]\n", dl_len); else pout("Elements in grown defect list: %d\n", dl_len / div); }}static void scsiPrintSeagateCacheLPage(int device){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -