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

📄 scsicmds.cpp

📁 硬盘各项性能的测试,如温度容量版本健康度型号
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    io_hdr.sensep = sense;    io_hdr.max_sense_len = sizeof(sense);    /* worst case is an extended foreground self test on a big disk */    io_hdr.timeout = SCSI_TIMEOUT_SELF_TEST;        status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);    if (0 != status)        return status;    scsi_do_sense_disect(&io_hdr, &sinfo);    return scsiSimpleSenseFilter(&sinfo);}/* RECEIVE DIAGNOSTIC command. Returns 0 if ok, 1 if NOT READY, 2 if * command not supported, 3 if field in command not supported or returns * negated errno. SPC-3 section 6.18 (rev 22a) */int scsiReceiveDiagnostic(int device, int pcv, int pagenum, UINT8 *pBuf,                       int bufLen){    struct scsi_cmnd_io io_hdr;    struct scsi_sense_disect sinfo;    UINT8 cdb[6];    UINT8 sense[32];    int status;    memset(&io_hdr, 0, sizeof(io_hdr));    memset(cdb, 0, sizeof(cdb));    io_hdr.dxfer_dir = DXFER_FROM_DEVICE;    io_hdr.dxfer_len = bufLen;    io_hdr.dxferp = pBuf;    cdb[0] = RECEIVE_DIAGNOSTIC;    cdb[1] = pcv;    cdb[2] = pagenum;    cdb[3] = (bufLen >> 8) & 0xff;    cdb[4] = bufLen & 0xff;    io_hdr.cmnd = cdb;    io_hdr.cmnd_len = sizeof(cdb);    io_hdr.sensep = sense;    io_hdr.max_sense_len = sizeof(sense);    io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;    status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);    if (0 != status)        return status;    scsi_do_sense_disect(&io_hdr, &sinfo);    return scsiSimpleSenseFilter(&sinfo);}/* TEST UNIT READY command. SPC-3 section 6.33 (rev 22a) */static int _testunitready(int device, struct scsi_sense_disect * sinfo){    struct scsi_cmnd_io io_hdr;    UINT8 cdb[6];    UINT8 sense[32];    int status;    memset(&io_hdr, 0, sizeof(io_hdr));    memset(cdb, 0, sizeof(cdb));    io_hdr.dxfer_dir = DXFER_NONE;    io_hdr.dxfer_len = 0;    io_hdr.dxferp = NULL;    cdb[0] = TEST_UNIT_READY;    io_hdr.cmnd = cdb;    io_hdr.cmnd_len = sizeof(cdb);    io_hdr.sensep = sense;    io_hdr.max_sense_len = sizeof(sense);    io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;    status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);    if (0 != status)        return status;    scsi_do_sense_disect(&io_hdr, sinfo);    return 0;}/* Returns 0 for device responds and media ready, 1 for device responds and   media not ready, or returns a negated errno value */int scsiTestUnitReady(int device){    struct scsi_sense_disect sinfo;    int status;    status = _testunitready(device, &sinfo);    if (0 != status)        return status;    status = scsiSimpleSenseFilter(&sinfo);    if (SIMPLE_ERR_TRY_AGAIN == status) {        /* power on reset, media changed, ok ... try again */        status = _testunitready(device, &sinfo);                if (0 != status)            return status;        status = scsiSimpleSenseFilter(&sinfo);    }    return status;}/* READ DEFECT (10) command. Returns 0 if ok, 1 if NOT READY, 2 if * command not supported, 3 if field in command not supported or returns * negated errno. SBC-2 section 5.12 (rev 16) */int scsiReadDefect10(int device, int req_plist, int req_glist, int dl_format,                     UINT8 *pBuf, int bufLen){    struct scsi_cmnd_io io_hdr;    struct scsi_sense_disect sinfo;    UINT8 cdb[10];    UINT8 sense[32];    int status;    memset(&io_hdr, 0, sizeof(io_hdr));    memset(cdb, 0, sizeof(cdb));    io_hdr.dxfer_dir = DXFER_FROM_DEVICE;    io_hdr.dxfer_len = bufLen;    io_hdr.dxferp = pBuf;    cdb[0] = READ_DEFECT_10;    cdb[2] = (unsigned char)(((req_plist << 4) & 0x10) |               ((req_glist << 3) & 0x8) | (dl_format & 0x7));    cdb[7] = (bufLen >> 8) & 0xff;    cdb[8] = bufLen & 0xff;    io_hdr.cmnd = cdb;    io_hdr.cmnd_len = sizeof(cdb);    io_hdr.sensep = sense;    io_hdr.max_sense_len = sizeof(sense);    io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;    status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);    if (0 != status)        return status;    scsi_do_sense_disect(&io_hdr, &sinfo);    return scsiSimpleSenseFilter(&sinfo);}/* Offset into mode sense (6 or 10 byte) response that actual mode page * starts at (relative to resp[0]). Returns -1 if problem */int scsiModePageOffset(const UINT8 * resp, int len, int modese_len){    int resp_len, bd_len;    int offset = -1;    if (resp) {        if (10 == modese_len) {            resp_len = (resp[0] << 8) + resp[1] + 2;            bd_len = (resp[6] << 8) + resp[7];            offset = bd_len + 8;        } else {            resp_len = resp[0] + 1;            bd_len = resp[3];            offset = bd_len + 4;        }        if ((offset + 2) > len) {            pout("scsiModePageOffset: raw_curr too small, offset=%d "                 "resp_len=%d bd_len=%d\n", offset, resp_len, bd_len);            offset = -1;        } else if ((offset + 2) > resp_len) {             if ((resp_len > 2) || con->reportscsiioctl)                pout("scsiModePageOffset: response length too short, "                     "resp_len=%d offset=%d bd_len=%d\n", resp_len,                     offset, bd_len);            offset = -1;        }    }    return offset;}/* IEC mode page byte 2 bit masks */#define DEXCPT_ENABLE   0x08#define EWASC_ENABLE    0x10#define DEXCPT_DISABLE  0xf7#define EWASC_DISABLE   0xef#define TEST_DISABLE    0xfb/* Fetches the Informational Exceptions Control mode page. First tries * the 6 byte MODE SENSE command and if that fails with an illegal opcode * tries a 10 byte MODE SENSE command. Returns 0 if successful, a positive * number if a known error (see  SIMPLE_ERR_ ...) or a negative errno * value. */int scsiFetchIECmpage(int device, struct scsi_iec_mode_page *iecp, int modese_len){    int err = 0;    memset(iecp, 0, sizeof(*iecp));    iecp->modese_len = modese_len;    iecp->requestedCurrent = 1;    if (iecp->modese_len <= 6) {        if ((err = scsiModeSense(device, INFORMATIONAL_EXCEPTIONS_CONTROL_PAGE,                                 0, MPAGE_CONTROL_CURRENT,                                 iecp->raw_curr, sizeof(iecp->raw_curr)))) {            if (SIMPLE_ERR_BAD_OPCODE == err)                iecp->modese_len = 10;            else {                iecp->modese_len = 0;                return err;            }        } else if (0 == iecp->modese_len)            iecp->modese_len = 6;    }    if (10 == iecp->modese_len) {        err = scsiModeSense10(device, INFORMATIONAL_EXCEPTIONS_CONTROL_PAGE,                              0, MPAGE_CONTROL_CURRENT,                              iecp->raw_curr, sizeof(iecp->raw_curr));        if (err) {            iecp->modese_len = 0;            return err;        }    }     iecp->gotCurrent = 1;    iecp->requestedChangeable = 1;    if (10 == iecp->modese_len)        err = scsiModeSense10(device, INFORMATIONAL_EXCEPTIONS_CONTROL_PAGE,                              0, MPAGE_CONTROL_CHANGEABLE,                              iecp->raw_chg, sizeof(iecp->raw_chg));    else if (6 == iecp->modese_len)        err = scsiModeSense(device, INFORMATIONAL_EXCEPTIONS_CONTROL_PAGE,                             0, MPAGE_CONTROL_CHANGEABLE,                             iecp->raw_chg, sizeof(iecp->raw_chg));    if (err)        return err;    iecp->gotChangeable = 1;    return 0;}int scsi_IsExceptionControlEnabled(const struct scsi_iec_mode_page *iecp){    int offset;    if (iecp && iecp->gotCurrent) {        offset = scsiModePageOffset(iecp->raw_curr, sizeof(iecp->raw_curr),                                    iecp->modese_len);        if (offset >= 0)            return (iecp->raw_curr[offset + 2] & DEXCPT_ENABLE) ? 0 : 1;        else            return 0;    } else        return 0;}int scsi_IsWarningEnabled(const struct scsi_iec_mode_page *iecp){    int offset;    if (iecp && iecp->gotCurrent) {        offset = scsiModePageOffset(iecp->raw_curr, sizeof(iecp->raw_curr),                                    iecp->modese_len);        if (offset >= 0)            return (iecp->raw_curr[offset + 2] & EWASC_ENABLE) ? 1 : 0;        else            return 0;    } else        return 0;}/* set EWASC and clear PERF, EBF, DEXCPT TEST and LOGERR */#define SCSI_IEC_MP_BYTE2_ENABLED 0x10 #define SCSI_IEC_MP_BYTE2_TEST_MASK 0x4/* exception/warning via an unrequested REQUEST SENSE command */#define SCSI_IEC_MP_MRIE 6      #define SCSI_IEC_MP_INTERVAL_T 0#define SCSI_IEC_MP_REPORT_COUNT 1/* Try to set (or clear) both Exception Control and Warning in the IE * mode page subject to the "changeable" mask. The object pointed to * by iecp is (possibly) inaccurate after this call, therefore * scsiFetchIECmpage() should be called again if the IEC mode page * is to be re-examined. * When -r ioctl is invoked 3 or more time on 'smartctl -s on ...' * then set the TEST bit (causes asc,ascq pair of 0x5d,0xff). */int scsiSetExceptionControlAndWarning(int device, int enabled,                                      const struct scsi_iec_mode_page *iecp){    int k, offset, resp_len;    int err = 0;    UINT8 rout[SCSI_IECMP_RAW_LEN];    int sp, eCEnabled, wEnabled;    if ((! iecp) || (! iecp->gotCurrent))        return -EINVAL;    offset = scsiModePageOffset(iecp->raw_curr, sizeof(iecp->raw_curr),                                iecp->modese_len);    if (offset < 0)        return -EINVAL;    memcpy(rout, iecp->raw_curr, SCSI_IECMP_RAW_LEN);    if (10 == iecp->modese_len) {        resp_len = (rout[0] << 8) + rout[1] + 2;        rout[3] &= 0xef;    /* for disks mask out DPOFUA bit */    } else {        resp_len = rout[0] + 1;        rout[2] &= 0xef;    /* for disks mask out DPOFUA bit */    }    sp = (rout[offset] & 0x80) ? 1 : 0; /* PS bit becomes 'SELECT's SP bit */    if (enabled) {        rout[offset + 2] = SCSI_IEC_MP_BYTE2_ENABLED;        if (con->reportscsiioctl > 2)            rout[offset + 2] |= SCSI_IEC_MP_BYTE2_TEST_MASK;        rout[offset + 3] = SCSI_IEC_MP_MRIE;        rout[offset + 4] = (SCSI_IEC_MP_INTERVAL_T >> 24) & 0xff;        rout[offset + 5] = (SCSI_IEC_MP_INTERVAL_T >> 16) & 0xff;        rout[offset + 6] = (SCSI_IEC_MP_INTERVAL_T >> 8) & 0xff;        rout[offset + 7] = SCSI_IEC_MP_INTERVAL_T & 0xff;        rout[offset + 8] = (SCSI_IEC_MP_REPORT_COUNT >> 24) & 0xff;        rout[offset + 9] = (SCSI_IEC_MP_REPORT_COUNT >> 16) & 0xff;        rout[offset + 10] = (SCSI_IEC_MP_REPORT_COUNT >> 8) & 0xff;        rout[offset + 11] = SCSI_IEC_MP_REPORT_COUNT & 0xff;        if (iecp->gotChangeable) {            UINT8 chg2 = iecp->raw_chg[offset + 2];            rout[offset + 2] = chg2 ? (rout[offset + 2] & chg2) :                                      iecp->raw_curr[offset + 2];            for (k = 3; k < 12; ++k) {                if (0 == iecp->raw_chg[offset + k])                    rout[offset + k] = iecp->raw_curr[offset + k];            }        }        if (0 == memcmp(&rout[offset + 2], &iecp->raw_chg[offset + 2], 10)) {            if (con->reportscsiioctl > 0)                pout("scsiSetExceptionControlAndWarning: already enabled\n");            return 0;        }    } else { /* disabling Exception Control and (temperature) Warnings */        eCEnabled = (rout[offset + 2] & DEXCPT_ENABLE) ? 0 : 1;        wEnabled = (rout[offset + 2] & EWASC_ENABLE) ? 1 : 0;        if ((! eCEnabled) && (! wEnabled)) {            if (con->reportscsiioctl > 0)                pout("scsiSetExceptionControlAndWarning: already disabled\n");            return 0;   /* nothing to do, leave other setting alone */        }        if (wEnabled)             rout[offset + 2] &= EWASC_DISABLE;        if (eCEnabled) {            if (iecp->gotChangeable &&                 (iecp->raw_chg[offset + 2] & DEXCPT_ENABLE))                rout[offset + 2] |= DEXCPT_ENABLE;                rout[offset + 2] &= TEST_DISABLE;/* clear TEST bit for spec */        }    }    if (10 == iecp->modese_len)        err = scsiModeSelect10(device, sp, rout, resp_len);    else if (6 == iecp->modese_len)        err = scsiModeSelect(device, sp, rout, resp_len);    return err;}int scsiGetTemp(int device, UINT8 *currenttemp, UINT8 *triptemp){    UINT8 tBuf[252];    int err;

⌨️ 快捷键说明

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