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

📄 atacmds.cpp

📁 硬盘各项性能的测试,如温度容量版本健康度型号
💻 CPP
📖 第 1 页 / 共 5 页
字号:
}// returns 1 if SMART enabled, 0 if SMART disabled, -1 if can't tellint ataIsSmartEnabled(struct ata_identify_device *drive){  unsigned short word85=drive->cfs_enable_1;  unsigned short word87=drive->csf_default;    // check if words 85/86/87 contain valid info  if ((word87>>14) == 0x01)    // return value of SMART enabled bit    return word85 & 0x0001;    // Since we can't rely word85, we don't know if SMART is enabled.  return -1;}// Reads SMART attributes into *dataint ataReadSmartValues(int device, struct ata_smart_values *data){          if (smartcommandhandler(device, READ_VALUES, 0, (char *)data)){    syserror("Error SMART Values Read failed");    return -1;  }  // compute checksum  if (checksum((unsigned char *)data))    checksumwarning("SMART Attribute Data Structure");    // swap endian order if needed  if (isbigendian()){    int i;    swap2((char *)&(data->revnumber));    swap2((char *)&(data->total_time_to_complete_off_line));    swap2((char *)&(data->smart_capability));    for (i=0; i<NUMBER_ATA_SMART_ATTRIBUTES; i++){      struct ata_smart_attribute *x=data->vendor_attributes+i;      swap2((char *)&(x->flags));    }  }  return 0;}// This corrects some quantities that are byte reversed in the SMART// SELF TEST LOGvoid fixsamsungselftestlog(struct ata_smart_selftestlog *data){  int i;    // bytes 508/509 (numbered from 0) swapped (swap of self-test index  // with one byte of reserved.  swap2((char *)&(data->mostrecenttest));  // LBA low register (here called 'selftestnumber", containing  // information about the TYPE of the self-test) is byte swapped with  // Self-test execution status byte.  These are bytes N, N+1 in the  // entries.  for (i=0; i<21; i++)    swap2((char *)&(data->selftest_struct[i].selftestnumber));  return;}// Reads the Self Test Log (log #6)int ataReadSelfTestLog (int device, struct ata_smart_selftestlog *data){  // get data from device  if (smartcommandhandler(device, READ_LOG, 0x06, (char *)data)){    syserror("Error SMART Error Self-Test Log Read failed");    return -1;  }  // compute its checksum, and issue a warning if needed  if (checksum((unsigned char *)data))    checksumwarning("SMART Self-Test Log Structure");    // fix firmware bugs in self-test log  if (con->fixfirmwarebug == FIX_SAMSUNG)    fixsamsungselftestlog(data);  // swap endian order if needed  if (isbigendian()){    int i;    swap2((char*)&(data->revnumber));    for (i=0; i<21; i++){      struct ata_smart_selftestlog_struct *x=data->selftest_struct+i;      swap2((char *)&(x->timestamp));      swap4((char *)&(x->lbafirstfailure));    }  }  return 0;}// Reads the Log Directory (log #0).  Note: NO CHECKSUM!!int ataReadLogDirectory (int device, struct ata_smart_log_directory *data){         // get data from device  if (smartcommandhandler(device, READ_LOG, 0x00, (char *)data)){    return -1;  }  // swap endian order if needed  if (isbigendian()){    swap2((char *)&(data->logversion));  }    return 0;}// Reads the selective self-test log (log #9)int ataReadSelectiveSelfTestLog(int device, struct ata_selective_self_test_log *data){      // get data from device  if (smartcommandhandler(device, READ_LOG, 0x09, (char *)data)){    syserror("Error SMART Read Selective Self-Test Log failed");    return -1;  }     // compute its checksum, and issue a warning if needed  if (checksum((unsigned char *)data))    checksumwarning("SMART Selective Self-Test Log Structure");    // swap endian order if needed  if (isbigendian()){    int i;    swap2((char *)&(data->logversion));    for (i=0;i<5;i++){      swap8((char *)&(data->span[i].start));      swap8((char *)&(data->span[i].end));    }    swap8((char *)&(data->currentlba));    swap2((char *)&(data->currentspan));    swap2((char *)&(data->flags));    swap2((char *)&(data->pendingtime));  }    if (data->logversion != 1)    pout("SMART Selective Self-Test Log Data Structure Revision Number (%d) should be 1\n", data->logversion);    return 0;}// Writes the selective self-test log (log #9)int ataWriteSelectiveSelfTestLog(int device, struct ata_smart_values *sv, uint64_t num_sectors){     // Disk size must be known  if (!num_sectors) {    pout("Disk size is unknown, unable to check selective self-test spans\n");    return -1;  }  // Read log  struct ata_selective_self_test_log sstlog, *data=&sstlog;  unsigned char *ptr=(unsigned char *)data;  if (ataReadSelectiveSelfTestLog(device, data)) {    pout("Since Read failed, will not attempt to WRITE Selective Self-test Log\n");    return -1;  }    // Fix logversion if needed  if (data->logversion !=1) {    if (!con->permissive) {      pout("Error SMART Selective Self-Test Log Data Structure Revision not recognized\n"           "Revision number should be 1 but is %d. To be safe, aborting WRITE LOG.\n"           "To fix revision number, add one '-T permissive' option.\n", data->logversion);      return -2;    }    con->permissive--;    pout("SMART Selective Self-Test Log Data Structure Revision should be 1 but is %d\n"         "'-T permissive' specified, now trying to fix it by WRITE LOG.\n", data->logversion);    data->logversion = 1;  }  // Host is NOT allowed to write selective self-test log if a selective  // self-test is in progress.  if (0<data->currentspan && data->currentspan<6 && ((sv->self_test_exec_status)>>4)==15) {    pout("Error SMART Selective or other Self-Test in progress.\n");    return -4;  }  // Set start/end values based on old spans for special -t select,... options  int i;  for (i=0; i<con->smartselectivenumspans; i++) {    char mode = con->smartselectivemode[i];    uint64_t start = con->smartselectivespan[i][0];    uint64_t end   = con->smartselectivespan[i][1];    if (mode == SEL_CONT) {// redo or next dependig on last test status      switch (sv->self_test_exec_status >> 4) {        case 1: case 2: // Aborted/Interrupted by host          pout("Continue Selective Self-Test: Redo last span\n");          mode = SEL_REDO;          break;        default: // All others          pout("Continue Selective Self-Test: Start next span\n");          mode = SEL_NEXT;          break;      }    }    switch (mode) {      case SEL_RANGE: // -t select,START-END        break;      case SEL_REDO: // -t select,redo... => Redo current        start = data->span[i].start;        if (end > 0) { // -t select,redo+SIZE          end--; end += start; // [oldstart, oldstart+SIZE)        }        else // -t select,redo          end = data->span[i].end; // [oldstart, oldend]        break;      case SEL_NEXT: // -t select,next... => Do next        if (data->span[i].end == 0) {          start = end = 0; break; // skip empty spans        }        start = data->span[i].end + 1;        if (start >= num_sectors)          start = 0; // wrap around        if (end > 0) { // -t select,next+SIZE          end--; end += start; // (oldend, oldend+SIZE]        }        else { // -t select,next          uint64_t oldsize = data->span[i].end - data->span[i].start + 1;          end = start + oldsize - 1; // (oldend, oldend+oldsize]          if (end >= num_sectors) {            // Adjust size to allow round-robin testing without future size decrease            uint64_t spans = (num_sectors + oldsize-1) / oldsize;            uint64_t newsize = (num_sectors + spans-1) / spans;            uint64_t newstart = num_sectors - newsize, newend = num_sectors - 1;            pout("Span %d changed from %"PRIu64"-%"PRIu64" (%"PRIu64" sectors)\n"                 "                 to %"PRIu64"-%"PRIu64" (%"PRIu64" sectors) (%"PRIu64" spans)\n",                i, start, end, oldsize, newstart, newend, newsize, spans);            start = newstart; end = newend;          }        }        break;      default:        pout("ataWriteSelectiveSelfTestLog: Invalid mode %d\n", mode);        return -1;    }    // Range check    if (start < num_sectors && num_sectors <= end) {      if (end != ~(uint64_t)0) // -t select,N-max        pout("Size of self-test span %d decreased according to disk size\n", i);      end = num_sectors - 1;    }    if (!(start <= end && end < num_sectors)) {      pout("Invalid selective self-test span %d: %"PRIu64"-%"PRIu64" (%"PRIu64" sectors)\n",        i, start, end, num_sectors);      return -1;    }    // Write back to allow ataSmartTest() to print the actual values    con->smartselectivespan[i][0] = start;    con->smartselectivespan[i][1] = end;  }  // Clear spans  for (i=0; i<5; i++)    memset(data->span+i, 0, sizeof(struct test_span));    // Set spans for testing   for (i=0; i<con->smartselectivenumspans; i++){    data->span[i].start = con->smartselectivespan[i][0];    data->span[i].end   = con->smartselectivespan[i][1];  }  // host must initialize to zero before initiating selective self-test  data->currentlba=0;  data->currentspan=0;    // Perform off-line scan after selective test?  if (1 == con->scanafterselect)    // NO    data->flags &= ~SELECTIVE_FLAG_DOSCAN;  else if (2 == con->scanafterselect)    // YES    data->flags |= SELECTIVE_FLAG_DOSCAN;    // Must clear active and pending flags before writing  data->flags &= ~(SELECTIVE_FLAG_ACTIVE);    data->flags &= ~(SELECTIVE_FLAG_PENDING);  // modify pending time?  if (con->pendingtime)    data->pendingtime=(unsigned short)(con->pendingtime-1);  // Set checksum to zero, then compute checksum  data->checksum=0;  unsigned char cksum=0;  for (i=0; i<512; i++)    cksum+=ptr[i];  cksum=~cksum;  cksum+=1;  data->checksum=cksum;  // swap endian order if needed  if (isbigendian()){    swap2((char *)&(data->logversion));    for (int i=0;i<5;i++){      swap8((char *)&(data->span[i].start));      swap8((char *)&(data->span[i].end));    }    swap8((char *)&(data->currentlba));    swap2((char *)&(data->currentspan));    swap2((char *)&(data->flags));    swap2((char *)&(data->pendingtime));  }  // write new selective self-test log  if (smartcommandhandler(device, WRITE_LOG, 0x09, (char *)data)){    syserror("Error Write Selective Self-Test Log failed");    return -3;  }  return 0;}// This corrects some quantities that are byte reversed in the SMART// ATA ERROR LOG.void fixsamsungerrorlog(struct ata_smart_errorlog *data){  int i,j;    // FIXED IN SAMSUNG -25 FIRMWARE???  // Device error count in bytes 452-3  swap2((char *)&(data->ata_error_count));    // FIXED IN SAMSUNG -22a FIRMWARE  // step through 5 error log data structures  for (i=0; i<5; i++){    // step through 5 command data structures    for (j=0; j<5; j++)      // Command data structure 4-byte millisec timestamp.  These are      // bytes (N+8, N+9, N+10, N+11).      swap4((char *)&(data->errorlog_struct[i].commands[j].timestamp));    // Error data structure two-byte hour life timestamp.  These are    // bytes (N+28, N+29).    swap2((char *)&(data->errorlog_struct[i].error_struct.timestamp));  }  return;}// NEEDED ONLY FOR SAMSUNG -22 (some) -23 AND -24?? FIRMWAREvoid fixsamsungerrorlog2(struct ata_smart_errorlog *data){  // Device error count in bytes 452-3  swap2((char *)&(data->ata_error_count));  return;}// Reads the Summary SMART Error Log (log #1). The Comprehensive SMART// Error Log is #2, and the Extended Comprehensive SMART Error log is// #3int ataReadErrorLog (int device, struct ata_smart_errorlog *data){          // get data from device  if (smartcommandhandler(device, READ_LOG, 0x01, (char *)data)){    syserror("Error SMART Error Log Read failed");    return -1;  }    // compute its checksum, and issue a warning if needed  if (checksum((unsigned char *)data))    checksumwarning("SMART ATA Error Log Structure");    // Some disks have the byte order reversed in some SMART Summary  // Error log entries  if (con->fixfirmwarebug == FIX_SAMSUNG)    fixsamsungerrorlog(data);  else if (con->fixfirmwarebug == FIX_SAMSUNG2)    fixsamsungerrorlog2(data);  // swap endian order if needed  if (isbigendian()){    int i,j;        // Device error count in bytes 452-3    swap2((char *)&(data->ata_error_count));        // step through 5 error log data structures    for (i=0; i<5; i++){      // step through 5 command data structures      for (j=0; j<5; j++)        // Command data structure 4-byte millisec timestamp        swap4((char *)&(data->errorlog_struct[i].commands[j].timestamp));      // Error data structure life timestamp      swap2((char *)&(data->errorlog_struct[i].error_struct.timestamp));    }  }    return 0;}int ataReadSmartThresholds (int device, struct ata_smart_thresholds_pvt *data){    // get data from device  if (smartcommandhandler(device, READ_THRESHOLDS, 0, (char *)data)){    syserror("Error SMART Thresholds Read failed");    return -1;  }    // compute its checksum, and issue a warning if needed  if (checksum((unsigned char *)data))    checksumwarning("SMART Attribute Thresholds Structure");    // swap endian order if needed  if (isbigendian())    swap2((char *)&(data->revnumber));  return 0;}int ataEnableSmart (int device ){         if (smartcommandhandler(device, ENABLE, 0, NULL)){    syserror("Error SMART Enable failed");    return -1;  }  return 0;}int ataDisableSmart (int device ){      

⌨️ 快捷键说明

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