Ticket #870: smart_SAS_Changes.patch

File smart_SAS_Changes.patch, 23.1 KB (added by Akhilesh_RN, 7 years ago)
  • smart-patch-old/drivedb.h

    diff -Naurw ../smart-patch-old/drivedb.h smart-patch-old/drivedb.h
    ../  
    13911391  //"-v 242,raw48,Total_LBAs_Read "
    13921392    "-v 244,raw48,Thermal_Throttle "
    13931393  },
     1394  { "Sandisk SAS Optimus2 and Ultrastar ss200 ESS SSDs",
     1395    "SD[A-Z0-9]{2}[O1][A-Z0-9]{3}-?[0-9]{3,4}[GT]-?[C5][A-Za-z0-9]{3}",
     1396    "","",
     1397    "-v 1,raw48,Raw_Read_Err_Rate "
     1398    "-v 2,raw48,Flash_ROM_Check "
     1399    "-v 5,raw16(raw16),Reallocated_Blk_Ct "
     1400    "-v 9,raw48,Power_ON_Hours "
     1401    "-v 12,raw48,Power_Cycle_Ct "
     1402    "-v 13,raw48,ECC_Rate "
     1403    "-v 29,raw48,Pwr_Fail_Backup_Circuit "
     1404    "-v 32,raw48,Avg_Write_Amplification "
     1405    "-v 177,raw48,Drive_Life_Remain% "
     1406    "-v 178,raw48,Drive_Life_Remain_x100 "
     1407    "-v 180,raw48,Unused_Reserved_Blk_Ct "
     1408    "-v 181,raw48,Program_Fail_Ct "
     1409    "-v 182,raw48,Erase_Fail_Ct "
     1410    "-v 190,raw48,Drive_Temp_Warning "
     1411    "-v 194,raw48,Drive_Temperature "
     1412    "-v 195,raw48,UECC_Ct "
     1413    "-v 198,raw48,Offline_Scan_UEC "
     1414    "-v 233,raw48,Number_Of_LBA_Written "
     1415    "-v 235,raw48,Power_Fail_Backup_Health "
     1416    "-v 245,raw48,DriveLife_Used% "
     1417    "-v 246,raw48,DriveLife_Used%x100 "
     1418  },
     1419  { "Sandisk SAS Lightning Gen II DELL ESS SSDs",
     1420  "LT[A-Z0-9]{4,6}",
     1421  "[DE][A-Z0-9]{3}", "",
     1422  "-v 1,raw48,Raw_Read_Err_Rate "
     1423  "-v 5,raw48,Reallocated_Blk_Ct "
     1424  "-v 9,raw48,POH_in_Life_Time "
     1425  "-v 12,raw48,Power_Cycle_Ct "
     1426  "-v 13,raw48,ECC_Rate "
     1427  "-v 115,raw48,Endurance_Limit_Met "
     1428  "-v 179,raw48,Used_Rsvd_Blk_Ct_Total  "
     1429  "-v 180,raw48,Unused_Rsvd_Blk_Ct_Total "
     1430  "-v 181,raw48,Program_Fail_Ct "
     1431  "-v 182,raw48,Erase_Fail_Ct "
     1432  "-v 194,raw48,Temperature "
     1433  "-v 195,raw48,UEC "
     1434  "-v 198,raw48,Offline_Scan_UEC "
     1435  "-v 199,raw48,CRC_Err_Ct "
     1436  "-v 201,raw48,Volatile_Memory_Fail "
     1437  "-v 202,raw48,Exception_Mode_Status "
     1438  "-v 233,raw48,Write_Cmnd_Ct "
     1439  "-v 240,raw48,Link_Err_Event "
     1440  "-v 245,raw48,Remaining_Device_Life "
     1441  "-v 255,raw48,Smart_Tests "
     1442  },
     1443  { "Sandisk SAS Lightning Gen II Generic ESS SSDs",
     1444    "LT[A-Z0-9]{4,6}",
     1445    "","",
     1446    "-v 1,raw48,Reallocated_Blk_Ct "
     1447    "-v 2,raw48,Temperature "
     1448    "-v 3,raw16(raw16),POH_in_LifeTime "
     1449    "-v 4,raw48,Power_Cycle_Ct "
     1450    "-v 5,raw48,Program_Fail_Ct "
     1451    "-v 6,raw48,Erase_Fail_Ct "
     1452    "-v 7,raw48,Uncorrectable_Err_Ct "
     1453    "-v 8,raw48,Write_Cmnd_Ct "
     1454    "-v 9,raw48,Smart_Test "
     1455    "-v 10,raw48,Raw_Read_Err_Rate "
     1456    "-v 11,raw48,Ecc_Rate "
     1457    "-v 12,raw48,Program_Fail_Ct_Port "
     1458    "-v 13,raw48,Erase_Fail_Ct_Port "
     1459    "-v 14,raw48,Wear_Leveling "
     1460    "-v 15,raw48,Used_Rsvd_Blk_Ct_Port "
     1461    "-v 16,raw48,Used_Rsvd_Blk_Ct_Total "
     1462    "-v 17,raw48,Unused_Rsvd_Blk_Ct_Total "
     1463    "-v 18,raw48,Hardware_Fail_Ct "
     1464    "-v 19,raw48,Offline_Scan_UEC  "
     1465    "-v 20,raw48,CRC_Err_Ct  "
     1466    "-v 21,raw48,Volatile_Memory_Fail  "
     1467    "-v 22,raw48,Unused_Rsvd_Blk_Ct_Port "
     1468    "-v 23,raw48,Read_Err_Rate  "
     1469    "-v 24,raw48,Write_Err_Rate  "
     1470    "-v 25,raw48,Endurance_Limit "
     1471    "-v 26,raw48,Start_Unit_Time  "
     1472    "-v 28,raw48,CBC_Health  "
     1473    "-v 29,raw48,Exception_Mode_Status  "
     1474    "-v 30,raw48,Link_Err_Event  "
     1475    "-v 31,raw48,Remaining_Device_Life  "
     1476  },
     1477  { "Sandisk SAS Lightning Gen II HP ESS SSDs",
     1478    "[EM][KO][A-Z0-9]{9}",
     1479    "","",
     1480    "-v 3,raw48,POH_in_Life_Time "
     1481    "-v 4,raw48,Power_Cycle_Ct "
     1482    "-v 5,raw48,Smart_Temp_Timestamps "
     1483    "-v 16,raw48,General_HW_Fail_Predict "
     1484    "-v 20,raw48,Excessive_Reassigns "
     1485    "-v 50,raw48,Excessive_Read_Err_Rate "
     1486    "-v 66,raw48,Excessive_Write_Err_Rate "
     1487    "-v 115,raw48,Endurance_Limit_Met "
     1488  },
    13941489  { "SiliconMotion based SSDs", // SM2246EN (Transcend TS6500)
    13951490    "CT(120|250|500|1000)BX100SSD1|" // Crucial BX100, tested with CT250BX100SSD1/MU02,
    13961491      // CT500BX100SSD1/MU02, CT1000BX100SSD1/MU02
  • smart-patch-old/knowndrives.cpp

    diff -Naurw ../smart-patch-old/knowndrives.cpp smart-patch-old/knowndrives.cpp
    ../  
    581581  return dbentry;
    582582}
    583583
     584// Searches drive database and sets preset vendor attribute
     585// options in defs and firmwarebugs.
     586// Values that have already been set will not be changed.
     587// Returns pointer to database entry or nullptr if none found
     588const drive_settings * scsi_lookup_drive_apply_presets(
     589    char * driveModel, int driveModelLen, char * fwRev, int fwRevLen, ata_vendor_attr_defs & defs)
     590{
     591        // get the drive's model/firmware strings
     592        char model[MODEL_STRING_LENGTH + 1], firmware[FIRMWARE_STRING_LENGTH + 1];
     593    firmwarebug_defs firmwarebugs;
     594
     595    snprintf(model, driveModelLen, "%s", driveModel);
     596    snprintf(firmware, fwRevLen, "%s", fwRev);
     597
     598        // Look up the drive in knowndrives[].
     599        const drive_settings * dbentry = lookup_drive(model, firmware);
     600        if (!dbentry)
     601                return 0;
     602
     603    if (*dbentry->presets) {
     604        // Apply presets
     605        if (!parse_presets(dbentry->presets, defs, firmwarebugs))
     606            pout("Syntax error in preset option string \"%s\"\n", dbentry->presets);
     607    }
     608
     609    return dbentry;
     610}
    584611
    585612/////////////////////////////////////////////////////////////////////////////
    586613// Parser for drive database files
  • smart-patch-old/knowndrives.h

    diff -Naurw ../smart-patch-old/knowndrives.h smart-patch-old/knowndrives.h
    ../  
    6060const drive_settings * lookup_drive_apply_presets(
    6161  const ata_identify_device * drive, ata_vendor_attr_defs & defs,
    6262  firmwarebug_defs & firmwarebugs);
    63 
     63const drive_settings * scsi_lookup_drive_apply_presets(
     64    char * driveModel, int driveModelLen, char * fwRev,int fwRevLen, ata_vendor_attr_defs & defs);
    6465// Get path for additional database file
    6566const char * get_drivedb_path_add();
    6667
  • smart-patch-old/scsicmds.cpp

    diff -Naurw ../smart-patch-old/scsicmds.cpp smart-patch-old/scsicmds.cpp
    ../  
    514514    io_hdr.dxferp = pBuf;
    515515    cdb[0] = LOG_SENSE;
    516516    cdb[2] = 0x40 | (pagenum & 0x3f);  /* Page control (PC)==1 */
     517    cdb[3] = subpagenum;
    517518    cdb[7] = (pageLen >> 8) & 0xff;
    518519    cdb[8] = pageLen & 0xff;
    519520    io_hdr.cmnd = cdb;
  • smart-patch-old/scsiprint.cpp

    diff -Naurw ../smart-patch-old/scsiprint.cpp smart-patch-old/scsiprint.cpp
    ../  
    3737#include "scsiprint.h"
    3838#include "smartctl.h"
    3939#include "utility.h"
     40#include "knowndrives.h"
    4041
    4142#define GBUF_SIZE 65535
    4243
     
    14521453        "0xf"
    14531454};
    14541455
     1456static int
     1457scsi_get_drive_data(scsi_device * device, scsi_device_info * device_info)
     1458{
     1459    int err, len, req_len, avail_len;
     1460    char product[16 + 1], revision[4 + 1];
     1461    int transport = -1;
     1462
     1463    memset(gBuf, 0, 96);
     1464    req_len = 36;
     1465    if ((err = scsiStdInquiry(device, gBuf, req_len))) {
     1466        print_on();
     1467        pout("Standard Inquiry (36 bytes) failed [%s]\n", scsiErrString(err));
     1468        pout("Retrying with a 64 byte Standard Inquiry\n");
     1469        print_off();
     1470        /* Marvell controllers fail on a 36 bytes StdInquiry, but 64 suffices */
     1471        req_len = 64;
     1472        if ((err = scsiStdInquiry(device, gBuf, req_len))) {
     1473            print_on();
     1474            pout("Standard Inquiry (64 bytes) failed [%s]\n",
     1475                scsiErrString(err));
     1476            print_off();
     1477            return 1;
     1478        }
     1479    }
     1480
     1481    avail_len = gBuf[4] + 5;
     1482    len = (avail_len < req_len) ? avail_len : req_len;
     1483
     1484    if (len < 36) {
     1485        print_on();
     1486        pout("Short INQUIRY response\n");
     1487        print_off();
     1488        return 1;
     1489    }
     1490
     1491    if (0 != strncmp((char *)&gBuf[8], "ATA", 3)) {
     1492        scsi_format_id_string(product, (const unsigned char *)&gBuf[16], 16);
     1493        scsi_format_id_string(revision, (const unsigned char *)&gBuf[32], 4);
     1494        snprintf((char*)device_info->model, sizeof(device_info->model), "%s", product);
     1495        snprintf((char*)device_info->fw_rev, sizeof(device_info->fw_rev), "%s", revision);
     1496    }
     1497
     1498    if (0 == (err = scsiInquiryVpd(device, SCSI_VPD_DEVICE_IDENTIFICATION,
     1499        gBuf, 252))) {
     1500        char s[256];
     1501        len = gBuf[3];
     1502        scsi_decode_lu_dev_id(gBuf + 4, len, s, sizeof(s), &transport);
     1503        if (strlen(s) > 0){
     1504            sscanf(s, "%llx", &device_info->WWNLun);
     1505        }
     1506    }
     1507    return 0;
     1508}
     1509
     1510
     1511
    14551512/* Returns 0 on success, 1 on general error and 2 for early, clean exit */
    14561513static int
    14571514scsiGetDriveInfo(scsi_device * device, UINT8 * peripheral_type, bool all)
     
    18811938        pout("Drive Trip Temperature:        %d C\n", trip);
    18821939    pout("\n");
    18831940}
     1941int check_wdc_valid_paramcode(uint16_t id)
     1942{
     1943    uint16_t i = 0;
     1944    struct
     1945    {
     1946        uint16_t paramCode;
     1947    }
     1948    paramList[] =
     1949    {
     1950        { WDC_PARAM_ID_POWER_ON_TIME },
     1951        { WDC_PARAM_ID_POWER_CYCLE_COUNT },
     1952        { WDC_PARAM_ID_SMART_TEMP_TIMESTAMPS },
     1953        { WDC_PARAM_ID_GEN_HW_FAIL },
     1954        { WDC_PARAM_ID_EXCESSIVE_REASSIGNS },
     1955        { WDC_PARAM_ID_START_UNIT_TIME },
     1956        { WDC_PARAM_ID_EXCESSIVE_RD_ERR_RATE },
     1957        { WDC_PARAM_ID_EXCESSIVE_WR_ERR_RATE },
     1958        { WDC_PARAM_ID_ENDURANCE_LIMIT_MET },
     1959    };
     1960
     1961    for (; i < sizeof(paramList) / sizeof(paramList[0]); i++){
     1962        if (id == paramList[i].paramCode)
     1963            return 1;
     1964    }
     1965    return 0;
     1966}
     1967
     1968bool match_wdc_regex(const char * pattern, const char * str)
     1969{
     1970    regular_expression regex;
     1971
     1972    if (!regex.compile(pattern, REG_EXTENDED)) {
     1973        pout("Internal error: unable to compile WDC regular expression \"%s\": %s\n",
     1974            pattern, regex.get_errmsg());
     1975        return false;
     1976    }
     1977    return regex.full_match(str);
     1978}
     1979
     1980bool is_wdc_drive(uint64_t WWNLun)
     1981{
     1982    // Check for WDC Drive using IEEE Registered Name
     1983    if (((WWNLun & 0XF000000000000000LL) >> 60) == 0x5){
     1984        if ((((WWNLun & 0x0FFFFFF000000000LL) >> 36) == 0x1e82)
     1985            || (((WWNLun & 0x0FFFFFF000000000LL) >> 36) == 0x1b44)
     1986            || (((WWNLun & 0x0FFFFFF000000000LL) >> 36) == 0x1173))
     1987        {
     1988            return true;
     1989        }
     1990    }
     1991    return false;
     1992}
     1993
     1994static void
     1995scsi_print_smart_data(scsi_smart_attribute *smartData, const ata_vendor_attr_defs & attribute_defs)
     1996{
     1997    char current[0x100], threshold[0x100], worst[0x100];
     1998    int i = 0;
     1999
     2000    pout("ID#  ATTRIBUTE_NAME                         VALUE         THRESH          WORST\n");
     2001    for (i = 1; i <= smartData->numberofAttributes; i++){
     2002        memset(current, 0, sizeof(current));
     2003        memset(threshold, 0, sizeof(threshold));
     2004        memset(worst, 0, sizeof(worst));
     2005
     2006        snprintf(current, sizeof(current), "%u", smartData[i].current);
     2007        snprintf(threshold, sizeof(threshold), "%u", smartData[i].threshold);
     2008        snprintf(worst, sizeof(worst), "%u", smartData[i].worst);
     2009        std::string attrname = ata_get_smart_attr_name(smartData[i].id, attribute_defs, 0);
     2010
     2011        pout("%-3d  %-24s               %-10s\t  %-10s\t  %-10s \n", smartData[i].id, attrname.c_str(), current, threshold, worst);
     2012    }
     2013}
     2014
     2015/*Read smartData from IELogPage and smartdata LogPage*/
     2016int
     2017scsi_read_wdc_smart_values(scsi_device * device, scsi_smart_attribute *smartData, scsi_smart_settings *scsiSmartSetting)
     2018{
     2019    UINT8 *tBuf = NULL;
     2020    int err, i = 1;
     2021    UINT8 *buffAddress = NULL;
     2022    UINT8 smartDataLen = 0;
     2023    UINT32 buffLength = 0;
     2024
     2025    if (!device || !smartData || !scsiSmartSetting){
     2026        return EINVAL;
     2027    }
     2028
     2029    tBuf = (UINT8*)calloc(1, 4);
     2030
     2031    if ((err = scsiLogSense(device, scsiSmartSetting->logPageCode, scsiSmartSetting->logSubpageCode, tBuf,
     2032        4, 0))) {
     2033        pout("Log Sense failed to get page length, IE page [%s]\n", scsiErrString(err));
     2034        return err;
     2035    }
     2036
     2037    buffLength = ((tBuf[2] << 8) | tBuf[3]) + 4;
     2038
     2039    memset(&tBuf, 0, sizeof(tBuf));
     2040    tBuf = (UINT8*)calloc(1, buffLength);
     2041
     2042    if ((err = scsiLogSense(device, scsiSmartSetting->logPageCode, scsiSmartSetting->logSubpageCode, tBuf,
     2043        buffLength, 0))) {
     2044        pout("Log Sense failed, IE page [%s]\n", scsiErrString(err));
     2045        return err;
     2046    }
     2047
     2048    buffAddress = tBuf + scsiSmartSetting->parameterStartOffset;
     2049    buffLength = buffLength - 4;
     2050
     2051    while (buffAddress <= (tBuf + buffLength) && i < (WDC_NUMBER_SCSI_SMART_ATTRIBUTES_MAX - 1)){
     2052        swap2((char*)&buffAddress[scsiSmartSetting->parameterIdOffset]);
     2053        swap4((char*)&buffAddress[scsiSmartSetting->thresholdValueOffset]);
     2054        swap4((char*)&buffAddress[scsiSmartSetting->currentValueOffset]);
     2055        swap4((char*)&buffAddress[scsiSmartSetting->worstValueOffset]);
     2056
     2057        memcpy(&smartData[i].id, &buffAddress[scsiSmartSetting->parameterIdOffset], 2);
     2058        //HP FW specific
     2059        if (strncmp(scsiSmartSetting->customerName, "HP", strlen("HP")) == 0) {
     2060            if (smartData[i].id == 6){
     2061                smartDataLen = buffAddress[scsiSmartSetting->bufferAddressOffset];
     2062                buffAddress += scsiSmartSetting->parameterValueLength + 4;
     2063                // for all the parameters in 6
     2064                while (smartDataLen) {
     2065                    smartData[i].id = *buffAddress++;
     2066                    if (!check_wdc_valid_paramcode(smartData[i].id)){
     2067                        buffAddress += 3;
     2068                        smartDataLen -= 4;
     2069                        continue;
     2070                    }
     2071                    smartData[i].threshold = *buffAddress++;
     2072                    smartData[i].current = *buffAddress++;
     2073                    smartData[i].worst = *buffAddress++;
     2074                    smartDataLen -= 4;
     2075                    i++;
     2076                }
     2077                break;
     2078            }
     2079            else{
     2080                smartData[i].threshold = 0;
     2081                memcpy(&smartData[i].current, &buffAddress[scsiSmartSetting->currentValueOffset], 4);
     2082                smartData[i].worst = 0;
     2083            }
     2084        }
     2085        else{
     2086            memcpy(&smartData[i].threshold, &buffAddress[scsiSmartSetting->thresholdValueOffset], 4);
     2087            memcpy(&smartData[i].current, &buffAddress[scsiSmartSetting->currentValueOffset], 4);
     2088            memcpy(&smartData[i].worst, &buffAddress[scsiSmartSetting->worstValueOffset], 4);
     2089        }
     2090
     2091        if (scsiSmartSetting->bufferAddressOffset)
     2092            buffAddress += buffAddress[scsiSmartSetting->bufferAddressOffset] + scsiSmartSetting->parameterValueLength;
     2093        else
     2094            buffAddress += scsiSmartSetting->parameterValueLength;
     2095
     2096        i++;
     2097    }
     2098    smartData->numberofAttributes = i - 1;
     2099
     2100    if (!buffAddress)
     2101        free(buffAddress);
     2102
     2103    return 0;
     2104}
     2105
     2106static void
     2107scsi_print_wdc_smart_attributes(scsi_device * device, scsi_device_info * drive)
     2108{
     2109    struct scsi_smart_attribute smartData[WDC_NUMBER_SCSI_SMART_ATTRIBUTES_MAX];
     2110    UINT8 dataBuffer[0x100];
     2111    scsi_smart_settings scsiSmartSetting;
     2112    const drive_settings * dbentry = 0;
     2113    ata_vendor_attr_defs attribute_defs;
     2114
     2115    memset(&smartData, 0, sizeof(scsi_smart_attribute));
     2116    memset(&scsiSmartSetting, 0, sizeof(scsi_smart_settings));
     2117    scsiSmartSetting.customerName = (char*)calloc(1, 20);
     2118
     2119    memset(dataBuffer, 0, sizeof(dataBuffer));
     2120    if (0 == scsiInquiryVpd(device, WDC_SCSI_SMART_DRIVE_INFO_PAGE, dataBuffer, sizeof(dataBuffer))){
     2121        memcpy((void*)drive->model, dataBuffer + WDC_SCSI_MODEL_NO_OFFSET, 16);
     2122    }
     2123
     2124    dbentry = scsi_lookup_drive_apply_presets(drive->model, sizeof(drive->model), drive->fw_rev, sizeof(drive->fw_rev), attribute_defs);
     2125    if (!dbentry)
     2126    {
     2127        pout("Drive model not present in drivedb.h: %s\n\n", device->get_errmsg());
     2128        return;
     2129    }
     2130
     2131    //Sandisk-WDC Lightning Gen II
     2132    if ((match_wdc_regex("LT[A-Z0-9]{4,6}", drive->model) || (match_wdc_regex("[EM][KO][A-Z0-9]{9}", drive->model)))) {
     2133        memset(dataBuffer, 0, sizeof(dataBuffer));
     2134        if (0 == scsiInquiryVpd(device, WDC_SCSI_VPD_ASCII_INFO_PAGE, dataBuffer, sizeof(dataBuffer))) {
     2135            if (dataBuffer[0xE9] == 0x40 || dataBuffer[0xE9] == 0x45 || dataBuffer[0xE9] == 0x46){
     2136                memcpy(scsiSmartSetting.customerName, dataBuffer + WDC_CUSTOMER_NAME_OFFSET, 10);
     2137
     2138                if (strncmp(scsiSmartSetting.customerName, "DELL", strlen("DELL")) == 0){
     2139
     2140                    scsiSmartSetting = { IE_LPAGE, 0, WDC_SMART_DATA_PARAMETER_START_OFFSET,
     2141                                         WDC_SMART_DATA_THRESHOLD_OFFSET_DELL, WDC_SMART_DATA_CURRENT_OFFSET_DELL,
     2142                                         WDC_SMART_DATA_WORST_OFFSET_DELL, WDC_SMART_DATA_PARAMETER_LENGTH,
     2143                                         WDC_SMART_DATA_BUFFER_ADDRESS_OFFSET, 0, "DELL" };
     2144                }
     2145                else if (strncmp(scsiSmartSetting.customerName, "HP", strlen("HP")) == 0){
     2146
     2147                    scsiSmartSetting = { IE_LPAGE, 0, WDC_SMART_DATA_PARAMETER_START_OFFSET,
     2148                                         WDC_SMART_DATA_THRESHOLD_OFFSET_HP, WDC_SMART_DATA_CURRENT_OFFSET_HP,
     2149                                         WDC_SMART_DATA_WORST_OFFSET_HP, WDC_SMART_DATA_PARAMETER_LENGTH,
     2150                                         WDC_SMART_DATA_BUFFER_ADDRESS_OFFSET, 0, "HP" };
     2151                }
     2152                else{
     2153
     2154                    scsiSmartSetting = { IE_LPAGE, 0, WDC_SMART_DATA_PARAMETER_START_OFFSET,
     2155                                         WDC_SMART_DATA_THRESHOLD_OFFSET_GENERIC, WDC_SMART_DATA_CURRENT_OFFSET_GENERIC,
     2156                                         WDC_SMART_DATA_WORST_OFFSET_GENERIC, WDC_SMART_DATA_PARAMETER_LENGTH_GENERIC, 0, 0, "Generic" };
     2157                }
     2158            }
     2159        }
     2160    }
     2161    else{
     2162        // Sandisk-WDC Optimus2 and Ultrastar ss200
     2163            scsiSmartSetting = { WDC_SMART_DATA_LOG_PAGE_CODE, WDC_SMART_DATA_LOG_SUBPAGE_CODE, WDC_SMART_DATA_PARAMETER_START_OFFSET,
     2164                                 WDC_SMART_DATA_THRESHOLD_OFFSET_ULTRASTAR, WDC_SMART_DATA_CURRENT_OFFSET_ULTRASTAR,
     2165                                 WDC_SMART_DATA_WORST_OFFSET_ULTRASTAR, WDC_SMART_DATA_PARAMETER_LENGTH, WDC_SMART_DATA_BUFFER_ADDRESS_OFFSET,
     2166                                 0, "" };
     2167        }
     2168
     2169    if (scsi_read_wdc_smart_values(device, smartData, &scsiSmartSetting)) {
     2170        pout("Read SMART Data failed: %s\n\n", device->get_errmsg());
     2171        return;
     2172    }
     2173
     2174    scsi_print_smart_data(smartData, attribute_defs);
     2175}
    18842176
    18852177/* Main entry point used by smartctl command. Return 0 for success */
    18862178int
     
    18932185    struct scsi_sense_disect sense_info;
    18942186    bool is_disk;
    18952187    bool is_tape;
    1896 
     2188    scsi_device_info device_info;
    18972189    bool any_output = options.drive_info;
    18982190
    18992191    if (supported_vpd_pages_p) {
     
    19012193        supported_vpd_pages_p = NULL;
    19022194    }
    19032195    supported_vpd_pages_p = new supported_vpd_pages(device);
     2196    memset(&device_info, 0, sizeof(scsi_device_info));
    19042197
    19052198    res = scsiGetDriveInfo(device, &peripheral_type, options.drive_info);
    19062199    if (res) {
     
    20412334            failuretest(OPTIONAL_CMD, returnval|=res);
    20422335        any_output = true;
    20432336    }
     2337       res = scsi_get_drive_data(device, &device_info);
     2338    if (res != 0)
     2339    {
     2340        pout("unable to get drive data");
     2341        return -1;
     2342    }
     2343
    20442344    if (options.smart_vendor_attrib) {
    20452345        if (! checkedSupportedLogPages)
    20462346            scsiGetSupportedLogPages(device);
     
    20482348            scsiPrintTemp(device);
    20492349        if (gStartStopLPage)
    20502350            scsiGetStartStopData(device);
     2351        if (gSmartLPage && is_wdc_drive(device_info.WWNLun))
     2352            scsi_print_wdc_smart_attributes(device, &device_info);
    20512353        if (is_disk) {
    20522354            scsiPrintGrownDefectListLen(device);
    20532355            if (gSeagateCacheLPage)
  • smart-patch-old/scsiprint.h

    diff -Naurw ../smart-patch-old/scsiprint.h smart-patch-old/scsiprint.h
    ../  
    3030#define SCSI_PRINT_H_
    3131
    3232#define SCSIPRINT_H_CVSID "$Id: scsiprint.h 4120 2015-08-27 16:12:21Z chrfranke $\n"
     33/*Sandisk-WDC vendor specific pages */
     34#define WDC_SMART_DATA_LOG_PAGE_CODE                0x3e
     35#define WDC_SMART_DATA_LOG_SUBPAGE_CODE             0x3f
     36#define WDC_SCSI_VPD_ASCII_INFO_PAGE                0x3
     37#define WDC_SCSI_SMART_DRIVE_INFO_PAGE              0xE9
     38#define WDC_SCSI_MODEL_NO_OFFSET                    0xA0
     39
     40/*Sandisk-WDC smart parameters info OEMs specific */
     41#define WDC_SMART_DATA_PARAMETER_START_OFFSET       16
     42#define WDC_SMART_DATA_PARAMETER_LENGTH             4
     43#define WDC_SMART_DATA_PARAMETER_LENGTH_GENERIC     40
     44#define WDC_SMART_DATA_BUFFER_ADDRESS_OFFSET        3
     45#define WDC_SMART_DATA_THRESHOLD_OFFSET_ULTRASTAR   16
     46#define WDC_SMART_DATA_CURRENT_OFFSET_ULTRASTAR     8
     47#define WDC_SMART_DATA_WORST_OFFSET_ULTRASTAR       12
     48#define WDC_SMART_DATA_THRESHOLD_OFFSET_DELL        13
     49#define WDC_SMART_DATA_CURRENT_OFFSET_DELL          5
     50#define WDC_SMART_DATA_WORST_OFFSET_DELL            9
     51#define WDC_SMART_DATA_THRESHOLD_OFFSET_HP          0
     52#define WDC_SMART_DATA_CURRENT_OFFSET_HP            4
     53#define WDC_SMART_DATA_WORST_OFFSET_HP              0
     54#define WDC_SMART_DATA_THRESHOLD_OFFSET_GENERIC     16
     55#define WDC_SMART_DATA_CURRENT_OFFSET_GENERIC       20
     56#define WDC_SMART_DATA_WORST_OFFSET_GENERIC         24
     57#define WDC_CUSTOMER_NAME_OFFSET                    0xCA
     58#define WDC_PARAM_ID_POWER_ON_TIME                  3
     59#define WDC_PARAM_ID_POWER_CYCLE_COUNT              4
     60#define WDC_PARAM_ID_SMART_TEMP_TIMESTAMPS          5
     61#define WDC_PARAM_ID_GEN_HW_FAIL                    16
     62#define WDC_PARAM_ID_EXCESSIVE_REASSIGNS            20
     63#define WDC_PARAM_ID_START_UNIT_TIME                22
     64#define WDC_PARAM_ID_EXCESSIVE_RD_ERR_RATE          50
     65#define WDC_PARAM_ID_EXCESSIVE_WR_ERR_RATE          66
     66#define WDC_PARAM_ID_ENDURANCE_LIMIT_MET            115
     67#define WDC_NUMBER_SCSI_SMART_ATTRIBUTES_MAX        42
    3368
    3469// Options for scsiPrintMain
    3570struct scsi_print_options
     
    77112    { }
    78113};
    79114
     115struct scsi_smart_attribute {
     116    uint16_t id;
     117    UINT32 current;
     118    UINT32 threshold;
     119    UINT32 worst;
     120    UINT8 numberofAttributes;
     121};
     122
     123struct scsi_smart_settings{
     124    UINT8 logPageCode;
     125    UINT8 logSubpageCode;
     126    UINT8 parameterStartOffset;
     127    UINT8 thresholdValueOffset;
     128    UINT8 currentValueOffset;
     129    UINT8 worstValueOffset;
     130    UINT8 parameterValueLength;
     131    UINT8 bufferAddressOffset;
     132    UINT8 parameterIdOffset;
     133    char * customerName;
     134};
     135
     136struct scsi_device_info {
     137    char  model[16 + 1];
     138    char  fw_rev[4 + 1];
     139    uint64_t  WWNLun;
     140};
    80141int scsiPrintMain(scsi_device * device, const scsi_print_options & options);
    81142
    82143#endif