⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ataprint.cpp

📁 硬盘各项性能的测试,如温度容量版本健康度型号
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/* * ataprint.cpp * * Home page of code is: http://smartmontools.sourceforge.net * * Copyright (C) 2002-8 Bruce Allen <smartmontools-support@lists.sourceforge.net> * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org> * * 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 "config.h"#include <ctype.h>#include <errno.h>#include <stdio.h>#include <string.h>#ifdef HAVE_LOCALE_H#include <locale.h>#endif // #ifdef HAVE_LOCALE_H#include "int64.h"#include "atacmdnames.h"#include "atacmds.h"#include "ataprint.h"#include "smartctl.h"#include "extern.h"#include "utility.h"#include "knowndrives.h"const char *ataprint_c_cvsid="$Id: ataprint.cpp,v 1.185 2008/03/04 22:09:47 ballen4705 Exp $"ATACMDNAMES_H_CVSID ATACMDS_H_CVSID ATAPRINT_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID KNOWNDRIVES_H_CVSID SMARTCTL_H_CVSID UTILITY_H_CVSID;// for passing global control variablesextern smartmonctrl *con;// to hold onto exit code for atexit routineextern int exitstatus;// Copies n bytes (or n-1 if n is odd) from in to out, but swaps adjacents// bytes.void swapbytes(char *out, const char *in, size_t n){  size_t i;  for (i = 0; i < n; i += 2) {    out[i]   = in[i+1];    out[i+1] = in[i];  }}// Copies in to out, but removes leading and trailing whitespace.void trim(char *out, const char *in){  int i, first, last;  // Find the first non-space character (maybe none).  first = -1;  for (i = 0; in[i]; i++)    if (!isspace((int)in[i])) {      first = i;      break;    }  if (first == -1) {    // There are no non-space characters.    out[0] = '\0';    return;  }  // Find the last non-space character.  for (i = strlen(in)-1; i >= first && isspace((int)in[i]); i--)    ;  last = i;  strncpy(out, in+first, last-first+1);  out[last-first+1] = '\0';}// Convenience function for formatting strings from ata_identify_devicevoid format_ata_string(char *out, const char *in, int n){  bool must_swap = !con->fixswappedid;#ifdef __NetBSD__  /* NetBSD kernel delivers IDENTIFY data in host byte order (but all else is LE) */  if (isbigendian())    must_swap = !must_swap;#endif  char tmp[65];  n = n > 64 ? 64 : n;  if (!must_swap)    strncpy(tmp, in, n);  else    swapbytes(tmp, in, n);  tmp[n] = '\0';  trim(out, tmp);}static const char * infofound(const char *output) {  return (*output ? output : "[No Information Found]");}/* For the given Command Register (CR) and Features Register (FR), attempts * to construct a string that describes the contents of the Status * Register (ST) and Error Register (ER).  The string is dynamically allocated * memory and the return value is a pointer to this string.  It is up to the * caller to free this memory.  If there is insufficient memory or if the * meanings of the flags of the error register are not known for the given * command then it returns NULL. * * The meanings of the flags of the error register for all commands are * described in the ATA spec and could all be supported here in theory. * Currently, only a few commands are supported (those that have been seen * to produce errors).  If many more are to be added then this function * should probably be redesigned. */char *construct_st_er_desc(struct ata_smart_errorlog_struct *data) {  unsigned char CR=data->commands[4].commandreg;  unsigned char FR=data->commands[4].featuresreg;  unsigned char ST=data->error_struct.status;  unsigned char ER=data->error_struct.error_register;  char *s;  const char *error_flag[8];  int i, print_lba=0, print_sector=0;  // Set of character strings corresponding to different error codes.  // Please keep in alphabetic order if you add more.  const char  *abrt  = "ABRT";  // ABORTED const char   *amnf  = "AMNF";  // ADDRESS MARK NOT FOUND const char   *ccto  = "CCTO";  // COMMAND COMPLETION TIMED OUT const char   *eom   = "EOM";   // END OF MEDIA const char   *icrc  = "ICRC";  // INTERFACE CRC ERROR const char   *idnf  = "IDNF";  // ID NOT FOUND const char   *ili   = "ILI";   // MEANING OF THIS BIT IS COMMAND-SET SPECIFIC const char   *mc    = "MC";    // MEDIA CHANGED  const char   *mcr   = "MCR";   // MEDIA CHANGE REQUEST const char   *nm    = "NM";    // NO MEDIA const char   *obs   = "obs";   // OBSOLETE const char   *tk0nf = "TK0NF"; // TRACK 0 NOT FOUND const char   *unc   = "UNC";   // UNCORRECTABLE const char   *wp    = "WP";    // WRITE PROTECTED  /* If for any command the Device Fault flag of the status register is   * not used then used_device_fault should be set to 0 (in the CR switch   * below)   */  int uses_device_fault = 1;  /* A value of NULL means that the error flag isn't used */  for (i = 0; i < 8; i++)    error_flag[i] = NULL;  switch (CR) {  case 0x10:  // RECALIBRATE    error_flag[2] = abrt;    error_flag[1] = tk0nf;    break;  case 0x20:  /* READ SECTOR(S) */  case 0x21:  // READ SECTOR(S)  case 0x24:  // READ SECTOR(S) EXT  case 0xC4:  /* READ MULTIPLE */  case 0x29:  // READ MULTIPLE EXT    error_flag[6] = unc;    error_flag[5] = mc;    error_flag[4] = idnf;    error_flag[3] = mcr;    error_flag[2] = abrt;    error_flag[1] = nm;    error_flag[0] = amnf;    print_lba=1;    break;  case 0x22:  // READ LONG (with retries)  case 0x23:  // READ LONG (without retries)    error_flag[4] = idnf;    error_flag[2] = abrt;    error_flag[0] = amnf;    print_lba=1;    break;  case 0x2a:  // READ STREAM DMA  case 0x2b:  // READ STREAM PIO    if (CR==0x2a)      error_flag[7] = icrc;    error_flag[6] = unc;    error_flag[5] = mc;    error_flag[4] = idnf;    error_flag[3] = mcr;    error_flag[2] = abrt;    error_flag[1] = nm;    error_flag[0] = ccto;    print_lba=1;    print_sector=(int)data->error_struct.sector_count;    break;  case 0x3A:  // WRITE STREAM DMA  case 0x3B:  // WRITE STREAM PIO    if (CR==0x3A)      error_flag[7] = icrc;    error_flag[6] = wp;    error_flag[5] = mc;    error_flag[4] = idnf;    error_flag[3] = mcr;    error_flag[2] = abrt;    error_flag[1] = nm;    error_flag[0] = ccto;    print_lba=1;    print_sector=(int)data->error_struct.sector_count;    break;  case 0x25:  /* READ DMA EXT */  case 0x26:  // READ DMA QUEUED EXT  case 0xC7:  // READ DMA QUEUED  case 0xC8:  /* READ DMA */  case 0xC9:    error_flag[7] = icrc;    error_flag[6] = unc;    error_flag[5] = mc;    error_flag[4] = idnf;    error_flag[3] = mcr;    error_flag[2] = abrt;    error_flag[1] = nm;    error_flag[0] = amnf;    print_lba=1;    if (CR==0x25 || CR==0xC8)      print_sector=(int)data->error_struct.sector_count;    break;  case 0x30:  /* WRITE SECTOR(S) */  case 0x31:  // WRITE SECTOR(S)  case 0x34:  // WRITE SECTOR(S) EXT  case 0xC5:  /* WRITE MULTIPLE */  case 0x39:  // WRITE MULTIPLE EXT  case 0xCE:  // WRITE MULTIPLE FUA EXT    error_flag[6] = wp;    error_flag[5] = mc;    error_flag[4] = idnf;    error_flag[3] = mcr;    error_flag[2] = abrt;    error_flag[1] = nm;    print_lba=1;    break;  case 0x32:  // WRITE LONG (with retries)  case 0x33:  // WRITE LONG (without retries)    error_flag[4] = idnf;    error_flag[2] = abrt;    print_lba=1;    break;  case 0x3C:  // WRITE VERIFY    error_flag[6] = unc;    error_flag[4] = idnf;    error_flag[2] = abrt;    error_flag[0] = amnf;    print_lba=1;    break;  case 0x40: // READ VERIFY SECTOR(S) with retries  case 0x41: // READ VERIFY SECTOR(S) without retries  case 0x42: // READ VERIFY SECTOR(S) EXT    error_flag[6] = unc;    error_flag[5] = mc;    error_flag[4] = idnf;    error_flag[3] = mcr;    error_flag[2] = abrt;    error_flag[1] = nm;    error_flag[0] = amnf;    print_lba=1;    break;  case 0xA0:  /* PACKET */    /* Bits 4-7 are all used for sense key (a 'command packet set specific error     * indication' according to the ATA/ATAPI-7 standard), so "Sense key" will     * be repeated in the error description string if more than one of those     * bits is set.     */    error_flag[7] = "Sense key (bit 3)",    error_flag[6] = "Sense key (bit 2)",    error_flag[5] = "Sense key (bit 1)",    error_flag[4] = "Sense key (bit 0)",    error_flag[2] = abrt;    error_flag[1] = eom;    error_flag[0] = ili;    break;  case 0xA1:  /* IDENTIFY PACKET DEVICE */  case 0xEF:  /* SET FEATURES */  case 0x00:  /* NOP */  case 0xC6:  /* SET MULTIPLE MODE */    error_flag[2] = abrt;    break;  case 0x2F:  // READ LOG EXT    error_flag[6] = unc;    error_flag[4] = idnf;    error_flag[2] = abrt;    error_flag[0] = obs;    break;  case 0x3F:  // WRITE LOG EXT    error_flag[4] = idnf;    error_flag[2] = abrt;    error_flag[0] = obs;    break;  case 0xB0:  /* SMART */    switch(FR) {    case 0xD0:  // SMART READ DATA    case 0xD1:  // SMART READ ATTRIBUTE THRESHOLDS    case 0xD5:  /* SMART READ LOG */      error_flag[6] = unc;      error_flag[4] = idnf;      error_flag[2] = abrt;      error_flag[0] = obs;      break;    case 0xD6:  /* SMART WRITE LOG */      error_flag[4] = idnf;      error_flag[2] = abrt;      error_flag[0] = obs;      break;    case 0xD2:  // Enable/Disable Attribute Autosave    case 0xD3:  // SMART SAVE ATTRIBUTE VALUES (ATA-3)    case 0xD8:  // SMART ENABLE OPERATIONS    case 0xD9:  /* SMART DISABLE OPERATIONS */    case 0xDA:  /* SMART RETURN STATUS */    case 0xDB:  // Enable/Disable Auto Offline (SFF)      error_flag[2] = abrt;      break;    case 0xD4:  // SMART EXECUTE IMMEDIATE OFFLINE      error_flag[4] = idnf;      error_flag[2] = abrt;      break;    default:      return NULL;      break;    }    break;  case 0xB1:  /* DEVICE CONFIGURATION */    switch (FR) {    case 0xC0:  /* DEVICE CONFIGURATION RESTORE */      error_flag[2] = abrt;      break;    default:      return NULL;      break;    }    break;  case 0xCA:  /* WRITE DMA */  case 0xCB:  case 0x35:  // WRITE DMA EXT  case 0x3D:  // WRITE DMA FUA EXT  case 0xCC:  // WRITE DMA QUEUED  case 0x36:  // WRITE DMA QUEUED EXT  case 0x3E:  // WRITE DMA QUEUED FUA EXT    error_flag[7] = icrc;    error_flag[6] = wp;    error_flag[5] = mc;    error_flag[4] = idnf;    error_flag[3] = mcr;    error_flag[2] = abrt;    error_flag[1] = nm;    error_flag[0] = amnf;    print_lba=1;    if (CR==0x35)      print_sector=(int)data->error_struct.sector_count;    break;  case 0xE4: // READ BUFFER  case 0xE8: // WRITE BUFFER    error_flag[2] = abrt;    break;  default:    return NULL;  }  /* 256 bytes -- that'll be plenty (OK, this is lazy!) */  if (!(s = (char *)malloc(256)))    return s;  s[0] = '\0';  /* We ignore any status flags other than Device Fault and Error */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -