📄 atacmds.cpp
字号:
return rawvalue; } // Print one six-byte quantity if (select==255){ out+=sprintf(out, "%"PRIu64, rawvalue); return rawvalue; } // This switch statement is where we handle Raw attributes // that are stored in an unusual vendor-specific format, switch (attribute->id){ // Spin-up time case 3: out+=sprintf(out, "%d", word[0]); // if second nonzero then it stores the average spin-up time if (word[1]) out+=sprintf(out, " (Average %d)", word[1]); break; // Power on time case 9: if (select==1){ // minutes int64_t tmp1=rawvalue/60; int64_t tmp2=rawvalue%60; out+=sprintf(out, "%"PRIu64"h+%02"PRIu64"m", tmp1, tmp2); } else if (select==3){ // seconds int64_t hours=rawvalue/3600; int64_t minutes=(rawvalue-3600*hours)/60; int64_t seconds=rawvalue%60; out+=sprintf(out, "%"PRIu64"h+%02"PRIu64"m+%02"PRIu64"s", hours, minutes, seconds); } else if (select==4){ // 30-second counter int64_t tmp1=rawvalue/120; int64_t tmp2=(rawvalue-120*tmp1)/2; out+=sprintf(out, "%"PRIu64"h+%02"PRIu64"m", tmp1, tmp2); } else // hours out+=sprintf(out, "%"PRIu64, rawvalue); //stored in hours break; // Temperature case 190: ataPrintTemperatureValue(out, attribute->raw, word); break; // Load unload cycles case 193: if (select==1){ // loadunload long load =attribute->raw[0] + (attribute->raw[1]<<8) + (attribute->raw[2]<<16); long unload=attribute->raw[3] + (attribute->raw[4]<<8) + (attribute->raw[5]<<16); out+=sprintf(out, "%lu/%lu", load, unload); } else // associated out+=sprintf(out, "%"PRIu64, rawvalue); break; // Temperature case 194: if (select==1){ // ten times temperature in Celsius int deg=word[0]/10; int tenths=word[0]%10; out+=sprintf(out, "%d.%d", deg, tenths); } else if (select==2) // unknown attribute out+=sprintf(out, "%"PRIu64, rawvalue); else ataPrintTemperatureValue(out, attribute->raw, word); break; default: out+=sprintf(out, "%"PRIu64, rawvalue); } // Return the full value return rawvalue;}// Note some attribute names appear redundant because different// manufacturers use different attribute IDs for an attribute with the// same name. The variable val should contain a non-zero value if a particular// attributes has a non-default interpretation.void ataPrintSmartAttribName(char *out, unsigned char id, unsigned char *definitions){ char *name; unsigned char val; // If no data array, use default interpretations if (definitions) val=definitions[id]; else val=0; switch (id){ case 1: name="Raw_Read_Error_Rate"; break; case 2: name="Throughput_Performance"; break; case 3: name="Spin_Up_Time"; break; case 4: name="Start_Stop_Count"; break; case 5: name="Reallocated_Sector_Ct"; break; case 6: name="Read_Channel_Margin"; break; case 7: name="Seek_Error_Rate"; break; case 8: name="Seek_Time_Performance"; break; case 9: switch (val) { case 1: name="Power_On_Minutes"; break; case 2: name="Temperature_Celsius"; break; case 3: name="Power_On_Seconds"; break; case 4: name="Power_On_Half_Minutes"; break; default: name="Power_On_Hours"; break; } break; case 10: name="Spin_Retry_Count"; break; case 11: name="Calibration_Retry_Count"; break; case 12: name="Power_Cycle_Count"; break; case 13: name="Read_Soft_Error_Rate"; break; case 187: name="Reported_Uncorrect"; break; case 189: name="High_Fly_Writes"; break; case 190: // Western Digital uses this for temperature. // It's identical to Attribute 194 except that it // has a failure threshold set to correspond to the // max allowed operating temperature of the drive, which // is typically 55C. So if this attribute has failed // in the past, it indicates that the drive temp exceeded // 55C sometime in the past. name="Airflow_Temperature_Cel"; break; case 191: name="G-Sense_Error_Rate"; break; case 192: switch (val) { case 1: // Fujitsu name="Emergency_Retract_Cycle_Ct"; break; default: name="Power-Off_Retract_Count"; break; } break; case 193: name="Load_Cycle_Count"; break; case 194: switch (val){ case 1: // Samsung SV1204H with RK100-13 firmware name="Temperature_Celsius_x10"; break; case 2: // for disks with no temperature Attribute name="Unknown_Attribute"; break; default: name="Temperature_Celsius"; break; } break; case 195: // Fujitsu name="ECC_On_The_Fly_Count"; name="Hardware_ECC_Recovered"; break; case 196: name="Reallocated_Event_Count"; break; case 197: name="Current_Pending_Sector"; break; case 198: switch (val){ case 1: // Fujitsu name="Off-line_Scan_UNC_Sector_Ct"; break; default: name="Offline_Uncorrectable"; break; } break; case 199: name="UDMA_CRC_Error_Count"; break; case 200: switch (val) { case 1: // Fujitsu MHS2020AT name="Write_Error_Count"; break; default: // Western Digital name="Multi_Zone_Error_Rate"; break; } break; case 201: switch (val) { case 1: // Fujitsu name="Detected_TA_Count"; break; default: name="Soft_Read_Error_Rate"; break; } break; case 202: // Fujitsu name="TA_Increase_Count"; // Maxtor: Data Address Mark Errors break; case 203: // Fujitsu name="Run_Out_Cancel"; // Maxtor: ECC Errors break; case 204: // Fujitsu name="Shock_Count_Write_Opern"; // Maxtor: Soft ECC Correction break; case 205: // Fujitsu name="Shock_Rate_Write_Opern"; // Maxtor: Thermal Aspirates break; case 206: // Fujitsu name="Flying_Height"; break; case 207: // Maxtor name="Spin_High_Current"; break; case 208: // Maxtor name="Spin_Buzz"; break; case 209: // Maxtor name="Offline_Seek_Performnce"; break; case 220: switch (val) { case 1: name="Temperature_Celsius"; break; default: name="Disk_Shift"; break; } break; case 221: name="G-Sense_Error_Rate"; break; case 222: name="Loaded_Hours"; break; case 223: name="Load_Retry_Count"; break; case 224: name="Load_Friction"; break; case 225: name="Load_Cycle_Count"; break; case 226: name="Load-in_Time"; break; case 227: name="Torq-amp_Count"; break; case 228: name="Power-off_Retract_Count"; break; case 230: // seen in IBM DTPA-353750 name="Head_Amplitude"; break; case 231: name="Temperature_Celsius"; break; case 240: name="Head_Flying_Hours"; break; case 250: name="Read_Error_Retry_Rate"; break; default: name="Unknown_Attribute"; break; } sprintf(out,"%3hu %s",(short int)id,name); return;}// Returns raw value of Attribute with ID==id. This will be in the// range 0 to 2^48-1 inclusive. If the Attribute does not exist,// return -1.int64_t ATAReturnAttributeRawValue(unsigned char id, struct ata_smart_values *data) { int i; // valid Attribute IDs are in the range 1 to 255 inclusive. if (!id || !data) return -1; // loop over Attributes to see if there is one with the desired ID for (i=0; i<NUMBER_ATA_SMART_ATTRIBUTES; i++) { struct ata_smart_attribute *ap = data->vendor_attributes + i; if (ap->id == id) { // we've found the desired Attribute. Return its value int64_t rawvalue=0; int j; for (j=0; j<6; j++) { // This looks a bit roundabout, but is necessary. Don't // succumb to the temptation to use raw[j]<<(8*j) since under // the normal rules this will be promoted to the native type. // On a 32 bit machine this might then overflow. int64_t temp; temp = ap->raw[j]; temp <<= 8*j; rawvalue |= temp; } // loop over j return rawvalue; } // found desired Attribute } // loop over Attributes // fall-through: no such Attribute found return -1;}// Return Temperature Attribute raw value selected according to possible// non-default interpretations. If the Attribute does not exist, return 0unsigned char ATAReturnTemperatureValue(/*const*/ struct ata_smart_values *data, const unsigned char *defs){ int i; for (i = 0; i < 3; i++) { static const unsigned char ids[3] = {194, 9, 220}; unsigned char id = ids[i]; unsigned char select = (defs ? defs[id] : 0); int64_t raw; unsigned temp; if (!( (id == 194 && select <= 1) // ! -v 194,unknown || (id == 9 && select == 2) // -v 9,temp || (id == 220 && select == 1))) // -v 220,temp continue; raw = ATAReturnAttributeRawValue(id, data); if (raw < 0) continue; temp = (unsigned short)raw; // ignore possible min/max values in high words if (id == 194 && select == 1) // -v 194,10xCelsius temp = (temp+5) / 10; if (!(0 < temp && temp <= 255)) continue; return temp; } // No valid attribute found return 0;}// Read SCT Statusint ataReadSCTStatus(int device, ata_sct_status_response * sts){ // read SCT status via SMART log 0xe0 memset(sts, 0, sizeof(*sts)); if (smartcommandhandler(device, READ_LOG, 0xe0, (char *)sts)){ syserror("Error Read SCT Status failed"); return -1; } // swap endian order if needed if (isbigendian()){ swapx(&sts->format_version); swapx(&sts->sct_version); swapx(&sts->sct_spec); swapx(&sts->ext_status_code); swap
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -