/* Returns file descriptor >= 0 if successful. If error in Unix returns
   negated errno. */
int
sg_cmds_open_device(const char * device_name, bool read_only, int verbose)
{
    /* The following 2 lines are temporary. It is to avoid a NULL pointer
     * crash when an old utility is used with a newer library built after
     * the sg_warnings_strm cleanup */
    if (NULL == sg_warnings_strm)
        sg_warnings_strm = stderr;

    return scsi_pt_open_device(device_name, read_only, verbose);
}
Beispiel #2
0
/* Returns file descriptor >= 0 if successful. If error in Unix returns
   negated errno. */
int
sg_cmds_open_device(const char * device_name, bool read_only, int verbose)
{
    return scsi_pt_open_device(device_name, read_only, verbose);
}
Beispiel #3
0
int main(int argc, char * argv[])
{
    int sg_fd, k, ok, dsize, res, duration, resid, cat, got, slen;
    unsigned char inq_cdb [INQ_CMD_LEN] =
    {0x12, 0, 0, 0, INQ_REPLY_LEN, 0};
    unsigned char tur_cdb [TUR_CMD_LEN] =
    {0x00, 0, 0, 0, 0, 0};
    unsigned char inqBuff[INQ_REPLY_LEN];
    char * file_name = 0;
    char b[512];
    unsigned char sense_b[32];
    int verbose = 0;
    struct sg_pt_base * ptvp;

    for (k = 1; k < argc; ++k) {
        if (0 == strcmp("-v", argv[k]))
            verbose = 1;
        else if (0 == strcmp("-vv", argv[k]))
            verbose = 2;
        else if (0 == strcmp("-vvv", argv[k]))
            verbose = 3;
        else if (*argv[k] == '-') {
            printf("Unrecognized switch: %s\n", argv[k]);
            file_name = 0;
            break;
        }
        else if (0 == file_name)
            file_name = argv[k];
        else {
            printf("too many arguments\n");
            file_name = 0;
            break;
        }
    }
    if (0 == file_name) {
        printf("Usage: 'sg_simple5 [-v|-vv|-vvv] <device>'\n");
        return 1;
    }

    sg_fd = scsi_pt_open_device(file_name, 1 /* ro */, 0);
    /* N.B. An access mode of O_RDWR is required for some SCSI commands */
    if (sg_fd < 0) {
        fprintf(stderr, "error opening file: %s: %s\n",
                file_name, safe_strerror(-sg_fd));
        return 1;
    }

    dsize = sizeof(inqBuff);
    ok = 0;

    ptvp = construct_scsi_pt_obj();     /* one object per command */
    if (NULL == ptvp) {
        fprintf(stderr, "sg_simple5: out of memory\n");
        return -1;
    }
    set_scsi_pt_cdb(ptvp, inq_cdb, sizeof(inq_cdb));
    set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
    set_scsi_pt_data_in(ptvp, inqBuff, dsize);
    res = do_scsi_pt(ptvp, sg_fd, CMD_TIMEOUT_SECS, verbose);
    if (res < 0) {
        fprintf(stderr, "  pass through os error: %s\n",
                safe_strerror(-res));
        goto finish_inq;
    } else if (SCSI_PT_DO_BAD_PARAMS == res) {
        fprintf(stderr, "  bad pass through setup\n");
        goto finish_inq;
    } else if (SCSI_PT_DO_TIMEOUT == res) {
        fprintf(stderr, "  pass through timeout\n");
        goto finish_inq;
    }
    if ((verbose > 1) && ((duration = get_scsi_pt_duration_ms(ptvp)) >= 0))
        fprintf(stderr, "      duration=%d ms\n", duration);
    resid = get_scsi_pt_resid(ptvp);
    switch ((cat = get_scsi_pt_result_category(ptvp))) {
    case SCSI_PT_RESULT_GOOD:
        got = dsize - resid;
        if (verbose && (resid > 0))
            fprintf(stderr, "    requested %d bytes but "
                    "got %d bytes)\n", dsize, got);
        break;
    case SCSI_PT_RESULT_STATUS: /* other than GOOD and CHECK CONDITION */
        if (verbose) {
            sg_get_scsi_status_str(get_scsi_pt_status_response(ptvp),
                                   sizeof(b), b);
            fprintf(stderr, "  scsi status: %s\n", b);
        }
        goto finish_inq;
    case SCSI_PT_RESULT_SENSE:
        slen = get_scsi_pt_sense_len(ptvp);
        if (verbose) {
            sg_get_sense_str("", sense_b, slen, (verbose > 1),
                             sizeof(b), b);
            fprintf(stderr, "%s", b);
        }
        if (verbose && (resid > 0)) {
            got = dsize - resid;
            if ((verbose) || (got > 0))
                fprintf(stderr, "    requested %d bytes but "
                        "got %d bytes\n", dsize, got);
        }
        goto finish_inq;
    case SCSI_PT_RESULT_TRANSPORT_ERR:
        if (verbose) {
            get_scsi_pt_transport_err_str(ptvp, sizeof(b), b);
            fprintf(stderr, "  transport: %s", b);
        }
        goto finish_inq;
    case SCSI_PT_RESULT_OS_ERR:
        if (verbose) {
            get_scsi_pt_os_err_str(ptvp, sizeof(b), b);
            fprintf(stderr, "  os: %s", b);
        }
        goto finish_inq;
    default:
        fprintf(stderr, "  unknown pass through result "
                "category (%d)\n", cat);
        goto finish_inq;
    }

    ok = 1;
finish_inq:
    destruct_scsi_pt_obj(ptvp);

    if (ok) { /* output result if it is available */
        char * p = (char *)inqBuff;

        printf("Some of the INQUIRY command's results:\n");
        printf("    %.8s  %.16s  %.4s\n", p + 8, p + 16, p + 32);
    }
    ok = 0;


    /* Now prepare TEST UNIT READY command */
    ptvp = construct_scsi_pt_obj();     /* one object per command */
    if (NULL == ptvp) {
        fprintf(stderr, "sg_simple5: out of memory\n");
        return -1;
    }
    set_scsi_pt_cdb(ptvp, tur_cdb, sizeof(tur_cdb));
    set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
    /* no data in or out */
    res = do_scsi_pt(ptvp, sg_fd, CMD_TIMEOUT_SECS, verbose);
    if (res < 0) {
        fprintf(stderr, "  pass through os error: %s\n",
                safe_strerror(-res));
        goto finish_inq;
    } else if (SCSI_PT_DO_BAD_PARAMS == res) {
        fprintf(stderr, "  bad pass through setup\n");
        goto finish_inq;
    } else if (SCSI_PT_DO_TIMEOUT == res) {
        fprintf(stderr, "  pass through timeout\n");
        goto finish_inq;
    }
    if ((verbose > 1) && ((duration = get_scsi_pt_duration_ms(ptvp)) >= 0))
        fprintf(stderr, "      duration=%d ms\n", duration);
    resid = get_scsi_pt_resid(ptvp);
    switch ((cat = get_scsi_pt_result_category(ptvp))) {
    case SCSI_PT_RESULT_GOOD:
        break;
    case SCSI_PT_RESULT_STATUS: /* other than GOOD and CHECK CONDITION */
        if (verbose) {
            sg_get_scsi_status_str(get_scsi_pt_status_response(ptvp),
                                   sizeof(b), b);
            fprintf(stderr, "  scsi status: %s\n", b);
        }
        goto finish_tur;
    case SCSI_PT_RESULT_SENSE:
        slen = get_scsi_pt_sense_len(ptvp);
        if (verbose) {
            sg_get_sense_str("", sense_b, slen, (verbose > 1),
                             sizeof(b), b);
            fprintf(stderr, "%s", b);
        }
        goto finish_tur;
    case SCSI_PT_RESULT_TRANSPORT_ERR:
        if (verbose) {
            get_scsi_pt_transport_err_str(ptvp, sizeof(b), b);
            fprintf(stderr, "  transport: %s", b);
        }
        goto finish_tur;
    case SCSI_PT_RESULT_OS_ERR:
        if (verbose) {
            get_scsi_pt_os_err_str(ptvp, sizeof(b), b);
            fprintf(stderr, "  os: %s", b);
        }
        goto finish_tur;
    default:
        fprintf(stderr, "  unknown pass through result "
                "category (%d)\n", cat);
        goto finish_tur;
    }

    ok = 1;
finish_tur:
    destruct_scsi_pt_obj(ptvp);

    if (ok)
        printf("Test Unit Ready successful so unit is ready!\n");
    else
        printf("Test Unit Ready failed so unit may _not_ be ready!\n");

    scsi_pt_close_device(sg_fd);
    return 0;
}
Beispiel #4
0
int
main(int argc, char *argv[])
{
    int ret = 0;
    int res_cat, status, slen, k, ret2;
    int sg_fd = -1;
    struct sg_pt_base *ptvp = NULL;
    unsigned char sense_buffer[32];
    unsigned char * dxfer_buffer_in = NULL;
    unsigned char * dxfer_buffer_out = NULL;
    unsigned char *wrkBuf = NULL;
    struct opts_t opts;
    struct opts_t * op;
    char b[128];

    op = &opts;
    memset(op, 0, sizeof(opts));
    op->timeout = DEFAULT_TIMEOUT;
    ret = process_cl(op, argc, argv);
    if (ret != 0) {
        usage();
        goto done;
    } else if (op->do_help) {
        usage();
        goto done;
    } else if (op->do_version) {
        version();
        goto done;
    }

    sg_fd = scsi_pt_open_device(op->device_name, op->readonly,
                                op->do_verbose);
    if (sg_fd < 0) {
        fprintf(stderr, "%s: %s\n", op->device_name, safe_strerror(-sg_fd));
        ret = SG_LIB_FILE_ERROR;
        goto done;
    }

    ptvp = construct_scsi_pt_obj();
    if (ptvp == NULL) {
        fprintf(stderr, "out of memory\n");
        ret = SG_LIB_CAT_OTHER;
        goto done;
    }
    if (op->do_verbose) {
        fprintf(stderr, "    cdb to send: ");
        for (k = 0; k < op->cdb_length; ++k)
            fprintf(stderr, "%02x ", op->cdb[k]);
        fprintf(stderr, "\n");
        if (op->do_verbose > 2) {
            sg_get_command_name(op->cdb, 0, sizeof(b) - 1, b);
            b[sizeof(b) - 1] = '\0';
            fprintf(stderr, "    Command name: %s\n", b);
        }
    }
    set_scsi_pt_cdb(ptvp, op->cdb, op->cdb_length);
    set_scsi_pt_sense(ptvp, sense_buffer, sizeof(sense_buffer));

    if (op->do_dataout) {
        dxfer_buffer_out = fetch_dataout(op);
        if (dxfer_buffer_out == NULL) {
            ret = SG_LIB_CAT_OTHER;
            goto done;
        }
        set_scsi_pt_data_out(ptvp, dxfer_buffer_out, op->dataout_len);
    }
    if (op->do_datain) {
        dxfer_buffer_in = my_memalign(op->datain_len, &wrkBuf);
        if (dxfer_buffer_in == NULL) {
            perror("malloc");
            ret = SG_LIB_CAT_OTHER;
            goto done;
        }
        set_scsi_pt_data_in(ptvp, dxfer_buffer_in, op->datain_len);
    }

    ret = do_scsi_pt(ptvp, sg_fd, op->timeout, op->do_verbose);
    if (ret > 0) {
        if (SCSI_PT_DO_BAD_PARAMS == ret) {
            fprintf(stderr, "do_scsi_pt: bad pass through setup\n");
            ret = SG_LIB_CAT_OTHER;
        } else if (SCSI_PT_DO_TIMEOUT == ret) {
            fprintf(stderr, "do_scsi_pt: timeout\n");
            ret = SG_LIB_CAT_TIMEOUT;
        } else
            ret = SG_LIB_CAT_OTHER;
        goto done;
    } else if (ret < 0) {
        fprintf(stderr, "do_scsi_pt: %s\n", safe_strerror(-ret));
        ret = SG_LIB_CAT_OTHER;
        goto done;
    }

    slen = 0;
    res_cat = get_scsi_pt_result_category(ptvp);
    switch (res_cat) {
    case SCSI_PT_RESULT_GOOD:
        ret = 0;
        break;
    case SCSI_PT_RESULT_SENSE:
        slen = get_scsi_pt_sense_len(ptvp);
        ret = sg_err_category_sense(sense_buffer, slen);
        break;
    case SCSI_PT_RESULT_TRANSPORT_ERR:
        get_scsi_pt_transport_err_str(ptvp, sizeof(b), b);
        fprintf(stderr, ">>> transport error: %s\n", b);
        ret = SG_LIB_CAT_OTHER;
        break;
    case SCSI_PT_RESULT_OS_ERR:
        get_scsi_pt_os_err_str(ptvp, sizeof(b), b);
        fprintf(stderr, ">>> os error: %s\n", b);
        ret = SG_LIB_CAT_OTHER;
        break;
    default:
        fprintf(stderr, ">>> unknown pass through result category (%d)\n",
                res_cat);
        ret = SG_LIB_CAT_OTHER;
        break;
    }

    status = get_scsi_pt_status_response(ptvp);
    fprintf(stderr, "SCSI Status: ");
    sg_print_scsi_status(status);
    fprintf(stderr, "\n\n");
    if ((SAM_STAT_CHECK_CONDITION == status) && (! op->no_sense)) {
        if (SCSI_PT_RESULT_SENSE != res_cat)
            slen = get_scsi_pt_sense_len(ptvp);
        if (0 == slen)
            fprintf(stderr, ">>> Strange: status is CHECK CONDITION but no "
                    "Sense Information\n");
        else {
            fprintf(stderr, "Sense Information:\n");
            sg_print_sense(NULL, sense_buffer, slen, (op->do_verbose > 0));
            fprintf(stderr, "\n");
        }
    }
    if (SAM_STAT_RESERVATION_CONFLICT == status)
        ret = SG_LIB_CAT_RES_CONFLICT;

    if (op->do_datain) {
        int data_len = op->datain_len - get_scsi_pt_resid(ptvp);

        if (ret && !(SG_LIB_CAT_RECOVERED == ret ||
                     SG_LIB_CAT_NO_SENSE == ret))
            fprintf(stderr, "Error %d occurred, no data received\n", ret);
        else if (data_len == 0) {
            fprintf(stderr, "No data received\n");
        } else {
            if (op->datain_file == NULL && !op->datain_binary) {
                fprintf(stderr, "Received %d bytes of data:\n", data_len);
                dStrHexErr((const char *)dxfer_buffer_in, data_len, 0);
            } else {
                const char * cp = "stdout";

                if (op->datain_file &&
                    ! ((1 == strlen(op->datain_file)) &&
                       ('-' == op->datain_file[0])))
                    cp = op->datain_file;
                fprintf(stderr, "Writing %d bytes of data to %s\n", data_len,
                        cp);
                ret2 = write_dataout(op->datain_file, dxfer_buffer_in,
                                     data_len);
                if (0 != ret2) {
                    if (0 == ret)
                        ret = ret2;
                    goto done;
                }
            }
        }
    }

done:
    if (op->do_verbose) {
        sg_get_category_sense_str(ret, sizeof(b), b, op->do_verbose - 1);
        fprintf(stderr, "%s\n", b);
    }
    if (wrkBuf)
        free(wrkBuf);
    if (ptvp)
        destruct_scsi_pt_obj(ptvp);
    if (sg_fd >= 0)
        scsi_pt_close_device(sg_fd);
    return ret;
}