Пример #1
0
/* Similar to _v2 but takes a pointer to an object (derived from) sg_pt_base.
 * That object is assumed to be constructed and have a device file descriptor
 * associated with it. Caller is responsible for lifetime of ptp. */
int
sg_ll_inquiry_pt(struct sg_pt_base * ptvp, bool evpd, int pg_op, void * resp,
                 int mx_resp_len, int timeout_secs, int * residp, bool noisy,
                 int verbose)
{
    clear_scsi_pt_obj(ptvp);
    return sg_ll_inquiry_com(ptvp, false, evpd, pg_op, resp, mx_resp_len,
                             timeout_secs, residp, noisy, verbose);

}
Пример #2
0
/* Invokes a SCSI START STOP UNIT command (SBC + MMC).
 * Return of 0 -> success,
 * various SG_LIB_CAT_* positive values or -1 -> other errors.
 * SBC-3 and MMC partially overlap on the power_condition_modifier(sbc) and
 * format_layer_number(mmc) fields. They also overlap on the noflush(sbc)
 * and fl(mmc) one bit field. This is the cause of the awkardly named
 * pc_mod__fl_num and noflush__fl arguments to this function.
 *  */
int
sg_ll_start_stop_unit_pt(struct sg_pt_base * ptvp, bool immed,
                         int pc_mod__fl_num, int power_cond, bool noflush__fl,
                         bool loej, bool start, bool noisy, int verbose)
{
    static const char * const cdb_s = "start stop unit";
    int k, res, ret, sense_cat;
    uint8_t ssuBlk[START_STOP_CMDLEN] = {START_STOP_CMD, 0, 0, 0, 0, 0};
    uint8_t sense_b[SENSE_BUFF_LEN];

    if (immed)
        ssuBlk[1] = 0x1;
    ssuBlk[3] = pc_mod__fl_num & 0xf;  /* bits 2 and 3 are reserved in MMC */
    ssuBlk[4] = ((power_cond & 0xf) << 4);
    if (noflush__fl)
        ssuBlk[4] |= 0x4;
    if (loej)
        ssuBlk[4] |= 0x2;
    if (start)
        ssuBlk[4] |= 0x1;
    if (verbose) {
        pr2ws("    %s command:", cdb_s);
        for (k = 0; k < (int)sizeof(ssuBlk); ++k)
                pr2ws(" %02x", ssuBlk[k]);
        pr2ws("\n");
    }

    clear_scsi_pt_obj(ptvp);
    set_scsi_pt_cdb(ptvp, ssuBlk, sizeof(ssuBlk));
    set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
    res = do_scsi_pt(ptvp, -1, START_PT_TIMEOUT, verbose);
    ret = sg_cmds_process_resp(ptvp, cdb_s, res, noisy, verbose, &sense_cat);
    if (-1 == ret)
        ret = sg_convert_errno(get_scsi_pt_os_err(ptvp));
    else if (-2 == ret) {
        switch (sense_cat) {
        case SG_LIB_CAT_RECOVERED:
        case SG_LIB_CAT_NO_SENSE:
            ret = 0;
            break;
        default:
            ret = sense_cat;
            break;
        }
    } else
            ret = 0;
    return ret;
}
Пример #3
0
/* Returns number of TURs performed */
static int
loop_turs(struct sg_pt_base * ptvp, struct loop_res_t * resp,
          struct opts_t * op)
{
    int k, res;
    int vb = op->verbose;
    char b[80];

    if (op->do_low) {
        int rs, n, sense_cat;
        uint8_t cdb[6];
        uint8_t sense_b[32];

        for (k = 0; k < op->do_number; ++k) {
            /* Might get Unit Attention on first invocation */
            memset(cdb, 0, sizeof(cdb));    /* TUR's cdb is 6 zeros */
            set_scsi_pt_cdb(ptvp, cdb, sizeof(cdb));
            set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
            rs = do_scsi_pt(ptvp, -1, DEF_PT_TIMEOUT, vb);
            n = sg_cmds_process_resp(ptvp, "Test unit ready", rs, (0 == k),
                                     vb, &sense_cat);
            if (-1 == n) {
                resp->ret = sg_convert_errno(get_scsi_pt_os_err(ptvp));
                return k;
            } else if (-2 == n) {
                switch (sense_cat) {
                case SG_LIB_CAT_RECOVERED:
                case SG_LIB_CAT_NO_SENSE:
                    break;
                case SG_LIB_CAT_NOT_READY:
                    ++resp->num_errs;
                    if (1 ==  op->do_number) {
                        resp->ret = sense_cat;
                        printf("device not ready\n");
                        resp->reported = true;
                    }
                    break;
                case SG_LIB_CAT_UNIT_ATTENTION:
                    ++resp->num_errs;
                    if (vb) {
                        pr2serr("Ignoring Unit attention (sense key)\n");
                        resp->reported = true;
                    }
                    break;
                default:
                    ++resp->num_errs;
                    if (1 == op->do_number) {
                        resp->ret = sense_cat;
                        sg_get_category_sense_str(sense_cat, sizeof(b), b, vb);
                        printf("%s\n", b);
                        resp->reported = true;
                        return k;
                    }
                    break;
                }
            }
            clear_scsi_pt_obj(ptvp);
        }
        return k;
    } else {
        for (k = 0; k < op->do_number; ++k) {
            /* Might get Unit Attention on first invocation */
            res = sg_ll_test_unit_ready_pt(ptvp, k, (0 == k), vb);
            if (res) {
                ++resp->num_errs;
                resp->ret = res;
                if (1 == op->do_number) {
                    if (SG_LIB_CAT_NOT_READY == res)
                        printf("device not ready\n");
                    else {
                        sg_get_category_sense_str(res, sizeof(b), b, vb);
                        printf("%s\n", b);
                    }
                    resp->reported = true;
                    break;
                }
            }
        }
        return k;
    }
}