Exemple #1
0
int main(int argc, char * argv[])
{
    int sg_fd, k, num, rsp_len, res;
    unsigned char rsp_buff[MX_ALLOC_LEN];
    int rsp_buff_size = MX_ALLOC_LEN;
    int read_in_len = 0;
    const char * cp;
    unsigned char read_in[MX_ALLOC_LEN];
    int ret = 0;
    struct opts_t opts;

    memset(&opts, 0, sizeof(opts));
    res = process_cl(&opts, argc, argv);
    if (res)
        return SG_LIB_SYNTAX_ERROR;
    if (opts.do_help) {
        if (opts.opt_new)
            usage();
        else
            usage_old();
        return 0;
    }
    if (opts.do_version) {
        fprintf(stderr, "Version string: %s\n", version_str);
        return 0;
    }

    if (NULL == opts.device_name) {
        fprintf(stderr, "No DEVICE argument given\n");
        if (opts.opt_new)
            usage();
        else
            usage_old();
        return SG_LIB_SYNTAX_ERROR;
    }
    if (opts.do_raw) {
        if (build_diag_page(opts.raw_arg, read_in, &read_in_len,
                            sizeof(read_in))) {
            if (opts.opt_new) {
                printf("Bad sequence after '--raw=' option\n");
                usage();
            } else {
                printf("Bad sequence after '-raw=' option\n");
                usage_old();
            }
            return SG_LIB_SYNTAX_ERROR;
        }
    }

    if ((opts.do_doff || opts.do_uoff) && (! opts.do_deftest)) {
        if (opts.opt_new) {
            printf("setting --doff or --uoff only useful when -t is set\n");
            usage();
        } else {
            printf("setting -doff or -uoff only useful when -t is set\n");
            usage_old();
        }
        return SG_LIB_SYNTAX_ERROR;
    }
    if ((opts.do_selftest > 0) && opts.do_deftest) {
        if (opts.opt_new) {
            printf("either set --selftest=SF or --test (not both)\n");
            usage();
        } else {
            printf("either set -s=SF or -t (not both)\n");
            usage_old();
        }
        return SG_LIB_SYNTAX_ERROR;
    }
    if (opts.do_raw) {
        if ((opts.do_selftest > 0) || opts.do_deftest || opts.do_extdur ||
            opts.do_list) {
            if (opts.opt_new) {
                printf("'--raw=' cannot be used with self-tests, '-e' or "
                       "'-l'\n");
                usage();
            } else {
                printf("'-raw=' cannot be used with self-tests, '-e' or "
                       "'-l'\n");
                usage_old();
            }
            return SG_LIB_SYNTAX_ERROR;
        }
        if (! opts.do_pf) {
            if (opts.opt_new)
                printf(">>> warning, '--pf' probably should be used with "
                       "'--raw='\n");
            else
                printf(">>> warning, '-pf' probably should be used with "
                       "'-raw='\n");
        }
    }
    if (NULL == opts.device_name) {
        if (opts.do_list) {
            list_page_codes();
            return 0;
        }
        fprintf(stderr, "No DEVICE argument given\n");
        if (opts.opt_new)
            usage();
        else
            usage_old();
        return SG_LIB_SYNTAX_ERROR;
    }

    if ((sg_fd = sg_cmds_open_device(opts.device_name, 0 /* rw */,
                                     opts.do_verbose)) < 0) {
        fprintf(stderr, ME "error opening file: %s: %s\n", opts.device_name,
                safe_strerror(-sg_fd));
        return SG_LIB_FILE_ERROR;
    }
    if (opts.do_extdur) {
        res = do_modes_0a(sg_fd, rsp_buff, 32, 1, 0, opts.do_verbose);
        if (0 == res) {
            /* Assume mode sense(10) response without block descriptors */
            num = (rsp_buff[0] << 8) + rsp_buff[1] - 6;
            if (num >= 0xc) {
                int secs;

                secs = (rsp_buff[18] << 8) + rsp_buff[19];
#ifdef SG_LIB_MINGW
                printf("Expected extended self-test duration=%d seconds "
                       "(%g minutes)\n", secs, secs / 60.0);
#else
                printf("Expected extended self-test duration=%d seconds "
                       "(%.2f minutes)\n", secs, secs / 60.0);
#endif
            } else
                printf("Extended self-test duration not available\n");
        } else {
            ret = res;
            printf("Extended self-test duration (mode page 0xa) failed\n");
            goto err_out9;
        }
    } else if (opts.do_list) {
        memset(rsp_buff, 0, sizeof(rsp_buff));
        res = do_senddiag(sg_fd, 0, 1 /* pf */, 0, 0, 0, rsp_buff, 4, 1,
                          opts.do_verbose);
        if (0 == res) {
            if (0 == sg_ll_receive_diag(sg_fd, 0, 0, rsp_buff,
                                        rsp_buff_size, 1, opts.do_verbose)) {
                printf("Supported diagnostic pages response:\n");
                rsp_len = (rsp_buff[2] << 8) + rsp_buff[3] + 4;
                if (opts.do_hex)
                    dStrHex((const char *)rsp_buff, rsp_len, 1);
                else {
                    for (k = 0; k < (rsp_len - 4); ++k) {
                        cp = find_page_code_desc(rsp_buff[k + 4]);
                        printf("  0x%02x  %s\n", rsp_buff[k + 4],
                               (cp ? cp : "<unknown>"));
                    }
                }
            } else {
                ret = res;
                fprintf(stderr, "RECEIVE DIAGNOSTIC RESULTS command "
                        "failed\n");
                goto err_out9;
            }
        } else {
            ret = res;
            goto err_out;
        }
    } else if (opts.do_raw) {
        res = do_senddiag(sg_fd, 0, opts.do_pf, 0, 0, 0, read_in,
                          read_in_len, 1, opts.do_verbose);
        if (res) {
            ret = res;
            goto err_out;
        }
    } else {
        res = do_senddiag(sg_fd, opts.do_selftest, opts.do_pf,
                          opts.do_deftest, opts.do_doff, opts.do_uoff, NULL,
                          0, 1, opts.do_verbose);
        if (0 == res) {
            if ((5 == opts.do_selftest) || (6 == opts.do_selftest))
                printf("Foreground self-test returned GOOD status\n");
            else if (opts.do_deftest && (! opts.do_doff) && (! opts.do_uoff))
                printf("Default self-test returned GOOD status\n");
        } else {
            ret = res;
            goto err_out;
        }
    }
    res = sg_cmds_close_device(sg_fd);
    if ((res < 0) && (0 == ret))
        return SG_LIB_SYNTAX_ERROR;
    return (ret >= 0) ? ret : SG_LIB_CAT_OTHER;

err_out:
    if (SG_LIB_CAT_UNIT_ATTENTION == res)
        fprintf(stderr, "SEND DIAGNOSTIC, unit attention\n");
    else if (SG_LIB_CAT_ABORTED_COMMAND == res)
        fprintf(stderr, "SEND DIAGNOSTIC, aborted command\n");
    else if (SG_LIB_CAT_NOT_READY == res)
        fprintf(stderr, "SEND DIAGNOSTIC, device not "
                "ready\n");
    else
        fprintf(stderr, "SEND DIAGNOSTIC command, failed\n");
err_out9:
    if (opts.do_verbose < 2)
        fprintf(stderr, "  try again with '-vv' for more information\n");
    res = sg_cmds_close_device(sg_fd);
    if ((res < 0) && (0 == ret))
        return SG_LIB_FILE_ERROR;
    return (ret >= 0) ? ret : SG_LIB_CAT_OTHER;
}
Exemple #2
0
int
main(int argc, char * argv[])
{
    int sg_fd, k, num, len, res, md_len, bd_len, longlba, page_num, spf;
    char ebuff[EBUFF_SZ];
    const char * descp;
    unsigned char * rsp_buff = NULL;
    unsigned char def_rsp_buff[DEF_ALLOC_LEN];
    unsigned char * malloc_rsp_buff = NULL;
    int rsp_buff_size = DEF_ALLOC_LEN;
    int ret = 0;
    int density_code_off, t_proto, inq_pdt, inq_byte6, resp_mode6;
    int num_ua_pages;
    unsigned char * ucp;
    unsigned char uc;
    struct sg_simple_inquiry_resp inq_out;
    char pdt_name[64];
    struct opts_t opts;

    memset(&opts, 0, sizeof(opts));
    opts.pg_code = -1;
    res = process_cl(&opts, argc, argv);
    if (res)
        return SG_LIB_SYNTAX_ERROR;
    if (opts.do_help) {
        usage_for(&opts);
        return 0;
    }
    if (opts.do_version) {
        fprintf(stderr, "Version string: %s\n", version_str);
        return 0;
    }

    if (NULL == opts.device_name) {
        if (opts.do_list) {
            if ((opts.pg_code < 0) || (opts.pg_code > PG_CODE_MAX)) {
                printf("    Assume peripheral device type: disk\n");
                list_page_codes(0, 0, -1);
            } else {
                printf("    peripheral device type: %s\n",
                       sg_get_pdt_str(opts.pg_code, sizeof(pdt_name),
                                      pdt_name));
                if (opts.subpg_code_set)
                    list_page_codes(opts.pg_code, 0, opts.subpg_code);
                else
                    list_page_codes(opts.pg_code, 0, -1);
            }
            return 0;
        }
        fprintf(stderr, "No DEVICE argument given\n");
        usage_for(&opts);
        return SG_LIB_SYNTAX_ERROR;
    }

    if (opts.do_examine && (opts.pg_code >= 0)) {
        fprintf(stderr, "can't give '-e' and a page number\n");
        return SG_LIB_SYNTAX_ERROR;
    }

    if ((opts.do_six) && (opts.do_llbaa)) {
        fprintf(stderr, "LLBAA not defined for MODE SENSE 6, try "
                "without '-L'\n");
        return SG_LIB_SYNTAX_ERROR;
    }
    if (opts.maxlen > 0) {
        if (opts.do_six && (opts.maxlen > 255)) {
            fprintf(stderr, "For Mode Sense (6) maxlen cannot exceed "
                    "255\n");
            return SG_LIB_SYNTAX_ERROR;
        }
        if (opts.maxlen > DEF_ALLOC_LEN) {
            malloc_rsp_buff = (unsigned char *)malloc(opts.maxlen);
            if (NULL == malloc_rsp_buff) {
                fprintf(stderr, "Unable to malloc maxlen=%d bytes\n",
                        opts.maxlen);
                return SG_LIB_SYNTAX_ERROR;
            }
            rsp_buff = malloc_rsp_buff;
        } else
            rsp_buff = def_rsp_buff;
        rsp_buff_size = opts.maxlen;
    } else {    /* maxlen == 0 */
        rsp_buff_size = opts.do_six ? DEF_6_ALLOC_LEN : DEF_ALLOC_LEN;
        rsp_buff = def_rsp_buff;
    }
    /* If no pages or list selected than treat as 'a' */
    if (! ((opts.pg_code >= 0) || opts.do_all || opts.do_list ||
            opts.do_examine))
        opts.do_all = 1;

    if (opts.do_raw) {
        if (sg_set_binary_mode(STDOUT_FILENO) < 0) {
            perror("sg_set_binary_mode");
            return SG_LIB_FILE_ERROR;
        }
    }

    if ((sg_fd = sg_cmds_open_device(opts.device_name, 1 /* ro */,
                                     opts.do_verbose)) < 0) {
        fprintf(stderr, "error opening file: %s: %s\n",
                opts.device_name, safe_strerror(-sg_fd));
        if (malloc_rsp_buff)
            free(malloc_rsp_buff);
        return SG_LIB_FILE_ERROR;
    }

    if (sg_simple_inquiry(sg_fd, &inq_out, 1, opts.do_verbose)) {
        fprintf(stderr, "%s doesn't respond to a SCSI INQUIRY\n",
                opts.device_name);
        ret = SG_LIB_CAT_OTHER;
        goto finish;
    }
    inq_pdt = inq_out.peripheral_type;
    inq_byte6 = inq_out.byte_6;
    if (0 == opts.do_raw)
        printf("    %.8s  %.16s  %.4s   peripheral_type: %s [0x%x]\n",
               inq_out.vendor, inq_out.product, inq_out.revision,
               sg_get_pdt_str(inq_pdt, sizeof(pdt_name), pdt_name), inq_pdt);
    if (opts.do_list) {
        if (opts.subpg_code_set)
            list_page_codes(inq_pdt, inq_byte6, opts.subpg_code);
        else
            list_page_codes(inq_pdt, inq_byte6, -1);
        goto finish;
    }
    if (opts.do_examine) {
        ret = examine_pages(sg_fd, inq_pdt, inq_byte6, &opts);
        goto finish;
    }
    if (PG_CODE_ALL == opts.pg_code) {
        if (0 == opts.do_all)
            ++opts.do_all;
    } else if (opts.do_all)
        opts.pg_code = PG_CODE_ALL;
    if (opts.do_all > 1)
        opts.subpg_code = SPG_CODE_ALL;

    if (opts.do_raw > 1) {
        if (opts.do_all) {
            if (opts.opt_new)
                fprintf(stderr, "'-R' requires a specific (sub)page, not "
                        "all\n");
            else
                fprintf(stderr, "'-r' requires a specific (sub)page, not "
                        "all\n");
            usage_for(&opts);
            ret = SG_LIB_SYNTAX_ERROR;
            goto finish;
        }
    }

    memset(rsp_buff, 0, sizeof(rsp_buff));
    if (opts.do_six) {
        res = sg_ll_mode_sense6(sg_fd, opts.do_dbd, opts.page_control,
                                opts.pg_code, opts.subpg_code, rsp_buff,
                                rsp_buff_size, 1, opts.do_verbose);
        if (SG_LIB_CAT_INVALID_OP == res)
            fprintf(stderr, ">>>>>> try again without the '-6' "
                    "switch for a 10 byte MODE SENSE command\n");
    } else {
        res = sg_ll_mode_sense10(sg_fd, opts.do_llbaa, opts.do_dbd,
                                 opts.page_control, opts.pg_code,
                                 opts.subpg_code, rsp_buff, rsp_buff_size,
                                 1, opts.do_verbose);
        if (SG_LIB_CAT_INVALID_OP == res)
            fprintf(stderr, ">>>>>> try again with a '-6' "
                    "switch for a 6 byte MODE SENSE command\n");
    }
    if (SG_LIB_CAT_ILLEGAL_REQ == res) {
        if (opts.subpg_code > 0)
            fprintf(stderr, "invalid field in cdb (perhaps subpages "
                    "not supported)\n");
        else if (opts.page_control > 0)
            fprintf(stderr, "invalid field in cdb (perhaps "
                    "page control (PC) not supported)\n");
        else
            fprintf(stderr, "invalid field in cdb (perhaps "
                "page 0x%x not supported)\n", opts.pg_code);
    } else if (SG_LIB_CAT_NOT_READY == res)
        fprintf(stderr, "device not ready\n");
    else if (SG_LIB_CAT_UNIT_ATTENTION == res)
        fprintf(stderr, "unit attention\n");
    else if (SG_LIB_CAT_ABORTED_COMMAND == res)
        fprintf(stderr, "aborted command\n");
    ret = res;
    if (0 == res) {
        int medium_type, specific, headerlen;

        ret = 0;
        resp_mode6 = opts.do_six;
        if (opts.do_flexible) {
            num = rsp_buff[0];
            if (opts.do_six && (num < 3))
                resp_mode6 = 0;
            if ((0 == opts.do_six) && (num > 5)) {
                if ((num > 11) && (0 == (num % 2)) && (0 == rsp_buff[4]) &&
                    (0 == rsp_buff[5]) && (0 == rsp_buff[6])) {
                    rsp_buff[1] = num;
                    rsp_buff[0] = 0;
                    fprintf(stderr, ">>> msense(10) but resp[0]=%d and "
                            "not msense(6) response so fix length\n", num);
                } else
                    resp_mode6 = 1;
            }
        }
        if ((! opts.do_raw) && (1 != opts.do_hex)) {
            if (resp_mode6 == opts.do_six)
                printf("Mode parameter header from MODE SENSE(%s):\n",
                       (opts.do_six ? "6" : "10"));
            else
                printf(" >>> Mode parameter header from MODE SENSE(%s),\n"
                       "     decoded as %s byte response:\n",
                       (opts.do_six ? "6" : "10"), (resp_mode6 ? "6" : "10"));
        }
        if (resp_mode6) {
            headerlen = 4;
            md_len = rsp_buff[0] + 1;
            bd_len = rsp_buff[3];
            medium_type = rsp_buff[1];
            specific = rsp_buff[2];
            longlba = 0;
        } else {
            headerlen = 8;
            md_len = (rsp_buff[0] << 8) + rsp_buff[1] + 2;
            bd_len = (rsp_buff[6] << 8) + rsp_buff[7];
            medium_type = rsp_buff[2];
            specific = rsp_buff[3];
            longlba = rsp_buff[4] & 1;
        }
        if ((bd_len + headerlen) > md_len) {
            fprintf(stderr, "Invalid block descriptor length=%d, ignore\n",
                    bd_len);
            bd_len = 0;
        }
        if (opts.do_raw) {
            if (1 == opts.do_raw)
                dStrRaw((const char *)rsp_buff, md_len);
            else {
                ucp = rsp_buff + bd_len + headerlen;
                md_len -= bd_len + headerlen;
                spf = ((ucp[0] & 0x40) ? 1 : 0);
                len = (spf ? ((ucp[2] << 8) + ucp[3] + 4) : (ucp[1] + 2));
                len = (len < md_len) ? len : md_len;
                for (k = 0; k < len; ++k)
                    printf("%02x\n", ucp[k]);
            }
            goto finish;
        }
        if (1 == opts.do_hex) {
            dStrHex((const char *)rsp_buff, md_len, 1);
            goto finish;
        } else if (opts.do_hex > 1)
            dStrHex((const char *)rsp_buff, headerlen, 1);
        if (0 == inq_pdt)
            printf("  Mode data length=%d, medium type=0x%.2x, WP=%d,"
                   " DpoFua=%d, longlba=%d\n", md_len, medium_type,
                   !!(specific & 0x80), !!(specific & 0x10), longlba);
        else
            printf("  Mode data length=%d, medium type=0x%.2x, specific"
                   " param=0x%.2x, longlba=%d\n", md_len, medium_type,
                   specific, longlba);
        if (md_len > rsp_buff_size) {
            printf("Only fetched %d bytes of response, truncate output\n",
                   rsp_buff_size);
            md_len = rsp_buff_size;
            if (bd_len + headerlen > rsp_buff_size)
                bd_len = rsp_buff_size - headerlen;
        }
        if (! opts.do_dbout) {
            printf("  Block descriptor length=%d\n", bd_len);
            if (bd_len > 0) {
                len = 8;
                density_code_off = 0;
                num = bd_len;
                if (longlba) {
                    printf("> longlba direct access device block "
                           "descriptors:\n");
                    len = 16;
                    density_code_off = 8;
                }
                else if (0 == inq_pdt) {
                    printf("> Direct access device block descriptors:\n");
                    density_code_off = 4;
                }
                else
                    printf("> General mode parameter block descriptors:\n");

                ucp = rsp_buff + headerlen;
                while (num > 0) {
                    printf("   Density code=0x%x\n",
                           *(ucp + density_code_off));
                    dStrHex((const char *)ucp, len, 1);
                    ucp += len;
                    num -= len;
                }
                printf("\n");
            }
        }
        ucp = rsp_buff + bd_len + headerlen;    /* start of mode page(s) */
        md_len -= bd_len + headerlen;           /* length of mode page(s) */
        num_ua_pages = 0;
        for (k = 0; md_len > 0; ++k) { /* got mode page(s) */
            if ((k > 0) && (! opts.do_all) &&
                (SPG_CODE_ALL != opts.subpg_code)) {
                fprintf(stderr, "Unexpectedly received extra mode page "
                                "responses, ignore\n");
                break;
            }
            uc = *ucp;
            spf = ((uc & 0x40) ? 1 : 0);
            len = (spf ? ((ucp[2] << 8) + ucp[3] + 4) : (ucp[1] + 2));
            page_num = ucp[0] & PG_CODE_MASK;
            if (0x0 == page_num) {
                ++num_ua_pages;
                if((num_ua_pages > 3) && (md_len > 0xa00)) {
                    fprintf(stderr, ">>> Seen 3 unit attention pages "
                            "(only one should be at end)\n     and mpage "
                            "length=%d, looks malformed, try '-f' option\n",
                            md_len);
                    break;
                }
            }
            if (opts.do_hex) {
                if (spf)
                    printf(">> page_code=0x%x, subpage_code=0x%x, page_cont"
                           "rol=%d\n", page_num, ucp[1], opts.page_control);
                else
                    printf(">> page_code=0x%x, page_control=%d\n", page_num,
                           opts.page_control);
            } else {
                descp = NULL;
                if ((0x18 == page_num) || (0x19 == page_num)) {
                    t_proto = (spf ? ucp[5] : ucp[2]) & 0xf;
                    descp = find_page_code_desc(page_num, (spf ? ucp[1] : 0),
                                                inq_pdt, inq_byte6, t_proto);
                } else
                    descp = find_page_code_desc(page_num, (spf ? ucp[1] : 0),
                                                inq_pdt, inq_byte6, -1);
                if (NULL == descp) {
                    if (spf)
                        snprintf(ebuff, EBUFF_SZ, "0x%x, subpage_code: 0x%x",
                                 page_num, ucp[1]);
                    else
                        snprintf(ebuff, EBUFF_SZ, "0x%x", page_num);
                }
                if (descp)
                    printf(">> %s, page_control: %s\n", descp,
                           pg_control_str_arr[opts.page_control]);
                else
                    printf(">> page_code: %s, page_control: %s\n", ebuff,
                           pg_control_str_arr[opts.page_control]);
            }
            num = (len > md_len) ? md_len : len;
            if ((k > 0) && (num > 256)) {
                num = 256;
                fprintf(stderr, ">>> page length (%d) > 256 bytes, unlikely "
                                "trim\n    Try '-f' option\n", len);
            }
            dStrHex((const char *)ucp, num , 1);
            ucp += len;
            md_len -= len;
        }
    }

finish:
    sg_cmds_close_device(sg_fd);
    if (malloc_rsp_buff)
        free(malloc_rsp_buff);
    return (ret >= 0) ? ret : SG_LIB_CAT_OTHER;
}
int
main(int argc, char *argv[])
{
    int k;
    int ret = 0;
    unsigned int ui;
    size_t s;
    struct opts_t opts;
    char b[2048];
    FILE * fp = NULL;
    const char * cp;

    memset(&opts, 0, sizeof(opts));
    memset(b, 0, sizeof(b));
    ret = process_cl(&opts, argc, argv);
    if (ret != 0) {
        usage();
        return ret;
    } else if (opts.do_help) {
        usage();
        return 0;
    } else if (opts.do_version) {
        pr2serr("version: %s\n", version_str);
        return 0;
    }


    if (opts.do_status) {
        sg_get_scsi_status_str(opts.sstatus, sizeof(b) - 1, b);
        printf("SCSI status: %s\n", b);
    }

    if ((0 == opts.sense_len) && opts.no_space_str) {
        if (opts.do_verbose > 2)
            pr2serr("no_space str: %s\n", opts.no_space_str);
        cp = opts.no_space_str;
        for (k = 0; isxdigit(cp[k]) && isxdigit(cp[k + 1]); k += 2) {
            if (1 != sscanf(cp + k, "%2x", &ui)) {
                pr2serr("bad no_space hex string: %s\n", cp);
                return SG_LIB_SYNTAX_ERROR;
            }
            opts.sense[opts.sense_len++] = (unsigned char)ui;
        }
    }

    if ((0 == opts.sense_len) && (! opts.do_binary) && (! opts.do_file)) {
        if (opts.do_status)
            return 0;
        pr2serr(">> Need sense data on the command line or in a file\n\n");
        usage();
        return SG_LIB_SYNTAX_ERROR;
    }
    if (opts.sense_len && (opts.do_binary || opts.do_file)) {
        pr2serr(">> Need sense data on command line or in a file, not "
                "both\n\n");
        return SG_LIB_SYNTAX_ERROR;
    }
    if (opts.do_binary && opts.do_file) {
        pr2serr(">> Either a binary file or a ASCII hexadecimal, file not "
                "both\n\n");
        return SG_LIB_SYNTAX_ERROR;
    }

    if (opts.do_binary) {
        fp = fopen(opts.fname, "r");
        if (NULL == fp) {
            pr2serr("unable to open file: %s\n", opts.fname);
            return SG_LIB_SYNTAX_ERROR;
        }
        s = fread(opts.sense, 1, MAX_SENSE_LEN, fp);
        fclose(fp);
        if (0 == s) {
            pr2serr("read nothing from file: %s\n", opts.fname);
            return SG_LIB_SYNTAX_ERROR;
        }
        opts.sense_len = s;
    } else if (opts.do_file) {
        ret = f2hex_arr(opts.fname, opts.no_space, opts.sense,
                        &opts.sense_len, MAX_SENSE_LEN);
        if (ret) {
            pr2serr("unable to decode ASCII hex from file: %s\n", opts.fname);
            return SG_LIB_SYNTAX_ERROR;
        }
    }

    if (opts.sense_len) {
        if (opts.wfname) {
            if ((fp = fopen(opts.wfname, "w"))) {
                write2wfn(fp, &opts);
                fclose(fp);
            } else {
                perror("open");
                pr2serr("trying to write to %s\n", opts.wfname);
            }
        }
        sg_get_sense_str(NULL, opts.sense, opts.sense_len, opts.do_verbose,
                         sizeof(b) - 1, b);
        printf("%s\n", b);
    }

    return 0;
}
Exemple #4
0
int
main(int argc, char * argv[])
{
    int sg_fd, k, num, rsp_len, res, rsp_buff_size, pg;
    int read_in_len = 0;
    int ret = 0;
    struct opts_t opts;
    struct opts_t * op;
    unsigned char * rsp_buff = NULL;
    const char * cp;
    unsigned char * read_in = NULL;

    op = &opts;
    memset(op, 0, sizeof(opts));
    op->maxlen = DEF_ALLOC_LEN;
    op->page_code = -1;
    res = process_cl(op, argc, argv);
    if (res)
        return SG_LIB_SYNTAX_ERROR;
    if (op->do_help) {
        if (op->opt_new)
            usage();
        else
            usage_old();
        return 0;
    }
    if (op->do_version) {
        fprintf(stderr, "Version string: %s\n", version_str);
        return 0;
    }
    rsp_buff_size = op->maxlen;

    if (NULL == op->device_name) {
        if (op->do_list) {
            list_page_codes();
            return 0;
        }
        fprintf(stderr, "No DEVICE argument given\n");
        if (op->opt_new)
            usage();
        else
            usage_old();
        return SG_LIB_SYNTAX_ERROR;
    }
    if (op->do_raw) {
        read_in = (unsigned char *)calloc(op->maxlen, 1);
        if (NULL == read_in) {
            fprintf(stderr, "unable to allocate %d bytes\n", op->maxlen);
            return SG_LIB_CAT_OTHER;
        }
        if (build_diag_page(op->raw_arg, read_in, &read_in_len, op->maxlen)) {
            if (op->opt_new) {
                printf("Bad sequence after '--raw=' option\n");
                usage();
            } else {
                printf("Bad sequence after '-raw=' option\n");
                usage_old();
            }
            return SG_LIB_SYNTAX_ERROR;
        }
    }

    if ((op->do_doff || op->do_uoff) && (! op->do_deftest)) {
        if (op->opt_new) {
            printf("setting --doff or --uoff only useful when -t is set\n");
            usage();
        } else {
            printf("setting -doff or -uoff only useful when -t is set\n");
            usage_old();
        }
        return SG_LIB_SYNTAX_ERROR;
    }
    if ((op->do_selftest > 0) && op->do_deftest) {
        if (op->opt_new) {
            printf("either set --selftest=SF or --test (not both)\n");
            usage();
        } else {
            printf("either set -s=SF or -t (not both)\n");
            usage_old();
        }
        return SG_LIB_SYNTAX_ERROR;
    }
    if (op->do_raw) {
        if ((op->do_selftest > 0) || op->do_deftest || op->do_extdur ||
            op->do_list) {
            if (op->opt_new) {
                printf("'--raw=' cannot be used with self-tests, '-e' or "
                       "'-l'\n");
                usage();
            } else {
                printf("'-raw=' cannot be used with self-tests, '-e' or "
                       "'-l'\n");
                usage_old();
            }
            return SG_LIB_SYNTAX_ERROR;
        }
        if (! op->do_pf) {
            if (op->opt_new)
                printf(">>> warning, '--pf' probably should be used with "
                       "'--raw='\n");
            else
                printf(">>> warning, '-pf' probably should be used with "
                       "'-raw='\n");
        }
    }
#ifdef SG_LIB_WIN32
#ifdef SG_LIB_WIN32_DIRECT
    if (op->do_verbose > 4)
        fprintf(stderr, "Initial win32 SPT interface state: %s\n",
                scsi_pt_win32_spt_state() ? "direct" : "indirect");
    if (op->maxlen >= 16384)
        scsi_pt_win32_direct(SG_LIB_WIN32_DIRECT /* SPT pt interface */);
#endif
#endif

    if ((sg_fd = sg_cmds_open_device(op->device_name, 0 /* rw */,
                                     op->do_verbose)) < 0) {
        fprintf(stderr, ME "error opening file: %s: %s\n", op->device_name,
                safe_strerror(-sg_fd));
        return SG_LIB_FILE_ERROR;
    }
    rsp_buff = (unsigned char *)calloc(op->maxlen, 1);
    if (NULL == rsp_buff) {
        fprintf(stderr, "unable to allocate %d bytes (2)\n", op->maxlen);
        return SG_LIB_CAT_OTHER;
    }
    if (op->do_extdur) {
        res = do_modes_0a(sg_fd, rsp_buff, 32, 1, 0, op->do_verbose);
        if (0 == res) {
            /* Assume mode sense(10) response without block descriptors */
            num = sg_get_unaligned_be16(rsp_buff) - 6;
            if (num >= 0xc) {
                int secs;

                secs = sg_get_unaligned_be16(rsp_buff + 18);
#ifdef SG_LIB_MINGW
                printf("Expected extended self-test duration=%d seconds "
                       "(%g minutes)\n", secs, secs / 60.0);
#else
                printf("Expected extended self-test duration=%d seconds "
                       "(%.2f minutes)\n", secs, secs / 60.0);
#endif
            } else
                printf("Extended self-test duration not available\n");
        } else {
            ret = res;
            printf("Extended self-test duration (mode page 0xa) failed\n");
            goto err_out9;
        }
    } else if ((op->do_list) || (op->page_code >= 0x0)) {
        pg = op->page_code;
        if (pg < 0)
            res = do_senddiag(sg_fd, 0, 1 /* pf */, 0, 0, 0, rsp_buff, 4, 1,
                              op->do_verbose);
        else
            res = 0;
        if (0 == res) {
            if (0 == sg_ll_receive_diag(sg_fd, (pg >= 0x0),
                                        ((pg >= 0x0) ? pg : 0), rsp_buff,
                                        rsp_buff_size, 1, op->do_verbose)) {
                rsp_len = sg_get_unaligned_be16(rsp_buff + 2) + 4;
                if (op->do_hex > 1)
                    dStrHex((const char *)rsp_buff, rsp_len,
                            (2 == op->do_hex) ? 0 : -1);
                else if (pg < 0x1) {
                    printf("Supported diagnostic pages response:\n");
                    if (op->do_hex)
                        dStrHex((const char *)rsp_buff, rsp_len, 1);
                    else {
                        for (k = 0; k < (rsp_len - 4); ++k) {
                            cp = find_page_code_desc(rsp_buff[k + 4]);
                            printf("  0x%02x  %s\n", rsp_buff[k + 4],
                                   (cp ? cp : "<unknown>"));
                        }
                    }
                } else {
                    cp = find_page_code_desc(pg);
                    if (cp)
                        printf("%s diagnostic page [0x%x] response in "
                               "hex:\n", cp, pg);
                    else
                        printf("diagnostic page 0x%x response in hex:\n", pg);
                    dStrHex((const char *)rsp_buff, rsp_len, 1);
                }
            } else {
                ret = res;
                fprintf(stderr, "RECEIVE DIAGNOSTIC RESULTS command "
                        "failed\n");
                goto err_out9;
            }
        } else {
            ret = res;
            goto err_out;
        }
    } else if (op->do_raw) {
        res = do_senddiag(sg_fd, 0, op->do_pf, 0, 0, 0, read_in,
                          read_in_len, 1, op->do_verbose);
        if (res) {
            ret = res;
            goto err_out;
        }
    } else {
        res = do_senddiag(sg_fd, op->do_selftest, op->do_pf, op->do_deftest,
                          op->do_doff, op->do_uoff, NULL, 0, 1,
                          op->do_verbose);
        if (0 == res) {
            if ((5 == op->do_selftest) || (6 == op->do_selftest))
                printf("Foreground self-test returned GOOD status\n");
            else if (op->do_deftest && (! op->do_doff) && (! op->do_uoff))
                printf("Default self-test returned GOOD status\n");
        } else {
            ret = res;
            goto err_out;
        }
    }
    res = sg_cmds_close_device(sg_fd);
    if ((res < 0) && (0 == ret))
        return SG_LIB_SYNTAX_ERROR;
    return (ret >= 0) ? ret : SG_LIB_CAT_OTHER;

err_out:
    if (SG_LIB_CAT_UNIT_ATTENTION == res)
        fprintf(stderr, "SEND DIAGNOSTIC, unit attention\n");
    else if (SG_LIB_CAT_ABORTED_COMMAND == res)
        fprintf(stderr, "SEND DIAGNOSTIC, aborted command\n");
    else if (SG_LIB_CAT_NOT_READY == res)
        fprintf(stderr, "SEND DIAGNOSTIC, device not "
                "ready\n");
    else
        fprintf(stderr, "SEND DIAGNOSTIC command, failed\n");
err_out9:
    if (op->do_verbose < 2)
        fprintf(stderr, "  try again with '-vv' for more information\n");
    res = sg_cmds_close_device(sg_fd);
    if ((res < 0) && (0 == ret))
        return SG_LIB_FILE_ERROR;
    if (read_in)
        free(read_in);
    if (rsp_buff)
        free(rsp_buff);
    return (ret >= 0) ? ret : SG_LIB_CAT_OTHER;
}
Exemple #5
0
int main(int argc, char *argv[])
{
    matrix A;
    vector u, v, x_bar;
    int status;
    double square_pnts[2][2];

#ifdef HAVE_MPI
    setup(&argc, &argv);
#endif /* HAVE_MPI */

    /* parse the command-line arguments */
    if ((status = process_cl(argc, argv)) != 0) {
#ifdef HAVE_MPI
        finalise();
#endif /* HAVE_MPI */
        fprintf(stderr, "ERROR: Received command-line parsing status %d\n", status);
        fflush(stderr);

        return EXIT_FAILURE;
    }

#ifdef HAVE_LIBGSL
    /* read GSL_IEEE_MODE */
    gsl_ieee_env_setup();
#else
    fesetround(FE_UPWARD);
#endif /* HAVE_LIBGSL */

    /* specify the domain */
    square_pnts[0][0] = globalArgs.x0;
    square_pnts[0][1] = globalArgs.x1;
    square_pnts[1][0] = globalArgs.y0;
    square_pnts[1][1] = globalArgs.y1;

    print_settings();

    /* set up the poisson matrix and vectors */
    setup_poiss_2d(&A, &u, &v, &x_bar, globalArgs.s, globalArgs.d,
                   square_pnts, *src_dens, *bound_cond);

#ifdef NDEBUG
    /* print the matrix and vectors */
# ifdef HAVE_MPI
    fprintf(stdout, "Partial matrix %d:\n", mpiArgs.rank);
# else
    printf("Matrix:\n");
# endif /* HAVE_MPI */
    matrix_print(&A);
#endif /* NDEBUG */

    /* solve with conjugate gradient */
    if (status == 0) {
        status = conjugate(&A, &v, &u, &x_bar, globalArgs.e);
    } else {
        fprintf(stderr, "ERROR: Received conjugate method status %d\n", status);
        fflush(stderr);
    }

    /* print the vector into a gnuplot format */
    if (status == 0) {
        status = print_surface(&x_bar, globalArgs.s - 2, *bound_cond);
    }

    matrix_free(&A);
    vector_free(&u);
    vector_free(&v);
    vector_free(&x_bar);

#ifdef HAVE_MPI
    finalise();
#endif /* HAVE_MPI */

    return status;
}
Exemple #6
0
int main(int argc, char * argv[])
{
    int sg_fd, k, res, progress, pr, rem;
    int num_errs = 0;
    int reported = 0;
    int ret = 0;
#ifndef SG_LIB_MINGW
    struct timeval start_tm, end_tm;
#endif
    struct opts_t opts;

    memset(&opts, 0, sizeof(opts));
    opts.do_number = 1;
    res = process_cl(&opts, argc, argv);
    if (res)
        return SG_LIB_SYNTAX_ERROR;
    if (opts.do_help) {
        usage_for(&opts);
        return 0;
    }
    if (opts.do_version) {
        fprintf(stderr, "Version string: %s\n", version_str);
        return 0;
    }

    if (NULL == opts.device_name) {
        fprintf(stderr, "No DEVICE argument given\n");
        usage_for(&opts);
        return SG_LIB_SYNTAX_ERROR;
    }

    if ((sg_fd = sg_cmds_open_device(opts.device_name, 1 /* ro */,
                                     opts.do_verbose)) < 0) {
        fprintf(stderr, "sg_turs: error opening file: %s: %s\n",
                opts.device_name, safe_strerror(-sg_fd));
        return SG_LIB_FILE_ERROR;
    }
    if (opts.do_progress) {
        for (k = 0; k < opts.do_number; ++k) {
            if (k > 0)
                sleep_for(30);
            progress = -1;
            res = sg_ll_test_unit_ready_progress(sg_fd, k, &progress,
                     ((1 == opts.do_number) ? 1 : 0), opts.do_verbose);
            if (progress < 0) {
                ret = res;
                break;
            } else {
                pr = (progress * 100) / 65536;
                rem = ((progress * 100) % 65536) / 656;
                printf("Progress indication: %d.%02d%% done\n", pr, rem);
            }
        }
        if (opts.do_number > 1)
            printf("Completed %d Test Unit Ready commands\n",
                   ((k < opts.do_number) ? k + 1 : k));
    } else {
#ifndef SG_LIB_MINGW
        if (opts.do_time) {
            start_tm.tv_sec = 0;
            start_tm.tv_usec = 0;
            gettimeofday(&start_tm, NULL);
        }
#endif
        for (k = 0; k < opts.do_number; ++k) {
            /* Might get Unit Attention on first invocation */
            res = sg_ll_test_unit_ready(sg_fd, k, (0 == k), opts.do_verbose);
            if (res) {
                ++num_errs;
                ret = res;
                if ((1 == opts.do_number) && (SG_LIB_CAT_NOT_READY == res)) {
                    printf("device not ready\n");
                    reported = 1;
                    break;
                }
            }
        }
#ifndef SG_LIB_MINGW
        if ((opts.do_time) && (start_tm.tv_sec || start_tm.tv_usec)) {
            struct timeval res_tm;
            double a, b;

            gettimeofday(&end_tm, NULL);
            res_tm.tv_sec = end_tm.tv_sec - start_tm.tv_sec;
            res_tm.tv_usec = end_tm.tv_usec - start_tm.tv_usec;
            if (res_tm.tv_usec < 0) {
                --res_tm.tv_sec;
                res_tm.tv_usec += 1000000;
            }
            a = res_tm.tv_sec;
            a += (0.000001 * res_tm.tv_usec);
            b = (double)opts.do_number;
            printf("time to perform commands was %d.%06d secs",
                   (int)res_tm.tv_sec, (int)res_tm.tv_usec);
            if (a > 0.00001)
                printf("; %.2f operations/sec\n", b / a);
            else
                printf("\n");
        }
#endif

        if (((opts.do_number > 1) || (num_errs > 0)) && (! reported))
            printf("Completed %d Test Unit Ready commands with %d errors\n",
                   opts.do_number, num_errs);
    }
    sg_cmds_close_device(sg_fd);
    return (ret >= 0) ? ret : SG_LIB_CAT_OTHER;
}
Exemple #7
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;
}