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

📄 scsiprint.cpp

📁 硬盘各项性能的测试,如温度容量版本健康度型号
💻 CPP
📖 第 1 页 / 共 4 页
字号:
            break;        // only print header if needed        if (noheader) {            pout("\nSMART Self-test log\n");            pout("Num  Test              Status                 segment  "                   "LifeTime  LBA_first_err [SK ASC ASQ]\n");            pout("     Description                              number   "                   "(hours)\n");            noheader=0;        }        // print parameter code (test number) & self-test code text        pout("#%2d  %s", (ucp[0] << 8) | ucp[1],             self_test_code[(ucp[4] >> 5) & 0x7]);        // check the self-test result nibble, using the self-test results        // field table from T10/1416-D (SPC-3) Rev. 23, section 7.2.10:        switch ((res = ucp[4] & 0xf)) {        case 0x3:            // an unknown error occurred while the device server            // was processing the self-test and the device server            // was unable to complete the self-test            retval|=FAILSMART;            break;        case 0x4:            // the self-test completed with a failure in a test            // segment, and the test segment that failed is not            // known            retval|=FAILLOG;            break;        case 0x5:            // the first segment of the self-test failed            retval|=FAILLOG;            break;        case 0x6:            // the second segment of the self-test failed            retval|=FAILLOG;            break;        case 0x7:            // another segment of the self-test failed and which            // test is indicated by the contents of the SELF-TEST            // NUMBER field            retval|=FAILLOG;            break;        default:            break;        }        pout("  %s", self_test_result[res]);        // self-test number identifies test that failed and consists        // of either the number of the segment that failed during        // the test, or the number of the test that failed and the        // number of the segment in which the test was run, using a        // vendor-specific method of putting both numbers into a        // single byte.        if (ucp[5])            pout(" %3d",  (int)ucp[5]);        else            pout("   -");        // print time that the self-test was completed        if (n==0 && res==0xf)        // self-test in progress            pout("     NOW");        else               pout("   %5d", n);                  // construct 8-byte integer address of first failure        for (i = 0; i < 8; i++) {            ull <<= 8;            ull |= ucp[i+8];        }        // print Address of First Failure, if sensible        if ((~(uint64_t)0 != ull) && (res > 0) && (res < 0xf)) {            char buff[32];            // was hex but change to decimal to conform with ATA            snprintf(buff, sizeof(buff), "%"PRIu64, ull);            // snprintf(buff, sizeof(buff), "0x%"PRIx64, ull);            pout("%18s", buff);        } else            pout("                 -");        // if sense key nonzero, then print it, along with        // additional sense code and additional sense code qualifier        if (ucp[16] & 0xf)            pout(" [0x%x 0x%x 0x%x]\n", ucp[16] & 0xf, ucp[17], ucp[18]);        else            pout(" [-   -    -]\n");    }    // if header never printed, then there was no output    if (noheader)        pout("No self-tests have been logged\n");    else        pout("\n");    if ((0 == scsiFetchExtendedSelfTestTime(device, &durationSec,                         modese_len)) && (durationSec > 0)) {        pout("Long (extended) Self Test duration: %d seconds "             "[%.1f minutes]\n", durationSec, durationSec / 60.0);    }    return retval;}static const char * bms_status[] = {    "no scans active",    "scan is active",    "pre-scan is active",    "halted due to fatal error",    "halted due to a vendor specific pattern of error",    "halted due to medium formatted without P-List",    "halted - vendor specific cause",    "halted due to temperature out of range",    "halted until BM interval timer expires", /* 8 */};static const char * reassign_status[] = {    "No reassignment needed",    "Require Reassign or Write command",    "Successfully reassigned",    "Reserved [0x3]",    "Failed",    "Recovered via rewrite in-place",    "Reassigned by app, has valid data",    "Reassigned by app, has no valid data",    "Unsuccessfully reassigned by app", /* 8 */};// See SCSI Block Commands - 3 (SBC-3) rev 6 (draft) section 6.2.2 .// Returns 0 if ok else FAIL* bitmask. Note can have a status entry// and up to 2048 events (although would hope to have less). May set// FAILLOG if serious errors detected (in the future).static int scsiPrintBackgroundResults(int device){    int num, j, m, err, pc, pl, truncated;    int noheader = 1;    int firstresult = 1;    int retval = 0;    UINT8 * ucp;    if ((err = scsiLogSense(device, BACKGROUND_RESULTS_LPAGE, 0, gBuf,                            LOG_RESP_LONG_LEN, 0))) {        PRINT_ON(con);        pout("scsiPrintBackgroundResults Failed [%s]\n", scsiErrString(err));        PRINT_OFF(con);        return FAILSMART;    }    if ((gBuf[0] & 0x3f) != BACKGROUND_RESULTS_LPAGE) {        PRINT_ON(con);        pout("Background scan results Log Sense Failed, page mismatch\n");        PRINT_OFF(con);        return FAILSMART;    }    // compute page length    num = (gBuf[2] << 8) + gBuf[3] + 4;    if (num < 20) {        PRINT_ON(con);        pout("Background scan results Log Sense length is %d, no scan "             "status\n", num);        PRINT_OFF(con);        return FAILSMART;    }    truncated = (num > LOG_RESP_LONG_LEN) ? num : 0;    if (truncated)        num = LOG_RESP_LONG_LEN;    ucp = gBuf + 4;    num -= 4;    while (num > 3) {        pc = (ucp[0] << 8) | ucp[1];        // pcb = ucp[2];        pl = ucp[3] + 4;        switch (pc) {        case 0:            if (noheader) {                noheader = 0;                pout("\nBackground scan results log\n");            }            pout("  Status: ");            if ((pl < 16) || (num < 16)) {                pout("\n");                break;            }            j = ucp[9];            if (j < (int)(sizeof(bms_status) / sizeof(bms_status[0])))                pout("%s\n", bms_status[j]);            else                pout("unknown [0x%x] background scan status value\n", j);            j = (ucp[4] << 24) + (ucp[5] << 16) + (ucp[6] << 8) + ucp[7];            pout("    Accumulated power on time, hours:minutes %d:%02d "                 "[%d minutes]\n", (j / 60), (j % 60), j);            pout("    Number of background scans performed: %d,  ",                 (ucp[10] << 8) + ucp[11]);            pout("scan progress: %.2f%%\n",                 (double)((ucp[12] << 8) + ucp[13]) * 100.0 / 65536.0);            break;        default:            if (noheader) {                noheader = 0;                pout("\nBackground scan results log\n");            }            if (firstresult) {                firstresult = 0;                pout("\n   #  when        lba(hex)    [sk,asc,ascq]    "                     "reassign_status\n");            }            pout(" %3d ", pc);            if ((pl < 24) || (num < 24)) {                if (pl < 24)                    pout("parameter length >= 24 expected, got %d\n", pl);                break;            }            j = (ucp[4] << 24) + (ucp[5] << 16) + (ucp[6] << 8) + ucp[7];            pout("%4d:%02d  ", (j / 60), (j % 60));            for (m = 0; m < 8; ++m)                pout("%02x", ucp[16 + m]);            pout("  [%x,%x,%x]   ", ucp[8] & 0xf, ucp[9], ucp[10]);            j = (ucp[8] >> 4) & 0xf;            if (j <                (int)(sizeof(reassign_status) / sizeof(reassign_status[0])))                pout("%s\n", reassign_status[j]);            else                pout("Reassign status: reserved [0x%x]\n", j);            break;        }        num -= pl;        ucp += pl;    }    if (truncated)        pout(" >>>> log truncated, fetched %d of %d available "             "bytes\n", LOG_RESP_LONG_LEN, truncated);    return retval;}static const char * peripheral_dt_arr[] = {        "disk",        "tape",        "printer",        "processor",        "optical disk(4)",        "CD/DVD",        "scanner",        "optical disk(7)",        "medium changer",        "communications",        "graphics(10)",        "graphics(11)",        "storage array",        "enclosure",        "simplified disk",        "optical card reader"};static const char * transport_proto_arr[] = {        "Fibre channel (FCP-2)",        "Parallel SCSI (SPI-4)",        "SSA",        "IEEE 1394 (SBP-2)",        "RDMA (SRP)",        "iSCSI",        "SAS",        "ADT",        "0x8",        "0x9",        "0xa",        "0xb",        "0xc",        "0xd",        "0xe",        "0xf"};/* Returns 0 on success, 1 on general error and 2 for early, clean exit */static int scsiGetDriveInfo(int device, UINT8 * peripheral_type, int all){    char manufacturer[9];    char product[17];    char revision[5];    char timedatetz[DATEANDEPOCHLEN];    struct scsi_iec_mode_page iec;    int err, iec_err, len, req_len, avail_len, val;    int is_tape = 0;    int peri_dt = 0;    int returnval=0;            memset(gBuf, 0, 96);    req_len = 36;    if ((err = scsiStdInquiry(device, gBuf, req_len))) {        PRINT_ON(con);        pout("Standard Inquiry (36 bytes) failed [%s]\n", scsiErrString(err));        pout("Retrying with a 64 byte Standard Inquiry\n");        PRINT_OFF(con);        /* Marvell controllers fail on a 36 bytes StdInquiry, but 64 suffices */        req_len = 64;        if ((err = scsiStdInquiry(device, gBuf, req_len))) {            PRINT_ON(con);            pout("Standard Inquiry (64 bytes) failed [%s]\n",                 scsiErrString(err));            PRINT_OFF(con);            return 1;        }    }    avail_len = gBuf[4] + 5;    len = (avail_len < req_len) ? avail_len : req_len;    peri_dt = gBuf[0] & 0x1f;    if (peripheral_type)        *peripheral_type = peri_dt;    if (len < 36) {        PRINT_ON(con);        pout("Short INQUIRY response, skip product id\n");        PRINT_OFF(con);        return 1;    }    memset(manufacturer, 0, sizeof(manufacturer));    strncpy(manufacturer, (char *)&gBuf[8], 8);     memset(product, 0, sizeof(product));    strncpy(product, (char *)&gBuf[16], 16);            memset(revision, 0, sizeof(revision));    strncpy(revision, (char *)&gBuf[32], 4);    if (all && (0 != strncmp(manufacturer, "ATA", 3)))        pout("Device: %s %s Version: %s\n", manufacturer, product, revision);    if (0 == strncmp(manufacturer, "3ware", 5) || 0 == strncmp(manufacturer, "AMCC", 4) ) {#if defined(_WIN32) || defined(__CYGWIN__)        pout("please try changing device to /dev/hdX,N\n");#else        pout("please try adding '-d 3ware,N'\n");        pout("you may also need to change device to /dev/twaN or /dev/tweN\n");#endif        return 2;    } else if ((len >= 42) &&	       (0 == strncmp((const char *)(gBuf + 36), "MVSATA", 6))) {        pout("please try '-d marvell'\n");        return 2;    } else if ((0 == con->controller_explicit) &&	       (0 == strncmp(manufacturer, "ATA     ", 8)) &&               has_sat_pass_through(device, 0)) {        con->controller_type = CONTROLLER_SAT;        if (con->reportscsiioctl > 0) {            PRINT_ON(con);            pout("Detected SAT interface, switch to device type 'sat'\n");            PRINT_OFF(con);        }	return 2;    } else if ((0 == con->controller_explicit) &&               (0 == strncmp(manufacturer, "ATA", 3))) {        pout("\nProbable ATA device behind a SAT layer\n"             "Try an additional '-d ata' or '-d sat' argument.\n");

⌨️ 快捷键说明

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