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

📄 scsicmds.cpp

📁 硬盘各项性能的测试,如温度容量版本健康度型号
💻 CPP
📖 第 1 页 / 共 5 页
字号:
int scsiModeSense(int device, int pagenum, int subpagenum, int pc,                  UINT8 *pBuf, int bufLen){    struct scsi_cmnd_io io_hdr;    struct scsi_sense_disect sinfo;    UINT8 cdb[6];    UINT8 sense[32];    int status;    if ((bufLen < 0) || (bufLen > 255))        return -EINVAL;    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] = MODE_SENSE;    cdb[2] = (pc << 6) | (pagenum & 0x3f);    cdb[3] = subpagenum;    cdb[4] = bufLen;    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);    status = scsiSimpleSenseFilter(&sinfo);    if (SIMPLE_ERR_TRY_AGAIN == status) {        status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);        if (0 != status)            return status;        scsi_do_sense_disect(&io_hdr, &sinfo);        status = scsiSimpleSenseFilter(&sinfo);    }    if ((0 == status) && (ALL_MODE_PAGES != pagenum)) {        int offset;        offset = scsiModePageOffset(pBuf, bufLen, 0);        if (offset < 0)            return SIMPLE_ERR_BAD_RESP;        else if (pagenum != (pBuf[offset] & 0x3f))            return SIMPLE_ERR_BAD_RESP;    }    return status;}/* Sends a 6 byte MODE SELECT command. Assumes given pBuf is the response * from a corresponding 6 byte MODE SENSE command. Such a response should * have a 4 byte header followed by 0 or more 8 byte block descriptors * (normally 1) and then 1 mode page. Returns 0 if ok, 1 if NOT READY, * 2 if command not supported (then MODE SELECT(10) may be supported),  * 3 if field in command not supported, 4 if bad parameter to command * or returns negated errno. SPC-3 sections 6.7 and 7.4 (rev 22a) */int scsiModeSelect(int device, int sp, UINT8 *pBuf, int bufLen){    struct scsi_cmnd_io io_hdr;    struct scsi_sense_disect sinfo;    UINT8 cdb[6];    UINT8 sense[32];    int status, pg_offset, pg_len, hdr_plus_1_pg;    pg_offset = 4 + pBuf[3];    if (pg_offset + 2 >= bufLen)        return -EINVAL;    pg_len = pBuf[pg_offset + 1] + 2;    hdr_plus_1_pg = pg_offset + pg_len;    if (hdr_plus_1_pg > bufLen)        return -EINVAL;    pBuf[0] = 0;    /* Length of returned mode sense data reserved for SELECT */    pBuf[pg_offset] &= 0x7f;    /* Mask out PS bit from byte 0 of page data */    memset(&io_hdr, 0, sizeof(io_hdr));    memset(cdb, 0, sizeof(cdb));    io_hdr.dxfer_dir = DXFER_TO_DEVICE;    io_hdr.dxfer_len = hdr_plus_1_pg;    io_hdr.dxferp = pBuf;    cdb[0] = MODE_SELECT;    cdb[1] = 0x10 | (sp & 1);      /* set PF (page format) bit always */    cdb[4] = hdr_plus_1_pg; /* make sure only one page sent */    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);}/* MODE SENSE (10 byte). Returns 0 if ok, 1 if NOT READY, 2 if command  * not supported (then MODE SENSE(6) might be supported), 3 if field in * command not supported or returns negated errno.   * SPC-3 sections 6.10 and 7.4 (rev 22a) [mode subpage==0] */int scsiModeSense10(int device, int pagenum, int subpagenum, int pc,                    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] = MODE_SENSE_10;    cdb[2] = (pc << 6) | (pagenum & 0x3f);    cdb[3] = subpagenum;    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);    status = scsiSimpleSenseFilter(&sinfo);    if (SIMPLE_ERR_TRY_AGAIN == status) {        status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);        if (0 != status)            return status;        scsi_do_sense_disect(&io_hdr, &sinfo);        status = scsiSimpleSenseFilter(&sinfo);    }    if ((0 == status) && (ALL_MODE_PAGES != pagenum)) {        int offset;        offset = scsiModePageOffset(pBuf, bufLen, 1);        if (offset < 0)            return SIMPLE_ERR_BAD_RESP;        else if (pagenum != (pBuf[offset] & 0x3f))            return SIMPLE_ERR_BAD_RESP;    }    return status;}/* Sends a 10 byte MODE SELECT command. Assumes given pBuf is the response * from a corresponding 10 byte MODE SENSE command. Such a response should * have a 8 byte header followed by 0 or more 8 byte block descriptors * (normally 1) and then 1 mode page. Returns 0 if ok, 1 NOT REAFY, 2 if  * command not supported (then MODE SELECT(6) may be supported), 3 if field * in command not supported, 4 if bad parameter to command or returns * negated errno. SPC-3 sections 6.8 and 7.4 (rev 22a) */int scsiModeSelect10(int device, int sp, UINT8 *pBuf, int bufLen){    struct scsi_cmnd_io io_hdr;    struct scsi_sense_disect sinfo;    UINT8 cdb[10];    UINT8 sense[32];    int status, pg_offset, pg_len, hdr_plus_1_pg;    pg_offset = 8 + (pBuf[6] << 8) + pBuf[7];    if (pg_offset + 2 >= bufLen)        return -EINVAL;    pg_len = pBuf[pg_offset + 1] + 2;    hdr_plus_1_pg = pg_offset + pg_len;    if (hdr_plus_1_pg > bufLen)        return -EINVAL;    pBuf[0] = 0;        pBuf[1] = 0; /* Length of returned mode sense data reserved for SELECT */    pBuf[pg_offset] &= 0x7f;    /* Mask out PS bit from byte 0 of page data */    memset(&io_hdr, 0, sizeof(io_hdr));    memset(cdb, 0, sizeof(cdb));    io_hdr.dxfer_dir = DXFER_TO_DEVICE;    io_hdr.dxfer_len = hdr_plus_1_pg;    io_hdr.dxferp = pBuf;    cdb[0] = MODE_SELECT_10;    cdb[1] = 0x10 | (sp & 1);      /* set PF (page format) bit always */    cdb[8] = hdr_plus_1_pg; /* make sure only one page sent */    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);}/* Standard INQUIRY returns 0 for ok, anything else is a major problem. * bufLen should be 36 for unsafe devices (like USB mass storage stuff) * otherwise they can lock up! SPC-3 sections 6.4 and 7.6 (rev 22a) */int scsiStdInquiry(int device, UINT8 *pBuf, int bufLen){    struct scsi_sense_disect sinfo;    struct scsi_cmnd_io io_hdr;    UINT8 cdb[6];    UINT8 sense[32];    int status;    if ((bufLen < 0) || (bufLen > 255))        return -EINVAL;    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] = INQUIRY;    cdb[4] = bufLen;    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);}/* INQUIRY to fetch Vital Page Data.  Returns 0 if ok, 1 if NOT READY * (unlikely), 2 if command not supported, 3 if field in command not  * supported, 5 if response indicates that EVPD bit ignored or returns * negated errno. SPC-3 section 6.4 and 7.6 (rev 22a) */int scsiInquiryVpd(int device, int vpd_page, UINT8 *pBuf, int bufLen){    struct scsi_cmnd_io io_hdr;    struct scsi_sense_disect sinfo;    UINT8 cdb[6];    UINT8 sense[32];    int status, res;    if ((bufLen < 0) || (bufLen > 255))        return -EINVAL;    memset(&io_hdr, 0, sizeof(io_hdr));    memset(cdb, 0, sizeof(cdb));    if (bufLen > 1)        pBuf[1] = 0x0;    io_hdr.dxfer_dir = DXFER_FROM_DEVICE;    io_hdr.dxfer_len = bufLen;    io_hdr.dxferp = pBuf;    cdb[0] = INQUIRY;    cdb[1] = 0x1;       /* set EVPD bit (enable Vital Product Data) */    cdb[2] = vpd_page;    cdb[4] = bufLen;    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);    if ((res = scsiSimpleSenseFilter(&sinfo)))        return res;    /* Guard against devices that ignore EVPD bit and do standard INQUIRY */    if (bufLen > 1) {        if (vpd_page == pBuf[1]) {            if ((0x80 == vpd_page) && (bufLen > 2) && (0x0 != pBuf[2]))                return SIMPLE_ERR_BAD_RESP;        } else            return SIMPLE_ERR_BAD_RESP;    }    return 0;}/* REQUEST SENSE command. Returns 0 if ok, anything else major problem. * SPC-3 section 6.27 (rev 22a) */int scsiRequestSense(int device, struct scsi_sense_disect * sense_info){    struct scsi_cmnd_io io_hdr;    UINT8 cdb[6];    UINT8 sense[32];    UINT8 buff[18];    int status, len;    UINT8 ecode;    memset(&io_hdr, 0, sizeof(io_hdr));    memset(cdb, 0, sizeof(cdb));    io_hdr.dxfer_dir = DXFER_FROM_DEVICE;    io_hdr.dxfer_len = sizeof(buff);    io_hdr.dxferp = buff;    cdb[0] = REQUEST_SENSE;    cdb[4] = sizeof(buff);    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) && (sense_info)) {        ecode = buff[0] & 0x7f;        sense_info->error_code = ecode;        sense_info->sense_key = buff[2] & 0xf;        sense_info->asc = 0;        sense_info->ascq = 0;        if ((0x70 == ecode) || (0x71 == ecode)) {            len = buff[7] + 8;            if (len > 13) {                sense_info->asc = buff[12];                sense_info->ascq = buff[13];            }        }    }    return status;}/* SEND 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.28 (rev 22a) */int scsiSendDiagnostic(int device, int functioncode, 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 = bufLen ? DXFER_TO_DEVICE: DXFER_NONE;    io_hdr.dxfer_len = bufLen;    io_hdr.dxferp = pBuf;    cdb[0] = SEND_DIAGNOSTIC;    if (SCSI_DIAG_DEF_SELF_TEST == functioncode)        cdb[1] = 0x4;  /* SelfTest bit */    else if (SCSI_DIAG_NO_SELF_TEST != functioncode)        cdb[1] = (functioncode & 0x7) << 5; /* SelfTest _code_ */    else   /* SCSI_DIAG_NO_SELF_TEST == functioncode */        cdb[1] = 0x10;  /* PF bit */    cdb[3] = (bufLen >> 8) & 0xff;    cdb[4] = bufLen & 0xff;    io_hdr.cmnd = cdb;    io_hdr.cmnd_len = sizeof(cdb);

⌨️ 快捷键说明

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